leaflet-city-mapper 0.0.6 → 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 (241) hide show
  1. package/README.md +10 -5
  2. package/dist/leaflet-city-mapper-src.js +7059 -6566
  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.js +1 -1
  11. package/package.json +1 -1
  12. package/src/camera/setBearing.js +5 -0
  13. package/src/camera/setPitch.js +5 -0
  14. package/src/cog/initCog.js +2 -2
  15. package/src/core/gridlayerGetTiledPixelBounds.js +37 -4
  16. package/src/core/markerSetPos.js +1 -1
  17. package/src/core/popupGetEvents.js +1 -1
  18. package/src/core/popupUpdatePosition.js +8 -8
  19. package/src/core/tooltipGetEvents.js +1 -1
  20. package/src/core/tooltipSetPosition.js +2 -2
  21. package/src/geometry/appendNativeTriangle.js +2 -2
  22. package/src/geometry/createModelGeometry.js +2 -9
  23. package/src/geometry/dashedSegment.js +10 -5
  24. package/src/geometry/disk.js +1 -1
  25. package/src/geometry/fillNativePolygon.js +20 -0
  26. package/src/geometry/lineJoin.js +2 -2
  27. package/src/geometry/markerQuadCorners.js +6 -0
  28. package/src/geometry/nativeGeometry.js +1 -1
  29. package/src/geometry/polygon.js +4 -10
  30. package/src/geometry/segment.js +4 -3
  31. package/src/globals/colorTexture.js +6 -0
  32. package/src/globals/depthTexture.js +1 -0
  33. package/src/globals/drawMeshEntry.js +1 -1
  34. package/src/globals/meshPipeline.js +1 -0
  35. package/src/globals/mvtTextDecoder.js +1 -0
  36. package/src/globals/nativeScalableStyleKeys.js +1 -0
  37. package/src/globals/scenePass.js +1 -0
  38. package/src/globals/vectorStyleNamedColors.js +8 -0
  39. package/src/globals/vectorTileEvents.js +1 -0
  40. package/src/globals/workerCogSource.js +1 -0
  41. package/src/gpu/mountRenderer.js +4 -11
  42. package/src/gpu/releaseRenderer.js +1 -0
  43. package/src/index.js +6 -12
  44. package/src/materials/createProgramUniforms.js +1 -0
  45. package/src/models/loadModel.js +6 -10
  46. package/src/models/loadModelResources.js +2 -8
  47. package/src/models/modelNode.js +3 -7
  48. package/src/models/prepareModel.js +19 -0
  49. package/src/models/prepareModelGeometry.js +25 -0
  50. package/src/models/prepareModelPrimitive.js +17 -0
  51. package/src/mvt/addMvtCrossings.js +17 -0
  52. package/src/mvt/appendMvtBandTriangles.js +31 -0
  53. package/src/mvt/appendMvtCoordinates.js +11 -0
  54. package/src/mvt/appendMvtPolygonTriangles.js +19 -0
  55. package/src/mvt/beginMvtPath.js +9 -0
  56. package/src/mvt/closeMvtPath.js +7 -0
  57. package/src/mvt/collectMvtEdges.js +19 -0
  58. package/src/mvt/createMvtReader.js +7 -0
  59. package/src/mvt/decodeVectorTile.js +32 -0
  60. package/src/mvt/expectMvtWire.js +3 -0
  61. package/src/mvt/finishMvtPath.js +5 -0
  62. package/src/mvt/finiteMvtCoordinate.js +7 -0
  63. package/src/mvt/groupMvtPolygons.js +25 -0
  64. package/src/mvt/isMvtFallbackError.js +6 -0
  65. package/src/mvt/mergeMvtActiveEdges.js +9 -0
  66. package/src/mvt/mvtEdgeX.js +4 -0
  67. package/src/mvt/mvtPathsVertices.js +8 -0
  68. package/src/mvt/mvtPolygonPaths.js +12 -0
  69. package/src/mvt/numericMvtValue.js +4 -0
  70. package/src/mvt/readMvtFeature.js +34 -0
  71. package/src/mvt/readMvtField.js +8 -0
  72. package/src/mvt/readMvtGeometry.js +29 -0
  73. package/src/mvt/readMvtInteger.js +12 -0
  74. package/src/mvt/readMvtKnownValue.js +21 -0
  75. package/src/mvt/readMvtLayer.js +31 -0
  76. package/src/mvt/readMvtMessage.js +10 -0
  77. package/src/mvt/readMvtNumber.js +9 -0
  78. package/src/mvt/readMvtNumbers.js +11 -0
  79. package/src/mvt/readMvtString.js +6 -0
  80. package/src/mvt/readMvtValue.js +19 -0
  81. package/src/mvt/skipMvtField.js +14 -0
  82. package/src/mvt/sortMvtActiveEdges.js +15 -0
  83. package/src/mvt/sortedMvtLevels.js +22 -0
  84. package/src/mvt/takeMvtBytes.js +8 -0
  85. package/src/mvt/tessellateVectorRings.js +19 -0
  86. package/src/mvt/triangulateVectorRings.js +19 -0
  87. package/src/native/beforeNativeRender.js +6 -0
  88. package/src/native/canScaleNativeStyle.js +17 -0
  89. package/src/native/createNativeMesh.js +31 -0
  90. package/src/native/disposeNativeLayer.js +1 -1
  91. package/src/native/getGridTerrainTile.js +34 -0
  92. package/src/native/gridTerrainElevation.js +30 -0
  93. package/src/native/loadGridTerrain.js +26 -0
  94. package/src/native/nativeLayer.js +2 -2
  95. package/src/native/nativeLayerMethod.js +5 -14
  96. package/src/native/nativeProgram.js +20 -0
  97. package/src/native/nativeVectorGeometry.js +23 -0
  98. package/src/native/orderNativeGridLayer.js +14 -0
  99. package/src/native/putNativeMesh.js +15 -21
  100. package/src/native/refreshNativeEvent.js +13 -2
  101. package/src/native/refreshNativeLayer.js +1 -0
  102. package/src/native/syncGridLayer.js +48 -3
  103. package/src/native/syncNativeStrokeAnchors.js +12 -0
  104. package/src/native/syncNativeStrokeZoom.js +29 -0
  105. package/src/native/syncVectorLayer.js +15 -13
  106. package/src/native/terrainGridMesh.js +34 -0
  107. package/src/native/updateNativeStrokeRadius.js +9 -0
  108. package/src/projections/displayContainerPoint.js +23 -3
  109. package/src/projections/groundBounds.js +2 -2
  110. package/src/projections/localPixel.js +7 -2
  111. package/src/projections/localPixelForGeometry.js +4 -2
  112. package/src/projections/projectCameraPoint.js +6 -5
  113. package/src/rendering/collectVisibleMesh.js +5 -2
  114. package/src/rendering/drawSceneMeshes.js +3 -1
  115. package/src/rendering/nativeStrokeExpansion.js +4 -0
  116. package/src/rendering/prepareMeshUniforms.js +2 -0
  117. package/src/rendering/resizeRenderer.js +9 -0
  118. package/src/scene/initializerFor.js +3 -5
  119. package/src/scene/layerInitialize.js +14 -12
  120. package/src/scene/resolveNextInitialization.js +1 -1
  121. package/src/shaders/materialShaders.js +1 -0
  122. package/src/shaders/materialVertexShader.js +7 -2
  123. package/src/shaders/nativeStrokeShader.js +6 -0
  124. package/src/sources/attachAreaMesh.js +5 -6
  125. package/src/sources/buildArea.js +4 -5
  126. package/src/sources/buildAreaFeature.js +3 -19
  127. package/src/sources/initVectorTiles.js +15 -0
  128. package/src/sources/isVectorTileSource.js +4 -0
  129. package/src/sources/readyVectorTiles.js +10 -0
  130. package/src/sources/sourceAreaContext.js +1 -6
  131. package/src/sunlight/createSun.js +0 -1
  132. package/src/terrain/initTerrain.js +7 -1
  133. package/src/terrain/loadTerrain.js +4 -1
  134. package/src/terrain/mapElevationOf.js +5 -1
  135. package/src/terrain/onTerrainAdd.js +11 -1
  136. package/src/terrain/onTerrainRemove.js +10 -1
  137. package/src/utils/yieldTask.js +5 -0
  138. package/src/vector-style/appendQuotedStyleCharacter.js +22 -0
  139. package/src/vector-style/arrayContainsRange.js +8 -0
  140. package/src/vector-style/evaluateBoolean.js +18 -0
  141. package/src/vector-style/evaluateCoalesceOrCase.js +21 -0
  142. package/src/vector-style/evaluateComparison.js +16 -0
  143. package/src/vector-style/evaluateIExpression.js +8 -0
  144. package/src/vector-style/evaluateInput.js +6 -0
  145. package/src/vector-style/evaluateInterpolate.js +27 -0
  146. package/src/vector-style/evaluateMatch.js +12 -0
  147. package/src/vector-style/evaluateMath.js +14 -0
  148. package/src/vector-style/evaluateMembership.js +18 -0
  149. package/src/vector-style/evaluateNegation.js +13 -0
  150. package/src/vector-style/evaluatePrimitive.js +9 -0
  151. package/src/vector-style/evaluateStep.js +11 -0
  152. package/src/vector-style/evaluateStyle.js +33 -0
  153. package/src/vector-style/evaluateToExpression.js +14 -0
  154. package/src/vector-style/fillVectorPaint.js +17 -0
  155. package/src/vector-style/lineVectorPaint.js +21 -0
  156. package/src/vector-style/parseFunctionalColor.js +14 -0
  157. package/src/vector-style/parseHexColor.js +13 -0
  158. package/src/vector-style/parseVectorStyle.js +13 -0
  159. package/src/vector-style/readPaintValue.js +6 -0
  160. package/src/vector-style/removeTrailingCommas.js +12 -0
  161. package/src/vector-style/scaleDashArray.js +13 -0
  162. package/src/vector-style/skipStyleComment.js +9 -0
  163. package/src/vector-style/stripStyleComments.js +21 -0
  164. package/src/vector-style/styleColor.js +11 -0
  165. package/src/vector-style/validateVectorLayers.js +10 -0
  166. package/src/vector-style/vectorPaint.js +8 -0
  167. package/src/vector-style/visibleStyle.js +7 -0
  168. package/src/vector-tiles/appendVectorBatch.js +22 -0
  169. package/src/vector-tiles/attachVectorTileBatch.js +17 -0
  170. package/src/vector-tiles/attachVectorTileBatches.js +15 -0
  171. package/src/vector-tiles/compareVectorLabelPriority.js +3 -0
  172. package/src/vector-tiles/compareVectorTileDistance.js +3 -0
  173. package/src/vector-tiles/configureVectorTileLayer.js +28 -0
  174. package/src/vector-tiles/forwardVectorTileError.js +5 -0
  175. package/src/vector-tiles/loadVectorSprite.js +5 -0
  176. package/src/vector-tiles/loadVectorTile.js +36 -0
  177. package/src/vector-tiles/onVectorTileAdd.js +39 -0
  178. package/src/vector-tiles/onVectorTileMessage.js +10 -0
  179. package/src/vector-tiles/onVectorTileRemove.js +20 -0
  180. package/src/vector-tiles/onVectorTileWorkerError.js +11 -0
  181. package/src/vector-tiles/paintVectorTileBatch.js +12 -0
  182. package/src/vector-tiles/prepareVectorLabel.js +43 -0
  183. package/src/vector-tiles/prepareVectorStyleLayer.js +30 -0
  184. package/src/vector-tiles/prepareVectorTile.js +16 -0
  185. package/src/vector-tiles/projectVectorPaths.js +15 -0
  186. package/src/vector-tiles/projectVectorPoint.js +6 -0
  187. package/src/vector-tiles/projectVectorTriangles.js +18 -0
  188. package/src/vector-tiles/pruneVectorTiles.js +11 -0
  189. package/src/vector-tiles/pumpVectorTiles.js +18 -0
  190. package/src/vector-tiles/readTileJSON.js +17 -0
  191. package/src/vector-tiles/readVectorStyle.js +17 -0
  192. package/src/vector-tiles/refreshVectorTiles.js +5 -0
  193. package/src/vector-tiles/reserveVectorLabelCells.js +6 -0
  194. package/src/vector-tiles/retireVectorTileGroup.js +13 -0
  195. package/src/vector-tiles/revokeVectorWorkerUrl.js +9 -0
  196. package/src/vector-tiles/rotateVectorLabel.js +12 -0
  197. package/src/vector-tiles/rotateVectorLabels.js +6 -0
  198. package/src/vector-tiles/simplifyVectorPath.js +21 -0
  199. package/src/vector-tiles/updateVectorLabelMarker.js +27 -0
  200. package/src/vector-tiles/updateVectorTileLabels.js +28 -0
  201. package/src/vector-tiles/updateVectorTilePaint.js +20 -0
  202. package/src/vector-tiles/updateVectorTiles.js +29 -0
  203. package/src/vector-tiles/validateVectorTileZooms.js +6 -0
  204. package/src/vector-tiles/vectorFeaturePaint.js +15 -0
  205. package/src/vector-tiles/vectorFeaturePaths.js +16 -0
  206. package/src/vector-tiles/vectorFeatureZoom.js +8 -0
  207. package/src/vector-tiles/vectorLabelAnchors.js +24 -0
  208. package/src/vector-tiles/vectorLabelCandidates.js +11 -0
  209. package/src/vector-tiles/vectorLabelCells.js +26 -0
  210. package/src/vector-tiles/vectorLabelIcon.js +30 -0
  211. package/src/vector-tiles/vectorLabelProperty.js +3 -0
  212. package/src/vector-tiles/vectorSpriteIcon.js +11 -0
  213. package/src/vector-tiles/vectorStraightRun.js +14 -0
  214. package/src/vector-tiles/vectorStyleDependencies.js +15 -0
  215. package/src/vector-tiles/vectorStyleValue.js +5 -0
  216. package/src/vector-tiles/vectorStyleZoom.js +6 -0
  217. package/src/vector-tiles/vectorTileAwaited.js +9 -0
  218. package/src/vector-tiles/vectorTileOverlaps.js +4 -0
  219. package/src/vector-tiles/vectorTilePaint.js +10 -0
  220. package/src/vector-tiles/vectorTileSettings.js +17 -0
  221. package/src/vector-tiles/vectorTilesIdle.js +3 -0
  222. package/src/vector-tiles/vectorTolerance.js +4 -0
  223. package/src/vector-tiles/wrapVectorLabel.js +11 -0
  224. package/src/weakmaps/nativeProgramsByRenderer.js +1 -0
  225. package/src/weakmaps/streamTerrainByLayer.js +1 -0
  226. package/src/weakmaps/streamTerrainByMap.js +1 -0
  227. package/src/weakmaps/vectorTileOptionsByLayer.js +1 -0
  228. package/src/weakmaps/vectorWorkerByLayer.js +1 -0
  229. package/src/weakmaps/workerMapByLayer.js +1 -0
  230. package/src/workers/buildAreaInWorker.js +3 -27
  231. package/src/workers/cogWorker.js +21 -0
  232. package/src/workers/createGeometryWorker.js +1 -0
  233. package/src/workers/geometryWorker.js +15 -0
  234. package/src/workers/getCogInWorker.js +7 -0
  235. package/src/workers/modelWorker.js +10 -0
  236. package/src/workers/openCogInWorker.js +14 -0
  237. package/src/workers/runSourceWorker.js +32 -0
  238. package/src/workers/settleGeometryWorker.js +1 -1
  239. package/src/workers/vectorTileWorker.js +10 -0
  240. package/src/geometry/buildExtrudedPolygon.js +0 -10
  241. package/src/sources/buildAreaPoint.js +0 -7
@@ -3,7 +3,7 @@ import { pointOf } from './toPoint.js';
3
3
  import { angles } from './cameraAngles.js';
4
4
 
5
5
 
6
- export function project(map, point, inverse = false, limit = false) {
6
+ export function project(map, point, inverse = false, limit = false, height = 0) {
7
7
  const size = map.getSize(), halfX = size.x / 2, halfY = size.y / 2, distance = size.y * 1.5;
8
8
  const result = pointOf(point);
9
9
  if (!distance) return result;
@@ -12,16 +12,17 @@ export function project(map, point, inverse = false, limit = false) {
12
12
  if (inverse) {
13
13
  const far = size.y * map.options.pitchMaxDistance;
14
14
  const denominator = tilt * distance + rise * y;
15
- let v = denominator * tilt > 0 ? y * distance / denominator : -far;
15
+ let v = denominator * tilt > 0
16
+ ? (y * (distance - tilt * height) + distance * rise * height) / denominator : -far;
16
17
  if (limit) v = Math.max(-far, Math.min(far, v));
17
- const u = x * (distance - rise * v) / distance;
18
+ const u = x * (distance - rise * v - tilt * height) / distance;
18
19
  result.x = cos * u + sin * v + halfX;
19
20
  result.y = -sin * u + cos * v + halfY;
20
21
  return result;
21
22
  }
22
23
  const u = cos * x - sin * y, v = sin * x + cos * y;
23
- const scale = distance / (distance - rise * v);
24
+ const scale = distance / (distance - rise * v - tilt * height);
24
25
  result.x = u * scale + halfX;
25
- result.y = tilt * v * scale + halfY;
26
+ result.y = (tilt * v - rise * height) * scale + halfY;
26
27
  return result;
27
28
  }
@@ -1,4 +1,5 @@
1
1
  import { computeBounds } from '../geometry/computeBounds.js';
2
+ import { nativeStrokeExpansion } from './nativeStrokeExpansion.js';
2
3
 
3
4
  export function collectVisibleMesh(mesh, projection, frustum, frustumLengths, candidates) {
4
5
  if (!mesh.geometry.bounds) computeBounds(mesh.geometry);
@@ -12,16 +13,18 @@ export function collectVisibleMesh(mesh, projection, frustum, frustumLengths, ca
12
13
  sphere.x = world[0] * center[0] + world[4] * center[1] + world[8] * center[2] + world[12];
13
14
  sphere.y = world[1] * center[0] + world[5] * center[1] + world[9] * center[2] + world[13];
14
15
  sphere.z = world[2] * center[0] + world[6] * center[1] + world[10] * center[2] + world[14];
15
- sphere.radius = bounds.radius * Math.max(
16
+ sphere.scale = Math.max(
16
17
  Math.hypot(world[0], world[1], world[2]),
17
18
  Math.hypot(world[4], world[5], world[6]),
18
19
  Math.hypot(world[8], world[9], world[10])
19
20
  );
21
+ sphere.radius = bounds.radius * sphere.scale;
20
22
  sphere.bounds = bounds;
21
23
  sphere.matrix = world;
22
24
  sphere.version = mesh._worldMatrixVersion;
23
25
  }
24
- const { x, y, z, radius } = sphere;
26
+ const { x, y, z } = sphere;
27
+ const radius = sphere.radius + nativeStrokeExpansion(mesh) * sphere.scale;
25
28
  const clipZ = projection[2] * x + projection[6] * y + projection[10] * z + projection[14];
26
29
  const clipW = projection[3] * x + projection[7] * y + projection[11] * z + projection[15];
27
30
  mesh._sortDepth = clipZ / clipW;
@@ -9,11 +9,13 @@ import { drawGeometry } from './drawGeometry.js';
9
9
  export function drawSceneMeshes(layer, encoder, meshes) {
10
10
  const renderer = rendererByLayer.get(layer);
11
11
  const pass = encoder.beginRenderPass((
12
- scenePass.colorAttachments[0].view = renderer.context.getCurrentTexture().createView(),
12
+ scenePass.colorAttachments[0].view = renderer.colorTexture.createView(),
13
+ scenePass.colorAttachments[0].resolveTarget = renderer.context.getCurrentTexture().createView(),
13
14
  scenePass.depthStencilAttachment.view = renderer.depthTexture.createView(),
14
15
  scenePass
15
16
  ));
16
17
  scenePass.colorAttachments[0].view = null;
18
+ scenePass.colorAttachments[0].resolveTarget = null;
17
19
  scenePass.depthStencilAttachment.view = null;
18
20
  pass.setViewport(0, 0, renderer.canvas.width, renderer.canvas.height, 0, 1);
19
21
  pass.setBindGroup(1, renderer.sunlight.bindGroup);
@@ -0,0 +1,4 @@
1
+ export function nativeStrokeExpansion(mesh) {
2
+ const strokeScale = mesh.program?.uniforms?.strokeScale?.value ?? 1;
3
+ return Math.max(0, strokeScale - 1) * (mesh.geometry.nativeStrokeRadius || 0);
4
+ }
@@ -20,6 +20,8 @@ export function prepareMeshUniforms(renderer, mesh) {
20
20
  data[base + 34] = mesh.program.nightSparkle ? data[55] : 0;
21
21
  data[base + 35] = mesh.ground ? 1 : mesh._appearance ?? 1;
22
22
  prepareMeshCutout(renderer, mesh, base);
23
+ data[base + 40] = uniforms.strokeScale?.value ?? 1;
24
+ data[base + 41] = data[base + 42] = data[base + 43] = 0;
23
25
  return offset;
24
26
  }
25
27
  import { prepareMeshCutout } from '../materials/prepareMeshCutout.js';
@@ -2,6 +2,7 @@ import { rendererByLayer } from '../weakmaps/rendererByLayer.js';
2
2
  import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
3
3
 
4
4
  import { depthTexture as sharedDepthTexture } from '../globals/depthTexture.js';
5
+ import { colorTexture as sharedColorTexture } from '../globals/colorTexture.js';
5
6
 
6
7
 
7
8
  import { destroyTexture } from '../textures/destroyTexture.js';
@@ -15,6 +16,14 @@ export function resizeRenderer(layer, size) {
15
16
  rendererByLayer.get(layer).canvas.style.width = `${size.x}px`;
16
17
  rendererByLayer.get(layer).canvas.style.height = `${size.y}px`;
17
18
  if (rendererByLayer.get(layer).depthTexture) destroyTexture(layer, rendererByLayer.get(layer).depthTexture);
19
+ rendererByLayer.get(layer).colorTexture?.destroy();
20
+ rendererByLayer.get(layer).colorTexture = rendererByLayer.get(layer).device.createTexture((
21
+ sharedColorTexture.size[0] = rendererByLayer.get(layer).canvas.width,
22
+ sharedColorTexture.size[1] = rendererByLayer.get(layer).canvas.height,
23
+ sharedColorTexture.format = rendererByLayer.get(layer).format,
24
+ sharedColorTexture.usage = GPUTextureUsage.RENDER_ATTACHMENT,
25
+ sharedColorTexture
26
+ ));
18
27
  rendererByLayer.get(layer).depthTexture = rendererByLayer.get(layer).device.createTexture((
19
28
  sharedDepthTexture.size[0] = rendererByLayer.get(layer).canvas.width,
20
29
  sharedDepthTexture.size[1] = rendererByLayer.get(layer).canvas.height,
@@ -1,14 +1,12 @@
1
- import { initializeGeoJSON } from '../sources/initializeGeoJSON.js';
2
1
  import { initRaster } from '../raster/initRaster.js';
3
2
  import { initTerrain } from '../terrain/initTerrain.js';
4
3
  import { initTraffic } from '../traffic/initTraffic.js';
5
4
  import { initCog } from '../cog/initCog.js';
6
5
 
7
- export function initializerFor(type) {
6
+ export function initializerFor(type, options = {}) {
8
7
  switch (type) {
9
- case 'geojson': return initializeGeoJSON;
10
- case 'pmtiles': return initRaster;
11
- case 'cog': return initCog;
8
+ case 'raster': return options.asset !== undefined || /\.tiff?(?:[?#]|$)/i.test(options.url)
9
+ ? initCog : initRaster;
12
10
  case 'terrain': return initTerrain;
13
11
  case 'traffic': return initTraffic;
14
12
  default: return null;
@@ -12,6 +12,9 @@ import { loading } from '../globals/loading.js';
12
12
 
13
13
 
14
14
  import { init3D } from './init3D.js';
15
+ import { initializeGeoJSON } from '../sources/initializeGeoJSON.js';
16
+ import { isVectorTileSource } from '../sources/isVectorTileSource.js';
17
+ import { initVectorTiles } from '../sources/initVectorTiles.js';
15
18
  import { noOperation } from '../utils/noOperation.js';
16
19
  import { resolveNextInitialization } from './resolveNextInitialization.js';
17
20
  import { initializeLayer } from './initializeLayer.js';
@@ -25,21 +28,20 @@ export function layerInitialize(options = sceneEmptyOptions) {
25
28
  L.Util.setOptions(this, options);
26
29
  return;
27
30
  }
28
- const {
29
- source: {
30
- type = options.source.data?.type === 'FeatureCollection'
31
- ? 'geojson'
32
- : /\.pmtiles(?:[?#]|$)/i.test(options.source.url) ? 'pmtiles'
33
- : /\.tiff?(?:[?#]|$)/i.test(options.source.url) ? 'cog' : '3d',
34
- ...source
35
- },
36
- ...core
37
- } = options;
31
+ const { source: { type = /\.pmtiles(?:[?#]|$)|\.tiff?(?:[?#]|$)/i.test(options.source.url)
32
+ ? 'raster' : 'vector', ...source }, ...core } = options;
38
33
  const settings = /* alloc */ { ...source, ...core };
39
34
  L.Util.setOptions(this, core);
40
35
  typeByLayer.set(this, type);
41
- if (type === '3d') {
42
- init3D(this, settings);
36
+ if (type === 'vector') {
37
+ if (isVectorTileSource(settings)) {
38
+ initVectorTiles(this, settings);
39
+ } else if (settings.data !== undefined ||
40
+ settings.url && !/\.(?:pmtiles|glb|gltf)(?:[?#]|$)/i.test(settings.url)) {
41
+ initializeGeoJSON(this, settings);
42
+ } else {
43
+ init3D(this, settings);
44
+ }
43
45
  return;
44
46
  }
45
47
  kindByLayer.set(this, 'pending');
@@ -5,7 +5,7 @@ import { initializerFor } from './initializerFor.js';
5
5
 
6
6
  export function resolveNextInitialization() {
7
7
  const task = pendingInitializations.shift();
8
- task.initialize = initializerFor(task.type);
8
+ task.initialize = initializerFor(task.type, task.settings);
9
9
  if (!task.initialize) {
10
10
  task.error = /* alloc */ new Error(`Unknown layer type: ${task.type}`);
11
11
  }
@@ -30,6 +30,7 @@ export function materialShaders(material = defaultMaterial, sparkle = false, ele
30
30
  terrain: vec4<f32>,
31
31
  highlight: vec4<f32>,
32
32
  cutout: vec4<f32>,
33
+ nativeStroke: vec4<f32>,
33
34
  };
34
35
  struct Frame {
35
36
  viewMatrix: mat4x4<f32>,
@@ -1,7 +1,9 @@
1
1
  import { roofVertexShader } from './roofVertexShader.js';
2
+ import { nativeStrokeShader } from './nativeStrokeShader.js';
2
3
 
3
4
  export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrain, textured, hasRoof) {
4
5
  const instanceOffset = material.instanced ? ' + input.instanceOffset.xyz' : '';
6
+ const stroke = nativeStrokeShader(material);
5
7
  return /* wgsl */ `
6
8
  struct Mesh {
7
9
  worldMatrix: mat4x4<f32>,
@@ -11,6 +13,7 @@ export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrai
11
13
  terrain: vec4<f32>,
12
14
  highlight: vec4<f32>,
13
15
  cutout: vec4<f32>,
16
+ nativeStroke: vec4<f32>,
14
17
  };
15
18
  struct Frame {
16
19
  viewMatrix: mat4x4<f32>,
@@ -46,6 +49,7 @@ export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrai
46
49
  @vertex fn vertexMain(input: VertexInput, @builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
47
50
  var output: VertexOutput;
48
51
  var position = input.position${instanceOffset};
52
+ ${stroke.position}
49
53
  ${hasTerrain ? 'position.y = elevation(u.terrain.xy + input.uv * u.terrain.z, u.terrain.w) - u.terrain.w;' : ''}
50
54
  let featureVertex = f32(vertexIndex)${material.instanced ? ' + input.instanceOffset.w' : ''};
51
55
  let highlighted = featureVertex >= u.highlight.x && featureVertex < u.highlight.y;
@@ -54,8 +58,9 @@ export function materialVertexShader(material, sparkle, elevationWGSL, hasTerrai
54
58
  : 'u.baseColor.rgb'};
55
59
  // Inverse-transpose from cofactors; the camera view matrix is orthonormal.
56
60
  let m = mat3x3<f32>(u.worldMatrix[0].xyz, u.worldMatrix[1].xyz, u.worldMatrix[2].xyz);
57
- let normal = (cross(m[1], m[2]) * input.normal.x + cross(m[2], m[0]) * input.normal.y +
58
- cross(m[0], m[1]) * input.normal.z) / determinant(m);
61
+ ${stroke.normal}
62
+ let normal = (cross(m[1], m[2]) * sourceNormal.x + cross(m[2], m[0]) * sourceNormal.y +
63
+ cross(m[0], m[1]) * sourceNormal.z) / determinant(m);
59
64
  output.normal = (frame.viewMatrix * vec4<f32>(normal, 0.0)).xyz;
60
65
  let world = u.worldMatrix * vec4<f32>(position, 1.0);
61
66
  output.shadowPosition = solar.matrix * world;
@@ -0,0 +1,6 @@
1
+ export function nativeStrokeShader(material) {
2
+ return /* alloc */ {
3
+ position: material.nativeStroke ? 'position = input.normal + (input.position - input.normal) * u.nativeStroke.x;' : '',
4
+ normal: material.nativeStroke ? 'let sourceNormal = vec3<f32>(0.0, 1.0, 0.0);' : 'let sourceNormal = input.normal;',
5
+ };
6
+ }
@@ -9,7 +9,6 @@ import { createProgram } from '../materials/createProgram.js';
9
9
 
10
10
  import { setParent } from '../scene/setParent.js';
11
11
  import { update } from '../scene/scheduleSceneUpdate.js';
12
- import { instanceAreaGeometry } from '../geometry/instanceAreaGeometry.js';
13
12
 
14
13
  export function attachAreaMesh(context) {
15
14
  const { backend: layer, area } = context;
@@ -18,15 +17,15 @@ export function attachAreaMesh(context) {
18
17
  return;
19
18
  }
20
19
  const device = rendererByLayer.get(layer).device;
21
- const data = context.preparedGeometry || instanceAreaGeometry(context);
20
+ const data = context.preparedGeometry;
22
21
  const attributes = /* alloc */ {
23
- position: /* alloc */ { size: 3, data: data.positions instanceof Float32Array ? data.positions : /* alloc */ new Float32Array(data.positions) },
24
- normal: /* alloc */ { size: 3, data: data.normals instanceof Float32Array ? data.normals : /* alloc */ new Float32Array(data.normals) },
25
- color: /* alloc */ { size: 3, data: data.colors instanceof Float32Array ? data.colors : /* alloc */ new Float32Array(data.colors) },
22
+ position: /* alloc */ { size: 3, data: data.positions },
23
+ normal: /* alloc */ { size: 3, data: data.normals },
24
+ color: /* alloc */ { size: 3, data: data.colors },
26
25
  };
27
26
  if (data.instanceOffsets) attributes.instanceOffset = /* alloc */ { size: 4, data: data.instanceOffsets };
28
27
  if (layer.options.nightLight) attributes.uv = /* alloc */ {
29
- size: 2, data: context.uvs instanceof Float32Array ? context.uvs : /* alloc */ new Float32Array(context.uvs),
28
+ size: 2, data: data.uvs,
30
29
  };
31
30
  let name, attribute;
32
31
  for (name in attributes) {
@@ -23,14 +23,13 @@ export async function buildArea(layer, area, map) {
23
23
  if (geojsonByLayer.get(layer) && typeof layer.options.style !== 'function') {
24
24
  throw /* alloc */ new Error('style must be a function');
25
25
  }
26
- const context = sourceAreaContext(layer, area, map);
27
- // ponytail: feature-count cutoff avoids startup overhead; count vertices if giant single polygons matter.
28
- if (layer.options.worker !== false && typeof Worker !== 'undefined' && data.features.length >= 64) {
29
- context.jobs = /* alloc */ [];
26
+ if (layer.options.worker === false) {
27
+ throw /* alloc */ new Error('worker: false is no longer supported; GeoJSON geometry requires Web Workers');
30
28
  }
29
+ const context = sourceAreaContext(layer, area, map);
31
30
  await buildAreaFeatures(context, area, data.features);
32
31
  if (area.request.signal.aborted) return;
33
- if (context.jobs) await buildAreaInWorker(context, area.request.signal);
32
+ await buildAreaInWorker(context, area.request.signal);
34
33
  if (area.request.signal.aborted) return;
35
34
  attachAreaMesh(context);
36
35
  } catch (error) {
@@ -1,5 +1,3 @@
1
- import { buildAreaPoint } from './buildAreaPoint.js';
2
- import { buildAreaPolygon } from '../geometry/buildExtrudedPolygon.js';
3
1
  import { parseColor } from '../colors/parseColor.js';
4
2
  import { featureAnchor } from './featureAnchor.js';
5
3
  import { extrusionStyle } from './extrusionStyle.js';
@@ -10,7 +8,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
13
  if (!matchesAreaTile(map, coords, lon, lat)) return;
16
14
  const style = extrusionStyle(layer, feature);
@@ -18,25 +16,11 @@ export function buildAreaFeature(context, feature) {
18
16
  context.skipped++;
19
17
  return;
20
18
  }
21
- const { top, bottom = 0, color = 0xd9b38c } = style;
19
+ const { color = 0xd9b38c } = style;
22
20
  const baseColor = parseColor(color);
23
- if (context.jobs) {
24
- prepareAreaGeometryJob(context, feature, lon, lat, style, baseColor);
25
- context.featureFaces.push(/* alloc */ {
26
- id: feature.id ?? feature.properties?.objectid ?? JSON.stringify(geometry),
27
- properties: feature.properties, baseColor,
28
- });
29
- return;
30
- }
31
- const vertexStart = context.positions.length / 3;
32
- if (isTree) buildAreaPoint(context, feature, lon, lat, style, baseColor);
33
- let polygon;
34
- if (geometry.type === 'Polygon') buildAreaPolygon(context, geometry.coordinates, top, bottom, baseColor);
35
- else if (geometry.type === 'MultiPolygon') for (polygon of geometry.coordinates) buildAreaPolygon(context, polygon, top, bottom, baseColor);
36
- const vertexEnd = context.positions.length / 3;
21
+ prepareAreaGeometryJob(context, feature, lon, lat, style, baseColor);
37
22
  context.featureFaces.push(/* alloc */ {
38
23
  id: feature.id ?? feature.properties?.objectid ?? JSON.stringify(geometry),
39
24
  properties: feature.properties, baseColor,
40
- faceStart: vertexStart / 3, faceEnd: vertexEnd / 3, vertexStart, vertexEnd,
41
25
  });
42
26
  }
@@ -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,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
+ }