mirror of https://gitee.com/antv-l7/antv-l7
fix(source)
This commit is contained in:
parent
2a84b5480e
commit
4cbcf77873
|
@ -13,14 +13,14 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
<script src="https://webapi.amap.com/maps?v=1.4.8&key=15cd8a57710d40c9b7c0e3cc120f1200&plugin=Map3D"></script>
|
<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="./assets/jquery-3.2.1.min.js"></script>
|
||||||
<script src="./assets/dat.gui.min.js"></script>
|
<script src="./assets/dat.gui.min.js"></script>
|
||||||
<script src="../build/L7.js"></script>
|
<script src="../build/L7.js"></script>
|
||||||
<script>
|
<script>
|
||||||
const scene = new L7.Scene({
|
const scene = new L7.Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
mapStyle: 'dark', // 样式URL
|
mapStyle: 'amap://styles/c9f1d10cae34f8ab05e425462c5a58d7', // 样式URL
|
||||||
center: [ -155, 60 ],
|
center: [ -155, 60 ],
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
zoom: 4.5
|
zoom: 4.5
|
||||||
|
@ -35,11 +35,12 @@ scene.on('loaded', () => {
|
||||||
.source(data)
|
.source(data)
|
||||||
.size('mag', [ 0, 1 ]) // weight映射通道
|
.size('mag', [ 0, 1 ]) // weight映射通道
|
||||||
.style({
|
.style({
|
||||||
intensity: 100,
|
intensity: 10,
|
||||||
radius: 30,
|
radius: 10,
|
||||||
|
opacity:1,
|
||||||
rampColors: {
|
rampColors: {
|
||||||
colors: [ 'rgba(33,102,172,0.0)', 'rgb(103,169,207)', 'rgb(209,229,240)', 'rgb(253,219,199)', 'rgb(239,138,98)', 'rgb(178,24,43,1.0)' ],
|
colors: [ '#ffda45ff', '#fde725ff', '#ffc934ff', '#ffb824ff', '#ffb824ff', '#fa8100ff' ],
|
||||||
positions: [ 0, 0.2, 0.4, 0.6, 0.8, 1.0 ]
|
positions: [ 0, 0.2, 0.4, 0.6, 0.9, 1.0 ]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.render();
|
.render();
|
||||||
|
|
|
@ -111,6 +111,7 @@
|
||||||
"polyline-normals": "^2.0.2",
|
"polyline-normals": "^2.0.2",
|
||||||
"rbush": "^2.0.2",
|
"rbush": "^2.0.2",
|
||||||
"simple-statistics": "^7.0.1",
|
"simple-statistics": "^7.0.1",
|
||||||
|
"supercluster": "^6.0.1",
|
||||||
"three": "^0.101.1",
|
"three": "^0.101.1",
|
||||||
"venn.js": "^0.2.20",
|
"venn.js": "^0.2.20",
|
||||||
"viewport-mercator-project": "^5.2.0",
|
"viewport-mercator-project": "^5.2.0",
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
// jscs:disable
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import THREE from 'three';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*
|
||||||
|
* Full-screen textured quad shader
|
||||||
|
*/
|
||||||
|
|
||||||
|
var CopyShader = {
|
||||||
|
|
||||||
|
uniforms: {
|
||||||
|
|
||||||
|
"tDiffuse": { type: "t", value: null },
|
||||||
|
"opacity": { type: "f", value: 1.0 }
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
vertexShader: [
|
||||||
|
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
"vUv = uv;",
|
||||||
|
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join( "\n" ),
|
||||||
|
|
||||||
|
fragmentShader: [
|
||||||
|
|
||||||
|
"uniform float opacity;",
|
||||||
|
|
||||||
|
"uniform sampler2D tDiffuse;",
|
||||||
|
|
||||||
|
"varying vec2 vUv;",
|
||||||
|
|
||||||
|
"void main() {",
|
||||||
|
|
||||||
|
"vec4 texel = texture2D( tDiffuse, vUv );",
|
||||||
|
"gl_FragColor = opacity * texel;",
|
||||||
|
|
||||||
|
"}"
|
||||||
|
|
||||||
|
].join( "\n" )
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CopyShader;
|
||||||
|
THREE.CopyShader = CopyShader;
|
|
@ -0,0 +1,21 @@
|
||||||
|
import EffectComposer from './composer';
|
||||||
|
|
||||||
|
export default function(renderer, container) {
|
||||||
|
const composer = new EffectComposer(renderer);
|
||||||
|
|
||||||
|
const updateSize = function() {
|
||||||
|
// TODO: Re-enable this when perf issues can be solved
|
||||||
|
//
|
||||||
|
// Rendering double the resolution of the screen can be really slow
|
||||||
|
// var pixelRatio = window.devicePixelRatio;
|
||||||
|
const pixelRatio = 1;
|
||||||
|
|
||||||
|
composer.setSize(container.clientWidth * pixelRatio, container.clientHeight * pixelRatio);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('resize', updateSize, false);
|
||||||
|
updateSize();
|
||||||
|
|
||||||
|
return composer;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
// jscs:disable
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import THREE from 'three';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
var MaskPass = function ( scene, camera ) {
|
||||||
|
|
||||||
|
this.scene = scene;
|
||||||
|
this.camera = camera;
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
this.clear = true;
|
||||||
|
this.needsSwap = false;
|
||||||
|
|
||||||
|
this.inverse = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
MaskPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
var context = renderer.context;
|
||||||
|
|
||||||
|
// don't update color or depth
|
||||||
|
|
||||||
|
context.colorMask( false, false, false, false );
|
||||||
|
context.depthMask( false );
|
||||||
|
|
||||||
|
// set up stencil
|
||||||
|
|
||||||
|
var writeValue, clearValue;
|
||||||
|
|
||||||
|
if ( this.inverse ) {
|
||||||
|
|
||||||
|
writeValue = 0;
|
||||||
|
clearValue = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
writeValue = 1;
|
||||||
|
clearValue = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
context.enable( context.STENCIL_TEST );
|
||||||
|
context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );
|
||||||
|
context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );
|
||||||
|
context.clearStencil( clearValue );
|
||||||
|
|
||||||
|
// draw into the stencil buffer
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, readBuffer, this.clear );
|
||||||
|
renderer.render( this.scene, this.camera, writeBuffer, this.clear );
|
||||||
|
|
||||||
|
// re-enable update of color and depth
|
||||||
|
|
||||||
|
context.colorMask( true, true, true, true );
|
||||||
|
context.depthMask( true );
|
||||||
|
|
||||||
|
// only render where stencil is set to 1
|
||||||
|
|
||||||
|
context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
|
||||||
|
context.stencilOp( context.KEEP, context.KEEP, context.KEEP );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var ClearMaskPass = function () {
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ClearMaskPass.prototype = {
|
||||||
|
|
||||||
|
render: function ( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
var context = renderer.context;
|
||||||
|
|
||||||
|
context.disable( context.STENCIL_TEST );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MaskPass;
|
||||||
|
export {ClearMaskPass as ClearMaskPass};
|
||||||
|
|
||||||
|
THREE.MaskPass = MaskPass;
|
||||||
|
THREE.ClearMaskPass = ClearMaskPass;
|
|
@ -0,0 +1,78 @@
|
||||||
|
// jscs:disable
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import THREE from 'three';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
var ShaderPass = function( shader, textureID ) {
|
||||||
|
|
||||||
|
this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse";
|
||||||
|
|
||||||
|
if ( shader instanceof THREE.ShaderMaterial ) {
|
||||||
|
|
||||||
|
this.uniforms = shader.uniforms;
|
||||||
|
|
||||||
|
this.material = shader;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ( shader ) {
|
||||||
|
|
||||||
|
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
||||||
|
|
||||||
|
this.material = new THREE.ShaderMaterial( {
|
||||||
|
|
||||||
|
defines: shader.defines || {},
|
||||||
|
uniforms: this.uniforms,
|
||||||
|
vertexShader: shader.vertexShader,
|
||||||
|
fragmentShader: shader.fragmentShader
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderToScreen = false;
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
this.needsSwap = true;
|
||||||
|
this.clear = false;
|
||||||
|
|
||||||
|
|
||||||
|
this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
||||||
|
this.scene = new THREE.Scene();
|
||||||
|
|
||||||
|
this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
|
||||||
|
this.scene.add( this.quad );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ShaderPass.prototype = {
|
||||||
|
|
||||||
|
render: function( renderer, writeBuffer, readBuffer, delta ) {
|
||||||
|
|
||||||
|
if ( this.uniforms[ this.textureID ] ) {
|
||||||
|
|
||||||
|
this.uniforms[ this.textureID ].value = readBuffer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.quad.material = this.material;
|
||||||
|
|
||||||
|
if ( this.renderToScreen ) {
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
renderer.render( this.scene, this.camera, writeBuffer, this.clear );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ShaderPass;
|
||||||
|
THREE.ShaderPass = ShaderPass;
|
|
@ -0,0 +1,150 @@
|
||||||
|
// jscs:disable
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import THREE from 'three';
|
||||||
|
import CopyShader from './CopyShader';
|
||||||
|
import ShaderPass from './ShaderPass';
|
||||||
|
import MaskPass, {ClearMaskPass} from './MaskPass';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alteredq / http://alteredqualia.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
var EffectComposer = function ( renderer, renderTarget ) {
|
||||||
|
|
||||||
|
this.renderer = renderer;
|
||||||
|
|
||||||
|
if ( renderTarget === undefined ) {
|
||||||
|
|
||||||
|
var pixelRatio = renderer.getPixelRatio();
|
||||||
|
|
||||||
|
var width = Math.floor( renderer.context.canvas.width / pixelRatio ) || 1;
|
||||||
|
var height = Math.floor( renderer.context.canvas.height / pixelRatio ) || 1;
|
||||||
|
var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };
|
||||||
|
|
||||||
|
renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderTarget1 = renderTarget;
|
||||||
|
this.renderTarget2 = renderTarget.clone();
|
||||||
|
|
||||||
|
this.writeBuffer = this.renderTarget1;
|
||||||
|
this.readBuffer = this.renderTarget2;
|
||||||
|
|
||||||
|
this.passes = [];
|
||||||
|
|
||||||
|
if ( CopyShader === undefined )
|
||||||
|
console.error( "EffectComposer relies on THREE.CopyShader" );
|
||||||
|
|
||||||
|
this.copyPass = new ShaderPass( CopyShader );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EffectComposer.prototype = {
|
||||||
|
|
||||||
|
swapBuffers: function() {
|
||||||
|
|
||||||
|
var tmp = this.readBuffer;
|
||||||
|
this.readBuffer = this.writeBuffer;
|
||||||
|
this.writeBuffer = tmp;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
addPass: function ( pass ) {
|
||||||
|
|
||||||
|
this.passes.push( pass );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
insertPass: function ( pass, index ) {
|
||||||
|
|
||||||
|
this.passes.splice( index, 0, pass );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function ( delta ) {
|
||||||
|
|
||||||
|
this.writeBuffer = this.renderTarget1;
|
||||||
|
this.readBuffer = this.renderTarget2;
|
||||||
|
|
||||||
|
var maskActive = false;
|
||||||
|
|
||||||
|
var pass, i, il = this.passes.length;
|
||||||
|
|
||||||
|
for ( i = 0; i < il; i ++ ) {
|
||||||
|
|
||||||
|
pass = this.passes[ i ];
|
||||||
|
|
||||||
|
if ( ! pass.enabled ) continue;
|
||||||
|
|
||||||
|
pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );
|
||||||
|
|
||||||
|
if ( pass.needsSwap ) {
|
||||||
|
|
||||||
|
if ( maskActive ) {
|
||||||
|
|
||||||
|
var context = this.renderer.context;
|
||||||
|
|
||||||
|
context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
|
||||||
|
|
||||||
|
this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );
|
||||||
|
|
||||||
|
context.stencilFunc( context.EQUAL, 1, 0xffffffff );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.swapBuffers();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pass instanceof MaskPass ) {
|
||||||
|
|
||||||
|
maskActive = true;
|
||||||
|
|
||||||
|
} else if ( pass instanceof ClearMaskPass ) {
|
||||||
|
|
||||||
|
maskActive = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function ( renderTarget ) {
|
||||||
|
|
||||||
|
if ( renderTarget === undefined ) {
|
||||||
|
|
||||||
|
renderTarget = this.renderTarget1.clone();
|
||||||
|
|
||||||
|
var pixelRatio = this.renderer.getPixelRatio();
|
||||||
|
|
||||||
|
renderTarget.setSize(
|
||||||
|
Math.floor( this.renderer.context.canvas.width / pixelRatio ),
|
||||||
|
Math.floor( this.renderer.context.canvas.height / pixelRatio )
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderTarget1.dispose();
|
||||||
|
this.renderTarget1 = renderTarget;
|
||||||
|
this.renderTarget2.dispose();
|
||||||
|
this.renderTarget2 = renderTarget.clone();
|
||||||
|
|
||||||
|
this.writeBuffer = this.renderTarget1;
|
||||||
|
this.readBuffer = this.renderTarget2;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
setSize: function ( width, height ) {
|
||||||
|
|
||||||
|
this.renderTarget1.setSize( width, height );
|
||||||
|
this.renderTarget2.setSize( width, height );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EffectComposer;
|
||||||
|
THREE.EffectComposer = EffectComposer;
|
|
@ -45,6 +45,10 @@ export default class Source extends Base {
|
||||||
});
|
});
|
||||||
this._transforms = trans;
|
this._transforms = trans;
|
||||||
}
|
}
|
||||||
|
transform(option) {
|
||||||
|
const data = getTransform(option.type)(this.data, option);
|
||||||
|
Object.assign(this.data, data);
|
||||||
|
}
|
||||||
_projectCoords() {
|
_projectCoords() {
|
||||||
this.data.dataArray.forEach(data => {
|
this.data.dataArray.forEach(data => {
|
||||||
// data.coordinates = this._coordProject(data.coordinates);
|
// data.coordinates = this._coordProject(data.coordinates);
|
||||||
|
@ -54,6 +58,7 @@ export default class Source extends Base {
|
||||||
createScale(field) {
|
createScale(field) {
|
||||||
const data = this.data.dataArray;
|
const data = this.data.dataArray;
|
||||||
const scales = this.get('scales');
|
const scales = this.get('scales');
|
||||||
|
console.log(scales);
|
||||||
let scale = scales[field];
|
let scale = scales[field];
|
||||||
const scaleController = this.get('scaleController');
|
const scaleController = this.get('scaleController');
|
||||||
if (!scale) {
|
if (!scale) {
|
||||||
|
|
|
@ -23,7 +23,8 @@ export function HeatmapColorizeMaterial(opt) {
|
||||||
const material = new Material({
|
const material = new Material({
|
||||||
uniforms: {
|
uniforms: {
|
||||||
u_texture: { value: opt.texture },
|
u_texture: { value: opt.texture },
|
||||||
u_colorRamp: { value: opt.colorRamp }
|
u_colorRamp: { value: opt.colorRamp },
|
||||||
|
u_opacity: { value: opt.opacity }
|
||||||
},
|
},
|
||||||
vertexShader: vs,
|
vertexShader: vs,
|
||||||
fragmentShader: fs,
|
fragmentShader: fs,
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
uniform sampler2D u_texture;
|
uniform sampler2D u_texture;
|
||||||
uniform sampler2D u_colorRamp;
|
uniform sampler2D u_colorRamp;
|
||||||
|
uniform float u_opacity;
|
||||||
varying vec2 v_uv;
|
varying vec2 v_uv;
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
float intensity = texture2D(u_texture,v_uv).r;
|
float intensity = texture2D(u_texture,v_uv).r;
|
||||||
vec4 color = texture2D(u_colorRamp,vec2(0.5,1.0-intensity));
|
vec4 color = texture2D(u_colorRamp,vec2(0.5,1.0-intensity));
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
gl_FragColor.a = color.a * smoothstep(0.,0.05,intensity);
|
gl_FragColor.a = color.a * smoothstep(0.,0.05,intensity) * u_opacity;
|
||||||
|
|
||||||
}
|
}
|
|
@ -84,10 +84,12 @@ export function updateIntensityPass(layer) {
|
||||||
|
|
||||||
function createColorizePass(layer, bbox) {
|
function createColorizePass(layer, bbox) {
|
||||||
// create plane geometry
|
// create plane geometry
|
||||||
|
const style = layer.get('styleOptions');
|
||||||
const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height);
|
const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height);
|
||||||
const material = new HeatmapColorizeMaterial({
|
const material = new HeatmapColorizeMaterial({
|
||||||
texture: layer.intensityPass.texture,
|
texture: layer.intensityPass.texture,
|
||||||
colorRamp: layer.colorRamp
|
colorRamp: layer.colorRamp,
|
||||||
|
opacity: style.opacity
|
||||||
});
|
});
|
||||||
const mesh = new THREE.Mesh(geometery, material);
|
const mesh = new THREE.Mesh(geometery, material);
|
||||||
mesh.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 0.0);
|
mesh.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 0.0);
|
||||||
|
|
|
@ -129,6 +129,10 @@ export default class GaodeMap extends Base {
|
||||||
scene.setZoom = zoom => {
|
scene.setZoom = zoom => {
|
||||||
return map.setZoom(zoom);
|
return map.setZoom(zoom);
|
||||||
};
|
};
|
||||||
|
scene.setZoomAndCenter = (zoom, center) => {
|
||||||
|
const lnglat = new AMap.LngLat(center[0], center[1]);
|
||||||
|
return map.setZoomAndCenter(zoom, lnglat);
|
||||||
|
};
|
||||||
scene.setBounds = extent => {
|
scene.setBounds = extent => {
|
||||||
return map.setBounds(new AMap.Bounds([ extent[0], extent[1] ], [ extent[2], extent[3] ]));
|
return map.setBounds(new AMap.Bounds([ extent[0], extent[1] ], [ extent[2], extent[3] ]));
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import Supercluster from 'supercluster';
|
||||||
|
export function cluster(data, option) {
|
||||||
|
const { radius = 40, maxZoom = 16, minZoom = 0, field, zoom = 2 } = option;
|
||||||
|
if (data.pointIndex) {
|
||||||
|
const clusterPoint = data.pointIndex.getClusters(data.extent, zoom);
|
||||||
|
data.dataArray = formatData(clusterPoint);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
const pointIndex = new Supercluster({
|
||||||
|
radius,
|
||||||
|
minZoom,
|
||||||
|
maxZoom,
|
||||||
|
map: props => ({ sum: props[field] }),
|
||||||
|
reduce: (accumulated, props) => { accumulated.sum += props.sum; }
|
||||||
|
});
|
||||||
|
const geojson = {
|
||||||
|
type: 'FeatureCollection'
|
||||||
|
};
|
||||||
|
geojson.features = data.dataArray.map(item => {
|
||||||
|
return {
|
||||||
|
type: 'Feature',
|
||||||
|
properties: {
|
||||||
|
[field]: item[field]
|
||||||
|
},
|
||||||
|
geometry: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: item.coordinates
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
pointIndex.load(geojson.features);
|
||||||
|
const clusterPoint = pointIndex.getClusters(data.extent, zoom);
|
||||||
|
const resultData = clusterPoint.map((point, index) => {
|
||||||
|
return {
|
||||||
|
coordinates: point.geometry.coordinates,
|
||||||
|
_id: index + 1,
|
||||||
|
...point.properties
|
||||||
|
};
|
||||||
|
});
|
||||||
|
data.dataArray = resultData;
|
||||||
|
data.pointIndex = pointIndex;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
function formatData(clusterPoint) {
|
||||||
|
return clusterPoint.map((point, index) => {
|
||||||
|
return {
|
||||||
|
coordinates: point.geometry.coordinates,
|
||||||
|
_id: index + 1,
|
||||||
|
...point.properties
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import { pointData } from '../../../asset/data/point';
|
||||||
|
import { cluster } from '../../../../src/source/transform/cluster';
|
||||||
|
describe('hexagon Test', function() {
|
||||||
|
|
||||||
|
it('pointToCuster', function() {
|
||||||
|
const dataArray = pointData.map(item => {
|
||||||
|
const lng = 1e-6 * (250 * item.grid_x + 125),
|
||||||
|
lat = 1e-6 * (250 * item.grid_y + 125);
|
||||||
|
return {
|
||||||
|
v: item.count * 1,
|
||||||
|
coordinates: [ lng, lat ]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
dataArray,
|
||||||
|
extent: [ -180, -85, 180, 85 ]
|
||||||
|
};
|
||||||
|
console.time('cluster');
|
||||||
|
const grid = cluster(data, { radius: 40, field: 'v', zoom: 13 });
|
||||||
|
console.log(grid);
|
||||||
|
console.timeEnd('cluster');
|
||||||
|
expect(grid.dataArray.length).eql(26);
|
||||||
|
console.time('cluster');
|
||||||
|
cluster(data, {zoom:14});
|
||||||
|
console.timeEnd('cluster');
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue