leaflet-city-mapper 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/cucumber.mjs +1 -3
- package/dist/leaflet-city-mapper-src.js +8574 -7879
- package/dist/leaflet-city-mapper-src.js.map +4 -4
- package/dist/leaflet-city-mapper-worker-src.js +2776 -0
- package/dist/leaflet-city-mapper-worker-src.js.map +4 -4
- package/dist/leaflet-city-mapper-worker.js +1 -1
- package/dist/leaflet-city-mapper-worker.js.map +4 -4
- package/dist/leaflet-city-mapper.js +5 -3
- package/dist/leaflet-city-mapper.js.map +4 -4
- package/libs/leaflet-lens.js +44 -27
- package/libs/leaflet.js +4 -4
- package/libs/openlayers-bindings.js +2 -1
- package/libs/openlayers-bindings.min.js +1 -1
- package/libs/openlayers-bindings.min.js.map +3 -3
- package/package.json +2 -2
- package/src/camera/mapCamera.js +7 -7
- package/src/camera/mapTryAnimatedPan.js +4 -4
- package/src/camera/setBearing.js +5 -0
- package/src/camera/setPitch.js +5 -0
- package/src/camera/updateMapCamera.js +8 -6
- package/src/cog/initCog.js +2 -2
- package/src/controls/cameraControls.js +27 -22
- package/src/core/cameraCircleBounds.js +2 -1
- package/src/core/closestCameraLayerPoint.js +2 -1
- package/src/core/constructLayer.js +9 -0
- package/src/core/extendLeafletClass.js +5 -0
- package/src/core/extendTerrainPixelBounds.js +31 -0
- package/src/core/gridlayerGetTiledPixelBounds.js +12 -4
- package/src/core/layerAddInitHook.js +7 -0
- package/src/core/layerCallInitHooks.js +13 -13
- package/src/core/layerMergeOptions.js +7 -0
- package/src/core/markerSetPos.js +1 -1
- package/src/core/popupGetEvents.js +1 -1
- package/src/core/popupUpdatePosition.js +8 -8
- package/src/core/projectNativePath.js +23 -0
- package/src/core/tooltipGetEvents.js +1 -1
- package/src/core/tooltipSetPosition.js +2 -2
- package/src/geometry/appendNativeTriangle.js +2 -2
- package/src/geometry/circleGeometry.js +4 -3
- package/src/geometry/createModelGeometry.js +2 -9
- package/src/geometry/dashedSegment.js +10 -5
- package/src/geometry/disk.js +1 -1
- package/src/geometry/fillNativePolygon.js +20 -0
- package/src/geometry/lineJoin.js +2 -2
- package/src/geometry/markerQuadCorners.js +6 -0
- package/src/geometry/nativeGeometry.js +1 -1
- package/src/geometry/polygon.js +4 -10
- package/src/geometry/segment.js +4 -3
- package/src/globals/colorTexture.js +6 -0
- package/src/globals/depthTexture.js +1 -0
- package/src/globals/drawMeshEntry.js +1 -1
- package/src/globals/layerControlAddItem.js +3 -0
- package/src/globals/leafletLayer.js +3 -0
- package/src/globals/meshPipeline.js +1 -0
- package/src/globals/mvtTextDecoder.js +1 -0
- package/src/globals/nativeScalableStyleKeys.js +1 -0
- package/src/globals/scenePass.js +1 -0
- package/src/globals/vectorStyleNamedColors.js +8 -0
- package/src/globals/vectorTileEvents.js +1 -0
- package/src/globals/workerCogSource.js +1 -0
- package/src/gpu/initializeRendererResources.js +10 -12
- package/src/gpu/mountRenderer.js +4 -11
- package/src/gpu/releaseRenderer.js +1 -0
- package/src/index.js +31 -22
- package/src/layer-controls/layerControlInputId.js +11 -0
- package/src/layer-controls/placeEntry.js +2 -0
- package/src/materials/createProgram.js +7 -6
- package/src/materials/createProgramUniforms.js +1 -0
- package/src/models/loadModel.js +6 -10
- package/src/models/loadModelResources.js +2 -8
- package/src/models/modelNode.js +3 -7
- package/src/models/prepareModel.js +19 -0
- package/src/models/prepareModelGeometry.js +25 -0
- package/src/models/prepareModelPrimitive.js +17 -0
- package/src/mvt/addMvtCrossings.js +17 -0
- package/src/mvt/appendMvtBandTriangles.js +31 -0
- package/src/mvt/appendMvtCoordinates.js +11 -0
- package/src/mvt/appendMvtPolygonTriangles.js +19 -0
- package/src/mvt/beginMvtPath.js +9 -0
- package/src/mvt/closeMvtPath.js +7 -0
- package/src/mvt/collectMvtEdges.js +19 -0
- package/src/mvt/createMvtReader.js +7 -0
- package/src/mvt/decodeVectorTile.js +32 -0
- package/src/mvt/expectMvtWire.js +3 -0
- package/src/mvt/finishMvtPath.js +5 -0
- package/src/mvt/finiteMvtCoordinate.js +7 -0
- package/src/mvt/groupMvtPolygons.js +25 -0
- package/src/mvt/isMvtFallbackError.js +6 -0
- package/src/mvt/mergeMvtActiveEdges.js +9 -0
- package/src/mvt/mvtEdgeX.js +4 -0
- package/src/mvt/mvtPathsVertices.js +8 -0
- package/src/mvt/mvtPolygonPaths.js +12 -0
- package/src/mvt/numericMvtValue.js +4 -0
- package/src/mvt/readMvtFeature.js +34 -0
- package/src/mvt/readMvtField.js +8 -0
- package/src/mvt/readMvtGeometry.js +29 -0
- package/src/mvt/readMvtInteger.js +12 -0
- package/src/mvt/readMvtKnownValue.js +21 -0
- package/src/mvt/readMvtLayer.js +31 -0
- package/src/mvt/readMvtMessage.js +10 -0
- package/src/mvt/readMvtNumber.js +9 -0
- package/src/mvt/readMvtNumbers.js +11 -0
- package/src/mvt/readMvtString.js +6 -0
- package/src/mvt/readMvtValue.js +19 -0
- package/src/mvt/skipMvtField.js +14 -0
- package/src/mvt/sortMvtActiveEdges.js +15 -0
- package/src/mvt/sortedMvtLevels.js +22 -0
- package/src/mvt/takeMvtBytes.js +8 -0
- package/src/mvt/tessellateVectorRings.js +19 -0
- package/src/mvt/triangulateVectorRings.js +19 -0
- package/src/native/beforeNativeRender.js +6 -0
- package/src/native/canScaleNativeStyle.js +17 -0
- package/src/native/createNativeMesh.js +31 -0
- package/src/native/disposeNativeLayer.js +1 -1
- package/src/native/getGridTerrainTile.js +34 -0
- package/src/native/gridTerrainElevation.js +26 -0
- package/src/native/loadGridTerrain.js +26 -0
- package/src/native/nativeLayer.js +2 -2
- package/src/native/nativeLayerMethod.js +5 -14
- package/src/native/nativeProgram.js +20 -0
- package/src/native/nativeTerrainElevation.js +16 -0
- package/src/native/nativeVectorGeometry.js +23 -0
- package/src/native/orderNativeGridLayer.js +14 -0
- package/src/native/prepareGridTerrainRequests.js +16 -0
- package/src/native/putNativeMesh.js +15 -21
- package/src/native/refreshNativeEvent.js +13 -2
- package/src/native/refreshNativeLayer.js +1 -0
- package/src/native/retainGridTerrain.js +10 -0
- package/src/native/syncGridLayer.js +17 -19
- package/src/native/syncGridTile.js +18 -0
- package/src/native/syncNativeStrokeAnchors.js +12 -0
- package/src/native/syncNativeStrokeZoom.js +29 -0
- package/src/native/syncTerrainGridTile.js +28 -0
- package/src/native/syncVectorLayer.js +15 -13
- package/src/native/terrainGridMesh.js +34 -0
- package/src/native/updateNativeStrokeRadius.js +9 -0
- package/src/projections/displayContainerPoint.js +23 -3
- package/src/projections/groundBounds.js +2 -2
- package/src/projections/localPixel.js +7 -2
- package/src/projections/localPixelForGeometry.js +4 -2
- package/src/projections/projectCameraPoint.js +6 -5
- package/src/rendering/collectVisibleMesh.js +5 -2
- package/src/rendering/drawGeometry.js +11 -11
- package/src/rendering/drawSceneMeshes.js +3 -1
- package/src/rendering/nativeStrokeExpansion.js +4 -0
- package/src/rendering/prepareMeshUniforms.js +2 -0
- package/src/rendering/resizeRenderer.js +20 -10
- package/src/scene/initializerFor.js +4 -5
- package/src/scene/layerInitialize.js +14 -12
- package/src/scene/resolveNextInitialization.js +1 -1
- package/src/shaders/materialShaders.js +1 -0
- package/src/shaders/materialVertexShader.js +7 -2
- package/src/shaders/nativeStrokeShader.js +6 -0
- package/src/shadows/drawShadowMeshes.js +6 -5
- package/src/sources/attachAreaMesh.js +5 -6
- package/src/sources/buildArea.js +4 -5
- package/src/sources/buildAreaFeature.js +3 -19
- package/src/sources/initVectorTiles.js +15 -0
- package/src/sources/isVectorTileSource.js +4 -0
- package/src/sources/pumpSourceAreas.js +1 -1
- package/src/sources/readyVectorTiles.js +10 -0
- package/src/sources/sourceAreaContext.js +1 -6
- package/src/sunlight/createSun.js +0 -1
- package/src/sunlight/initSunlight.js +19 -8
- package/src/terrain/initTerrain.js +7 -1
- package/src/terrain/loadTerrain.js +4 -1
- package/src/terrain/mapElevationOf.js +5 -1
- package/src/terrain/onTerrainAdd.js +11 -1
- package/src/terrain/onTerrainRemove.js +10 -1
- package/src/textures/nativeTextureFor.js +2 -3
- package/src/textures/uploadCanvasTexture.js +11 -2
- package/src/utils/yieldTask.js +5 -0
- package/src/vector-style/appendQuotedStyleCharacter.js +22 -0
- package/src/vector-style/arrayContainsRange.js +8 -0
- package/src/vector-style/evaluateBoolean.js +18 -0
- package/src/vector-style/evaluateCoalesceOrCase.js +21 -0
- package/src/vector-style/evaluateComparison.js +16 -0
- package/src/vector-style/evaluateIExpression.js +8 -0
- package/src/vector-style/evaluateInput.js +6 -0
- package/src/vector-style/evaluateInterpolate.js +27 -0
- package/src/vector-style/evaluateMatch.js +12 -0
- package/src/vector-style/evaluateMath.js +14 -0
- package/src/vector-style/evaluateMembership.js +18 -0
- package/src/vector-style/evaluateNegation.js +13 -0
- package/src/vector-style/evaluatePrimitive.js +9 -0
- package/src/vector-style/evaluateStep.js +11 -0
- package/src/vector-style/evaluateStyle.js +33 -0
- package/src/vector-style/evaluateToExpression.js +14 -0
- package/src/vector-style/fillVectorPaint.js +17 -0
- package/src/vector-style/lineVectorPaint.js +21 -0
- package/src/vector-style/parseFunctionalColor.js +14 -0
- package/src/vector-style/parseHexColor.js +13 -0
- package/src/vector-style/parseVectorStyle.js +13 -0
- package/src/vector-style/readPaintValue.js +6 -0
- package/src/vector-style/removeTrailingCommas.js +12 -0
- package/src/vector-style/scaleDashArray.js +13 -0
- package/src/vector-style/skipStyleComment.js +9 -0
- package/src/vector-style/stripStyleComments.js +21 -0
- package/src/vector-style/styleColor.js +11 -0
- package/src/vector-style/validateVectorLayers.js +10 -0
- package/src/vector-style/vectorPaint.js +8 -0
- package/src/vector-style/visibleStyle.js +7 -0
- package/src/vector-tiles/appendVectorBatch.js +22 -0
- package/src/vector-tiles/attachVectorTileBatch.js +17 -0
- package/src/vector-tiles/attachVectorTileBatches.js +15 -0
- package/src/vector-tiles/compareVectorLabelPriority.js +3 -0
- package/src/vector-tiles/compareVectorTileDistance.js +3 -0
- package/src/vector-tiles/configureVectorTileLayer.js +28 -0
- package/src/vector-tiles/createVectorLabel.js +22 -0
- package/src/vector-tiles/forwardVectorTileError.js +5 -0
- package/src/vector-tiles/loadVectorSprite.js +5 -0
- package/src/vector-tiles/loadVectorTile.js +36 -0
- package/src/vector-tiles/onVectorTileAdd.js +39 -0
- package/src/vector-tiles/onVectorTileMessage.js +10 -0
- package/src/vector-tiles/onVectorTileRemove.js +20 -0
- package/src/vector-tiles/onVectorTileWorkerError.js +11 -0
- package/src/vector-tiles/paintVectorTileBatch.js +12 -0
- package/src/vector-tiles/prepareVectorLabel.js +25 -0
- package/src/vector-tiles/prepareVectorStyleLayer.js +30 -0
- package/src/vector-tiles/prepareVectorTile.js +16 -0
- package/src/vector-tiles/projectVectorPaths.js +15 -0
- package/src/vector-tiles/projectVectorPoint.js +6 -0
- package/src/vector-tiles/projectVectorTriangles.js +18 -0
- package/src/vector-tiles/pruneVectorTiles.js +11 -0
- package/src/vector-tiles/pumpVectorTiles.js +18 -0
- package/src/vector-tiles/readTileJSON.js +17 -0
- package/src/vector-tiles/readVectorStyle.js +17 -0
- package/src/vector-tiles/refreshVectorTiles.js +5 -0
- package/src/vector-tiles/reserveVectorLabelCells.js +6 -0
- package/src/vector-tiles/retireVectorTileGroup.js +13 -0
- package/src/vector-tiles/revokeVectorWorkerUrl.js +9 -0
- package/src/vector-tiles/rotateVectorLabel.js +12 -0
- package/src/vector-tiles/rotateVectorLabels.js +6 -0
- package/src/vector-tiles/simplifyVectorPath.js +21 -0
- package/src/vector-tiles/updateVectorLabelMarker.js +27 -0
- package/src/vector-tiles/updateVectorLabelStyle.js +8 -0
- package/src/vector-tiles/updateVectorTileLabels.js +28 -0
- package/src/vector-tiles/updateVectorTilePaint.js +20 -0
- package/src/vector-tiles/updateVectorTiles.js +29 -0
- package/src/vector-tiles/validateVectorTileZooms.js +6 -0
- package/src/vector-tiles/vectorFeaturePaint.js +15 -0
- package/src/vector-tiles/vectorFeaturePaths.js +16 -0
- package/src/vector-tiles/vectorFeatureZoom.js +8 -0
- package/src/vector-tiles/vectorLabelAnchors.js +24 -0
- package/src/vector-tiles/vectorLabelCandidates.js +11 -0
- package/src/vector-tiles/vectorLabelCells.js +23 -0
- package/src/vector-tiles/vectorLabelIcon.js +30 -0
- package/src/vector-tiles/vectorLabelProperty.js +3 -0
- package/src/vector-tiles/vectorLabelText.js +10 -0
- package/src/vector-tiles/vectorSpriteIcon.js +11 -0
- package/src/vector-tiles/vectorStraightRun.js +14 -0
- package/src/vector-tiles/vectorStyleDependencies.js +15 -0
- package/src/vector-tiles/vectorStyleValue.js +5 -0
- package/src/vector-tiles/vectorStyleZoom.js +6 -0
- package/src/vector-tiles/vectorTileAwaited.js +9 -0
- package/src/vector-tiles/vectorTileOverlaps.js +4 -0
- package/src/vector-tiles/vectorTilePaint.js +10 -0
- package/src/vector-tiles/vectorTileSettings.js +17 -0
- package/src/vector-tiles/vectorTilesIdle.js +3 -0
- package/src/vector-tiles/vectorTolerance.js +4 -0
- package/src/vector-tiles/wrapVectorLabel.js +11 -0
- package/src/walk/initWalk.js +19 -6
- package/src/weakmaps/nativeProgramsByRenderer.js +1 -0
- package/src/weakmaps/pathProjectionByMap.js +1 -0
- package/src/weakmaps/streamTerrainByLayer.js +1 -0
- package/src/weakmaps/streamTerrainByMap.js +1 -0
- package/src/weakmaps/vectorTileOptionsByLayer.js +1 -0
- package/src/weakmaps/vectorWorkerByLayer.js +1 -0
- package/src/weakmaps/workerMapByLayer.js +1 -0
- package/src/workers/buildAreaInWorker.js +3 -27
- package/src/workers/cogWorker.js +20 -0
- package/src/workers/createGeometryWorker.js +1 -0
- package/src/workers/geometryWorker.js +15 -0
- package/src/workers/getCogInWorker.js +7 -0
- package/src/workers/modelWorker.js +10 -0
- package/src/workers/openCogInWorker.js +14 -0
- package/src/workers/runSourceWorker.js +32 -0
- package/src/workers/settleGeometryWorker.js +1 -1
- package/src/workers/vectorTileWorker.js +10 -0
- package/src/geometry/buildExtrudedPolygon.js +0 -10
- package/src/globals/layerCallInitHooks.js +0 -1
- package/src/sources/buildAreaPoint.js +0 -7
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
|
|
2
|
-
|
|
1
|
+
import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
|
|
2
|
+
|
|
3
3
|
import { sceneSunlightUniforms } from '../globals/sceneSunlightUniforms.js';
|
|
4
4
|
import { resizeSunlight } from '../shadows/resizeSunlight.js';
|
|
5
5
|
|
|
6
6
|
export function initializeRendererResources(layer, device) {
|
|
7
|
+
const renderer = rendererByLayer.get(layer);
|
|
7
8
|
const layout = device.createBindGroupLayout(/* alloc */ {
|
|
8
9
|
entries: /* alloc */ [
|
|
9
10
|
/* alloc */ { binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: /* alloc */ { type: 'uniform' } },
|
|
@@ -12,16 +13,13 @@ export function initializeRendererResources(layer, device) {
|
|
|
12
13
|
/* alloc */ { binding: 3, visibility: GPUShaderStage.FRAGMENT, buffer: /* alloc */ { type: 'read-only-storage' } },
|
|
13
14
|
]
|
|
14
15
|
});
|
|
15
|
-
const buffer =
|
|
16
|
-
const sampler =
|
|
17
|
-
const lights =
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const buffer = device.createBuffer(/* alloc */ { size: 80, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
|
|
17
|
+
const sampler = device.createSampler(/* alloc */ { compare: 'less-equal', minFilter: 'linear', magFilter: 'linear' });
|
|
18
|
+
const lights = device.createBuffer(/* alloc */ { size: 32, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST });
|
|
19
|
+
renderer.sunlight = /* alloc */ { layout, buffer, sampler, lights, size: 0 };
|
|
20
|
+
device.queue.writeBuffer(buffer, 0, sceneSunlightUniforms);
|
|
20
21
|
resizeSunlight(layer, 1);
|
|
21
|
-
|
|
22
|
-
emptyImage.width = 1;
|
|
23
|
-
emptyImage.height = 1;
|
|
24
|
-
rendererByLayer.get(layer).roofFallbackTexture = /* alloc */ {
|
|
22
|
+
renderer.roofFallbackTexture = /* alloc */ {
|
|
25
23
|
device,
|
|
26
24
|
texture: device.createTexture(/* alloc */ {
|
|
27
25
|
size: /* alloc */ [1, 1],
|
|
@@ -31,6 +29,6 @@ export function initializeRendererResources(layer, device) {
|
|
|
31
29
|
sampler: device.createSampler(/* alloc */ {
|
|
32
30
|
addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge',
|
|
33
31
|
}),
|
|
34
|
-
image:
|
|
32
|
+
image: null, format: 'rgba8unorm', srgb: false, uploaded: null,
|
|
35
33
|
};
|
|
36
34
|
}
|
package/src/gpu/mountRenderer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
|
|
2
|
-
|
|
1
|
+
import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
|
|
2
|
+
|
|
3
3
|
import { onMapChange } from '../scene/onMapChange.js';
|
|
4
4
|
import { startZoom } from '../animations/startZoom.js';
|
|
5
5
|
import { onZoomAnim } from '../animations/onZoomAnim.js';
|
|
@@ -8,17 +8,10 @@ import { endZoom } from '../animations/endZoom.js';
|
|
|
8
8
|
export function mountRenderer(layer, map, canvas) {
|
|
9
9
|
sizeByLayer.set(layer, null);
|
|
10
10
|
canvas.className = 'leaflet-3d';
|
|
11
|
-
canvas.style.cssText = 'position:absolute;top:0;left:0;pointer-events:none';
|
|
11
|
+
canvas.style.cssText = 'position:absolute;top:0;left:0;z-index:1;pointer-events:none';
|
|
12
12
|
canvas.setAttribute('role', 'img');
|
|
13
13
|
canvas.setAttribute('aria-label', layer.options.ariaLabel ?? '3D scene');
|
|
14
|
-
|
|
15
|
-
if (!pane) {
|
|
16
|
-
pane = map.createPane('webgpuPane', map.getContainer());
|
|
17
|
-
// The pitch sky uses 0 and may be inserted after this pane.
|
|
18
|
-
pane.style.zIndex = 1;
|
|
19
|
-
pane.style.pointerEvents = 'none';
|
|
20
|
-
}
|
|
21
|
-
pane.append(canvas);
|
|
14
|
+
map.getPane('mapPane').before(canvas);
|
|
22
15
|
map.on('move zoom rotate pitch resize viewreset layeradd layerremove', onMapChange, layer);
|
|
23
16
|
map.on('zoomstart', startZoom, layer);
|
|
24
17
|
map.on('zoomanim', onZoomAnim, layer);
|
|
@@ -2,6 +2,7 @@ export async function releaseRenderer(renderer, layer) {
|
|
|
2
2
|
try {
|
|
3
3
|
await renderer.device.queue.onSubmittedWorkDone();
|
|
4
4
|
renderer.depthTexture?.destroy();
|
|
5
|
+
renderer.colorTexture?.destroy();
|
|
5
6
|
renderer.roofFallbackTexture?.texture?.destroy();
|
|
6
7
|
renderer.uniformBuffer?.destroy();
|
|
7
8
|
renderer.sunlight?.texture?.destroy();
|
package/src/index.js
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import { L } from './globals/L.js';
|
|
2
2
|
import { layerProto } from './globals/layerProto.js';
|
|
3
|
-
import { layerCallInitHooks as sharedLayerCallInitHooks } from './globals/layerCallInitHooks.js';
|
|
4
3
|
import { removeLayer as sharedRemoveLayer } from './globals/removeLayer.js';
|
|
5
4
|
|
|
6
5
|
import './camera/mapCamera.js';
|
|
7
|
-
import { init3D } from './scene/init3D.js';
|
|
8
|
-
import { initNativeGPU } from './native/initNativeGPU.js';
|
|
9
|
-
import { initRaster } from './raster/initRaster.js';
|
|
10
|
-
import { setGeoJSONData } from './sources/setGeoJSONData.js';
|
|
11
|
-
import { initTerrain } from './terrain/initTerrain.js';
|
|
12
6
|
import './sunlight/initSunlight.js';
|
|
13
|
-
import { initTraffic } from './traffic/initTraffic.js';
|
|
14
7
|
import './walk/initWalk.js';
|
|
15
8
|
|
|
16
|
-
import { initializeNativeLayer } from './core/initializeNativeLayer.js';
|
|
17
9
|
import { layerLayerAdd } from './scene/addRegisteredLayer.js';
|
|
18
10
|
import { layerInitialize } from './scene/layerInitialize.js';
|
|
19
11
|
import { removeLayer } from './core/removeLayer.js';
|
|
20
12
|
import { getPitch } from './camera/getPitch.js';
|
|
21
13
|
import { getBearing } from './camera/getBearing.js';
|
|
14
|
+
import { setPitch } from './camera/setPitch.js';
|
|
15
|
+
import { setBearing } from './camera/setBearing.js';
|
|
22
16
|
import { setRotation } from './core/setRotation.js';
|
|
23
17
|
import { layerCallInitHooks } from './core/layerCallInitHooks.js';
|
|
18
|
+
import { leafletLayer } from './globals/leafletLayer.js';
|
|
19
|
+
import { constructLayer } from './core/constructLayer.js';
|
|
20
|
+
import { layerAddInitHook } from './core/layerAddInitHook.js';
|
|
21
|
+
import { layerMergeOptions } from './core/layerMergeOptions.js';
|
|
24
22
|
|
|
25
23
|
/**
|
|
26
24
|
* `new L.Layer({ source: { type, url, ...settings }, pane, attribution })`: layers with a `source`
|
|
@@ -39,19 +37,36 @@ import { layerCallInitHooks } from './core/layerCallInitHooks.js';
|
|
|
39
37
|
* Operations receive the layer explicitly, without subclasses or prototype replacement.
|
|
40
38
|
* Dataset-specific code and data (routes, timetables, API loaders) belong to the application, e.g. misc/.
|
|
41
39
|
*
|
|
42
|
-
* When `type` is omitted,
|
|
43
|
-
* 'pmtiles', *.tif/*.tiff URLs use 'cog', and other sources use '3d'.
|
|
40
|
+
* When `type` is omitted, *.pmtiles and *.tif/*.tiff URLs use 'raster'; other sources use 'vector'.
|
|
44
41
|
*/
|
|
45
42
|
|
|
46
|
-
layerProto.value = Object.defineProperties({}, Object.getOwnPropertyDescriptors(
|
|
47
|
-
|
|
43
|
+
layerProto.value = Object.defineProperties({}, Object.getOwnPropertyDescriptors(leafletLayer.prototype));
|
|
44
|
+
layerProto.value._layerAdd = leafletLayer.prototype._layerAdd;
|
|
45
|
+
layerProto.value.callInitHooks = leafletLayer.prototype.callInitHooks;
|
|
46
|
+
|
|
47
|
+
if (L.version.startsWith('2.')) {
|
|
48
|
+
// Keep the native prototype and instanceof contract, but finish options before init hooks.
|
|
49
|
+
Object.setPrototypeOf(constructLayer, leafletLayer);
|
|
50
|
+
constructLayer.prototype = leafletLayer.prototype;
|
|
51
|
+
constructLayer.initHooks = true;
|
|
52
|
+
constructLayer.addInitHook = layerAddInitHook;
|
|
53
|
+
constructLayer.mergeOptions = layerMergeOptions;
|
|
54
|
+
L.Layer = constructLayer;
|
|
55
|
+
leafletLayer.prototype.constructor = L.Layer;
|
|
56
|
+
leafletLayer.addInitHook(layerCallInitHooks);
|
|
57
|
+
} else {
|
|
58
|
+
leafletLayer.prototype.initialize = layerInitialize;
|
|
59
|
+
leafletLayer.prototype.callInitHooks = layerCallInitHooks;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Object.assign(leafletLayer.prototype, { _layerAdd: layerLayerAdd });
|
|
48
63
|
|
|
49
64
|
/**
|
|
50
|
-
* The '
|
|
65
|
+
* The 'vector' layer type: native WebGPU scene synchronized with the map camera.
|
|
51
66
|
* Layers on one map share a canvas, scene and camera; each has its own root transform.
|
|
52
67
|
*
|
|
53
68
|
* @typedef {Object} Layer3DOptions Layer options; pane and attribution remain standard L.Layer options.
|
|
54
|
-
* @property {
|
|
69
|
+
* @property {'vector'|'raster'|'terrain'|'traffic'} [type]
|
|
55
70
|
* @property {number[]} [center] Local origin [lat,lng]; defaults to the first map center.
|
|
56
71
|
* @property {number} [terrainOffset=0] Vertical offset in metres when terrain is enabled.
|
|
57
72
|
* @property {boolean} [terrainConform=false] Fit lower model geometry to local terrain elevation.
|
|
@@ -101,12 +116,6 @@ sharedLayerCallInitHooks.value = L.Layer.prototype.callInitHooks;
|
|
|
101
116
|
* @param {Layer3DOptions} [options] World origin comes from center or the first map centre.
|
|
102
117
|
*/
|
|
103
118
|
|
|
104
|
-
L.Layer.include({
|
|
105
|
-
initialize: layerInitialize,
|
|
106
|
-
_layerAdd: layerLayerAdd,
|
|
107
|
-
callInitHooks: layerCallInitHooks,
|
|
108
|
-
});
|
|
109
|
-
|
|
110
119
|
sharedRemoveLayer.value = L.Map.prototype.removeLayer;
|
|
111
|
-
L.Map.
|
|
112
|
-
L.Marker.
|
|
120
|
+
Object.assign(L.Map.prototype, { removeLayer, getPitch, getBearing, setPitch, setBearing });
|
|
121
|
+
Object.assign(L.Marker.prototype, { setRotation });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { L } from '../globals/L.js';
|
|
2
|
+
import { layerControlAddItem } from '../globals/layerControlAddItem.js';
|
|
3
|
+
|
|
4
|
+
// Leaflet 2 stores layer associations on its control, not on the input.
|
|
5
|
+
if (layerControlAddItem && !L.Control.Layers) L.LayersControl.prototype._addItem = addLayerControlInputId;
|
|
6
|
+
|
|
7
|
+
export function addLayerControlInputId(entry) {
|
|
8
|
+
const label = layerControlAddItem.call(this, entry);
|
|
9
|
+
label.querySelector('.leaflet-control-layers-selector').layerId = L.Util.stamp(entry.layer);
|
|
10
|
+
return label;
|
|
11
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { L } from '../globals/L.js';
|
|
2
2
|
import { placeEntryElement } from './placeEntryElement.js';
|
|
3
|
+
import './layerControlInputId.js';
|
|
4
|
+
|
|
3
5
|
export function placeEntry(map, layer, element) {
|
|
4
6
|
let input, entry;
|
|
5
7
|
for (input of map.getContainer().querySelectorAll('.leaflet-control-layers-selector')) {
|
|
@@ -19,17 +19,18 @@ import { materialShaders } from '../shaders/materialShaders.js';
|
|
|
19
19
|
import { reportCompilation } from '../gpu/reportShaderCompilation.js';
|
|
20
20
|
|
|
21
21
|
export function createProgram(layer, material = defaultMaterial) {
|
|
22
|
+
const renderer = rendererByLayer.get(layer), { device } = renderer;
|
|
22
23
|
const shaders = materialShaders(
|
|
23
24
|
material,
|
|
24
25
|
!!layer.options.nightSparkle,
|
|
25
26
|
material.terrain ? elevationWGSL : ''
|
|
26
27
|
);
|
|
27
|
-
const vertex =
|
|
28
|
+
const vertex = device.createShaderModule((
|
|
28
29
|
vertexShader.code = shaders.vertex,
|
|
29
30
|
vertexShader
|
|
30
31
|
));
|
|
31
32
|
vertexShader.code = null;
|
|
32
|
-
const fragment =
|
|
33
|
+
const fragment = device.createShaderModule((
|
|
33
34
|
fragmentShader.code = shaders.fragment,
|
|
34
35
|
fragmentShader
|
|
35
36
|
));
|
|
@@ -45,17 +46,17 @@ export function createProgram(layer, material = defaultMaterial) {
|
|
|
45
46
|
shaders.textured ? uVLayout : null,
|
|
46
47
|
];
|
|
47
48
|
if (material.instanced) vertexBuffers.push(instanceLayout);
|
|
48
|
-
const bindGroupLayout = createProgramLayout(
|
|
49
|
-
const pipelineLayout =
|
|
49
|
+
const bindGroupLayout = createProgramLayout(device, shaders);
|
|
50
|
+
const pipelineLayout = device.createPipelineLayout((
|
|
50
51
|
sharedPipelineLayout.bindGroupLayouts[0] = bindGroupLayout,
|
|
51
|
-
sharedPipelineLayout.bindGroupLayouts[1] =
|
|
52
|
+
sharedPipelineLayout.bindGroupLayouts[1] = renderer.sunlight.layout,
|
|
52
53
|
sharedPipelineLayout
|
|
53
54
|
));
|
|
54
55
|
sharedPipelineLayout.bindGroupLayouts[0] = null;
|
|
55
56
|
sharedPipelineLayout.bindGroupLayouts[1] = null;
|
|
56
57
|
const uniforms = createProgramUniforms(material);
|
|
57
58
|
return /* alloc */ {
|
|
58
|
-
device
|
|
59
|
+
device,
|
|
59
60
|
vertex,
|
|
60
61
|
fragment,
|
|
61
62
|
bindings: shaders.bindings,
|
|
@@ -13,5 +13,6 @@ export function createProgramUniforms(material) {
|
|
|
13
13
|
if (material.emissiveTexture) uniforms.emissiveTexture = /* alloc */ { value: material.emissiveTexture };
|
|
14
14
|
if (material.occlusionTexture) uniforms.occlusionTexture = /* alloc */ { value: material.occlusionTexture };
|
|
15
15
|
if (material.roofTexture || material.wallTexture) uniforms.roofTexture = /* alloc */ { value: null };
|
|
16
|
+
if (material.nativeStroke) uniforms.strokeScale = /* alloc */ { value: 1 };
|
|
16
17
|
return uniforms;
|
|
17
18
|
}
|
package/src/models/loadModel.js
CHANGED
|
@@ -3,14 +3,14 @@ import { modelByLayer } from '../weakmaps/modelByLayer.js';
|
|
|
3
3
|
import { modelUrlByLayer } from '../weakmaps/modelUrlByLayer.js';
|
|
4
4
|
import { rootByLayer } from '../weakmaps/rootByLayer.js';
|
|
5
5
|
import { terrain3DByMap } from '../weakmaps/terrain3DByMap.js';
|
|
6
|
+
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
import {
|
|
10
|
+
import { runSourceWorker } from '../workers/runSourceWorker.js';
|
|
10
11
|
import { setParent } from '../scene/setParent.js';
|
|
11
12
|
import { emptyNode } from '../scene/createSceneNode.js';
|
|
12
13
|
import { conformModelToTerrain } from '../geometry/conformModelToTerrain.js';
|
|
13
|
-
import { loadModelResources } from './loadModelResources.js';
|
|
14
14
|
import { createModelContext } from './createModelContext.js';
|
|
15
15
|
import { buildModelNodes } from './buildModelNodes.js';
|
|
16
16
|
import { applyModelTransform } from './applyModelTransform.js';
|
|
@@ -22,14 +22,10 @@ import { applyModelTransform } from './applyModelTransform.js';
|
|
|
22
22
|
export async function loadModel(layer) {
|
|
23
23
|
await addedByLayer.get(layer).promise;
|
|
24
24
|
const url = /* alloc */ new URL(modelUrlByLayer.get(layer), document.baseURI).href;
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const data = await response.arrayBuffer();
|
|
30
|
-
const description = decodeModel(data);
|
|
31
|
-
const directory = /* alloc */ new URL('.', url).href;
|
|
32
|
-
const images = await loadModelResources(layer, description, directory);
|
|
25
|
+
const { description, images } = await runSourceWorker(layer._map, layer.options.workerUrl,
|
|
26
|
+
/* alloc */ { type: 'model', url });
|
|
27
|
+
await addedByLayer.get(layer).promise;
|
|
28
|
+
await cameraViewByMap.get(layer._map);
|
|
33
29
|
const context = createModelContext(layer, description, images);
|
|
34
30
|
const scene = description.scenes?.[description.scene || 0];
|
|
35
31
|
if (!scene) throw /* alloc */ new Error('Missing glTF scene');
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
import { addedByLayer } from '../weakmaps/addedByLayer.js';
|
|
2
|
-
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
3
|
-
|
|
4
1
|
import { geometryEmpty } from '../globals/geometryEmpty.js';
|
|
5
2
|
import { loadBuffer } from './loadBuffer.js';
|
|
6
3
|
import { loadImage } from '../textures/loadModelImage.js';
|
|
7
4
|
|
|
8
|
-
export async function loadModelResources(
|
|
5
|
+
export async function loadModelResources(description, directory) {
|
|
9
6
|
const bufferRequests = /* alloc */ [];
|
|
10
7
|
let buffer;
|
|
11
8
|
for (buffer of description.buffers || geometryEmpty) bufferRequests.push(loadBuffer(buffer, directory));
|
|
12
9
|
await Promise.all(bufferRequests);
|
|
13
|
-
await addedByLayer.get(layer).promise;
|
|
14
10
|
const imageRequests = /* alloc */ [];
|
|
15
11
|
let image;
|
|
16
12
|
for (image of description.images || geometryEmpty) imageRequests.push(loadImage(description, directory, image));
|
|
17
|
-
|
|
18
|
-
await cameraViewByMap.get(layer._map);
|
|
19
|
-
return images;
|
|
13
|
+
return Promise.all(imageRequests);
|
|
20
14
|
}
|
package/src/models/modelNode.js
CHANGED
|
@@ -4,8 +4,6 @@ import { geometryEmpty } from '../globals/geometryEmpty.js';
|
|
|
4
4
|
import { emptyNode } from '../scene/createSceneNode.js';
|
|
5
5
|
import { nodeMatrix } from '../transforms/modelNodeMatrix.js';
|
|
6
6
|
import { setParent } from '../scene/setParent.js';
|
|
7
|
-
import { readModelAttributes } from './readModelAttributes.js';
|
|
8
|
-
import { readModelIndices } from './readModelIndices.js';
|
|
9
7
|
import { createModelGeometry } from '../geometry/createModelGeometry.js';
|
|
10
8
|
|
|
11
9
|
export function modelNode(context, index) {
|
|
@@ -20,13 +18,11 @@ export function modelNode(context, index) {
|
|
|
20
18
|
name: spec.name
|
|
21
19
|
};
|
|
22
20
|
group.matrix = nodeMatrix(spec);
|
|
23
|
-
let primitive,
|
|
21
|
+
let primitive, attributes, built, mesh, child;
|
|
24
22
|
if (spec.mesh !== undefined) {
|
|
25
23
|
for (primitive of description.meshes[spec.mesh].primitives) {
|
|
26
|
-
|
|
27
|
-
attributes =
|
|
28
|
-
vertexCount = attributeData.vertexCount;
|
|
29
|
-
readModelIndices(description, primitive, attributes, vertexCount);
|
|
24
|
+
// Node instances own their CPU data and GPU buffers, even when they share a glTF mesh.
|
|
25
|
+
attributes = structuredClone(primitive.preparedAttributes);
|
|
30
26
|
built = createModelGeometry(context, primitive, attributes);
|
|
31
27
|
mesh = /* alloc */ {
|
|
32
28
|
...emptyNode(),
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { decodeModel } from './decodeModel.js';
|
|
2
|
+
import { loadModelResources } from './loadModelResources.js';
|
|
3
|
+
import { prepareModelGeometry } from './prepareModelGeometry.js';
|
|
4
|
+
|
|
5
|
+
export async function prepareModel(url) {
|
|
6
|
+
const response = await fetch(url);
|
|
7
|
+
if (!response.ok) throw /* alloc */ new Error(`Unable to load model: HTTP ${response.status}`);
|
|
8
|
+
const description = decodeModel(await response.arrayBuffer());
|
|
9
|
+
const scene = description.scenes?.[description.scene || 0];
|
|
10
|
+
if (!scene) throw /* alloc */ new Error('Missing glTF scene');
|
|
11
|
+
const images = await loadModelResources(description, /* alloc */ new URL('.', url).href);
|
|
12
|
+
const transfers = prepareModelGeometry(description, scene);
|
|
13
|
+
let image;
|
|
14
|
+
for (image of images) transfers.push(image);
|
|
15
|
+
delete description.buffers;
|
|
16
|
+
delete description.bufferViews;
|
|
17
|
+
delete description.accessors;
|
|
18
|
+
return /* alloc */ { description, images, transfers };
|
|
19
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { geometryEmpty } from '../globals/geometryEmpty.js';
|
|
2
|
+
import { prepareModelPrimitive } from './prepareModelPrimitive.js';
|
|
3
|
+
|
|
4
|
+
export function prepareModelGeometry(description, scene) {
|
|
5
|
+
const pending = scene.nodes.slice(), visited = /* alloc */ new Set();
|
|
6
|
+
const meshes = /* alloc */ new Set(), transfers = /* alloc */ new Set();
|
|
7
|
+
let index, spec, primitive, attribute, child;
|
|
8
|
+
while (pending.length) {
|
|
9
|
+
index = pending.pop();
|
|
10
|
+
if (visited.has(index)) continue;
|
|
11
|
+
visited.add(index);
|
|
12
|
+
spec = description.nodes[index];
|
|
13
|
+
if (!spec) throw /* alloc */ new Error('Invalid glTF node');
|
|
14
|
+
if (spec.mesh !== undefined) meshes.add(spec.mesh);
|
|
15
|
+
for (child of spec.children || geometryEmpty) pending.push(child);
|
|
16
|
+
}
|
|
17
|
+
for (index of meshes) {
|
|
18
|
+
for (primitive of description.meshes[index].primitives) {
|
|
19
|
+
for (attribute of Object.values(prepareModelPrimitive(description, primitive))) {
|
|
20
|
+
transfers.add(attribute.data.buffer);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return /* alloc */ [...transfers];
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { readModelAttributes } from './readModelAttributes.js';
|
|
2
|
+
import { readModelIndices } from './readModelIndices.js';
|
|
3
|
+
import { vertexNormals } from '../geometry/vertexNormals.js';
|
|
4
|
+
|
|
5
|
+
export function prepareModelPrimitive(description, primitive) {
|
|
6
|
+
const { attributes, vertexCount } = readModelAttributes(description, primitive);
|
|
7
|
+
readModelIndices(description, primitive, attributes, vertexCount);
|
|
8
|
+
if (!attributes.normal) {
|
|
9
|
+
attributes.normal = /* alloc */ { size: 3,
|
|
10
|
+
data: vertexNormals(attributes.position.data, attributes.index?.data) };
|
|
11
|
+
}
|
|
12
|
+
if (attributes.index?.data instanceof Uint8Array) {
|
|
13
|
+
attributes.index.data = Uint16Array.from(attributes.index.data);
|
|
14
|
+
}
|
|
15
|
+
primitive.preparedAttributes = attributes;
|
|
16
|
+
return attributes;
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { mvtEdgeX } from './mvtEdgeX.js';
|
|
2
|
+
|
|
3
|
+
export function addMvtCrossings(edges, levels) {
|
|
4
|
+
let i = 0, j, a, b, top, bottom, start, end;
|
|
5
|
+
for (; i < edges.length; i++) {
|
|
6
|
+
a = edges[i];
|
|
7
|
+
for (j = i + 1; j < edges.length; j++) {
|
|
8
|
+
b = edges[j];
|
|
9
|
+
top = Math.max(a[0][1], b[0][1]);
|
|
10
|
+
bottom = Math.min(a[1][1], b[1][1]);
|
|
11
|
+
if (top >= bottom) continue;
|
|
12
|
+
start = mvtEdgeX(a, top) - mvtEdgeX(b, top);
|
|
13
|
+
end = mvtEdgeX(a, bottom) - mvtEdgeX(b, bottom);
|
|
14
|
+
if (start * end < 0) levels.add(top + (bottom - top) * start / (start - end));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { mvtEdgeX } from './mvtEdgeX.js';
|
|
2
|
+
import { sortMvtActiveEdges } from './sortMvtActiveEdges.js';
|
|
3
|
+
|
|
4
|
+
export function appendMvtBandTriangles(edges, top, bottom, triangles) {
|
|
5
|
+
const mid = (top + bottom) / 2, active = /* alloc */ [];
|
|
6
|
+
let edge, i = 0, leftTop, leftBottom, rightTop, rightBottom;
|
|
7
|
+
for (edge of edges) {
|
|
8
|
+
if (edge[0][1] < mid && edge[1][1] > mid) {
|
|
9
|
+
active.push(/* alloc */ { edge, x: mvtEdgeX(edge, mid) });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
sortMvtActiveEdges(active);
|
|
13
|
+
if (active.length % 2) throw /* alloc */ new Error('Unbalanced MVT polygon edges');
|
|
14
|
+
for (; i < active.length; i += 2) {
|
|
15
|
+
leftTop = mvtEdgeX(active[i].edge, top);
|
|
16
|
+
leftBottom = mvtEdgeX(active[i].edge, bottom);
|
|
17
|
+
rightTop = mvtEdgeX(active[i + 1].edge, top);
|
|
18
|
+
rightBottom = mvtEdgeX(active[i + 1].edge, bottom);
|
|
19
|
+
if (rightTop < leftTop - 1e-8 || rightBottom < leftBottom - 1e-8) {
|
|
20
|
+
throw /* alloc */ new Error('Crossing MVT polygon edges');
|
|
21
|
+
}
|
|
22
|
+
if ((rightTop - leftTop) * (bottom - top) > 1e-6) {
|
|
23
|
+
triangles.push(/* alloc */ [/* alloc */ [leftTop, top], /* alloc */ [rightTop, top],
|
|
24
|
+
/* alloc */ [leftBottom, bottom]]);
|
|
25
|
+
}
|
|
26
|
+
if ((rightBottom - leftBottom) * (bottom - top) > 1e-6) {
|
|
27
|
+
triangles.push(/* alloc */ [/* alloc */ [rightTop, top], /* alloc */ [rightBottom, bottom],
|
|
28
|
+
/* alloc */ [leftBottom, bottom]]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function appendMvtCoordinates(commands, state, count) {
|
|
2
|
+
let i = 0, dx, dy;
|
|
3
|
+
for (; i < count; i++) {
|
|
4
|
+
dx = commands[state.index++];
|
|
5
|
+
dy = commands[state.index++];
|
|
6
|
+
if (dx > 0xffffffff || dy > 0xffffffff) throw /* alloc */ new Error('Invalid MVT coordinate');
|
|
7
|
+
state.x += dx % 2 ? -(dx + 1) / 2 : dx / 2;
|
|
8
|
+
state.y += dy % 2 ? -(dy + 1) / 2 : dy / 2;
|
|
9
|
+
state.path.push(/* alloc */ [state.x, state.y]);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { tessellateVectorRings } from './tessellateVectorRings.js';
|
|
2
|
+
import { triangulate } from '../triangulation/triangulate.js';
|
|
3
|
+
import { isMvtFallbackError } from './isMvtFallbackError.js';
|
|
4
|
+
|
|
5
|
+
export function appendMvtPolygonTriangles(rings, paths, vertices, triangles) {
|
|
6
|
+
let indices, index, triangle, points, i = 0;
|
|
7
|
+
try {
|
|
8
|
+
indices = triangulate(paths[0], paths.slice(1));
|
|
9
|
+
for (triangle of indices) {
|
|
10
|
+
points = /* alloc */ [];
|
|
11
|
+
for (index of triangle) points.push(/* alloc */ [vertices[index].x, vertices[index].y]);
|
|
12
|
+
triangles.push(points);
|
|
13
|
+
}
|
|
14
|
+
} catch (error) {
|
|
15
|
+
if (!isMvtFallbackError(error)) throw error;
|
|
16
|
+
indices = tessellateVectorRings(rings);
|
|
17
|
+
for (; i < indices.length; i++) triangles.push(indices[i]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { finishMvtPath } from './finishMvtPath.js';
|
|
2
|
+
|
|
3
|
+
export function beginMvtPath(state, paths, type, count) {
|
|
4
|
+
finishMvtPath(state.path, type, state.closed);
|
|
5
|
+
if (type !== 1 && count !== 1) throw /* alloc */ new Error('Invalid MVT MoveTo');
|
|
6
|
+
state.path = /* alloc */ [];
|
|
7
|
+
paths.push(state.path);
|
|
8
|
+
state.closed = false;
|
|
9
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function closeMvtPath(state, type, count) {
|
|
2
|
+
if (type !== 3 || count !== 1 || !state.path || state.closed || state.path.length < 3) {
|
|
3
|
+
throw /* alloc */ new Error('Invalid MVT ClosePath');
|
|
4
|
+
}
|
|
5
|
+
state.path.push(/* alloc */ [...state.path[0]]);
|
|
6
|
+
state.closed = true;
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { finiteMvtCoordinate } from './finiteMvtCoordinate.js';
|
|
2
|
+
|
|
3
|
+
export function collectMvtEdges(rings, edges, levels) {
|
|
4
|
+
let ring, i, a, b;
|
|
5
|
+
for (ring of rings) {
|
|
6
|
+
if (ring.length < 4 || ring[0][0] !== ring.at(-1)[0] || ring[0][1] !== ring.at(-1)[1]) {
|
|
7
|
+
throw /* alloc */ new Error('MVT tessellation requires closed rings');
|
|
8
|
+
}
|
|
9
|
+
for (i = 1; i < ring.length; i++) {
|
|
10
|
+
a = ring[i - 1];
|
|
11
|
+
b = ring[i];
|
|
12
|
+
if (!finiteMvtCoordinate(a) || !finiteMvtCoordinate(b)) {
|
|
13
|
+
throw /* alloc */ new Error('Invalid MVT ring coordinate');
|
|
14
|
+
}
|
|
15
|
+
levels.add(a[1]);
|
|
16
|
+
if (a[1] !== b[1]) edges.push(/* alloc */ [a[1] < b[1] ? a : b, a[1] < b[1] ? b : a]);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { createMvtReader } from './createMvtReader.js';
|
|
2
|
+
import { readMvtField } from './readMvtField.js';
|
|
3
|
+
import { readMvtLayer } from './readMvtLayer.js';
|
|
4
|
+
import { readMvtMessage } from './readMvtMessage.js';
|
|
5
|
+
import { skipMvtField } from './skipMvtField.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Decode an uncompressed MVT ArrayBuffer/Uint8Array into tile-local layers.
|
|
9
|
+
* Feature types: 0 unknown, 1 points, 2 lines, 3 polygon rings (including holes).
|
|
10
|
+
* Integers outside JavaScript's safe range are returned as decimal strings.
|
|
11
|
+
*/
|
|
12
|
+
export function decodeVectorTile(buffer) {
|
|
13
|
+
if (!(buffer instanceof ArrayBuffer) && !(buffer instanceof Uint8Array)) {
|
|
14
|
+
throw /* alloc */ new TypeError('MVT input must be an ArrayBuffer or Uint8Array');
|
|
15
|
+
}
|
|
16
|
+
const bytes = buffer instanceof Uint8Array ? buffer : /* alloc */ new Uint8Array(buffer);
|
|
17
|
+
const reader = createMvtReader(bytes);
|
|
18
|
+
const layers = /* alloc */ [], names = /* alloc */ new Set();
|
|
19
|
+
let field, wire, layer;
|
|
20
|
+
while (reader.pos < reader.bytes.length) {
|
|
21
|
+
[field, wire] = readMvtField(reader);
|
|
22
|
+
if (field !== 3) {
|
|
23
|
+
skipMvtField(reader, wire);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
layer = readMvtLayer(readMvtMessage(reader, wire));
|
|
27
|
+
if (names.has(layer.name)) throw /* alloc */ new Error('Duplicate MVT layer name');
|
|
28
|
+
names.add(layer.name);
|
|
29
|
+
layers.push(layer);
|
|
30
|
+
}
|
|
31
|
+
return layers;
|
|
32
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { finiteMvtCoordinate } from './finiteMvtCoordinate.js';
|
|
2
|
+
|
|
3
|
+
export function groupMvtPolygons(rings) {
|
|
4
|
+
const polygons = /* alloc */ [];
|
|
5
|
+
let polygon, exteriorSign, ring, area, i;
|
|
6
|
+
for (ring of rings) {
|
|
7
|
+
if (ring.length < 4 || ring[0][0] !== ring.at(-1)[0] || ring[0][1] !== ring.at(-1)[1]) {
|
|
8
|
+
throw /* alloc */ new Error('MVT tessellation requires closed rings');
|
|
9
|
+
}
|
|
10
|
+
area = 0;
|
|
11
|
+
for (i = 1; i < ring.length; i++) {
|
|
12
|
+
if (!finiteMvtCoordinate(ring[i]) || !finiteMvtCoordinate(ring[i - 1])) {
|
|
13
|
+
throw /* alloc */ new Error('Invalid MVT ring coordinate');
|
|
14
|
+
}
|
|
15
|
+
area += ring[i - 1][0] * ring[i][1] - ring[i][0] * ring[i - 1][1];
|
|
16
|
+
}
|
|
17
|
+
if (!polygon || area && Math.sign(area) === exteriorSign) {
|
|
18
|
+
polygon = /* alloc */ [];
|
|
19
|
+
polygons.push(polygon);
|
|
20
|
+
exteriorSign = Math.sign(area);
|
|
21
|
+
}
|
|
22
|
+
polygon.push(ring);
|
|
23
|
+
}
|
|
24
|
+
return polygons;
|
|
25
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function isMvtFallbackError(error) {
|
|
2
|
+
return error.message === 'Polygon triangulation area mismatch' ||
|
|
3
|
+
error.message === 'Degenerate polygon ring' ||
|
|
4
|
+
error.message === 'Unable to triangulate polygon: invalid or self-intersecting rings' ||
|
|
5
|
+
error.message === 'Unable to connect polygon hole';
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function mergeMvtActiveEdges(active, sorted, left, mid, right) {
|
|
2
|
+
let i = left, j = mid, k = left;
|
|
3
|
+
while (i < mid && j < right) {
|
|
4
|
+
if (active[j].x < active[i].x) sorted[k++] = active[j++];
|
|
5
|
+
else sorted[k++] = active[i++];
|
|
6
|
+
}
|
|
7
|
+
while (i < mid) sorted[k++] = active[i++];
|
|
8
|
+
while (j < right) sorted[k++] = active[j++];
|
|
9
|
+
}
|