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.
Files changed (261) hide show
  1. package/README.md +10 -5
  2. package/dist/leaflet-city-mapper-src.js +6874 -6304
  3. package/dist/leaflet-city-mapper-src.js.map +4 -4
  4. package/dist/leaflet-city-mapper-worker-src.js +2766 -0
  5. package/dist/leaflet-city-mapper-worker-src.js.map +4 -4
  6. package/dist/leaflet-city-mapper-worker.js +1 -1
  7. package/dist/leaflet-city-mapper-worker.js.map +4 -4
  8. package/dist/leaflet-city-mapper.js +5 -3
  9. package/dist/leaflet-city-mapper.js.map +4 -4
  10. package/libs/leaflet-lens.js +15 -3
  11. package/libs/leaflet.js +1 -1
  12. package/package.json +1 -1
  13. package/src/camera/setBearing.js +5 -0
  14. package/src/camera/setPitch.js +5 -0
  15. package/src/cog/initCog.js +2 -2
  16. package/src/collision/collectIntersections.js +16 -0
  17. package/src/collision/collider.js +3 -2
  18. package/src/collision/countCrossings.js +15 -0
  19. package/src/collision/insideMesh.js +4 -24
  20. package/src/collision/insideWalker.js +2 -2
  21. package/src/collision/readTriangle.js +7 -4
  22. package/src/collision/setTrafficNormal.js +9 -0
  23. package/src/collision/trafficCollision.js +4 -9
  24. package/src/collision/vertexCount.js +3 -0
  25. package/src/controls/cameraControls.js +6 -0
  26. package/src/core/gridlayerGetTiledPixelBounds.js +37 -4
  27. package/src/core/markerSetPos.js +1 -1
  28. package/src/core/popupGetEvents.js +1 -1
  29. package/src/core/popupUpdatePosition.js +8 -8
  30. package/src/core/tooltipGetEvents.js +1 -1
  31. package/src/core/tooltipSetPosition.js +2 -2
  32. package/src/geometry/appendNativeTriangle.js +2 -2
  33. package/src/geometry/createModelGeometry.js +2 -9
  34. package/src/geometry/dashedSegment.js +10 -5
  35. package/src/geometry/disk.js +1 -1
  36. package/src/geometry/fillNativePolygon.js +20 -0
  37. package/src/geometry/lineJoin.js +2 -2
  38. package/src/geometry/markerQuadCorners.js +6 -0
  39. package/src/geometry/nativeGeometry.js +1 -1
  40. package/src/geometry/polygon.js +4 -10
  41. package/src/geometry/segment.js +4 -3
  42. package/src/globals/colorTexture.js +6 -0
  43. package/src/globals/depthTexture.js +1 -0
  44. package/src/globals/drawMeshEntry.js +1 -1
  45. package/src/globals/meshPipeline.js +1 -0
  46. package/src/globals/mvtTextDecoder.js +1 -0
  47. package/src/globals/nativeScalableStyleKeys.js +1 -0
  48. package/src/globals/scenePass.js +1 -0
  49. package/src/globals/vectorStyleNamedColors.js +8 -0
  50. package/src/globals/vectorTileEvents.js +1 -0
  51. package/src/globals/workerCogSource.js +1 -0
  52. package/src/gpu/mountRenderer.js +4 -11
  53. package/src/gpu/releaseRenderer.js +1 -0
  54. package/src/index.js +6 -12
  55. package/src/materials/createProgramUniforms.js +1 -0
  56. package/src/models/loadModel.js +6 -10
  57. package/src/models/loadModelResources.js +2 -8
  58. package/src/models/modelNode.js +3 -7
  59. package/src/models/prepareModel.js +19 -0
  60. package/src/models/prepareModelGeometry.js +25 -0
  61. package/src/models/prepareModelPrimitive.js +17 -0
  62. package/src/mvt/addMvtCrossings.js +17 -0
  63. package/src/mvt/appendMvtBandTriangles.js +31 -0
  64. package/src/mvt/appendMvtCoordinates.js +11 -0
  65. package/src/mvt/appendMvtPolygonTriangles.js +19 -0
  66. package/src/mvt/beginMvtPath.js +9 -0
  67. package/src/mvt/closeMvtPath.js +7 -0
  68. package/src/mvt/collectMvtEdges.js +19 -0
  69. package/src/mvt/createMvtReader.js +7 -0
  70. package/src/mvt/decodeVectorTile.js +32 -0
  71. package/src/mvt/expectMvtWire.js +3 -0
  72. package/src/mvt/finishMvtPath.js +5 -0
  73. package/src/mvt/finiteMvtCoordinate.js +7 -0
  74. package/src/mvt/groupMvtPolygons.js +25 -0
  75. package/src/mvt/isMvtFallbackError.js +6 -0
  76. package/src/mvt/mergeMvtActiveEdges.js +9 -0
  77. package/src/mvt/mvtEdgeX.js +4 -0
  78. package/src/mvt/mvtPathsVertices.js +8 -0
  79. package/src/mvt/mvtPolygonPaths.js +12 -0
  80. package/src/mvt/numericMvtValue.js +4 -0
  81. package/src/mvt/readMvtFeature.js +34 -0
  82. package/src/mvt/readMvtField.js +8 -0
  83. package/src/mvt/readMvtGeometry.js +29 -0
  84. package/src/mvt/readMvtInteger.js +12 -0
  85. package/src/mvt/readMvtKnownValue.js +21 -0
  86. package/src/mvt/readMvtLayer.js +31 -0
  87. package/src/mvt/readMvtMessage.js +10 -0
  88. package/src/mvt/readMvtNumber.js +9 -0
  89. package/src/mvt/readMvtNumbers.js +11 -0
  90. package/src/mvt/readMvtString.js +6 -0
  91. package/src/mvt/readMvtValue.js +19 -0
  92. package/src/mvt/skipMvtField.js +14 -0
  93. package/src/mvt/sortMvtActiveEdges.js +15 -0
  94. package/src/mvt/sortedMvtLevels.js +22 -0
  95. package/src/mvt/takeMvtBytes.js +8 -0
  96. package/src/mvt/tessellateVectorRings.js +19 -0
  97. package/src/mvt/triangulateVectorRings.js +19 -0
  98. package/src/native/beforeNativeRender.js +6 -0
  99. package/src/native/canScaleNativeStyle.js +17 -0
  100. package/src/native/createNativeMesh.js +31 -0
  101. package/src/native/disposeNativeLayer.js +1 -1
  102. package/src/native/getGridTerrainTile.js +34 -0
  103. package/src/native/gridTerrainElevation.js +30 -0
  104. package/src/native/loadGridTerrain.js +26 -0
  105. package/src/native/nativeLayer.js +2 -2
  106. package/src/native/nativeLayerMethod.js +5 -14
  107. package/src/native/nativeProgram.js +20 -0
  108. package/src/native/nativeVectorGeometry.js +23 -0
  109. package/src/native/orderNativeGridLayer.js +14 -0
  110. package/src/native/putNativeMesh.js +15 -21
  111. package/src/native/refreshNativeEvent.js +13 -2
  112. package/src/native/refreshNativeLayer.js +1 -0
  113. package/src/native/syncGridLayer.js +48 -3
  114. package/src/native/syncNativeStrokeAnchors.js +12 -0
  115. package/src/native/syncNativeStrokeZoom.js +29 -0
  116. package/src/native/syncVectorLayer.js +15 -13
  117. package/src/native/terrainGridMesh.js +34 -0
  118. package/src/native/updateNativeStrokeRadius.js +9 -0
  119. package/src/projections/displayContainerPoint.js +23 -3
  120. package/src/projections/groundBounds.js +2 -2
  121. package/src/projections/localPixel.js +7 -2
  122. package/src/projections/localPixelForGeometry.js +4 -2
  123. package/src/projections/projectCameraPoint.js +6 -5
  124. package/src/raster/setRasterOpacity.js +1 -1
  125. package/src/raster/setRasterZIndex.js +1 -1
  126. package/src/rendering/collectVisibleMesh.js +5 -2
  127. package/src/rendering/drawSceneMeshes.js +3 -1
  128. package/src/rendering/nativeStrokeExpansion.js +4 -0
  129. package/src/rendering/prepareMeshUniforms.js +2 -0
  130. package/src/rendering/resizeRenderer.js +9 -0
  131. package/src/scene/initializerFor.js +3 -5
  132. package/src/scene/layerInitialize.js +14 -12
  133. package/src/scene/resolveNextInitialization.js +1 -1
  134. package/src/shaders/materialShaders.js +1 -0
  135. package/src/shaders/materialVertexShader.js +7 -2
  136. package/src/shaders/nativeStrokeShader.js +6 -0
  137. package/src/sources/attachAreaMesh.js +5 -6
  138. package/src/sources/buildArea.js +7 -17
  139. package/src/sources/buildAreaFeature.js +5 -24
  140. package/src/sources/buildAreaFeatures.js +14 -0
  141. package/src/sources/initVectorTiles.js +15 -0
  142. package/src/sources/isVectorTileSource.js +4 -0
  143. package/src/sources/matchesAreaTile.js +7 -0
  144. package/src/sources/prepareAreaGeometryJob.js +2 -11
  145. package/src/sources/projectAreaPolygons.js +15 -0
  146. package/src/sources/readyVectorTiles.js +10 -0
  147. package/src/sources/sourceAreaContext.js +1 -6
  148. package/src/sunlight/createSun.js +0 -1
  149. package/src/terrain/initTerrain.js +7 -1
  150. package/src/terrain/loadTerrain.js +4 -1
  151. package/src/terrain/mapElevationOf.js +5 -1
  152. package/src/terrain/onTerrainAdd.js +11 -1
  153. package/src/terrain/onTerrainRemove.js +10 -1
  154. package/src/utils/yieldTask.js +5 -0
  155. package/src/vector-style/appendQuotedStyleCharacter.js +22 -0
  156. package/src/vector-style/arrayContainsRange.js +8 -0
  157. package/src/vector-style/evaluateBoolean.js +18 -0
  158. package/src/vector-style/evaluateCoalesceOrCase.js +21 -0
  159. package/src/vector-style/evaluateComparison.js +16 -0
  160. package/src/vector-style/evaluateIExpression.js +8 -0
  161. package/src/vector-style/evaluateInput.js +6 -0
  162. package/src/vector-style/evaluateInterpolate.js +27 -0
  163. package/src/vector-style/evaluateMatch.js +12 -0
  164. package/src/vector-style/evaluateMath.js +14 -0
  165. package/src/vector-style/evaluateMembership.js +18 -0
  166. package/src/vector-style/evaluateNegation.js +13 -0
  167. package/src/vector-style/evaluatePrimitive.js +9 -0
  168. package/src/vector-style/evaluateStep.js +11 -0
  169. package/src/vector-style/evaluateStyle.js +33 -0
  170. package/src/vector-style/evaluateToExpression.js +14 -0
  171. package/src/vector-style/fillVectorPaint.js +17 -0
  172. package/src/vector-style/lineVectorPaint.js +21 -0
  173. package/src/vector-style/parseFunctionalColor.js +14 -0
  174. package/src/vector-style/parseHexColor.js +13 -0
  175. package/src/vector-style/parseVectorStyle.js +13 -0
  176. package/src/vector-style/readPaintValue.js +6 -0
  177. package/src/vector-style/removeTrailingCommas.js +12 -0
  178. package/src/vector-style/scaleDashArray.js +13 -0
  179. package/src/vector-style/skipStyleComment.js +9 -0
  180. package/src/vector-style/stripStyleComments.js +21 -0
  181. package/src/vector-style/styleColor.js +11 -0
  182. package/src/vector-style/validateVectorLayers.js +10 -0
  183. package/src/vector-style/vectorPaint.js +8 -0
  184. package/src/vector-style/visibleStyle.js +7 -0
  185. package/src/vector-tiles/appendVectorBatch.js +22 -0
  186. package/src/vector-tiles/attachVectorTileBatch.js +17 -0
  187. package/src/vector-tiles/attachVectorTileBatches.js +15 -0
  188. package/src/vector-tiles/compareVectorLabelPriority.js +3 -0
  189. package/src/vector-tiles/compareVectorTileDistance.js +3 -0
  190. package/src/vector-tiles/configureVectorTileLayer.js +28 -0
  191. package/src/vector-tiles/forwardVectorTileError.js +5 -0
  192. package/src/vector-tiles/loadVectorSprite.js +5 -0
  193. package/src/vector-tiles/loadVectorTile.js +36 -0
  194. package/src/vector-tiles/onVectorTileAdd.js +39 -0
  195. package/src/vector-tiles/onVectorTileMessage.js +10 -0
  196. package/src/vector-tiles/onVectorTileRemove.js +20 -0
  197. package/src/vector-tiles/onVectorTileWorkerError.js +11 -0
  198. package/src/vector-tiles/paintVectorTileBatch.js +12 -0
  199. package/src/vector-tiles/prepareVectorLabel.js +43 -0
  200. package/src/vector-tiles/prepareVectorStyleLayer.js +30 -0
  201. package/src/vector-tiles/prepareVectorTile.js +16 -0
  202. package/src/vector-tiles/projectVectorPaths.js +15 -0
  203. package/src/vector-tiles/projectVectorPoint.js +6 -0
  204. package/src/vector-tiles/projectVectorTriangles.js +18 -0
  205. package/src/vector-tiles/pruneVectorTiles.js +11 -0
  206. package/src/vector-tiles/pumpVectorTiles.js +18 -0
  207. package/src/vector-tiles/readTileJSON.js +17 -0
  208. package/src/vector-tiles/readVectorStyle.js +17 -0
  209. package/src/vector-tiles/refreshVectorTiles.js +5 -0
  210. package/src/vector-tiles/reserveVectorLabelCells.js +6 -0
  211. package/src/vector-tiles/retireVectorTileGroup.js +13 -0
  212. package/src/vector-tiles/revokeVectorWorkerUrl.js +9 -0
  213. package/src/vector-tiles/rotateVectorLabel.js +12 -0
  214. package/src/vector-tiles/rotateVectorLabels.js +6 -0
  215. package/src/vector-tiles/simplifyVectorPath.js +21 -0
  216. package/src/vector-tiles/updateVectorLabelMarker.js +27 -0
  217. package/src/vector-tiles/updateVectorTileLabels.js +28 -0
  218. package/src/vector-tiles/updateVectorTilePaint.js +20 -0
  219. package/src/vector-tiles/updateVectorTiles.js +29 -0
  220. package/src/vector-tiles/validateVectorTileZooms.js +6 -0
  221. package/src/vector-tiles/vectorFeaturePaint.js +15 -0
  222. package/src/vector-tiles/vectorFeaturePaths.js +16 -0
  223. package/src/vector-tiles/vectorFeatureZoom.js +8 -0
  224. package/src/vector-tiles/vectorLabelAnchors.js +24 -0
  225. package/src/vector-tiles/vectorLabelCandidates.js +11 -0
  226. package/src/vector-tiles/vectorLabelCells.js +26 -0
  227. package/src/vector-tiles/vectorLabelIcon.js +30 -0
  228. package/src/vector-tiles/vectorLabelProperty.js +3 -0
  229. package/src/vector-tiles/vectorSpriteIcon.js +11 -0
  230. package/src/vector-tiles/vectorStraightRun.js +14 -0
  231. package/src/vector-tiles/vectorStyleDependencies.js +15 -0
  232. package/src/vector-tiles/vectorStyleValue.js +5 -0
  233. package/src/vector-tiles/vectorStyleZoom.js +6 -0
  234. package/src/vector-tiles/vectorTileAwaited.js +9 -0
  235. package/src/vector-tiles/vectorTileOverlaps.js +4 -0
  236. package/src/vector-tiles/vectorTilePaint.js +10 -0
  237. package/src/vector-tiles/vectorTileSettings.js +17 -0
  238. package/src/vector-tiles/vectorTilesIdle.js +3 -0
  239. package/src/vector-tiles/vectorTolerance.js +4 -0
  240. package/src/vector-tiles/wrapVectorLabel.js +11 -0
  241. package/src/walk/animateWalker.js +2 -13
  242. package/src/walk/updateWalkerFrame.js +19 -0
  243. package/src/weakmaps/nativeProgramsByRenderer.js +1 -0
  244. package/src/weakmaps/streamTerrainByLayer.js +1 -0
  245. package/src/weakmaps/streamTerrainByMap.js +1 -0
  246. package/src/weakmaps/vectorTileOptionsByLayer.js +1 -0
  247. package/src/weakmaps/vectorWorkerByLayer.js +1 -0
  248. package/src/weakmaps/workerMapByLayer.js +1 -0
  249. package/src/workers/acquireGeometryWorker.js +2 -5
  250. package/src/workers/buildAreaInWorker.js +3 -23
  251. package/src/workers/cogWorker.js +21 -0
  252. package/src/workers/createGeometryWorker.js +20 -0
  253. package/src/workers/geometryWorker.js +15 -0
  254. package/src/workers/getCogInWorker.js +7 -0
  255. package/src/workers/modelWorker.js +10 -0
  256. package/src/workers/openCogInWorker.js +14 -0
  257. package/src/workers/runSourceWorker.js +32 -0
  258. package/src/workers/settleGeometryWorker.js +1 -1
  259. package/src/workers/vectorTileWorker.js +10 -0
  260. package/src/geometry/buildExtrudedPolygon.js +0 -10
  261. package/src/sources/buildAreaPoint.js +0 -7
@@ -0,0 +1,12 @@
1
+ import { takeMvtBytes } from './takeMvtBytes.js';
2
+
3
+ export function readMvtInteger(reader) {
4
+ let value = 0n, i = 0, byte;
5
+ for (; i < 10; i++) {
6
+ byte = reader.bytes[takeMvtBytes(reader, 1)];
7
+ if (i === 9 && byte > 1) throw /* alloc */ new Error('Invalid MVT varint');
8
+ value |= BigInt(byte & 127) << BigInt(i * 7);
9
+ if (byte < 128) return value;
10
+ }
11
+ throw /* alloc */ new Error('Invalid MVT varint');
12
+ }
@@ -0,0 +1,21 @@
1
+ import { expectMvtWire } from './expectMvtWire.js';
2
+ import { numericMvtValue } from './numericMvtValue.js';
3
+ import { readMvtInteger } from './readMvtInteger.js';
4
+ import { readMvtString } from './readMvtString.js';
5
+ import { takeMvtBytes } from './takeMvtBytes.js';
6
+
7
+ export function readMvtKnownValue(reader, field, wire) {
8
+ let offset, integer;
9
+ if (field === 1) return readMvtString(reader, wire);
10
+ if (field === 2 || field === 3) {
11
+ expectMvtWire(wire, field === 2 ? 5 : 1);
12
+ offset = takeMvtBytes(reader, field === 2 ? 4 : 8);
13
+ return field === 2 ? reader.view.getFloat32(offset, true) : reader.view.getFloat64(offset, true);
14
+ }
15
+ expectMvtWire(wire, 0);
16
+ integer = readMvtInteger(reader);
17
+ if (field === 4) return numericMvtValue(BigInt.asIntN(64, integer));
18
+ if (field === 5) return numericMvtValue(integer);
19
+ if (field === 6) return numericMvtValue((integer >> 1n) ^ -(integer & 1n));
20
+ return integer !== 0n;
21
+ }
@@ -0,0 +1,31 @@
1
+ import { expectMvtWire } from './expectMvtWire.js';
2
+ import { readMvtFeature } from './readMvtFeature.js';
3
+ import { readMvtField } from './readMvtField.js';
4
+ import { readMvtMessage } from './readMvtMessage.js';
5
+ import { readMvtNumber } from './readMvtNumber.js';
6
+ import { readMvtString } from './readMvtString.js';
7
+ import { readMvtValue } from './readMvtValue.js';
8
+ import { skipMvtField } from './skipMvtField.js';
9
+
10
+ export function readMvtLayer(reader) {
11
+ let name, version, extent = 4096, field, wire, value, i = 0;
12
+ const keys = /* alloc */ [], values = /* alloc */ [], features = /* alloc */ [];
13
+ while (reader.pos < reader.bytes.length) {
14
+ [field, wire] = readMvtField(reader);
15
+ if (field === 1) name = readMvtString(reader, wire);
16
+ else if (field === 2) features.push(readMvtMessage(reader, wire));
17
+ else if (field === 3) keys.push(readMvtString(reader, wire));
18
+ else if (field === 4) values.push(readMvtValue(readMvtMessage(reader, wire)));
19
+ else if (field === 5 || field === 15) {
20
+ expectMvtWire(wire, 0);
21
+ value = readMvtNumber(reader);
22
+ if (field === 5) extent = value;
23
+ else version = value;
24
+ } else skipMvtField(reader, wire);
25
+ }
26
+ if (!name || !/* alloc */ [1, 2].includes(version) || !extent || extent > 0xffffffff) {
27
+ throw /* alloc */ new Error('Invalid MVT layer metadata');
28
+ }
29
+ for (; i < features.length; i++) features[i] = readMvtFeature(features[i], keys, values);
30
+ return /* alloc */ { name, extent, features };
31
+ }
@@ -0,0 +1,10 @@
1
+ import { createMvtReader } from './createMvtReader.js';
2
+ import { expectMvtWire } from './expectMvtWire.js';
3
+ import { readMvtNumber } from './readMvtNumber.js';
4
+ import { takeMvtBytes } from './takeMvtBytes.js';
5
+
6
+ export function readMvtMessage(reader, wire) {
7
+ expectMvtWire(wire, 2);
8
+ const size = readMvtNumber(reader), start = takeMvtBytes(reader, size);
9
+ return createMvtReader(reader.bytes.subarray(start, start + size));
10
+ }
@@ -0,0 +1,9 @@
1
+ import { readMvtInteger } from './readMvtInteger.js';
2
+
3
+ export function readMvtNumber(reader) {
4
+ const value = readMvtInteger(reader);
5
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
6
+ throw /* alloc */ new Error('MVT integer exceeds safe range');
7
+ }
8
+ return Number(value);
9
+ }
@@ -0,0 +1,11 @@
1
+ import { readMvtMessage } from './readMvtMessage.js';
2
+ import { readMvtNumber } from './readMvtNumber.js';
3
+
4
+ export function readMvtNumbers(reader, wire, target) {
5
+ let packed;
6
+ if (wire === 0) target.push(readMvtNumber(reader));
7
+ else {
8
+ packed = readMvtMessage(reader, wire);
9
+ while (packed.pos < packed.bytes.length) target.push(readMvtNumber(packed));
10
+ }
11
+ }
@@ -0,0 +1,6 @@
1
+ import { mvtTextDecoder } from '../globals/mvtTextDecoder.js';
2
+ import { readMvtMessage } from './readMvtMessage.js';
3
+
4
+ export function readMvtString(reader, wire) {
5
+ return mvtTextDecoder.decode(readMvtMessage(reader, wire).bytes);
6
+ }
@@ -0,0 +1,19 @@
1
+ import { readMvtField } from './readMvtField.js';
2
+ import { skipMvtField } from './skipMvtField.js';
3
+ import { readMvtKnownValue } from './readMvtKnownValue.js';
4
+
5
+ export function readMvtValue(reader) {
6
+ let value, found = false, field, wire;
7
+ while (reader.pos < reader.bytes.length) {
8
+ [field, wire] = readMvtField(reader);
9
+ if (field < 1 || field > 7) {
10
+ skipMvtField(reader, wire);
11
+ continue;
12
+ }
13
+ if (found) throw /* alloc */ new Error('Multiple MVT value types');
14
+ found = true;
15
+ value = readMvtKnownValue(reader, field, wire);
16
+ }
17
+ if (!found) throw /* alloc */ new Error('Empty MVT value');
18
+ return value;
19
+ }
@@ -0,0 +1,14 @@
1
+ import { expectMvtWire } from './expectMvtWire.js';
2
+ import { readMvtInteger } from './readMvtInteger.js';
3
+ import { readMvtNumber } from './readMvtNumber.js';
4
+ import { takeMvtBytes } from './takeMvtBytes.js';
5
+
6
+ export function skipMvtField(reader, wire) {
7
+ switch (wire) {
8
+ case 0: readMvtInteger(reader); break;
9
+ case 1: takeMvtBytes(reader, 8); break;
10
+ case 2: takeMvtBytes(reader, readMvtNumber(reader)); break;
11
+ case 5: takeMvtBytes(reader, 4); break;
12
+ default: throw /* alloc */ new Error('Unsupported MVT wire type');
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ import { mergeMvtActiveEdges } from './mergeMvtActiveEdges.js';
2
+
3
+ export function sortMvtActiveEdges(active) {
4
+ const sorted = /* alloc */ new Array(active.length);
5
+ let width = 1, left, mid, right, i;
6
+ while (width < active.length) {
7
+ for (left = 0; left < active.length; left += width * 2) {
8
+ mid = Math.min(left + width, active.length);
9
+ right = Math.min(left + width * 2, active.length);
10
+ mergeMvtActiveEdges(active, sorted, left, mid, right);
11
+ }
12
+ for (i = 0; i < active.length; i++) active[i] = sorted[i];
13
+ width *= 2;
14
+ }
15
+ }
@@ -0,0 +1,22 @@
1
+ export function sortedMvtLevels(levels) {
2
+ const sorted = /* alloc */ [];
3
+ let y, gap = 0, i = 0, j, value, count = 0;
4
+ for (y of levels) sorted.push(y);
5
+ gap = Math.floor(sorted.length / 2);
6
+ for (; gap > 0; gap = Math.floor(gap / 2)) {
7
+ for (i = gap; i < sorted.length; i++) {
8
+ value = sorted[i];
9
+ j = i;
10
+ while (j >= gap && sorted[j - gap] > value) {
11
+ sorted[j] = sorted[j - gap];
12
+ j -= gap;
13
+ }
14
+ sorted[j] = value;
15
+ }
16
+ }
17
+ for (i = 0; i < sorted.length; i++) {
18
+ if (!count || sorted[i] - sorted[count - 1] > 1e-8) sorted[count++] = sorted[i];
19
+ }
20
+ sorted.length = count;
21
+ return sorted;
22
+ }
@@ -0,0 +1,8 @@
1
+ export function takeMvtBytes(reader, size) {
2
+ if (!Number.isSafeInteger(size) || size < 0 || size > reader.bytes.length - reader.pos) {
3
+ throw /* alloc */ new Error('Truncated MVT field');
4
+ }
5
+ const start = reader.pos;
6
+ reader.pos += size;
7
+ return start;
8
+ }
@@ -0,0 +1,19 @@
1
+ import { addMvtCrossings } from './addMvtCrossings.js';
2
+ import { appendMvtBandTriangles } from './appendMvtBandTriangles.js';
3
+ import { collectMvtEdges } from './collectMvtEdges.js';
4
+ import { sortedMvtLevels } from './sortedMvtLevels.js';
5
+
6
+ export function tessellateVectorRings(rings) {
7
+ const edges = /* alloc */ [], levels = /* alloc */ new Set(), triangles = /* alloc */ [];
8
+ let sorted, i = 1, top, bottom;
9
+ collectMvtEdges(rings, edges, levels);
10
+ addMvtCrossings(edges, levels);
11
+ sorted = sortedMvtLevels(levels);
12
+ // ponytail: quadratic edge scan; use a sweep-line index for large datasets.
13
+ for (; i < sorted.length; i++) {
14
+ top = sorted[i - 1];
15
+ bottom = sorted[i];
16
+ if (bottom > top) appendMvtBandTriangles(edges, top, bottom, triangles);
17
+ }
18
+ return triangles;
19
+ }
@@ -0,0 +1,19 @@
1
+ import { appendMvtPolygonTriangles } from './appendMvtPolygonTriangles.js';
2
+ import { groupMvtPolygons } from './groupMvtPolygons.js';
3
+ import { mvtPathsVertices } from './mvtPathsVertices.js';
4
+ import { mvtPolygonPaths } from './mvtPolygonPaths.js';
5
+
6
+ /**
7
+ * Reuse City Mapper's triangulator in tile space, with even-odd tessellation
8
+ * for quantized touching/crossing rings. Output triangles omit their closure.
9
+ */
10
+ export function triangulateVectorRings(rings) {
11
+ const polygons = groupMvtPolygons(rings), triangles = /* alloc */ [];
12
+ let polygon, paths, vertices;
13
+ for (polygon of polygons) {
14
+ paths = mvtPolygonPaths(polygon);
15
+ vertices = mvtPathsVertices(paths);
16
+ appendMvtPolygonTriangles(polygon, paths, vertices, triangles);
17
+ }
18
+ return triangles;
19
+ }
@@ -1,8 +1,14 @@
1
1
  import { synchronizeNativeLayer } from './synchronizeNativeLayer.js';
2
+ import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
2
3
 
3
4
  export function beforeNativeRender(state) {
4
5
  try {
5
6
  synchronizeNativeLayer(state);
7
+ const uniform = state.meshes.get('stroke')?.program.uniforms.strokeScale;
8
+ if (uniform) {
9
+ const zoom = cameraViewByMap.get(state.map)?.zoom ?? state.map.getZoom();
10
+ uniform.value = 2 ** (state.strokeZoom - zoom) * Number(state.source.options.weight) / state.strokeWeight;
11
+ }
6
12
  } catch (error) {
7
13
  state.failed = true;
8
14
  state.source.fire('error', /* alloc */ { error });
@@ -0,0 +1,17 @@
1
+ import { L } from '../globals/L.js';
2
+ import { nativeScalableStyleKeys } from '../globals/nativeScalableStyleKeys.js';
3
+
4
+ export function canScaleNativeStyle(name, state, args) {
5
+ const { source } = state;
6
+ if (name !== 'setStyle' || source.options.interactive !== false || state.dirty && !state.zoomOnly) return false;
7
+ const stroke = state.strokeCoordinates && state.meshes.get('stroke')?.program.uniforms.strokeScale;
8
+ const fill = source instanceof L.Polygon && !source.options.stroke && state.meshes.has('fill');
9
+ if (!stroke && !fill) return false;
10
+ let key;
11
+ if (args[0]) {
12
+ for (key of Object.keys(args[0])) {
13
+ if (!nativeScalableStyleKeys.has(key)) return false;
14
+ }
15
+ }
16
+ return true;
17
+ }
@@ -0,0 +1,31 @@
1
+ import { L } from '../globals/L.js';
2
+ import { disposeMesh } from '../rendering/disposeMesh.js';
3
+ import { createMesh } from '../rendering/createMesh.js';
4
+ import { nativeProgram } from './nativeProgram.js';
5
+
6
+ export function createNativeMesh(state, key, position, color, opacity, texture, uv, terrain, nativeStroke) {
7
+ const { backend: layer, source, meshes } = state;
8
+ // Unlit, noninteractive strokes use the normal slot for stationary anchors.
9
+ const normal = nativeStroke ? state.strokeAnchors : /* alloc */ [];
10
+ let index, mesh = meshes.get(key);
11
+ if (!nativeStroke) {
12
+ for (index = 0; index < position.length; index++) normal.push(index % 3 === 1 ? 1 : 0);
13
+ }
14
+ const data = /* alloc */ { position, normal };
15
+ if (uv) data.uv = uv;
16
+ const material = /* alloc */ {
17
+ vertexColors: false, color, opacity, unlit: true, alphaMode: 'BLEND', depthWrite: terrain, nativeStroke,
18
+ };
19
+ if (texture) material.baseTexture = texture;
20
+ if (mesh) disposeMesh(layer, mesh);
21
+ mesh = createMesh(layer, data, material, 0, source instanceof L.GridLayer
22
+ ? (terrain ? state.terrainRasterProgram : state.rasterProgram) || nativeProgram(layer, material)
23
+ : nativeProgram(layer, material));
24
+ if (source instanceof L.GridLayer) {
25
+ if (terrain) state.terrainRasterProgram ||= mesh.program;
26
+ else state.rasterProgram ||= mesh.program;
27
+ mesh.texture = texture;
28
+ }
29
+ meshes.set(key, mesh);
30
+ return mesh;
31
+ }
@@ -17,7 +17,7 @@ export function disposeNativeLayer() {
17
17
  const { source, map, backend: layer, meshes, textures, images } = state;
18
18
  const events = 'load tileload tileunload move drag';
19
19
  source.off(events, refreshNativeEvent, state);
20
- map.off('zoomend', refreshNativeEvent, state);
20
+ map.off('zoomend terrainchange', refreshNativeEvent, state);
21
21
  if (state.marker) map.off('move zoom rotate pitch resize viewreset', updateNativeLayerView, state);
22
22
  removeNativeEvents(state);
23
23
  let name, methods, mesh, texture, image;
@@ -0,0 +1,34 @@
1
+ export async function getGridTerrainTile(state, z, x, y) {
2
+ const limit = 2 ** z;
3
+ x = ((x % limit) + limit) % limit;
4
+ y = Math.max(0, Math.min(limit - 1, y));
5
+ const key = `${z}/${x}/${y}`;
6
+ let entry = state.terrainCache.get(key);
7
+ if (!entry) {
8
+ entry = /* alloc */ { promise: state.layer.options.getTile(z, x, y, state.terrainController.signal) };
9
+ state.terrainCache.set(key, entry);
10
+ } else {
11
+ state.terrainCache.delete(key);
12
+ state.terrainCache.set(key, entry);
13
+ }
14
+ try {
15
+ if (!entry.data) entry.data = await entry.promise;
16
+ if (!(entry.data instanceof Float32Array) || entry.data.length !== 65536) {
17
+ throw /* alloc */ new Error(`Invalid elevation tile ${key}: expected 256x256 Float32Array`);
18
+ }
19
+ if (!entry.range) {
20
+ let minimum = Infinity, maximum = -Infinity, elevation;
21
+ for (elevation of entry.data) {
22
+ if (!Number.isFinite(elevation) || elevation <= -1000) continue;
23
+ minimum = Math.min(minimum, elevation);
24
+ maximum = Math.max(maximum, elevation);
25
+ }
26
+ entry.range = /* alloc */ [minimum, maximum];
27
+ }
28
+ } catch (error) {
29
+ if (state.terrainCache.get(key) === entry) state.terrainCache.delete(key);
30
+ throw error;
31
+ }
32
+ while (state.terrainCache.size > 256) state.terrainCache.delete(state.terrainCache.keys().next().value);
33
+ return entry.data;
34
+ }
@@ -0,0 +1,30 @@
1
+ import { terrainElevation } from '../terrain/terrainElevation.js';
2
+ import { nativeGPUByLayer } from '../weakmaps/nativeGPUByLayer.js';
3
+
4
+ export function gridTerrainElevation(state, location) {
5
+ let z = Math.max(0, Math.min(24, Math.round(state.map.getZoom())));
6
+ const tiles = /* alloc */ new Map();
7
+ let point, limit, x, y, dx, dy, tx, ty, entry, elevation, layer, native, request;
8
+ for (; z >= 0; z--) {
9
+ point = state.map.project(location, z), limit = 2 ** z;
10
+ x = Math.floor(point.x / 256), y = Math.floor(point.y / 256);
11
+ for (layer of Object.values(state.map._layers)) {
12
+ native = nativeGPUByLayer.get(layer);
13
+ if (native?.disposed || native?.terrainStream !== state) continue;
14
+ request = native.terrainRequests?.get(`${x}:${y}:${z}`);
15
+ if (!request?.tiles || layer._tiles[`${x}:${y}:${z}`] !== request.tile) continue;
16
+ elevation = terrainElevation(point, request.tiles);
17
+ if (Number.isFinite(elevation)) return elevation;
18
+ }
19
+ tiles.clear();
20
+ for (dy = -1; dy <= 1; dy++) for (dx = -1; dx <= 1; dx++) {
21
+ tx = ((x + dx) % limit + limit) % limit;
22
+ ty = Math.max(0, Math.min(limit - 1, y + dy));
23
+ entry = state.terrainCache.get(`${z}/${tx}/${ty}`);
24
+ if (entry?.data) tiles.set(`${x + dx}/${y + dy}`, entry.data);
25
+ }
26
+ elevation = terrainElevation(point, tiles);
27
+ if (Number.isFinite(elevation)) return elevation;
28
+ }
29
+ return null;
30
+ }
@@ -0,0 +1,26 @@
1
+ import { getGridTerrainTile } from './getGridTerrainTile.js';
2
+ import { refreshNativeLayer } from './refreshNativeLayer.js';
3
+
4
+ export async function loadGridTerrain(state, key, tile, request) {
5
+ const { x, y, z } = tile.coords, stream = request.stream;
6
+ const jobs = /* alloc */ [], tiles = /* alloc */ new Map();
7
+ let dx, dy, i = 0;
8
+ try {
9
+ for (dy = -1; dy <= 1; dy++) for (dx = -1; dx <= 1; dx++) {
10
+ jobs.push(getGridTerrainTile(stream, z, x + dx, y + dy));
11
+ }
12
+ const values = await Promise.all(jobs);
13
+ if (state.disposed || stream.terrainController.signal.aborted ||
14
+ state.source._tiles[key] !== tile || state.terrainRequests.get(key) !== request) return;
15
+ for (dy = -1; dy <= 1; dy++) for (dx = -1; dx <= 1; dx++) tiles.set(`${x + dx}/${y + dy}`, values[i++]);
16
+ request.tiles = tiles;
17
+ refreshNativeLayer(state);
18
+ state.map.fire('terrainchange');
19
+ state.source._update();
20
+ } catch (error) {
21
+ if (!state.disposed && !stream.terrainController.signal.aborted && state.source._tiles[key] === tile) {
22
+ request.error = error;
23
+ stream.layer.fire('error', /* alloc */ { error, coords: tile.coords });
24
+ }
25
+ }
26
+ }
@@ -25,7 +25,7 @@ import { synchronizeNativeLayer } from './synchronizeNativeLayer.js';
25
25
  export async function nativeLayer(state) {
26
26
  const { source, map } = state;
27
27
  const layer = state.backend = createLayer(/* alloc */ {
28
- source: /* alloc */ { type: '3d' },
28
+ source: /* alloc */ { type: 'vector' },
29
29
  });
30
30
  state.meshes = /* alloc */ new Map();
31
31
  state.textures = /* alloc */ new Map();
@@ -43,7 +43,7 @@ export async function nativeLayer(state) {
43
43
  state.disposed = false;
44
44
  const currentEvents = 'load tileload tileunload move drag';
45
45
  source.on(currentEvents, refreshNativeEvent, state);
46
- map.on('zoomend', refreshNativeEvent, state);
46
+ map.on('zoomend terrainchange', refreshNativeEvent, state);
47
47
  if (state.marker) map.on('move zoom rotate pitch resize viewreset', updateNativeLayerView, state);
48
48
  nativeEvents(state);
49
49
  let name, own, original;
@@ -3,25 +3,15 @@ import { nativeGPUBackByMap } from '../weakmaps/nativeGPUBackByMap.js';
3
3
  import { nativeGPUOrderByMap } from '../weakmaps/nativeGPUOrderByMap.js';
4
4
 
5
5
 
6
- import { L } from '../globals/L.js';
7
-
8
-
9
6
  import { refreshNativeLayer } from './refreshNativeLayer.js';
7
+ import { canScaleNativeStyle } from './canScaleNativeStyle.js';
8
+ import { orderNativeGridLayer } from './orderNativeGridLayer.js';
10
9
 
11
10
  export function nativeLayerMethod(name, source, args) {
12
11
  const state = nativeGPUByLayer.get(source), original = state.methods.get(name).original;
12
+ const scalable = canScaleNativeStyle(name, state, args);
13
13
  const result = original.apply(source, args);
14
- let layer, zIndex;
15
- if ((name === 'bringToFront' || name === 'bringToBack') && source instanceof L.GridLayer) {
16
- let extreme = name === 'bringToFront' ? -Infinity : Infinity;
17
- for (layer of Object.values(state.map._layers)) {
18
- if (layer === source || !(layer instanceof L.GridLayer) || layer.getPane() !== source.getPane()) continue;
19
- zIndex = layer.options.zIndex || 0;
20
- extreme = name === 'bringToFront' ? Math.max(extreme, zIndex) : Math.min(extreme, zIndex);
21
- }
22
- const edge = name === 'bringToFront' ? extreme + 1 : extreme - 1;
23
- if (Number.isFinite(edge)) source.setZIndex(edge);
24
- }
14
+ orderNativeGridLayer(state, name);
25
15
  if (name === 'bringToFront') {
26
16
  state.order = nativeGPUOrderByMap.get(state.map) + 1;
27
17
  nativeGPUOrderByMap.set(state.map, state.order);
@@ -31,5 +21,6 @@ export function nativeLayerMethod(name, source, args) {
31
21
  nativeGPUBackByMap.set(state.map, state.order);
32
22
  }
33
23
  refreshNativeLayer(state);
24
+ if (scalable && (!source.options.stroke || Number(source.options.weight) > 0)) state.zoomOnly = true;
34
25
  return result;
35
26
  }
@@ -0,0 +1,20 @@
1
+ import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
2
+ import { nativeProgramsByRenderer } from '../weakmaps/nativeProgramsByRenderer.js';
3
+ import { createProgram } from '../materials/createProgram.js';
4
+ import { createProgramUniforms } from '../materials/createProgramUniforms.js';
5
+
6
+ export function nativeProgram(layer, material) {
7
+ const renderer = rendererByLayer.get(layer);
8
+ let programs = nativeProgramsByRenderer.get(renderer);
9
+ if (!programs) {
10
+ programs = /* alloc */ new Map();
11
+ nativeProgramsByRenderer.set(renderer, programs);
12
+ }
13
+ const key = `${Boolean(material.baseTexture)}:${Boolean(material.nativeStroke)}:${Boolean(material.depthWrite)}`;
14
+ let template = programs.get(key);
15
+ if (!template) {
16
+ template = createProgram(layer, /* alloc */ { doubleSided: true, ...material });
17
+ programs.set(key, template);
18
+ }
19
+ return /* alloc */ { ...template, uniforms: createProgramUniforms(material), _layerMaterial: material };
20
+ }
@@ -0,0 +1,23 @@
1
+ import { geometryPixelStates } from '../globals/geometryPixelStates.js';
2
+ import { nativeGeometry } from '../geometry/nativeGeometry.js';
3
+ import { localPixelForGeometry } from '../projections/localPixelForGeometry.js';
4
+ import { locationByLayer } from '../weakmaps/locationByLayer.js';
5
+ import { radians } from '../globals/radians.js';
6
+ import { L } from '../globals/L.js';
7
+
8
+ export function nativeVectorGeometry(state) {
9
+ const { source } = state;
10
+ state.strokeCoordinates = null;
11
+ state.strokeAnchors = source instanceof L.Polyline && !source.options.dashArray ? /* alloc */ [] : null;
12
+ const crs = state.map.options.crs, origin = locationByLayer.get(state.backend);
13
+ state.pixelProjection = /* alloc */ {
14
+ transformation: crs.transformation, scale: crs.scale(state.map.getZoom()),
15
+ origin: crs.project(origin), metres: Math.cos(origin.lat * radians),
16
+ };
17
+ geometryPixelStates.push(state);
18
+ try {
19
+ return nativeGeometry(source, state.map, localPixelForGeometry);
20
+ } finally {
21
+ geometryPixelStates.pop();
22
+ }
23
+ }
@@ -0,0 +1,14 @@
1
+ import { L } from '../globals/L.js';
2
+
3
+ export function orderNativeGridLayer(state, name) {
4
+ const { source } = state;
5
+ if (!(source instanceof L.GridLayer) || name !== 'bringToFront' && name !== 'bringToBack') return;
6
+ let extreme = name === 'bringToFront' ? -Infinity : Infinity, layer, zIndex;
7
+ for (layer of Object.values(state.map._layers)) {
8
+ if (layer === source || !(layer instanceof L.GridLayer) || layer.getPane() !== source.getPane()) continue;
9
+ zIndex = layer.options.zIndex || 0;
10
+ extreme = name === 'bringToFront' ? Math.max(extreme, zIndex) : Math.min(extreme, zIndex);
11
+ }
12
+ const edge = name === 'bringToFront' ? extreme + 1 : extreme - 1;
13
+ if (Number.isFinite(edge)) source.setZIndex(edge);
14
+ }
@@ -1,36 +1,30 @@
1
1
  import { L } from '../globals/L.js';
2
- import { disposeMesh } from '../rendering/disposeMesh.js';
3
- import { createMesh } from '../rendering/createMesh.js';
4
2
  import { styleNativeMesh } from './styleNativeMesh.js';
3
+ import { createNativeMesh } from './createNativeMesh.js';
4
+ import { updateNativeStrokeRadius } from './updateNativeStrokeRadius.js';
5
5
 
6
- export function putNativeMesh(state, key, position, color, opacity, texture, uv) {
7
- const { backend: layer, source, meshes } = state;
6
+ export function putNativeMesh(state, key, position, color, opacity, texture, uv, terrain = false) {
7
+ const { source, meshes } = state;
8
8
  if (!position.length) return;
9
+ const nativeStroke = key === 'stroke' && Boolean(state.strokeCoordinates) && source.options.interactive === false;
9
10
  let mesh = meshes.get(key);
10
11
  if (!mesh || mesh.geometry.attributes.position.data.length !== position.length ||
11
- mesh.program.uniforms.baseTexture?.value !== texture) {
12
- const normal = /* alloc */ [];
13
- let index;
14
- for (index = 0; index < position.length; index++) normal.push(index % 3 === 1 ? 1 : 0);
15
- const data = /* alloc */ { position, normal };
16
- if (uv) data.uv = uv;
17
- const material = /* alloc */ {
18
- vertexColors: false, color, opacity, unlit: true, alphaMode: 'BLEND',
19
- };
20
- if (texture) material.baseTexture = texture;
21
- if (mesh) disposeMesh(layer, mesh);
22
- mesh = createMesh(layer, data, material, 0, source instanceof L.GridLayer ? state.rasterProgram : undefined);
23
- if (source instanceof L.GridLayer) {
24
- state.rasterProgram ||= mesh.program;
25
- mesh.texture = texture;
26
- }
27
- meshes.set(key, mesh);
12
+ (source instanceof L.GridLayer && mesh.program.depthWrite !== terrain) ||
13
+ mesh.program.uniforms.baseTexture?.value !== texture ||
14
+ Boolean(mesh.program._layerMaterial.nativeStroke) !== nativeStroke) {
15
+ mesh = createNativeMesh(state, key, position, color, opacity, texture, uv, terrain, nativeStroke);
28
16
  } else {
29
17
  const attribute = mesh.geometry.attributes.position;
30
18
  attribute.data.set(position);
31
19
  attribute.needsUpdate = true;
32
20
  mesh.geometry.bounds = null;
21
+ if (nativeStroke) {
22
+ mesh.geometry.attributes.normal.data.set(state.strokeAnchors);
23
+ mesh.geometry.attributes.normal.needsUpdate = true;
24
+ }
33
25
  }
26
+ if (nativeStroke) updateNativeStrokeRadius(mesh);
27
+ if (mesh.program.uniforms.strokeScale) mesh.program.uniforms.strokeScale.value = 1;
34
28
  styleNativeMesh(state, mesh, color, opacity);
35
29
  return mesh;
36
30
  }
@@ -1,5 +1,16 @@
1
1
  import { refreshNativeLayer } from './refreshNativeLayer.js';
2
+ import { L } from '../globals/L.js';
3
+ import { update } from '../scene/scheduleSceneUpdate.js';
2
4
 
3
- export function refreshNativeEvent() {
4
- refreshNativeLayer(this);
5
+ export function refreshNativeEvent(event) {
6
+ if (event?.type === 'zoomend' && this.source instanceof L.Polyline &&
7
+ (!this.source.options.stroke || !(Number(this.source.options.weight) > 0))) return;
8
+ if (event?.type === 'zoomend' && this.strokeCoordinates && (!this.dirty || this.zoomOnly)) {
9
+ this.zoomOnly = true;
10
+ this.dirty = true;
11
+ update(this.backend);
12
+ return;
13
+ }
14
+ if (event?.type === 'terrainchange' && this.marker) this.source.update();
15
+ refreshNativeLayer(this);
5
16
  }
@@ -10,6 +10,7 @@ import { update } from '../scene/scheduleSceneUpdate.js';
10
10
  import { hideTargets } from './hideTargets.js';
11
11
 
12
12
  export function refreshNativeLayer(state = this) {
13
+ state.zoomOnly = false;
13
14
  state.dirty = true;
14
15
  state.viewDirty = true;
15
16
  state.failed = false;