fix tile layer caculate tile lod

This commit is contained in:
thinkinggis 2019-05-06 11:54:32 +08:00
parent d5465275a0
commit 9c14140314
7 changed files with 72 additions and 23 deletions

View File

@ -34,7 +34,9 @@ const scene = new L7.Scene({
}); });
window.scene = scene; window.scene = scene;
scene.on('loaded', () => { scene.on('loaded', () => {
scene.ImageTileLayer() scene.ImageTileLayer({
zIndex:0
})
.source('http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}') .source('http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}')
.render(); .render();
@ -48,7 +50,7 @@ scene.on('loaded', () => {
.color('pm2_5_24h',["#FFF5B8","#FFDC7D","#FFAB5C","#F27049","#D42F31","#730D1C"]) .color('pm2_5_24h',["#FFF5B8","#FFDC7D","#FFAB5C","#F27049","#D42F31","#730D1C"])
.shape('fill') .shape('fill')
.style({ .style({
opacity: 0.2 opacity: 1.0
}) })
.render(); .render();

View File

@ -679,6 +679,8 @@ export default class Layer extends Base {
} else if (this.type === 'polyline') { } else if (this.type === 'polyline') {
offset = 2; offset = 2;
} else if (this.type === 'polygon') {
offset = 1;
} }
this._object3D.position && (this._object3D.position.z = offset * Math.pow(2, 20 - zoom)); this._object3D.position && (this._object3D.position.z = offset * Math.pow(2, 20 - zoom));
if (zoom < minZoom || zoom > maxZoom) { if (zoom < minZoom || zoom > maxZoom) {

View File

@ -5,5 +5,4 @@ export default class ImageTileLayer extends TileLayer {
_createTile(key, layer) { _createTile(key, layer) {
return new ImageTile(key, this.url, layer); return new ImageTile(key, this.url, layer);
} }
} }

View File

@ -60,7 +60,31 @@ export default class Tile {
const n = Math.PI - 2 * Math.PI * y / Math.pow(2, 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))); 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;
} }
} }

View File

@ -1,7 +1,7 @@
import LRUCache from '../../util/lru-cache'; import LRUCache from '../../util/lru-cache';
export default class TileCache { export default class TileCache {
constructor(limit = 500) { constructor(limit = 50, tileDestroy) {
this._cache = new LRUCache(limit); this._cache = new LRUCache(limit, tileDestroy);
} }
getTile(key) { getTile(key) {

View File

@ -1,12 +1,13 @@
import Layer from '../../core/layer'; import Layer from '../../core/layer';
import * as THREE from '../../core/three'; import * as THREE from '../../core/three';
import TileCache from './tileCache'; import TileCache from './tileCache';
import { throttle } from '@antv/util';
import { toLngLat } from '@antv/geo-coord'; import { toLngLat } from '@antv/geo-coord';
import { epsg3857 } from '@antv/geo-coord/lib/geo/crs/crs-epsg3857'; import { epsg3857 } from '@antv/geo-coord/lib/geo/crs/crs-epsg3857';
export default class TileLayer extends Layer { export default class TileLayer extends Layer {
constructor(scene, cfg) { constructor(scene, cfg) {
super(scene, cfg); super(scene, cfg);
this._tileCache = new TileCache(); this._tileCache = new TileCache(50, this._destroyTile);
this._crs = epsg3857; this._crs = epsg3857;
this._tiles = new THREE.Object3D(); this._tiles = new THREE.Object3D();
this._tileKeys = []; this._tileKeys = [];
@ -31,6 +32,7 @@ export default class TileLayer extends Layer {
} }
zoomchange(ev) { zoomchange(ev) {
super.zoomchange(ev); super.zoomchange(ev);
throttle(this._calculateLOD, 200);
this._calculateLOD(); this._calculateLOD();
} }
dragend(ev) { dragend(ev) {
@ -43,23 +45,35 @@ export default class TileLayer extends Layer {
const SE = viewPort.getSouthEast(); const SE = viewPort.getSouthEast();
const NW = viewPort.getNorthWest(); const NW = viewPort.getNorthWest();
const zoom = Math.round(this.scene.getZoom()) - 1; const zoom = Math.round(this.scene.getZoom()) - 1;
const NWPonint = this._crs.lngLatToPoint(toLngLat(NW.lng, NW.lat), zoom); const tileCount = Math.pow(2, zoom);
const SEPonint = this._crs.lngLatToPoint(toLngLat(SE.lng, SE.lat), zoom); const center = this.scene.getCenter();
const minXY = NWPonint.divideBy(256).round(); const NWPoint = this._crs.lngLatToPoint(toLngLat(NW.lng, NW.lat), zoom);
const maxXY = SEPonint.divideBy(256).round(); 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); // console.log(NW.lng, NW.lat, SE.lng, SE.lat, NWPonint, SEPonint);
let updateTileList = []; let updateTileList = [];
this.tileList = []; this.tileList = [];
const halfx = Math.floor((maxXY.x - minXY.x) / 2) + 1; const halfx = Math.floor((maxXY.x - minXY.x) / 2) + 1;
const halfy = Math.floor((maxXY.y - minXY.y) / 2) + 1; const halfy = Math.floor((maxXY.y - minXY.y) / 2) + 1;
for (let i = minXY.x - halfx; i < maxXY.x + halfx; i++) { if (!(centerPoint.x > NWPoint.x && centerPoint.x < SEPoint.x)) { // 地图循环的问题
for (let j = minXY.y - halfy; j < maxXY.y + halfy; j++) { for (let i = 0; i < minXY.x; i++) {
const key = [ i, j, zoom ].join('_'); for (let j = Math.min(0, minXY.y - halfy); j < Math.max(maxXY.y + halfy, tileCount); j++) {
this.tileList.push(key); this._updateTileList(updateTileList, i, j, zoom);
if (this._tileKeys.indexOf(key) === -1) {
updateTileList.push(key);
} }
} }
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 => { // tileList = tileList.filter(tile => {
@ -67,8 +81,8 @@ export default class TileLayer extends Layer {
updateTileList = updateTileList.sort((a, b) => { updateTileList = updateTileList.sort((a, b) => {
const tile1 = a.split('_'); const tile1 = a.split('_');
const tile2 = b.split('_'); const tile2 = b.split('_');
const d1 = Math.pow((tile1[0] - halfx), 2) + Math.pow((tile1[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] - halfy), 2) + Math.pow((tile2[1] - halfy)); const d2 = Math.pow((tile2[0] * 1 - centerXY.x), 2) + Math.pow((tile2[1] * 1 - centerXY.y), 2);
return d1 - d2; return d1 - d2;
}); });
updateTileList.forEach(key => { updateTileList.forEach(key => {
@ -76,6 +90,13 @@ export default class TileLayer extends Layer {
}); });
this._removeOutTiles(); 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) { _requestTile(key, layer) {
let tile = this._tileCache.getTile(key); let tile = this._tileCache.getTile(key);
if (!tile) { if (!tile) {
@ -109,8 +130,8 @@ export default class TileLayer extends Layer {
this._tiles.remove(this._tiles.children[i]); this._tiles.remove(this._tiles.children[i]);
} }
} }
_destroyTile() { _destroyTile(tile) {
tile.destroy();
} }
desttroy() { desttroy() {
} }

View File

@ -6,9 +6,9 @@
*/ */
export default class LRUCache { export default class LRUCache {
constructor(limit = 5) { constructor(limit = 50, destroy = () => {}) {
this.limit = limit; this.limit = limit;
this.destroy = destroy;
this.clear(); this.clear();
} }
@ -48,6 +48,7 @@ export default class LRUCache {
delete(key) { delete(key) {
const value = this._cache[key]; const value = this._cache[key];
this.destroy(value);
if (value) { if (value) {
this._deleteCache(key); this._deleteCache(key);
this._deleteOrder(key); this._deleteOrder(key);