diff --git a/demos/vectorTile.html b/demos/vectorTile.html
new file mode 100644
index 0000000000..40b4957717
--- /dev/null
+++ b/demos/vectorTile.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+ hexagon demo
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
index 43486efeb6..7721ec43f6 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@antv/l7",
- "version": "1.1.10",
+ "version": "1.1.11",
"description": "Large-scale WebGL-powered Geospatial Data Visualization",
"main": "build/l7.js",
"browser": "build/l7.js",
diff --git a/src/core/engine/index.js b/src/core/engine/index.js
index 9f04690f43..03ae64af2a 100644
--- a/src/core/engine/index.js
+++ b/src/core/engine/index.js
@@ -24,11 +24,14 @@ export default class Engine extends EventEmitter {
});
}
update() {
+ this._renderer.clear();
this._renderer.render(this._scene, this._camera);
this._initPostProcessing();
}
destroy() {
-
+ }
+ renderScene(scene) {
+ this._renderer.render(scene, this._camera);
}
run() {
this.update();
diff --git a/src/core/engine/renderer.js b/src/core/engine/renderer.js
index fd4d64a6d5..4607a8fe3b 100644
--- a/src/core/engine/renderer.js
+++ b/src/core/engine/renderer.js
@@ -9,7 +9,8 @@ export default class Renderer {
initRender() {
this.renderer = new THREE.WebGLRenderer({
antialias: true,
- alpha: true
+ alpha: true,
+ autoClear: false
});
this.renderer.setClearColor(0xff0000, 0.0);
this.pixelRatio = window.devicePixelRatio;
diff --git a/src/core/layer.js b/src/core/layer.js
index 9523aa21eb..0cac7b1228 100644
--- a/src/core/layer.js
+++ b/src/core/layer.js
@@ -309,7 +309,7 @@ export default class Layer extends Base {
}
createScale(field) {
- const data = this.layerSource.data.dataArray;
+ const data = this.layerSource ? this.layerSource.data.dataArray : null;
const scales = this.get('scales');
let scale = scales[field];
const scaleController = this.get('scaleController');
@@ -404,7 +404,7 @@ export default class Layer extends Base {
const nextAttrs = this.get('attrOptions');
const preStyle = this.get('preStyleOption');
const nextStyle = this.get('styleOptions');
- if (preAttrs === undefined && preStyle === undefined) {
+ if (preAttrs === undefined && preStyle === undefined) { // 首次渲染
this._mapping();
this._setPreOption();
this._scaleByZoom();
@@ -490,12 +490,13 @@ export default class Layer extends Base {
this.layerMesh.material.updateUninform(newOption);
}
- _mapping() {
+ _mapping(source) {
const self = this;
const attrs = self.get('attrs');
const mappedData = [];
// const data = this.layerSource.propertiesData;
- const data = this.layerSource.data.dataArray;
+ let data;
+ source ? data = source.data.dataArray : data = this.layerSource.data.dataArray;
for (let i = 0; i < data.length; i++) {
const record = data[i];
const newRecord = {};
@@ -528,14 +529,16 @@ export default class Layer extends Base {
});
}
this.layerData = mappedData;
+ return mappedData;
}
// 更新地图映射
- _updateMaping() {
+ _updateMaping(source, layer) {
const self = this;
const attrs = self.get('attrs');
- const data = this.layerSource.data.dataArray;
+ const data = source ? source.data.dataArray : this.layerSource.data.dataArray;
+ const layerData = layer || this.layerData;
for (let i = 0; i < data.length; i++) {
const record = data[i];
for (const attrName in attrs) {
@@ -547,10 +550,10 @@ export default class Layer extends Base {
for (let j = 0; j < values.length; j++) {
const val = values[j];
const name = names[j];
- this.layerData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
+ layerData[i][name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
}
} else {
- this.layerData[i][names[0]] = values.length === 1 ? values[0] : values;
+ layerData[i][names[0]] = values.length === 1 ? values[0] : values;
}
attr.neadUpdate = true;
@@ -668,6 +671,7 @@ export default class Layer extends Base {
pickAttr.needsUpdate = true;
}
_visibleWithZoom() {
+ if (this._object3D === null) return;
const zoom = this.scene.getZoom();
const minZoom = this.get('minZoom');
const maxZoom = this.get('maxZoom');
@@ -751,7 +755,6 @@ export default class Layer extends Base {
this.clearMapEvent();
if (this._object3D.type === 'composer') {
this.remove(this._object3D);
-
return;
}
if (this._object3D && this._object3D.children) {
@@ -778,8 +781,19 @@ export default class Layer extends Base {
child = null;
}
}
+ this.layerMesh.geometry = null;
+ this.layerMesh.material.dispose();
+ this.layerMesh.material = null;
+ if (this._pickingMesh) {
+ this._pickingMesh.children[0].geometry = null;
+ this._pickingMesh.children[0].material.dispose();
+ this._pickingMesh.children[0].material = null;
+ }
+ this._buffer = null;
this._object3D = null;
this.scene._engine._scene.remove(this._object3D);
+ this.layerData.length = 0;
+ this.layerSource = null;
this.scene._engine._picking.remove(this._pickingMesh);
this.destroyed = true;
}
diff --git a/src/core/scene.js b/src/core/scene.js
index 0789516806..b83e20fb99 100644
--- a/src/core/scene.js
+++ b/src/core/scene.js
@@ -25,7 +25,8 @@ export default class Scene extends Base {
_initEngine(mapContainer) {
this._engine = new Engine(mapContainer, this);
- this.registerMapEvent();
+ // this.registerMapEvent();
+ this._engine.run();
// this.workerPool = new WorkerPool();
compileBuiltinModules();
}
@@ -73,7 +74,6 @@ export default class Scene extends Base {
}
off(type, hander) {
if (this.map) { this.map.off(type, hander); }
-
super.off(type, hander);
}
addImage() {
diff --git a/src/geom/buffer/line.js b/src/geom/buffer/line.js
index b86dac7895..ab6a47d22e 100644
--- a/src/geom/buffer/line.js
+++ b/src/geom/buffer/line.js
@@ -87,6 +87,7 @@ export default class LineBuffer extends BufferBase {
layerData.forEach(item => {
const props = item;
const positionCount = positions.length / 3;
+ // TODO 处理多个线段的情况
const attr = lineShape.Line(item.coordinates, props, positionCount, (lineType !== 'soild'));
positions.push(...attr.positions);
normal.push(...attr.normal);
diff --git a/src/geom/material/heatmapMateial.js b/src/geom/material/heatmapMaterial.js
similarity index 100%
rename from src/geom/material/heatmapMateial.js
rename to src/geom/material/heatmapMaterial.js
diff --git a/src/geom/material/tile/maskMaterial.js b/src/geom/material/tile/maskMaterial.js
new file mode 100644
index 0000000000..36ddd9e098
--- /dev/null
+++ b/src/geom/material/tile/maskMaterial.js
@@ -0,0 +1,24 @@
+import Material from './../material';
+import { getModule } from '../../../util/shaderModule';
+export default class MaskMaterial extends Material {
+ getDefaultParameters() {
+ return {
+ uniforms: {
+ },
+ defines: {
+
+ }
+ };
+ }
+ constructor(_uniforms, _defines, parameters) {
+ super(parameters);
+ const { uniforms, defines } = this.getDefaultParameters();
+ const { vs, fs } = getModule('mask_quard');
+ this.uniforms = Object.assign(uniforms, this.setUniform(_uniforms));
+ this.type = 'MaskMaterial';
+ this.defines = Object.assign(defines, _defines);
+ this.vertexShader = vs;
+ this.fragmentShader = fs;
+ this.transparent = true;
+ }
+}
diff --git a/src/geom/shader/index.js b/src/geom/shader/index.js
index 0962214754..e67e880d91 100644
--- a/src/geom/shader/index.js
+++ b/src/geom/shader/index.js
@@ -45,6 +45,11 @@ import raster_frag from '../shader/raster_frag.glsl';
import tile_polygon_vert from '../shader/tile/polygon_vert.glsl';
import tile_polygon_frag from '../shader/tile/polygon_frag.glsl';
+// mask
+import mask_quard_vert from '../shader/tile/mask_quard_vert.glsl';
+import mask_quard_frag from '../shader/tile/mask_quard_frag.glsl';
+
+
import common from './common.glsl';
import { registerModule } from '../../util/shaderModule';
import pick_color from './shaderChunks/pick_color.glsl';
@@ -65,5 +70,6 @@ export function compileBuiltinModules() {
registerModule('image', { vs: image_vert, fs: image_frag });
registerModule('raster', { vs: raster_vert, fs: raster_frag });
registerModule('tilepolygon', { vs: tile_polygon_vert, fs: tile_polygon_frag });
+ registerModule('mask_quard', { vs: mask_quard_vert, fs: mask_quard_frag });
}
diff --git a/src/geom/shader/tile/mask_quard_frag.glsl b/src/geom/shader/tile/mask_quard_frag.glsl
new file mode 100644
index 0000000000..6b4ceede8f
--- /dev/null
+++ b/src/geom/shader/tile/mask_quard_frag.glsl
@@ -0,0 +1,4 @@
+ precision highp float;
+ void main() {
+ gl_FragColor = vec4(1.0);
+}
\ No newline at end of file
diff --git a/src/geom/shader/tile/mask_quard_vert.glsl b/src/geom/shader/tile/mask_quard_vert.glsl
new file mode 100644
index 0000000000..b8988414c9
--- /dev/null
+++ b/src/geom/shader/tile/mask_quard_vert.glsl
@@ -0,0 +1,6 @@
+precision highp float;
+void main(){
+ mat4 matModelViewProjection=projectionMatrix*modelViewMatrix;
+ gl_Position = matModelViewProjection * vec4(position, 1.0);
+
+}
\ No newline at end of file
diff --git a/src/geom/shape/line.js b/src/geom/shape/line.js
index f171c1f86c..ab266ba861 100644
--- a/src/geom/shape/line.js
+++ b/src/geom/shape/line.js
@@ -65,7 +65,10 @@ export function defaultLine(geo, index) {
}
// mesh line
export function Line(path, props, positionsIndex) {
- if (path.length === 1) path = path[0];// 面坐标转线坐标
+ // 区分path是面还是线
+ if (Array.isArray(path[0][0])) {
+ path = path[0]; // 面坐标转线坐标
+ }
const positions = [];
const pickingIds = [];
const normal = [];
@@ -77,7 +80,8 @@ export function Line(path, props, positionsIndex) {
const sizes = [];
let c = 0;
let index = positionsIndex;
- const { size, color, id } = props;
+ let { size, color, id } = props;
+ !Array.isArray(size) && (size = [ size ]);
path.forEach((point, pointIndex, list) => {
const i = index;
colors.push(...color);
diff --git a/src/global.js b/src/global.js
index f33666f102..b6f5e5341e 100644
--- a/src/global.js
+++ b/src/global.js
@@ -5,7 +5,7 @@
// const Global = {};
const FONT_FAMILY = '"-apple-system", BlinkMacSystemFont, "Segoe UI", Roboto,"Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",SimSun, "sans-serif"';
const Global = {
- version: '1.0.0',
+ version: '1.11.1',
scene: {
mapType: 'AMAP',
zoom: 5,
diff --git a/src/layer/index.js b/src/layer/index.js
index 8b33d8534e..04c572c984 100644
--- a/src/layer/index.js
+++ b/src/layer/index.js
@@ -7,6 +7,7 @@ import RasterLayer from './rasterLayer';
import HeatmapLayer from './heatmapLayer';
import TileLayer from './tile/tileLayer';
import ImageTileLayer from './tile/imageTileLayer';
+import VectorTileLayer from './tile/VectorTileLayer';
registerLayer('PolygonLayer', PolygonLayer);
registerLayer('PointLayer', PointLayer);
@@ -16,7 +17,8 @@ registerLayer('RasterLayer', RasterLayer);
registerLayer('HeatmapLayer', HeatmapLayer);
registerLayer('TileLayer', TileLayer);
registerLayer('ImageTileLayer', ImageTileLayer);
+registerLayer('VectorTileLayer', VectorTileLayer);
-export { LAYER_MAP } from './factory';
+export { LAYER_MAP, getLayer } from './factory';
export { registerLayer };
diff --git a/src/layer/lineLayer.js b/src/layer/lineLayer.js
index 4a2046686e..be0bef02c8 100644
--- a/src/layer/lineLayer.js
+++ b/src/layer/lineLayer.js
@@ -39,7 +39,7 @@ export default class LineLayer extends Layer {
if (this.shapeType === 'arc') {
DrawArc(attributes, layerCfg, this);
} else {
- DrawLine(attributes, layerCfg, this);
+ this.add(DrawLine(attributes, layerCfg, this));
}
}
}
diff --git a/src/layer/render/heatmap/heatmap.js b/src/layer/render/heatmap/heatmap.js
index c03d7f9b46..2a5bf555d5 100644
--- a/src/layer/render/heatmap/heatmap.js
+++ b/src/layer/render/heatmap/heatmap.js
@@ -1,6 +1,6 @@
import HeatmapBuffer from '../../../geom/buffer/heatmap/heatmap';
import { createColorRamp } from '../../../geom/buffer/heatmap/heatmap';
-import { HeatmapIntensityMaterial, HeatmapColorizeMaterial } from '../../../geom/material/heatmapMateial';
+import { HeatmapIntensityMaterial, HeatmapColorizeMaterial } from '../../../geom/material/heatmapMaterial';
// import Renderpass from '../../../core/engine/renderpass.bak';
import RenderPass from '../../../core/engine/render-pass';
import ShaderPass from '../../../core/engine/shader-pass';
diff --git a/src/layer/render/line/drawMeshLine.js b/src/layer/render/line/drawMeshLine.js
index 37eaf2ad25..85da3b91b6 100644
--- a/src/layer/render/line/drawMeshLine.js
+++ b/src/layer/render/line/drawMeshLine.js
@@ -40,5 +40,5 @@ export default function DrawLine(attributes, cfg, layer) {
});
lineMaterial.setDefinesvalue('ANIMATE', true);
}
- layer.add(lineMesh);
+ return lineMesh;
}
diff --git a/src/layer/tile/VectorTileLayer.js b/src/layer/tile/VectorTileLayer.js
new file mode 100644
index 0000000000..73258a6e40
--- /dev/null
+++ b/src/layer/tile/VectorTileLayer.js
@@ -0,0 +1,7 @@
+import TileLayer from './tileLayer';
+import VectorTile from './vectorTile';
+export default class VectorTileLayer extends TileLayer {
+ _createTile(key, layer) {
+ return new VectorTile(key, this.url, layer);
+ }
+}
diff --git a/src/layer/tile/imageTile.js b/src/layer/tile/imageTile.js
index d30e336385..563c65c933 100644
--- a/src/layer/tile/imageTile.js
+++ b/src/layer/tile/imageTile.js
@@ -23,7 +23,7 @@ export default class ImageTile extends Tile {
const image = document.createElement('img');
image.addEventListener('load', () => {
-
+ this._isLoaded = true;
this._createMesh(image);
this._ready = true;
}, false);
@@ -58,8 +58,8 @@ export default class ImageTile extends Tile {
buffer.attributes.texture = buffer.texture;
const style = this.layer.get('styleOptions');
const mesh = DrawImage(buffer.attributes, style);
- this.Object3D.add(mesh);
- return this.Object3D;
+ this._object3D.add(mesh);
+ return this._object3D;
}
_abortRequest() {
if (!this._image) {
diff --git a/src/layer/tile/tile.js b/src/layer/tile/tile.js
index 261800150c..87770386f5 100644
--- a/src/layer/tile/tile.js
+++ b/src/layer/tile/tile.js
@@ -1,10 +1,12 @@
import * as THREE from '../../core/three';
+import EventEmitter from 'wolfy87-eventemitter';
import { toLngLatBounds, toBounds } from '@antv/geo-coord';
const r2d = 180 / Math.PI;
const tileURLRegex = /\{([zxy])\}/g;
-export default class Tile {
+export default class Tile extends EventEmitter {
constructor(key, url, layer) {
+ super();
this.layer = layer;
this._tile = key.split('_').map(v => v * 1);
this._path = url;
@@ -15,7 +17,10 @@ export default class Tile {
this._center = this._tileBounds.getCenter();
this._centerLnglat = this._tileLnglatBounds.getCenter();
- this.Object3D = new THREE.Object3D();
+ this._object3D = new THREE.Object3D();
+ this._object3D.onBeforeRender = () => {
+ };
+ this._isLoaded = false;
this.requestTileAsync();
@@ -34,12 +39,12 @@ export default class Tile {
}
// 经纬度范围转瓦片范围
_tileBounds(lnglatBound) {
- const ne = this.layer.scene.project([ lnglatBound.getNorthWest().lng, lnglatBound.getNorthEast().lat ]);
- const sw = this.layer.scene.project([ lnglatBound.getSouthEast().lng, lnglatBound.getSouthWest().lat ]);
+ const ne = this.layer.scene.project([ lnglatBound.getNorthEast().lng, lnglatBound.getNorthEast().lat ]);
+ const sw = this.layer.scene.project([ lnglatBound.getSouthWest().lng, lnglatBound.getSouthWest().lat ]);
return toBounds(sw, ne);
}
getMesh() {
- return this.Object3D;
+ return this._object3D;
}
@@ -60,6 +65,8 @@ export default class Tile {
const n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
}
+ _preRender() {
+ }
destroy() {
if (this._object3D && this._object3D.children) {
let child;
diff --git a/src/layer/tile/tileLayer.js b/src/layer/tile/tileLayer.js
index a3bc44afc9..2182e95ed6 100644
--- a/src/layer/tile/tileLayer.js
+++ b/src/layer/tile/tileLayer.js
@@ -1,5 +1,7 @@
import Layer from '../../core/layer';
+import source from '../../core/source';
import * as THREE from '../../core/three';
+import Util from '../../util';
import TileCache from './tileCache';
import { throttle } from '@antv/util';
import { toLngLat } from '@antv/geo-coord';
@@ -12,16 +14,28 @@ export default class TileLayer extends Layer {
this._tiles = new THREE.Object3D();
this._tileKeys = [];
this.tileList = [];
-
-
}
- source(url) {
+ source(url, cfg = {}) {
this.url = url;
+ this.sourceCfg = cfg;
return this;
}
+ tileSource(data) {
+ super.source(data, this.sourceCfg);
+ if (data instanceof source) {
+ return data;
+ }
+ this.sourceCfg.data = data;
+ this.sourceCfg.mapType = this.scene.mapType;
+ this.sourceCfg.zoom = this.scene.getZoom();
+ return new source(this.sourceCfg);
+ }
render() {
+ this._initControllers();
this._initMapEvent();
+ this._initAttrs();
this.draw();
+ return this;
}
draw() {
this._object3D.add(this._tiles);
@@ -29,6 +43,44 @@ export default class TileLayer extends Layer {
}
drawTile() {
+ }
+ _mapping(source) {
+
+ const attrs = this.get('attrs');
+ const mappedData = [];
+ // const data = this.layerSource.propertiesData;
+ const data = source.data.dataArray;
+ for (let i = 0; i < data.length; i++) {
+ const record = data[i];
+ const newRecord = {};
+ newRecord.id = data[i]._id;
+ for (const k in attrs) {
+ if (attrs.hasOwnProperty(k)) {
+ const attr = attrs[k];
+ const names = attr.names;
+ const values = this._getAttrValues(attr, record);
+ if (names.length > 1) { // position 之类的生成多个字段的属性
+ for (let j = 0; j < values.length; j++) {
+ const val = values[j];
+ const name = names[j];
+ newRecord[name] = (Util.isArray(val) && val.length === 1) ? val[0] : val; // 只有一个值时返回第一个属性值
+ }
+ } else {
+ newRecord[names[0]] = values.length === 1 ? values[0] : values;
+
+ }
+ }
+ }
+ newRecord.coordinates = record.coordinates;
+ mappedData.push(newRecord);
+ }
+ // 通过透明度过滤数据
+ if (attrs.hasOwnProperty('filter')) {
+ mappedData.forEach(item => {
+ item.filter === false && (item.color[3] = 0);
+ });
+ }
+ return mappedData;
}
zoomchange(ev) {
super.zoomchange(ev);
@@ -56,8 +108,9 @@ export default class TileLayer extends Layer {
// console.log(NW.lng, NW.lat, SE.lng, SE.lat, NWPonint, SEPonint);
let updateTileList = [];
this.tileList = [];
- const halfx = Math.floor((maxXY.x - minXY.x) / 2) + 1;
- const halfy = Math.floor((maxXY.y - minXY.y) / 2) + 1;
+ const halfx = 1;
+ const halfy = 1;
+
if (!(centerPoint.x > NWPoint.x && centerPoint.x < SEPoint.x)) { // 地图循环的问题
for (let i = 0; i < minXY.x; i++) {
for (let j = Math.min(0, minXY.y - halfy); j < Math.max(maxXY.y + halfy, tileCount); j++) {
@@ -90,10 +143,11 @@ export default class TileLayer extends Layer {
});
this._removeOutTiles();
}
+
_updateTileList(updateTileList, x, y, z) {
const key = [ x, y, z ].join('_');
this.tileList.push(key);
- if (this._tileKeys.indexOf(key) === -1) {
+ if (this._tileKeys.indexOf(key) === -1 && updateTileList.indexOf(key) === -1) {
updateTileList.push(key);
}
}
@@ -101,14 +155,21 @@ export default class TileLayer extends Layer {
let tile = this._tileCache.getTile(key);
if (!tile) {
tile = this._createTile(key, layer);
- const mesh = tile.getMesh();
- mesh.name = key;
- this._tileCache.setTile(tile, key);
+ tile.on('tileLoaded', () => {
+ if (this.tileList.indexOf(key) === -1) {
+ return;
+ }
+ const mesh = tile.getMesh();
+ mesh.name = key;
+ this._tileCache.setTile(tile, key);
+ this._tileKeys.push(key);
+ mesh.children.length !== 0 && this._tiles.add(tile.getMesh());
+ this.scene._engine.update();
+ });
+ } else {
+ this._tiles.add(tile.getMesh());
this._tileKeys.push(key);
- // this.scene._engine.update();
}
- this._tiles.add(tile.getMesh());
- this._tileKeys.push(key);
}
// 移除视野外的tile
_removeOutTiles() {
@@ -116,6 +177,8 @@ export default class TileLayer extends Layer {
const tile = this._tiles.children[i];
const key = tile.name;
if (this.tileList.indexOf(key) === -1) {
+ const tileObj = this._tileCache.getTile(key);
+ tileObj && tileObj._abortRequest();
this._tiles.remove(tile);
}
this._tileKeys = [].concat(this.tileList);
diff --git a/src/layer/tile/vectorTile.js b/src/layer/tile/vectorTile.js
new file mode 100644
index 0000000000..30ded2ab04
--- /dev/null
+++ b/src/layer/tile/vectorTile.js
@@ -0,0 +1,141 @@
+import Tile from './tile';
+import { getArrayBuffer } from '../../util/ajax';
+import PBF from 'pbf';
+import * as VectorParser from '@mapbox/vector-tile';
+import * as THREE from '../../core/three';
+import MaskMaterial from '../../geom/material/tile/maskMaterial';
+import { LineBuffer } from '../../geom/buffer/index';
+import DrawLine from '../../layer/render/line/drawMeshLine';
+
+export default class VectorTile extends Tile {
+ 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);
+ this.xhrRequest = getArrayBuffer({ url }, (err, data) => {
+ if (err) {
+ this._noData = true;
+ return;
+ }
+ this._isLoaded = true;
+ this._parserData(data.data);
+ });
+ }
+ _creatSource(data) {
+ this.source = this.layer.tileSource(data);
+ }
+ _parserData(data) {
+ const tile = new VectorParser.VectorTile(new PBF(data));
+ // CHN_Cities_L CHN_Cities CHN_L
+ const layerName = 'county4326';
+ const features = [];
+ const vectorLayer = tile.layers[layerName];
+ for (let i = 0; i < vectorLayer.length; i++) {
+ const feature = vectorLayer.feature(i);
+ features.push(feature.toGeoJSON(this._tile[0], this._tile[1], this._tile[2]));
+ }
+ const geodata = {
+ type: 'FeatureCollection',
+ features
+ };
+ this._creatSource(geodata);
+ this._createMesh();
+ }
+ _createMesh() {
+ this.layerData = this.layer._mapping(this.source);
+ const style = this.layer.get('styleOptions');
+ const buffer = new LineBuffer({
+ layerData: this.layerData,
+ style,
+ shapeType: 'line'
+
+ });
+ const animateOptions = this.layer.get('animateOptions');
+ const activeOption = this.layer.get('activedOptions');
+ const layerCfg = {
+ zoom: this.layer.scene.getZoom(),
+ style,
+ animateOptions,
+ activeOption
+ };
+ this.mesh = new DrawLine(buffer.attributes, layerCfg, this.layer);
+ this.mesh.onBeforeRender = renderer => {
+ this._renderMask(renderer);
+ };
+ this.mesh.onAfterRender = renderer => {
+ const context = renderer.context;
+ context.disable(context.STENCIL_TEST);
+ };
+ this._object3D.add(this.mesh);
+ this.emit('tileLoaded');
+ return this._object3D;
+ }
+ _renderMask(renderer) {
+ const maskScene = new THREE.Scene();
+ this.maskScene = maskScene;
+ const tileMesh = this._tileMaskMesh();
+ maskScene.add(tileMesh);
+ const context = renderer.context;
+ renderer.autoClear = false;
+ renderer.clearDepth();
+ context.enable(context.STENCIL_TEST);
+ context.stencilOp(context.REPLACE, context.REPLACE, context.REPLACE);
+ context.stencilFunc(context.ALWAYS, 1, 0xffffffff);
+ context.clearStencil(0);
+ context.clear(context.STENCIL_BUFFER_BIT);
+ context.colorMask(false, false, false, false);
+
+ // config the stencil buffer to collect data for testing
+ this.layer.scene._engine.renderScene(maskScene);
+ context.colorMask(true, true, true, true);
+ context.depthMask(true);
+ renderer.clearDepth();
+
+ // 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);
+ }
+ _tileMaskMesh() {
+ const tilebound = this._tileBounds;
+ const bl = [ tilebound.getBottomLeft().x, tilebound.getBottomLeft().y, 0 ];
+ const br = [ tilebound.getBottomRight().x, tilebound.getBottomRight().y, 0 ];
+ const tl = [ tilebound.getTopLeft().x, tilebound.getTopLeft().y, 0 ];
+ const tr = [ tilebound.getTopRight().x, tilebound.getTopRight().y, 0 ];
+ const positions = [ ...bl, ...tr, ...br, ...bl, ...tl, ...tr ];
+ const geometry = new THREE.BufferGeometry();
+ geometry.addAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
+ const maskMaterial = new MaskMaterial();
+ const maskMesh = new THREE.Mesh(geometry, maskMaterial);
+ return maskMesh;
+ }
+ _abortRequest() {
+ if (!this.xhrRequest) {
+ return;
+ }
+
+ this.xhrRequest.abort();
+ }
+ destroy() {
+
+ this.mesh.destroy();
+ // if (this.maskScene) {
+ // this.maskScene.children[0].geometry = null;
+ // this.maskScene.children[0].material.dispose();
+ // this.maskScene.children[0].material = null;
+ // }
+ }
+}
diff --git a/src/util/lru-cache.js b/src/util/lru-cache.js
index ab7a78339b..d44c2626dc 100644
--- a/src/util/lru-cache.js
+++ b/src/util/lru-cache.js
@@ -48,10 +48,10 @@ export default class LRUCache {
delete(key) {
const value = this._cache[key];
- this.destroy(value);
if (value) {
this._deleteCache(key);
this._deleteOrder(key);
+ this.destroy(value);
}
}