leaflet-city-mapper 0.0.5 → 0.0.7
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 +10 -5
- package/dist/leaflet-city-mapper-src.js +6874 -6304
- package/dist/leaflet-city-mapper-src.js.map +4 -4
- package/dist/leaflet-city-mapper-worker-src.js +2766 -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 +15 -3
- package/libs/leaflet.js +1 -1
- package/package.json +1 -1
- package/src/camera/setBearing.js +5 -0
- package/src/camera/setPitch.js +5 -0
- package/src/cog/initCog.js +2 -2
- package/src/collision/collectIntersections.js +16 -0
- package/src/collision/collider.js +3 -2
- package/src/collision/countCrossings.js +15 -0
- package/src/collision/insideMesh.js +4 -24
- package/src/collision/insideWalker.js +2 -2
- package/src/collision/readTriangle.js +7 -4
- package/src/collision/setTrafficNormal.js +9 -0
- package/src/collision/trafficCollision.js +4 -9
- package/src/collision/vertexCount.js +3 -0
- package/src/controls/cameraControls.js +6 -0
- package/src/core/gridlayerGetTiledPixelBounds.js +37 -4
- package/src/core/markerSetPos.js +1 -1
- package/src/core/popupGetEvents.js +1 -1
- package/src/core/popupUpdatePosition.js +8 -8
- package/src/core/tooltipGetEvents.js +1 -1
- package/src/core/tooltipSetPosition.js +2 -2
- package/src/geometry/appendNativeTriangle.js +2 -2
- 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/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/mountRenderer.js +4 -11
- package/src/gpu/releaseRenderer.js +1 -0
- package/src/index.js +6 -12
- 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 +30 -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/nativeVectorGeometry.js +23 -0
- package/src/native/orderNativeGridLayer.js +14 -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/syncGridLayer.js +48 -3
- package/src/native/syncNativeStrokeAnchors.js +12 -0
- package/src/native/syncNativeStrokeZoom.js +29 -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/raster/setRasterOpacity.js +1 -1
- package/src/raster/setRasterZIndex.js +1 -1
- package/src/rendering/collectVisibleMesh.js +5 -2
- 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 +9 -0
- package/src/scene/initializerFor.js +3 -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/sources/attachAreaMesh.js +5 -6
- package/src/sources/buildArea.js +7 -17
- package/src/sources/buildAreaFeature.js +5 -24
- package/src/sources/buildAreaFeatures.js +14 -0
- package/src/sources/initVectorTiles.js +15 -0
- package/src/sources/isVectorTileSource.js +4 -0
- package/src/sources/matchesAreaTile.js +7 -0
- package/src/sources/prepareAreaGeometryJob.js +2 -11
- package/src/sources/projectAreaPolygons.js +15 -0
- package/src/sources/readyVectorTiles.js +10 -0
- package/src/sources/sourceAreaContext.js +1 -6
- package/src/sunlight/createSun.js +0 -1
- 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/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/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 +43 -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/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 +26 -0
- package/src/vector-tiles/vectorLabelIcon.js +30 -0
- package/src/vector-tiles/vectorLabelProperty.js +3 -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/animateWalker.js +2 -13
- package/src/walk/updateWalkerFrame.js +19 -0
- package/src/weakmaps/nativeProgramsByRenderer.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/acquireGeometryWorker.js +2 -5
- package/src/workers/buildAreaInWorker.js +3 -23
- package/src/workers/cogWorker.js +21 -0
- package/src/workers/createGeometryWorker.js +20 -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/sources/buildAreaPoint.js +0 -7
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function parseHexColor(value) {
|
|
2
|
+
let i = 0, offset = 0;
|
|
3
|
+
if (value.length === 4) {
|
|
4
|
+
value = '#' + value[1] + value[1] + value[2] + value[2] + value[3] + value[3];
|
|
5
|
+
}
|
|
6
|
+
const color = /* alloc */ [];
|
|
7
|
+
for (i = 1; i < 6; i += 2) {
|
|
8
|
+
offset = parseInt(value.slice(i, i + 2), 16);
|
|
9
|
+
color.push(offset);
|
|
10
|
+
}
|
|
11
|
+
color.push(1);
|
|
12
|
+
return color;
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { removeTrailingCommas } from './removeTrailingCommas.js';
|
|
2
|
+
import { stripStyleComments } from './stripStyleComments.js';
|
|
3
|
+
import { validateVectorLayers } from './validateVectorLayers.js';
|
|
4
|
+
|
|
5
|
+
export function parseVectorStyle(text) {
|
|
6
|
+
const prefix = /^\s*(?:const|let|var)\s+otm_layers\s*=\s*/.exec(text);
|
|
7
|
+
if (prefix) text = text.slice(prefix[0].length);
|
|
8
|
+
const cleaned = removeTrailingCommas(stripStyleComments(text).trim().replace(/;$/, ''));
|
|
9
|
+
const document = JSON.parse(cleaned);
|
|
10
|
+
const layers = document.layers ?? document;
|
|
11
|
+
validateVectorLayers(layers);
|
|
12
|
+
return layers;
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function removeTrailingCommas(json) {
|
|
2
|
+
let cleaned = '', quoted = false, escaped = false, i = 0, char = '';
|
|
3
|
+
for (i = 0; i < json.length; i++) {
|
|
4
|
+
char = json[i];
|
|
5
|
+
if (!quoted && char === ',' && /^\s*[\]}]/.test(json.slice(i + 1))) continue;
|
|
6
|
+
cleaned += char;
|
|
7
|
+
if (escaped) escaped = false;
|
|
8
|
+
else if (quoted && char === '\\') escaped = true;
|
|
9
|
+
else if (char === '"') quoted = !quoted;
|
|
10
|
+
}
|
|
11
|
+
return cleaned;
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { evaluateStyle } from './evaluateStyle.js';
|
|
2
|
+
|
|
3
|
+
export function scaleDashArray(dash, weight, properties, zoom) {
|
|
4
|
+
if (!dash) return undefined;
|
|
5
|
+
let values = dash, i = 0, result = '';
|
|
6
|
+
if (typeof dash[0] !== 'number') values = evaluateStyle(dash, properties, zoom);
|
|
7
|
+
if (!Array.isArray(values)) throw /* alloc */ new TypeError('Style dash array must be an array');
|
|
8
|
+
for (i = 0; i < values.length; i++) {
|
|
9
|
+
if (i) result += ' ';
|
|
10
|
+
result += values[i] * weight;
|
|
11
|
+
}
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function skipStyleComment(text, index, marker) {
|
|
2
|
+
if (marker === '/') {
|
|
3
|
+
while (index < text.length && text[index] !== '\n') index++;
|
|
4
|
+
return index;
|
|
5
|
+
}
|
|
6
|
+
const end = text.indexOf('*/', index + 2);
|
|
7
|
+
if (end < 0) throw /* alloc */ new Error('Unterminated style comment');
|
|
8
|
+
return end + 1;
|
|
9
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { appendQuotedStyleCharacter } from './appendQuotedStyleCharacter.js';
|
|
2
|
+
import { skipStyleComment } from './skipStyleComment.js';
|
|
3
|
+
|
|
4
|
+
export function stripStyleComments(text) {
|
|
5
|
+
let json = '', i = 0, char = '', next = '', converted = undefined;
|
|
6
|
+
const state = /* alloc */ { quoted: '', escaped: false };
|
|
7
|
+
for (i = 0; i < text.length; i++) {
|
|
8
|
+
char = text[i];
|
|
9
|
+
next = text[i + 1];
|
|
10
|
+
converted = appendQuotedStyleCharacter(char, state);
|
|
11
|
+
if (converted !== undefined) {
|
|
12
|
+
json += converted;
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
if (char === '/' && (next === '/' || next === '*')) {
|
|
16
|
+
i = skipStyleComment(text, i, next);
|
|
17
|
+
json += next === '/' ? '\n' : ' ';
|
|
18
|
+
} else json += char;
|
|
19
|
+
}
|
|
20
|
+
return json;
|
|
21
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { vectorStyleNamedColors } from '../globals/vectorStyleNamedColors.js';
|
|
2
|
+
import { parseFunctionalColor } from './parseFunctionalColor.js';
|
|
3
|
+
import { parseHexColor } from './parseHexColor.js';
|
|
4
|
+
|
|
5
|
+
export function styleColor(value) {
|
|
6
|
+
if (Object.hasOwn(vectorStyleNamedColors, value)) return vectorStyleNamedColors[value];
|
|
7
|
+
if (/^#[0-9a-f]{3}$/i.test(value) || /^#[0-9a-f]{6}$/i.test(value)) {
|
|
8
|
+
return parseHexColor(value);
|
|
9
|
+
}
|
|
10
|
+
return parseFunctionalColor(value);
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function validateVectorLayers(layers) {
|
|
2
|
+
let i = 0, layer = null;
|
|
3
|
+
if (!Array.isArray(layers)) throw /* alloc */ new Error('Invalid vector style layers');
|
|
4
|
+
for (i = 0; i < layers.length; i++) {
|
|
5
|
+
layer = layers[i];
|
|
6
|
+
if (!layer || typeof layer.id !== 'string' || typeof layer.type !== 'string') {
|
|
7
|
+
throw /* alloc */ new Error('Invalid vector style layers');
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { fillVectorPaint } from './fillVectorPaint.js';
|
|
2
|
+
import { lineVectorPaint } from './lineVectorPaint.js';
|
|
3
|
+
|
|
4
|
+
export function vectorPaint(layer, properties, zoom) {
|
|
5
|
+
const paint = layer.paint || /* alloc */ {};
|
|
6
|
+
if (layer.type === 'fill') return fillVectorPaint(paint, properties, zoom);
|
|
7
|
+
return lineVectorPaint(layer, paint, properties, zoom);
|
|
8
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { evaluateStyle } from './evaluateStyle.js';
|
|
2
|
+
|
|
3
|
+
export function visibleStyle(layer, properties, zoom) {
|
|
4
|
+
return zoom >= (layer.minzoom ?? 0) && zoom < (layer.maxzoom ?? Infinity) &&
|
|
5
|
+
layer.layout?.visibility !== 'none' &&
|
|
6
|
+
(!layer.filter || evaluateStyle(layer.filter, properties, zoom, true));
|
|
7
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { vectorFeaturePaths } from './vectorFeaturePaths.js';
|
|
2
|
+
|
|
3
|
+
export function appendVectorBatch(job, layer, entry, feature, order, batches, dependencies, paint) {
|
|
4
|
+
const values = /* alloc */ [];
|
|
5
|
+
let key, batch, path, count;
|
|
6
|
+
for (key of dependencies) values.push(feature.properties[key]);
|
|
7
|
+
key = JSON.stringify(/* alloc */ [paint, values]);
|
|
8
|
+
batch = batches.get(key);
|
|
9
|
+
if (!batch) {
|
|
10
|
+
batch = /* alloc */ { kind: entry.type, order, paint, properties: feature.properties, entry,
|
|
11
|
+
paths: /* alloc */ [], coordinates: 0 };
|
|
12
|
+
batches.set(key, batch);
|
|
13
|
+
}
|
|
14
|
+
for (path of vectorFeaturePaths(job, layer, entry, feature)) {
|
|
15
|
+
count = entry.type === 'fill' ? 3 : path.length;
|
|
16
|
+
if (batch.coordinates + count > 6000 && batch.paths.length) {
|
|
17
|
+
job.output.push(/* alloc */ { ...batch, paths: batch.paths });
|
|
18
|
+
batch.paths = /* alloc */ []; batch.coordinates = 0;
|
|
19
|
+
}
|
|
20
|
+
batch.paths.push(path); batch.coordinates += count;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { L } from '../globals/L.js';
|
|
2
|
+
import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
|
|
3
|
+
import { vectorStyleZoom } from './vectorStyleZoom.js';
|
|
4
|
+
import { vectorTilePaint } from './vectorTilePaint.js';
|
|
5
|
+
import { forwardVectorTileError } from './forwardVectorTileError.js';
|
|
6
|
+
|
|
7
|
+
export function attachVectorTileBatch(owner, tile, group, batch) {
|
|
8
|
+
const { pane } = vectorTileOptionsByLayer.get(owner);
|
|
9
|
+
const paint = vectorTilePaint(batch, vectorStyleZoom(owner));
|
|
10
|
+
const options = /* alloc */ { ...paint, pane: `${pane}-${batch.order}`, interactive: false, smoothFactor: 0 };
|
|
11
|
+
const layer = batch.kind === 'fill'
|
|
12
|
+
? /* alloc */ new L.Polygon(batch.paths, /* alloc */ { ...options, stroke: false, triangulated: true })
|
|
13
|
+
: /* alloc */ new L.Polyline(batch.paths, options);
|
|
14
|
+
layer.on('error', forwardVectorTileError, owner);
|
|
15
|
+
tile.rendered.push(/* alloc */ { layer, kind: batch.kind, entry: batch.entry, properties: batch.properties });
|
|
16
|
+
group.addLayer(layer);
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { attachVectorTileBatch } from './attachVectorTileBatch.js';
|
|
2
|
+
import { vectorTilesIdle } from './vectorTilesIdle.js';
|
|
3
|
+
import { yieldTask } from '../utils/yieldTask.js';
|
|
4
|
+
|
|
5
|
+
export async function attachVectorTileBatches(owner, tile, group, batches, session) {
|
|
6
|
+
let batch, start = performance.now();
|
|
7
|
+
for (batch of batches) {
|
|
8
|
+
while (!vectorTilesIdle(owner, session) && owner.session === session &&
|
|
9
|
+
!tile.controller.signal.aborted) await yieldTask(50);
|
|
10
|
+
if (tile.controller.signal.aborted || owner.session !== session) return false;
|
|
11
|
+
attachVectorTileBatch(owner, tile, group, batch);
|
|
12
|
+
if (performance.now() - start > 8) { await yieldTask(); start = performance.now(); }
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { L } from '../globals/L.js';
|
|
2
|
+
import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
|
|
3
|
+
import { vectorTileSettings } from './vectorTileSettings.js';
|
|
4
|
+
import { loadVectorSprite } from './loadVectorSprite.js';
|
|
5
|
+
import { onVectorTileAdd } from './onVectorTileAdd.js';
|
|
6
|
+
import { onVectorTileRemove } from './onVectorTileRemove.js';
|
|
7
|
+
import { updateVectorTiles } from './updateVectorTiles.js';
|
|
8
|
+
import { updateVectorTilePaint } from './updateVectorTilePaint.js';
|
|
9
|
+
import { updateVectorTileLabels } from './updateVectorTileLabels.js';
|
|
10
|
+
import { pruneVectorTiles } from './pruneVectorTiles.js';
|
|
11
|
+
import { retireVectorTileGroup } from './retireVectorTileGroup.js';
|
|
12
|
+
import { pumpVectorTiles } from './pumpVectorTiles.js';
|
|
13
|
+
import { loadVectorTile } from './loadVectorTile.js';
|
|
14
|
+
|
|
15
|
+
export async function configureVectorTileLayer(layer, options) {
|
|
16
|
+
const settings = await vectorTileSettings(options);
|
|
17
|
+
if (typeof settings.sprite === 'string') settings.spriteSheet = await loadVectorSprite(settings.sprite);
|
|
18
|
+
const { url, tileJSON, style, sourceId, minNativeZoom, maxNativeZoom, maxZoom, ...core } = settings;
|
|
19
|
+
L.Util.setOptions(layer, core);
|
|
20
|
+
settings.pane = `mvt-${L.Util.stamp(layer)}`;
|
|
21
|
+
vectorTileOptionsByLayer.set(layer, settings);
|
|
22
|
+
Object.assign(layer, /* alloc */ {
|
|
23
|
+
onAdd: onVectorTileAdd, onRemove: onVectorTileRemove, update: updateVectorTiles,
|
|
24
|
+
updatePaint: updateVectorTilePaint, updateLabels: updateVectorTileLabels,
|
|
25
|
+
prune: pruneVectorTiles, retire: retireVectorTileGroup, pump: pumpVectorTiles, load: loadVectorTile,
|
|
26
|
+
});
|
|
27
|
+
return layer;
|
|
28
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { L } from '../globals/L.js';
|
|
2
|
+
import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
|
|
3
|
+
import { vectorStyleZoom } from './vectorStyleZoom.js';
|
|
4
|
+
import { attachVectorTileBatches } from './attachVectorTileBatches.js';
|
|
5
|
+
|
|
6
|
+
export async function loadVectorTile(tile) {
|
|
7
|
+
const { coords, controller } = tile, session = this.session;
|
|
8
|
+
const { url, style, sourceId, maxZoom, maxNativeZoom } = vectorTileOptionsByLayer.get(this);
|
|
9
|
+
const count = 2 ** coords.z, x = ((coords.x % count) + count) % count;
|
|
10
|
+
let group;
|
|
11
|
+
try {
|
|
12
|
+
const tileUrl = L.Util.template(url, /* alloc */ { z: coords.z, x, y: coords.y });
|
|
13
|
+
const response = await fetch(tileUrl, /* alloc */ { signal: controller.signal });
|
|
14
|
+
if (!response.ok) throw /* alloc */ new Error(`Tile ${tile.key}: HTTP ${response.status}`);
|
|
15
|
+
const buffer = await response.arrayBuffer();
|
|
16
|
+
if (controller.signal.aborted) return;
|
|
17
|
+
const id = ++this.sequence, prepared = Promise.withResolvers();
|
|
18
|
+
this.waiting.set(id, prepared);
|
|
19
|
+
this.worker.postMessage(/* alloc */ { type: 'vector', id, buffer, coords, style, source: sourceId, maxZoom,
|
|
20
|
+
zoom: vectorStyleZoom(this), mapZoom: coords.z >= maxNativeZoom ? maxZoom : this._map.getZoom() }, /* alloc */ [buffer]);
|
|
21
|
+
const data = await prepared.promise;
|
|
22
|
+
if (controller.signal.aborted || this.session !== session) return;
|
|
23
|
+
group = /* alloc */ new L.LayerGroup().addTo(this._map);
|
|
24
|
+
tile.rendered = /* alloc */ [];
|
|
25
|
+
if (!await attachVectorTileBatches(this, tile, group, data.batches, session)) { group.remove(); return; }
|
|
26
|
+
tile.group = group; tile.labelCandidates = data.labels;
|
|
27
|
+
this.fire('tileload', /* alloc */ { coords, group });
|
|
28
|
+
this.prune();
|
|
29
|
+
this.refresh();
|
|
30
|
+
} catch (error) {
|
|
31
|
+
group?.remove();
|
|
32
|
+
if (!controller.signal.aborted && this.session === session) this.fire('error', /* alloc */ { error });
|
|
33
|
+
} finally {
|
|
34
|
+
if (this.session === session) { this.inflight--; this.pump(); }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
|
|
2
|
+
import { geometryWorkerUrl } from '../globals/geometryWorkerUrl.js';
|
|
3
|
+
import { vectorTileEvents } from '../globals/vectorTileEvents.js';
|
|
4
|
+
import { evaluateStyle } from '../vector-style/evaluateStyle.js';
|
|
5
|
+
import { vectorStyleZoom } from './vectorStyleZoom.js';
|
|
6
|
+
import { refreshVectorTiles } from './refreshVectorTiles.js';
|
|
7
|
+
import { rotateVectorLabels } from './rotateVectorLabels.js';
|
|
8
|
+
import { onVectorTileMessage } from './onVectorTileMessage.js';
|
|
9
|
+
import { onVectorTileWorkerError } from './onVectorTileWorkerError.js';
|
|
10
|
+
import { createGeometryWorker } from '../workers/createGeometryWorker.js';
|
|
11
|
+
import { vectorWorkerByLayer } from '../weakmaps/vectorWorkerByLayer.js';
|
|
12
|
+
|
|
13
|
+
export function onVectorTileAdd(map) {
|
|
14
|
+
const { style, pane } = vectorTileOptionsByLayer.get(this);
|
|
15
|
+
let index, entry;
|
|
16
|
+
for ([index] of style.entries()) {
|
|
17
|
+
(map.getPane(`${pane}-${index}`) || map.createPane(`${pane}-${index}`)).style.zIndex = 200 + index;
|
|
18
|
+
}
|
|
19
|
+
for (entry of style) {
|
|
20
|
+
if (entry.type !== 'background') continue;
|
|
21
|
+
map.getContainer().style.background = evaluateStyle(entry.paint['background-color'], /* alloc */ {}, vectorStyleZoom(this));
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
this.session = /* alloc */ {};
|
|
25
|
+
this.tiles = /* alloc */ new Map(); this.labels = /* alloc */ new Map(); this.waiting = /* alloc */ new Map();
|
|
26
|
+
this.retiring = /* alloc */ new Set();
|
|
27
|
+
this.inflight = 0; this.sequence = 0;
|
|
28
|
+
this.changedAt = 0; this.paintZoom = null;
|
|
29
|
+
const workerEntry = createGeometryWorker(this.options.workerUrl || geometryWorkerUrl);
|
|
30
|
+
vectorWorkerByLayer.set(this, workerEntry);
|
|
31
|
+
this.worker = workerEntry.worker;
|
|
32
|
+
this.worker.onmessage = onVectorTileMessage.bind(this);
|
|
33
|
+
this.worker.onerror = onVectorTileWorkerError.bind(this);
|
|
34
|
+
this.refresh = refreshVectorTiles.bind(this);
|
|
35
|
+
this.rotateLabels = rotateVectorLabels.bind(this);
|
|
36
|
+
map.on(vectorTileEvents, this.refresh);
|
|
37
|
+
map.on('move rotate pitch', this.rotateLabels);
|
|
38
|
+
this.update();
|
|
39
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { revokeVectorWorkerUrl } from './revokeVectorWorkerUrl.js';
|
|
2
|
+
|
|
3
|
+
export function onVectorTileMessage({ data }) {
|
|
4
|
+
revokeVectorWorkerUrl(this);
|
|
5
|
+
const pending = this.waiting.get(data.id);
|
|
6
|
+
if (!pending) return;
|
|
7
|
+
this.waiting.delete(data.id);
|
|
8
|
+
if (data.error) pending.reject(/* alloc */ new Error(data.error));
|
|
9
|
+
else pending.resolve(data);
|
|
10
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { vectorTileEvents } from '../globals/vectorTileEvents.js';
|
|
2
|
+
import { vectorWorkerByLayer } from '../weakmaps/vectorWorkerByLayer.js';
|
|
3
|
+
import { revokeVectorWorkerUrl } from './revokeVectorWorkerUrl.js';
|
|
4
|
+
|
|
5
|
+
export function onVectorTileRemove(map) {
|
|
6
|
+
map.off(vectorTileEvents, this.refresh);
|
|
7
|
+
map.off('move rotate pitch', this.rotateLabels);
|
|
8
|
+
clearTimeout(this.timer);
|
|
9
|
+
this.session = null;
|
|
10
|
+
this.worker.terminate();
|
|
11
|
+
revokeVectorWorkerUrl(this);
|
|
12
|
+
vectorWorkerByLayer.delete(this);
|
|
13
|
+
let pending, tile, group, marker;
|
|
14
|
+
for (pending of this.waiting.values()) pending.reject(/* alloc */ new DOMException('Layer removed', 'AbortError'));
|
|
15
|
+
this.waiting.clear();
|
|
16
|
+
for (tile of this.tiles.values()) { tile.controller.abort(); tile.group?.remove(); }
|
|
17
|
+
for (group of this.retiring) group.remove();
|
|
18
|
+
for (marker of this.labels.values()) marker.remove();
|
|
19
|
+
this.tiles.clear(); this.labels.clear(); this.retiring.clear();
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { reportError } from '../scene/reportLayerError.js';
|
|
2
|
+
import { revokeVectorWorkerUrl } from './revokeVectorWorkerUrl.js';
|
|
3
|
+
|
|
4
|
+
export function onVectorTileWorkerError(event) {
|
|
5
|
+
revokeVectorWorkerUrl(this);
|
|
6
|
+
const error = /* alloc */ new Error(`Worker MVT: ${event.message}`);
|
|
7
|
+
let pending;
|
|
8
|
+
for (pending of this.waiting.values()) pending.reject(error);
|
|
9
|
+
this.waiting.clear();
|
|
10
|
+
reportError(this, error);
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { vectorTilePaint } from './vectorTilePaint.js';
|
|
2
|
+
|
|
3
|
+
export function paintVectorTileBatch(batch, zoom) {
|
|
4
|
+
const paint = vectorTilePaint(batch, zoom), { layer } = batch;
|
|
5
|
+
if (batch.kind === 'line') {
|
|
6
|
+
if (paint.dashArray !== layer.options.dashArray) layer.setStyle(paint);
|
|
7
|
+
else layer.setStyle(/* alloc */ { color: paint.color, opacity: paint.opacity, weight: paint.weight });
|
|
8
|
+
} else if (JSON.stringify(paint.fillColor) !== JSON.stringify(layer.options.fillColor) ||
|
|
9
|
+
paint.fillOpacity !== layer.options.fillOpacity) {
|
|
10
|
+
layer.setStyle(/* alloc */ { fillColor: paint.fillColor, fillOpacity: paint.fillOpacity });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { evaluateStyle } from '../vector-style/evaluateStyle.js';
|
|
2
|
+
import { projectVectorPoint } from './projectVectorPoint.js';
|
|
3
|
+
import { vectorLabelProperty } from './vectorLabelProperty.js';
|
|
4
|
+
import { vectorStyleValue } from './vectorStyleValue.js';
|
|
5
|
+
import { vectorLabelAnchors } from './vectorLabelAnchors.js';
|
|
6
|
+
|
|
7
|
+
export function prepareVectorLabel(job, layer, entry, feature, order) {
|
|
8
|
+
let text = entry.layout?.['text-field'];
|
|
9
|
+
const { properties } = feature, { zoom } = job;
|
|
10
|
+
const icon = entry.layout?.['symbol-placement'] === 'line' ? null
|
|
11
|
+
: evaluateStyle(entry.layout?.['icon-image'], properties, zoom);
|
|
12
|
+
if (Array.isArray(text)) text = evaluateStyle(text, properties, zoom);
|
|
13
|
+
if (typeof text !== 'string') text = '';
|
|
14
|
+
text = text.replace(/\{([^}]+)\}/g, vectorLabelProperty.bind(null, properties));
|
|
15
|
+
if (!text.trim() && typeof icon !== 'string') return;
|
|
16
|
+
if (entry.layout?.['text-transform'] === 'uppercase') text = text.toUpperCase();
|
|
17
|
+
const size = vectorStyleValue(entry.layout, 'text-size', 12, properties, zoom), line = feature.type === 2 && text.trim();
|
|
18
|
+
const spacing = layer.extent / 16, anchors = /* alloc */ [];
|
|
19
|
+
let path, anchor;
|
|
20
|
+
for (path of line ? feature.geometry : feature.geometry.slice(0, 1)) {
|
|
21
|
+
if (!path?.length) continue;
|
|
22
|
+
if (!line) anchors.push(/* alloc */ { point: path[Math.floor(path.length / 2)], a: null });
|
|
23
|
+
else for (anchor of vectorLabelAnchors(path, spacing)) anchors.push(anchor);
|
|
24
|
+
}
|
|
25
|
+
for (anchor of anchors) {
|
|
26
|
+
if (anchor.point[0] < 0 || anchor.point[0] >= layer.extent || anchor.point[1] < 0 || anchor.point[1] >= layer.extent) continue;
|
|
27
|
+
job.labels.push(/* alloc */ { text, latlng: projectVectorPoint(anchor.point, job.coords, layer.extent),
|
|
28
|
+
order, entry, properties, size, pixelBase: anchor.length * 256 / layer.extent / 2 ** job.coords.z,
|
|
29
|
+
along: anchor.a ? /* alloc */ [
|
|
30
|
+
projectVectorPoint(anchor.a, job.coords, layer.extent),
|
|
31
|
+
projectVectorPoint(anchor.b, job.coords, layer.extent),
|
|
32
|
+
] : null,
|
|
33
|
+
icon: text.trim() ? null : icon,
|
|
34
|
+
iconOffset: evaluateStyle(entry.layout?.['icon-offset'], properties, zoom) || /* alloc */ [0, 0],
|
|
35
|
+
allowOverlap: entry.layout?.['icon-allow-overlap'] === true,
|
|
36
|
+
color: vectorStyleValue(entry.paint, 'text-color', '#000', properties, zoom),
|
|
37
|
+
halo: vectorStyleValue(entry.paint, 'text-halo-color', '#fff', properties, zoom),
|
|
38
|
+
haloWidth: vectorStyleValue(entry.paint, 'text-halo-width', 0, properties, zoom),
|
|
39
|
+
priority: /* alloc */ ['place_labels', 'place'].includes(entry['source-layer']) ? 0
|
|
40
|
+
: /* alloc */ ['street_labels', 'transportation_name'].includes(entry['source-layer']) ? 1 : 2,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { vectorStyleDependencies } from './vectorStyleDependencies.js';
|
|
2
|
+
import { vectorFeatureZoom } from './vectorFeatureZoom.js';
|
|
3
|
+
import { prepareVectorLabel } from './prepareVectorLabel.js';
|
|
4
|
+
import { vectorFeaturePaint } from './vectorFeaturePaint.js';
|
|
5
|
+
import { vectorPaint } from '../vector-style/vectorPaint.js';
|
|
6
|
+
import { appendVectorBatch } from './appendVectorBatch.js';
|
|
7
|
+
|
|
8
|
+
export function prepareVectorStyleLayer(job, layer, entry, order) {
|
|
9
|
+
const batches = /* alloc */ new Map(), dependencies = vectorStyleDependencies(entry);
|
|
10
|
+
const outlineColor = entry.type === 'fill' ? entry.paint?.['fill-outline-color'] : null;
|
|
11
|
+
const outline = outlineColor ? /* alloc */ { ...entry, type: 'line',
|
|
12
|
+
paint: /* alloc */ { 'line-color': outlineColor, 'line-width': 1 } } : null;
|
|
13
|
+
let feature, sampleZoom, paint, batch;
|
|
14
|
+
for (feature of layer.features) {
|
|
15
|
+
sampleZoom = vectorFeatureZoom(entry, feature.properties, job.zoom, job.maxZoom);
|
|
16
|
+
if (sampleZoom < 0) continue;
|
|
17
|
+
if (entry.type === 'symbol') {
|
|
18
|
+
prepareVectorLabel(job, layer, entry, feature, order);
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
paint = vectorFeaturePaint(entry, feature, sampleZoom, job.maxZoom);
|
|
22
|
+
if (!paint) continue;
|
|
23
|
+
appendVectorBatch(job, layer, entry, feature, order, batches, dependencies, paint);
|
|
24
|
+
if (outline && feature.type === 3) {
|
|
25
|
+
appendVectorBatch(job, layer, outline, feature, order, batches, dependencies,
|
|
26
|
+
vectorPaint(outline, feature.properties, sampleZoom));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (batch of batches.values()) if (batch.paths.length) job.output.push(batch);
|
|
30
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { decodeVectorTile } from '../mvt/decodeVectorTile.js';
|
|
2
|
+
import { prepareVectorStyleLayer } from './prepareVectorStyleLayer.js';
|
|
3
|
+
|
|
4
|
+
export function prepareVectorTile(buffer, coords, style, zoom, source, maxZoom = 19, mapZoom = zoom) {
|
|
5
|
+
const layers = decodeVectorTile(buffer), byName = /* alloc */ new Map();
|
|
6
|
+
const job = /* alloc */ { coords, zoom, mapZoom, maxZoom, output: /* alloc */ [], labels: /* alloc */ [],
|
|
7
|
+
triangles: /* alloc */ new WeakMap(), projected: /* alloc */ new WeakMap() };
|
|
8
|
+
let layer, order, entry;
|
|
9
|
+
for (layer of layers) byName.set(layer.name, layer);
|
|
10
|
+
for ([order, entry] of style.entries()) {
|
|
11
|
+
layer = byName.get(entry['source-layer']);
|
|
12
|
+
if (!layer || source !== undefined && entry.source !== source) continue;
|
|
13
|
+
prepareVectorStyleLayer(job, layer, entry, order);
|
|
14
|
+
}
|
|
15
|
+
return /* alloc */ { batches: job.output, labels: job.labels };
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { projectVectorPoint } from './projectVectorPoint.js';
|
|
2
|
+
import { simplifyVectorPath } from './simplifyVectorPath.js';
|
|
3
|
+
|
|
4
|
+
export function projectVectorPaths(geometry, coords, extent, tolerance) {
|
|
5
|
+
const paths = /* alloc */ [];
|
|
6
|
+
let path, simplified, projected, point;
|
|
7
|
+
for (path of geometry) {
|
|
8
|
+
simplified = simplifyVectorPath(path, tolerance);
|
|
9
|
+
if (simplified.length < 3 && Math.hypot(simplified.at(-1)[0] - simplified[0][0], simplified.at(-1)[1] - simplified[0][1]) < tolerance * 2) continue;
|
|
10
|
+
projected = /* alloc */ [];
|
|
11
|
+
for (point of simplified) projected.push(projectVectorPoint(point, coords, extent));
|
|
12
|
+
paths.push(projected);
|
|
13
|
+
}
|
|
14
|
+
return paths;
|
|
15
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export function projectVectorPoint(point, coords, extent) {
|
|
2
|
+
const size = 2 ** coords.z;
|
|
3
|
+
const x = (coords.x + point[0] / extent) / size;
|
|
4
|
+
const y = (coords.y + point[1] / extent) / size;
|
|
5
|
+
return /* alloc */ [Math.atan(Math.sinh(Math.PI * (1 - 2 * y))) * 180 / Math.PI, x * 360 - 180];
|
|
6
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { triangulateVectorRings } from '../mvt/triangulateVectorRings.js';
|
|
2
|
+
import { projectVectorPoint } from './projectVectorPoint.js';
|
|
3
|
+
import { simplifyVectorPath } from './simplifyVectorPath.js';
|
|
4
|
+
|
|
5
|
+
export function projectVectorTriangles(geometry, coords, extent, tolerance) {
|
|
6
|
+
const paths = /* alloc */ [], rings = /* alloc */ [];
|
|
7
|
+
let triangle, projected, point, ring;
|
|
8
|
+
for (ring of geometry) {
|
|
9
|
+
ring = simplifyVectorPath(ring, tolerance);
|
|
10
|
+
if (ring.length >= 4) rings.push(ring);
|
|
11
|
+
}
|
|
12
|
+
for (triangle of triangulateVectorRings(rings)) {
|
|
13
|
+
projected = /* alloc */ [];
|
|
14
|
+
for (point of triangle) projected.push(projectVectorPoint(point, coords, extent));
|
|
15
|
+
paths.push(/* alloc */ [projected]);
|
|
16
|
+
}
|
|
17
|
+
return paths;
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { reportError } from '../scene/reportLayerError.js';
|
|
2
|
+
import { vectorTileAwaited } from './vectorTileAwaited.js';
|
|
3
|
+
|
|
4
|
+
export function pruneVectorTiles() {
|
|
5
|
+
let tile, key;
|
|
6
|
+
for ([key, tile] of this.tiles) {
|
|
7
|
+
if (tile.needed || tile.group && vectorTileAwaited(this, tile)) continue;
|
|
8
|
+
tile.controller.abort(); this.tiles.delete(key);
|
|
9
|
+
if (tile.group) this.retire(tile.group).catch(reportError.bind(null, this));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { compareVectorTileDistance } from './compareVectorTileDistance.js';
|
|
2
|
+
|
|
3
|
+
export function pumpVectorTiles() {
|
|
4
|
+
if (!this.session) return;
|
|
5
|
+
const center = this._map.getCenter(), pending = /* alloc */ [];
|
|
6
|
+
let tile, point;
|
|
7
|
+
for (tile of this.tiles.values()) {
|
|
8
|
+
if (!tile.needed || tile.started) continue;
|
|
9
|
+
point = this._map.project(center, tile.coords.z).divideBy(256);
|
|
10
|
+
tile.distance = (tile.coords.x - point.x) ** 2 + (tile.coords.y - point.y) ** 2;
|
|
11
|
+
pending.push(tile);
|
|
12
|
+
}
|
|
13
|
+
pending.sort(compareVectorTileDistance);
|
|
14
|
+
for (tile of pending) {
|
|
15
|
+
if (this.inflight >= 4) break;
|
|
16
|
+
tile.started = true; this.inflight++; this.load(tile);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export async function readTileJSON(options) {
|
|
2
|
+
const url = /* alloc */ new URL(options.tileJSON, document.baseURI).href;
|
|
3
|
+
const response = await fetch(url);
|
|
4
|
+
if (!response.ok) throw /* alloc */ new Error(`TileJSON: HTTP ${response.status}`);
|
|
5
|
+
const metadata = await response.json();
|
|
6
|
+
if (!metadata || !Array.isArray(metadata.tiles) || !metadata.tiles.length ||
|
|
7
|
+
typeof metadata.tiles[0] !== 'string') {
|
|
8
|
+
throw /* alloc */ new Error('TileJSON requires a tile URL template');
|
|
9
|
+
}
|
|
10
|
+
return /* alloc */ {
|
|
11
|
+
...options,
|
|
12
|
+
url: /* alloc */ new URL(metadata.tiles[0], url).href,
|
|
13
|
+
minNativeZoom: options.minNativeZoom ?? metadata.minzoom,
|
|
14
|
+
maxNativeZoom: options.maxNativeZoom ?? metadata.maxzoom,
|
|
15
|
+
attribution: options.attribution ?? metadata.attribution,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { parseVectorStyle } from '../vector-style/parseVectorStyle.js';
|
|
2
|
+
|
|
3
|
+
export async function readVectorStyle(style) {
|
|
4
|
+
if (typeof style === 'string') {
|
|
5
|
+
const response = await fetch(style);
|
|
6
|
+
if (!response.ok) throw /* alloc */ new Error(`Vector style: HTTP ${response.status}`);
|
|
7
|
+
style = parseVectorStyle(await response.text());
|
|
8
|
+
} else style = style?.layers ?? style;
|
|
9
|
+
if (!Array.isArray(style)) throw /* alloc */ new Error('Invalid vector style layers');
|
|
10
|
+
let entry;
|
|
11
|
+
for (entry of style) {
|
|
12
|
+
if (!entry || typeof entry.id !== 'string' || typeof entry.type !== 'string') {
|
|
13
|
+
throw /* alloc */ new Error('Invalid vector style layers');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return style;
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { yieldTask } from '../utils/yieldTask.js';
|
|
2
|
+
|
|
3
|
+
export async function retireVectorTileGroup(group) {
|
|
4
|
+
const session = this.session;
|
|
5
|
+
this.retiring.add(group);
|
|
6
|
+
let removed = 0, layer;
|
|
7
|
+
for (layer of group.getLayers()) {
|
|
8
|
+
if (this.session !== session) return;
|
|
9
|
+
group.removeLayer(layer);
|
|
10
|
+
if (++removed % 8 === 0) await yieldTask();
|
|
11
|
+
}
|
|
12
|
+
group.remove(); this.retiring.delete(group);
|
|
13
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { vectorWorkerByLayer } from '../weakmaps/vectorWorkerByLayer.js';
|
|
2
|
+
|
|
3
|
+
export function revokeVectorWorkerUrl(layer) {
|
|
4
|
+
const entry = vectorWorkerByLayer.get(layer);
|
|
5
|
+
if (entry?.blobUrl) {
|
|
6
|
+
URL.revokeObjectURL(entry.blobUrl);
|
|
7
|
+
entry.blobUrl = null;
|
|
8
|
+
}
|
|
9
|
+
}
|