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
@@ -1,45 +1,26 @@
1
- import { L } from '../globals/L.js';
2
- import { buildAreaPoint } from './buildAreaPoint.js';
3
- import { buildAreaPolygon } from '../geometry/buildExtrudedPolygon.js';
4
1
  import { parseColor } from '../colors/parseColor.js';
5
2
  import { featureAnchor } from './featureAnchor.js';
6
3
  import { extrusionStyle } from './extrusionStyle.js';
7
4
  import { prepareAreaGeometryJob } from './prepareAreaGeometryJob.js';
5
+ import { matchesAreaTile } from './matchesAreaTile.js';
8
6
 
9
7
  export function buildAreaFeature(context, feature) {
10
8
  const { backend: layer, area, map } = context;
11
9
  const coords = area.coords;
12
10
  const coordinates = featureAnchor(feature, layer.options.nightLight);
13
- const geometry = feature.geometry, isTree = geometry.type === 'Point';
11
+ const geometry = feature.geometry;
14
12
  const lon = coordinates[0], lat = coordinates[1];
15
- if (coords) {
16
- const anchor = map.project(/* alloc */ new L.LatLng(lat, lon), coords.z);
17
- if (Math.floor(anchor.x / 256) !== coords.x || Math.floor(anchor.y / 256) !== coords.y) return;
18
- }
13
+ if (!matchesAreaTile(map, coords, lon, lat)) return;
19
14
  const style = extrusionStyle(layer, feature);
20
15
  if (style === null) {
21
16
  context.skipped++;
22
17
  return;
23
18
  }
24
- const { top, bottom = 0, color = 0xd9b38c } = style;
19
+ const { color = 0xd9b38c } = style;
25
20
  const baseColor = parseColor(color);
26
- if (context.jobs) {
27
- prepareAreaGeometryJob(context, feature, lon, lat, style, baseColor);
28
- context.featureFaces.push(/* alloc */ {
29
- id: feature.id ?? feature.properties?.objectid ?? JSON.stringify(geometry),
30
- properties: feature.properties, baseColor,
31
- });
32
- return;
33
- }
34
- const vertexStart = context.positions.length / 3;
35
- if (isTree) buildAreaPoint(context, feature, lon, lat, style, baseColor);
36
- let polygon;
37
- if (geometry.type === 'Polygon') buildAreaPolygon(context, geometry.coordinates, top, bottom, baseColor);
38
- else if (geometry.type === 'MultiPolygon') for (polygon of geometry.coordinates) buildAreaPolygon(context, polygon, top, bottom, baseColor);
39
- const vertexEnd = context.positions.length / 3;
21
+ prepareAreaGeometryJob(context, feature, lon, lat, style, baseColor);
40
22
  context.featureFaces.push(/* alloc */ {
41
23
  id: feature.id ?? feature.properties?.objectid ?? JSON.stringify(geometry),
42
24
  properties: feature.properties, baseColor,
43
- faceStart: vertexStart / 3, faceEnd: vertexEnd / 3, vertexStart, vertexEnd,
44
25
  });
45
26
  }
@@ -0,0 +1,14 @@
1
+ import { buildAreaFeature } from './buildAreaFeature.js';
2
+
3
+ export async function buildAreaFeatures(context, area, features) {
4
+ let deadline = performance.now() + 4, feature;
5
+ for (feature of features) {
6
+ if (area.request.signal.aborted) return;
7
+ if (performance.now() >= deadline) {
8
+ await /* alloc */ new Promise(requestAnimationFrame);
9
+ if (area.request.signal.aborted) return;
10
+ deadline = performance.now() + 4;
11
+ }
12
+ buildAreaFeature(context, feature);
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ import { kindByLayer } from '../weakmaps/kindByLayer.js';
2
+ import { readyByLayer } from '../weakmaps/readyByLayer.js';
3
+ import { configureVectorTileLayer } from '../vector-tiles/configureVectorTileLayer.js';
4
+ import { readyVectorTiles } from './readyVectorTiles.js';
5
+ import { reportError } from '../raster/reportRasterError.js';
6
+ import { noOperation } from '../utils/noOperation.js';
7
+
8
+ export function initVectorTiles(layer, options) {
9
+ kindByLayer.set(layer, 'pending');
10
+ const ready = configureVectorTileLayer(layer, options)
11
+ .then(readyVectorTiles.bind(null, layer))
12
+ .catch(reportError.bind(null, layer));
13
+ readyByLayer.set(layer, ready);
14
+ ready.catch(noOperation);
15
+ }
@@ -0,0 +1,4 @@
1
+ export function isVectorTileSource(options) {
2
+ return options.data === undefined && (options.tileJSON !== undefined ||
3
+ typeof options.url === 'string' && /\{[zxy]\}|%7B[zxy]%7D/i.test(options.url));
4
+ }
@@ -0,0 +1,7 @@
1
+ import { L } from '../globals/L.js';
2
+
3
+ export function matchesAreaTile(map, coords, lon, lat) {
4
+ if (!coords) return true;
5
+ const anchor = map.project(/* alloc */ new L.LatLng(lat, lon), coords.z);
6
+ return Math.floor(anchor.x / 256) === coords.x && Math.floor(anchor.y / 256) === coords.y;
7
+ }
@@ -1,19 +1,10 @@
1
1
  import { projectedTree } from '../projections/projectTreePoint.js';
2
- import { projectRing } from '../projections/projectRing.js';
3
2
  import { parseColor } from '../colors/parseColor.js';
3
+ import { projectAreaPolygons } from './projectAreaPolygons.js';
4
4
 
5
5
  export function prepareAreaGeometryJob(context, feature, lon, lat, style, baseColor) {
6
6
  const geometry = feature.geometry;
7
- const polygons = /* alloc */ [];
8
- const rings = geometry.type === 'Polygon' ? /* alloc */ [geometry.coordinates]
9
- : geometry.type === 'MultiPolygon' ? geometry.coordinates : /* alloc */ [];
10
- let polygon, ring, paths;
11
- for (polygon of rings) {
12
- if (!polygon.length) throw /* alloc */ new Error('Empty GeoJSON polygon');
13
- paths = /* alloc */ [];
14
- for (ring of polygon) paths.push(projectRing(context, ring));
15
- polygons.push(paths);
16
- }
7
+ const polygons = projectAreaPolygons(context, geometry);
17
8
  const point = geometry.type === 'Point' ? projectedTree(context, lon, lat) : null;
18
9
  const nightLight = context.backend.options.nightLight;
19
10
  const crownColor = point ? parseColor(style.color ?? (nightLight ? undefined : 0x4f823b)) : baseColor;
@@ -0,0 +1,15 @@
1
+ import { projectRing } from '../projections/projectRing.js';
2
+
3
+ export function projectAreaPolygons(context, geometry) {
4
+ const rings = geometry.type === 'Polygon' ? /* alloc */ [geometry.coordinates]
5
+ : geometry.type === 'MultiPolygon' ? geometry.coordinates : /* alloc */ [];
6
+ const polygons = /* alloc */ [];
7
+ let polygon, ring, paths;
8
+ for (polygon of rings) {
9
+ if (!polygon.length) throw /* alloc */ new Error('Empty GeoJSON polygon');
10
+ paths = /* alloc */ [];
11
+ for (ring of polygon) paths.push(projectRing(context, ring));
12
+ polygons.push(paths);
13
+ }
14
+ return polygons;
15
+ }
@@ -0,0 +1,10 @@
1
+ import { kindByLayer } from '../weakmaps/kindByLayer.js';
2
+
3
+ export function readyVectorTiles(layer) {
4
+ const map = layer._map;
5
+ map?.removeLayer(layer);
6
+ kindByLayer.delete(layer);
7
+ map?.addLayer(layer);
8
+ layer.fire('ready');
9
+ return layer;
10
+ }
@@ -8,13 +8,8 @@ export function sourceAreaContext(layer, area, map) {
8
8
  return /* alloc */ {
9
9
  backend: layer, area, map, crs, origin,
10
10
  metres: Math.cos(locationByLayer.get(layer).lat * radians),
11
- positions: /* alloc */ [],
12
- normals: /* alloc */ [],
13
- colors: /* alloc */ [],
14
- uvs: /* alloc */ [],
11
+ jobs: /* alloc */ [],
15
12
  featureFaces: /* alloc */ [],
16
- lights: /* alloc */ [],
17
- supports: /* alloc */ new Set(),
18
13
  skipped: 0,
19
14
  };
20
15
  }
@@ -38,7 +38,6 @@ export function createSun(map) {
38
38
  status.setAttribute('role', 'status');
39
39
  const note = document.createElement('small');
40
40
  note.style.color = '#555';
41
- note.textContent = 'Indicative · loaded geometry only. Streetlight illumination is estimated, not measured lux.';
42
41
  container.append(date, slider, timeRow, status, note);
43
42
  const state = /* alloc */ {
44
43
  control: null, map, originalSky: '', container, sunDisc, moonDisc, date, slider, output, status,
@@ -3,6 +3,7 @@ import { rasterTilesByLayer } from '../weakmaps/rasterTilesByLayer.js';
3
3
  import { terrainReadyByLayer } from '../weakmaps/terrainReadyByLayer.js';
4
4
  import { terrainSourceByLayer } from '../weakmaps/terrainSourceByLayer.js';
5
5
  import { terrainTilesByLayer } from '../weakmaps/terrainTilesByLayer.js';
6
+ import { streamTerrainByLayer } from '../weakmaps/streamTerrainByLayer.js';
6
7
 
7
8
 
8
9
 
@@ -12,10 +13,14 @@ import { init3D } from '../scene/init3D.js';
12
13
 
13
14
  /**
14
15
  * Renders Float32 DEM tiles and archived raster basemaps in the shared WebGPU scene.
15
- * Source options: `url` (single-zoom Float32 PMTiles or supported COG DEM);
16
+ * Source options: `url` (single-zoom Float32 PMTiles or supported COG DEM),
17
+ * or `getTile(z, x, y, signal)` for streamed 256px Float32 elevations;
16
18
  * `bridges` (optional GeoJSON deck polygons with Z, see _addBridges).
17
19
  */
18
20
  export function initTerrain(layer, options) {
21
+ if (options.getTile !== undefined && typeof options.getTile !== 'function') {
22
+ throw /* alloc */ new Error('Streamed terrain requires a getTile function');
23
+ }
19
24
  const terrainSource = options.url;
20
25
  const layerOptions = /* alloc */ { ...options };
21
26
  delete layerOptions.url;
@@ -24,5 +29,6 @@ export function initTerrain(layer, options) {
24
29
  terrainTilesByLayer.set(layer, /* alloc */ new Map());
25
30
  rasterTilesByLayer.set(layer, /* alloc */ new Map());
26
31
  terrainReadyByLayer.set(layer, false);
32
+ if (options.getTile) streamTerrainByLayer.set(layer, true);
27
33
  kindByLayer.set(layer, 'terrain');
28
34
  }
@@ -5,6 +5,7 @@ import { terrainControllerByLayer } from '../weakmaps/terrainControllerByLayer.j
5
5
  import { terrainLoadingByLayer } from '../weakmaps/terrainLoadingByLayer.js';
6
6
  import { terrainReadyByLayer } from '../weakmaps/terrainReadyByLayer.js';
7
7
  import { terrainSourceByLayer } from '../weakmaps/terrainSourceByLayer.js';
8
+ import { workerMapByLayer } from '../weakmaps/workerMapByLayer.js';
8
9
 
9
10
  import { createLayer } from '../scene/createLayer.js';
10
11
 
@@ -23,9 +24,11 @@ export async function loadTerrain(layer) {
23
24
  try {
24
25
  if (!terrainSourceByLayer.get(layer)) throw /* alloc */ new Error('Terrain layer requires a PMTiles or COG elevation archive');
25
26
  const archive = createLayer(/* alloc */ { source: /* alloc */ {
26
- type: layer.options.asset !== undefined || /\.tiff?(?:[?#]|$)/i.test(terrainSourceByLayer.get(layer)) ? 'cog' : 'pmtiles',
27
+ type: 'raster',
27
28
  url: terrainSourceByLayer.get(layer), archive: layer.options.archive, asset: layer.options.asset,
29
+ workerUrl: layer.options.workerUrl,
28
30
  } });
31
+ workerMapByLayer.set(archive, layer._map);
29
32
  terrainArchiveByLayer.set(layer, archive);
30
33
  await readyByLayer.get(archive);
31
34
  const header = headerByLayer.get(archive);
@@ -1,7 +1,11 @@
1
1
  import { terrain3DByMap } from '../weakmaps/terrain3DByMap.js';
2
+ import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
2
3
  import { getElevation } from './getElevation.js';
4
+ import { gridTerrainElevation } from '../native/gridTerrainElevation.js';
3
5
 
4
6
  export function mapElevationOf(map, location) {
5
7
  const terrain = terrain3DByMap.get(map);
6
- return terrain && getElevation(terrain, location);
8
+ if (terrain) return getElevation(terrain, location);
9
+ const stream = streamTerrainByMap.get(map);
10
+ return stream && gridTerrainElevation(stream, location);
7
11
  }
@@ -1,6 +1,8 @@
1
1
  import { rootByLayer } from '../weakmaps/rootByLayer.js';
2
2
  import { terrainPromiseByLayer } from '../weakmaps/terrainPromiseByLayer.js';
3
3
  import { terrain3DByMap } from '../weakmaps/terrain3DByMap.js';
4
+ import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
5
+ import { streamTerrainByLayer } from '../weakmaps/streamTerrainByLayer.js';
4
6
 
5
7
 
6
8
 
@@ -13,9 +15,17 @@ import { setLayerTerrain } from './setLayerTerrain.js';
13
15
 
14
16
  export function onTerrainAdd(layer, map) {
15
17
 
16
- if (terrain3DByMap.get(map) && terrain3DByMap.get(map) !== layer) {
18
+ if (streamTerrainByMap.get(map) || terrain3DByMap.get(map) && terrain3DByMap.get(map) !== layer) {
17
19
  throw /* alloc */ new Error('Only one terrain layer can be active per map');
18
20
  }
21
+ if (streamTerrainByLayer.get(layer)) {
22
+ streamTerrainByMap.set(map, /* alloc */ {
23
+ layer, map, terrainCache: /* alloc */ new Map(), terrainController: /* alloc */ new AbortController(),
24
+ });
25
+ onAdd3DLayer(layer, map);
26
+ map.fire('terrainchange');
27
+ return;
28
+ }
19
29
  terrain3DByMap.set(map, layer);
20
30
  onAdd3DLayer(layer, map);
21
31
  if (rootByLayer.get(layer)) terrainPromiseByLayer.set(layer, loadTerrain(layer));
@@ -11,6 +11,7 @@ import { terrainPromiseByLayer } from '../weakmaps/terrainPromiseByLayer.js';
11
11
  import { terrainReadyByLayer } from '../weakmaps/terrainReadyByLayer.js';
12
12
  import { terrainTilesByLayer } from '../weakmaps/terrainTilesByLayer.js';
13
13
  import { terrain3DByMap } from '../weakmaps/terrain3DByMap.js';
14
+ import { streamTerrainByMap } from '../weakmaps/streamTerrainByMap.js';
14
15
 
15
16
 
16
17
  import { renderEmpty } from '../globals/renderEmpty.js';
@@ -25,7 +26,15 @@ import { onRemove3DLayer } from '../scene/onRemove3DLayer.js';
25
26
  import { clearLayerTerrain } from './clearLayerTerrain.js';
26
27
 
27
28
  export function onTerrainRemove(layer, map) {
28
-
29
+ const stream = streamTerrainByMap.get(map);
30
+ if (stream?.layer === layer) {
31
+ streamTerrainByMap.delete(map);
32
+ stream.terrainController.abort();
33
+ stream.terrainCache.clear();
34
+ map.fire('terrainchange');
35
+ onRemove3DLayer(layer, map);
36
+ return;
37
+ }
29
38
  terrainControllerByLayer.get(layer)?.abort();
30
39
  terrainLoadingByLayer.set(layer, false);
31
40
  terrainReadyByLayer.set(layer, false);
@@ -0,0 +1,5 @@
1
+ export function yieldTask(delay = 0) {
2
+ const task = Promise.withResolvers();
3
+ setTimeout(task.resolve, delay);
4
+ return task.promise;
5
+ }
@@ -0,0 +1,22 @@
1
+ export function appendQuotedStyleCharacter(char, state) {
2
+ if (state.quoted) {
3
+ if (state.escaped) {
4
+ state.escaped = false;
5
+ return char === "'" ? char : '\\' + char;
6
+ }
7
+ if (char === '\\') {
8
+ state.escaped = true;
9
+ return '';
10
+ }
11
+ if (char === state.quoted) {
12
+ state.quoted = '';
13
+ return '"';
14
+ }
15
+ return char === '"' ? '\\"' : char;
16
+ }
17
+ if (char === '"' || char === "'") {
18
+ state.quoted = char;
19
+ return '"';
20
+ }
21
+ return undefined;
22
+ }
@@ -0,0 +1,8 @@
1
+ export function arrayContainsRange(values, start, end, target) {
2
+ let i = 0, value = null;
3
+ for (i = start; i < end; i++) {
4
+ value = values[i];
5
+ if (value === target || (value !== value && target !== target)) return true;
6
+ }
7
+ return false;
8
+ }
@@ -0,0 +1,18 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function evaluateBoolean(op, args, properties, zoom, legacy) {
4
+ let i = 0;
5
+ if (op === 'all') {
6
+ for (i = 0; i < args.length; i++) {
7
+ if (!evaluateStyle(args[i], properties, zoom, legacy)) return false;
8
+ }
9
+ return true;
10
+ }
11
+ if (op === 'any') {
12
+ for (i = 0; i < args.length; i++) {
13
+ if (evaluateStyle(args[i], properties, zoom, legacy)) return true;
14
+ }
15
+ return false;
16
+ }
17
+ throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
18
+ }
@@ -0,0 +1,21 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function evaluateCoalesceOrCase(op, args, properties, zoom, legacy) {
4
+ let i = 0, result = null;
5
+ if (op === 'coalesce') {
6
+ for (i = 0; i < args.length; i++) {
7
+ result = evaluateStyle(args[i], properties, zoom);
8
+ if (result !== null && result !== undefined) return result;
9
+ }
10
+ return null;
11
+ }
12
+ if (op === 'case') {
13
+ for (i = 0; i < args.length - 1; i += 2) {
14
+ if (evaluateStyle(args[i], properties, zoom)) {
15
+ return evaluateStyle(args[i + 1], properties, zoom);
16
+ }
17
+ }
18
+ return evaluateStyle(args[args.length - 1], properties, zoom);
19
+ }
20
+ throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
21
+ }
@@ -0,0 +1,16 @@
1
+ import { evaluateInput } from './evaluateInput.js';
2
+ import { evaluateStyle } from './evaluateStyle.js';
3
+
4
+ export function evaluateComparison(op, args, properties, zoom, legacy) {
5
+ const left = evaluateInput(args[0], properties, zoom, legacy);
6
+ const right = evaluateStyle(args[1], properties, zoom);
7
+ switch (op) {
8
+ case '==': return left === right;
9
+ case '!=': return left !== right;
10
+ case '<=': return left <= right;
11
+ case '>=': return left >= right;
12
+ case '<': return left < right;
13
+ case '>': return left > right;
14
+ default: throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
15
+ }
16
+ }
@@ -0,0 +1,8 @@
1
+ import { evaluateInterpolate } from './evaluateInterpolate.js';
2
+ import { evaluateMembership } from './evaluateMembership.js';
3
+
4
+ export function evaluateIExpression(op, args, properties, zoom, legacy) {
5
+ if (op === 'in') return evaluateMembership(op, args, properties, zoom, legacy);
6
+ if (op === 'interpolate') return evaluateInterpolate(args, properties, zoom);
7
+ throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
8
+ }
@@ -0,0 +1,6 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function evaluateInput(value, properties, zoom, legacy) {
4
+ if (legacy && typeof value === 'string') return properties[value];
5
+ return evaluateStyle(value, properties, zoom);
6
+ }
@@ -0,0 +1,27 @@
1
+ import { styleColor } from './styleColor.js';
2
+ import { evaluateStyle } from './evaluateStyle.js';
3
+
4
+ export function evaluateInterpolate(args, properties, zoom) {
5
+ const result = evaluateStyle(args[1], properties, zoom);
6
+ const base = args[0][0] === 'exponential' ? args[0][1] : 1;
7
+ let i = 0, lower = 0, upper = 0, ratio = 0, left = null, right = null, j = 0, color = '';
8
+ if (result <= args[2]) return evaluateStyle(args[3], properties, zoom);
9
+ for (i = 4; i < args.length; i += 2) {
10
+ if (result > args[i]) continue;
11
+ lower = args[i - 2];
12
+ upper = args[i];
13
+ ratio = base === 1 ? (result - lower) / (upper - lower)
14
+ : (base ** (result - lower) - 1) / (base ** (upper - lower) - 1);
15
+ left = evaluateStyle(args[i - 1], properties, zoom);
16
+ right = evaluateStyle(args[i + 1], properties, zoom);
17
+ if (typeof left === 'number' && typeof right === 'number') return left + (right - left) * ratio;
18
+ left = styleColor(left);
19
+ right = styleColor(right);
20
+ for (j = 0; j < 3; j++) {
21
+ if (j) color += ',';
22
+ color += Math.round(left[j] + (right[j] - left[j]) * ratio);
23
+ }
24
+ return `rgba(${color},${left[3] + (right[3] - left[3]) * ratio})`;
25
+ }
26
+ return evaluateStyle(args.at(-1), properties, zoom);
27
+ }
@@ -0,0 +1,12 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function evaluateMatch(args, properties, zoom) {
4
+ const result = evaluateStyle(args[0], properties, zoom);
5
+ let i = 0, matched = false;
6
+ for (i = 1; i < args.length - 1; i += 2) {
7
+ if (Array.isArray(args[i])) matched = args[i].includes(result);
8
+ else matched = args[i] === result;
9
+ if (matched) return evaluateStyle(args[i + 1], properties, zoom);
10
+ }
11
+ return evaluateStyle(args[args.length - 1], properties, zoom);
12
+ }
@@ -0,0 +1,14 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function evaluateMath(op, args, properties, zoom) {
4
+ let i = 0, sum = 0;
5
+ if (op === '+') {
6
+ for (i = 0; i < args.length; i++) sum += evaluateStyle(args[i], properties, zoom);
7
+ return sum;
8
+ }
9
+ if (op === '-') {
10
+ if (args.length === 1) return -evaluateStyle(args[0], properties, zoom);
11
+ return evaluateStyle(args[0], properties, zoom) - evaluateStyle(args[1], properties, zoom);
12
+ }
13
+ throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
14
+ }
@@ -0,0 +1,18 @@
1
+ import { arrayContainsRange } from './arrayContainsRange.js';
2
+ import { evaluateInput } from './evaluateInput.js';
3
+ import { evaluateStyle } from './evaluateStyle.js';
4
+
5
+ export function evaluateMembership(op, args, properties, zoom, legacy) {
6
+ let target = null;
7
+ if (op === '!in') {
8
+ target = evaluateInput(args[0], properties, zoom, legacy);
9
+ return !arrayContainsRange(args, 1, args.length, target);
10
+ }
11
+ if (legacy) {
12
+ target = evaluateInput(args[0], properties, zoom, true);
13
+ return arrayContainsRange(args, 1, args.length, target);
14
+ }
15
+ const values = evaluateStyle(args[1], properties, zoom);
16
+ target = evaluateInput(args[0], properties, zoom, false);
17
+ return values.includes(target);
18
+ }
@@ -0,0 +1,13 @@
1
+ import { evaluateInput } from './evaluateInput.js';
2
+ import { evaluateMembership } from './evaluateMembership.js';
3
+ import { evaluateStyle } from './evaluateStyle.js';
4
+
5
+ export function evaluateNegation(op, args, properties, zoom, legacy) {
6
+ if (op === '!') return !evaluateStyle(args[0], properties, zoom, legacy);
7
+ if (op === '!=') {
8
+ return evaluateInput(args[0], properties, zoom, legacy) !==
9
+ evaluateStyle(args[1], properties, zoom);
10
+ }
11
+ if (op === '!in') return evaluateMembership(op, args, properties, zoom, legacy);
12
+ throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
13
+ }
@@ -0,0 +1,9 @@
1
+ export function evaluatePrimitive(op, args, properties, zoom) {
2
+ switch (op) {
3
+ case 'literal': return args[0];
4
+ case 'get': return properties[args[0]];
5
+ case 'has': return Object.hasOwn(properties, args[0]);
6
+ case 'zoom': return zoom;
7
+ default: throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function evaluateStep(args, properties, zoom) {
4
+ const result = evaluateStyle(args[0], properties, zoom);
5
+ let output = args[1], i = 0;
6
+ for (i = 2; i < args.length; i += 2) {
7
+ if (result < args[i]) break;
8
+ output = args[i + 1];
9
+ }
10
+ return evaluateStyle(output, properties, zoom);
11
+ }
@@ -0,0 +1,33 @@
1
+ import { evaluateBoolean } from './evaluateBoolean.js';
2
+ import { evaluateCoalesceOrCase } from './evaluateCoalesceOrCase.js';
3
+ import { evaluateComparison } from './evaluateComparison.js';
4
+ import { evaluateIExpression } from './evaluateIExpression.js';
5
+ import { evaluateMath } from './evaluateMath.js';
6
+ import { evaluateMatch } from './evaluateMatch.js';
7
+ import { evaluateNegation } from './evaluateNegation.js';
8
+ import { evaluatePrimitive } from './evaluatePrimitive.js';
9
+ import { evaluateStep } from './evaluateStep.js';
10
+ import { evaluateToExpression } from './evaluateToExpression.js';
11
+
12
+ export function evaluateStyle(value, properties, zoom, legacy = false) {
13
+ if (!Array.isArray(value)) return value;
14
+ const op = value[0];
15
+ const args = value.slice(1);
16
+ const operation = String(op);
17
+ if (/^(?:literal|get|has|zoom)$/.test(operation)) {
18
+ return evaluatePrimitive(op, args, properties, zoom);
19
+ }
20
+ switch (operation[0]) {
21
+ case 'a': return evaluateBoolean(op, args, properties, zoom, legacy);
22
+ case '!': return evaluateNegation(op, args, properties, zoom, legacy);
23
+ case '=':
24
+ case '<':
25
+ case '>': return evaluateComparison(op, args, properties, zoom, legacy);
26
+ case 'i': return evaluateIExpression(op, args, properties, zoom, legacy);
27
+ case 't': return evaluateToExpression(op, args, properties, zoom, legacy);
28
+ case 'c': return evaluateCoalesceOrCase(op, args, properties, zoom, legacy);
29
+ case 'm': return evaluateMatch(args, properties, zoom);
30
+ case 's': return evaluateStep(args, properties, zoom);
31
+ default: return evaluateMath(op, args, properties, zoom);
32
+ }
33
+ }
@@ -0,0 +1,14 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function evaluateToExpression(op, args, properties, zoom) {
4
+ if (op === 'to-boolean') return Boolean(evaluateStyle(args[0], properties, zoom));
5
+ if (op === 'to-number') {
6
+ let i = 0, number = 0;
7
+ for (i = 0; i < args.length; i++) {
8
+ number = Number(evaluateStyle(args[i], properties, zoom));
9
+ if (Number.isFinite(number)) return number;
10
+ }
11
+ throw /* alloc */ new Error('Invalid numeric style expression');
12
+ }
13
+ throw /* alloc */ new Error(`Unsupported vector style expression: ${op}`);
14
+ }
@@ -0,0 +1,17 @@
1
+ import { readPaintValue } from './readPaintValue.js';
2
+ import { styleColor } from './styleColor.js';
3
+
4
+ export function fillVectorPaint(paint, properties, zoom) {
5
+ const fill = styleColor(readPaintValue(paint, 'fill-color', '#000', properties, zoom));
6
+ const outline = readPaintValue(paint, 'fill-outline-color', null, properties, zoom);
7
+ const rgb = outline === null ? null : styleColor(outline);
8
+ const fillOpacity = readPaintValue(paint, 'fill-opacity', 1, properties, zoom) * fill[3];
9
+ const fillColor = /* alloc */ { r: fill[0] / 255, g: fill[1] / 255, b: fill[2] / 255 };
10
+ const color = rgb ? /* alloc */ { r: rgb[0] / 255, g: rgb[1] / 255, b: rgb[2] / 255 } : null;
11
+ return /* alloc */ {
12
+ fillColor,
13
+ fillOpacity,
14
+ color,
15
+ weight: 0.5
16
+ };
17
+ }
@@ -0,0 +1,21 @@
1
+ import { readPaintValue } from './readPaintValue.js';
2
+ import { scaleDashArray } from './scaleDashArray.js';
3
+ import { styleColor } from './styleColor.js';
4
+
5
+ export function lineVectorPaint(layer, paint, properties, zoom) {
6
+ const weight = readPaintValue(paint, 'line-width', 1, properties, zoom);
7
+ const rgb = styleColor(readPaintValue(paint, 'line-color', '#000', properties, zoom));
8
+ const opacity = readPaintValue(paint, 'line-opacity', 1, properties, zoom) * rgb[3];
9
+ const dashArray = scaleDashArray(paint['line-dasharray'], weight, properties, zoom);
10
+ const lineCap = layer.layout?.['line-cap'] || 'butt';
11
+ const lineJoin = layer.layout?.['line-join'] || 'miter';
12
+ const color = /* alloc */ { r: rgb[0] / 255, g: rgb[1] / 255, b: rgb[2] / 255 };
13
+ return /* alloc */ {
14
+ color,
15
+ opacity,
16
+ weight,
17
+ dashArray,
18
+ lineCap,
19
+ lineJoin
20
+ };
21
+ }
@@ -0,0 +1,14 @@
1
+ export function parseFunctionalColor(value) {
2
+ const match = /^rgba?\(([^)]+)\)$/.exec(value);
3
+ if (match) {
4
+ const values = match[1].split(',');
5
+ let i = 0, finite = true;
6
+ for (i = 0; i < values.length; i++) values[i] = Number(values[i]);
7
+ if (values.length === 3) values.push(1);
8
+ for (i = 0; i < values.length; i++) {
9
+ if (!Number.isFinite(values[i])) finite = false;
10
+ }
11
+ if (values.length === 4 && finite) return values;
12
+ }
13
+ throw /* alloc */ new Error(`Unsupported interpolated style color: ${value}`);
14
+ }