From 11ed4e03ad4fe66f8a05ed7d5669d110bd15592e Mon Sep 17 00:00:00 2001 From: hu de yi Date: Wed, 25 Mar 2026 10:53:53 +0800 Subject: [PATCH 1/4] fix: fix vt 3d-wireframe plugin Overflow of altitude values --- packages/vt/src/worker/builder/Wireframe.js | 55 +++++++++++++------ .../vt/src/worker/builder/build_wireframe.js | 4 +- .../vt/src/worker/layer/BaseLayerWorker.js | 2 +- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/packages/vt/src/worker/builder/Wireframe.js b/packages/vt/src/worker/builder/Wireframe.js index 3bb8885413..a5b71ae22b 100644 --- a/packages/vt/src/worker/builder/Wireframe.js +++ b/packages/vt/src/worker/builder/Wireframe.js @@ -1,29 +1,30 @@ import { countVertexes, isClippedEdge, fillPosArray } from './Common'; import { KEY_IDX } from '../../common/Constant'; import { vec3 } from 'gl-matrix'; -import { isFunctionDefinition } from '@maptalks/function-type'; +import { isFunctionDefinition, loadFunctionTypes } from '@maptalks/function-type'; import { getVectorPacker } from '../../packer/inject'; -const { PackUtil, StyleUtil, FilterUtil } = getVectorPacker(); +const { PackUtil, StyleUtil } = getVectorPacker(); export function buildWireframe( - features, EXTENT, colorSymbol, opacity, + features, EXTENT, lineColor, lineOpacity, { altitudeScale, altitudeProperty, defaultAltitude, heightProperty, minHeightProperty, defaultHeight, bottom - } + }, + mapZoom ) { + const drawBottom = bottom; const scale = EXTENT / features[0].extent; // debugger const size = countVertexes(features) * 2 + features.length * 3 * 2; //wireframe need to count last point in const featIndexes = []; - const vertices = new Int16Array(size); + // -32768 到 32767 + let vertices = new Int16Array(size); const colors = new Uint8Array(vertices.length / 3 * 4); - if (isFunctionDefinition(colorSymbol)) { - colorSymbol = FilterUtil.compileFilter(colorSymbol); - } + const lineColorIsFunction = isFunctionDefinition(lineColor); const indices = []; function fillIndices(start, offset, height) { @@ -68,6 +69,23 @@ export function buildWireframe( return offset + count; } + let minAlt = Infinity, maxAlt = -Infinity; + const heights = []; + // Find the maximum elevation + for (let r = 0, n = features.length; r < n; r++) { + const feature = features[r]; + const { altitude, height } = PackUtil.getFeaAltitudeAndHeight(feature, altitudeScale, altitudeProperty, defaultAltitude, heightProperty, defaultHeight, minHeightProperty); + minAlt = Math.min(altitude, minAlt); + maxAlt = Math.max(altitude, maxAlt); + const idx = 2 * r; + heights[idx] = altitude; + heights[idx + 1] = height; + } + // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray + if (Math.max(Math.abs(minAlt), Math.abs(maxAlt)) > 32767) { + vertices = new Int32Array(size); + } + let offset = 0; let maxAltitude = -Infinity; let minAltitude = Infinity; @@ -76,12 +94,14 @@ export function buildWireframe( for (let r = 0, n = features.length; r < n; r++) { const feature = features[r]; const geometry = feature.geometry; - if (colorSymbol) { - let color; - if (typeof colorSymbol === 'function') { - color = colorSymbol(feature && feature.properties); - } else { - color = colorSymbol; + if (lineColor) { + let color = lineColor; + if (lineColorIsFunction) { + const colorSymbol = loadFunctionTypes({ lineColor }, () => { + return [mapZoom, feature.properties || {}]; + }); + color = colorSymbol.lineColor; + color = color || '#fff'; } StyleUtil.normalizeColor(rgb, color); } else { @@ -89,7 +109,10 @@ export function buildWireframe( } const colorStart = offset / 3 * 4; - const { altitude, height } = PackUtil.getFeaAltitudeAndHeight(feature, altitudeScale, altitudeProperty, defaultAltitude, heightProperty, defaultHeight, minHeightProperty); + const idx = 2 * r; + const altitude = heights[idx]; + const height = heights[idx + 1]; + if (height < 0) { minAltitude = Math.min(altitude, minAltitude); maxAltitude = Math.max(altitude - height, maxAltitude); @@ -117,7 +140,7 @@ export function buildWireframe( colors[i] = rgb[0]; colors[i + 1] = rgb[1]; colors[i + 2] = rgb[2]; - colors[i + 3] = 255 * (opacity || 1); + colors[i + 3] = 255 * (lineOpacity || 1); } const count = indices.length - featIndexes.length; for (let i = 0; i < count; i++) { diff --git a/packages/vt/src/worker/builder/build_wireframe.js b/packages/vt/src/worker/builder/build_wireframe.js index 8f10aae13b..8f64620c3d 100644 --- a/packages/vt/src/worker/builder/build_wireframe.js +++ b/packages/vt/src/worker/builder/build_wireframe.js @@ -1,7 +1,7 @@ import { buildWireframe } from './Wireframe'; -export default function (features, extent, symbol, dataConfig) { - const frames = buildWireframe(features, extent, symbol.lineColor, symbol.lineOpacity, dataConfig); +export default function (features, extent, symbol, dataConfig, mapZoom) { + const frames = buildWireframe(features, extent, symbol.lineColor, symbol.lineOpacity, dataConfig, mapZoom); const { minAltitude, maxAltitude } = frames; delete frames.minAltitude; delete frames.maxAltitude; diff --git a/packages/vt/src/worker/layer/BaseLayerWorker.js b/packages/vt/src/worker/layer/BaseLayerWorker.js index 31e0bf6228..6c21a27c01 100644 --- a/packages/vt/src/worker/layer/BaseLayerWorker.js +++ b/packages/vt/src/worker/layer/BaseLayerWorker.js @@ -602,7 +602,7 @@ export default class BaseLayerWorker { ) )]); } else if (type === '3d-wireframe') { - return Promise.all([Promise.resolve(buildWireframe(features, extent, symbol, dataConfig))]); + return Promise.all([Promise.resolve(buildWireframe(features, extent, symbol, dataConfig, zoom))]); } else if (type === 'point') { options = extend(options, { requestor: this.fetchIconGlyphs.bind(this), From e026cab46e543417b8f883b6342de906240feac0 Mon Sep 17 00:00:00 2001 From: hu de yi Date: Wed, 25 Mar 2026 10:58:36 +0800 Subject: [PATCH 2/4] fix: fix vt 3d-wireframe plugin Overflow of altitude values --- packages/vt/src/worker/builder/Wireframe.js | 57 +++++++++++++------ .../vt/src/worker/builder/build_wireframe.js | 6 +- .../vt/src/worker/layer/BaseLayerWorker.js | 2 +- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/packages/vt/src/worker/builder/Wireframe.js b/packages/vt/src/worker/builder/Wireframe.js index 3bb8885413..1808069e5e 100644 --- a/packages/vt/src/worker/builder/Wireframe.js +++ b/packages/vt/src/worker/builder/Wireframe.js @@ -1,29 +1,30 @@ import { countVertexes, isClippedEdge, fillPosArray } from './Common'; import { KEY_IDX } from '../../common/Constant'; import { vec3 } from 'gl-matrix'; -import { isFunctionDefinition } from '@maptalks/function-type'; +import { isFunctionDefinition, loadFunctionTypes } from '@maptalks/function-type'; import { getVectorPacker } from '../../packer/inject'; -const { PackUtil, StyleUtil, FilterUtil } = getVectorPacker(); +const { PackUtil, StyleUtil } = getVectorPacker(); -export function buildWireframe( - features, EXTENT, colorSymbol, opacity, +export function wireframe( + features, EXTENT, lineColor, lineOpacity, { altitudeScale, altitudeProperty, defaultAltitude, heightProperty, minHeightProperty, defaultHeight, bottom - } + }, + mapZoom ) { + const drawBottom = bottom; const scale = EXTENT / features[0].extent; // debugger const size = countVertexes(features) * 2 + features.length * 3 * 2; //wireframe need to count last point in const featIndexes = []; - const vertices = new Int16Array(size); + // -32768 到 32767 + let vertices = new Int16Array(size); const colors = new Uint8Array(vertices.length / 3 * 4); - if (isFunctionDefinition(colorSymbol)) { - colorSymbol = FilterUtil.compileFilter(colorSymbol); - } + const lineColorIsFunction = isFunctionDefinition(lineColor); const indices = []; function fillIndices(start, offset, height) { @@ -68,6 +69,23 @@ export function buildWireframe( return offset + count; } + let minAlt = Infinity, maxAlt = -Infinity; + const heights = []; + // Find the maximum elevation + for (let r = 0, n = features.length; r < n; r++) { + const feature = features[r]; + const { altitude, height } = PackUtil.getFeaAltitudeAndHeight(feature, altitudeScale, altitudeProperty, defaultAltitude, heightProperty, defaultHeight, minHeightProperty); + minAlt = Math.min(altitude, minAlt); + maxAlt = Math.max(altitude, maxAlt); + const idx = 2 * r; + heights[idx] = altitude; + heights[idx + 1] = height; + } + // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray + if (Math.max(Math.abs(minAlt), Math.abs(maxAlt)) > 32767) { + vertices = new Int32Array(size); + } + let offset = 0; let maxAltitude = -Infinity; let minAltitude = Infinity; @@ -76,12 +94,14 @@ export function buildWireframe( for (let r = 0, n = features.length; r < n; r++) { const feature = features[r]; const geometry = feature.geometry; - if (colorSymbol) { - let color; - if (typeof colorSymbol === 'function') { - color = colorSymbol(feature && feature.properties); - } else { - color = colorSymbol; + if (lineColor) { + let color = lineColor; + if (lineColorIsFunction) { + const colorSymbol = loadFunctionTypes({ lineColor }, () => { + return [mapZoom, feature.properties || {}]; + }); + color = colorSymbol.lineColor; + color = color || '#fff'; } StyleUtil.normalizeColor(rgb, color); } else { @@ -89,7 +109,10 @@ export function buildWireframe( } const colorStart = offset / 3 * 4; - const { altitude, height } = PackUtil.getFeaAltitudeAndHeight(feature, altitudeScale, altitudeProperty, defaultAltitude, heightProperty, defaultHeight, minHeightProperty); + const idx = 2 * r; + const altitude = heights[idx]; + const height = heights[idx + 1]; + if (height < 0) { minAltitude = Math.min(altitude, minAltitude); maxAltitude = Math.max(altitude - height, maxAltitude); @@ -117,7 +140,7 @@ export function buildWireframe( colors[i] = rgb[0]; colors[i + 1] = rgb[1]; colors[i + 2] = rgb[2]; - colors[i + 3] = 255 * (opacity || 1); + colors[i + 3] = 255 * (lineOpacity || 1); } const count = indices.length - featIndexes.length; for (let i = 0; i < count; i++) { diff --git a/packages/vt/src/worker/builder/build_wireframe.js b/packages/vt/src/worker/builder/build_wireframe.js index 8f10aae13b..240cc4397f 100644 --- a/packages/vt/src/worker/builder/build_wireframe.js +++ b/packages/vt/src/worker/builder/build_wireframe.js @@ -1,7 +1,7 @@ -import { buildWireframe } from './Wireframe'; +import { wireframe } from './Wireframe'; -export default function (features, extent, symbol, dataConfig) { - const frames = buildWireframe(features, extent, symbol.lineColor, symbol.lineOpacity, dataConfig); +export default function (features, extent, symbol, dataConfig, mapZoom) { + const frames = wireframe(features, extent, symbol.lineColor, symbol.lineOpacity, dataConfig, mapZoom); const { minAltitude, maxAltitude } = frames; delete frames.minAltitude; delete frames.maxAltitude; diff --git a/packages/vt/src/worker/layer/BaseLayerWorker.js b/packages/vt/src/worker/layer/BaseLayerWorker.js index 31e0bf6228..6c21a27c01 100644 --- a/packages/vt/src/worker/layer/BaseLayerWorker.js +++ b/packages/vt/src/worker/layer/BaseLayerWorker.js @@ -602,7 +602,7 @@ export default class BaseLayerWorker { ) )]); } else if (type === '3d-wireframe') { - return Promise.all([Promise.resolve(buildWireframe(features, extent, symbol, dataConfig))]); + return Promise.all([Promise.resolve(buildWireframe(features, extent, symbol, dataConfig, zoom))]); } else if (type === 'point') { options = extend(options, { requestor: this.fetchIconGlyphs.bind(this), From 0d481573a1de660ae0b7d17bcea57752c049e08c Mon Sep 17 00:00:00 2001 From: hu de yi Date: Wed, 25 Mar 2026 11:22:59 +0800 Subject: [PATCH 3/4] updates --- packages/vt/src/worker/builder/Wireframe.js | 36 +++++++++++-------- .../vt/src/worker/builder/build_wireframe.js | 2 +- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/packages/vt/src/worker/builder/Wireframe.js b/packages/vt/src/worker/builder/Wireframe.js index 8d667d4aa6..cc026f23a9 100644 --- a/packages/vt/src/worker/builder/Wireframe.js +++ b/packages/vt/src/worker/builder/Wireframe.js @@ -1,13 +1,12 @@ import { countVertexes, isClippedEdge, fillPosArray } from './Common'; import { KEY_IDX } from '../../common/Constant'; -import { vec3 } from 'gl-matrix'; import { isFunctionDefinition, loadFunctionTypes } from '@maptalks/function-type'; import { getVectorPacker } from '../../packer/inject'; const { PackUtil, StyleUtil } = getVectorPacker(); export function wireframe( - features, EXTENT, lineColor, lineOpacity, + features, EXTENT, symbol, { altitudeScale, altitudeProperty, defaultAltitude, heightProperty, minHeightProperty, defaultHeight, bottom @@ -24,7 +23,9 @@ export function wireframe( // -32768 到 32767 let vertices = new Int16Array(size); const colors = new Uint8Array(vertices.length / 3 * 4); + const { lineColor, lineOpacity } = symbol || {}; const lineColorIsFunction = isFunctionDefinition(lineColor); + const lineOpacityIsFunction = isFunctionDefinition(lineOpacity); const indices = []; function fillIndices(start, offset, height) { @@ -95,20 +96,25 @@ export function wireframe( for (let r = 0, n = features.length; r < n; r++) { const feature = features[r]; const geometry = feature.geometry; - if (lineColor) { - let color = lineColor; - if (lineColorIsFunction) { - const colorSymbol = loadFunctionTypes({ lineColor }, () => { - return [mapZoom, feature.properties || {}]; - }); - color = colorSymbol.lineColor; - color = color || '#fff'; - } - StyleUtil.normalizeColor(rgb, color); + let color, opacity; + if (lineColorIsFunction || lineOpacityIsFunction) { + const colorSymbol = loadFunctionTypes(symbol, () => { + return [mapZoom, feature.properties || {}]; + }); + color = colorSymbol.lineColor; + opacity = colorSymbol.lineOpacity; + } else { - vec3.set(rgb, 255, 255, 255); + color = lineColor; + opacity = lineOpacity; } - + if (typeof opacity !== 'number') { + opacity = 1; + } + if (!color) { + color = '#fff'; + } + StyleUtil.normalizeColor(rgb, color); const colorStart = offset / 3 * 4; const idx = 2 * r; const altitude = heights[idx]; @@ -141,7 +147,7 @@ export function wireframe( colors[i] = rgb[0]; colors[i + 1] = rgb[1]; colors[i + 2] = rgb[2]; - colors[i + 3] = 255 * (lineOpacity || 1); + colors[i + 3] = 255 * opacity; } const count = indices.length - featIndexes.length; for (let i = 0; i < count; i++) { diff --git a/packages/vt/src/worker/builder/build_wireframe.js b/packages/vt/src/worker/builder/build_wireframe.js index 240cc4397f..5e4e9af8dc 100644 --- a/packages/vt/src/worker/builder/build_wireframe.js +++ b/packages/vt/src/worker/builder/build_wireframe.js @@ -1,7 +1,7 @@ import { wireframe } from './Wireframe'; export default function (features, extent, symbol, dataConfig, mapZoom) { - const frames = wireframe(features, extent, symbol.lineColor, symbol.lineOpacity, dataConfig, mapZoom); + const frames = wireframe(features, extent, symbol, dataConfig, mapZoom); const { minAltitude, maxAltitude } = frames; delete frames.minAltitude; delete frames.maxAltitude; From d7f479bb11f86ed0a68341e65cc4bd79cc9be408 Mon Sep 17 00:00:00 2001 From: hu de yi Date: Wed, 25 Mar 2026 15:13:10 +0800 Subject: [PATCH 4/4] updates --- packages/vt/src/worker/builder/Wireframe.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/vt/src/worker/builder/Wireframe.js b/packages/vt/src/worker/builder/Wireframe.js index cc026f23a9..0ee69ea11f 100644 --- a/packages/vt/src/worker/builder/Wireframe.js +++ b/packages/vt/src/worker/builder/Wireframe.js @@ -1,4 +1,5 @@ import { countVertexes, isClippedEdge, fillPosArray } from './Common'; +import { isNumber } from '../../common/Util'; import { KEY_IDX } from '../../common/Constant'; import { isFunctionDefinition, loadFunctionTypes } from '@maptalks/function-type'; import { getVectorPacker } from '../../packer/inject'; @@ -96,7 +97,7 @@ export function wireframe( for (let r = 0, n = features.length; r < n; r++) { const feature = features[r]; const geometry = feature.geometry; - let color, opacity; + let color = lineColor, opacity = lineOpacity; if (lineColorIsFunction || lineOpacityIsFunction) { const colorSymbol = loadFunctionTypes(symbol, () => { return [mapZoom, feature.properties || {}]; @@ -104,11 +105,8 @@ export function wireframe( color = colorSymbol.lineColor; opacity = colorSymbol.lineOpacity; - } else { - color = lineColor; - opacity = lineOpacity; } - if (typeof opacity !== 'number') { + if (!isNumber(opacity)) { opacity = 1; } if (!color) {