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
@@ -19,6 +19,7 @@ export const meshPipeline = {
19
19
  cullMode: null,
20
20
  frontFace: null
21
21
  },
22
+ multisample: { count: 4 },
22
23
  depthStencil: {
23
24
  format: 'depth24plus',
24
25
  depthWriteEnabled: null,
@@ -0,0 +1 @@
1
+ export const mvtTextDecoder = new TextDecoder('utf-8', { fatal: true });
@@ -0,0 +1 @@
1
+ export const nativeScalableStyleKeys = new Set(['color', 'opacity', 'weight', 'fillColor', 'fillOpacity']);
@@ -1,6 +1,7 @@
1
1
  export const scenePass = {
2
2
  colorAttachments: [{
3
3
  view: null,
4
+ resolveTarget: null,
4
5
  clearValue: {
5
6
  r: 0,
6
7
  g: 0,
@@ -0,0 +1,8 @@
1
+ export const vectorStyleNamedColors = {
2
+ black: [0, 0, 0, 1],
3
+ white: [255, 255, 255, 1],
4
+ gray: [128, 128, 128, 1],
5
+ blue: [0, 0, 255, 1],
6
+ red: [255, 0, 0, 1],
7
+ green: [0, 128, 0, 1]
8
+ };
@@ -0,0 +1 @@
1
+ export const vectorTileEvents = 'move zoom rotate pitch resize viewreset';
@@ -0,0 +1 @@
1
+ export const workerCogSource = { key: null, archive: null };
@@ -1,5 +1,5 @@
1
- import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
2
-
1
+ import { sizeByLayer } from '../weakmaps/sizeByLayer.js';
2
+
3
3
  import { onMapChange } from '../scene/onMapChange.js';
4
4
  import { startZoom } from '../animations/startZoom.js';
5
5
  import { onZoomAnim } from '../animations/onZoomAnim.js';
@@ -8,17 +8,10 @@ import { endZoom } from '../animations/endZoom.js';
8
8
  export function mountRenderer(layer, map, canvas) {
9
9
  sizeByLayer.set(layer, null);
10
10
  canvas.className = 'leaflet-3d';
11
- canvas.style.cssText = 'position:absolute;top:0;left:0;pointer-events:none';
11
+ canvas.style.cssText = 'position:absolute;top:0;left:0;z-index:1;pointer-events:none';
12
12
  canvas.setAttribute('role', 'img');
13
13
  canvas.setAttribute('aria-label', layer.options.ariaLabel ?? '3D scene');
14
- let pane = map.getPane('webgpuPane');
15
- if (!pane) {
16
- pane = map.createPane('webgpuPane', map.getContainer());
17
- // The pitch sky uses 0 and may be inserted after this pane.
18
- pane.style.zIndex = 1;
19
- pane.style.pointerEvents = 'none';
20
- }
21
- pane.append(canvas);
14
+ map.getPane('mapPane').before(canvas);
22
15
  map.on('move zoom rotate pitch resize viewreset layeradd layerremove', onMapChange, layer);
23
16
  map.on('zoomstart', startZoom, layer);
24
17
  map.on('zoomanim', onZoomAnim, layer);
@@ -2,6 +2,7 @@ export async function releaseRenderer(renderer, layer) {
2
2
  try {
3
3
  await renderer.device.queue.onSubmittedWorkDone();
4
4
  renderer.depthTexture?.destroy();
5
+ renderer.colorTexture?.destroy();
5
6
  renderer.roofFallbackTexture?.texture?.destroy();
6
7
  renderer.uniformBuffer?.destroy();
7
8
  renderer.sunlight?.texture?.destroy();
package/src/index.js CHANGED
@@ -4,21 +4,16 @@ import { layerCallInitHooks as sharedLayerCallInitHooks } from './globals/layerC
4
4
  import { removeLayer as sharedRemoveLayer } from './globals/removeLayer.js';
5
5
 
6
6
  import './camera/mapCamera.js';
7
- import { init3D } from './scene/init3D.js';
8
- import { initNativeGPU } from './native/initNativeGPU.js';
9
- import { initRaster } from './raster/initRaster.js';
10
- import { setGeoJSONData } from './sources/setGeoJSONData.js';
11
- import { initTerrain } from './terrain/initTerrain.js';
12
7
  import './sunlight/initSunlight.js';
13
- import { initTraffic } from './traffic/initTraffic.js';
14
8
  import './walk/initWalk.js';
15
9
 
16
- import { initializeNativeLayer } from './core/initializeNativeLayer.js';
17
10
  import { layerLayerAdd } from './scene/addRegisteredLayer.js';
18
11
  import { layerInitialize } from './scene/layerInitialize.js';
19
12
  import { removeLayer } from './core/removeLayer.js';
20
13
  import { getPitch } from './camera/getPitch.js';
21
14
  import { getBearing } from './camera/getBearing.js';
15
+ import { setPitch } from './camera/setPitch.js';
16
+ import { setBearing } from './camera/setBearing.js';
22
17
  import { setRotation } from './core/setRotation.js';
23
18
  import { layerCallInitHooks } from './core/layerCallInitHooks.js';
24
19
 
@@ -39,19 +34,18 @@ import { layerCallInitHooks } from './core/layerCallInitHooks.js';
39
34
  * Operations receive the layer explicitly, without subclasses or prototype replacement.
40
35
  * Dataset-specific code and data (routes, timetables, API loaders) belong to the application, e.g. misc/.
41
36
  *
42
- * When `type` is omitted, inline FeatureCollections use 'geojson'; *.pmtiles URLs use
43
- * 'pmtiles', *.tif/*.tiff URLs use 'cog', and other sources use '3d'.
37
+ * When `type` is omitted, *.pmtiles and *.tif/*.tiff URLs use 'raster'; other sources use 'vector'.
44
38
  */
45
39
 
46
40
  layerProto.value = Object.defineProperties({}, Object.getOwnPropertyDescriptors(L.Layer.prototype));
47
41
  sharedLayerCallInitHooks.value = L.Layer.prototype.callInitHooks;
48
42
 
49
43
  /**
50
- * The '3d' layer type: native WebGPU scene synchronized with the map camera.
44
+ * The 'vector' layer type: native WebGPU scene synchronized with the map camera.
51
45
  * Layers on one map share a canvas, scene and camera; each has its own root transform.
52
46
  *
53
47
  * @typedef {Object} Layer3DOptions Layer options; pane and attribution remain standard L.Layer options.
54
- * @property {string} [type] '3d', 'geojson', 'pmtiles', 'cog', 'terrain' or 'traffic'.
48
+ * @property {'vector'|'raster'|'terrain'|'traffic'} [type]
55
49
  * @property {number[]} [center] Local origin [lat,lng]; defaults to the first map center.
56
50
  * @property {number} [terrainOffset=0] Vertical offset in metres when terrain is enabled.
57
51
  * @property {boolean} [terrainConform=false] Fit lower model geometry to local terrain elevation.
@@ -108,5 +102,5 @@ L.Layer.include({
108
102
  });
109
103
 
110
104
  sharedRemoveLayer.value = L.Map.prototype.removeLayer;
111
- L.Map.include({ removeLayer, getPitch, getBearing });
105
+ L.Map.include({ removeLayer, getPitch, getBearing, setPitch, setBearing });
112
106
  L.Marker.include({ setRotation });
@@ -13,5 +13,6 @@ export function createProgramUniforms(material) {
13
13
  if (material.emissiveTexture) uniforms.emissiveTexture = /* alloc */ { value: material.emissiveTexture };
14
14
  if (material.occlusionTexture) uniforms.occlusionTexture = /* alloc */ { value: material.occlusionTexture };
15
15
  if (material.roofTexture || material.wallTexture) uniforms.roofTexture = /* alloc */ { value: null };
16
+ if (material.nativeStroke) uniforms.strokeScale = /* alloc */ { value: 1 };
16
17
  return uniforms;
17
18
  }
@@ -3,14 +3,14 @@ import { modelByLayer } from '../weakmaps/modelByLayer.js';
3
3
  import { modelUrlByLayer } from '../weakmaps/modelUrlByLayer.js';
4
4
  import { rootByLayer } from '../weakmaps/rootByLayer.js';
5
5
  import { terrain3DByMap } from '../weakmaps/terrain3DByMap.js';
6
+ import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
6
7
 
7
8
 
8
9
 
9
- import { decodeModel } from './decodeModel.js';
10
+ import { runSourceWorker } from '../workers/runSourceWorker.js';
10
11
  import { setParent } from '../scene/setParent.js';
11
12
  import { emptyNode } from '../scene/createSceneNode.js';
12
13
  import { conformModelToTerrain } from '../geometry/conformModelToTerrain.js';
13
- import { loadModelResources } from './loadModelResources.js';
14
14
  import { createModelContext } from './createModelContext.js';
15
15
  import { buildModelNodes } from './buildModelNodes.js';
16
16
  import { applyModelTransform } from './applyModelTransform.js';
@@ -22,14 +22,10 @@ import { applyModelTransform } from './applyModelTransform.js';
22
22
  export async function loadModel(layer) {
23
23
  await addedByLayer.get(layer).promise;
24
24
  const url = /* alloc */ new URL(modelUrlByLayer.get(layer), document.baseURI).href;
25
- const response = await fetch(url);
26
- if (!response.ok) {
27
- throw /* alloc */ new Error(`Unable to load model: HTTP ${response.status}`);
28
- }
29
- const data = await response.arrayBuffer();
30
- const description = decodeModel(data);
31
- const directory = /* alloc */ new URL('.', url).href;
32
- const images = await loadModelResources(layer, description, directory);
25
+ const { description, images } = await runSourceWorker(layer._map, layer.options.workerUrl,
26
+ /* alloc */ { type: 'model', url });
27
+ await addedByLayer.get(layer).promise;
28
+ await cameraViewByMap.get(layer._map);
33
29
  const context = createModelContext(layer, description, images);
34
30
  const scene = description.scenes?.[description.scene || 0];
35
31
  if (!scene) throw /* alloc */ new Error('Missing glTF scene');
@@ -1,20 +1,14 @@
1
- import { addedByLayer } from '../weakmaps/addedByLayer.js';
2
- import { cameraViewByMap } from '../weakmaps/cameraViewByMap.js';
3
-
4
1
  import { geometryEmpty } from '../globals/geometryEmpty.js';
5
2
  import { loadBuffer } from './loadBuffer.js';
6
3
  import { loadImage } from '../textures/loadModelImage.js';
7
4
 
8
- export async function loadModelResources(layer, description, directory) {
5
+ export async function loadModelResources(description, directory) {
9
6
  const bufferRequests = /* alloc */ [];
10
7
  let buffer;
11
8
  for (buffer of description.buffers || geometryEmpty) bufferRequests.push(loadBuffer(buffer, directory));
12
9
  await Promise.all(bufferRequests);
13
- await addedByLayer.get(layer).promise;
14
10
  const imageRequests = /* alloc */ [];
15
11
  let image;
16
12
  for (image of description.images || geometryEmpty) imageRequests.push(loadImage(description, directory, image));
17
- const images = await Promise.all(imageRequests);
18
- await cameraViewByMap.get(layer._map);
19
- return images;
13
+ return Promise.all(imageRequests);
20
14
  }
@@ -4,8 +4,6 @@ import { geometryEmpty } from '../globals/geometryEmpty.js';
4
4
  import { emptyNode } from '../scene/createSceneNode.js';
5
5
  import { nodeMatrix } from '../transforms/modelNodeMatrix.js';
6
6
  import { setParent } from '../scene/setParent.js';
7
- import { readModelAttributes } from './readModelAttributes.js';
8
- import { readModelIndices } from './readModelIndices.js';
9
7
  import { createModelGeometry } from '../geometry/createModelGeometry.js';
10
8
 
11
9
  export function modelNode(context, index) {
@@ -20,13 +18,11 @@ export function modelNode(context, index) {
20
18
  name: spec.name
21
19
  };
22
20
  group.matrix = nodeMatrix(spec);
23
- let primitive, attributeData, attributes, vertexCount, built, mesh, child;
21
+ let primitive, attributes, built, mesh, child;
24
22
  if (spec.mesh !== undefined) {
25
23
  for (primitive of description.meshes[spec.mesh].primitives) {
26
- attributeData = readModelAttributes(description, primitive);
27
- attributes = attributeData.attributes;
28
- vertexCount = attributeData.vertexCount;
29
- readModelIndices(description, primitive, attributes, vertexCount);
24
+ // Node instances own their CPU data and GPU buffers, even when they share a glTF mesh.
25
+ attributes = structuredClone(primitive.preparedAttributes);
30
26
  built = createModelGeometry(context, primitive, attributes);
31
27
  mesh = /* alloc */ {
32
28
  ...emptyNode(),
@@ -0,0 +1,19 @@
1
+ import { decodeModel } from './decodeModel.js';
2
+ import { loadModelResources } from './loadModelResources.js';
3
+ import { prepareModelGeometry } from './prepareModelGeometry.js';
4
+
5
+ export async function prepareModel(url) {
6
+ const response = await fetch(url);
7
+ if (!response.ok) throw /* alloc */ new Error(`Unable to load model: HTTP ${response.status}`);
8
+ const description = decodeModel(await response.arrayBuffer());
9
+ const scene = description.scenes?.[description.scene || 0];
10
+ if (!scene) throw /* alloc */ new Error('Missing glTF scene');
11
+ const images = await loadModelResources(description, /* alloc */ new URL('.', url).href);
12
+ const transfers = prepareModelGeometry(description, scene);
13
+ let image;
14
+ for (image of images) transfers.push(image);
15
+ delete description.buffers;
16
+ delete description.bufferViews;
17
+ delete description.accessors;
18
+ return /* alloc */ { description, images, transfers };
19
+ }
@@ -0,0 +1,25 @@
1
+ import { geometryEmpty } from '../globals/geometryEmpty.js';
2
+ import { prepareModelPrimitive } from './prepareModelPrimitive.js';
3
+
4
+ export function prepareModelGeometry(description, scene) {
5
+ const pending = scene.nodes.slice(), visited = /* alloc */ new Set();
6
+ const meshes = /* alloc */ new Set(), transfers = /* alloc */ new Set();
7
+ let index, spec, primitive, attribute, child;
8
+ while (pending.length) {
9
+ index = pending.pop();
10
+ if (visited.has(index)) continue;
11
+ visited.add(index);
12
+ spec = description.nodes[index];
13
+ if (!spec) throw /* alloc */ new Error('Invalid glTF node');
14
+ if (spec.mesh !== undefined) meshes.add(spec.mesh);
15
+ for (child of spec.children || geometryEmpty) pending.push(child);
16
+ }
17
+ for (index of meshes) {
18
+ for (primitive of description.meshes[index].primitives) {
19
+ for (attribute of Object.values(prepareModelPrimitive(description, primitive))) {
20
+ transfers.add(attribute.data.buffer);
21
+ }
22
+ }
23
+ }
24
+ return /* alloc */ [...transfers];
25
+ }
@@ -0,0 +1,17 @@
1
+ import { readModelAttributes } from './readModelAttributes.js';
2
+ import { readModelIndices } from './readModelIndices.js';
3
+ import { vertexNormals } from '../geometry/vertexNormals.js';
4
+
5
+ export function prepareModelPrimitive(description, primitive) {
6
+ const { attributes, vertexCount } = readModelAttributes(description, primitive);
7
+ readModelIndices(description, primitive, attributes, vertexCount);
8
+ if (!attributes.normal) {
9
+ attributes.normal = /* alloc */ { size: 3,
10
+ data: vertexNormals(attributes.position.data, attributes.index?.data) };
11
+ }
12
+ if (attributes.index?.data instanceof Uint8Array) {
13
+ attributes.index.data = Uint16Array.from(attributes.index.data);
14
+ }
15
+ primitive.preparedAttributes = attributes;
16
+ return attributes;
17
+ }
@@ -0,0 +1,17 @@
1
+ import { mvtEdgeX } from './mvtEdgeX.js';
2
+
3
+ export function addMvtCrossings(edges, levels) {
4
+ let i = 0, j, a, b, top, bottom, start, end;
5
+ for (; i < edges.length; i++) {
6
+ a = edges[i];
7
+ for (j = i + 1; j < edges.length; j++) {
8
+ b = edges[j];
9
+ top = Math.max(a[0][1], b[0][1]);
10
+ bottom = Math.min(a[1][1], b[1][1]);
11
+ if (top >= bottom) continue;
12
+ start = mvtEdgeX(a, top) - mvtEdgeX(b, top);
13
+ end = mvtEdgeX(a, bottom) - mvtEdgeX(b, bottom);
14
+ if (start * end < 0) levels.add(top + (bottom - top) * start / (start - end));
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,31 @@
1
+ import { mvtEdgeX } from './mvtEdgeX.js';
2
+ import { sortMvtActiveEdges } from './sortMvtActiveEdges.js';
3
+
4
+ export function appendMvtBandTriangles(edges, top, bottom, triangles) {
5
+ const mid = (top + bottom) / 2, active = /* alloc */ [];
6
+ let edge, i = 0, leftTop, leftBottom, rightTop, rightBottom;
7
+ for (edge of edges) {
8
+ if (edge[0][1] < mid && edge[1][1] > mid) {
9
+ active.push(/* alloc */ { edge, x: mvtEdgeX(edge, mid) });
10
+ }
11
+ }
12
+ sortMvtActiveEdges(active);
13
+ if (active.length % 2) throw /* alloc */ new Error('Unbalanced MVT polygon edges');
14
+ for (; i < active.length; i += 2) {
15
+ leftTop = mvtEdgeX(active[i].edge, top);
16
+ leftBottom = mvtEdgeX(active[i].edge, bottom);
17
+ rightTop = mvtEdgeX(active[i + 1].edge, top);
18
+ rightBottom = mvtEdgeX(active[i + 1].edge, bottom);
19
+ if (rightTop < leftTop - 1e-8 || rightBottom < leftBottom - 1e-8) {
20
+ throw /* alloc */ new Error('Crossing MVT polygon edges');
21
+ }
22
+ if ((rightTop - leftTop) * (bottom - top) > 1e-6) {
23
+ triangles.push(/* alloc */ [/* alloc */ [leftTop, top], /* alloc */ [rightTop, top],
24
+ /* alloc */ [leftBottom, bottom]]);
25
+ }
26
+ if ((rightBottom - leftBottom) * (bottom - top) > 1e-6) {
27
+ triangles.push(/* alloc */ [/* alloc */ [rightTop, top], /* alloc */ [rightBottom, bottom],
28
+ /* alloc */ [leftBottom, bottom]]);
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,11 @@
1
+ export function appendMvtCoordinates(commands, state, count) {
2
+ let i = 0, dx, dy;
3
+ for (; i < count; i++) {
4
+ dx = commands[state.index++];
5
+ dy = commands[state.index++];
6
+ if (dx > 0xffffffff || dy > 0xffffffff) throw /* alloc */ new Error('Invalid MVT coordinate');
7
+ state.x += dx % 2 ? -(dx + 1) / 2 : dx / 2;
8
+ state.y += dy % 2 ? -(dy + 1) / 2 : dy / 2;
9
+ state.path.push(/* alloc */ [state.x, state.y]);
10
+ }
11
+ }
@@ -0,0 +1,19 @@
1
+ import { tessellateVectorRings } from './tessellateVectorRings.js';
2
+ import { triangulate } from '../triangulation/triangulate.js';
3
+ import { isMvtFallbackError } from './isMvtFallbackError.js';
4
+
5
+ export function appendMvtPolygonTriangles(rings, paths, vertices, triangles) {
6
+ let indices, index, triangle, points, i = 0;
7
+ try {
8
+ indices = triangulate(paths[0], paths.slice(1));
9
+ for (triangle of indices) {
10
+ points = /* alloc */ [];
11
+ for (index of triangle) points.push(/* alloc */ [vertices[index].x, vertices[index].y]);
12
+ triangles.push(points);
13
+ }
14
+ } catch (error) {
15
+ if (!isMvtFallbackError(error)) throw error;
16
+ indices = tessellateVectorRings(rings);
17
+ for (; i < indices.length; i++) triangles.push(indices[i]);
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ import { finishMvtPath } from './finishMvtPath.js';
2
+
3
+ export function beginMvtPath(state, paths, type, count) {
4
+ finishMvtPath(state.path, type, state.closed);
5
+ if (type !== 1 && count !== 1) throw /* alloc */ new Error('Invalid MVT MoveTo');
6
+ state.path = /* alloc */ [];
7
+ paths.push(state.path);
8
+ state.closed = false;
9
+ }
@@ -0,0 +1,7 @@
1
+ export function closeMvtPath(state, type, count) {
2
+ if (type !== 3 || count !== 1 || !state.path || state.closed || state.path.length < 3) {
3
+ throw /* alloc */ new Error('Invalid MVT ClosePath');
4
+ }
5
+ state.path.push(/* alloc */ [...state.path[0]]);
6
+ state.closed = true;
7
+ }
@@ -0,0 +1,19 @@
1
+ import { finiteMvtCoordinate } from './finiteMvtCoordinate.js';
2
+
3
+ export function collectMvtEdges(rings, edges, levels) {
4
+ let ring, i, a, b;
5
+ for (ring of rings) {
6
+ if (ring.length < 4 || ring[0][0] !== ring.at(-1)[0] || ring[0][1] !== ring.at(-1)[1]) {
7
+ throw /* alloc */ new Error('MVT tessellation requires closed rings');
8
+ }
9
+ for (i = 1; i < ring.length; i++) {
10
+ a = ring[i - 1];
11
+ b = ring[i];
12
+ if (!finiteMvtCoordinate(a) || !finiteMvtCoordinate(b)) {
13
+ throw /* alloc */ new Error('Invalid MVT ring coordinate');
14
+ }
15
+ levels.add(a[1]);
16
+ if (a[1] !== b[1]) edges.push(/* alloc */ [a[1] < b[1] ? a : b, a[1] < b[1] ? b : a]);
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,7 @@
1
+ export function createMvtReader(bytes) {
2
+ return /* alloc */ {
3
+ bytes,
4
+ view: /* alloc */ new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
5
+ pos: 0,
6
+ };
7
+ }
@@ -0,0 +1,32 @@
1
+ import { createMvtReader } from './createMvtReader.js';
2
+ import { readMvtField } from './readMvtField.js';
3
+ import { readMvtLayer } from './readMvtLayer.js';
4
+ import { readMvtMessage } from './readMvtMessage.js';
5
+ import { skipMvtField } from './skipMvtField.js';
6
+
7
+ /**
8
+ * Decode an uncompressed MVT ArrayBuffer/Uint8Array into tile-local layers.
9
+ * Feature types: 0 unknown, 1 points, 2 lines, 3 polygon rings (including holes).
10
+ * Integers outside JavaScript's safe range are returned as decimal strings.
11
+ */
12
+ export function decodeVectorTile(buffer) {
13
+ if (!(buffer instanceof ArrayBuffer) && !(buffer instanceof Uint8Array)) {
14
+ throw /* alloc */ new TypeError('MVT input must be an ArrayBuffer or Uint8Array');
15
+ }
16
+ const bytes = buffer instanceof Uint8Array ? buffer : /* alloc */ new Uint8Array(buffer);
17
+ const reader = createMvtReader(bytes);
18
+ const layers = /* alloc */ [], names = /* alloc */ new Set();
19
+ let field, wire, layer;
20
+ while (reader.pos < reader.bytes.length) {
21
+ [field, wire] = readMvtField(reader);
22
+ if (field !== 3) {
23
+ skipMvtField(reader, wire);
24
+ continue;
25
+ }
26
+ layer = readMvtLayer(readMvtMessage(reader, wire));
27
+ if (names.has(layer.name)) throw /* alloc */ new Error('Duplicate MVT layer name');
28
+ names.add(layer.name);
29
+ layers.push(layer);
30
+ }
31
+ return layers;
32
+ }
@@ -0,0 +1,3 @@
1
+ export function expectMvtWire(wire, expected) {
2
+ if (wire !== expected) throw /* alloc */ new Error('Invalid MVT wire type');
3
+ }
@@ -0,0 +1,5 @@
1
+ export function finishMvtPath(path, type, closed) {
2
+ if (path && (type === 2 && path.length < 2 || type === 3 && !closed)) {
3
+ throw /* alloc */ new Error('Incomplete MVT geometry');
4
+ }
5
+ }
@@ -0,0 +1,7 @@
1
+ export function finiteMvtCoordinate(point) {
2
+ let i = 0;
3
+ for (; i < point.length; i++) {
4
+ if (!Number.isFinite(point[i])) return false;
5
+ }
6
+ return true;
7
+ }
@@ -0,0 +1,25 @@
1
+ import { finiteMvtCoordinate } from './finiteMvtCoordinate.js';
2
+
3
+ export function groupMvtPolygons(rings) {
4
+ const polygons = /* alloc */ [];
5
+ let polygon, exteriorSign, ring, area, i;
6
+ for (ring of rings) {
7
+ if (ring.length < 4 || ring[0][0] !== ring.at(-1)[0] || ring[0][1] !== ring.at(-1)[1]) {
8
+ throw /* alloc */ new Error('MVT tessellation requires closed rings');
9
+ }
10
+ area = 0;
11
+ for (i = 1; i < ring.length; i++) {
12
+ if (!finiteMvtCoordinate(ring[i]) || !finiteMvtCoordinate(ring[i - 1])) {
13
+ throw /* alloc */ new Error('Invalid MVT ring coordinate');
14
+ }
15
+ area += ring[i - 1][0] * ring[i][1] - ring[i][0] * ring[i - 1][1];
16
+ }
17
+ if (!polygon || area && Math.sign(area) === exteriorSign) {
18
+ polygon = /* alloc */ [];
19
+ polygons.push(polygon);
20
+ exteriorSign = Math.sign(area);
21
+ }
22
+ polygon.push(ring);
23
+ }
24
+ return polygons;
25
+ }
@@ -0,0 +1,6 @@
1
+ export function isMvtFallbackError(error) {
2
+ return error.message === 'Polygon triangulation area mismatch' ||
3
+ error.message === 'Degenerate polygon ring' ||
4
+ error.message === 'Unable to triangulate polygon: invalid or self-intersecting rings' ||
5
+ error.message === 'Unable to connect polygon hole';
6
+ }
@@ -0,0 +1,9 @@
1
+ export function mergeMvtActiveEdges(active, sorted, left, mid, right) {
2
+ let i = left, j = mid, k = left;
3
+ while (i < mid && j < right) {
4
+ if (active[j].x < active[i].x) sorted[k++] = active[j++];
5
+ else sorted[k++] = active[i++];
6
+ }
7
+ while (i < mid) sorted[k++] = active[i++];
8
+ while (j < right) sorted[k++] = active[j++];
9
+ }
@@ -0,0 +1,4 @@
1
+ export function mvtEdgeX(edge, y) {
2
+ return edge[0][0] + (y - edge[0][1]) *
3
+ (edge[1][0] - edge[0][0]) / (edge[1][1] - edge[0][1]);
4
+ }
@@ -0,0 +1,8 @@
1
+ export function mvtPathsVertices(paths) {
2
+ const vertices = /* alloc */ [];
3
+ let path, point;
4
+ for (path of paths) {
5
+ for (point of path) vertices.push(point);
6
+ }
7
+ return vertices;
8
+ }
@@ -0,0 +1,12 @@
1
+ export function mvtPolygonPaths(rings) {
2
+ const paths = /* alloc */ [];
3
+ let ring, i, path;
4
+ for (ring of rings) {
5
+ path = /* alloc */ [];
6
+ for (i = 0; i < ring.length - 1; i++) {
7
+ path.push(/* alloc */ { x: ring[i][0], y: ring[i][1] });
8
+ }
9
+ paths.push(path);
10
+ }
11
+ return paths;
12
+ }
@@ -0,0 +1,4 @@
1
+ export function numericMvtValue(value) {
2
+ return value >= BigInt(Number.MIN_SAFE_INTEGER) && value <= BigInt(Number.MAX_SAFE_INTEGER)
3
+ ? Number(value) : value.toString();
4
+ }
@@ -0,0 +1,34 @@
1
+ import { expectMvtWire } from './expectMvtWire.js';
2
+ import { numericMvtValue } from './numericMvtValue.js';
3
+ import { readMvtField } from './readMvtField.js';
4
+ import { readMvtGeometry } from './readMvtGeometry.js';
5
+ import { readMvtInteger } from './readMvtInteger.js';
6
+ import { readMvtNumber } from './readMvtNumber.js';
7
+ import { readMvtNumbers } from './readMvtNumbers.js';
8
+ import { skipMvtField } from './skipMvtField.js';
9
+
10
+ export function readMvtFeature(reader, keys, values) {
11
+ let id, type = 0, field, wire, i = 0;
12
+ const tags = /* alloc */ [], commands = /* alloc */ [];
13
+ while (reader.pos < reader.bytes.length) {
14
+ [field, wire] = readMvtField(reader);
15
+ if (field === 1) {
16
+ expectMvtWire(wire, 0);
17
+ id = numericMvtValue(readMvtInteger(reader));
18
+ } else if (field === 2) readMvtNumbers(reader, wire, tags);
19
+ else if (field === 3) {
20
+ expectMvtWire(wire, 0);
21
+ type = readMvtNumber(reader);
22
+ } else if (field === 4) readMvtNumbers(reader, wire, commands);
23
+ else skipMvtField(reader, wire);
24
+ }
25
+ if (tags.length % 2 || type > 3) throw /* alloc */ new Error('Invalid MVT feature');
26
+ const properties = Object.create(null);
27
+ for (; i < tags.length; i += 2) {
28
+ if (tags[i] >= keys.length || tags[i + 1] >= values.length) {
29
+ throw /* alloc */ new Error('Invalid MVT property index');
30
+ }
31
+ properties[keys[tags[i]]] = values[tags[i + 1]];
32
+ }
33
+ return /* alloc */ { id, type, properties, geometry: type ? readMvtGeometry(commands, type) : /* alloc */ [] };
34
+ }
@@ -0,0 +1,8 @@
1
+ import { readMvtNumber } from './readMvtNumber.js';
2
+
3
+ export function readMvtField(reader) {
4
+ const tag = readMvtNumber(reader);
5
+ const field = Math.floor(tag / 8), wire = tag % 8;
6
+ if (!field || field > 536870911) throw /* alloc */ new Error('Invalid MVT field number');
7
+ return /* alloc */ [field, wire];
8
+ }
@@ -0,0 +1,29 @@
1
+ import { finishMvtPath } from './finishMvtPath.js';
2
+ import { appendMvtCoordinates } from './appendMvtCoordinates.js';
3
+ import { beginMvtPath } from './beginMvtPath.js';
4
+ import { closeMvtPath } from './closeMvtPath.js';
5
+
6
+ export function readMvtGeometry(commands, type) {
7
+ const paths = /* alloc */ [];
8
+ const state = /* alloc */ { x: 0, y: 0, path: null, closed: false, index: 0 };
9
+ let command, id, count;
10
+ while (state.index < commands.length) {
11
+ command = commands[state.index++];
12
+ id = command % 8;
13
+ count = Math.floor(command / 8);
14
+ if (!count || command > 0xffffffff) throw /* alloc */ new Error('Invalid MVT geometry command');
15
+ if (id === 7) {
16
+ closeMvtPath(state, type, count);
17
+ continue;
18
+ }
19
+ if (id !== 1 && id !== 2 || count > Math.floor((commands.length - state.index) / 2)) {
20
+ throw /* alloc */ new Error('Invalid MVT geometry parameters');
21
+ }
22
+ if (id === 1) beginMvtPath(state, paths, type, count);
23
+ else if (type === 1 || !state.path || state.closed) throw /* alloc */ new Error('Invalid MVT LineTo');
24
+ appendMvtCoordinates(commands, state, count);
25
+ }
26
+ finishMvtPath(state.path, type, state.closed);
27
+ if (!paths.length) throw /* alloc */ new Error('Empty MVT geometry');
28
+ return paths;
29
+ }