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
@@ -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
+ }
@@ -0,0 +1,13 @@
1
+ export function parseHexColor(value) {
2
+ let i = 0, offset = 0;
3
+ if (value.length === 4) {
4
+ value = '#' + value[1] + value[1] + value[2] + value[2] + value[3] + value[3];
5
+ }
6
+ const color = /* alloc */ [];
7
+ for (i = 1; i < 6; i += 2) {
8
+ offset = parseInt(value.slice(i, i + 2), 16);
9
+ color.push(offset);
10
+ }
11
+ color.push(1);
12
+ return color;
13
+ }
@@ -0,0 +1,13 @@
1
+ import { removeTrailingCommas } from './removeTrailingCommas.js';
2
+ import { stripStyleComments } from './stripStyleComments.js';
3
+ import { validateVectorLayers } from './validateVectorLayers.js';
4
+
5
+ export function parseVectorStyle(text) {
6
+ const prefix = /^\s*(?:const|let|var)\s+otm_layers\s*=\s*/.exec(text);
7
+ if (prefix) text = text.slice(prefix[0].length);
8
+ const cleaned = removeTrailingCommas(stripStyleComments(text).trim().replace(/;$/, ''));
9
+ const document = JSON.parse(cleaned);
10
+ const layers = document.layers ?? document;
11
+ validateVectorLayers(layers);
12
+ return layers;
13
+ }
@@ -0,0 +1,6 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function readPaintValue(paint, key, fallback, properties, zoom) {
4
+ if (paint[key] === undefined) return fallback;
5
+ return evaluateStyle(paint[key], properties, zoom);
6
+ }
@@ -0,0 +1,12 @@
1
+ export function removeTrailingCommas(json) {
2
+ let cleaned = '', quoted = false, escaped = false, i = 0, char = '';
3
+ for (i = 0; i < json.length; i++) {
4
+ char = json[i];
5
+ if (!quoted && char === ',' && /^\s*[\]}]/.test(json.slice(i + 1))) continue;
6
+ cleaned += char;
7
+ if (escaped) escaped = false;
8
+ else if (quoted && char === '\\') escaped = true;
9
+ else if (char === '"') quoted = !quoted;
10
+ }
11
+ return cleaned;
12
+ }
@@ -0,0 +1,13 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function scaleDashArray(dash, weight, properties, zoom) {
4
+ if (!dash) return undefined;
5
+ let values = dash, i = 0, result = '';
6
+ if (typeof dash[0] !== 'number') values = evaluateStyle(dash, properties, zoom);
7
+ if (!Array.isArray(values)) throw /* alloc */ new TypeError('Style dash array must be an array');
8
+ for (i = 0; i < values.length; i++) {
9
+ if (i) result += ' ';
10
+ result += values[i] * weight;
11
+ }
12
+ return result;
13
+ }
@@ -0,0 +1,9 @@
1
+ export function skipStyleComment(text, index, marker) {
2
+ if (marker === '/') {
3
+ while (index < text.length && text[index] !== '\n') index++;
4
+ return index;
5
+ }
6
+ const end = text.indexOf('*/', index + 2);
7
+ if (end < 0) throw /* alloc */ new Error('Unterminated style comment');
8
+ return end + 1;
9
+ }
@@ -0,0 +1,21 @@
1
+ import { appendQuotedStyleCharacter } from './appendQuotedStyleCharacter.js';
2
+ import { skipStyleComment } from './skipStyleComment.js';
3
+
4
+ export function stripStyleComments(text) {
5
+ let json = '', i = 0, char = '', next = '', converted = undefined;
6
+ const state = /* alloc */ { quoted: '', escaped: false };
7
+ for (i = 0; i < text.length; i++) {
8
+ char = text[i];
9
+ next = text[i + 1];
10
+ converted = appendQuotedStyleCharacter(char, state);
11
+ if (converted !== undefined) {
12
+ json += converted;
13
+ continue;
14
+ }
15
+ if (char === '/' && (next === '/' || next === '*')) {
16
+ i = skipStyleComment(text, i, next);
17
+ json += next === '/' ? '\n' : ' ';
18
+ } else json += char;
19
+ }
20
+ return json;
21
+ }
@@ -0,0 +1,11 @@
1
+ import { vectorStyleNamedColors } from '../globals/vectorStyleNamedColors.js';
2
+ import { parseFunctionalColor } from './parseFunctionalColor.js';
3
+ import { parseHexColor } from './parseHexColor.js';
4
+
5
+ export function styleColor(value) {
6
+ if (Object.hasOwn(vectorStyleNamedColors, value)) return vectorStyleNamedColors[value];
7
+ if (/^#[0-9a-f]{3}$/i.test(value) || /^#[0-9a-f]{6}$/i.test(value)) {
8
+ return parseHexColor(value);
9
+ }
10
+ return parseFunctionalColor(value);
11
+ }
@@ -0,0 +1,10 @@
1
+ export function validateVectorLayers(layers) {
2
+ let i = 0, layer = null;
3
+ if (!Array.isArray(layers)) throw /* alloc */ new Error('Invalid vector style layers');
4
+ for (i = 0; i < layers.length; i++) {
5
+ layer = layers[i];
6
+ if (!layer || typeof layer.id !== 'string' || typeof layer.type !== 'string') {
7
+ throw /* alloc */ new Error('Invalid vector style layers');
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ import { fillVectorPaint } from './fillVectorPaint.js';
2
+ import { lineVectorPaint } from './lineVectorPaint.js';
3
+
4
+ export function vectorPaint(layer, properties, zoom) {
5
+ const paint = layer.paint || /* alloc */ {};
6
+ if (layer.type === 'fill') return fillVectorPaint(paint, properties, zoom);
7
+ return lineVectorPaint(layer, paint, properties, zoom);
8
+ }
@@ -0,0 +1,7 @@
1
+ import { evaluateStyle } from './evaluateStyle.js';
2
+
3
+ export function visibleStyle(layer, properties, zoom) {
4
+ return zoom >= (layer.minzoom ?? 0) && zoom < (layer.maxzoom ?? Infinity) &&
5
+ layer.layout?.visibility !== 'none' &&
6
+ (!layer.filter || evaluateStyle(layer.filter, properties, zoom, true));
7
+ }
@@ -0,0 +1,22 @@
1
+ import { vectorFeaturePaths } from './vectorFeaturePaths.js';
2
+
3
+ export function appendVectorBatch(job, layer, entry, feature, order, batches, dependencies, paint) {
4
+ const values = /* alloc */ [];
5
+ let key, batch, path, count;
6
+ for (key of dependencies) values.push(feature.properties[key]);
7
+ key = JSON.stringify(/* alloc */ [paint, values]);
8
+ batch = batches.get(key);
9
+ if (!batch) {
10
+ batch = /* alloc */ { kind: entry.type, order, paint, properties: feature.properties, entry,
11
+ paths: /* alloc */ [], coordinates: 0 };
12
+ batches.set(key, batch);
13
+ }
14
+ for (path of vectorFeaturePaths(job, layer, entry, feature)) {
15
+ count = entry.type === 'fill' ? 3 : path.length;
16
+ if (batch.coordinates + count > 6000 && batch.paths.length) {
17
+ job.output.push(/* alloc */ { ...batch, paths: batch.paths });
18
+ batch.paths = /* alloc */ []; batch.coordinates = 0;
19
+ }
20
+ batch.paths.push(path); batch.coordinates += count;
21
+ }
22
+ }
@@ -0,0 +1,17 @@
1
+ import { L } from '../globals/L.js';
2
+ import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
3
+ import { vectorStyleZoom } from './vectorStyleZoom.js';
4
+ import { vectorTilePaint } from './vectorTilePaint.js';
5
+ import { forwardVectorTileError } from './forwardVectorTileError.js';
6
+
7
+ export function attachVectorTileBatch(owner, tile, group, batch) {
8
+ const { pane } = vectorTileOptionsByLayer.get(owner);
9
+ const paint = vectorTilePaint(batch, vectorStyleZoom(owner));
10
+ const options = /* alloc */ { ...paint, pane: `${pane}-${batch.order}`, interactive: false, smoothFactor: 0 };
11
+ const layer = batch.kind === 'fill'
12
+ ? /* alloc */ new L.Polygon(batch.paths, /* alloc */ { ...options, stroke: false, triangulated: true })
13
+ : /* alloc */ new L.Polyline(batch.paths, options);
14
+ layer.on('error', forwardVectorTileError, owner);
15
+ tile.rendered.push(/* alloc */ { layer, kind: batch.kind, entry: batch.entry, properties: batch.properties });
16
+ group.addLayer(layer);
17
+ }
@@ -0,0 +1,15 @@
1
+ import { attachVectorTileBatch } from './attachVectorTileBatch.js';
2
+ import { vectorTilesIdle } from './vectorTilesIdle.js';
3
+ import { yieldTask } from '../utils/yieldTask.js';
4
+
5
+ export async function attachVectorTileBatches(owner, tile, group, batches, session) {
6
+ let batch, start = performance.now();
7
+ for (batch of batches) {
8
+ while (!vectorTilesIdle(owner, session) && owner.session === session &&
9
+ !tile.controller.signal.aborted) await yieldTask(50);
10
+ if (tile.controller.signal.aborted || owner.session !== session) return false;
11
+ attachVectorTileBatch(owner, tile, group, batch);
12
+ if (performance.now() - start > 8) { await yieldTask(); start = performance.now(); }
13
+ }
14
+ return true;
15
+ }
@@ -0,0 +1,3 @@
1
+ export function compareVectorLabelPriority(a, b) {
2
+ return a.priority - b.priority;
3
+ }
@@ -0,0 +1,3 @@
1
+ export function compareVectorTileDistance(a, b) {
2
+ return a.distance - b.distance;
3
+ }
@@ -0,0 +1,28 @@
1
+ import { L } from '../globals/L.js';
2
+ import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
3
+ import { vectorTileSettings } from './vectorTileSettings.js';
4
+ import { loadVectorSprite } from './loadVectorSprite.js';
5
+ import { onVectorTileAdd } from './onVectorTileAdd.js';
6
+ import { onVectorTileRemove } from './onVectorTileRemove.js';
7
+ import { updateVectorTiles } from './updateVectorTiles.js';
8
+ import { updateVectorTilePaint } from './updateVectorTilePaint.js';
9
+ import { updateVectorTileLabels } from './updateVectorTileLabels.js';
10
+ import { pruneVectorTiles } from './pruneVectorTiles.js';
11
+ import { retireVectorTileGroup } from './retireVectorTileGroup.js';
12
+ import { pumpVectorTiles } from './pumpVectorTiles.js';
13
+ import { loadVectorTile } from './loadVectorTile.js';
14
+
15
+ export async function configureVectorTileLayer(layer, options) {
16
+ const settings = await vectorTileSettings(options);
17
+ if (typeof settings.sprite === 'string') settings.spriteSheet = await loadVectorSprite(settings.sprite);
18
+ const { url, tileJSON, style, sourceId, minNativeZoom, maxNativeZoom, maxZoom, ...core } = settings;
19
+ L.Util.setOptions(layer, core);
20
+ settings.pane = `mvt-${L.Util.stamp(layer)}`;
21
+ vectorTileOptionsByLayer.set(layer, settings);
22
+ Object.assign(layer, /* alloc */ {
23
+ onAdd: onVectorTileAdd, onRemove: onVectorTileRemove, update: updateVectorTiles,
24
+ updatePaint: updateVectorTilePaint, updateLabels: updateVectorTileLabels,
25
+ prune: pruneVectorTiles, retire: retireVectorTileGroup, pump: pumpVectorTiles, load: loadVectorTile,
26
+ });
27
+ return layer;
28
+ }
@@ -0,0 +1,5 @@
1
+ import { reportError } from '../scene/reportLayerError.js';
2
+
3
+ export function forwardVectorTileError({ error }) {
4
+ reportError(this, error);
5
+ }
@@ -0,0 +1,5 @@
1
+ export async function loadVectorSprite(url) {
2
+ const response = await fetch(`${url}.json`);
3
+ if (!response.ok) throw /* alloc */ new Error(`Sprite ${url}.json: HTTP ${response.status}`);
4
+ return /* alloc */ { url: `${url}.png`, index: await response.json() };
5
+ }
@@ -0,0 +1,36 @@
1
+ import { L } from '../globals/L.js';
2
+ import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
3
+ import { vectorStyleZoom } from './vectorStyleZoom.js';
4
+ import { attachVectorTileBatches } from './attachVectorTileBatches.js';
5
+
6
+ export async function loadVectorTile(tile) {
7
+ const { coords, controller } = tile, session = this.session;
8
+ const { url, style, sourceId, maxZoom, maxNativeZoom } = vectorTileOptionsByLayer.get(this);
9
+ const count = 2 ** coords.z, x = ((coords.x % count) + count) % count;
10
+ let group;
11
+ try {
12
+ const tileUrl = L.Util.template(url, /* alloc */ { z: coords.z, x, y: coords.y });
13
+ const response = await fetch(tileUrl, /* alloc */ { signal: controller.signal });
14
+ if (!response.ok) throw /* alloc */ new Error(`Tile ${tile.key}: HTTP ${response.status}`);
15
+ const buffer = await response.arrayBuffer();
16
+ if (controller.signal.aborted) return;
17
+ const id = ++this.sequence, prepared = Promise.withResolvers();
18
+ this.waiting.set(id, prepared);
19
+ this.worker.postMessage(/* alloc */ { type: 'vector', id, buffer, coords, style, source: sourceId, maxZoom,
20
+ zoom: vectorStyleZoom(this), mapZoom: coords.z >= maxNativeZoom ? maxZoom : this._map.getZoom() }, /* alloc */ [buffer]);
21
+ const data = await prepared.promise;
22
+ if (controller.signal.aborted || this.session !== session) return;
23
+ group = /* alloc */ new L.LayerGroup().addTo(this._map);
24
+ tile.rendered = /* alloc */ [];
25
+ if (!await attachVectorTileBatches(this, tile, group, data.batches, session)) { group.remove(); return; }
26
+ tile.group = group; tile.labelCandidates = data.labels;
27
+ this.fire('tileload', /* alloc */ { coords, group });
28
+ this.prune();
29
+ this.refresh();
30
+ } catch (error) {
31
+ group?.remove();
32
+ if (!controller.signal.aborted && this.session === session) this.fire('error', /* alloc */ { error });
33
+ } finally {
34
+ if (this.session === session) { this.inflight--; this.pump(); }
35
+ }
36
+ }
@@ -0,0 +1,39 @@
1
+ import { vectorTileOptionsByLayer } from '../weakmaps/vectorTileOptionsByLayer.js';
2
+ import { geometryWorkerUrl } from '../globals/geometryWorkerUrl.js';
3
+ import { vectorTileEvents } from '../globals/vectorTileEvents.js';
4
+ import { evaluateStyle } from '../vector-style/evaluateStyle.js';
5
+ import { vectorStyleZoom } from './vectorStyleZoom.js';
6
+ import { refreshVectorTiles } from './refreshVectorTiles.js';
7
+ import { rotateVectorLabels } from './rotateVectorLabels.js';
8
+ import { onVectorTileMessage } from './onVectorTileMessage.js';
9
+ import { onVectorTileWorkerError } from './onVectorTileWorkerError.js';
10
+ import { createGeometryWorker } from '../workers/createGeometryWorker.js';
11
+ import { vectorWorkerByLayer } from '../weakmaps/vectorWorkerByLayer.js';
12
+
13
+ export function onVectorTileAdd(map) {
14
+ const { style, pane } = vectorTileOptionsByLayer.get(this);
15
+ let index, entry;
16
+ for ([index] of style.entries()) {
17
+ (map.getPane(`${pane}-${index}`) || map.createPane(`${pane}-${index}`)).style.zIndex = 200 + index;
18
+ }
19
+ for (entry of style) {
20
+ if (entry.type !== 'background') continue;
21
+ map.getContainer().style.background = evaluateStyle(entry.paint['background-color'], /* alloc */ {}, vectorStyleZoom(this));
22
+ break;
23
+ }
24
+ this.session = /* alloc */ {};
25
+ this.tiles = /* alloc */ new Map(); this.labels = /* alloc */ new Map(); this.waiting = /* alloc */ new Map();
26
+ this.retiring = /* alloc */ new Set();
27
+ this.inflight = 0; this.sequence = 0;
28
+ this.changedAt = 0; this.paintZoom = null;
29
+ const workerEntry = createGeometryWorker(this.options.workerUrl || geometryWorkerUrl);
30
+ vectorWorkerByLayer.set(this, workerEntry);
31
+ this.worker = workerEntry.worker;
32
+ this.worker.onmessage = onVectorTileMessage.bind(this);
33
+ this.worker.onerror = onVectorTileWorkerError.bind(this);
34
+ this.refresh = refreshVectorTiles.bind(this);
35
+ this.rotateLabels = rotateVectorLabels.bind(this);
36
+ map.on(vectorTileEvents, this.refresh);
37
+ map.on('move rotate pitch', this.rotateLabels);
38
+ this.update();
39
+ }
@@ -0,0 +1,10 @@
1
+ import { revokeVectorWorkerUrl } from './revokeVectorWorkerUrl.js';
2
+
3
+ export function onVectorTileMessage({ data }) {
4
+ revokeVectorWorkerUrl(this);
5
+ const pending = this.waiting.get(data.id);
6
+ if (!pending) return;
7
+ this.waiting.delete(data.id);
8
+ if (data.error) pending.reject(/* alloc */ new Error(data.error));
9
+ else pending.resolve(data);
10
+ }
@@ -0,0 +1,20 @@
1
+ import { vectorTileEvents } from '../globals/vectorTileEvents.js';
2
+ import { vectorWorkerByLayer } from '../weakmaps/vectorWorkerByLayer.js';
3
+ import { revokeVectorWorkerUrl } from './revokeVectorWorkerUrl.js';
4
+
5
+ export function onVectorTileRemove(map) {
6
+ map.off(vectorTileEvents, this.refresh);
7
+ map.off('move rotate pitch', this.rotateLabels);
8
+ clearTimeout(this.timer);
9
+ this.session = null;
10
+ this.worker.terminate();
11
+ revokeVectorWorkerUrl(this);
12
+ vectorWorkerByLayer.delete(this);
13
+ let pending, tile, group, marker;
14
+ for (pending of this.waiting.values()) pending.reject(/* alloc */ new DOMException('Layer removed', 'AbortError'));
15
+ this.waiting.clear();
16
+ for (tile of this.tiles.values()) { tile.controller.abort(); tile.group?.remove(); }
17
+ for (group of this.retiring) group.remove();
18
+ for (marker of this.labels.values()) marker.remove();
19
+ this.tiles.clear(); this.labels.clear(); this.retiring.clear();
20
+ }
@@ -0,0 +1,11 @@
1
+ import { reportError } from '../scene/reportLayerError.js';
2
+ import { revokeVectorWorkerUrl } from './revokeVectorWorkerUrl.js';
3
+
4
+ export function onVectorTileWorkerError(event) {
5
+ revokeVectorWorkerUrl(this);
6
+ const error = /* alloc */ new Error(`Worker MVT: ${event.message}`);
7
+ let pending;
8
+ for (pending of this.waiting.values()) pending.reject(error);
9
+ this.waiting.clear();
10
+ reportError(this, error);
11
+ }
@@ -0,0 +1,12 @@
1
+ import { vectorTilePaint } from './vectorTilePaint.js';
2
+
3
+ export function paintVectorTileBatch(batch, zoom) {
4
+ const paint = vectorTilePaint(batch, zoom), { layer } = batch;
5
+ if (batch.kind === 'line') {
6
+ if (paint.dashArray !== layer.options.dashArray) layer.setStyle(paint);
7
+ else layer.setStyle(/* alloc */ { color: paint.color, opacity: paint.opacity, weight: paint.weight });
8
+ } else if (JSON.stringify(paint.fillColor) !== JSON.stringify(layer.options.fillColor) ||
9
+ paint.fillOpacity !== layer.options.fillOpacity) {
10
+ layer.setStyle(/* alloc */ { fillColor: paint.fillColor, fillOpacity: paint.fillOpacity });
11
+ }
12
+ }