Skip to content

Commit 7467890

Browse files
authored
add terrain tile mode for TileLayer (#2086)
* initial commit for terrain tile mode * first working commit (seems) * some fixes * restore child tiles searching in none terrain tile mode, which is faster * some fixes for TerrainLayer * ask map to redraw when layer removed * fix * use _tileQueueIds to control whether to consume a tile * always enableVertexAttrib due to fusion.gl's states updates * add enableVertexAttrib in tile debug info drawing * fix layer remove event
1 parent 6ef9b01 commit 7467890

File tree

6 files changed

+383
-116
lines changed

6 files changed

+383
-116
lines changed

src/core/util/util.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export function parseJSON(str) {
109109
export function pushIn(dest) {
110110
for (let i = 1; i < arguments.length; i++) {
111111
const src = arguments[i];
112-
if (src) {
112+
if (src && src.length) {
113113
for (let ii = 0, ll = src.length; ii < ll; ii++) {
114114
dest.push(src[ii]);
115115
}

src/layer/Layer.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,13 @@ class Layer extends JSONAble(Eventable(Renderable(Class))) {
399399
*/
400400
remove() {
401401
if (this.map) {
402+
const renderer = this.map.getRenderer();
402403
this.map.removeLayer(this);
404+
if (renderer) {
405+
renderer.setToRedraw();
406+
}
407+
} else {
408+
this.fire('remove');
403409
}
404410
return this;
405411
}

src/layer/tile/TileLayer.js

Lines changed: 67 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ const options = {
145145
'tileLimitPerFrame': 0,
146146

147147
'tileStackStartDepth': 7,
148-
'tileStackDepth': 3,
148+
'tileStackDepth': 5,
149149

150150
'awareOfTerrain': true,
151151
'bufferPixel': 0.5,
@@ -356,7 +356,7 @@ class TileLayer extends Layer {
356356
z = this._getTileZoom(map.getZoom());
357357
}
358358
const sr = this.getSpatialReference();
359-
const maxZoom = Math.min(z, this.getMaxZoom(), this.options['maxAvailableZoom'] || Infinity);
359+
const maxZoom = Math.min(z, this.getMaxZoom(), this.getMaxAvailableZoom() || Infinity);
360360
const projectionView = map.projViewMatrix;
361361
const fullExtent = this._getTileFullExtent();
362362

@@ -445,18 +445,9 @@ class TileLayer extends Layer {
445445
}
446446

447447
_splitNode(node, projectionView, queue, tiles, gridExtent, maxZoom, offset, parentRenderer, glRes) {
448-
const zoomOffset = this.options['zoomOffset'];
449-
const tileSystem = this._getTileConfig().tileSystem;
450-
const scaleY = tileSystem.scale.y;
451448
const z = node.z + 1;
452449
const sr = this.getSpatialReference();
453-
const { x, y, extent2d, idx, idy } = node;
454-
const childScale = 2;
455-
const width = extent2d.getWidth() / 2 * childScale;
456-
const height = extent2d.getHeight() / 2 * childScale;
457-
const minx = extent2d.xmin * childScale;
458-
const maxy = extent2d.ymax * childScale;
459-
const miny = extent2d.ymin * childScale;
450+
const { idx, idy } = node;
460451

461452
const renderer = parentRenderer || this.getRenderer();
462453

@@ -467,8 +458,6 @@ class TileLayer extends Layer {
467458
for (let i = 0; i < 4; i++) {
468459
const dx = (i % 2);
469460
const dy = (i >> 1);
470-
const childX = (x << 1) + dx;
471-
const childY = (y << 1) + dy;
472461
const childIdx = (idx << 1) + dx;
473462
const childIdy = (idy << 1) + dy;
474463

@@ -482,40 +471,14 @@ class TileLayer extends Layer {
482471
node.children[i] = tileId;
483472
}
484473
const cached = renderer.isTileCachedOrLoading(tileId);
485-
let extent;
486474
let childNode = cached && cached.info;
487475
if (!childNode) {
488476
if (!this.tileInfoCache) {
489477
this.tileInfoCache = new LRUCache(this.options['maxCacheSize'] * 4);
490478
}
491479
childNode = this.tileInfoCache.get(tileId);
492480
if (!childNode) {
493-
if (scaleY < 0) {
494-
const nwx = minx + dx * width;
495-
const nwy = maxy - dy * height;
496-
// extent2d 是 node.z 级别上的 extent
497-
extent = new PointExtent(nwx, nwy - height, nwx + width, nwy);
498-
499-
} else {
500-
const swx = minx + dx * width;
501-
const swy = miny + dy * height;
502-
extent = new PointExtent(swx, swy, swx + width, swy + height);
503-
}
504-
childNode = {
505-
x: childX,
506-
y: childY,
507-
idx: childIdx,
508-
idy: childIdy,
509-
z,
510-
extent2d: extent,
511-
error: node.error / 2,
512-
res,
513-
id: tileId,
514-
children: [],
515-
url: this.getTileUrl(childX, childY, z + zoomOffset),
516-
offset
517-
};
518-
this.tileInfoCache.add(tileId, childNode);
481+
childNode = this._createChildNode(node, dx, dy, offset, tileId);
519482
}
520483
if (parentRenderer) {
521484
childNode['layer'] = this.getId();
@@ -548,7 +511,54 @@ class TileLayer extends Layer {
548511
queue.push(...children);
549512
}
550513

514+
}
515+
516+
_createChildNode(node, dx, dy, offset, tileId) {
517+
const zoomOffset = this.options['zoomOffset'];
518+
const { x, y, idx, idy, extent2d } = node;
519+
const z = node.z + 1;
520+
const childX = (x << 1) + dx;
521+
const childY = (y << 1) + dy;
522+
const childIdx = (idx << 1) + dx;
523+
const childIdy = (idy << 1) + dy;
524+
const childScale = 2;
525+
const width = extent2d.getWidth() / 2 * childScale;
526+
const height = extent2d.getHeight() / 2 * childScale;
527+
const minx = extent2d.xmin * childScale;
528+
const maxy = extent2d.ymax * childScale;
529+
const miny = extent2d.ymin * childScale;
530+
const tileSystem = this._getTileConfig().tileSystem;
531+
const scaleY = tileSystem.scale.y;
532+
tileId = tileId || this._getTileId(childIdx, childIdy, z);
533+
let extent;
534+
if (scaleY < 0) {
535+
const nwx = minx + dx * width;
536+
const nwy = maxy - dy * height;
537+
// extent2d 是 node.z 级别上的 extent
538+
extent = new PointExtent(nwx, nwy - height, nwx + width, nwy);
551539

540+
} else {
541+
const swx = minx + dx * width;
542+
const swy = miny + dy * height;
543+
extent = new PointExtent(swx, swy, swx + width, swy + height);
544+
}
545+
const childNode = {
546+
parent: node.id,
547+
x: childX,
548+
y: childY,
549+
idx: childIdx,
550+
idy: childIdy,
551+
z,
552+
extent2d: extent,
553+
error: node.error / 2,
554+
res: node.res / 2,
555+
id: tileId,
556+
children: [],
557+
url: this.getTileUrl(childX, childY, z + zoomOffset),
558+
offset
559+
};
560+
this.tileInfoCache.add(tileId, childNode);
561+
return childNode;
552562
}
553563

554564
_isTileVisible(node, projectionView, glScale, maxZoom, offset) {
@@ -866,7 +876,7 @@ class TileLayer extends Layer {
866876
const dz = Math.log(res1 / res0) * Math.LOG2E; // polyfill of Math.log2
867877
zoom += dz;
868878
}
869-
const maxZoom = this.options['maxAvailableZoom'];
879+
const maxZoom = this.getMaxAvailableZoom();
870880
if (!isNil(maxZoom) && zoom > maxZoom) {
871881
zoom = maxZoom;
872882
}
@@ -877,6 +887,15 @@ class TileLayer extends Layer {
877887
return zoom;
878888
}
879889

890+
/**
891+
* Get tileLayer's max available zoom, either options['maxAvailableZoom'] or spatialReference's maxZoom
892+
*
893+
* @returns {Number}
894+
**/
895+
getMaxAvailableZoom() {
896+
const sr = this.getSpatialReference();
897+
return this.options['maxAvailableZoom'] || sr && sr.getMaxZoom();
898+
}
880899

881900
_getTiles(tileZoom, containerExtent, cascadeLevel, parentRenderer, ignoreMinZoom) {
882901
// rendWhenReady = false;
@@ -1187,18 +1206,22 @@ class TileLayer extends Layer {
11871206
return tileInfo;
11881207
}
11891208

1190-
_getTileOffset(z) {
1209+
_getTileOffset(...params) {
11911210
// offset result can't be cached, as it varies with map's center.
11921211
let offset = this.options['offset'];
11931212
if (isFunction(offset)) {
1194-
offset = offset.call(this, z);
1213+
offset = offset.call(this, ...params);
11951214
}
11961215
if (isNumber(offset)) {
11971216
offset = [offset, offset];
11981217
}
11991218
return offset || [0, 0];
12001219
}
12011220

1221+
getTileId(x, y, zoom, id) {
1222+
return this._getTileId(x, y, zoom, id);
1223+
}
1224+
12021225
_getTileId(x, y, zoom, id) {
12031226
//id is to mark GroupTileLayer's child layers
12041227
return `${id || this.getId()}_${x}_${y}_${zoom}`;

src/map/Map.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,14 +1292,11 @@ class Map extends Handlerable(Eventable(Renderable(Class))) {
12921292
if (renderer) {
12931293
renderer.setLayerCanvasUpdated();
12941294
}
1295-
removed.forEach(layer => {
1296-
layer.fire('remove');
1295+
this.once('frameend', () => {
1296+
removed.forEach(layer => {
1297+
layer.fire('remove');
1298+
});
12971299
});
1298-
// this.once('frameend', () => {
1299-
// removed.forEach(layer => {
1300-
// layer.fire('remove');
1301-
// });
1302-
// });
13031300
}
13041301
/**
13051302
* removelayer event, fired when removing layers.

src/renderer/layer/ImageGLRenderable.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,11 @@ const ImageGLRenderable = Base => {
133133
v2[1] = 2;
134134
v2[2] = image.glBuffer.type;
135135
this.enableVertexAttrib(v2); // ['a_position', 3]
136-
// gl.bindBuffer(gl.ARRAY_BUFFER, this.texBuffer);
137-
// this.enableVertexAttrib(['a_texCoord', 2, 'UNSIGNED_BYTE']);
136+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texBuffer);
137+
v2[0] = 'a_texCoord';
138+
v2[1] = 2;
139+
v2[2] = 'UNSIGNED_BYTE';
140+
this.enableVertexAttrib(v2);
138141
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
139142

140143
if (debug) {
@@ -189,6 +192,8 @@ const ImageGLRenderable = Base => {
189192
x2, y2
190193
), gl.DYNAMIC_DRAW);
191194
gl.uniform1f(this.program['u_debug_line'], 0);
195+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texBuffer);
196+
this.enableVertexAttrib(['a_texCoord', 2, 'UNSIGNED_BYTE']);
192197
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
193198
gl.enable(gl.DEPTH_TEST);
194199
}

0 commit comments

Comments
 (0)