Skip to content

Commit

Permalink
add terrain tile mode for TileLayer (#2086)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
fuzhenn authored Oct 4, 2023
1 parent 6ef9b01 commit 7467890
Show file tree
Hide file tree
Showing 6 changed files with 383 additions and 116 deletions.
2 changes: 1 addition & 1 deletion src/core/util/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export function parseJSON(str) {
export function pushIn(dest) {
for (let i = 1; i < arguments.length; i++) {
const src = arguments[i];
if (src) {
if (src && src.length) {
for (let ii = 0, ll = src.length; ii < ll; ii++) {
dest.push(src[ii]);
}
Expand Down
6 changes: 6 additions & 0 deletions src/layer/Layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,13 @@ class Layer extends JSONAble(Eventable(Renderable(Class))) {
*/
remove() {
if (this.map) {
const renderer = this.map.getRenderer();
this.map.removeLayer(this);
if (renderer) {
renderer.setToRedraw();
}
} else {
this.fire('remove');
}
return this;
}
Expand Down
111 changes: 67 additions & 44 deletions src/layer/tile/TileLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ const options = {
'tileLimitPerFrame': 0,

'tileStackStartDepth': 7,
'tileStackDepth': 3,
'tileStackDepth': 5,

'awareOfTerrain': true,
'bufferPixel': 0.5,
Expand Down Expand Up @@ -356,7 +356,7 @@ class TileLayer extends Layer {
z = this._getTileZoom(map.getZoom());
}
const sr = this.getSpatialReference();
const maxZoom = Math.min(z, this.getMaxZoom(), this.options['maxAvailableZoom'] || Infinity);
const maxZoom = Math.min(z, this.getMaxZoom(), this.getMaxAvailableZoom() || Infinity);
const projectionView = map.projViewMatrix;
const fullExtent = this._getTileFullExtent();

Expand Down Expand Up @@ -445,18 +445,9 @@ class TileLayer extends Layer {
}

_splitNode(node, projectionView, queue, tiles, gridExtent, maxZoom, offset, parentRenderer, glRes) {
const zoomOffset = this.options['zoomOffset'];
const tileSystem = this._getTileConfig().tileSystem;
const scaleY = tileSystem.scale.y;
const z = node.z + 1;
const sr = this.getSpatialReference();
const { x, y, extent2d, idx, idy } = node;
const childScale = 2;
const width = extent2d.getWidth() / 2 * childScale;
const height = extent2d.getHeight() / 2 * childScale;
const minx = extent2d.xmin * childScale;
const maxy = extent2d.ymax * childScale;
const miny = extent2d.ymin * childScale;
const { idx, idy } = node;

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

Expand All @@ -467,8 +458,6 @@ class TileLayer extends Layer {
for (let i = 0; i < 4; i++) {
const dx = (i % 2);
const dy = (i >> 1);
const childX = (x << 1) + dx;
const childY = (y << 1) + dy;
const childIdx = (idx << 1) + dx;
const childIdy = (idy << 1) + dy;

Expand All @@ -482,40 +471,14 @@ class TileLayer extends Layer {
node.children[i] = tileId;
}
const cached = renderer.isTileCachedOrLoading(tileId);
let extent;
let childNode = cached && cached.info;
if (!childNode) {
if (!this.tileInfoCache) {
this.tileInfoCache = new LRUCache(this.options['maxCacheSize'] * 4);
}
childNode = this.tileInfoCache.get(tileId);
if (!childNode) {
if (scaleY < 0) {
const nwx = minx + dx * width;
const nwy = maxy - dy * height;
// extent2d 是 node.z 级别上的 extent
extent = new PointExtent(nwx, nwy - height, nwx + width, nwy);

} else {
const swx = minx + dx * width;
const swy = miny + dy * height;
extent = new PointExtent(swx, swy, swx + width, swy + height);
}
childNode = {
x: childX,
y: childY,
idx: childIdx,
idy: childIdy,
z,
extent2d: extent,
error: node.error / 2,
res,
id: tileId,
children: [],
url: this.getTileUrl(childX, childY, z + zoomOffset),
offset
};
this.tileInfoCache.add(tileId, childNode);
childNode = this._createChildNode(node, dx, dy, offset, tileId);
}
if (parentRenderer) {
childNode['layer'] = this.getId();
Expand Down Expand Up @@ -548,7 +511,54 @@ class TileLayer extends Layer {
queue.push(...children);
}

}

_createChildNode(node, dx, dy, offset, tileId) {
const zoomOffset = this.options['zoomOffset'];
const { x, y, idx, idy, extent2d } = node;
const z = node.z + 1;
const childX = (x << 1) + dx;
const childY = (y << 1) + dy;
const childIdx = (idx << 1) + dx;
const childIdy = (idy << 1) + dy;
const childScale = 2;
const width = extent2d.getWidth() / 2 * childScale;
const height = extent2d.getHeight() / 2 * childScale;
const minx = extent2d.xmin * childScale;
const maxy = extent2d.ymax * childScale;
const miny = extent2d.ymin * childScale;
const tileSystem = this._getTileConfig().tileSystem;
const scaleY = tileSystem.scale.y;
tileId = tileId || this._getTileId(childIdx, childIdy, z);
let extent;
if (scaleY < 0) {
const nwx = minx + dx * width;
const nwy = maxy - dy * height;
// extent2d 是 node.z 级别上的 extent
extent = new PointExtent(nwx, nwy - height, nwx + width, nwy);

} else {
const swx = minx + dx * width;
const swy = miny + dy * height;
extent = new PointExtent(swx, swy, swx + width, swy + height);
}
const childNode = {
parent: node.id,
x: childX,
y: childY,
idx: childIdx,
idy: childIdy,
z,
extent2d: extent,
error: node.error / 2,
res: node.res / 2,
id: tileId,
children: [],
url: this.getTileUrl(childX, childY, z + zoomOffset),
offset
};
this.tileInfoCache.add(tileId, childNode);
return childNode;
}

_isTileVisible(node, projectionView, glScale, maxZoom, offset) {
Expand Down Expand Up @@ -866,7 +876,7 @@ class TileLayer extends Layer {
const dz = Math.log(res1 / res0) * Math.LOG2E; // polyfill of Math.log2
zoom += dz;
}
const maxZoom = this.options['maxAvailableZoom'];
const maxZoom = this.getMaxAvailableZoom();
if (!isNil(maxZoom) && zoom > maxZoom) {
zoom = maxZoom;
}
Expand All @@ -877,6 +887,15 @@ class TileLayer extends Layer {
return zoom;
}

/**
* Get tileLayer's max available zoom, either options['maxAvailableZoom'] or spatialReference's maxZoom
*
* @returns {Number}
**/
getMaxAvailableZoom() {
const sr = this.getSpatialReference();
return this.options['maxAvailableZoom'] || sr && sr.getMaxZoom();
}

_getTiles(tileZoom, containerExtent, cascadeLevel, parentRenderer, ignoreMinZoom) {
// rendWhenReady = false;
Expand Down Expand Up @@ -1187,18 +1206,22 @@ class TileLayer extends Layer {
return tileInfo;
}

_getTileOffset(z) {
_getTileOffset(...params) {
// offset result can't be cached, as it varies with map's center.
let offset = this.options['offset'];
if (isFunction(offset)) {
offset = offset.call(this, z);
offset = offset.call(this, ...params);
}
if (isNumber(offset)) {
offset = [offset, offset];
}
return offset || [0, 0];
}

getTileId(x, y, zoom, id) {
return this._getTileId(x, y, zoom, id);
}

_getTileId(x, y, zoom, id) {
//id is to mark GroupTileLayer's child layers
return `${id || this.getId()}_${x}_${y}_${zoom}`;
Expand Down
11 changes: 4 additions & 7 deletions src/map/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -1292,14 +1292,11 @@ class Map extends Handlerable(Eventable(Renderable(Class))) {
if (renderer) {
renderer.setLayerCanvasUpdated();
}
removed.forEach(layer => {
layer.fire('remove');
this.once('frameend', () => {
removed.forEach(layer => {
layer.fire('remove');
});
});
// this.once('frameend', () => {
// removed.forEach(layer => {
// layer.fire('remove');
// });
// });
}
/**
* removelayer event, fired when removing layers.
Expand Down
9 changes: 7 additions & 2 deletions src/renderer/layer/ImageGLRenderable.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,11 @@ const ImageGLRenderable = Base => {
v2[1] = 2;
v2[2] = image.glBuffer.type;
this.enableVertexAttrib(v2); // ['a_position', 3]
// gl.bindBuffer(gl.ARRAY_BUFFER, this.texBuffer);
// this.enableVertexAttrib(['a_texCoord', 2, 'UNSIGNED_BYTE']);
gl.bindBuffer(gl.ARRAY_BUFFER, this.texBuffer);
v2[0] = 'a_texCoord';
v2[1] = 2;
v2[2] = 'UNSIGNED_BYTE';
this.enableVertexAttrib(v2);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

if (debug) {
Expand Down Expand Up @@ -189,6 +192,8 @@ const ImageGLRenderable = Base => {
x2, y2
), gl.DYNAMIC_DRAW);
gl.uniform1f(this.program['u_debug_line'], 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.texBuffer);
this.enableVertexAttrib(['a_texCoord', 2, 'UNSIGNED_BYTE']);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
gl.enable(gl.DEPTH_TEST);
}
Expand Down
Loading

0 comments on commit 7467890

Please sign in to comment.