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
package/libs/leaflet-lens.js
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
initialize(outerLayer, innerLayer, options) {
|
|
10
10
|
L.Util.setOptions(this, options);
|
|
11
|
+
if (options?.enabled === undefined) {
|
|
12
|
+
this.options.enabled = !matchMedia('(hover: none) and (pointer: coarse)').matches;
|
|
13
|
+
}
|
|
11
14
|
if (!outerLayer?.options || !innerLayer?.options || outerLayer === innerLayer) {
|
|
12
15
|
throw new TypeError('Lens requires two distinct raster layers');
|
|
13
16
|
}
|
|
@@ -40,14 +43,15 @@
|
|
|
40
43
|
this._button = L.DomUtil.create('button', '', container);
|
|
41
44
|
this._button.type = 'button';
|
|
42
45
|
this._button.textContent = '🔍';
|
|
43
|
-
this._button.title = 'Toggle lens; move the pointer over the map to reveal the layer underneath';
|
|
46
|
+
this._button.title = 'Toggle lens; touch or move the pointer over the map to reveal the layer underneath';
|
|
44
47
|
this._button.setAttribute('aria-label', 'Toggle lens');
|
|
45
48
|
this._button.style.cssText = 'display:block;border:0;border-radius:2px;padding:0 8px;min-width:30px;height:30px;background:white;color:#222;font:inherit;cursor:pointer';
|
|
46
49
|
L.DomEvent.disableClickPropagation(container);
|
|
47
50
|
L.DomEvent.disableScrollPropagation(container);
|
|
48
51
|
L.DomEvent.on(this._button, 'click', this._toggle, this);
|
|
49
52
|
this._events = {
|
|
50
|
-
|
|
53
|
+
pointerdown: this._onPointerDown.bind(this), pointermove: this._onPointerMove.bind(this),
|
|
54
|
+
pointerleave: this._onPointerLeave.bind(this), pointercancel: this._hide.bind(this),
|
|
51
55
|
focus: this._onFocus.bind(this), blur: this._hide.bind(this), keydown: this._onKeyDown.bind(this),
|
|
52
56
|
};
|
|
53
57
|
for (const [type, handler] of Object.entries(this._events)) {
|
|
@@ -111,8 +115,16 @@
|
|
|
111
115
|
});
|
|
112
116
|
},
|
|
113
117
|
|
|
118
|
+
_onPointerDown(event) {
|
|
119
|
+
if (event.pointerType === 'touch') this._onPointerMove(event);
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
_onPointerLeave(event) {
|
|
123
|
+
if (event.pointerType !== 'touch') this._hide();
|
|
124
|
+
},
|
|
125
|
+
|
|
114
126
|
_onFocus() {
|
|
115
|
-
this._show(this._map.getSize().divideBy(2));
|
|
127
|
+
if (this._lens.hidden) this._show(this._map.getSize().divideBy(2));
|
|
116
128
|
},
|
|
117
129
|
|
|
118
130
|
_onKeyDown(event) {
|
package/libs/leaflet.js
CHANGED
|
@@ -11,7 +11,7 @@ const openlayers = new URLSearchParams(location.search).get('engine') === 'openl
|
|
|
11
11
|
document.write((openlayers
|
|
12
12
|
? '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@10.6.1/ol.css">' +
|
|
13
13
|
'<script src="https://cdn.jsdelivr.net/npm/ol@10.6.1/dist/ol.js"><\/script>' +
|
|
14
|
-
'<script src="https://unpkg.com/leaflet-city-mapper@0.0.
|
|
14
|
+
'<script src="https://unpkg.com/leaflet-city-mapper@0.0.7/libs/openlayers-bindings.min.js"><\/script>'
|
|
15
15
|
: '<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css"><script src="https://unpkg.com/leaflet@1.9/dist/leaflet-src.js"><\/script>'));
|
|
16
16
|
|
|
17
17
|
const engineStyle = document.createElement('style');
|
package/package.json
CHANGED
package/src/cog/initCog.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { initRaster } from '../raster/initRaster.js';
|
|
2
|
-
import {
|
|
2
|
+
import { openCogInWorker } from '../workers/openCogInWorker.js';
|
|
3
3
|
|
|
4
4
|
export function initCog(layer, options) {
|
|
5
5
|
initRaster(layer, /* alloc */ { ariaLabel: 'COG raster', ...options,
|
|
6
|
-
archive: options.archive ||
|
|
6
|
+
archive: options.archive || openCogInWorker(layer, options) });
|
|
7
7
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CELL } from '../globals/CELL.js';
|
|
2
|
+
import { horizontalRay } from './horizontalRay.js';
|
|
3
|
+
|
|
4
|
+
export function collectIntersections(shape, x, y, z, seen, hits, end, iz) {
|
|
5
|
+
let ix, cell, triangle, distance;
|
|
6
|
+
for (ix = Math.floor(x / CELL); ix <= end; ix++) {
|
|
7
|
+
cell = shape.cells.get(`${ix},${iz}`);
|
|
8
|
+
if (!cell) continue;
|
|
9
|
+
for (triangle of cell) {
|
|
10
|
+
if (seen.has(triangle)) continue;
|
|
11
|
+
seen.add(triangle);
|
|
12
|
+
distance = horizontalRay(shape.tri, triangle, x, y, z, 1, 0);
|
|
13
|
+
if (distance > 1e-4) hits.push(distance);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { colliders } from '../weakmaps/colliders.js';
|
|
2
2
|
import { indexTriangle } from './indexTriangle.js';
|
|
3
3
|
import { readTriangle } from './readTriangle.js';
|
|
4
|
+
import { vertexCount } from './vertexCount.js';
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export function collider(mesh) {
|
|
7
8
|
let c = colliders.get(mesh.geometry);
|
|
8
9
|
if (c) return c;
|
|
9
|
-
const m = mesh.worldMatrix, { position
|
|
10
|
+
const m = mesh.worldMatrix, { position, index, normal, uv, instanceOffset } = mesh.geometry.attributes;
|
|
10
11
|
|
|
11
|
-
const vertices =
|
|
12
|
+
const vertices = vertexCount(position, index);
|
|
12
13
|
const count = vertices * (instanceOffset?.count ?? 1);
|
|
13
14
|
const tri = /* alloc */ [];
|
|
14
15
|
const nrm = /* alloc */ [];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function countCrossings(hits) {
|
|
2
|
+
let ix, j, distance;
|
|
3
|
+
for (ix = 1; ix < hits.length; ix++) {
|
|
4
|
+
distance = hits[ix];
|
|
5
|
+
j = ix - 1;
|
|
6
|
+
while (j >= 0 && hits[j] > distance) hits[j + 1] = hits[j--];
|
|
7
|
+
hits[j + 1] = distance;
|
|
8
|
+
}
|
|
9
|
+
let crossings = 0, previous = -Infinity;
|
|
10
|
+
for (distance of hits) {
|
|
11
|
+
if (distance - previous > 1e-4) crossings++;
|
|
12
|
+
previous = distance;
|
|
13
|
+
}
|
|
14
|
+
return crossings;
|
|
15
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CELL } from '../globals/CELL.js';
|
|
2
2
|
|
|
3
3
|
import { collider } from './collider.js';
|
|
4
|
-
import { horizontalRay } from './horizontalRay.js';
|
|
5
4
|
import { computeBounds } from '../geometry/computeBounds.js';
|
|
5
|
+
import { collectIntersections } from './collectIntersections.js';
|
|
6
|
+
import { countCrossings } from './countCrossings.js';
|
|
6
7
|
|
|
7
8
|
export function insideMesh(mesh, x, y, z, seen, intersections) {
|
|
8
9
|
const geometry = mesh.geometry;
|
|
@@ -27,27 +28,6 @@ export function insideMesh(mesh, x, y, z, seen, intersections) {
|
|
|
27
28
|
const hits = intersections;
|
|
28
29
|
hits.length = 0;
|
|
29
30
|
seen.clear();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
cell = shape.cells.get(`${ix},${iz}`);
|
|
33
|
-
if (!cell) continue;
|
|
34
|
-
for (triangle of cell) {
|
|
35
|
-
if (seen.has(triangle)) continue;
|
|
36
|
-
seen.add(triangle);
|
|
37
|
-
distance = horizontalRay(shape.tri, triangle, x, y, z, 1, 0);
|
|
38
|
-
if (distance > 1e-4) hits.push(distance);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
for (ix = 1; ix < hits.length; ix++) {
|
|
42
|
-
distance = hits[ix];
|
|
43
|
-
let j = ix - 1;
|
|
44
|
-
while (j >= 0 && hits[j] > distance) hits[j + 1] = hits[j--];
|
|
45
|
-
hits[j + 1] = distance;
|
|
46
|
-
}
|
|
47
|
-
let crossings = 0, previous = -Infinity;
|
|
48
|
-
for (distance of hits) {
|
|
49
|
-
if (distance - previous > 1e-4) crossings++;
|
|
50
|
-
previous = distance;
|
|
51
|
-
}
|
|
52
|
-
return crossings % 2 === 1;
|
|
31
|
+
collectIntersections(shape, x, y, z, seen, hits, end, iz);
|
|
32
|
+
return countCrossings(hits) % 2 === 1;
|
|
53
33
|
}
|
|
@@ -20,7 +20,7 @@ export function insideWalker(context) {
|
|
|
20
20
|
const y = root.position[1] + feet[1] * root.scale[1];
|
|
21
21
|
const z = root.position[2] + feet[2] * root.scale[2];
|
|
22
22
|
const layers = layersByLayer.get(shared);
|
|
23
|
-
let other, node, child;
|
|
23
|
+
let other, node, child, nodes;
|
|
24
24
|
for (other of layers) {
|
|
25
25
|
if (other === layer || kindByLayer.get(other) === 'terrain') continue;
|
|
26
26
|
if (kindByLayer.get(other) === 'traffic') {
|
|
@@ -29,7 +29,7 @@ export function insideWalker(context) {
|
|
|
29
29
|
if (trafficCollision(other, x, y, z, 0, 0, 0, hitData)) return true;
|
|
30
30
|
continue;
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
nodes = hitData.nodes;
|
|
33
33
|
nodes.length = 0;
|
|
34
34
|
if (rootByLayer.get(other)) nodes.push(rootByLayer.get(other));
|
|
35
35
|
while (nodes.length) {
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import { vertexCount } from './vertexCount.js';
|
|
2
|
+
|
|
1
3
|
export function readTriangle(mesh, i, a, b, c) {
|
|
2
4
|
const { position, index, instanceOffset } = mesh.geometry.attributes;
|
|
3
|
-
const
|
|
5
|
+
const size = position.size ?? 3;
|
|
6
|
+
const vertices = vertexCount(position, index);
|
|
4
7
|
const vertex = instanceOffset ? i % vertices : i;
|
|
5
8
|
const offset = instanceOffset ? Math.floor(i / vertices) * instanceOffset.size : 0;
|
|
6
9
|
const x = instanceOffset?.data[offset] ?? 0;
|
|
7
10
|
const y = instanceOffset?.data[offset + 1] ?? 0;
|
|
8
11
|
const z = instanceOffset?.data[offset + 2] ?? 0;
|
|
9
|
-
const ai = (index ? index.data[vertex] : vertex) *
|
|
10
|
-
const bi = (index ? index.data[vertex + 1] : vertex + 1) *
|
|
11
|
-
const ci = (index ? index.data[vertex + 2] : vertex + 2) *
|
|
12
|
+
const ai = (index ? index.data[vertex] : vertex) * size;
|
|
13
|
+
const bi = (index ? index.data[vertex + 1] : vertex + 1) * size;
|
|
14
|
+
const ci = (index ? index.data[vertex + 2] : vertex + 2) * size;
|
|
12
15
|
a[0] = position.data[ai]; a[1] = position.data[ai + 1]; a[2] = position.data[ai + 2];
|
|
13
16
|
b[0] = position.data[bi]; b[1] = position.data[bi + 1]; b[2] = position.data[bi + 2];
|
|
14
17
|
c[0] = position.data[ci]; c[1] = position.data[ci + 1]; c[2] = position.data[ci + 2];
|
|
@@ -2,13 +2,14 @@ import { rootByLayer } from '../weakmaps/rootByLayer.js';
|
|
|
2
2
|
import { trafficByLayer } from '../weakmaps/trafficByLayer.js';
|
|
3
3
|
|
|
4
4
|
import { locateTraffic } from '../traffic/locateTraffic.js';
|
|
5
|
+
import { setTrafficNormal } from './setTrafficNormal.js';
|
|
5
6
|
|
|
6
7
|
export function trafficCollision(layer, x, y, z, dx, dz, reach, data) {
|
|
7
8
|
const state = trafficByLayer.get(layer);
|
|
8
9
|
if (!state?.mesh || !state.trips.length) return false;
|
|
9
10
|
let bounds = state.collisionBounds;
|
|
10
11
|
if (!bounds) {
|
|
11
|
-
bounds = state.collisionBounds = { radius: 0, minY: Infinity, maxY: -Infinity };
|
|
12
|
+
bounds = state.collisionBounds = /* alloc */ { radius: 0, minY: Infinity, maxY: -Infinity };
|
|
12
13
|
let i, px, py, pz;
|
|
13
14
|
for (i = 0; i < state.template.position.length; i += 3) {
|
|
14
15
|
px = state.template.position[i];
|
|
@@ -19,7 +20,7 @@ export function trafficCollision(layer, x, y, z, dx, dz, reach, data) {
|
|
|
19
20
|
bounds.maxY = Math.max(bounds.maxY, py);
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
|
-
const root = rootByLayer.get(layer), position = state.position ||= {};
|
|
23
|
+
const root = rootByLayer.get(layer), position = state.position ||= /* alloc */ {};
|
|
23
24
|
const scale = Math.max(root.scale[0], root.scale[1], root.scale[2]);
|
|
24
25
|
const radius = bounds.radius * scale + 0.35;
|
|
25
26
|
let trip, projection, closest, rx, rz, perpendicular, entry, distance, bottom, top, px, pz;
|
|
@@ -48,13 +49,7 @@ export function trafficCollision(layer, x, y, z, dx, dz, reach, data) {
|
|
|
48
49
|
data.best = entry;
|
|
49
50
|
data.found = true;
|
|
50
51
|
distance = Math.hypot(x + entry * dx - px, z + entry * dz - pz);
|
|
51
|
-
|
|
52
|
-
data.normal[0] = -dx;
|
|
53
|
-
data.normal[1] = -dz;
|
|
54
|
-
} else {
|
|
55
|
-
data.normal[0] = (x + entry * dx - px) / distance;
|
|
56
|
-
data.normal[1] = (z + entry * dz - pz) / distance;
|
|
57
|
-
}
|
|
52
|
+
setTrafficNormal(data, x + entry * dx - px, z + entry * dz - pz, distance, dx, dz);
|
|
58
53
|
}
|
|
59
54
|
return data.found;
|
|
60
55
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { cameraTouchStateByMap } from '../weakmaps/cameraTouchStateByMap.js';
|
|
2
|
+
import { cameraHandlersByMap } from '../weakmaps/cameraHandlersByMap.js';
|
|
2
3
|
import { rotateControlByMap } from '../weakmaps/rotateControlByMap.js';
|
|
4
|
+
import { touchPitchByMap } from '../weakmaps/touchPitchByMap.js';
|
|
5
|
+
import { touchRotateByMap } from '../weakmaps/touchRotateByMap.js';
|
|
3
6
|
|
|
4
7
|
import { L } from '../globals/L.js';
|
|
5
8
|
import { Compass } from '../globals/Compass.js';
|
|
@@ -75,6 +78,8 @@ export function cameraControls(map) {
|
|
|
75
78
|
addCameraHandler(map, 'compassBearing', Compass.value);
|
|
76
79
|
addCameraHandler(map, 'touchRotate', TouchMode.value);
|
|
77
80
|
addCameraHandler(map, 'touchPitch', TouchMode.value);
|
|
81
|
+
touchRotateByMap.set(map, cameraHandlersByMap.get(map).get('touchRotate'));
|
|
82
|
+
touchPitchByMap.set(map, cameraHandlersByMap.get(map).get('touchPitch'));
|
|
78
83
|
const container = map.getContainer();
|
|
79
84
|
const state = /* alloc */ { map, container, touch: null, nativeZoom: undefined };
|
|
80
85
|
cameraTouchStateByMap.set(map, state);
|
|
@@ -86,6 +91,7 @@ export function cameraControls(map) {
|
|
|
86
91
|
container.addEventListener('touchcancel', endCameraTouchEvent, true);
|
|
87
92
|
window.addEventListener('blur', endAllCameraTouches);
|
|
88
93
|
map.on('cameratouchchange', changeCameraTouch, map);
|
|
94
|
+
changeCameraTouch.call(map);
|
|
89
95
|
if (map.options.rotateControl) {
|
|
90
96
|
rotateControlByMap.set(map, /* alloc */ new L.Control.Rotate(typeof map.options.rotateControl === 'object' ? map.options.rotateControl : cameraEmptyOptions));
|
|
91
97
|
rotateControlByMap.get(map).addTo(map);
|
|
@@ -3,10 +3,43 @@ import { tiledBounds } from '../globals/tiledBounds.js';
|
|
|
3
3
|
|
|
4
4
|
import { mapGetBearing } from '../camera/mapGetBearing.js';
|
|
5
5
|
import { mapGetPitch } from '../camera/mapGetPitch.js';
|
|
6
|
+
import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
|
|
7
|
+
import { renderers } from '../weakmaps/renderers.js';
|
|
8
|
+
import { sceneOriginByLayer } from '../weakmaps/sceneOriginByLayer.js';
|
|
9
|
+
import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
|
|
10
|
+
import { mapMethods } from '../globals/mapMethods.js';
|
|
11
|
+
import { radians } from '../globals/radians.js';
|
|
12
|
+
import { earthCirc } from '../globals/earthCirc.js';
|
|
13
|
+
import { mapElevationOf } from '../terrain/mapElevationOf.js';
|
|
14
|
+
import { groundBounds } from '../projections/groundBounds.js';
|
|
15
|
+
import { animationPoint } from '../projections/transformZoomAnimationPoint.js';
|
|
6
16
|
|
|
7
17
|
export function gridlayerGetTiledPixelBounds(center) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
const map = this._map, stream = streamTerrainByMap.get(map);
|
|
19
|
+
if (!stream && !mapGetBearing(map) && !mapGetPitch(map)) return tiledBounds.value.call(this, center);
|
|
20
|
+
const bounds = map.getBounds();
|
|
21
|
+
const result = /* alloc */ new L.Bounds(map.project(bounds.getNorthWest(), this._tileZoom),
|
|
22
|
+
map.project(bounds.getSouthEast(), this._tileZoom));
|
|
23
|
+
const shared = renderers.get(map), origin = shared && sceneOriginByLayer.get(shared);
|
|
24
|
+
if (!stream || !origin) return result;
|
|
25
|
+
let minimum = Infinity, maximum = -Infinity, key, entry;
|
|
26
|
+
for ([key, entry] of stream.terrainCache) {
|
|
27
|
+
if (!key.startsWith(`${this._tileZoom}/`) || !entry.range) continue;
|
|
28
|
+
minimum = Math.min(minimum, entry.range[0]);
|
|
29
|
+
maximum = Math.max(maximum, entry.range[1]);
|
|
30
|
+
}
|
|
31
|
+
if (!Number.isFinite(minimum) || !Number.isFinite(maximum)) return result;
|
|
32
|
+
const zoom = cameraViewByMap.get(map)?.zoom ?? map.getZoom();
|
|
33
|
+
const scale = map.options.crs.scale(zoom) / (earthCirc * Math.cos(origin.lat * radians));
|
|
34
|
+
const target = mapElevationOf(map, map.getCenter()) ?? 0;
|
|
35
|
+
let i, j, footprint, point, raw;
|
|
36
|
+
for (i = 0; i < 2; i++) {
|
|
37
|
+
footprint = groundBounds(map, undefined, ((i ? maximum : minimum) - target) * scale);
|
|
38
|
+
for (j = 0; j < 2; j++) {
|
|
39
|
+
point = j ? footprint.max : footprint.min;
|
|
40
|
+
raw = mapMethods.value.containerPointToLayerPoint.call(map, animationPoint(map, point, true));
|
|
41
|
+
result.extend(map.project(map.layerPointToLatLng(raw), this._tileZoom));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
12
45
|
}
|
package/src/core/markerSetPos.js
CHANGED
|
@@ -5,7 +5,7 @@ import { markerCameraIconPoint } from '../projections/markerCameraIconPoint.js';
|
|
|
5
5
|
import { displayPoint } from '../projections/displayContainerPoint.js';
|
|
6
6
|
|
|
7
7
|
export function markerSetPos(point) {
|
|
8
|
-
markerMethods.value._setPos.call(this, displayPoint(this._map, point));
|
|
8
|
+
markerMethods.value._setPos.call(this, displayPoint(this._map, point, this.getLatLng()));
|
|
9
9
|
let i, element, key, direction, options, anchor;
|
|
10
10
|
for (i = 0; i < 2; i++) {
|
|
11
11
|
element = i ? this._shadow : this._icon;
|
|
@@ -3,6 +3,6 @@ import { popupEvents } from '../globals/popupEvents.js';
|
|
|
3
3
|
|
|
4
4
|
export function popupGetEvents() {
|
|
5
5
|
const events = popupEvents.value.call(this);
|
|
6
|
-
events.rotate = events.pitch = events.move = this._updatePosition;
|
|
6
|
+
events.rotate = events.pitch = events.move = events.terrainchange = this._updatePosition;
|
|
7
7
|
return events;
|
|
8
8
|
}
|
|
@@ -5,13 +5,13 @@ import { popupPosition } from '../globals/popupPosition.js';
|
|
|
5
5
|
import { displayPoint } from '../projections/displayContainerPoint.js';
|
|
6
6
|
|
|
7
7
|
export function popupUpdatePosition() {
|
|
8
|
-
popupPosition.value.call(this);
|
|
9
|
-
if (!this._map) return;
|
|
10
|
-
const point = this._map.latLngToLayerPoint(this._latlng), delta = displayPoint(this._map, point).subtract(point);
|
|
11
|
-
if (this._zoomAnimated) {
|
|
12
|
-
L.DomUtil.setPosition(this._container, L.DomUtil.getPosition(this._container).add(delta));
|
|
13
|
-
} else {
|
|
14
|
-
this._container.style.left = `${this._containerLeft + delta.x}px`;
|
|
15
|
-
this._container.style.bottom = `${this._containerBottom - delta.y}px`;
|
|
8
|
+
popupPosition.value.call(this);
|
|
9
|
+
if (!this._map) return;
|
|
10
|
+
const point = this._map.latLngToLayerPoint(this._latlng), delta = displayPoint(this._map, point, this._latlng).subtract(point);
|
|
11
|
+
if (this._zoomAnimated) {
|
|
12
|
+
L.DomUtil.setPosition(this._container, L.DomUtil.getPosition(this._container).add(delta));
|
|
13
|
+
} else {
|
|
14
|
+
this._container.style.left = `${this._containerLeft + delta.x}px`;
|
|
15
|
+
this._container.style.bottom = `${this._containerBottom - delta.y}px`;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -3,6 +3,6 @@ import { tooltipEvents } from '../globals/tooltipEvents.js';
|
|
|
3
3
|
|
|
4
4
|
export function tooltipGetEvents() {
|
|
5
5
|
const events = tooltipEvents.value.call(this);
|
|
6
|
-
events.rotate = events.pitch = events.move = this._updatePosition;
|
|
6
|
+
events.rotate = events.pitch = events.move = events.terrainchange = this._updatePosition;
|
|
7
7
|
return events;
|
|
8
8
|
}
|
|
@@ -5,7 +5,7 @@ import { tooltipPosition } from '../globals/tooltipPosition.js';
|
|
|
5
5
|
import { displayPoint } from '../projections/displayContainerPoint.js';
|
|
6
6
|
|
|
7
7
|
export function tooltipSetPosition(point) {
|
|
8
|
-
tooltipPosition.value.call(this, point);
|
|
9
|
-
const delta = displayPoint(this._map, point).subtract(point);
|
|
8
|
+
tooltipPosition.value.call(this, point);
|
|
9
|
+
const delta = displayPoint(this._map, point, this._latlng).subtract(point);
|
|
10
10
|
L.DomUtil.setPosition(this._container, L.DomUtil.getPosition(this._container).add(delta));
|
|
11
11
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export function triangle(point, target, a, b, c) {
|
|
2
|
-
return target.push(...point(a), ...point(b), ...point(c));
|
|
1
|
+
export function triangle(point, target, a, b, c, anchorA, anchorB, anchorC) {
|
|
2
|
+
return target.push(...point(a, anchorA), ...point(b, anchorB), ...point(c, anchorC));
|
|
3
3
|
}
|
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
|
|
2
|
-
|
|
3
|
-
import { vertexNormals } from './vertexNormals.js';
|
|
1
|
+
import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
|
|
2
|
+
|
|
4
3
|
import { createProgram } from '../materials/createProgram.js';
|
|
5
4
|
|
|
6
5
|
export function createModelGeometry(context, primitive, attributes) {
|
|
7
|
-
let normals;
|
|
8
|
-
if (!attributes.normal) {
|
|
9
|
-
normals = vertexNormals(attributes.position.data, attributes.index?.data);
|
|
10
|
-
attributes.normal = /* alloc */ { size: 3, data: normals };
|
|
11
|
-
}
|
|
12
6
|
const style = context.materials[primitive.material] || /* alloc */ {
|
|
13
7
|
color: /* alloc */ [1, 1, 1], metallic: 1,
|
|
14
8
|
};
|
|
@@ -18,7 +12,6 @@ export function createModelGeometry(context, primitive, attributes) {
|
|
|
18
12
|
const program = createProgram(context.backend, style);
|
|
19
13
|
context.resources.push(program);
|
|
20
14
|
const device = rendererByLayer.get(context.backend).device;
|
|
21
|
-
if (attributes.index?.data instanceof Uint8Array) attributes.index.data = Uint16Array.from(attributes.index.data);
|
|
22
15
|
let name, attribute;
|
|
23
16
|
for ([name, attribute] of Object.entries(attributes)) {
|
|
24
17
|
attribute.size ||= 1;
|
|
@@ -2,15 +2,20 @@ import { segment } from './segment.js';
|
|
|
2
2
|
|
|
3
3
|
export function dashedSegment(context, a, b, length, distance, period) {
|
|
4
4
|
const dash = context.dash;
|
|
5
|
-
let offset = 0, phase, index, end, delta;
|
|
5
|
+
let offset = 0, phase = ((distance % period) + period) % period, index = 0, end, delta, skipped = 0;
|
|
6
|
+
while (index < dash.length - 1 && phase >= dash[index]) phase -= dash[index++];
|
|
7
|
+
let remaining = Math.max(0, dash[index] - phase);
|
|
6
8
|
while (offset < length) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
end = Math.min(length, offset + dash[index] - phase);
|
|
10
|
-
if (index % 2 === 0) {
|
|
9
|
+
end = Math.min(length, offset + remaining);
|
|
10
|
+
if (end > offset && index % 2 === 0) {
|
|
11
11
|
delta = b.subtract(a).divideBy(length);
|
|
12
12
|
segment(context, a.add(delta.multiplyBy(offset)), a.add(delta.multiplyBy(end)), true, true);
|
|
13
13
|
}
|
|
14
|
+
if (end <= offset) {
|
|
15
|
+
if (++skipped >= dash.length) throw /* alloc */ new Error('Leaflet dashArray is too small for these coordinates');
|
|
16
|
+
} else skipped = 0;
|
|
14
17
|
offset = end;
|
|
18
|
+
index = (index + 1) % dash.length;
|
|
19
|
+
remaining = dash[index];
|
|
15
20
|
}
|
|
16
21
|
}
|
package/src/geometry/disk.js
CHANGED
|
@@ -6,6 +6,6 @@ export function disk(point, center, radius, target, radiusY = radius) {
|
|
|
6
6
|
const count = Math.max(12, Math.min(128, Math.ceil(Math.PI * Math.sqrt(radius))));
|
|
7
7
|
let i;
|
|
8
8
|
for (i = 0; i < count; i++) {
|
|
9
|
-
triangle(point, target, center, diskAt(center, radius, radiusY, count, i), diskAt(center, radius, radiusY, count, i + 1));
|
|
9
|
+
triangle(point, target, center, diskAt(center, radius, radiusY, count, i), diskAt(center, radius, radiusY, count, i + 1), center, center, center);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { triangle } from './appendNativeTriangle.js';
|
|
2
|
+
import { triangulate } from '../triangulation/triangulate.js';
|
|
3
|
+
|
|
4
|
+
export function fillNativePolygon(context, projected) {
|
|
5
|
+
const { options, fill, point } = context;
|
|
6
|
+
if (options.triangulated) {
|
|
7
|
+
if (projected.length !== 1 || projected[0].length !== 3) {
|
|
8
|
+
throw /* alloc */ new Error('triangulated polygons require three vertices per polygon and no holes');
|
|
9
|
+
}
|
|
10
|
+
triangle(point, fill, projected[0][0], projected[0][1], projected[0][2]);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const valid = /* alloc */ [];
|
|
14
|
+
let ring, indices;
|
|
15
|
+
for (ring of projected) if (ring.length >= 3) valid.push(ring);
|
|
16
|
+
const vertices = valid.flat();
|
|
17
|
+
for (indices of triangulate(valid[0], valid.slice(1))) {
|
|
18
|
+
triangle(point, fill, vertices[indices[0]], vertices[indices[1]], vertices[indices[2]]);
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/geometry/lineJoin.js
CHANGED
|
@@ -19,8 +19,8 @@ export function lineJoin(context, points, i, b, length) {
|
|
|
19
19
|
const from = a.add(n1.multiplyBy(radius)), to = a.add(n2.multiplyBy(radius));
|
|
20
20
|
const denominator = 1 + n1.x * n2.x + n1.y * n2.y;
|
|
21
21
|
const miter = denominator > 0 ? n1.add(n2).multiplyBy(radius / denominator) : null;
|
|
22
|
-
triangle(point, stroke, from, a, to);
|
|
22
|
+
triangle(point, stroke, from, a, to, a, a, a);
|
|
23
23
|
if (options.lineJoin === 'miter' && miter && Math.hypot(miter.x, miter.y) <= radius * 4) {
|
|
24
|
-
triangle(point, stroke, from, a.add(miter), to);
|
|
24
|
+
triangle(point, stroke, from, a.add(miter), to, a, a, a);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -8,11 +8,17 @@ import { localPosition } from '../projections/localPosition.js';
|
|
|
8
8
|
|
|
9
9
|
import { transformNativePoint } from '../transforms/transformNativePoint.js';
|
|
10
10
|
import { markerImageBounds } from './markerImageBounds.js';
|
|
11
|
+
import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
|
|
12
|
+
import { mapElevationOf } from '../terrain/mapElevationOf.js';
|
|
11
13
|
|
|
12
14
|
export function markerQuadCorners(state, key, image) {
|
|
13
15
|
const { source, map, backend: layer } = state;
|
|
14
16
|
|
|
15
17
|
const position = localPosition(state, source.getLatLng());
|
|
18
|
+
if (streamTerrainByMap.get(map)) {
|
|
19
|
+
const root = rootByLayer.get(layer), elevation = mapElevationOf(map, source.getLatLng());
|
|
20
|
+
if (Number.isFinite(elevation)) position[1] = (elevation - root.position[1]) / root.scale[1];
|
|
21
|
+
}
|
|
16
22
|
const size = map.getSize();
|
|
17
23
|
const matrices = state.markerMatrices ||= /* alloc */ {
|
|
18
24
|
root: /* alloc */ new DOMMatrix(),
|
|
@@ -3,7 +3,7 @@ import { visit } from './visitNativeCoordinates.js';
|
|
|
3
3
|
import { dashValues } from './dashValues.js';
|
|
4
4
|
import { circleGeometry } from './circleGeometry.js';
|
|
5
5
|
|
|
6
|
-
/** Leaflet paths become flat triangles;
|
|
6
|
+
/** Leaflet paths become flat triangles; solid strokes retain stationary zoom anchors. */
|
|
7
7
|
export function nativeGeometry(source, map, point) {
|
|
8
8
|
const fill = /* alloc */ [];
|
|
9
9
|
const stroke = /* alloc */ [];
|
package/src/geometry/polygon.js
CHANGED
|
@@ -1,23 +1,17 @@
|
|
|
1
|
-
import { triangle } from './appendNativeTriangle.js';
|
|
2
1
|
import { line } from './line.js';
|
|
3
|
-
import {
|
|
2
|
+
import { fillNativePolygon } from './fillNativePolygon.js';
|
|
4
3
|
|
|
5
4
|
export function polygon(context, rings, closed) {
|
|
6
|
-
const { options,
|
|
5
|
+
const { options, map } = context;
|
|
7
6
|
const projected = /* alloc */ [];
|
|
8
|
-
let ring, path, latlng
|
|
7
|
+
let ring, path, latlng;
|
|
9
8
|
for (ring of rings) {
|
|
10
9
|
path = /* alloc */ [];
|
|
11
10
|
for (latlng of ring) path.push(map.project(latlng));
|
|
12
11
|
projected.push(path);
|
|
13
12
|
}
|
|
14
13
|
if (closed && options.fill && projected[0]?.length >= 3) {
|
|
15
|
-
|
|
16
|
-
for (ring of projected) if (ring.length >= 3) valid.push(ring);
|
|
17
|
-
const vertices = valid.flat();
|
|
18
|
-
for (indices of triangulate(valid[0], valid.slice(1))) {
|
|
19
|
-
triangle(point, fill, vertices[indices[0]], vertices[indices[1]], vertices[indices[2]]);
|
|
20
|
-
}
|
|
14
|
+
fillNativePolygon(context, projected);
|
|
21
15
|
}
|
|
22
16
|
for (ring of projected) line(context, ring, closed);
|
|
23
17
|
}
|
package/src/geometry/segment.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { L } from '../globals/L.js';
|
|
1
|
+
import { L } from '../globals/L.js';
|
|
2
2
|
import { triangle } from './appendNativeTriangle.js';
|
|
3
3
|
import { disk } from './disk.js';
|
|
4
4
|
|
|
5
5
|
export function segment(context, a, b, startCap, endCap) {
|
|
6
6
|
const { options, width, stroke, point } = context;
|
|
7
7
|
const radius = width / 2;
|
|
8
|
+
const anchorA = a, anchorB = b;
|
|
8
9
|
const length = a.distanceTo(b);
|
|
9
10
|
if (!length) return;
|
|
10
11
|
const direction = b.subtract(a).divideBy(length);
|
|
@@ -13,8 +14,8 @@ export function segment(context, a, b, startCap, endCap) {
|
|
|
13
14
|
if (startCap) a = a.subtract(direction.multiplyBy(radius));
|
|
14
15
|
if (endCap) b = b.add(direction.multiplyBy(radius));
|
|
15
16
|
}
|
|
16
|
-
triangle(point, stroke, a.add(normal), a.subtract(normal), b.add(normal));
|
|
17
|
-
triangle(point, stroke, b.add(normal), a.subtract(normal), b.subtract(normal));
|
|
17
|
+
triangle(point, stroke, a.add(normal), a.subtract(normal), b.add(normal), anchorA, anchorA, anchorB);
|
|
18
|
+
triangle(point, stroke, b.add(normal), a.subtract(normal), b.subtract(normal), anchorB, anchorA, anchorB);
|
|
18
19
|
if (options.lineCap === 'round') {
|
|
19
20
|
if (startCap) disk(point, a, radius, stroke);
|
|
20
21
|
if (endCap) disk(point, b, radius, stroke);
|