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;
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();

View File

@ -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) {

View File

@ -5,5 +5,4 @@ export default class ImageTileLayer extends TileLayer {
_createTile(key, 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);
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';
export default class TileCache {
constructor(limit = 500) {
this._cache = new LRUCache(limit);
constructor(limit = 50, tileDestroy) {
this._cache = new LRUCache(limit, tileDestroy);
}
getTile(key) {

View File

@ -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() {
}

View File

@ -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);