From 31df454f22adcabcb835774edb464f9ecafc8f37 Mon Sep 17 00:00:00 2001 From: orangemug Date: Wed, 13 Dec 2023 15:45:06 +0000 Subject: [PATCH 1/8] Added *-sort-key support. --- src/stylefunction.js | 67 ++++++++++++++++++++++++++++++++++++++++---- src/util.js | 7 +++-- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/stylefunction.js b/src/stylefunction.js index 7e33669f..ba64f51d 100644 --- a/src/stylefunction.js +++ b/src/stylefunction.js @@ -21,6 +21,7 @@ import mb2css from 'mapbox-to-css-font'; import spec from '@mapbox/mapbox-gl-style-spec/reference/v8.json'; import {applyLetterSpacing, wrapText} from './text.js'; import { + calcSortIndex, clearFunctionCache, createCanvas, defaultResolutions, @@ -518,6 +519,20 @@ export function stylefunction( functionCache, featureState ); + + const zIndex = calcSortIndex( + index, + getValue( + layer, + 'layout', + layer.type + '-sort-key', + zoom, + f, + functionCache, + featureState + ) + ); + if (layer.type + '-pattern' in paint) { const fillIcon = getValue( layer, @@ -548,7 +563,7 @@ export function stylefunction( styles[stylesLength] = style; } fill = style.getFill(); - style.setZIndex(index); + style.setZIndex(zIndex); const icon_cache_key = icon + '.' + opacity; let pattern = patternCache[icon_cache_key]; if (!pattern) { @@ -634,7 +649,7 @@ export function stylefunction( stroke.setColor(strokeColor); stroke.setWidth(0.5); } - style.setZIndex(index); + style.setZIndex(zIndex); } } } @@ -722,6 +737,20 @@ export function stylefunction( ); stroke.setColor(color); stroke.setWidth(width); + + const zIndex = calcSortIndex( + index, + getValue( + layer, + 'layout', + 'line-sort-key', + zoom, + f, + functionCache, + featureState + ) + ); + stroke.setLineDash( paint['line-dasharray'] ? getValue( @@ -737,7 +766,7 @@ export function stylefunction( }) : null ); - style.setZIndex(index); + style.setZIndex(zIndex); } } @@ -1055,10 +1084,24 @@ export function stylefunction( ) ] ); + + const zIndex = calcSortIndex( + index, + getValue( + layer, + 'layout', + 'line-sort-key', + zoom, + f, + functionCache, + featureState + ) + ); + style.setImage(iconImg); text = style.getText(); style.setText(undefined); - style.setZIndex(index); + style.setZIndex(zIndex); hasImage = true; skipLabel = false; } @@ -1531,6 +1574,20 @@ export function stylefunction( ), opacity ); + + const zIndex = calcSortIndex( + index, + getValue( + layer, + 'layout', + 'symbol-sort-key', + zoom, + f, + functionCache, + featureState + ) + ); + if (haloColor) { textHalo.setColor(haloColor); // spec here : https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-symbol-text-halo-width @@ -1561,7 +1618,7 @@ export function stylefunction( padding[2] = textPadding; padding[3] = textPadding; } - style.setZIndex(index); + style.setZIndex(zIndex); } } } diff --git a/src/util.js b/src/util.js index e9aa25b8..9e22605b 100644 --- a/src/util.js +++ b/src/util.js @@ -400,6 +400,9 @@ export function drawSDF(image, area, color) { } /** - * @typedef {import("./apply.js").Options} Options - * @private + * @param {number} index + * @param {number} sortIndex */ +export function calcSortIndex(index, sortIndex) { + return index + (sortIndex === undefined ? 0 : sortIndex) * 0.00000000001; +} From 69fd4ad5641963684deaef23d96966241a99af42 Mon Sep 17 00:00:00 2001 From: orangemug Date: Thu, 14 Dec 2023 16:17:37 +0000 Subject: [PATCH 2/8] Added comments to calcSortIndex(...) --- src/util.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/util.js b/src/util.js index 9e22605b..ec44bc25 100644 --- a/src/util.js +++ b/src/util.js @@ -400,8 +400,9 @@ export function drawSDF(image, area, color) { } /** - * @param {number} index - * @param {number} sortIndex + * @param {number} index render index of layer + * @param {number} sortIndex the sort index within that layer + * @return {number} newly calculated index */ export function calcSortIndex(index, sortIndex) { return index + (sortIndex === undefined ? 0 : sortIndex) * 0.00000000001; From 43b7a8fa16e77a6a445b2101f2411b2182a9d4ed Mon Sep 17 00:00:00 2001 From: orangemug Date: Thu, 14 Dec 2023 16:18:13 +0000 Subject: [PATCH 3/8] Don't apply calcSortIndex(...) to layers with type `fill-extrusion` --- src/stylefunction.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/stylefunction.js b/src/stylefunction.js index ba64f51d..f397dbdb 100644 --- a/src/stylefunction.js +++ b/src/stylefunction.js @@ -520,18 +520,21 @@ export function stylefunction( featureState ); - const zIndex = calcSortIndex( - index, - getValue( - layer, - 'layout', - layer.type + '-sort-key', - zoom, - f, - functionCache, - featureState - ) - ); + let zIndex = index; + if (layer.type === 'fill') { + zIndex = calcSortIndex( + index, + getValue( + layer, + 'layout', + 'fill-sort-key', + zoom, + f, + functionCache, + featureState + ) + ); + } if (layer.type + '-pattern' in paint) { const fillIcon = getValue( From 501bbcc1f397993ad70121f29330131aed778d47 Mon Sep 17 00:00:00 2001 From: orangemug Date: Thu, 14 Dec 2023 16:34:48 +0000 Subject: [PATCH 4/8] Added back in missing `@typedef` comment. --- src/util.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/util.js b/src/util.js index ec44bc25..f5d1dd43 100644 --- a/src/util.js +++ b/src/util.js @@ -399,6 +399,11 @@ export function drawSDF(image, area, color) { return imageCanvas; } +/** + * @typedef {import("./apply.js").Options} Options + * @private + */ + /** * @param {number} index render index of layer * @param {number} sortIndex the sort index within that layer From dc97aee13e5787a2340d4a39f78874762136e26d Mon Sep 17 00:00:00 2001 From: orangemug Date: Mon, 18 Dec 2023 09:37:43 +0000 Subject: [PATCH 5/8] Fix failing tests --- src/stylefunction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stylefunction.js b/src/stylefunction.js index f397dbdb..daca134f 100644 --- a/src/stylefunction.js +++ b/src/stylefunction.js @@ -1093,7 +1093,7 @@ export function stylefunction( getValue( layer, 'layout', - 'line-sort-key', + 'symbol-sort-key', zoom, f, functionCache, From 1ee8809b6536b3d899d314af0e1fec62483cf899 Mon Sep 17 00:00:00 2001 From: orangemug Date: Mon, 18 Dec 2023 11:08:26 +0000 Subject: [PATCH 6/8] Reworked to use renderOrder instead of zIndex as per review comments. --- src/apply.js | 33 +++++++++++++++++++++ src/stylefunction.js | 70 +++++--------------------------------------- src/util.js | 9 ------ 3 files changed, 41 insertions(+), 71 deletions(-) diff --git a/src/apply.js b/src/apply.js index 8c562b66..4a121f57 100644 --- a/src/apply.js +++ b/src/apply.js @@ -28,6 +28,7 @@ import { stylefunction as applyStylefunction, getValue, styleFunctionArgs, + types, } from './stylefunction.js'; import {bbox as bboxStrategy} from 'ol/loadingstrategy.js'; import {createXYZ} from 'ol/tilegrid.js'; @@ -50,6 +51,7 @@ import { } from 'ol/proj.js'; import {getFonts} from './text.js'; import {getTopLeft} from 'ol/extent.js'; +import {getUid} from 'ol'; import {hillshade} from './shaders.js'; import { normalizeSourceUrl, @@ -904,6 +906,37 @@ export function setupLayer(glStyle, styleUrl, glLayer, options) { layer.on('prerender', prerenderRasterLayer(glLayer, layer, functionCache)); } else if (glSource.type == 'geojson') { layer = setupGeoJSONLayer(glSource, styleUrl, options); + layer.setRenderOrder((f1, f2) => { + const getRenderOrder = (feature) => { + if (['fill', 'line', 'symbol', 'circle'].includes(glLayer.type)) { + const f = { + id: feature.getId(), + type: types[feature.getGeometry().getType()], + properties: feature.getProperties(), + }; + + const featureState = layer.get('mapbox-featurestate')[ + feature.getId() + ]; + + const sortOrder = getValue( + glLayer, + 'layout', + `${glLayer.type}-sort-key`, + null, + f, + functionCache, + featureState + ); + if (sortOrder === null) { + return parseInt(getUid(feature), 10); + } + return sortOrder; + } + }; + + return getRenderOrder(f1) - getRenderOrder(f2); + }); } else if (glSource.type == 'raster-dem' && glLayer.type == 'hillshade') { const hillshadeLayer = setupHillshadeLayer(glSource, styleUrl, options); layer = hillshadeLayer; diff --git a/src/stylefunction.js b/src/stylefunction.js index daca134f..2175991c 100644 --- a/src/stylefunction.js +++ b/src/stylefunction.js @@ -21,7 +21,6 @@ import mb2css from 'mapbox-to-css-font'; import spec from '@mapbox/mapbox-gl-style-spec/reference/v8.json'; import {applyLetterSpacing, wrapText} from './text.js'; import { - calcSortIndex, clearFunctionCache, createCanvas, defaultResolutions, @@ -46,7 +45,7 @@ import {isFunction} from '@mapbox/mapbox-gl-style-spec/function/index.js'; * @typedef {import('./util.js').ResourceType} ResourceType */ -const types = { +export const types = { 'Point': 1, 'MultiPoint': 1, 'LineString': 2, @@ -520,22 +519,6 @@ export function stylefunction( featureState ); - let zIndex = index; - if (layer.type === 'fill') { - zIndex = calcSortIndex( - index, - getValue( - layer, - 'layout', - 'fill-sort-key', - zoom, - f, - functionCache, - featureState - ) - ); - } - if (layer.type + '-pattern' in paint) { const fillIcon = getValue( layer, @@ -566,7 +549,7 @@ export function stylefunction( styles[stylesLength] = style; } fill = style.getFill(); - style.setZIndex(zIndex); + style.setZIndex(index); const icon_cache_key = icon + '.' + opacity; let pattern = patternCache[icon_cache_key]; if (!pattern) { @@ -652,7 +635,8 @@ export function stylefunction( stroke.setColor(strokeColor); stroke.setWidth(0.5); } - style.setZIndex(zIndex); + + style.setZIndex(index); } } } @@ -741,19 +725,6 @@ export function stylefunction( stroke.setColor(color); stroke.setWidth(width); - const zIndex = calcSortIndex( - index, - getValue( - layer, - 'layout', - 'line-sort-key', - zoom, - f, - functionCache, - featureState - ) - ); - stroke.setLineDash( paint['line-dasharray'] ? getValue( @@ -769,7 +740,7 @@ export function stylefunction( }) : null ); - style.setZIndex(zIndex); + style.setZIndex(index); } } @@ -1088,23 +1059,11 @@ export function stylefunction( ] ); - const zIndex = calcSortIndex( - index, - getValue( - layer, - 'layout', - 'symbol-sort-key', - zoom, - f, - functionCache, - featureState - ) - ); - style.setImage(iconImg); text = style.getText(); style.setText(undefined); - style.setZIndex(zIndex); + + style.setZIndex(index); hasImage = true; skipLabel = false; } @@ -1578,19 +1537,6 @@ export function stylefunction( opacity ); - const zIndex = calcSortIndex( - index, - getValue( - layer, - 'layout', - 'symbol-sort-key', - zoom, - f, - functionCache, - featureState - ) - ); - if (haloColor) { textHalo.setColor(haloColor); // spec here : https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-symbol-text-halo-width @@ -1621,7 +1567,7 @@ export function stylefunction( padding[2] = textPadding; padding[3] = textPadding; } - style.setZIndex(zIndex); + style.setZIndex(index); } } } diff --git a/src/util.js b/src/util.js index f5d1dd43..e9aa25b8 100644 --- a/src/util.js +++ b/src/util.js @@ -403,12 +403,3 @@ export function drawSDF(image, area, color) { * @typedef {import("./apply.js").Options} Options * @private */ - -/** - * @param {number} index render index of layer - * @param {number} sortIndex the sort index within that layer - * @return {number} newly calculated index - */ -export function calcSortIndex(index, sortIndex) { - return index + (sortIndex === undefined ? 0 : sortIndex) * 0.00000000001; -} From ff0a6eed37926ea2f0f975ad4173a2a39f0ff491 Mon Sep 17 00:00:00 2001 From: orangemug Date: Mon, 18 Dec 2023 11:11:11 +0000 Subject: [PATCH 7/8] Remove whitespace. --- src/stylefunction.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/stylefunction.js b/src/stylefunction.js index 2175991c..9cfe2ba1 100644 --- a/src/stylefunction.js +++ b/src/stylefunction.js @@ -518,7 +518,6 @@ export function stylefunction( functionCache, featureState ); - if (layer.type + '-pattern' in paint) { const fillIcon = getValue( layer, @@ -635,7 +634,6 @@ export function stylefunction( stroke.setColor(strokeColor); stroke.setWidth(0.5); } - style.setZIndex(index); } } @@ -724,7 +722,6 @@ export function stylefunction( ); stroke.setColor(color); stroke.setWidth(width); - stroke.setLineDash( paint['line-dasharray'] ? getValue( @@ -1058,11 +1055,9 @@ export function stylefunction( ) ] ); - style.setImage(iconImg); text = style.getText(); style.setText(undefined); - style.setZIndex(index); hasImage = true; skipLabel = false; @@ -1536,7 +1531,6 @@ export function stylefunction( ), opacity ); - if (haloColor) { textHalo.setColor(haloColor); // spec here : https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-symbol-text-halo-width From 682f75e34ab55201f270572fa1cfa1dcfdacf401 Mon Sep 17 00:00:00 2001 From: orangemug Date: Mon, 18 Dec 2023 12:09:11 +0000 Subject: [PATCH 8/8] Added default to renderOrder As per --- src/apply.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apply.js b/src/apply.js index 4a121f57..c07dbc93 100644 --- a/src/apply.js +++ b/src/apply.js @@ -933,6 +933,7 @@ export function setupLayer(glStyle, styleUrl, glLayer, options) { } return sortOrder; } + return parseInt(getUid(feature), 10); }; return getRenderOrder(f1) - getRenderOrder(f2);