mirror of https://gitee.com/antv-l7/antv-l7
feat(layer): add tile
This commit is contained in:
parent
cb47408323
commit
fb84894316
|
@ -24,7 +24,7 @@
|
|||
<script src="../build/L7.js"></script>
|
||||
<script>
|
||||
const colorObj ={
|
||||
blue: ["#E8FCFF", "#CFF6FF", "#A1E9ff", "#65CEF7", "#3CB1F0", "#2894E0", "#1772c2", "#105CB3", "#0D408C", "#002466"].reverse(),
|
||||
blue: ["#E8FCFF", "#CFF6FF", "#A1E9ff", "#65CEF7", "#3CB1F0", "#2894E0", "#1772c2", "#105CB3", "#0D408C", "#002466"],
|
||||
red: ["#FFF4F2", "#FFDFDB", "#FAADAA", "#F77472", "#F04850", "#D63147", "#BD223E", "#A81642", "#820C37", "#5C0023"].reverse(),
|
||||
orange:["#FFF7EB", "#FFECD4", "#FAD09D", "#F7B16A", "#F08D41", "#DB6C2C", "#C2491D", "#AD2B11", "#871D0C", "#610800"].reverse(),
|
||||
green:["#FAFFF0", "#EBF7D2", "#C8E695", "#A5D660", "#7DC238", "#59A616", "#3F8C0B", "#237804", "#125200", "#082B00"].reverse(),
|
||||
|
@ -35,7 +35,7 @@ const colorObj ={
|
|||
|
||||
const scene = new L7.Scene({
|
||||
id: 'map',
|
||||
mapStyle: 'light', // 样式URL
|
||||
mapStyle: 'dark', // 样式URL
|
||||
center: [ 120.19382669582967, 30.258134 ],
|
||||
pitch: 0,
|
||||
zoom: 12,
|
||||
|
@ -52,14 +52,14 @@ scene.on('loaded', () => {
|
|||
isCluster:true
|
||||
})
|
||||
.shape('hexagon')
|
||||
.size('point_count', [ 2, 30]) // default 1
|
||||
.size('point_count', [ 5, 40]) // default 1
|
||||
//.size('value', [ 10, 300]) // default 1
|
||||
.active(true)
|
||||
.color('#2894E0')
|
||||
.color('point_count',colorObj.blue)
|
||||
.style({
|
||||
stroke: 'rgb(255,255,255)',
|
||||
strokeWidth: 1,
|
||||
opacity: 0.8
|
||||
opacity: 1
|
||||
})
|
||||
.render();
|
||||
window.circleLayer = circleLayer;
|
||||
|
@ -69,8 +69,11 @@ scene.on('loaded', () => {
|
|||
.source(circleLayer.layerSource)
|
||||
.shape('point_count', 'text')
|
||||
.active(true)
|
||||
.size('point_count', [ 0, 16]) // default 1
|
||||
.color('#f00')
|
||||
.filter('point_count',(p)=>{
|
||||
return p > 50
|
||||
})
|
||||
.size('point_count', [ 5, 20]) // default 1
|
||||
.color('#fff')
|
||||
.style({
|
||||
stroke: '#999',
|
||||
strokeWidth: 0,
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@antv/l7",
|
||||
"version": "1.1.7",
|
||||
"version": "1.1.8",
|
||||
"description": "Large-scale WebGL-powered Geospatial Data Visualization",
|
||||
"main": "build/l7.js",
|
||||
"browser": "build/l7.js",
|
||||
|
|
|
@ -557,7 +557,6 @@ export default class Layer extends Base {
|
|||
let { featureId, point2d, type } = e;
|
||||
if (featureId < 0 && this._activeIds !== null) {
|
||||
type = 'mouseleave';
|
||||
// featureId = this._activeIds;
|
||||
}
|
||||
this._activeIds = featureId;
|
||||
const feature = this.layerSource.getSelectFeature(featureId);
|
||||
|
@ -579,7 +578,7 @@ export default class Layer extends Base {
|
|||
}
|
||||
/**
|
||||
* 用于过滤数据
|
||||
* @param {*} object 需要过滤的mesh
|
||||
* @param {*} object 更新颜色和数据过滤
|
||||
*/
|
||||
_updateFilter(object) {
|
||||
this._updateMaping();
|
||||
|
@ -629,6 +628,7 @@ export default class Layer extends Base {
|
|||
this._object3D.visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 重新构建mesh
|
||||
redraw() {
|
||||
this._object3D.children.forEach(child => {
|
||||
|
|
|
@ -1,21 +1,38 @@
|
|||
import Base from '../core/base';
|
||||
export class GeomBase extends Base {
|
||||
|
||||
export const GeomBase = {
|
||||
color: 'updateDraw',
|
||||
size: 'repaint',
|
||||
filter: 'updateDraw',
|
||||
layer: '',
|
||||
pickable: true,
|
||||
setLayer(layer) {
|
||||
this.layer = layer;
|
||||
this.style = layer.get('styleOption');
|
||||
},
|
||||
getShape(type) {
|
||||
return type;
|
||||
},
|
||||
draw() {
|
||||
const shape = this.getShape();
|
||||
this.Mesh = shape.Mesh();
|
||||
},
|
||||
// 更新geometry buffer;
|
||||
updateDraw() {
|
||||
|
||||
},
|
||||
repaint() {
|
||||
|
||||
}
|
||||
};
|
||||
export const shapeBae = {
|
||||
geometryBuffer() {
|
||||
},
|
||||
|
||||
geometry() {},
|
||||
|
||||
material() {},
|
||||
|
||||
mesh() {
|
||||
|
||||
}
|
||||
geometry() {
|
||||
}
|
||||
|
||||
material() {
|
||||
|
||||
}
|
||||
|
||||
drawMesh() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default GeomBase;
|
||||
};
|
||||
|
|
|
@ -55,7 +55,8 @@ export function MeshLineMaterial(options) {
|
|||
},
|
||||
vertexShader: vs,
|
||||
fragmentShader: fs,
|
||||
transparent: true
|
||||
transparent: true,
|
||||
blending: THREE.AdditiveBlending
|
||||
});
|
||||
return material;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,8 @@ void main() {
|
|||
}
|
||||
#ifdef ANIMATE
|
||||
vTime = 1.0- (mod(u_time*50.,3600.)- position.z) / 100.;
|
||||
// vTime = 1.0- (28800. + mod(u_time* 10.,28800.)- position.z / 1000.) / 100.;
|
||||
#endif
|
||||
gl_Position = matModelViewProjection * vec4(position.xy,0., 1.0);
|
||||
gl_Position = matModelViewProjection * vec4(position.xy, 0., 1.0);
|
||||
worldId = id_toPickColor(pickingId);
|
||||
}
|
|
@ -20,7 +20,7 @@ uniform float u_trailLength;
|
|||
|
||||
void main() {
|
||||
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
|
||||
vec3 pointPos = position.xyz + vec3(normal * a_size * pow(2.0,20.0-u_zoom) / 2.0 * a_miter);
|
||||
vec3 pointPos = vec3(position.xy,0.) + vec3(normal * a_size * pow(2.0,20.0-u_zoom) / 2.0 * a_miter);
|
||||
v_color = a_color;
|
||||
if(pickingId == u_activeId) {
|
||||
v_color = u_activeColor;
|
||||
|
@ -30,8 +30,9 @@ void main() {
|
|||
float alpa =1.0 - fract( mod(1.0- a_distance,u_interval)* (1.0/u_interval) + u_time / u_duration);
|
||||
alpa = (alpa + u_trailLength -1.0) / u_trailLength;
|
||||
vTime = clamp(alpa,0.,1.);
|
||||
// vTime = (28800. + mod(u_time* 1000.,28800.)- position.z) / 100.;
|
||||
#endif
|
||||
worldId = id_toPickColor(pickingId);
|
||||
gl_Position = matModelViewProjection * vec4(pointPos, 1.0);
|
||||
gl_Position = matModelViewProjection * vec4(pointPos.xy, 0., 1.0);
|
||||
|
||||
}
|
|
@ -94,7 +94,7 @@ export function Line(path, props, positionsIndex) {
|
|||
indexArray[c++] = i + 2;
|
||||
indexArray[c++] = i + 3;
|
||||
}
|
||||
point[2] = size[1];
|
||||
// point[2] = size[1];
|
||||
positions.push(...point);
|
||||
positions.push(...point);
|
||||
|
||||
|
|
|
@ -135,9 +135,9 @@ export default class PointLayer extends Layer {
|
|||
const preBox = cfg.bbox;
|
||||
const preZoom = cfg.zoom;
|
||||
if (!(preBox && preBox[0] < bbox[0] && preBox[1] < bbox[1] && preBox[2] > bbox[2] && preBox[3] < bbox[3] && // 当前范围在范围内
|
||||
(Math.abs(zoom - preZoom)) < 1)) {
|
||||
(Math.abs(zoom - preZoom)) < 0.5)) {
|
||||
const newbbox = [ SW.lng - step, SW.lat - step, NE.lng + step, NE.lat + step ];
|
||||
this.layerSource.updateCusterData(Math.floor(zoom), newbbox);
|
||||
this.layerSource.updateCusterData(Math.floor(zoom - 1), newbbox);
|
||||
this.repaint();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
// import * as THREE from '../../core/three';
|
||||
// import Tile from './tile';
|
||||
// export default class ImageTile extends Tile {
|
||||
// constructor(layer, z, x, y) {
|
||||
|
||||
// }
|
||||
// requestTileAsync() {
|
||||
// // Making this asynchronous really speeds up the LOD framerate
|
||||
// setTimeout(() => {
|
||||
// if (!this._mesh) {
|
||||
// this._mesh = this._createMesh();
|
||||
// this._requestTile();
|
||||
// }
|
||||
// }, 0);
|
||||
// }
|
||||
// _requestTile() {
|
||||
// const urlParams = {
|
||||
// x: this._tile[0],
|
||||
// y: this._tile[1],
|
||||
// z: this._tile[2]
|
||||
// };
|
||||
|
||||
// const url = this._getTileURL(urlParams);
|
||||
|
||||
// const image = document.createElement('img');
|
||||
|
||||
// image.addEventListener('load', event => {
|
||||
// const texture = new THREE.Texture();
|
||||
|
||||
// texture.image = image;
|
||||
// texture.needsUpdate = true;
|
||||
|
||||
// // Silky smooth images when tilted
|
||||
// texture.magFilter = THREE.LinearFilter;
|
||||
// texture.minFilter = THREE.LinearMipMapLinearFilter;
|
||||
|
||||
// // TODO: Set this to renderer.getMaxAnisotropy() / 4
|
||||
// texture.anisotropy = 4;
|
||||
|
||||
// texture.needsUpdate = true;
|
||||
|
||||
// // Something went wrong and the tile or its material is missing
|
||||
// //
|
||||
// // Possibly removed by the cache before the image loaded
|
||||
// if (!this._mesh || !this._mesh.children[0] || !this._mesh.children[0].material) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// this._mesh.children[0].material.map = texture;
|
||||
// this._mesh.children[0].material.needsUpdate = true;
|
||||
|
||||
// this._texture = texture;
|
||||
// this._ready = true;
|
||||
// }, false);
|
||||
|
||||
// // image.addEventListener('progress', event => {}, false);
|
||||
// // image.addEventListener('error', event => {}, false);
|
||||
|
||||
// image.crossOrigin = '';
|
||||
|
||||
// // Load image
|
||||
// image.src = url;
|
||||
|
||||
// this._image = image;
|
||||
// }
|
||||
|
||||
// _createMesh() {
|
||||
// // Something went wrong and the tile
|
||||
// //
|
||||
// // Possibly removed by the cache before loaded
|
||||
// if (!this._center) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const mesh = new THREE.Object3D();
|
||||
// const geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);
|
||||
|
||||
// let material;
|
||||
// if (!this._world._environment._skybox) {
|
||||
// material = new THREE.MeshBasicMaterial({
|
||||
// depthWrite: false
|
||||
// });
|
||||
|
||||
// // const material = new THREE.MeshPhongMaterial({
|
||||
// // depthWrite: false
|
||||
// // });
|
||||
// } else {
|
||||
// // Other MeshStandardMaterial settings
|
||||
// //
|
||||
// // material.envMapIntensity will change the amount of colour reflected(?)
|
||||
// // from the environment map–can be greater than 1 for more intensity
|
||||
|
||||
// material = new THREE.MeshStandardMaterial({
|
||||
// depthWrite: false
|
||||
// });
|
||||
// material.roughness = 1;
|
||||
// material.metalness = 0.1;
|
||||
// material.envMap = this._world._environment._skybox.getRenderTarget();
|
||||
// }
|
||||
|
||||
// const localMesh = new THREE.Mesh(geom, material);
|
||||
// localMesh.rotation.x = -90 * Math.PI / 180;
|
||||
|
||||
// localMesh.receiveShadow = true;
|
||||
|
||||
// mesh.add(localMesh);
|
||||
// mesh.renderOrder = 0.1;
|
||||
|
||||
// mesh.position.x = this._center[0];
|
||||
// mesh.position.z = this._center[1];
|
||||
|
||||
// // const box = new BoxHelper(localMesh);
|
||||
// // mesh.add(box);
|
||||
// //
|
||||
// // mesh.add(this._createDebugMesh());
|
||||
|
||||
// return mesh;
|
||||
// }
|
||||
// _abortRequest() {
|
||||
// if (!this._image) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// this._image.src = '';
|
||||
// }
|
||||
|
||||
// destroy() {
|
||||
// // Cancel any pending requests
|
||||
// this._abortRequest();
|
||||
|
||||
// // Clear image reference
|
||||
// this._image = null;
|
||||
|
||||
// super.destroy();
|
||||
// }
|
||||
|
||||
// }
|
|
@ -0,0 +1,22 @@
|
|||
import LRUCache from '../../util/lru-cache';
|
||||
export default class TileCache {
|
||||
constructor(limit = 50) {
|
||||
this._cache = new LRUCache(limit);
|
||||
}
|
||||
|
||||
getTile(z, x, y) {
|
||||
const key = this._generateKey(z, x, y);
|
||||
return this._cache.get(key);
|
||||
}
|
||||
|
||||
setTile(tile, z, x, y) {
|
||||
const key = this._generateKey(z, x, y);
|
||||
this._cache.set(key, tile);
|
||||
}
|
||||
_generateKey(z, x, y) {
|
||||
return [ z, x, y ].join('_');
|
||||
}
|
||||
destory() {
|
||||
this._cache.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// const r2d = 180 / Math.PI;
|
||||
// const tileURLRegex = /\{([zxy])\}/g;
|
||||
// export class Tile {
|
||||
// constructor(layer, z, x, y) {
|
||||
// this.layer = layer;
|
||||
// this._tile = [ z, x, y ];
|
||||
|
||||
// }
|
||||
// _createMesh() {}
|
||||
// _createDebugMesh() {}
|
||||
|
||||
// _getTileURL(urlParams) {
|
||||
// if (!urlParams.s) {
|
||||
// // Default to a random choice of a, b or c
|
||||
// urlParams.s = String.fromCharCode(97 + Math.floor(Math.random() * 3));
|
||||
// }
|
||||
|
||||
// tileURLRegex.lastIndex = 0;
|
||||
// return this._path.replace(tileURLRegex, function(value, key) {
|
||||
// // Replace with paramter, otherwise keep existing value
|
||||
// return urlParams[key];
|
||||
// });
|
||||
// }
|
||||
|
||||
// _tileBoundsFromWGS84(boundsWGS84) {
|
||||
// const sw = this._layer._world.latLonToPoint(LatLon(boundsWGS84[1], boundsWGS84[0]));
|
||||
// const ne = this._layer._world.latLonToPoint(LatLon(boundsWGS84[3], boundsWGS84[2]));
|
||||
|
||||
// return [sw.x, sw.y, ne.x, ne.y];
|
||||
// }
|
||||
|
||||
// // Get tile bounds in WGS84 coordinates
|
||||
// _tileBoundsWGS84(tile) {
|
||||
// const e = this._tile2lon(tile[0] + 1, tile[2]);
|
||||
// const w = this._tile2lon(tile[0], tile[2]);
|
||||
// const s = this._tile2lat(tile[1] + 1, tile[2]);
|
||||
// const n = this._tile2lat(tile[1], tile[2]);
|
||||
// return [ w, s, e, n ];
|
||||
// }
|
||||
|
||||
// _tile2lon(x, z) {
|
||||
// return x / Math.pow(2, z) * 360 - 180;
|
||||
// }
|
||||
|
||||
// _tile2lat(y, z) {
|
||||
// const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
|
||||
// return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
||||
// }
|
||||
|
||||
// _boundsToCenter(bounds) {
|
||||
// const x = bounds[0] + (bounds[2] - bounds[0]) / 2;
|
||||
// const y = bounds[1] + (bounds[3] - bounds[1]) / 2;
|
||||
|
||||
// return [ x, y ];
|
||||
// }
|
||||
// destory() {
|
||||
|
||||
// }
|
||||
// }
|
|
@ -1,11 +1,10 @@
|
|||
import * as turfMeta from '@turf/meta';
|
||||
import { default as cleanCoords } from '@turf/clean-coords';
|
||||
import { getCoords } from '@turf/invariant';
|
||||
|
||||
export default function geoJSON(data) {
|
||||
const resultData = [];
|
||||
turfMeta.flattenEach(data, (currentFeature, featureIndex) => { // 多个polygon 拆成一个
|
||||
const coord = getCoords(cleanCoords(currentFeature));
|
||||
const coord = getCoords(currentFeature);
|
||||
const dataItem = {
|
||||
...currentFeature.properties,
|
||||
coordinates: coord,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Supercluster from 'supercluster';
|
||||
export function cluster(data, option) {
|
||||
const { radius = 40, maxZoom = 16, minZoom = 0, field, zoom = 2 } = option;
|
||||
const { radius = 80, maxZoom = 18, minZoom = 0, field, zoom = 2 } = option;
|
||||
if (data.pointIndex) {
|
||||
const clusterPoint = data.pointIndex.getClusters(data.extent, zoom);
|
||||
data.dataArray = formatData(clusterPoint);
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* LRU Cache class with limit
|
||||
*
|
||||
* Update order for each get/set operation
|
||||
* Delete oldest when reach given limit
|
||||
*/
|
||||
|
||||
export default class LRUCache {
|
||||
constructor(limit = 5) {
|
||||
this.limit = limit;
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._cache = {};
|
||||
// access/update order, first item is oldest, last item is newest
|
||||
this._order = [];
|
||||
}
|
||||
|
||||
get(key) {
|
||||
const value = this._cache[key];
|
||||
if (value) {
|
||||
// update order
|
||||
this._deleteOrder(key);
|
||||
this._appendOrder(key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
if (!this._cache[key]) {
|
||||
// if reach limit, delete the oldest
|
||||
if (Object.keys(this._cache).length === this.limit) {
|
||||
this.delete(this._order[0]);
|
||||
}
|
||||
|
||||
this._cache[key] = value;
|
||||
this._appendOrder(key);
|
||||
} else {
|
||||
// if found in cache, delete the old one, insert new one to the first of list
|
||||
this.delete(key);
|
||||
|
||||
this._cache[key] = value;
|
||||
this._appendOrder(key);
|
||||
}
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
const value = this._cache[key];
|
||||
if (value) {
|
||||
this._deleteCache(key);
|
||||
this._deleteOrder(key);
|
||||
}
|
||||
}
|
||||
|
||||
_deleteCache(key) {
|
||||
delete this._cache[key];
|
||||
}
|
||||
|
||||
_deleteOrder(key) {
|
||||
const index = this._order.findIndex(o => o === key);
|
||||
if (index >= 0) {
|
||||
this._order.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
_appendOrder(key) {
|
||||
this._order.push(key);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue