Skip to content

Commit

Permalink
refactor(VectorTilesSource): remove useless styles by zoom.
Browse files Browse the repository at this point in the history
  • Loading branch information
gchoqueux committed Apr 9, 2021
1 parent 0581d3d commit baabbae
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 82 deletions.
10 changes: 0 additions & 10 deletions src/Layer/InfoLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,6 @@ export class InfoTiledGeometryLayer extends InfoLayer {
});
}

get currentMaxTileZoom() {
let zoom = -1;
this.displayed.tiles.forEach((t) => {
if (t.extent.zoom > zoom) {
zoom = t.extent.zoom;
}
});
return zoom;
}

clear() {
this.displayed.tiles.clear();
}
Expand Down
31 changes: 12 additions & 19 deletions src/Layer/LabelLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,6 @@ class LabelLayer extends Layer {
const featureField = f.style && f.style.text.field;

f.geometries.forEach((g) => {
const minzoom = (g.properties.style && g.properties.style.zoom.min)
|| (f.style && f.style.zoom.min)
|| (this.style && this.style.zoom && this.style.zoom.min);

// Don't create a label if it is in-between two steps of zoom
if (minzoom !== undefined) {
if (!this.source.isFileSource) {
if (data.extent.zoom != minzoom) { return; }
} else if (extent.zoom != minzoom) { return; }
}

// NOTE: this only works because only POINT is supported, it
// needs more work for LINE and POLYGON
coord.setFromArray(f.vertices, g.size * g.indices[0].offset);
Expand Down Expand Up @@ -206,15 +195,19 @@ class LabelLayer extends Layer {
label.updateElevationFromLayer(this.parent);
}

node.add(label);
label.update3dPosition(context.view.referenceCrs);
const present = node.children.find(l => l.isLabel && l.baseContent == label.baseContent);

if (node.level < 4) {
label.horizonCullingPoint = new THREE.Vector3();
label.updateHorizonCullingPoint();
}
if (!present) {
node.add(label);
label.update3dPosition(context.view.referenceCrs);

labelsDiv.push(label.content);
if (node.level < 4) {
label.horizonCullingPoint = new THREE.Vector3();
label.updateHorizonCullingPoint();
}

labelsDiv.push(label.content);
}
});
});

Expand All @@ -240,7 +233,7 @@ class LabelLayer extends Layer {
// way, we cull labels on parent tile first, and then on
// children tile. This allows a z-order priority, and reduce
// flickering.
node.children.sort(c => (c.isLabel ? -1 : 1));
node.children.sort(c => (c.isLabel ? -c.order : 1));

// Necessary event listener, to remove any Label attached to
// this tile
Expand Down
8 changes: 2 additions & 6 deletions src/Parser/VectorTileParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,6 @@ function vtFeatureToFeatureGeometry(vtFeature, feature, classify = false) {
feature.updateExtent(geometry);
}

export function getStyle(styles, id, zoom) {
return styles[id].find(s => s.zoom.min <= zoom && s.zoom.max > zoom);
}

function readPBF(file, options) {
options.out = options.out || {};
const vectorTile = new VectorTile(new Protobuf(file));
Expand Down Expand Up @@ -141,13 +137,13 @@ function readPBF(file, options) {
feature = collection.requestFeatureById(layer.id, vtFeature.type - 1);
feature.id = layer.id;
feature.order = layer.order;
feature.style = getStyle(options.in.styles, feature.id, z);
feature.style = options.in.styles[feature.id];
vtFeatureToFeatureGeometry(vtFeature, feature);
} else if (!collection.features.find(f => f.id === layer.id)) {
feature = collection.newFeatureByReference(feature);
feature.id = layer.id;
feature.order = layer.order;
feature.style = getStyle(options.in.styles, feature.id, z);
feature.style = options.in.styles[feature.id];
}
}
}
Expand Down
18 changes: 12 additions & 6 deletions src/Renderer/Label2DRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ function isIntersectedOrOverlaped(a, b) {
|| a.top > b.bottom || a.bottom < b.top);
}

// find label in children
function hasLabelChildren(object) {
const parent = object.parent;
return parent.material && !parent.material.visible &&
parent.children.find(c => c.isTileMesh && c.children.find(cc => cc.isLabel));
}

// A grid to manage labels on the screen.
class ScreenGrid {
constructor(x = 12, y = 10, width, height) {
Expand Down Expand Up @@ -136,7 +143,7 @@ class Label2DRenderer {

viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);

this.culling(scene, this.infoTileLayer.currentMaxTileZoom, this.infoTileLayer.displayed.extent);
this.culling(scene, this.infoTileLayer.displayed.extent);

// sort by order, then by visibility inside those subsets
// https://docs.mapbox.com/help/troubleshooting/optimize-map-label-placement/#label-hierarchy
Expand All @@ -160,7 +167,7 @@ class Label2DRenderer {
this.grid.hidden.forEach((label) => { label.visible = false; });
}

culling(object, currentMaxZoom, extent) {
culling(object, extent) {
if (!object.isLabel) {
if (!object.visible) {
this.hideNodeDOM(object);
Expand All @@ -174,10 +181,9 @@ class Label2DRenderer {

this.showNodeDOM(object);

object.children.forEach(c => this.culling(c, currentMaxZoom, extent));
// By verifying the maxzoom and the presence of the label inside the
// visible extent, we can filter more labels.
} else if (object.zoom.max <= currentMaxZoom || !extent.isPointInside(object.coordinates)) {
object.children.forEach(c => this.culling(c, extent));
// the presence of the label inside the visible extent and if children has label, we can filter more labels.
} else if (!extent.isPointInside(object.coordinates) || hasLabelChildren(object)) {
this.grid.hidden.push(object);
// Do some horizon culling (if possible) if the tiles level is small
// enough. The chosen value of 4 seems to provide a good result.
Expand Down
46 changes: 5 additions & 41 deletions src/Source/VectorTilesSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ function toTMSUrl(url) {
return url.replace(/\{/g, '${');
}

function checkStopsValues(obj, target) {
for (const p in obj) {
if (obj[p].stops) {
obj[p].stops.forEach(s => target.push(s[0]));
}
}
}

/**
* @classdesc
* VectorTilesSource are object containing informations on how to fetch vector
Expand Down Expand Up @@ -103,47 +95,19 @@ class VectorTilesSource extends TMSSource {
if (layer.type === 'background') {
this.backgroundLayer = layer;
} else if (ffilter(layer)) {
// TODO: add support for expressions
// https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions
let stops = [];
checkStopsValues(layer.layout, stops);
checkStopsValues(layer.paint, stops);

let minStop = Math.min(...stops);
// if none is found, default to 0
minStop = (minStop == Infinity) ? 0 : minStop;
// compare to layer.minzoom and take the highest
minStop = (layer.minzoom == undefined) ? minStop : Math.max(layer.minzoom, minStop);

stops.push(minStop);
stops.push(layer.maxzoom == undefined ? 24 : layer.maxzoom);
stops.sort((a, b) => (a - b));

// remove all value < minStop
stops = stops.filter(s => s >= minStop);

this.styles[layer.id] = [];
for (let i = 0; i < stops.length - 1; i++) {
if (stops[i] == stops[i + 1]) { continue; }
const style = new Style();
style.zoom.min = stops[i];
style.zoom.max = stops[i + 1];
style.setFromVectorTileLayer(layer, this.sprites, order, this.symbolToCircle);
this.styles[layer.id].push(style);
}
const style = new Style().setFromVectorTileLayer(layer, this.sprites, order, this.symbolToCircle);
style.zoom.min = layer.minzoom || 0;
style.zoom.max = layer.maxzoom || 24;
this.styles[layer.id] = style;

if (!this.layers[layer['source-layer']]) {
this.layers[layer['source-layer']] = [];
}

this.layers[layer['source-layer']].push({
id: layer.id,
order,
filterExpression: featureFilter(layer.filter),
zoom: {
min: stops[0],
max: stops[stops.length - 1],
},
zoom: style.zoom,
});
}
});
Expand Down

0 comments on commit baabbae

Please sign in to comment.