From 9c14140314efba28d2f3778250c73d5aad65535c Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Mon, 6 May 2019 11:54:32 +0800 Subject: [PATCH] fix tile layer caculate tile lod --- demos/tile.html | 6 ++-- src/core/layer.js | 2 ++ src/layer/tile/imageTileLayer.js | 1 - src/layer/tile/tile.js | 26 +++++++++++++++- src/layer/tile/tileCache.js | 4 +-- src/layer/tile/tileLayer.js | 51 ++++++++++++++++++++++---------- src/util/lru-cache.js | 5 ++-- 7 files changed, 72 insertions(+), 23 deletions(-) diff --git a/demos/tile.html b/demos/tile.html index bfc4552833..b3ac0aaae2 100644 --- a/demos/tile.html +++ b/demos/tile.html @@ -34,7 +34,9 @@ const scene = new L7.Scene({ }); window.scene = scene; scene.on('loaded', () => { - scene.ImageTileLayer() + scene.ImageTileLayer({ + zIndex:0 + }) .source('http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}') .render(); @@ -48,7 +50,7 @@ scene.on('loaded', () => { .color('pm2_5_24h',["#FFF5B8","#FFDC7D","#FFAB5C","#F27049","#D42F31","#730D1C"]) .shape('fill') .style({ - opacity: 0.2 + opacity: 1.0 }) .render(); diff --git a/src/core/layer.js b/src/core/layer.js index 507729b617..9523aa21eb 100644 --- a/src/core/layer.js +++ b/src/core/layer.js @@ -679,6 +679,8 @@ export default class Layer extends Base { } else if (this.type === 'polyline') { offset = 2; + } else if (this.type === 'polygon') { + offset = 1; } this._object3D.position && (this._object3D.position.z = offset * Math.pow(2, 20 - zoom)); if (zoom < minZoom || zoom > maxZoom) { diff --git a/src/layer/tile/imageTileLayer.js b/src/layer/tile/imageTileLayer.js index 5f39e39bf7..5417854b73 100644 --- a/src/layer/tile/imageTileLayer.js +++ b/src/layer/tile/imageTileLayer.js @@ -5,5 +5,4 @@ export default class ImageTileLayer extends TileLayer { _createTile(key, layer) { return new ImageTile(key, this.url, layer); } - } diff --git a/src/layer/tile/tile.js b/src/layer/tile/tile.js index d96c8a69bf..261800150c 100644 --- a/src/layer/tile/tile.js +++ b/src/layer/tile/tile.js @@ -60,7 +60,31 @@ 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))); } - destory() { + destroy() { + if (this._object3D && this._object3D.children) { + let child; + for (let i = 0; i < this._object3D.children.length; i++) { + child = this._object3D.children[i]; + if (!child) { + continue; + } + this.remove(child); + if (child.geometry) { + // child.geometry.dispose(); + child.geometry = null; + } + if (child.material) { + if (child.material.map) { + child.material.map.dispose(); + child.material.map = null; + } + child.material.dispose(); + child.material = null; + } + child = null; + } + } + this._object3D = null; } } diff --git a/src/layer/tile/tileCache.js b/src/layer/tile/tileCache.js index a96260d16d..9681b739f5 100644 --- a/src/layer/tile/tileCache.js +++ b/src/layer/tile/tileCache.js @@ -1,7 +1,7 @@ import LRUCache from '../../util/lru-cache'; export default class TileCache { - constructor(limit = 500) { - this._cache = new LRUCache(limit); + constructor(limit = 50, tileDestroy) { + this._cache = new LRUCache(limit, tileDestroy); } getTile(key) { diff --git a/src/layer/tile/tileLayer.js b/src/layer/tile/tileLayer.js index dde0de7787..a3bc44afc9 100644 --- a/src/layer/tile/tileLayer.js +++ b/src/layer/tile/tileLayer.js @@ -1,12 +1,13 @@ import Layer from '../../core/layer'; import * as THREE from '../../core/three'; import TileCache from './tileCache'; +import { throttle } from '@antv/util'; import { toLngLat } from '@antv/geo-coord'; import { epsg3857 } from '@antv/geo-coord/lib/geo/crs/crs-epsg3857'; export default class TileLayer extends Layer { constructor(scene, cfg) { super(scene, cfg); - this._tileCache = new TileCache(); + this._tileCache = new TileCache(50, this._destroyTile); this._crs = epsg3857; this._tiles = new THREE.Object3D(); this._tileKeys = []; @@ -31,6 +32,7 @@ export default class TileLayer extends Layer { } zoomchange(ev) { super.zoomchange(ev); + throttle(this._calculateLOD, 200); this._calculateLOD(); } dragend(ev) { @@ -43,23 +45,35 @@ export default class TileLayer extends Layer { const SE = viewPort.getSouthEast(); const NW = viewPort.getNorthWest(); const zoom = Math.round(this.scene.getZoom()) - 1; - const NWPonint = this._crs.lngLatToPoint(toLngLat(NW.lng, NW.lat), zoom); - const SEPonint = this._crs.lngLatToPoint(toLngLat(SE.lng, SE.lat), zoom); - const minXY = NWPonint.divideBy(256).round(); - const maxXY = SEPonint.divideBy(256).round(); + const tileCount = Math.pow(2, zoom); + const center = this.scene.getCenter(); + const NWPoint = this._crs.lngLatToPoint(toLngLat(NW.lng, NW.lat), zoom); + const SEPoint = this._crs.lngLatToPoint(toLngLat(SE.lng, SE.lat), zoom); + const centerPoint = this._crs.lngLatToPoint(toLngLat(center.lng, center.lat), zoom); + const centerXY = centerPoint.divideBy(256).round(); + const minXY = NWPoint.divideBy(256).round(); + const maxXY = SEPoint.divideBy(256).round(); // 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; - for (let i = minXY.x - halfx; i < maxXY.x + halfx; i++) { - for (let j = minXY.y - halfy; j < maxXY.y + halfy; j++) { - const key = [ i, j, zoom ].join('_'); - this.tileList.push(key); - if (this._tileKeys.indexOf(key) === -1) { - updateTileList.push(key); + 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++) { + this._updateTileList(updateTileList, i, j, zoom); } } + for (let i = maxXY.x; i < tileCount; i++) { + for (let j = Math.min(0, minXY.y - halfy); j < Math.max(maxXY.y + halfy, tileCount); j++) { + this._updateTileList(updateTileList, i, j, zoom); + } + } + } + for (let i = Math.max(0, minXY.x - halfx); i < Math.min(maxXY.x + halfx, tileCount); i++) { + for (let j = Math.max(0, minXY.y - halfy); j < Math.min(maxXY.y + halfy, tileCount); j++) { + this._updateTileList(updateTileList, i, j, zoom); + } } // 过滤掉已经存在的 // tileList = tileList.filter(tile => { @@ -67,8 +81,8 @@ export default class TileLayer extends Layer { updateTileList = updateTileList.sort((a, b) => { const tile1 = a.split('_'); const tile2 = b.split('_'); - const d1 = Math.pow((tile1[0] - halfx), 2) + Math.pow((tile1[1] - halfy)); - const d2 = Math.pow((tile2[0] - halfy), 2) + Math.pow((tile2[1] - halfy)); + const d1 = Math.pow((tile1[0] * 1 - centerXY.x), 2) + Math.pow((tile1[1] * 1 - centerXY.y), 2); + const d2 = Math.pow((tile2[0] * 1 - centerXY.x), 2) + Math.pow((tile2[1] * 1 - centerXY.y), 2); return d1 - d2; }); updateTileList.forEach(key => { @@ -76,6 +90,13 @@ 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) { + updateTileList.push(key); + } + } _requestTile(key, layer) { let tile = this._tileCache.getTile(key); if (!tile) { @@ -109,8 +130,8 @@ export default class TileLayer extends Layer { this._tiles.remove(this._tiles.children[i]); } } - _destroyTile() { - + _destroyTile(tile) { + tile.destroy(); } desttroy() { } diff --git a/src/util/lru-cache.js b/src/util/lru-cache.js index 8b417e53e2..ab7a78339b 100644 --- a/src/util/lru-cache.js +++ b/src/util/lru-cache.js @@ -6,9 +6,9 @@ */ export default class LRUCache { - constructor(limit = 5) { + constructor(limit = 50, destroy = () => {}) { this.limit = limit; - + this.destroy = destroy; this.clear(); } @@ -48,6 +48,7 @@ export default class LRUCache { delete(key) { const value = this._cache[key]; + this.destroy(value); if (value) { this._deleteCache(key); this._deleteOrder(key);