mirror of https://gitee.com/antv-l7/antv-l7
feat(layer): add tile
This commit is contained in:
parent
ee284d81cc
commit
181d7bc42f
|
@ -24,7 +24,7 @@
|
||||||
<script src="../build/L7.js"></script>
|
<script src="../build/L7.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const colorObj ={
|
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(),
|
red: ["#FFF4F2", "#FFDFDB", "#FAADAA", "#F77472", "#F04850", "#D63147", "#BD223E", "#A81642", "#820C37", "#5C0023"].reverse(),
|
||||||
orange:["#FFF7EB", "#FFECD4", "#FAD09D", "#F7B16A", "#F08D41", "#DB6C2C", "#C2491D", "#AD2B11", "#871D0C", "#610800"].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(),
|
green:["#FAFFF0", "#EBF7D2", "#C8E695", "#A5D660", "#7DC238", "#59A616", "#3F8C0B", "#237804", "#125200", "#082B00"].reverse(),
|
||||||
|
@ -35,7 +35,7 @@ const colorObj ={
|
||||||
|
|
||||||
const scene = new L7.Scene({
|
const scene = new L7.Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
mapStyle: 'light', // 样式URL
|
mapStyle: 'dark', // 样式URL
|
||||||
center: [ 120.19382669582967, 30.258134 ],
|
center: [ 120.19382669582967, 30.258134 ],
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
zoom: 12,
|
zoom: 12,
|
||||||
|
@ -52,14 +52,14 @@ scene.on('loaded', () => {
|
||||||
isCluster:true
|
isCluster:true
|
||||||
})
|
})
|
||||||
.shape('hexagon')
|
.shape('hexagon')
|
||||||
.size('point_count', [ 2, 30]) // default 1
|
.size('point_count', [ 5, 40]) // default 1
|
||||||
//.size('value', [ 10, 300]) // default 1
|
//.size('value', [ 10, 300]) // default 1
|
||||||
.active(true)
|
.active(true)
|
||||||
.color('#2894E0')
|
.color('point_count',colorObj.blue)
|
||||||
.style({
|
.style({
|
||||||
stroke: 'rgb(255,255,255)',
|
stroke: 'rgb(255,255,255)',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
opacity: 0.8
|
opacity: 1
|
||||||
})
|
})
|
||||||
.render();
|
.render();
|
||||||
window.circleLayer = circleLayer;
|
window.circleLayer = circleLayer;
|
||||||
|
@ -69,8 +69,11 @@ scene.on('loaded', () => {
|
||||||
.source(circleLayer.layerSource)
|
.source(circleLayer.layerSource)
|
||||||
.shape('point_count', 'text')
|
.shape('point_count', 'text')
|
||||||
.active(true)
|
.active(true)
|
||||||
.size('point_count', [ 0, 16]) // default 1
|
.filter('point_count',(p)=>{
|
||||||
.color('#f00')
|
return p > 50
|
||||||
|
})
|
||||||
|
.size('point_count', [ 5, 20]) // default 1
|
||||||
|
.color('#fff')
|
||||||
.style({
|
.style({
|
||||||
stroke: '#999',
|
stroke: '#999',
|
||||||
strokeWidth: 0,
|
strokeWidth: 0,
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@antv/l7",
|
"name": "@antv/l7",
|
||||||
"version": "1.1.7",
|
"version": "1.1.8",
|
||||||
"description": "Large-scale WebGL-powered Geospatial Data Visualization",
|
"description": "Large-scale WebGL-powered Geospatial Data Visualization",
|
||||||
"main": "build/l7.js",
|
"main": "build/l7.js",
|
||||||
"browser": "build/l7.js",
|
"browser": "build/l7.js",
|
||||||
|
|
|
@ -557,7 +557,6 @@ export default class Layer extends Base {
|
||||||
let { featureId, point2d, type } = e;
|
let { featureId, point2d, type } = e;
|
||||||
if (featureId < 0 && this._activeIds !== null) {
|
if (featureId < 0 && this._activeIds !== null) {
|
||||||
type = 'mouseleave';
|
type = 'mouseleave';
|
||||||
// featureId = this._activeIds;
|
|
||||||
}
|
}
|
||||||
this._activeIds = featureId;
|
this._activeIds = featureId;
|
||||||
const feature = this.layerSource.getSelectFeature(featureId);
|
const feature = this.layerSource.getSelectFeature(featureId);
|
||||||
|
@ -579,7 +578,7 @@ export default class Layer extends Base {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 用于过滤数据
|
* 用于过滤数据
|
||||||
* @param {*} object 需要过滤的mesh
|
* @param {*} object 更新颜色和数据过滤
|
||||||
*/
|
*/
|
||||||
_updateFilter(object) {
|
_updateFilter(object) {
|
||||||
this._updateMaping();
|
this._updateMaping();
|
||||||
|
@ -629,6 +628,7 @@ export default class Layer extends Base {
|
||||||
this._object3D.visible = true;
|
this._object3D.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新构建mesh
|
// 重新构建mesh
|
||||||
redraw() {
|
redraw() {
|
||||||
this._object3D.children.forEach(child => {
|
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() {
|
geometryBuffer() {
|
||||||
|
},
|
||||||
|
|
||||||
|
geometry() {},
|
||||||
|
|
||||||
|
material() {},
|
||||||
|
|
||||||
|
mesh() {
|
||||||
|
|
||||||
}
|
}
|
||||||
geometry() {
|
};
|
||||||
}
|
|
||||||
|
|
||||||
material() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
drawMesh() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default GeomBase;
|
|
||||||
|
|
|
@ -55,7 +55,8 @@ export function MeshLineMaterial(options) {
|
||||||
},
|
},
|
||||||
vertexShader: vs,
|
vertexShader: vs,
|
||||||
fragmentShader: fs,
|
fragmentShader: fs,
|
||||||
transparent: true
|
transparent: true,
|
||||||
|
blending: THREE.AdditiveBlending
|
||||||
});
|
});
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ void main() {
|
||||||
}
|
}
|
||||||
#ifdef ANIMATE
|
#ifdef ANIMATE
|
||||||
vTime = 1.0- (mod(u_time*50.,3600.)- position.z) / 100.;
|
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
|
#endif
|
||||||
gl_Position = matModelViewProjection * vec4(position.xy,0., 1.0);
|
gl_Position = matModelViewProjection * vec4(position.xy, 0., 1.0);
|
||||||
worldId = id_toPickColor(pickingId);
|
worldId = id_toPickColor(pickingId);
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ uniform float u_trailLength;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
|
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;
|
v_color = a_color;
|
||||||
if(pickingId == u_activeId) {
|
if(pickingId == u_activeId) {
|
||||||
v_color = u_activeColor;
|
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);
|
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;
|
alpa = (alpa + u_trailLength -1.0) / u_trailLength;
|
||||||
vTime = clamp(alpa,0.,1.);
|
vTime = clamp(alpa,0.,1.);
|
||||||
|
// vTime = (28800. + mod(u_time* 1000.,28800.)- position.z) / 100.;
|
||||||
#endif
|
#endif
|
||||||
worldId = id_toPickColor(pickingId);
|
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 + 2;
|
||||||
indexArray[c++] = i + 3;
|
indexArray[c++] = i + 3;
|
||||||
}
|
}
|
||||||
point[2] = size[1];
|
// point[2] = size[1];
|
||||||
positions.push(...point);
|
positions.push(...point);
|
||||||
positions.push(...point);
|
positions.push(...point);
|
||||||
|
|
||||||
|
|
|
@ -135,9 +135,9 @@ export default class PointLayer extends Layer {
|
||||||
const preBox = cfg.bbox;
|
const preBox = cfg.bbox;
|
||||||
const preZoom = cfg.zoom;
|
const preZoom = cfg.zoom;
|
||||||
if (!(preBox && preBox[0] < bbox[0] && preBox[1] < bbox[1] && preBox[2] > bbox[2] && preBox[3] < bbox[3] && // 当前范围在范围内
|
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 ];
|
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();
|
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 * as turfMeta from '@turf/meta';
|
||||||
import { default as cleanCoords } from '@turf/clean-coords';
|
|
||||||
import { getCoords } from '@turf/invariant';
|
import { getCoords } from '@turf/invariant';
|
||||||
|
|
||||||
export default function geoJSON(data) {
|
export default function geoJSON(data) {
|
||||||
const resultData = [];
|
const resultData = [];
|
||||||
turfMeta.flattenEach(data, (currentFeature, featureIndex) => { // 多个polygon 拆成一个
|
turfMeta.flattenEach(data, (currentFeature, featureIndex) => { // 多个polygon 拆成一个
|
||||||
const coord = getCoords(cleanCoords(currentFeature));
|
const coord = getCoords(currentFeature);
|
||||||
const dataItem = {
|
const dataItem = {
|
||||||
...currentFeature.properties,
|
...currentFeature.properties,
|
||||||
coordinates: coord,
|
coordinates: coord,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Supercluster from 'supercluster';
|
import Supercluster from 'supercluster';
|
||||||
export function cluster(data, option) {
|
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) {
|
if (data.pointIndex) {
|
||||||
const clusterPoint = data.pointIndex.getClusters(data.extent, zoom);
|
const clusterPoint = data.pointIndex.getClusters(data.extent, zoom);
|
||||||
data.dataArray = formatData(clusterPoint);
|
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