Merge pull request #14 from antvis/json_source

feat(json): point数据coord 设置支持数组
This commit is contained in:
@thinkinggis 2019-08-19 11:17:34 +08:00 committed by GitHub
commit 70328ec285
8 changed files with 243 additions and 57 deletions

93
demos/legend.html Normal file
View File

@ -0,0 +1,93 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://gw.alipayobjects.com/os/rmsportal/PqLCOJpqoOUfuPRacUzE.css" />
<title>自定义图例组件</title>
<style> ::-webkit-scrollbar{display:none;}html,body{overflow:hidden;margin:0;}
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>/*Fixing iframe window.innerHeight 0 issue in Safari*/ document.body.clientHeight; </script>
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
<script src="../build/L7.js"></script>
<style>
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 {
margin: 0 0 5px;
color: #777;
}
.legend {
line-height: 18px;
color: #555;
}
.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
<script>
var scene = new L7.Scene({
id: 'map',
mapStyle: 'light', // 样式URL
center: [120.19382669582967, 30.258134],
pitch: 0,
zoom: 4,
zoomControl: false,
scaleControl: false
});
scene.on('loaded', function() {
var colors = ["#FFF5B8", "#FFDC7D", "#FFAB5C", "#F27049", "#D42F31", "#730D1C"];
$.getJSON('https://gw.alipayobjects.com/os/rmsportal/JToMOWvicvJOISZFCkEI.json', function(city) {
var layer = scene.PolygonLayer().source(city).color('pm2_5_24h', function(p) {
if (p > 120) {
return colors[5];
} else if (p > 65) {
return colors[4];
} else if (p > 30) {
return colors[3];
} else if (p > 15) {
return colors[2];
} else if (p > 8) {
return colors[1];
} else {
return colors[0];
}
}).shape('fill').active(true).style({
opacity: 1
}).render();
var legendinfo = layer.getLegendCfg('pm2_5_24h');
var legend = new L7.Control.Base({
position: 'bottomright'
});
legend.onAdd = function(scene) {
const el = document.createElement('div');
el.className = 'info legend';
const grades = [0, 8, 15, 30, 65, 120 ];
for (var i = 0; i < grades.length; i++) {
el.innerHTML +=
'<i style="background:' + colors[i] + '"></i> ' +
grades[i] + (grades[i + 1] ? '&ndash;' + grades[i + 1] + '<br>' : '+');
}
return el;
};
legend.addTo(scene);
});
});
</script>
</body>
</html>

View File

@ -7,55 +7,127 @@
<meta name="geometry" content="diagram">
<link rel="stylesheet" href="./assets/common.css">
<title>city demo</title>
</head>
<style>
#map { position:absolute; top:0; bottom:0; width:100%; }
#timepannel {
background: white;
z-index: 10;
position: absolute;
right:50px;
padding: 10px;
}
</style>
</head>
<body>
<div id ='timepannel'>时间: 6时</div>
<div id="map">
</div>
<script src="https://webapi.amap.com/maps?v=1.4.8&key=f28fca5384129d180ad82915156a9baf&plugin=Map3D"></script>
<script src="./assets/jquery-3.2.1.min.js"></script>
<script src="../build/L7.js"></script>
<script>
var buildLayer =null;
function parseCSV (data) {
const lines = data.split('\n')
const header = lines[0]
const columns = header.split(',')
return lines.slice(1).filter(l => l).map(line => {
const obj = {}
line.split(',').forEach((value, i) => {
const name = columns[i]
obj[name] = value;
})
return obj
})
}
const scene = new L7.Scene({
id: 'map',
mapStyle: 'amap://styles/c9f1d10cae34f8ab05e425462c5a58d7', // 样式URL
center: [120.102915,30.261396],
pitch: 0,
zoom: 3,
minZoom: 5,
maxZoom: 18
mapStyle: 'dark', // 样式URL
center: [-73.95115, 40.76628 ],
pitch: 56,
zoom: 13.67,
rotation:255.1,
hash:true
});
scene.on('loaded', () => {
scene.image.addImage('arrow', '/demos/assets/arrow.png');
scene.image.addImage('right', '/demos/assets/right.png');
$.get('https://gw.alipayobjects.com/os/basement_prod/3ed18d7c-bce4-48ca-8716-5248b584481d.json',(data)=>{
scene.on('loaded',()=>{
Promise.all([
fetch('https://gw.alipayobjects.com/os/basement_prod/9acd4831-5655-41a5-b0a0-831603e0092d.json').then(d => d.text()).then(JSON.parse),
fetch('https://gw.alipayobjects.com/os/basement_prod/dbe4e40b-3fbf-4a20-b36b-7a8bd3b8aef2.csv').then(d => d.text()),
fetch('https://gw.alipayobjects.com/os/basement_prod/89d20ef7-77df-44ca-a238-6e3679ab3ae4.csv').then(d => d.text())
]).then(function onLoad ([coordinates, trips, stations]) {
const stationArray = parseCSV(stations);
const stationObj = {};
stationArray.forEach((st)=>{
stationObj[st.station_id] = {
x:st.longitude* 1,
y:st.latitude * 1,
}
})
const tripsArray = parseCSV(trips);
const triplines = [];
tripsArray.forEach(trip=>{
if(stationObj[trip.start_station] && stationObj[trip.end_station]) {
const line = {
x: stationObj[trip.start_station].x,
y: stationObj[trip.start_station].y,
x1: stationObj[trip.end_station].x,
y1: stationObj[trip.end_station].y,
duration: trip.duration,
}
triplines.push(line);
}
})
const linelayer = scene.LineLayer({
zIndex: 2
const triplayer = scene.LineLayer({
zIndex: 1
})
.shape('line')
.size(10)
.source(data)
.color('#2b83ba')
.pattern('arrow')
.source(triplines.slice(0,500),{
parser:{
type:'json',
x:'x',
y:'y',
x1:'x1',
y1:'y1'
}
})
.shape('arc')
.size(2)
.color('#fec44f')
.style({
patternSpacing: 20
})
opacity:0.9,
})
.render();
});
const road = scene.LineLayer({
zIndex: 0
})
.source(coordinates)
.shape('line')
.size(1.5)
.color('#eee')
.style({
opacity:1,
})
.render();
const station = scene.PointLayer({
zIndex: 0
})
.source(stations,{
parser:{
type:'csv',
x:'longitude',
y:'latitude'
}
})
.shape('circle')
.active(true)
.size(5)
.color('#fec44f')
.style({
opacity:0.9,
})
.render();
})
})
</script>
</body>

View File

@ -1,11 +1,11 @@
import Control from './base';
import Base from './base';
import Zoom from './zoom';
import Scale from './Scale';
import Attribution from './attribution';
import Layers from './layer';
export {
Control,
Base,
Zoom,
Scale,
Attribution,

View File

@ -2,6 +2,7 @@ import Util from '../../util';
import Global from '../../global';
import ScaleController from './scale';
import Attr from '../../attr/index';
import ColorUtil from '../../attr/color-util';
export default class Mapping {
/** mapping
* 初始化mapping
@ -182,4 +183,31 @@ export default class Mapping {
}
return [ field ];
}
/**
* 获取图例配置项
* @param {*} field 字段
* @param {*} type 图例类型 color, size
* @return {*} 图例配置项
*/
getLegendCfg(field, type = 'color') {
// todo heatmap
if (this.layer.type === 'heatmap' && this.layer.shapeType === 'heatmap') {
return this.get('styleOptions').rampColors;
}
const scales = this.layer.get('scales');
const scale = scales[field];
const colorAttrs = this.layer.get('attrs')[type];
const lengendCfg = {};
if (scale) {
const ticks = scale.ticks;
lengendCfg.value = ticks;
lengendCfg.type = scale.type;
const values = ticks.map(value => {
const v = this._getAttrValues(colorAttrs, { [field]: value });
return type === 'color' ? ColorUtil.colorArray2RGBA(v) : v;
});
lengendCfg[type] = values;
}
return lengendCfg;
}
}

View File

@ -4,10 +4,10 @@
*/
import Base from './base';
import * as THREE from './three';
import ColorUtil from '../attr/color-util';
import Controller from './controller/index';
import source from './source';
import diff from '../util/diff';
import ColorUtil from '../attr/color-util';
import { updateObjecteUniform } from '../util/object3d-util';
import Util from '../util';
import Global from '../global';
@ -666,25 +666,8 @@ export default class Layer extends Base {
* @return {*} 图例配置项
*/
getLegendCfg(field, type = 'color') {
// todo heatmap
if (this.type === 'heatmap' && this.shapeType === 'heatmap') {
return this.get('styleOptions').rampColors;
}
const scales = this.get('scales');
const scale = scales[field];
const colorAttrs = this.get('attrs')[type];
const lengendCfg = {};
if (scale) {
const ticks = scale.ticks;
lengendCfg.value = ticks;
lengendCfg.type = scale.type;
const values = ticks.map(value => {
const v = this._getAttrValues(colorAttrs, { [field]: value });
return type === 'color' ? ColorUtil.colorArray2RGBA(v) : v;
});
lengendCfg[type] = values;
}
return lengendCfg;
const mapCtr = this.get('mappingController');
return mapCtr.getLegendCfg(field, type);
}
preRender() {

View File

@ -38,7 +38,8 @@ export function ArcLineMaterial(options) {
vertexShader: vs,
fragmentShader: fs,
transparent: true,
blending: THREE.AdditiveBlending
blending: THREE.AdditiveBlending,
side: THREE.DoubleSide
});
return material;
}

View File

@ -30,5 +30,6 @@ export default function DrawArcLine(layerData, layer, buffer) {
SHAPE: false
});
const arcMesh = new THREE.Mesh(geometry, lineMaterial);
arcMesh.frustumCulled = false;
return arcMesh;
}

View File

@ -3,15 +3,23 @@ export default function json(data, cfg) {
const { x, y, x1, y1, coordinates } = cfg;
const resultdata = [];
data.forEach((col, featureIndex) => {
data.slice(0).forEach((col, featureIndex) => {
let coords = [];
if (x && y) { coords = [ col[x], col[y] ]; } // 点数据
if (x1 && y1) { // 弧线 或者线段
coords = [[ col[x], col[y] ], [ col[x1], col[y1] ]];
}
if (coordinates) {
let type = 'Polygon';
if (!Array.isArray(coordinates[0])) {
type = 'Point';
}
if (Array.isArray(coordinates[0]) && !Array.isArray(coordinates[0][0])) {
type = 'LineString';
}
const geometry = {
type: 'Polygon',
type,
coordinates: [ ...col[coordinates] ]
};
rewind(geometry, true);