leaflet-city-mapper 0.0.1 → 0.0.3

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 (629) hide show
  1. package/README.md +61 -13
  2. package/cucumber.mjs +4 -0
  3. package/dist/leaflet-city-mapper.js +3 -1
  4. package/dist/leaflet-city-mapper.js.map +4 -4
  5. package/package.json +3 -4
  6. package/src/archives/decodeDirectory.js +32 -0
  7. package/src/archives/decodeHeader.js +19 -0
  8. package/src/archives/decompress.js +5 -0
  9. package/src/archives/getHeader.js +9 -0
  10. package/src/archives/getZxy.js +75 -0
  11. package/src/archives/loadDirectory.js +7 -0
  12. package/src/archives/loadSource.js +17 -0
  13. package/src/archives/read.js +29 -0
  14. package/src/archives/tileId.js +19 -0
  15. package/src/archives/varint.js +15 -0
  16. package/src/camera/angles.js +6 -0
  17. package/src/camera/animationPoint.js +8 -0
  18. package/src/camera/cameraMapReady.js +8 -0
  19. package/src/camera/cancelCameraAnimation.js +11 -0
  20. package/src/camera/cleanupCameraMap.js +11 -0
  21. package/src/camera/constrainCameraToBounds.js +3 -0
  22. package/src/camera/displayPoint.js +3 -0
  23. package/src/camera/fitCameraBounds.js +48 -0
  24. package/src/camera/groundBounds.js +11 -0
  25. package/src/camera/initializeCameraMap.js +25 -0
  26. package/src/camera/mapAnimateCamera.js +17 -0
  27. package/src/camera/mapCamera.js +123 -0
  28. package/src/camera/mapContainerPointToLayerPoint.js +7 -0
  29. package/src/camera/mapGetBearing.js +1 -0
  30. package/src/camera/mapGetBounds.js +14 -0
  31. package/src/camera/mapGetBoundsCenterZoom.js +7 -0
  32. package/src/camera/mapGetBoundsZoom.js +14 -0
  33. package/src/camera/mapGetCenterLayerPoint.js +5 -0
  34. package/src/camera/mapGetPitch.js +1 -0
  35. package/src/camera/mapLayerPointToContainerPoint.js +7 -0
  36. package/src/camera/mapLimitCenter.js +12 -0
  37. package/src/camera/mapLimitOffset.js +10 -0
  38. package/src/camera/mapPanBy.js +9 -0
  39. package/src/camera/mapPanInside.js +14 -0
  40. package/src/camera/mapResetNorth.js +1 -0
  41. package/src/camera/mapResetNorthPitch.js +1 -0
  42. package/src/camera/mapSetBearing.js +1 -0
  43. package/src/camera/mapSetPitch.js +1 -0
  44. package/src/camera/mapSetPitchAndBearing.js +14 -0
  45. package/src/camera/mapSetZoomAround.js +11 -0
  46. package/src/camera/mapStopPitchBearingAnimation.js +6 -0
  47. package/src/camera/mapTryAnimatedPan.js +9 -0
  48. package/src/camera/mapUpdateCameraOverlays.js +7 -0
  49. package/src/camera/pointOf.js +3 -0
  50. package/src/camera/project.js +20 -0
  51. package/src/camera/runCameraAnimations.js +28 -0
  52. package/src/camera/scheduleCameraAnimation.js +8 -0
  53. package/src/camera/updateSky.js +16 -0
  54. package/src/camera/verticalGroundY.js +4 -0
  55. package/src/collision/collectMeshes.js +5 -0
  56. package/src/collision/collider.js +63 -0
  57. package/src/collision/horizontalRay.js +12 -0
  58. package/src/collision/intersectMeshes.js +133 -0
  59. package/src/collision/sortHits.js +23 -0
  60. package/src/constants/CELL.js +4 -0
  61. package/src/constants/Compass.js +7 -0
  62. package/src/constants/ContainerResize.js +7 -0
  63. package/src/constants/HEIGHT.js +1 -0
  64. package/src/constants/PitchDrag.js +7 -0
  65. package/src/constants/ShiftRotate.js +7 -0
  66. package/src/constants/TILE_RADIUS.js +1 -0
  67. package/src/constants/TILE_SIZE.js +1 -0
  68. package/src/constants/TouchMode.js +6 -0
  69. package/src/constants/accessorSizes.js +1 -0
  70. package/src/constants/accessorTypes.js +8 -0
  71. package/src/constants/attachState.js +1 -0
  72. package/src/constants/cameraControlsState.js +1 -0
  73. package/src/constants/cityMapper.js +6 -0
  74. package/src/constants/colliders.js +2 -0
  75. package/src/constants/dark.js +1 -0
  76. package/src/constants/elevationWGSL.js +27 -0
  77. package/src/constants/glass.js +1 -0
  78. package/src/constants/headlight.js +1 -0
  79. package/src/constants/hull.js +1 -0
  80. package/src/constants/indexState.js +1 -0
  81. package/src/constants/limbs.js +9 -0
  82. package/src/constants/mapCameraState.js +1 -0
  83. package/src/constants/moves.js +11 -0
  84. package/src/constants/nativeEventMaps.js +1 -0
  85. package/src/constants/nativeLayerState.js +1 -0
  86. package/src/constants/nativeMethodHandlers.js +31 -0
  87. package/src/constants/onMapChangeState.js +1 -0
  88. package/src/constants/onZoomAnimState.js +1 -0
  89. package/src/constants/paints.js +10 -0
  90. package/src/constants/parts.js +19 -0
  91. package/src/constants/pendingUpdates.js +1 -0
  92. package/src/constants/pumpState.js +1 -0
  93. package/src/constants/renderers.js +2 -0
  94. package/src/constants/ringDirections.js +10 -0
  95. package/src/constants/roundProfile.js +1 -0
  96. package/src/constants/shirt.js +1 -0
  97. package/src/constants/skin.js +2 -0
  98. package/src/constants/speed.js +3 -0
  99. package/src/constants/taillight.js +1 -0
  100. package/src/constants/trafficShader.js +49 -0
  101. package/src/constants/trousers.js +1 -0
  102. package/src/constants/tyre.js +1 -0
  103. package/src/constants/underEntryState.js +1 -0
  104. package/src/constants/vehicles.js +40 -0
  105. package/src/constants/white.js +1 -0
  106. package/src/controls/acceptPitchDrag.js +4 -0
  107. package/src/controls/acceptRotateDrag.js +3 -0
  108. package/src/controls/adjustCameraDrag.js +10 -0
  109. package/src/controls/cameraControls.js +60 -0
  110. package/src/controls/cameraDragClick.js +9 -0
  111. package/src/controls/cameraDragContextMenu.js +8 -0
  112. package/src/controls/cameraDragDown.js +20 -0
  113. package/src/controls/cameraDragEnd.js +6 -0
  114. package/src/controls/cameraDragMove.js +23 -0
  115. package/src/controls/changeCameraTouch.js +14 -0
  116. package/src/controls/cleanupCameraTouch.js +24 -0
  117. package/src/controls/compassAddHooks.js +15 -0
  118. package/src/controls/compassOrientation.js +6 -0
  119. package/src/controls/compassRemoveHooks.js +5 -0
  120. package/src/controls/containerResizeAddHooks.js +8 -0
  121. package/src/controls/containerResizeRemoveHooks.js +5 -0
  122. package/src/controls/dragCamera.js +22 -0
  123. package/src/controls/editable.js +3 -0
  124. package/src/controls/endAllCameraDrags.js +7 -0
  125. package/src/controls/endAllCameraTouches.js +7 -0
  126. package/src/controls/endCameraTouch.js +11 -0
  127. package/src/controls/endCameraTouchEvent.js +5 -0
  128. package/src/controls/finishCameraDrag.js +9 -0
  129. package/src/controls/finishCompassPermission.js +16 -0
  130. package/src/controls/loadCameraControls.js +9 -0
  131. package/src/controls/moveCameraTouch.js +22 -0
  132. package/src/controls/notifyCameraTouchChange.js +1 -0
  133. package/src/controls/pitchDragAddHooks.js +6 -0
  134. package/src/controls/pitchDragRemoveHooks.js +5 -0
  135. package/src/controls/refreshRotateControl.js +7 -0
  136. package/src/controls/refreshRotateFocus.js +5 -0
  137. package/src/controls/removeCameraDrag.js +23 -0
  138. package/src/controls/resizeMap.js +3 -0
  139. package/src/controls/rotateButtonClick.js +7 -0
  140. package/src/controls/rotateButtonKeydown.js +11 -0
  141. package/src/controls/rotateControl.js +3 -0
  142. package/src/controls/rotateOnAdd.js +38 -0
  143. package/src/controls/rotateOnRemove.js +6 -0
  144. package/src/controls/shiftRotateAddHooks.js +8 -0
  145. package/src/controls/shiftRotateRemoveHooks.js +5 -0
  146. package/src/controls/shiftRotateWheel.js +9 -0
  147. package/src/controls/startCameraTouch.js +23 -0
  148. package/src/core/addImageState.js +7 -0
  149. package/src/core/addRasterImage.js +10 -0
  150. package/src/core/adjustCameraMarkerPan.js +22 -0
  151. package/src/core/beforeNativeRender.js +10 -0
  152. package/src/core/boundsQuad.js +11 -0
  153. package/src/core/bringNativeLayerToBack.js +3 -0
  154. package/src/core/bringNativeLayerToFront.js +3 -0
  155. package/src/core/cameraCircleBounds.js +6 -0
  156. package/src/core/cameraMarkerDrag.js +18 -0
  157. package/src/core/cameraMarkerOnDrag.js +8 -0
  158. package/src/core/cancelGridFade.js +10 -0
  159. package/src/core/closestCameraLayerPoint.js +7 -0
  160. package/src/core/compareNativeHits.js +3 -0
  161. package/src/core/current.js +3 -0
  162. package/src/core/disposeNativeLayer.js +35 -0
  163. package/src/core/fireRasterLoad.js +5 -0
  164. package/src/core/forwardNativeError.js +3 -0
  165. package/src/core/gridlayerGetEvents.js +7 -0
  166. package/src/core/gridlayerGetTiledPixelBounds.js +8 -0
  167. package/src/core/handleNativeMapEvent.js +47 -0
  168. package/src/core/hideTargets.js +16 -0
  169. package/src/core/initNativeGPU.js +21 -0
  170. package/src/core/initializeGridContainer.js +6 -0
  171. package/src/core/initializeNativeLayer.js +42 -0
  172. package/src/core/localPixel.js +5 -0
  173. package/src/core/localPixelForGeometry.js +6 -0
  174. package/src/core/localPosition.js +6 -0
  175. package/src/core/markerCameraIconPoint.js +9 -0
  176. package/src/core/markerGetEvents.js +5 -0
  177. package/src/core/markerInitInteraction.js +8 -0
  178. package/src/core/markerQuadCorners.js +31 -0
  179. package/src/core/markerSetIcon.js +9 -0
  180. package/src/core/markerSetPos.js +14 -0
  181. package/src/core/markerSetRotation.js +7 -0
  182. package/src/core/markerUpdateZIndex.js +8 -0
  183. package/src/core/nativeAddLatLng.js +3 -0
  184. package/src/core/nativeBringToBack.js +3 -0
  185. package/src/core/nativeBringToFront.js +3 -0
  186. package/src/core/nativeEvents.js +26 -0
  187. package/src/core/nativeImageError.js +8 -0
  188. package/src/core/nativeImageRefresh.js +7 -0
  189. package/src/core/nativeLayer.js +97 -0
  190. package/src/core/nativeLayerMethod.js +21 -0
  191. package/src/core/nativeRedraw.js +3 -0
  192. package/src/core/nativeSetBounds.js +3 -0
  193. package/src/core/nativeSetIcon.js +3 -0
  194. package/src/core/nativeSetLatLng.js +3 -0
  195. package/src/core/nativeSetLatLngs.js +3 -0
  196. package/src/core/nativeSetOpacity.js +3 -0
  197. package/src/core/nativeSetRadius.js +3 -0
  198. package/src/core/nativeSetStyle.js +3 -0
  199. package/src/core/nativeSetUrl.js +3 -0
  200. package/src/core/nativeSetZIndex.js +3 -0
  201. package/src/core/nativeSetZIndexOffset.js +3 -0
  202. package/src/core/popupAdjustPan.js +23 -0
  203. package/src/core/popupGetEvents.js +5 -0
  204. package/src/core/popupUpdatePosition.js +14 -0
  205. package/src/core/putNativeMesh.js +33 -0
  206. package/src/core/quadNativeMesh.js +15 -0
  207. package/src/core/readyNativeGPU.js +6 -0
  208. package/src/core/refreshNativeEvent.js +5 -0
  209. package/src/core/refreshNativeLayer.js +29 -0
  210. package/src/core/refreshNativeLayerContract.js +3 -0
  211. package/src/core/rejectNativeReady.js +3 -0
  212. package/src/core/removeImageState.js +8 -0
  213. package/src/core/removeNativeEvents.js +16 -0
  214. package/src/core/removeTargets.js +8 -0
  215. package/src/core/reorderNativeLayer.js +6 -0
  216. package/src/core/resolveNativeReady.js +3 -0
  217. package/src/core/restoreNativeEvents.js +6 -0
  218. package/src/core/runGridFades.js +14 -0
  219. package/src/core/runMarkerPanFrame.js +12 -0
  220. package/src/core/scheduleGridFade.js +9 -0
  221. package/src/core/scheduleMarkerPan.js +8 -0
  222. package/src/core/styleNativeMesh.js +10 -0
  223. package/src/core/syncGridLayer.js +22 -0
  224. package/src/core/syncImageOverlay.js +9 -0
  225. package/src/core/syncMarker.js +12 -0
  226. package/src/core/syncVectorLayer.js +26 -0
  227. package/src/core/synchronizeNativeLayer.js +35 -0
  228. package/src/core/textureFor.js +48 -0
  229. package/src/core/tooltipGetEvents.js +5 -0
  230. package/src/core/tooltipSetPosition.js +8 -0
  231. package/src/core/updateGridOpacity.js +23 -0
  232. package/src/core/updateNativeLayerView.js +6 -0
  233. package/src/core/uploadCanvasTexture.js +19 -0
  234. package/src/geometry/addBridges.js +88 -0
  235. package/src/geometry/below.js +3 -0
  236. package/src/geometry/box.js +3 -0
  237. package/src/geometry/bridgeElevation.js +19 -0
  238. package/src/geometry/bridgeLocal.js +4 -0
  239. package/src/geometry/build.js +19 -0
  240. package/src/geometry/circleAt.js +5 -0
  241. package/src/geometry/clipLine.js +23 -0
  242. package/src/geometry/clipSegment.js +19 -0
  243. package/src/geometry/computeBounds.js +33 -0
  244. package/src/geometry/conformModelToTerrain.js +67 -0
  245. package/src/geometry/cross.js +3 -0
  246. package/src/geometry/disk.js +11 -0
  247. package/src/geometry/diskAt.js +4 -0
  248. package/src/geometry/dot.js +6 -0
  249. package/src/geometry/emitter.js +8 -0
  250. package/src/geometry/lampPostGeometry.js +24 -0
  251. package/src/geometry/lampRing.js +11 -0
  252. package/src/geometry/lightGeometry.js +15 -0
  253. package/src/geometry/line.js +54 -0
  254. package/src/geometry/nativeGeometry.js +55 -0
  255. package/src/geometry/nativeTriangle.js +3 -0
  256. package/src/geometry/polygon.js +22 -0
  257. package/src/geometry/push.js +3 -0
  258. package/src/geometry/quad.js +4 -0
  259. package/src/geometry/roofCoverage.js +52 -0
  260. package/src/geometry/samePoint.js +3 -0
  261. package/src/geometry/segment.js +21 -0
  262. package/src/geometry/setVertexColor.js +15 -0
  263. package/src/geometry/sub.js +6 -0
  264. package/src/geometry/surface.js +17 -0
  265. package/src/geometry/treeGeometry.js +31 -0
  266. package/src/geometry/treeRing.js +14 -0
  267. package/src/geometry/triangle.js +12 -0
  268. package/src/geometry/vertexNormals.js +32 -0
  269. package/src/geometry/visit.js +9 -0
  270. package/src/index.js +98 -65
  271. package/src/lighting/cacheLightGrid.js +23 -0
  272. package/src/lighting/collectLightMeshes.js +6 -0
  273. package/src/lighting/lightGrid.js +42 -0
  274. package/src/lighting/updatePointLights.js +34 -0
  275. package/src/lighting/visitCells.js +15 -0
  276. package/src/lighting/worldLights.js +27 -0
  277. package/src/models/decodeModel.js +45 -0
  278. package/src/models/hasUnsupportedPrimitives.js +10 -0
  279. package/src/models/loadBuffer.js +6 -0
  280. package/src/models/loadImage.js +15 -0
  281. package/src/models/loadModel.js +69 -0
  282. package/src/models/materialFor.js +21 -0
  283. package/src/models/modelNode.js +93 -0
  284. package/src/models/nodeMatrix.js +22 -0
  285. package/src/models/readAccessor.js +53 -0
  286. package/src/models/readAccessorValues.js +16 -0
  287. package/src/models/textureFor.js +35 -0
  288. package/src/models/textureSampler.js +10 -0
  289. package/src/picking/collectVisibleMesh.js +4 -0
  290. package/src/picking/findFeature.js +49 -0
  291. package/src/picking/hit.js +23 -0
  292. package/src/picking/hitMesh.js +30 -0
  293. package/src/picking/onClick.js +13 -0
  294. package/src/picking/onPointerLeave.js +11 -0
  295. package/src/picking/onPointerMove.js +15 -0
  296. package/src/picking/pointerClick.js +5 -0
  297. package/src/picking/pointerLeave.js +5 -0
  298. package/src/picking/pointerMove.js +5 -0
  299. package/src/picking/raycast.js +59 -0
  300. package/src/picking/setHighlight.js +13 -0
  301. package/src/picking/shouldSkipOther.js +3 -0
  302. package/src/picking/showFeature.js +34 -0
  303. package/src/raster/addRasterTile.js +114 -0
  304. package/src/raster/comparePendingTiles.js +5 -0
  305. package/src/raster/createGeometry.js +22 -0
  306. package/src/raster/createRasterMesh.js +47 -0
  307. package/src/raster/finishAttachment.js +11 -0
  308. package/src/raster/finishRasterTile.js +47 -0
  309. package/src/raster/getRasterEvents.js +6 -0
  310. package/src/raster/getRasterTileSize.js +5 -0
  311. package/src/raster/initRaster.js +38 -0
  312. package/src/raster/isLoading.js +5 -0
  313. package/src/raster/loadRasterTile.js +10 -0
  314. package/src/raster/onPMTileAdd.js +10 -0
  315. package/src/raster/onPMTileRemove.js +8 -0
  316. package/src/raster/pruneRasterTiles.js +37 -0
  317. package/src/raster/pumpRasterTiles.js +22 -0
  318. package/src/raster/readyRaster.js +13 -0
  319. package/src/raster/registerTerrainTile.js +12 -0
  320. package/src/raster/releaseRasterTile.js +18 -0
  321. package/src/raster/releaseRasterTiles.js +15 -0
  322. package/src/raster/removeRasterTile.js +13 -0
  323. package/src/raster/reportError.js +6 -0
  324. package/src/raster/setPMTileOpacity.js +7 -0
  325. package/src/raster/setPMTileZIndex.js +7 -0
  326. package/src/raster/setRasterOpacity.js +11 -0
  327. package/src/raster/setRasterTerrain.js +21 -0
  328. package/src/raster/setRasterZIndex.js +11 -0
  329. package/src/raster/updateAttachedTiles.js +10 -0
  330. package/src/raster/updateRasterTiles.js +59 -0
  331. package/src/rendering/collectFrameMeshes.js +31 -0
  332. package/src/rendering/collectMeshes.js +36 -0
  333. package/src/rendering/compareMeshes.js +10 -0
  334. package/src/rendering/compareRoofTiles.js +4 -0
  335. package/src/rendering/composeRoofAtlas.js +52 -0
  336. package/src/rendering/createMesh.js +33 -0
  337. package/src/rendering/createProgram.js +92 -0
  338. package/src/rendering/destroyAfterSubmission.js +8 -0
  339. package/src/rendering/destroyTexture.js +6 -0
  340. package/src/rendering/disposeMesh.js +14 -0
  341. package/src/rendering/drawGeometry.js +129 -0
  342. package/src/rendering/drawSceneMeshes.js +51 -0
  343. package/src/rendering/ensureRoofBlit.js +40 -0
  344. package/src/rendering/prepareFrameMeshes.js +42 -0
  345. package/src/rendering/prepareFrameUniforms.js +49 -0
  346. package/src/rendering/rebuildRoofAtlas.js +67 -0
  347. package/src/rendering/render.js +57 -0
  348. package/src/rendering/reportCompilation.js +17 -0
  349. package/src/rendering/resizeRenderer.js +19 -0
  350. package/src/rendering/sortMeshes.js +6 -0
  351. package/src/rendering/synchronizeZoomView.js +34 -0
  352. package/src/rendering/textureBinding.js +7 -0
  353. package/src/rendering/updateMapCamera.js +32 -0
  354. package/src/rendering/updateRoofRaster.js +32 -0
  355. package/src/scene/attach.js +161 -0
  356. package/src/scene/attachLayer.js +10 -0
  357. package/src/scene/cancelUpdate.js +10 -0
  358. package/src/scene/emptyEvents.js +3 -0
  359. package/src/scene/emptyNode.js +11 -0
  360. package/src/scene/endZoom.js +16 -0
  361. package/src/scene/failAttachment.js +9 -0
  362. package/src/scene/get3DEvents.js +13 -0
  363. package/src/scene/init3D.js +30 -0
  364. package/src/scene/initializeLayer.js +16 -0
  365. package/src/scene/initializerFor.js +14 -0
  366. package/src/scene/layerInitialize.js +38 -0
  367. package/src/scene/layerLayerAdd.js +21 -0
  368. package/src/scene/onAdd3DLayer.js +35 -0
  369. package/src/scene/onMapChange.js +16 -0
  370. package/src/scene/onRemove3DLayer.js +69 -0
  371. package/src/scene/onZoomAnim.js +16 -0
  372. package/src/scene/placeEntry.js +11 -0
  373. package/src/scene/placeUnderEntry.js +8 -0
  374. package/src/scene/ready3D.js +25 -0
  375. package/src/scene/releaseRenderer.js +14 -0
  376. package/src/scene/removeEntry.js +6 -0
  377. package/src/scene/renderPendingMapChange.js +11 -0
  378. package/src/scene/renderPendingUpdates.js +19 -0
  379. package/src/scene/renderPendingZoomAnimation.js +7 -0
  380. package/src/scene/rendererDeviceError.js +10 -0
  381. package/src/scene/rendererDeviceLost.js +11 -0
  382. package/src/scene/replaceEntry.js +7 -0
  383. package/src/scene/reportError.js +3 -0
  384. package/src/scene/requestAdapter.js +12 -0
  385. package/src/scene/requestDevice.js +9 -0
  386. package/src/scene/resolveNextInitialization.js +12 -0
  387. package/src/scene/restoreObject.js +71 -0
  388. package/src/scene/runPlacements.js +7 -0
  389. package/src/scene/setParent.js +7 -0
  390. package/src/scene/showWebGPUWarning.js +16 -0
  391. package/src/scene/startZoom.js +5 -0
  392. package/src/scene/traverse.js +7 -0
  393. package/src/scene/underEntry.js +17 -0
  394. package/src/scene/update.js +19 -0
  395. package/src/scene/updateCamera.js +34 -0
  396. package/src/scene/updateWorldMatrix.js +48 -0
  397. package/src/{utils/shaders.js → shaders/materialShaders.js} +246 -237
  398. package/src/shadows/bindSunlight.js +12 -0
  399. package/src/shadows/drawShadowMeshes.js +48 -0
  400. package/src/shadows/ensureShadowPipeline.js +53 -0
  401. package/src/shadows/renderSunlight.js +46 -0
  402. package/src/shadows/resizeSunlight.js +15 -0
  403. package/src/shadows/shadowBounds.js +32 -0
  404. package/src/shadows/shadowCacheMatches.js +23 -0
  405. package/src/shadows/shadowMatrix.js +39 -0
  406. package/src/sources/addGeneratedTriangle.js +6 -0
  407. package/src/sources/addTriangle.js +17 -0
  408. package/src/sources/attachAreaMesh.js +58 -0
  409. package/src/sources/buildArea.js +42 -0
  410. package/src/sources/buildAreaFeature.js +41 -0
  411. package/src/sources/buildAreaPoint.js +25 -0
  412. package/src/sources/buildAreaPolygon.js +29 -0
  413. package/src/sources/compareAreaDistance.js +4 -0
  414. package/src/sources/generateTreeGeometry.js +11 -0
  415. package/src/sources/groundOffset.js +3 -0
  416. package/src/sources/initializeGeoJSON.js +8 -0
  417. package/src/sources/instanceAreaGeometry.js +29 -0
  418. package/src/sources/projectRing.js +20 -0
  419. package/src/sources/projectedTree.js +13 -0
  420. package/src/sources/pump.js +54 -0
  421. package/src/sources/releaseArea.js +22 -0
  422. package/src/sources/setGeoJSONData.js +12 -0
  423. package/src/sources/setGeoJSONLayerData.js +5 -0
  424. package/src/sources/sourceAreaContext.js +9 -0
  425. package/src/sources/updateArea.js +45 -0
  426. package/src/sources/updateStatus.js +12 -0
  427. package/src/sunlight/addTimeLayer.js +3 -0
  428. package/src/sunlight/addTo.js +10 -0
  429. package/src/sunlight/atmosphere.js +28 -0
  430. package/src/sunlight/horizontalPosition.js +16 -0
  431. package/src/sunlight/initSunlight.js +14 -0
  432. package/src/sunlight/initialize.js +11 -0
  433. package/src/sunlight/mix.js +6 -0
  434. package/src/sunlight/moonPosition.js +17 -0
  435. package/src/sunlight/onAdd.js +5 -0
  436. package/src/sunlight/onAddSun.js +66 -0
  437. package/src/sunlight/projectCelestialBody.js +13 -0
  438. package/src/sunlight/remove.js +7 -0
  439. package/src/sunlight/removeSun.js +15 -0
  440. package/src/sunlight/removeTimeLayer.js +3 -0
  441. package/src/sunlight/render.js +7 -0
  442. package/src/sunlight/rgb.js +6 -0
  443. package/src/sunlight/solarPosition.js +17 -0
  444. package/src/sunlight/styleTimeControl.js +7 -0
  445. package/src/sunlight/tickSun.js +5 -0
  446. package/src/sunlight/updateSky.js +20 -0
  447. package/src/sunlight/updateSun.js +34 -0
  448. package/src/sunlight/useLiveTime.js +6 -0
  449. package/src/sunlight/useSelectedTime.js +20 -0
  450. package/src/terrain/clearLayerTerrain.js +5 -0
  451. package/src/terrain/getElevation.js +10 -0
  452. package/src/terrain/initTerrain.js +20 -0
  453. package/src/terrain/loadReadyTerrain.js +5 -0
  454. package/src/terrain/loadTerrain.js +63 -0
  455. package/src/terrain/loadTerrainTiles.js +13 -0
  456. package/src/terrain/onTerrainAdd.js +21 -0
  457. package/src/terrain/onTerrainChange.js +14 -0
  458. package/src/terrain/onTerrainRemove.js +41 -0
  459. package/src/terrain/readBridges.js +4 -0
  460. package/src/terrain/sample.js +7 -0
  461. package/src/terrain/setLayerTerrain.js +5 -0
  462. package/src/terrain/setTerrainHeight.js +10 -0
  463. package/src/terrain/terrainAtlas.js +23 -0
  464. package/src/terrain/terrainElevation.js +20 -0
  465. package/src/terrain/terrainGrid.js +24 -0
  466. package/src/traffic/addTraffic.js +7 -0
  467. package/src/traffic/along.js +14 -0
  468. package/src/traffic/clockMinutes.js +6 -0
  469. package/src/traffic/compareDepartures.js +5 -0
  470. package/src/traffic/createTrafficMesh.js +7 -0
  471. package/src/traffic/destroyTrafficGpu.js +5 -0
  472. package/src/traffic/disposeTrafficObject.js +13 -0
  473. package/src/traffic/drawTrafficRoute.js +6 -0
  474. package/src/traffic/failTraffic.js +6 -0
  475. package/src/traffic/failedTrafficLoad.js +5 -0
  476. package/src/traffic/fetchTrafficLanes.js +10 -0
  477. package/src/traffic/groundTraffic.js +15 -0
  478. package/src/traffic/initTraffic.js +54 -0
  479. package/src/traffic/loadTraffic.js +15 -0
  480. package/src/traffic/loadedTrafficLanes.js +16 -0
  481. package/src/traffic/locateTraffic.js +9 -0
  482. package/src/traffic/moveTraffic.js +15 -0
  483. package/src/traffic/placeTraffic.js +21 -0
  484. package/src/traffic/prepareTraffic.js +25 -0
  485. package/src/traffic/readyTraffic.js +6 -0
  486. package/src/traffic/rebaseTraffic.js +58 -0
  487. package/src/traffic/rebuildTrafficMesh.js +28 -0
  488. package/src/traffic/removeTraffic.js +17 -0
  489. package/src/traffic/routeColor.js +6 -0
  490. package/src/traffic/routeGeometry.js +31 -0
  491. package/src/traffic/scheduledTrips.js +40 -0
  492. package/src/traffic/startTraffic.js +8 -0
  493. package/src/traffic/tickTraffic.js +57 -0
  494. package/src/traffic/toLanes.js +16 -0
  495. package/src/traffic/tooltip.js +11 -0
  496. package/src/traffic/trafficBounds.js +17 -0
  497. package/src/traffic/trafficNow.js +4 -0
  498. package/src/traffic/trafficStorage.js +5 -0
  499. package/src/traffic/tripsAt.js +27 -0
  500. package/src/traffic/updateTraffic.js +8 -0
  501. package/src/traffic/updateTrafficTerrain.js +12 -0
  502. package/src/traffic/vehicleOffsets.js +11 -0
  503. package/src/triangulation/area.js +9 -0
  504. package/src/triangulation/clean.js +18 -0
  505. package/src/triangulation/containsVertex.js +11 -0
  506. package/src/triangulation/cross.js +3 -0
  507. package/src/triangulation/crossesBoundary.js +8 -0
  508. package/src/triangulation/crossesRing.js +9 -0
  509. package/src/triangulation/equal.js +3 -0
  510. package/src/triangulation/inside.js +10 -0
  511. package/src/triangulation/insideHole.js +7 -0
  512. package/src/triangulation/intersects.js +11 -0
  513. package/src/triangulation/isClockWise.js +13 -0
  514. package/src/triangulation/minimumX.js +6 -0
  515. package/src/triangulation/on.js +4 -0
  516. package/src/triangulation/sortHoles.js +26 -0
  517. package/src/triangulation/triangulate.js +86 -0
  518. package/src/utils/channel.js +4 -0
  519. package/src/utils/compareDistance.js +3 -0
  520. package/src/utils/noOperation.js +1 -0
  521. package/src/utils/parseColor.js +42 -0
  522. package/src/utils/toSRGB.js +3 -0
  523. package/src/utils/wrap.js +3 -0
  524. package/src/vehicles/bicycleModel.js +23 -0
  525. package/src/vehicles/boatBenches.js +8 -0
  526. package/src/vehicles/boatModel.js +27 -0
  527. package/src/vehicles/busModel.js +6 -0
  528. package/src/vehicles/carModel.js +22 -0
  529. package/src/vehicles/carriage.js +19 -0
  530. package/src/vehicles/metroModel.js +9 -0
  531. package/src/vehicles/mirror.js +8 -0
  532. package/src/vehicles/pedestrianModel.js +17 -0
  533. package/src/vehicles/tramModel.js +9 -0
  534. package/src/walk/blocked.js +6 -0
  535. package/src/walk/createWalk.js +60 -0
  536. package/src/walk/initWalk.js +18 -0
  537. package/src/walk/initialize.js +6 -0
  538. package/src/walk/local.js +10 -0
  539. package/src/walk/onAdd.js +4 -0
  540. package/src/walk/onBlur.js +3 -0
  541. package/src/walk/onKey.js +12 -0
  542. package/src/walk/onPointer.js +13 -0
  543. package/src/walk/onRemove.js +4 -0
  544. package/src/walk/onTerrain.js +5 -0
  545. package/src/walk/place.js +18 -0
  546. package/src/walk/start.js +37 -0
  547. package/src/walk/step.js +53 -0
  548. package/src/walk/stop.js +27 -0
  549. package/src/walk/toggle.js +6 -0
  550. package/dist/scene/gpu.js +0 -3
  551. package/dist/scene/gpu.js.map +0 -7
  552. package/dist/scene/lighting.js +0 -9
  553. package/dist/scene/lighting.js.map +0 -7
  554. package/dist/scene/model.js +0 -2
  555. package/dist/scene/model.js.map +0 -7
  556. package/dist/scene/picking.js +0 -2
  557. package/dist/scene/picking.js.map +0 -7
  558. package/dist/scene/pmtiles.js +0 -2
  559. package/dist/scene/pmtiles.js.map +0 -7
  560. package/dist/scene/render.js +0 -15
  561. package/dist/scene/render.js.map +0 -7
  562. package/dist/scene/sources.js +0 -2
  563. package/dist/scene/sources.js.map +0 -7
  564. package/dist/types/3d.js +0 -2
  565. package/dist/types/3d.js.map +0 -7
  566. package/dist/types/geojson.js +0 -2
  567. package/dist/types/geojson.js.map +0 -7
  568. package/dist/types/pmtiles.js +0 -2
  569. package/dist/types/pmtiles.js.map +0 -7
  570. package/dist/types/sunlight.js +0 -2
  571. package/dist/types/sunlight.js.map +0 -7
  572. package/dist/types/terrain.js +0 -24
  573. package/dist/types/terrain.js.map +0 -7
  574. package/dist/types/traffic.js +0 -41
  575. package/dist/types/traffic.js.map +0 -7
  576. package/dist/types/walk.js +0 -2
  577. package/dist/types/walk.js.map +0 -7
  578. package/dist/utils/control.js +0 -2
  579. package/dist/utils/control.js.map +0 -7
  580. package/dist/utils/geometry.js +0 -2
  581. package/dist/utils/geometry.js.map +0 -7
  582. package/dist/utils/lighting.js +0 -2
  583. package/dist/utils/lighting.js.map +0 -7
  584. package/dist/utils/model.js +0 -2
  585. package/dist/utils/model.js.map +0 -7
  586. package/dist/utils/picking.js +0 -2
  587. package/dist/utils/picking.js.map +0 -7
  588. package/dist/utils/pmtiles.js +0 -2
  589. package/dist/utils/pmtiles.js.map +0 -7
  590. package/dist/utils/scene.js +0 -2
  591. package/dist/utils/scene.js.map +0 -7
  592. package/dist/utils/shaders.js +0 -203
  593. package/dist/utils/shaders.js.map +0 -7
  594. package/dist/utils/sun.js +0 -2
  595. package/dist/utils/sun.js.map +0 -7
  596. package/dist/utils/terrain.js +0 -2
  597. package/dist/utils/terrain.js.map +0 -7
  598. package/dist/utils/traffic.js +0 -2
  599. package/dist/utils/traffic.js.map +0 -7
  600. package/dist/utils/vehicles.js +0 -2
  601. package/dist/utils/vehicles.js.map +0 -7
  602. package/dist/utils/walk.js +0 -2
  603. package/dist/utils/walk.js.map +0 -7
  604. package/src/scene/gpu.js +0 -438
  605. package/src/scene/lighting.js +0 -193
  606. package/src/scene/model.js +0 -204
  607. package/src/scene/picking.js +0 -150
  608. package/src/scene/pmtiles.js +0 -94
  609. package/src/scene/render.js +0 -467
  610. package/src/scene/sources.js +0 -265
  611. package/src/types/3d.js +0 -337
  612. package/src/types/geojson.js +0 -42
  613. package/src/types/pmtiles.js +0 -143
  614. package/src/types/sunlight.js +0 -142
  615. package/src/types/terrain.js +0 -331
  616. package/src/types/traffic.js +0 -356
  617. package/src/types/walk.js +0 -219
  618. package/src/utils/control.js +0 -18
  619. package/src/utils/geometry.js +0 -256
  620. package/src/utils/lighting.js +0 -51
  621. package/src/utils/model.js +0 -178
  622. package/src/utils/picking.js +0 -119
  623. package/src/utils/pmtiles.js +0 -79
  624. package/src/utils/scene.js +0 -102
  625. package/src/utils/sun.js +0 -71
  626. package/src/utils/terrain.js +0 -78
  627. package/src/utils/traffic.js +0 -90
  628. package/src/utils/vehicles.js +0 -69
  629. package/src/utils/walk.js +0 -72
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/pmtiles.js"],
4
- "sourcesContent": ["import { decodeHeader, decodeDirectory, decompress, tileId } from '../utils/pmtiles.js';\r\n\r\n/**\r\n * PMTiles v3 range reader.\r\n * Supports uncompressed/gzip sections. Other compression methods fail explicitly.\r\n * Specification: https://github.com/protomaps/PMTiles/blob/main/spec/v3/spec.md\r\n */\r\n/** Read exactly one archive range; reject changed archives rather than mix revisions. */\r\nexport async function read(backend, offset, length, signal) {\r\n signal?.throwIfAborted();\r\n if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(length) ||\r\n offset < 0 || length <= 0 || !Number.isSafeInteger(offset + length)) {\r\n throw new Error('Invalid PMTiles byte range');\r\n }\r\n const response = await fetch(backend.url, {\r\n headers: { Range: `bytes=${offset}-${offset + length - 1}` }, signal,\r\n });\r\n if (!response.ok) throw new Error(`Unable to read PMTiles: HTTP ${response.status}`);\r\n const etag = response.headers.get('ETag');\r\n if (backend._etag && etag !== backend._etag) {\r\n throw new Error('PMTiles archive changed; recreate the layer');\r\n }\r\n if (etag) {\r\n backend._etag = etag;\r\n }\r\n let data = await response.arrayBuffer();\r\n if (response.status === 200) {\r\n data = data.slice(offset, offset + length);\r\n } else if (response.status !== 206 || !response.headers.get('Content-Range')?.startsWith(`bytes ${offset}-${offset + length - 1}/`)) {\r\n throw new Error('Invalid PMTiles range response');\r\n }\r\n if (data.byteLength !== length) {\r\n throw new Error('Truncated PMTiles range');\r\n }\r\n return data;\r\n}\r\n\r\n/** Cache header initialization; failures remain visible to all callers. */\r\nexport function getHeader(backend) {\r\n return backend._header ||= backend._read(0, 127).then(decodeHeader);\r\n}\r\n\r\n/** Nearest directory entry at/before the Hilbert ID, then follow leaf pointers. */\r\nexport async function getZxy(backend, z, x, y, signal) {\r\n const id = tileId(z, x, y);\r\n signal?.throwIfAborted();\r\n const header = await backend.getHeader();\r\n signal?.throwIfAborted();\r\n if (z < header.minZoom || z > header.maxZoom) return;\r\n let offset = header.rootDirectoryOffset, length = header.rootDirectoryLength;\r\n const visited = new Set();\r\n for (let depth = 0; depth < 4; depth++) {\r\n if (visited.has(offset)) {\r\n throw new Error('Cyclic PMTiles directory');\r\n }\r\n visited.add(offset);\r\n const key = `${offset}:${length}`;\r\n if (!backend._directories.has(key)) {\r\n if (backend._directories.size >= 32) {\r\n backend._directories.delete(backend._directories.keys().next().value);\r\n }\r\n const pending = backend._read(offset, length)\r\n .then(data => decompress(data, header.internalCompression))\r\n .then(decodeDirectory)\r\n .catch(error => {\r\n if (backend._directories.get(key) === pending) backend._directories.delete(key);\r\n throw error;\r\n });\r\n backend._directories.set(key, pending);\r\n }\r\n const entries = await backend._directories.get(key);\r\n signal?.throwIfAborted();\r\n let low = 0,\r\n high = entries.length - 1;\r\n while (low <= high) {\r\n const mid = (low + high) >> 1;\r\n if (entries[mid].tileId <= id) low = mid + 1;\r\n else high = mid - 1;\r\n }\r\n const entry = entries[high];\r\n if (!entry) return;\r\n if (entry.runLength) {\r\n if (id - entry.tileId >= entry.runLength) return;\r\n if (entry.offset + entry.length > header.tileDataLength) throw new Error('PMTiles tile outside data section');\r\n const data = await decompress(await backend._read(header.tileDataOffset + entry.offset, entry.length, signal), header.tileCompression);\r\n signal?.throwIfAborted();\r\n return { data };\r\n }\r\n if (entry.offset + entry.length > header.leafDirectoryLength) throw new Error('PMTiles directory outside leaf section');\r\n offset = header.leafDirectoryOffset + entry.offset;\r\n length = entry.length;\r\n }\r\n throw new Error('PMTiles directory depth exceeds four levels');\r\n}\r\n"],
5
- "mappings": "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",
6
- "names": ["decodeHeader", "decodeDirectory", "decompress", "tileId", "read", "backend", "offset", "length", "signal", "response", "etag", "data", "getHeader", "getZxy", "z", "x", "y", "id", "header", "visited", "depth", "key", "pending", "error", "entries", "low", "high", "mid", "entry"]
7
- }
@@ -1,15 +0,0 @@
1
- import{computeBounds as ae}from"../utils/geometry.js";import{traverse as K,updateWorldMatrix as fe,updateCamera as ce}from"../utils/scene.js";function ge(e){const s=e._shared;return s?s!==e?(s.update(),e):(e._frame||=requestAnimationFrame(()=>{e._frame=null,e._shared===e&&e.renderer&&e._render()}),e):e}function xe(e){e._queued||(e._queued=!0,queueMicrotask(()=>{e._queued=!1,!(e._shared!==e||!e.renderer)&&(e._map._animatingZoom?e.update():e._render())}))}function he(e){let s;return e._map.eachLayer(x=>{!s&&x instanceof L.TileLayer&&x._levels&&(s=x._levels[x._tileZoom])}),s}function de(e){e._zoomLevel=e._getTileLevel()}function ye(e){for(const s of e._zoomTransitions?.keys()||[])s.finish();e._zoomTransitions=null,e._zoomLevel=null,e.update()}function _e(e){if(cancelAnimationFrame(e._frame),e._frame=null,e._shared!==e||!e.renderer)return;const s=e._map,x=s.getSize();if(!x.x||!x.y)return;if(s._animatingZoom){e._zoomTransitions||=new Map;const t=performance.now();for(const r of s.getContainer().getAnimations({subtree:!0})){if(!(r instanceof CSSTransition)||r.transitionProperty!=="transform"||!r.effect.target.classList.contains("leaflet-zoom-animated")||e._zoomTransitions.has(r))continue;const i=r.currentTime||0;r.pause(),e._zoomTransitions.set(r,{start:t,time:i})}for(const[r,{start:i,time:c}]of e._zoomTransitions)r.currentTime=Math.min(r.effect.getComputedTiming().endTime,c+t-i)}(!e._size||!e._size.equals(x))&&(e.renderer.width=x.x,e.renderer.height=x.y,e.renderer.canvas.width=Math.round(x.x*e.renderer.dpr),e.renderer.canvas.height=Math.round(x.y*e.renderer.dpr),e.renderer.canvas.style.width=`${x.x}px`,e.renderer.canvas.style.height=`${x.y}px`,e.renderer.depthTexture&&e._destroyTexture(e.renderer.depthTexture),e.renderer.depthTexture=e.renderer.device.createTexture({size:[e.renderer.canvas.width,e.renderer.canvas.height],format:"depth24plus",usage:GPUTextureUsage.RENDER_ATTACHMENT}),e._size=x);let F=s.options.crs.scale(s.getZoom())/(4007501668557849e-8*Math.cos(e._sceneOrigin.lat*Math.PI/180)),j=s.project(e._sceneOrigin).subtract(s.getPixelOrigin());const T=e._zoomLevel?.el.isConnected?e._zoomLevel:e._getTileLevel();if(T&&s._animatingZoom&&(e._zoomLevel=T),T){const t=new DOMMatrix(s._animatingZoom?getComputedStyle(T.el).transform:T.el.style.transform),r=s.project(e._sceneOrigin,T.zoom).subtract(T.origin);j=new L.Point(r.x*t.a+t.e,r.y*t.d+t.f),F*=s.getZoomScale(T.zoom,s.getZoom())*t.a}const G=x.y*1.5/F,Q=s.containerPointToLayerPoint(x.divideBy(2)),B=[(Q.x-j.x)/F,s._terrain3D?._getElevation(s.getCenter())??0,(Q.y-j.y)/F],U=s.getPitch()*Math.PI/180,N=s.getBearing()*Math.PI/180,p=e.camera;p.fov=2*Math.atan(1/3)*180/Math.PI,p.aspect=x.x/x.y,p.near=Math.max(.1,G/1e4),p.far=Math.max(1e4,G*10),p.position[0]=B[0]+Math.sin(N)*Math.sin(U)*G,p.position[1]=B[1]+Math.cos(U)*G,p.position[2]=B[2]+Math.cos(N)*Math.sin(U)*G,p.up[0]=-Math.sin(N)*Math.cos(U),p.up[1]=Math.sin(U),p.up[2]=-Math.cos(N)*Math.cos(U),p.target[0]=B[0],p.target[1]=B[1],p.target[2]=B[2],ce(p);const v=s._sunlight,O=new DOMPoint(...v?.direction||[-300,500,300],0).matrixTransform(new DOMMatrix(p.viewMatrix)),q=Math.hypot(O.x,O.y,O.z)||1,ue=[O.x/q,O.y/q,O.z/q],D=new DOMPoint(0,1,0,0).matrixTransform(new DOMMatrix(p.viewMatrix)),$=Math.hypot(D.x,D.y,D.z)||1,le=[D.x/$,D.y/$,D.z/$],o=p.projectionViewMatrix,n=[[o[3]+o[0],o[7]+o[4],o[11]+o[8],o[15]+o[12]],[o[3]-o[0],o[7]-o[4],o[11]-o[8],o[15]-o[12]],[o[3]+o[1],o[7]+o[5],o[11]+o[9],o[15]+o[13]],[o[3]-o[1],o[7]-o[5],o[11]-o[9],o[15]-o[13]],[o[2],o[6],o[10],o[14]],[o[3]-o[2],o[7]-o[6],o[11]-o[10],o[15]-o[14]]],S=[Math.hypot(n[0][0],n[0][1],n[0][2]),Math.hypot(n[1][0],n[1][1],n[1][2]),Math.hypot(n[2][0],n[2][1],n[2][2]),Math.hypot(n[3][0],n[3][1],n[3][2]),Math.hypot(n[4][0],n[4][1],n[4][2]),Math.hypot(n[5][0],n[5][1],n[5][2])];fe(e.scene),K(e.scene,t=>{if(!t.visible)return!0;if(t.geometry){t.geometry.bounds||ae(t.geometry);const r=t.geometry.bounds,i=t.worldMatrix,c=r.center,a=i[0]*c[0]+i[4]*c[1]+i[8]*c[2]+i[12],l=i[1]*c[0]+i[5]*c[1]+i[9]*c[2]+i[13],f=i[2]*c[0]+i[6]*c[1]+i[10]*c[2]+i[14],m=r.radius*Math.max(Math.hypot(i[0],i[1],i[2]),Math.hypot(i[4],i[5],i[6]),Math.hypot(i[8],i[9],i[10]));if(t._visibleInFrame=n[0][0]*a+n[0][1]*l+n[0][2]*f+n[0][3]>=-m*S[0]&&n[1][0]*a+n[1][1]*l+n[1][2]*f+n[1][3]>=-m*S[1]&&n[2][0]*a+n[2][1]*l+n[2][2]*f+n[2][3]>=-m*S[2]&&n[3][0]*a+n[3][1]*l+n[3][2]*f+n[3][3]>=-m*S[3]&&n[4][0]*a+n[4][1]*l+n[4][2]*f+n[4][3]>=-m*S[4]&&n[5][0]*a+n[5][1]*l+n[5][2]*f+n[5][3]>=-m*S[5],!t._visibleInFrame)return}if(t.program?.transparent){t.geometry.bounds||ae(t.geometry);const r=t.geometry.bounds.center,i=t.worldMatrix,c=i[0]*r[0]+i[4]*r[1]+i[8]*r[2]+i[12],a=i[1]*r[0]+i[5]*r[1]+i[9]*r[2]+i[13],l=i[2]*r[0]+i[6]*r[1]+i[10]*r[2]+i[14],f=p.projectionViewMatrix,m=f[2]*c+f[6]*a+f[10]*l+f[14],b=f[3]*c+f[7]*a+f[11]*l+f[15];t._sortDepth=m/b}});const u=e.renderer;if([...e._layers].some(t=>t.options.roofTexture)){const t=Object.values(s._layers).filter(a=>a instanceof L.Layer.types.pmtiles&&a._tiles&&a.options.opacity>0),r=t.flatMap(a=>Object.values(a._tiles).filter(l=>l.el.done&&!l.el.request.signal.aborted&&l.el.isConnected).map(l=>({...l,layer:a}))),i=r.map(({el:a,coords:l,layer:f})=>`${L.Util.stamp(a)}:${l.z}:${l.x}:${l.y}:${f.options.opacity}:${f.options.zIndex}`).join("|"),c=t.map(a=>`${L.Util.stamp(a)}:${a.options.opacity}:${a.options.zIndex}`).join("|");if(!e._roofRaster||e._roofRaster.selection!==c||!t.some(a=>a.isLoading())&&e._roofRaster.signature!==i){const a=r.length?Math.max(...r.map(g=>g.coords.z)):s.getZoom(),l=new L.Bounds;for(const{coords:g,layer:_}of r){const h=_.getTileSize().multiplyBy(s.getZoomScale(a,g.z));l.extend(new L.Point(g.x,g.y).scaleBy(h)),l.extend(new L.Point(g.x+1,g.y+1).scaleBy(h))}const f=l.min||s.project(e._sceneOrigin,a),m=l.isValid()?l.getSize():new L.Point(1,1),k=Math.min(1,4096/Math.max(m.x,m.y)),w=Math.max(1,Math.ceil(m.x*k)),z=Math.max(1,Math.ceil(m.y*k)),ee=s.project(e._sceneOrigin,a),te=s.options.crs.scale(a)/(4007501668557849e-8*Math.cos(e._sceneOrigin.lat*Math.PI/180)),E=new DOMMatrix;E.m11=te/m.x,E.m33=te/m.y,E.m41=(ee.x-f.x)/m.x,E.m43=(ee.y-f.y)/m.y;const P=e._roofRaster?.texture;P&&(P.width!==w||P.height!==z)&&(e._destroyTexture(P.texture),P.texture=u.device.createTexture({size:[w,z],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),P.width=w,P.height=z),e._roofRaster={signature:i,selection:c,matrix:Array.from(E.toFloat64Array()),texture:P||{device:u.device,texture:u.device.createTexture({size:[w,z],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),sampler:u.device.createSampler({addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),samplerOptions:{addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"},image:null,width:w,height:z,format:"rgba8unorm",srgb:!1,flipY:!1,uploaded:null}};const y=u.device;if(!u.roofBlit){const g=y.createShaderModule({code:`
2
- @group(0) @binding(0) var source: texture_2d<f32>;
3
- @group(0) @binding(1) var sourceSampler: sampler;
4
- @group(0) @binding(2) var<uniform> opacity: f32;
5
- struct Varyings { @builtin(position) position: vec4f, @location(0) uv: vec2f };
6
- @vertex fn vertexMain(@builtin(vertex_index) index: u32) -> Varyings {
7
- let uv = vec2f(f32(index & 1u), f32(index >> 1u));
8
- return Varyings(vec4f(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, 0.0, 1.0), uv);
9
- }
10
- @fragment fn fragmentMain(input: Varyings) -> @location(0) vec4f {
11
- let color = textureSample(source, sourceSampler, input.uv);
12
- return vec4f(color.rgb, color.a * opacity);
13
- }
14
- `});u.roofBlit={pipeline:y.createRenderPipeline({layout:"auto",vertex:{module:g,entryPoint:"vertexMain"},fragment:{module:g,entryPoint:"fragmentMain",targets:[{format:"rgba8unorm",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}]},primitive:{topology:"triangle-strip"}}),sampler:y.createSampler({magFilter:"linear",minFilter:"linear"})}}const Z=e._roofTiles||=new Map;for(const[g,_]of Z)(!r.some(h=>h.el===g)||s._terrain3D?._rasterTiles.has(g))&&(_.texture.destroy(),Z.delete(g));const W=new Float32Array(Math.max(1,r.length)*64),X=y.createBuffer({size:W.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),re=y.createCommandEncoder(),I=re.beginRenderPass({colorAttachments:[{view:e._roofRaster.texture.texture.createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}]});I.setPipeline(u.roofBlit.pipeline),r.sort((g,_)=>(g.layer.options.zIndex||0)-(_.layer.options.zIndex||0)||g.coords.z-_.coords.z);for(const[g,{coords:_,el:h,layer:oe}]of r.entries()){let d=s._terrain3D?._rasterTiles.get(h)?.texture||Z.get(h);d||(d={texture:y.createTexture({size:[h.naturalWidth,h.naturalHeight],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),image:h,uploaded:null},Z.set(h,d)),d.uploaded!==d.image&&(y.queue.copyExternalImageToTexture({source:h},{texture:d.texture},[d.texture.width,d.texture.height]),d.uploaded=d.image),W[g*64]=oe.options.opacity;const J=oe.getTileSize().multiplyBy(s.getZoomScale(a,_.z)),ie=new L.Point(_.x,_.y).scaleBy(J).subtract(f),ne=ie.x*w/m.x,se=ie.y*z/m.y;I.setViewport(ne,se,Math.min(J.x*w/m.x,w-ne),Math.min(J.y*z/m.y,z-se),0,1),I.setBindGroup(0,y.createBindGroup({layout:u.roofBlit.pipeline.getBindGroupLayout(0),entries:[{binding:0,resource:d.texture.createView()},{binding:1,resource:u.roofBlit.sampler},{binding:2,resource:{buffer:X,offset:g*256,size:4}}]})),I.draw(4)}I.end(),y.queue.writeBuffer(X,0,W),y.queue.submit([re.finish()]),X.destroy()}}else if(e._roofRaster){e._destroyTexture(e._roofRaster.texture.texture),e._roofRaster=null;for(const t of e._roofTiles?.values()||[])t.texture.destroy();e._roofTiles=null}const C=[];K(e.scene,t=>{if(!t.visible)return!0;t.geometry&&t._visibleInFrame&&C.push(t)}),C.sort((t,r)=>Number(t.program.transparent)-Number(r.program.transparent)||t.program.transparent&&((t.renderOrder||0)-(r.renderOrder||0)||r._sortDepth-t._sortDepth)||t.id-r.id);const Y=u.device.createCommandEncoder(),H=[],V=[];if(v?.altitude>=3)for(const t of e._layers)t instanceof L.Layer.types.terrain||K(t.root,r=>{if(!r.visible)return!0;r.geometry&&!r.tile&&!r.program.nightLight&&r.program.depthTest!==!1&&V.push(r)});(!u.uniformBuffer||u.uniformBuffer.size<(C.length*2+V.length+1)*256)&&(u.uniformBuffer&&e._destroyTexture(u.uniformBuffer),u.uniformBuffer=u.device.createBuffer({size:Math.max(64,C.length*4+V.length*2)*256,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),u.uniformData=new Float32Array(u.uniformBuffer.size/4));const M=u.uniformData;M.set(p.viewMatrix,0),M.set(p.projectionMatrix,16),M.set(e._roofRaster?.matrix||[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],32),M.set(ue,48),M[51]=v&&v.altitude<=0?0:1,M.set(le,52);const A=v?Math.max(0,Math.min(1,(3-v.altitude)/9)):0;M[55]=A*A*(3-2*A),M.set(v?.tint||[1,1,1],56),M[59]=0,A>0&&e._updatePointLights(),u.uniformSlot=1,e._renderSunlight(Y,V,v);const R=Y.beginRenderPass({colorAttachments:[{view:u.context.getCurrentTexture().createView(),clearValue:{r:0,g:0,b:0,a:0},loadOp:"clear",storeOp:"store"}],depthStencilAttachment:{view:u.depthTexture.createView(),depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"}});R.setViewport(0,0,u.canvas.width,u.canvas.height,0,1),R.setBindGroup(1,u.sunlight.bindGroup);for(const t of C){t.tile&&t.tile.style.visibility!=="hidden"&&H.push(t.tile);const r=t.worldMatrix;t.texture&&(t.program.uniforms.baseTexture.value=t.texture,t.program.uniforms.opacity.value=t.opacity);const i=t.program.uniforms;i.roofTexture&&(i.roofTexture.value=e._roofRaster?.texture||u.roofFallbackTexture);const c=r[0]*(r[5]*r[10]-r[6]*r[9])-r[4]*(r[1]*r[10]-r[2]*r[9])+r[8]*(r[1]*r[6]-r[2]*r[5]);if(!Number.isFinite(c)||c===0)throw new Error("Singular 3D transform");const a=c<0?"cw":"ccw",l=t.program;l.transparent&&l._layerMaterial.doubleSided?(e._drawGeometry(t,R,"front",a),e._drawGeometry(t,R,"back",a)):e._drawGeometry(t,R,l.cullMode,a)}R.end(),u.device.queue.writeBuffer(u.uniformBuffer,0,u.uniformData,0,u.uniformSlot*64),u.device.queue.submit([Y.finish()]),H.length&&u.device.queue.onSubmittedWorkDone().then(()=>{for(const t of H)t.isConnected&&t._terrainVisibility!==void 0&&(t.style.visibility="hidden")},t=>{for(const r of e._layers||[])r.fire("error",{error:t})}),s._animatingZoom&&e.update()}export{ye as endZoom,he as getTileLevel,xe as onMapChange,_e as render,de as startZoom,ge as update};
15
- //# sourceMappingURL=render.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/render.js"],
4
- "sourcesContent": ["import { computeBounds } from '../utils/geometry.js';\nimport { traverse, updateWorldMatrix, updateCamera } from '../utils/scene.js';\n\n/** Scene graph, shared camera and frame rendering. */\n/** Content changes: render once on the next animation frame. */\nexport function update(backend) {\n const shared = backend._shared;\n if (!shared) return backend;\n if (shared !== backend) {\n shared.update();\n return backend;\n }\n backend._frame ||= requestAnimationFrame(() => {\n backend._frame = null;\n if (backend._shared === backend && backend.renderer) backend._render();\n });\n return backend;\n}\n\n/** Map movement: render within the frame of Leaflet's CSS transforms, coalescing same-tick events. */\nexport function onMapChange(backend) {\n if (backend._queued) return;\n backend._queued = true;\n queueMicrotask(() => {\n backend._queued = false;\n if (backend._shared !== backend || !backend.renderer) return;\n if (backend._map._animatingZoom) backend.update();\n else backend._render();\n });\n}\n\n/** Find a raster tile's active CSS level to reproduce Leaflet's animated scale/rounding. */\nexport function getTileLevel(backend) {\n let level;\n backend._map.eachLayer(layer => {\n if (!level && layer instanceof L.TileLayer && layer._levels) {\n level = layer._levels[layer._tileZoom];\n }\n });\n return level;\n}\n\n/** Preserve the outgoing tile level before Leaflet changes its logical zoom. */\nexport function startZoom(backend) {\n backend._zoomLevel = backend._getTileLevel();\n}\n\n/** Stop using the outgoing level after zoomend; the next redraw uses current tiles. */\nexport function endZoom(backend) {\n for (const animation of backend._zoomTransitions?.keys() || []) animation.finish();\n backend._zoomTransitions = null;\n backend._zoomLevel = null;\n backend.update();\n}\n\n/**\n * Rendering owner: CSS pixels -> scene metres -> perspective camera.\n * Lights and transparent sort centers are converted into the current camera space.\n * Without raster tiles, logical map projection supplies the same static alignment.\n */\nexport function render(backend) {\n cancelAnimationFrame(backend._frame);\n backend._frame = null;\n if (backend._shared !== backend || !backend.renderer) return;\n const map = backend._map;\n const size = map.getSize();\n if (!size.x || !size.y) return;\n if (map._animatingZoom) {\n backend._zoomTransitions ||= new Map();\n const now = performance.now();\n for (const animation of map.getContainer().getAnimations({ subtree: true })) {\n if (!(animation instanceof CSSTransition) || animation.transitionProperty !== 'transform' ||\n !animation.effect.target.classList.contains('leaflet-zoom-animated') ||\n backend._zoomTransitions.has(animation)\n ) {\n continue;\n }\n const time = animation.currentTime || 0;\n animation.pause();\n backend._zoomTransitions.set(animation, { start: now, time });\n }\n // Freeze CSS between rendered frames: the compositor must not outrun the canvas.\n for (const [animation, { start, time }] of backend._zoomTransitions) {\n animation.currentTime = Math.min(animation.effect.getComputedTiming().endTime, time + now - start);\n }\n }\n if (!backend._size || !backend._size.equals(size)) {\n backend.renderer.width = size.x;\n backend.renderer.height = size.y;\n backend.renderer.canvas.width = Math.round(size.x * backend.renderer.dpr);\n backend.renderer.canvas.height = Math.round(size.y * backend.renderer.dpr);\n backend.renderer.canvas.style.width = `${size.x}px`;\n backend.renderer.canvas.style.height = `${size.y}px`;\n if (backend.renderer.depthTexture) backend._destroyTexture(backend.renderer.depthTexture);\n backend.renderer.depthTexture = backend.renderer.device.createTexture({\n size: [backend.renderer.canvas.width, backend.renderer.canvas.height],\n format: 'depth24plus',\n usage: GPUTextureUsage.RENDER_ATTACHMENT,\n });\n backend._size = size;\n }\n\n // Match the map's CSS camera: a perspective distance of 1.5 viewport heights.\n let pixelsPerMeter = map.options.crs.scale(map.getZoom()) / (40075016.68557849 * Math.cos(backend._sceneOrigin.lat * Math.PI / 180));\n let origin = map.project(backend._sceneOrigin).subtract(map.getPixelOrigin());\n const level = backend._zoomLevel?.el.isConnected ? backend._zoomLevel : backend._getTileLevel();\n if (level && map._animatingZoom) {\n backend._zoomLevel = level;\n }\n // Leaflet's logical zoom jumps before its tile CSS transition finishes.\n // Use the rendered tile transform, including its rounding, on every animation frame.\n if (level) {\n const transform = new DOMMatrix(map._animatingZoom ? getComputedStyle(level.el).transform : level.el.style.transform);\n const point = map.project(backend._sceneOrigin, level.zoom).subtract(level.origin);\n origin = new L.Point(point.x * transform.a + transform.e, point.y * transform.d + transform.f);\n pixelsPerMeter *= map.getZoomScale(level.zoom, map.getZoom()) * transform.a;\n }\n const distance = size.y * 1.5 / pixelsPerMeter;\n const center = map.containerPointToLayerPoint(size.divideBy(2));\n const target = [\n (center.x - origin.x) / pixelsPerMeter,\n map._terrain3D?._getElevation(map.getCenter()) ?? 0,\n (center.y - origin.y) / pixelsPerMeter\n ];\n const pitch = map.getPitch() * Math.PI / 180;\n const bearing = map.getBearing() * Math.PI / 180;\n const camera = backend.camera;\n camera.fov = 2 * Math.atan(1 / 3) * 180 / Math.PI;\n camera.aspect = size.x / size.y;\n camera.near = Math.max(0.1, distance / 10000);\n camera.far = Math.max(10000, distance * 10);\n camera.position[0] = target[0] + Math.sin(bearing) * Math.sin(pitch) * distance;\n camera.position[1] = target[1] + Math.cos(pitch) * distance;\n camera.position[2] = target[2] + Math.cos(bearing) * Math.sin(pitch) * distance;\n camera.up[0] = -Math.sin(bearing) * Math.cos(pitch);\n camera.up[1] = Math.sin(pitch);\n camera.up[2] = -Math.cos(bearing) * Math.cos(pitch);\n camera.target[0] = target[0]; camera.target[1] = target[1]; camera.target[2] = target[2];\n // Refresh the camera view, projection and combined projection-view matrices.\n updateCamera(camera);\n const sunlight = map._sunlight;\n const lightPoint = new DOMPoint(...(sunlight?.direction || [-300, 500, 300]), 0).matrixTransform(new DOMMatrix(camera.viewMatrix));\n const lightLength = Math.hypot(lightPoint.x, lightPoint.y, lightPoint.z) || 1;\n const light = [lightPoint.x / lightLength, lightPoint.y / lightLength, lightPoint.z / lightLength];\n const skyPoint = new DOMPoint(0, 1, 0, 0).matrixTransform(new DOMMatrix(camera.viewMatrix));\n const skyLength = Math.hypot(skyPoint.x, skyPoint.y, skyPoint.z) || 1;\n const sky = [skyPoint.x / skyLength, skyPoint.y / skyLength, skyPoint.z / skyLength];\n const projection = camera.projectionViewMatrix;\n const frustum = [\n [projection[3] + projection[0], projection[7] + projection[4], projection[11] + projection[8], projection[15] + projection[12]],\n [projection[3] - projection[0], projection[7] - projection[4], projection[11] - projection[8], projection[15] - projection[12]],\n [projection[3] + projection[1], projection[7] + projection[5], projection[11] + projection[9], projection[15] + projection[13]],\n [projection[3] - projection[1], projection[7] - projection[5], projection[11] - projection[9], projection[15] - projection[13]],\n [projection[2], projection[6], projection[10], projection[14]],\n [projection[3] - projection[2], projection[7] - projection[6], projection[11] - projection[10], projection[15] - projection[14]],\n ];\n const frustumLengths = [\n Math.hypot(frustum[0][0], frustum[0][1], frustum[0][2]),\n Math.hypot(frustum[1][0], frustum[1][1], frustum[1][2]),\n Math.hypot(frustum[2][0], frustum[2][1], frustum[2][2]),\n Math.hypot(frustum[3][0], frustum[3][1], frustum[3][2]),\n Math.hypot(frustum[4][0], frustum[4][1], frustum[4][2]),\n Math.hypot(frustum[5][0], frustum[5][1], frustum[5][2]),\n ];\n updateWorldMatrix(backend.scene);\n traverse(backend.scene, mesh => {\n if (!mesh.visible) return true;\n if (mesh.geometry) {\n if (!mesh.geometry.bounds) computeBounds(mesh.geometry);\n const bounds = mesh.geometry.bounds;\n const world = mesh.worldMatrix;\n const center = bounds.center;\n const x = world[0] * center[0] + world[4] * center[1] + world[8] * center[2] + world[12];\n const y = world[1] * center[0] + world[5] * center[1] + world[9] * center[2] + world[13];\n const z = world[2] * center[0] + world[6] * center[1] + world[10] * center[2] + world[14];\n const radius = bounds.radius * Math.max(\n Math.hypot(world[0], world[1], world[2]),\n Math.hypot(world[4], world[5], world[6]),\n Math.hypot(world[8], world[9], world[10])\n );\n mesh._visibleInFrame =\n frustum[0][0] * x + frustum[0][1] * y + frustum[0][2] * z + frustum[0][3] >= -radius * frustumLengths[0] &&\n frustum[1][0] * x + frustum[1][1] * y + frustum[1][2] * z + frustum[1][3] >= -radius * frustumLengths[1] &&\n frustum[2][0] * x + frustum[2][1] * y + frustum[2][2] * z + frustum[2][3] >= -radius * frustumLengths[2] &&\n frustum[3][0] * x + frustum[3][1] * y + frustum[3][2] * z + frustum[3][3] >= -radius * frustumLengths[3] &&\n frustum[4][0] * x + frustum[4][1] * y + frustum[4][2] * z + frustum[4][3] >= -radius * frustumLengths[4] &&\n frustum[5][0] * x + frustum[5][1] * y + frustum[5][2] * z + frustum[5][3] >= -radius * frustumLengths[5];\n if (!mesh._visibleInFrame) return;\n }\n if (mesh.program?.transparent) {\n if (!mesh.geometry.bounds) computeBounds(mesh.geometry);\n const center = mesh.geometry.bounds.center, world = mesh.worldMatrix;\n const x = world[0] * center[0] + world[4] * center[1] + world[8] * center[2] + world[12];\n const y = world[1] * center[0] + world[5] * center[1] + world[9] * center[2] + world[13];\n const z = world[2] * center[0] + world[6] * center[1] + world[10] * center[2] + world[14];\n const projection = camera.projectionViewMatrix;\n const clipZ = projection[2] * x + projection[6] * y + projection[10] * z + projection[14];\n const clipW = projection[3] * x + projection[7] * y + projection[11] * z + projection[15];\n mesh._sortDepth = clipZ / clipW;\n }\n });\n const renderer = backend.renderer;\n if ([...backend._layers].some(layer => layer.options.roofTexture)) {\n const rasters = Object.values(map._layers).filter(layer =>\n layer instanceof L.Layer.types.pmtiles && layer._tiles && layer.options.opacity > 0);\n const tiles = rasters.flatMap(layer => Object.values(layer._tiles)\n .filter(tile => tile.el.done && !tile.el.request.signal.aborted && tile.el.isConnected)\n .map(tile => ({ ...tile, layer })));\n const signature = tiles.map(({ el, coords, layer }) =>\n `${L.Util.stamp(el)}:${coords.z}:${coords.x}:${coords.y}:${layer.options.opacity}:${layer.options.zIndex}`).join('|');\n const selection = rasters.map(layer =>\n `${L.Util.stamp(layer)}:${layer.options.opacity}:${layer.options.zIndex}`).join('|');\n // Retain the geographically aligned atlas until a tile batch finishes loading.\n if (!backend._roofRaster || backend._roofRaster.selection !== selection ||\n (!rasters.some(layer => layer.isLoading()) && backend._roofRaster.signature !== signature)) {\n const zoom = tiles.length ? Math.max(...tiles.map(tile => tile.coords.z)) : map.getZoom();\n const bounds = new L.Bounds();\n for (const { coords, layer } of tiles) {\n const size = layer.getTileSize().multiplyBy(map.getZoomScale(zoom, coords.z));\n bounds.extend(new L.Point(coords.x, coords.y).scaleBy(size));\n bounds.extend(new L.Point(coords.x + 1, coords.y + 1).scaleBy(size));\n }\n const min = bounds.min || map.project(backend._sceneOrigin, zoom);\n const size = bounds.isValid() ? bounds.getSize() : new L.Point(1, 1);\n // ponytail: cap at 4096 px; virtual textures if wide views need native detail.\n const limit = 4096;\n const scale = Math.min(1, limit / Math.max(size.x, size.y));\n const width = Math.max(1, Math.ceil(size.x * scale));\n const height = Math.max(1, Math.ceil(size.y * scale));\n const origin = map.project(backend._sceneOrigin, zoom);\n const pixels = map.options.crs.scale(zoom) / (40075016.68557849 * Math.cos(backend._sceneOrigin.lat * Math.PI / 180));\n const matrix = new DOMMatrix();\n matrix.m11 = pixels / size.x; matrix.m33 = pixels / size.y;\n matrix.m41 = (origin.x - min.x) / size.x; matrix.m43 = (origin.y - min.y) / size.y;\n const texture = backend._roofRaster?.texture;\n if (texture && (texture.width !== width || texture.height !== height)) {\n backend._destroyTexture(texture.texture);\n texture.texture = renderer.device.createTexture({\n size: [width, height],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n });\n texture.width = width;\n texture.height = height;\n }\n backend._roofRaster = {\n signature, selection, matrix: Array.from(matrix.toFloat64Array()),\n texture: texture || {\n device: renderer.device,\n texture: renderer.device.createTexture({\n size: [width, height],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n sampler: renderer.device.createSampler({\n addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge',\n }),\n samplerOptions: { addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge' },\n image: null, width, height,\n format: 'rgba8unorm', srgb: false, flipY: false, uploaded: null,\n },\n };\n // Compose the atlas on the GPU: re-uploading a large canvas stalls Firefox for hundreds of ms.\n const device = renderer.device;\n if (!renderer.roofBlit) {\n const module = device.createShaderModule({ code: `\n @group(0) @binding(0) var source: texture_2d<f32>;\n @group(0) @binding(1) var sourceSampler: sampler;\n @group(0) @binding(2) var<uniform> opacity: f32;\n struct Varyings { @builtin(position) position: vec4f, @location(0) uv: vec2f };\n @vertex fn vertexMain(@builtin(vertex_index) index: u32) -> Varyings {\n let uv = vec2f(f32(index & 1u), f32(index >> 1u));\n return Varyings(vec4f(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, 0.0, 1.0), uv);\n }\n @fragment fn fragmentMain(input: Varyings) -> @location(0) vec4f {\n let color = textureSample(source, sourceSampler, input.uv);\n return vec4f(color.rgb, color.a * opacity);\n }\n ` });\n renderer.roofBlit = {\n pipeline: device.createRenderPipeline({\n layout: 'auto',\n vertex: { module, entryPoint: 'vertexMain' },\n fragment: {\n module,\n entryPoint: 'fragmentMain',\n targets: [{\n format: 'rgba8unorm',\n blend: {\n color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' },\n },\n }],\n },\n primitive: { topology: 'triangle-strip' },\n }),\n sampler: device.createSampler({ magFilter: 'linear', minFilter: 'linear' }),\n };\n }\n // Raster tiles keep their GPU copy; terrain meshes already own one for the same image.\n const roofTiles = backend._roofTiles ||= new Map();\n for (const [el, source] of roofTiles) {\n if (!tiles.some(tile => tile.el === el) || map._terrain3D?._rasterTiles.has(el)) {\n source.texture.destroy();\n roofTiles.delete(el);\n }\n }\n const opacities = new Float32Array(Math.max(1, tiles.length) * 64);\n const opacityBuffer = device.createBuffer({\n size: opacities.byteLength,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n const encoder = device.createCommandEncoder();\n const atlasPass = encoder.beginRenderPass({\n colorAttachments: [{\n view: backend._roofRaster.texture.texture.createView(),\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n loadOp: 'clear',\n storeOp: 'store',\n }],\n });\n atlasPass.setPipeline(renderer.roofBlit.pipeline);\n tiles.sort((a, b) => (a.layer.options.zIndex || 0) - (b.layer.options.zIndex || 0) || a.coords.z - b.coords.z);\n for (const [i, { coords, el, layer }] of tiles.entries()) {\n let source = map._terrain3D?._rasterTiles.get(el)?.texture || roofTiles.get(el);\n if (!source) {\n source = {\n texture: device.createTexture({\n size: [el.naturalWidth, el.naturalHeight],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n image: el, uploaded: null,\n };\n roofTiles.set(el, source);\n }\n if (source.uploaded !== source.image) {\n device.queue.copyExternalImageToTexture({ source: el }, { texture: source.texture },\n [source.texture.width, source.texture.height]);\n source.uploaded = source.image;\n }\n opacities[i * 64] = layer.options.opacity;\n const tileSize = layer.getTileSize().multiplyBy(map.getZoomScale(zoom, coords.z));\n const offset = new L.Point(coords.x, coords.y).scaleBy(tileSize).subtract(min);\n const x = offset.x * width / size.x, y = offset.y * height / size.y;\n atlasPass.setViewport(x, y, Math.min(tileSize.x * width / size.x, width - x),\n Math.min(tileSize.y * height / size.y, height - y), 0, 1);\n atlasPass.setBindGroup(0, device.createBindGroup({\n layout: renderer.roofBlit.pipeline.getBindGroupLayout(0),\n entries: [\n { binding: 0, resource: source.texture.createView() },\n { binding: 1, resource: renderer.roofBlit.sampler },\n { binding: 2, resource: { buffer: opacityBuffer, offset: i * 256, size: 4 } },\n ],\n }));\n atlasPass.draw(4);\n }\n atlasPass.end();\n device.queue.writeBuffer(opacityBuffer, 0, opacities);\n device.queue.submit([encoder.finish()]);\n opacityBuffer.destroy();\n }\n } else if (backend._roofRaster) {\n backend._destroyTexture(backend._roofRaster.texture.texture);\n backend._roofRaster = null;\n for (const source of backend._roofTiles?.values() || []) source.texture.destroy();\n backend._roofTiles = null;\n }\n // Visible meshes: opaque first, transparent surfaces back-to-front.\n const meshes = [];\n traverse(backend.scene, mesh => { if (!mesh.visible) return true; if (mesh.geometry && mesh._visibleInFrame) meshes.push(mesh); });\n meshes.sort((a, b) => Number(a.program.transparent) - Number(b.program.transparent) ||\n (a.program.transparent\n ? (a.renderOrder || 0) - (b.renderOrder || 0) ||\n b._sortDepth - a._sortDepth || a.id - b.id\n : a.id - b.id)\n );\n const encoder = renderer.device.createCommandEncoder();\n const pendingRasterTiles = [];\n // One uniform upload per frame: per-mesh writeBuffer calls dominate Firefox's GPU process.\n // Slot 0 holds the camera; 256-byte mesh slots follow (double-sided meshes use two).\n const shadowMeshes = [];\n if (sunlight?.altitude >= 3) {\n for (const layer of backend._layers) {\n if (layer instanceof L.Layer.types.terrain) continue;\n traverse(layer.root, mesh => {\n if (!mesh.visible) return true;\n if (mesh.geometry && !mesh.tile && !mesh.program.nightLight && mesh.program.depthTest !== false) shadowMeshes.push(mesh);\n });\n }\n }\n if (!renderer.uniformBuffer || renderer.uniformBuffer.size < (meshes.length * 2 + shadowMeshes.length + 1) * 256) {\n if (renderer.uniformBuffer) backend._destroyTexture(renderer.uniformBuffer);\n renderer.uniformBuffer = renderer.device.createBuffer({\n size: Math.max(64, meshes.length * 4 + shadowMeshes.length * 2) * 256,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,\n });\n renderer.uniformData = new Float32Array(renderer.uniformBuffer.size / 4);\n }\n const frameData = renderer.uniformData;\n frameData.set(camera.viewMatrix, 0);\n frameData.set(camera.projectionMatrix, 16);\n frameData.set(backend._roofRaster?.matrix || [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 32);\n frameData.set(light, 48);\n frameData[51] = sunlight && sunlight.altitude <= 0 ? 0 : 1;\n frameData.set(sky, 52);\n const night = sunlight ? Math.max(0, Math.min(1, (3 - sunlight.altitude) / 9)) : 0;\n frameData[55] = night * night * (3 - 2 * night);\n frameData.set(sunlight?.tint || [1, 1, 1], 56);\n frameData[59] = 0;\n if (night > 0) backend._updatePointLights();\n renderer.uniformSlot = 1;\n backend._renderSunlight(encoder, shadowMeshes, sunlight);\n const pass = encoder.beginRenderPass({\n colorAttachments: [{\n view: renderer.context.getCurrentTexture().createView(),\n clearValue: { r: 0, g: 0, b: 0, a: 0 },\n loadOp: 'clear',\n storeOp: 'store',\n }],\n depthStencilAttachment: {\n view: renderer.depthTexture.createView(),\n depthClearValue: 1,\n depthLoadOp: 'clear',\n depthStoreOp: 'store',\n },\n });\n pass.setViewport(0, 0, renderer.canvas.width, renderer.canvas.height, 0, 1);\n pass.setBindGroup(1, renderer.sunlight.bindGroup);\n for (const mesh of meshes) {\n if (mesh.tile && mesh.tile.style.visibility !== 'hidden') pendingRasterTiles.push(mesh.tile);\n const world = mesh.worldMatrix;\n if (mesh.texture) {\n mesh.program.uniforms.baseTexture.value = mesh.texture;\n mesh.program.uniforms.opacity.value = mesh.opacity;\n }\n const uniforms = mesh.program.uniforms;\n if (uniforms.roofTexture) uniforms.roofTexture.value = backend._roofRaster?.texture || renderer.roofFallbackTexture;\n const determinant = world[0] * (world[5] * world[10] - world[6] * world[9]) -\n world[4] * (world[1] * world[10] - world[2] * world[9]) +\n world[8] * (world[1] * world[6] - world[2] * world[5]);\n if (!Number.isFinite(determinant) || determinant === 0) {\n throw new Error('Singular 3D transform');\n }\n const frontFace = determinant < 0 ? 'cw' : 'ccw';\n const program = mesh.program;\n if (program.transparent && program._layerMaterial.doubleSided) {\n backend._drawGeometry(mesh, pass, 'front', frontFace);\n backend._drawGeometry(mesh, pass, 'back', frontFace);\n } else {\n backend._drawGeometry(mesh, pass, program.cullMode, frontFace);\n }\n }\n pass.end();\n renderer.device.queue.writeBuffer(renderer.uniformBuffer, 0, renderer.uniformData, 0, renderer.uniformSlot * 64);\n renderer.device.queue.submit([encoder.finish()]);\n if (pendingRasterTiles.length) {\n renderer.device.queue.onSubmittedWorkDone().then(() => {\n for (const tile of pendingRasterTiles) {\n if (tile.isConnected && tile._terrainVisibility !== undefined) tile.style.visibility = 'hidden';\n }\n }, error => {\n for (const layer of backend._layers || []) layer.fire('error', { error });\n });\n }\n if (map._animatingZoom) backend.update();\n}\n"],
5
- "mappings": "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",
6
- "names": ["computeBounds", "traverse", "updateWorldMatrix", "updateCamera", "update", "backend", "shared", "onMapChange", "getTileLevel", "level", "layer", "startZoom", "endZoom", "animation", "render", "map", "size", "now", "time", "start", "pixelsPerMeter", "origin", "transform", "point", "distance", "center", "target", "pitch", "bearing", "camera", "sunlight", "lightPoint", "lightLength", "light", "skyPoint", "skyLength", "sky", "projection", "frustum", "frustumLengths", "mesh", "bounds", "world", "x", "y", "z", "radius", "clipZ", "clipW", "renderer", "rasters", "tiles", "tile", "signature", "el", "coords", "selection", "zoom", "min", "scale", "width", "height", "pixels", "matrix", "texture", "device", "module", "roofTiles", "source", "opacities", "opacityBuffer", "encoder", "atlasPass", "a", "b", "i", "tileSize", "offset", "meshes", "pendingRasterTiles", "shadowMeshes", "frameData", "night", "pass", "uniforms", "determinant", "frontFace", "program", "error"]
7
- }
@@ -1,2 +0,0 @@
1
- import{parseColor as Y,triangulate as K,isClockWise as Q,treeGeometry as b,lightGeometry as k,lampPostGeometry as tt}from"../utils/geometry.js";import{emptyNode as et}from"../utils/scene.js";function it(t){if(t._map){for(const e of t._areas.values())t._releaseArea(e);t._areas.clear(),t._updateArea()}}function st(t){if(!t._map||!t.header)return;const e=t.header.minZoom,o=t._map.project(t._map.getCenter(),e).divideBy(256).floor(),n=t._map.getBounds(),O=t._map.project(n.getNorthWest(),e).divideBy(256).floor(),m=t._map.project(n.getSouthEast(),e).divideBy(256).floor(),G=t._map.project([t.header.maxLat,t.header.minLon],e).divideBy(256).floor(),P=t._map.project([t.header.minLat,t.header.maxLon],e).divideBy(256).floor(),A=new Map;for(let f=Math.max(0,O.x-1,G.x);f<=Math.min(2**e-1,m.x+1,P.x);f++)for(let y=Math.max(0,O.y-1,G.y);y<=Math.min(2**e-1,m.y+1,P.y);y++)A.set(`${f}/${y}`,{z:e,x:f,y});for(const[f,y]of t._areas)A.has(f)||(t._releaseArea(y),t._areas.delete(f));for(const[f,y]of[...A].sort(([,q],[,B])=>Math.hypot(q.x-o.x,q.y-o.y)-Math.hypot(B.x-o.x,B.y-o.y)))t._areas.has(f)||t._areas.set(f,{coords:y,request:new AbortController});t._pump()}async function nt(t,e){const{z:o,x:n,y:O}=e.coords,m=await t.getZxy(o,n,O,e.request.signal);return m?JSON.parse(new TextDecoder().decode(m.data)):{type:"FeatureCollection",features:[]}}function at(t){if(!(!t._map||!t._shared)){for(const e of t._areas.values()){if(t._inflight>=2)break;e.started||(e.started=!0,t._inflight++,(async()=>{try{const o=e.coords,n=await t._loadSource(e);if(e.request.signal.aborted)return;if(n?.type!=="FeatureCollection"||!Array.isArray(n.features))throw new Error("Invalid GeoJSON response");const O=n.features,m=[],G=[],P=[],A=[],f=[],y=[],q=new Set;let B=0;const U=t._map,R=U.options.crs,I=R.project(t.location),J=Math.cos(t.location.lat*Math.PI/180),$=i=>i.ground||0,S=(i,r,h,E,g,w,s,l,p,c)=>{const d=h.x-i.x,C=E-r,z=i.y-h.y,x=g.x-i.x,_=w-r,a=i.y-g.y;if((C*a-z*_)*s+(z*x-d*a)*l+(d*_-C*x)*p<0){const u=h,v=E;h=g,E=w,g=u,w=v}m.push(i.x,r+$(i),-i.y,h.x,E+$(h),-h.y,g.x,w+$(g),-g.y),G.push(s,l,p,s,l,p,s,l,p),P.push(c.r,c.g,c.b,c.r,c.g,c.b,c.r,c.g,c.b),t.options.nightLight&&A.push(...i.uv,...h.uv,...g.uv)};let Z=performance.now()+8;for(const i of O){if(e.request.signal.aborted)return;if(performance.now()>=Z){if(await new Promise(requestAnimationFrame),e.request.signal.aborted)return;Z=performance.now()+8}const r=i?.geometry,h=r?.type==="Point";if(t.options.nightLight&&!h)throw new Error("Night lights require Point geometry");const E=r?.type==="Polygon"?[r.coordinates]:r?.type==="MultiPolygon"?r.coordinates:null;if(!E&&!h)throw new Error("Unsupported GeoJSON geometry");const[g,w]=(h?r.coordinates:E[0]?.[0]?.[0])??[];if(!Number.isFinite(g)||!Number.isFinite(w))throw new Error("Invalid GeoJSON coordinates");if(o){const x=U.project(new L.LatLng(w,g),o.z);if(Math.floor(x.x/256)!==o.x||Math.floor(x.y/256)!==o.y)continue}const s=t.options.featureStyle(i);if(s===null){B++;continue}if(!s||typeof s!="object")throw new Error("featureStyle must return an extrusion style or null");const{top:l,bottom:p=0,color:c=14267276}=s;if(!Number.isFinite(l)||!Number.isFinite(p)||p<0||l<=p)throw new Error("Invalid extrusion heights: expected top > bottom >= 0");const d=Y(c),C=m.length/3;if(h){const x=R.project(new L.LatLng(w,g)),_=U._terrain3D?._getElevation([w,g]),a={x:(x.x-I.x)*J,y:(x.y-I.y)*J,ground:Number.isFinite(_)&&Number.isFinite(t.root.position[1])?_-t.root.position[1]:0};if(t.options.nightLight){if(!Number.isFinite(s.lightFlux)||s.lightFlux<=0)throw new Error("Invalid light flux");const u=i.properties?.cod_ouvrag||`${g},${w}`;s.poleRadius>0&&!q.has(u)&&(tt(a,s,S),q.add(u)),k(a,s,S),y.push({position:[a.x,a.ground+l,-a.y],radius:Math.hypot(l,s.lightRadius),color:[d.r,d.g,d.b],flux:s.lightFlux})}else b(a,s,S)}for(const x of E||[]){if(!x.length)throw new Error("Empty GeoJSON polygon");const _=x.map(u=>{if(u.length<4)throw new Error("Invalid GeoJSON polygon ring");return u.slice(0,-1).map(([v,N])=>{if(!Number.isFinite(v)||!Number.isFinite(N))throw new Error("Invalid GeoJSON coordinates");const j=R.project(new L.LatLng(N,v)),F=t._map._terrain3D?._getElevation([N,v]);return{x:(j.x-I.x)*J,y:(j.y-I.y)*J,ground:Number.isFinite(F)&&Number.isFinite(t.root.position[1])?F-t.root.position[1]:0}})}),a=_.flat();for(const[u,v,N]of K(_[0],_.slice(1)))S(a[u],l,a[v],l,a[N],l,0,1,0,d),p>0&&S(a[u],p,a[v],p,a[N],p,0,-1,0,d);_.forEach((u,v)=>{const N=Q(u)===(v===0)?-1:1;for(let j=0;j<u.length;j++){const F=u[j],M=u[(j+1)%u.length],W=Math.hypot(M.x-F.x,M.y-F.y);if(!W)continue;const H=N*(M.y-F.y)/W,V=N*(M.x-F.x)/W;S(F,p,M,p,M,l,H,0,V,d),S(F,p,M,l,F,l,H,0,V,d)}})}const z=m.length/3;f.push({id:i.id??i.properties?.objectid??JSON.stringify(r),properties:i.properties,baseColor:d,faceStart:C/3,faceEnd:z/3,vertexStart:C,vertexEnd:z})}if(!m.length){Object.assign(e,{mesh:null,buildings:0,skipped:B,done:!0});return}const T=t.renderer.device,D={position:{size:3,data:new Float32Array(m)},normal:{size:3,data:new Float32Array(G)},color:{size:3,data:new Float32Array(P)}};t.options.nightLight&&(D.uv={size:2,data:new Float32Array(A)});for(const[i,r]of Object.entries(D))r.count=r.data.length/r.size,r.buffer=T.createBuffer({size:Math.max(4,r.data.byteLength),usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),T.queue.writeBuffer(r.buffer,0,r.data);const X={device:T,attributes:D,drawRange:{start:0,count:D.position.count}};Object.assign(e,{mesh:{...et(),device:T,geometry:X,program:t._createProgram({vertexColors:!0,roofTexture:!!t.options.roofTexture,...t.options.nightLight?{nightLight:!0,alphaMode:"BLEND",doubleSided:!0}:{}}),id:L.Layer.types["3d"]._nextId++,renderOrder:0,extras:{featureFaces:f,lights:y}},buildings:f.length,skipped:B,done:!0}),t.add(e.mesh)}catch(o){if(e.request.signal.aborted)return;e.error=o.message,t.fire("error",{error:o})}})().finally(()=>{t._inflight--,t._pump()}))}t._updateStatus()}}function ut(t,e){if(e.request.abort(),e.mesh){t.highlightedFeature?.mesh===e.mesh&&(t._setHighlight(null),t.hoveredFeature=null,t._showFeature(null)),t.remove(e.mesh);const o=e.mesh.geometry;for(const n of Object.values(o.attributes))n.buffer.destroy();t._removeProgram(e.mesh.program)}}function lt(t,e=!0){const o={enabled:e,loaded:0,skipped:0,pending:0,errors:[]};for(const n of t._areas.values())n.error?o.errors.push(n.error):n.done||o.pending++,o.loaded+=n.buildings??0,o.skipped+=n.skipped??0;t.fire("progress",o)}export{nt as loadSource,it as onTerrainChange,at as pump,ut as releaseArea,st as updateArea,lt as updateStatus};
2
- //# sourceMappingURL=sources.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/scene/sources.js"],
4
- "sourcesContent": ["import { parseColor, triangulate, isClockWise, treeGeometry, lightGeometry, lampPostGeometry } from '../utils/geometry.js';\nimport { emptyNode } from '../utils/scene.js';\n\n/** GeoJSON source areas: loading, building and releasing. */\nexport function onTerrainChange(backend) {\n if (!backend._map) return;\n for (const area of backend._areas.values()) backend._releaseArea(area);\n backend._areas.clear();\n backend._updateArea();\n}\n\n/** Cover the visible ground bounds and one bordering block, clipped to the archive. */\nexport function updateArea(backend) {\n if (!backend._map || !backend.header) return;\n const z = backend.header.minZoom;\n const center = backend._map.project(backend._map.getCenter(), z).divideBy(256).floor();\n const bounds = backend._map.getBounds();\n const nw = backend._map.project(bounds.getNorthWest(), z).divideBy(256).floor();\n const se = backend._map.project(bounds.getSouthEast(), z).divideBy(256).floor();\n const archiveNW = backend._map.project([backend.header.maxLat, backend.header.minLon], z).divideBy(256).floor();\n const archiveSE = backend._map.project([backend.header.minLat, backend.header.maxLon], z).divideBy(256).floor();\n const wanted = new Map();\n for (let x = Math.max(0, nw.x - 1, archiveNW.x); x <= Math.min(2 ** z - 1, se.x + 1, archiveSE.x); x++) {\n for (let y = Math.max(0, nw.y - 1, archiveNW.y); y <= Math.min(2 ** z - 1, se.y + 1, archiveSE.y); y++) {\n wanted.set(`${x}/${y}`, { z, x, y });\n }\n }\n for (const [key, area] of backend._areas) {\n if (!wanted.has(key)) {\n backend._releaseArea(area);\n backend._areas.delete(key);\n }\n }\n // Load the nearest new blocks first without rebuilding retained geometry.\n for (const [key, coords] of [...wanted].sort(([, a], [, b]) =>\n Math.hypot(a.x - center.x, a.y - center.y) - Math.hypot(b.x - center.x, b.y - center.y))) {\n if (!backend._areas.has(key)) backend._areas.set(key, { coords, request: new AbortController() });\n }\n backend._pump();\n}\n\nexport async function loadSource(backend, area) {\n const { z, x, y } = area.coords;\n const result = await backend.getZxy(z, x, y, area.request.signal);\n return result ? JSON.parse(new TextDecoder().decode(result.data))\n : { type: 'FeatureCollection', features: [] };\n}\n\n/** Start at most two load/build tasks; cancelled tasks still free their slot in finally. */\nexport function pump(backend) {\n // Meshes need the shared renderer; _attach() re-runs _updateArea() once it exists.\n if (!backend._map || !backend._shared) return;\n for (const area of backend._areas.values()) {\n if (backend._inflight >= 2) break;\n if (area.started) continue;\n area.started = true;\n backend._inflight++;\n (async () => {\n try {\n const coords = area.coords;\n const data = await backend._loadSource(area);\n if (area.request.signal.aborted) return;\n if (data?.type !== 'FeatureCollection' || !Array.isArray(data.features)) {\n throw new Error('Invalid GeoJSON response');\n }\n const features = data.features;\n const positions = [], normals = [], colors = [], uvs = [], featureFaces = [], lights = [];\n const supports = new Set();\n let skipped = 0;\n const map = backend._map;\n const crs = map.options.crs;\n const origin = crs.project(backend.location);\n const metres = Math.cos(backend.location.lat * Math.PI / 180);\n const groundOffset = point => point.ground || 0;\n const addTriangle = (a, ah, b, bh, c, ch, nx, ny, nz, color) => {\n const ux = b.x - a.x, uy = bh - ah, uz = a.y - b.y;\n const vx = c.x - a.x, vy = ch - ah, vz = a.y - c.y;\n // Orient the triangle to its intended outward normal after flipping north to -z.\n if ((uy * vz - uz * vy) * nx + (uz * vx - ux * vz) * ny + (ux * vy - uy * vx) * nz < 0) {\n const point = b, height = bh;\n b = c; bh = ch; c = point; ch = height;\n }\n positions.push(a.x, ah + groundOffset(a), -a.y,\n b.x, bh + groundOffset(b), -b.y,\n c.x, ch + groundOffset(c), -c.y);\n normals.push(nx, ny, nz, nx, ny, nz, nx, ny, nz);\n colors.push(color.r, color.g, color.b, color.r, color.g, color.b, color.r, color.g, color.b);\n if (backend.options.nightLight) uvs.push(...a.uv, ...b.uv, ...c.uv);\n };\n let deadline = performance.now() + 8;\n for (const feature of features) {\n if (area.request.signal.aborted) return;\n if (performance.now() >= deadline) {\n await new Promise(requestAnimationFrame);\n if (area.request.signal.aborted) return;\n deadline = performance.now() + 8;\n }\n const geometry = feature?.geometry;\n const isTree = geometry?.type === 'Point';\n if (backend.options.nightLight && !isTree) throw new Error('Night lights require Point geometry');\n const polygons = geometry?.type === 'Polygon' ? [geometry.coordinates] : geometry?.type === 'MultiPolygon' ? geometry.coordinates : null;\n if (!polygons && !isTree) throw new Error('Unsupported GeoJSON geometry');\n const [lon, lat] = (isTree ? geometry.coordinates : polygons[0]?.[0]?.[0]) ?? [];\n if (!Number.isFinite(lon) || !Number.isFinite(lat)) throw new Error('Invalid GeoJSON coordinates');\n if (coords) {\n const anchor = map.project(new L.LatLng(lat, lon), coords.z);\n // Overlapping archive blocks may contain the same polygon; its first vertex owns it.\n if (Math.floor(anchor.x / 256) !== coords.x || Math.floor(anchor.y / 256) !== coords.y) continue;\n }\n const style = backend.options.featureStyle(feature);\n if (style === null) {\n skipped++;\n continue;\n }\n if (!style || typeof style !== 'object') throw new Error('featureStyle must return an extrusion style or null');\n const { top, bottom = 0, color = 0xd9b38c } = style;\n if (!Number.isFinite(top) || !Number.isFinite(bottom) || bottom < 0 || top <= bottom) {\n throw new Error('Invalid extrusion heights: expected top > bottom >= 0');\n }\n const baseColor = parseColor(color);\n const vertexStart = positions.length / 3;\n if (isTree) {\n const point = crs.project(new L.LatLng(lat, lon));\n const elevation = map._terrain3D?._getElevation([lat, lon]);\n const projected = {\n x: (point.x - origin.x) * metres, y: (point.y - origin.y) * metres,\n ground: Number.isFinite(elevation) && Number.isFinite(backend.root.position[1])\n ? elevation - backend.root.position[1] : 0,\n };\n if (backend.options.nightLight) {\n if (!Number.isFinite(style.lightFlux) || style.lightFlux <= 0) throw new Error('Invalid light flux');\n const support = feature.properties?.cod_ouvrag || `${lon},${lat}`;\n if (style.poleRadius > 0 && !supports.has(support)) {\n lampPostGeometry(projected, style, addTriangle);\n supports.add(support);\n }\n lightGeometry(projected, style, addTriangle);\n lights.push({\n position: [projected.x, projected.ground + top, -projected.y],\n radius: Math.hypot(top, style.lightRadius), color: [baseColor.r, baseColor.g, baseColor.b],\n flux: style.lightFlux,\n });\n } else treeGeometry(projected, style, addTriangle);\n }\n for (const rings of polygons || []) {\n if (!rings.length) throw new Error('Empty GeoJSON polygon');\n const paths = rings.map(ring => {\n if (ring.length < 4) throw new Error('Invalid GeoJSON polygon ring');\n return ring.slice(0, -1).map(([lng, lat]) => {\n if (!Number.isFinite(lng) || !Number.isFinite(lat)) throw new Error('Invalid GeoJSON coordinates');\n const point = crs.project(new L.LatLng(lat, lng));\n const elevation = backend._map._terrain3D?._getElevation([lat, lng]);\n return {\n x: (point.x - origin.x) * metres,\n y: (point.y - origin.y) * metres,\n ground: Number.isFinite(elevation) && Number.isFinite(backend.root.position[1])\n ? elevation - backend.root.position[1] : 0,\n };\n });\n });\n const points = paths.flat();\n for (const [a, b, c] of triangulate(paths[0], paths.slice(1))) {\n addTriangle(points[a], top, points[b], top, points[c], top, 0, 1, 0, baseColor);\n if (bottom > 0) addTriangle(points[a], bottom, points[b], bottom, points[c], bottom, 0, -1, 0, baseColor);\n }\n paths.forEach((path, index) => {\n // Interior walls face into the courtyard; exterior walls face away from the building.\n const sign = isClockWise(path) === (index === 0) ? -1 : 1;\n for (let i = 0; i < path.length; i++) {\n const a = path[i], b = path[(i + 1) % path.length];\n const length = Math.hypot(b.x - a.x, b.y - a.y);\n if (!length) continue;\n const nx = sign * (b.y - a.y) / length, nz = sign * (b.x - a.x) / length;\n addTriangle(a, bottom, b, bottom, b, top, nx, 0, nz, baseColor);\n addTriangle(a, bottom, b, top, a, top, nx, 0, nz, baseColor);\n }\n });\n }\n const vertexEnd = positions.length / 3;\n featureFaces.push({\n id: feature.id ?? feature.properties?.objectid ?? JSON.stringify(geometry),\n properties: feature.properties, baseColor,\n faceStart: vertexStart / 3, faceEnd: vertexEnd / 3, vertexStart, vertexEnd,\n });\n }\n if (!positions.length) {\n Object.assign(area, { mesh: null, buildings: 0, skipped, done: true });\n return;\n }\n const device = backend.renderer.device;\n const attributes = {\n position: { size: 3, data: new Float32Array(positions) },\n normal: { size: 3, data: new Float32Array(normals) },\n color: { size: 3, data: new Float32Array(colors) },\n };\n if (backend.options.nightLight) attributes.uv = { size: 2, data: new Float32Array(uvs) };\n for (const [name, attribute] of Object.entries(attributes)) {\n attribute.count = attribute.data.length / attribute.size;\n attribute.buffer = device.createBuffer({\n size: Math.max(4, attribute.data.byteLength),\n usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n });\n device.queue.writeBuffer(attribute.buffer, 0, attribute.data);\n }\n const meshGeometry = {\n device,\n attributes,\n drawRange: { start: 0, count: attributes.position.count },\n };\n Object.assign(area, {\n mesh: {\n ...emptyNode(),\n device,\n geometry: meshGeometry,\n program: backend._createProgram({ vertexColors: true, roofTexture: Boolean(backend.options.roofTexture),\n ...(backend.options.nightLight ? { nightLight: true, alphaMode: 'BLEND', doubleSided: true } : {}) }),\n id: L.Layer.types['3d']._nextId++,\n renderOrder: 0,\n extras: { featureFaces, lights },\n },\n buildings: featureFaces.length,\n skipped,\n done: true\n });\n backend.add(area.mesh);\n } catch (error) {\n if (area.request.signal.aborted) return;\n area.error = error.message;\n backend.fire('error', { error });\n }\n })().finally(() => {\n backend._inflight--;\n backend._pump();\n });\n }\n backend._updateStatus();\n}\n\n/** Cancel pending work and dispose this block's GPU data, including any hover highlight. */\nexport function releaseArea(backend, area) {\n area.request.abort();\n if (area.mesh) {\n if (backend.highlightedFeature?.mesh === area.mesh) {\n backend._setHighlight(null);\n backend.hoveredFeature = null;\n backend._showFeature(null);\n }\n backend.remove(area.mesh);\n const geometry = area.mesh.geometry;\n for (const attribute of Object.values(geometry.attributes)) attribute.buffer.destroy();\n backend._removeProgram(area.mesh.program);\n }\n}\n\n/** Emit a snapshot for consumers; ready does not wait for all neighborhood tasks. */\nexport function updateStatus(backend, enabled = true) {\n const progress = { enabled, loaded: 0, skipped: 0, pending: 0, errors: [] };\n for (const area of backend._areas.values()) {\n if (area.error) progress.errors.push(area.error);\n else if (!area.done) progress.pending++;\n progress.loaded += area.buildings ?? 0;\n progress.skipped += area.skipped ?? 0;\n }\n backend.fire('progress', progress);\n}\n"],
5
- "mappings": "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",
6
- "names": ["parseColor", "triangulate", "isClockWise", "treeGeometry", "lightGeometry", "lampPostGeometry", "emptyNode", "onTerrainChange", "backend", "area", "updateArea", "z", "center", "bounds", "nw", "se", "archiveNW", "archiveSE", "wanted", "x", "key", "coords", "a", "b", "loadSource", "y", "result", "pump", "data", "features", "positions", "normals", "colors", "uvs", "featureFaces", "lights", "supports", "skipped", "map", "crs", "origin", "metres", "groundOffset", "point", "addTriangle", "ah", "bh", "c", "ch", "nx", "ny", "nz", "color", "ux", "uy", "uz", "vx", "vy", "vz", "height", "deadline", "feature", "geometry", "isTree", "polygons", "lon", "lat", "anchor", "style", "top", "bottom", "baseColor", "vertexStart", "elevation", "projected", "support", "rings", "paths", "ring", "lng", "points", "path", "index", "sign", "i", "length", "vertexEnd", "device", "attributes", "name", "attribute", "meshGeometry", "error", "releaseArea", "updateStatus", "enabled", "progress"]
7
- }
package/dist/types/3d.js DELETED
@@ -1,2 +0,0 @@
1
- import*as s from"../utils/geometry.js";import*as n from"../scene/gpu.js";import*as l from"../scene/lighting.js";import*as p from"../scene/model.js";import*as a from"../scene/picking.js";import*as _ from"../scene/pmtiles.js";import*as m from"../utils/pmtiles.js";import*as h from"../scene/render.js";import*as d from"../utils/scene.js";import*as u from"../scene/sources.js";L.Layer.types["3d"]=L.Layer.extend({color(e){return s.parseColor(e)},_setVertexColor(e,r,t,i){return s.setVertexColor(e,r,t,i),this.update()},_triangulate(e,r){return s.triangulate(e,r)},_isClockWise(e){return s.isClockWise(e)},_treeGeometry(e,r,t){return s.treeGeometry(e,r,t)},_lightGeometry(e,r,t){return s.lightGeometry(e,r,t)},_lampPostGeometry(e,r,t){return s.lampPostGeometry(e,r,t)},_attach(e){return n.attach(this,e)},_destroyTexture(e){return n.destroyTexture(this,e)},_createProgram(e){return n.createProgram(this,e)},_removeProgram(e){return n.removeProgram(e)},_createMesh(e,r,t){return n.createMesh(this,e,r,t)},_disposeMesh(e){return n.disposeMesh(this,e)},_computeBounds(e){return s.computeBounds(e)},_drawGeometry(e,r,t,i){return n.drawGeometry(this,e,r,t,i)},_initSunlight(){return l.initSunlight(this)},_resizeSunlight(e){return l.resizeSunlight(this,e)},_bindSunlight(){return l.bindSunlight(this)},_updatePointLights(){return l.updatePointLights(this)},_renderSunlight(e,r,t){return l.renderSunlight(this,e,r,t)},_loadModel(){return p.loadModel(this)},raycast(e,r,t){return a.raycast(this,e,r,t)},_findFeature(e){return a.findFeature(this,e)},_setHighlight(e){return a.setHighlight(this,e)},_showFeature(e,r){return a.showFeature(this,e,r)},_onPointerMove(e){return a.onPointerMove(this,e)},_onClick(e){return a.onClick(this,e)},_onPointerLeave(){return a.onPointerLeave(this)},_read(e,r,t){return _.read(this,e,r,t)},_decompress(e,r){return m.decompress(e,r)},getHeader(){return _.getHeader(this)},getZxy(e,r,t,i){return _.getZxy(this,e,r,t,i)},update(){return h.update(this)},_onMapChange(){return h.onMapChange(this)},_getTileLevel(){return h.getTileLevel(this)},_startZoom(){return h.startZoom(this)},_endZoom(){return h.endZoom(this)},_render(){return h.render(this)},setParent(e,r){return d.setParent(e,r)},traverse(e,r){return d.traverse(e,r)},_updateWorldMatrix(e){return d.updateWorldMatrix(e)},_updateCamera(e){return d.updateCamera(e)},_onTerrainChange(){return u.onTerrainChange(this)},_updateArea(){return u.updateArea(this)},_pump(){return u.pump(this)},_loadSource(e){return u.loadSource(this,e)},_releaseArea(e){return u.releaseArea(this,e)},_updateStatus(e){return u.updateStatus(this,e)},statics:{_renderers:new WeakMap},options:{ariaLabel:"3D scene"},initialize(e){L.Util.setOptions(this,e);const r=!this._geojson&&/\.(glb|gltf)(?:[?#]|$)/i.test(this.options.url);this.modelUrl=r?this.options.url:null,this.url=this.options.url&&!r&&!this._geojson?new URL(this.options.url,document.baseURI).href:null,this._directories=new Map,this.options.center&&(this.location=new L.LatLng(this.options.center[0],this.options.center[1])),this._areas=new Map,this._inflight=0,this._added=Promise.withResolvers(),queueMicrotask(async()=>{try{this.root=d.emptyNode(),this.raycaster={origin:[0,0,0],direction:[0,0,0]},(this.url||this._geojson)&&(this.group=this.root,this.url&&(this.header=await this.getHeader())),this._map&&(await this._attach(this._map),this._added.resolve()),this.modelUrl&&await this._loadModel(),this._shared&&this.update(),this.fire("ready")}catch(t){this.fire("error",{error:t})}})},onAdd(e){if(!this.location){const r=e.getCenter();this.location=new L.LatLng(r.lat,r.lng)}(this.url||this._geojson||this.options.tooltipContent||this.modelUrl)&&(this.container=e.getContainer(),this.options.tooltipContent&&(this._tooltip=L.DomUtil.create("div","leaflet-3d-tooltip",this.container),this._tooltip.hidden=!0,this._tooltip.setAttribute("role","tooltip"),this._tooltip.setAttribute("aria-live","polite"),this._tooltip.style.cssText="position:absolute;z-index:600;max-width:220px;padding:10px 12px;border:1px solid #6b5140;border-radius:6px;background:#fffaf0;box-shadow:0 3px 12px #0005;color:#30251d;font:13px/1.45 sans-serif;pointer-events:none"),L.DomEvent.on(this.container,{mousemove:this._onPointerMove,click:this._onClick,mouseleave:this._onPointerLeave},this)),this.root&&this._attach(e).then(()=>this._added.resolve(),r=>this.fire("error",{error:r}))},getEvents(){return this.url?{moveend:this._updateArea,zoomend:this._updateArea,rotate:this._updateArea,pitch:this._updateArea,resize:this._updateArea,terrainchange:this._onTerrainChange}:{}},onRemove(e){this._added=Promise.withResolvers(),this.container&&(this._onPointerLeave(),L.DomEvent.off(this.container,{mousemove:this._onPointerMove,click:this._onClick,mouseleave:this._onPointerLeave},this),this.container=null);for(const t of this._areas.values())this._releaseArea(t);this._areas.clear(),this._tooltip?.remove(),this._tooltip=null,(this.url||this._geojson)&&this._updateStatus(!1);const r=this._shared;if(r){if(this.setParent(this.root,null),r._layers.delete(this),r===this)if(e.off("move zoom rotate pitch resize viewreset layeradd layerremove",this._onMapChange,this),e.off("zoomstart",this._startZoom,this),e.off("zoomanim",this.update,this),e.off("zoomend",this._endZoom,this),cancelAnimationFrame(this._frame),this._frame=null,this._queued=!1,this._layers.size){const t=this._layers.values().next().value;for(const i of["_layers","_sceneOrigin","_size","_zoomLevel","_zoomTransitions","_cursor","_roofRaster","_roofTiles"])t[i]=this[i],delete this[i];for(const i of t._layers)i._shared=t;L.Layer.types["3d"]._renderers.set(e,t),e.on("move zoom rotate pitch resize viewreset layeradd layerremove",t._onMapChange,t),e.on("zoomstart",t._startZoom,t),e.on("zoomanim",t.update,t),e.on("zoomend",t._endZoom,t),t.update()}else{this._roofRaster&&this._destroyTexture(this._roofRaster.texture.texture),this._roofRaster=null;for(const o of this._roofTiles?.values()||[])this._destroyTexture(o.texture);this._roofTiles=null;for(const o of this._zoomTransitions?.keys()||[])o.play();this._zoomTransitions=null,this.renderer.canvas.remove();const t=this.renderer,i=[t.depthTexture,t.roofFallbackTexture.texture,t.uniformBuffer,t.sunlight?.texture,t.sunlight?.buffer,t.sunlight?.lights].filter(Boolean);t.device.queue.onSubmittedWorkDone().then(()=>{for(const o of i)o.destroy();t.device.destroy()},o=>{this.fire("error",{error:o}),t.device.destroy()}),L.Layer.types["3d"]._renderers.delete(e);for(const o of["_layers","_sceneOrigin","_size","_zoomLevel","_cursor"])delete this[o]}else r.update();this._shared=null,this.renderer=this.scene=this.camera=null}},add(e){return this.setParent(e,this.root),this.update()},_setTerrainHeight(){!this.root||!this.location||(this._terrainBaseY??=this.root.position[1],this.root.position[1]=this._terrainBaseY+(this._map?._terrain3D?._getElevation(this.location)??0))},remove(e){return e===void 0?L.Layer.prototype.remove.call(this):(this.setParent(e,null),this.update())}}),L.Layer.types["3d"]._nextId=0;
2
- //# sourceMappingURL=3d.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/types/3d.js"],
4
- "sourcesContent": ["/**\n * The '3d' layer type, loaded on demand by src/index.js.\n *\n * A native WebGPU scene drawn above the map tiles and kept in sync with the map camera\n * (center, zoom, bearing, pitch and zoom animations).\n *\n * No rendering dependencies. Use the `ready` event before using the helpers.\n * All instances on one map share a canvas, scene and camera, with one group per layer.\n *\n * World coordinates are metres relative to `location`: x east, y up, z south.\n * The shared scene instead uses the first attached layer's origin. `root` converts\n * each layer's local metres into that shared space, including latitude scaling.\n *\n * Lifecycle: initialize CPU state -> attach shared GPU device -> load configured\n * data/model -> ready. Removal cancels source work and detaches this layer only;\n * the last removal destroys the context. Model CPU arrays/images survive for re-add.\n *\n * This file holds the Leaflet lifecycle and explicit delegates to scene/ operations.\n * Stateless computations live in utils/; scene/ owns loading, GPU resources and interaction.\n * PMTiles v3 reading is implemented directly by this layer. Models are static triangles, without\n * animation, skinning, morph targets, normal maps or required extensions.\n *\n * Events: ready; error {error}; progress {enabled, loaded, skipped, pending, errors};\n * featurehover/featureclick {feature, originalEvent}. A feature may be null on a miss.\n * Picking tests geometry, not texture alpha: a transparent texel can still be hit.\n *\n * @example\n * new L.Layer({ source: { url: 'tower.glb', center: [48.8582601, 2.29449985] } }).addTo(map);\n * new L.Layer({ source: { type: '3d', url: 'buildings.pmtiles', featureStyle }, attribution }).addTo(map);\n * new L.Layer({ source: { type: 'terrain', url: 'terrain.pmtiles' } }).addTo(map);\n * new L.Layer({ source: { url: 'orthophotos.pmtiles', maxZoom: 24 } }).addTo(map);\n *\n * @typedef {Object} Layer3DOptions The `source` object; `pane`/`attribution` stay standard L.Layer options.\n * @property {string} [type] 'pmtiles' (raster tiles), '3d' (WebGPU scene) or 'terrain'; see L.Layer.types.\n * @property {number[]} [center] Local origin [lat,lng]; defaults to the first map center.\n * @property {number[]} [rotation] Model Euler rotation [x,y,z] in radians, YXZ order.\n * @property {number[]} [scale] Model scale [x,y,z]; independent of geographic scaling.\n * @property {string} [url] GLB/glTF model URL (loaded before ready), or PMTiles URL containing\n * Polygon/MultiPolygon or tree/light Point GeoJSON ('3d'), raster tiles ('pmtiles') or Float32 DEM ('terrain').\n * @property {function(Object): (ExtrusionStyle|null)} [featureStyle] Source styling; null skips.\n * @property {function(PickedFeature): (Node|string)} [tooltipContent] No HTML string evaluation.\n * @property {string} [ariaLabel='3D scene'] Shared canvas accessible name.\n * @property {boolean} [nightLight=false] Point sources: emissive bulbs and local illumination.\n * @property {boolean} [nightSparkle=false] Model: sparse luminous points at night.\n *\n * @typedef {Object} ExtrusionStyle\n * @property {number} top Roof height in metres; must exceed bottom.\n * @property {number} [bottom=0] Nonnegative base height; positive values create an underside.\n * @property {number|string|Object} [color=0xd9b38c] RGB/CSS color, or linear-space {h,s,l}.\n * @property {number} [trunkRadius] Point trees: trunk radius in metres.\n * @property {number} [crownRadius] Point trees: maximum crown radius in metres.\n * @property {number} [crownBottom] Point trees: crown base in metres, between bottom and top.\n * @property {string} [crownShape='round'] Point trees: 'round' or 'cone' schematic crown.\n * @property {number|string|Object} [trunkColor=0x72513a] Point trees: bark color.\n * @property {number} [lightRadius] Point lights: estimated ground reach in metres; top is emitter height.\n * @property {number} [lightFlux] Point lights: luminous flux in lumens.\n *\n * @typedef {Object} PickedFeature\n * @property {string|number} id Source feature id or configured model URL.\n * @property {Object} properties GeoJSON properties or model-level glTF extras.\n * @property {Object} mesh Intersected mesh.\n * @property {number[]} point Intersection [x,y,z] in shared scene metres, not layer-local metres.\n * @property {Object} [model] Configured model root; absent for source polygons.\n * @property {number} [vertexStart] First polygon vertex in the batched mesh.\n * @property {number} [vertexEnd] Exclusive end of the polygon's vertex range.\n *\n * @typedef {Object} SourceArea\n * @property {Object} coords Archive block {z,x,y}; z is header.minZoom, not display zoom.\n * @property {AbortController} request Cancellation also prevents attaching obsolete results.\n * @property {boolean} [started] Enqueued work has consumed a concurrency slot.\n * @property {boolean} [done] Geometry built successfully, including empty blocks.\n * @property {Object|null} [mesh] One batched GPU mesh per non-empty block.\n * @property {number} [buildings] Emitted feature count, not number of triangles.\n * @property {number} [skipped] Features intentionally skipped by featureStyle.\n * @property {string} [error] Failed load/build message; reported through error and progress.\n *\n * @since leaflet-rotate (v0.6.0)\n */\n\nimport * as shapes from '../utils/geometry.js';\nimport * as gpu from '../scene/gpu.js';\nimport * as lighting from '../scene/lighting.js';\nimport * as model from '../scene/model.js';\nimport * as picking from '../scene/picking.js';\nimport * as pmtiles from '../scene/pmtiles.js';\nimport * as archive from '../utils/pmtiles.js';\nimport * as render from '../scene/render.js';\nimport * as graph from '../utils/scene.js';\nimport * as sources from '../scene/sources.js';\n\nL.Layer.types['3d'] = L.Layer.extend({\n color(value) { return shapes.parseColor(value); },\n _setVertexColor(mesh, start, end, color) { shapes.setVertexColor(mesh, start, end, color); return this.update(); },\n _triangulate(contour, holes) { return shapes.triangulate(contour, holes); },\n _isClockWise(points) { return shapes.isClockWise(points); },\n _treeGeometry(point, style, addTriangle) { return shapes.treeGeometry(point, style, addTriangle); },\n _lightGeometry(point, style, addTriangle) { return shapes.lightGeometry(point, style, addTriangle); },\n _lampPostGeometry(point, style, addTriangle) { return shapes.lampPostGeometry(point, style, addTriangle); },\n _attach(map) { return gpu.attach(this, map); },\n _destroyTexture(texture) { return gpu.destroyTexture(this, texture); },\n _createProgram(material) { return gpu.createProgram(this, material); },\n _removeProgram(program) { return gpu.removeProgram(program); },\n _createMesh(data, material, usage) { return gpu.createMesh(this, data, material, usage); },\n _disposeMesh(mesh) { return gpu.disposeMesh(this, mesh); },\n _computeBounds(geometry) { return shapes.computeBounds(geometry); },\n _drawGeometry(mesh, pass, cullMode, frontFace) { return gpu.drawGeometry(this, mesh, pass, cullMode, frontFace); },\n _initSunlight() { return lighting.initSunlight(this); },\n _resizeSunlight(size) { return lighting.resizeSunlight(this, size); },\n _bindSunlight() { return lighting.bindSunlight(this); },\n _updatePointLights() { return lighting.updatePointLights(this); },\n _renderSunlight(encoder, meshes, sunlight) { return lighting.renderSunlight(this, encoder, meshes, sunlight); },\n _loadModel() { return model.loadModel(this); },\n raycast(event, objects, recursive) { return picking.raycast(this, event, objects, recursive); },\n _findFeature(event) { return picking.findFeature(this, event); },\n _setHighlight(feature) { return picking.setHighlight(this, feature); },\n _showFeature(feature, event) { return picking.showFeature(this, feature, event); },\n _onPointerMove(event) { return picking.onPointerMove(this, event); },\n _onClick(event) { return picking.onClick(this, event); },\n _onPointerLeave() { return picking.onPointerLeave(this); },\n _read(offset, length, signal) { return pmtiles.read(this, offset, length, signal); },\n _decompress(data, compression) { return archive.decompress(data, compression); },\n getHeader() { return pmtiles.getHeader(this); },\n getZxy(z, x, y, signal) { return pmtiles.getZxy(this, z, x, y, signal); },\n update() { return render.update(this); },\n _onMapChange() { return render.onMapChange(this); },\n _getTileLevel() { return render.getTileLevel(this); },\n _startZoom() { return render.startZoom(this); },\n _endZoom() { return render.endZoom(this); },\n _render() { return render.render(this); },\n setParent(node, parent) { return graph.setParent(node, parent); },\n traverse(node, callback) { return graph.traverse(node, callback); },\n _updateWorldMatrix(node) { return graph.updateWorldMatrix(node); },\n _updateCamera(camera) { return graph.updateCamera(camera); },\n _onTerrainChange() { return sources.onTerrainChange(this); },\n _updateArea() { return sources.updateArea(this); },\n _pump() { return sources.pump(this); },\n _loadSource(area) { return sources.loadSource(this, area); },\n _releaseArea(area) { return sources.releaseArea(this, area); },\n _updateStatus(enabled) { return sources.updateStatus(this, enabled); },\n\n statics: {\n /** Rendering owner per map; entries are removed on the last layer removal. */\n _renderers: new WeakMap(),\n },\n\n options: {\n // Accessible description of the canvas.\n ariaLabel: '3D scene',\n },\n\n /**\n * @param {Layer3DOptions} [options] World origin comes from center or the first map centre.\n * Public state: `location` is fixed after first addition; `root` is this layer's\n * transform; `group` aliases root only for sources; `model` is the configured\n * model wrapper. `_shared` references the rendering owner (a '3d' layer);\n * `scene`, `camera` and `renderer` alias its resources while attached.\n *\n */\n initialize(options) {\n L.Util.setOptions(this, options);\n // ponytail: models are recognised by extension; extensionless model URLs need a .glb/.gltf suffix or query.\n const model = !this._geojson && /\\.(glb|gltf)(?:[?#]|$)/i.test(this.options.url);\n this.modelUrl = model ? this.options.url : null;\n this.url = this.options.url && !model && !this._geojson ? new URL(this.options.url, document.baseURI).href : null;\n this._directories = new Map();\n if (this.options.center) {\n this.location = new L.LatLng(this.options.center[0], this.options.center[1]);\n }\n /** @type {Map<string, SourceArea>} Keys are archive x/y, not screen tiles. */\n this._areas = new Map();\n // Counts pending archive/build tasks, including ones cancelled after a pan.\n this._inflight = 0;\n // Gate GPU work on attachment; replaced on removal to support delayed loads.\n this._added = Promise.withResolvers();\n // Defer initialization so callers can subscribe to ready/error after construction.\n queueMicrotask(async () => {\n try {\n this.root = graph.emptyNode();\n this.raycaster = {\n origin: [0, 0, 0],\n direction: [0, 0, 0]\n };\n if (this.url || this._geojson) {\n this.group = this.root;\n if (this.url) this.header = await this.getHeader();\n }\n if (this._map) {\n await this._attach(this._map);\n this._added.resolve();\n }\n if (this.modelUrl) await this._loadModel();\n if (this._shared) this.update();\n this.fire('ready');\n } catch (error) {\n this.fire('error', { error });\n }\n });\n },\n\n /** Attach interaction immediately; initialization may finish before or after onAdd. */\n onAdd(map) {\n if (!this.location) {\n const center = map.getCenter();\n this.location = new L.LatLng(center.lat, center.lng);\n }\n if (this.url || this._geojson || this.options.tooltipContent || this.modelUrl) {\n this.container = map.getContainer();\n if (this.options.tooltipContent) {\n this._tooltip = L.DomUtil.create('div', 'leaflet-3d-tooltip', this.container);\n this._tooltip.hidden = true;\n this._tooltip.setAttribute('role', 'tooltip');\n this._tooltip.setAttribute('aria-live', 'polite');\n this._tooltip.style.cssText = 'position:absolute;z-index:600;max-width:220px;padding:10px 12px;border:1px solid #6b5140;border-radius:6px;background:#fffaf0;box-shadow:0 3px 12px #0005;color:#30251d;font:13px/1.45 sans-serif;pointer-events:none';\n }\n L.DomEvent.on(this.container, {\n mousemove: this._onPointerMove,\n click: this._onClick,\n mouseleave: this._onPointerLeave,\n }, this);\n }\n if (this.root) {\n this._attach(map).then(() => this._added.resolve(), error => this.fire('error', { error }));\n }\n },\n\n /** Reconcile source coverage when the visible ground footprint changes. */\n getEvents() {\n return this.url ? {\n moveend: this._updateArea,\n zoomend: this._updateArea,\n rotate: this._updateArea,\n pitch: this._updateArea,\n resize: this._updateArea,\n terrainchange: this._onTerrainChange,\n } : {};\n },\n\n /** Release source meshes/UI; retain manually added objects and model CPU data. */\n onRemove(map) {\n this._added = Promise.withResolvers();\n if (this.container) {\n this._onPointerLeave();\n L.DomEvent.off(this.container, {\n mousemove: this._onPointerMove,\n click: this._onClick,\n mouseleave: this._onPointerLeave,\n }, this);\n this.container = null;\n }\n for (const area of this._areas.values()) this._releaseArea(area);\n this._areas.clear();\n this._tooltip?.remove();\n this._tooltip = null;\n if (this.url || this._geojson) this._updateStatus(false);\n const shared = this._shared;\n if (!shared) return;\n this.setParent(this.root, null);\n shared._layers.delete(this);\n if (shared === this) {\n map.off('move zoom rotate pitch resize viewreset layeradd layerremove', this._onMapChange, this);\n map.off('zoomstart', this._startZoom, this);\n map.off('zoomanim', this.update, this);\n map.off('zoomend', this._endZoom, this);\n cancelAnimationFrame(this._frame);\n this._frame = null;\n this._queued = false;\n if (this._layers.size) {\n // Keep the original scene origin and GPU resources when ownership changes.\n const next = this._layers.values().next().value;\n for (const key of ['_layers', '_sceneOrigin', '_size', '_zoomLevel', '_zoomTransitions', '_cursor', '_roofRaster', '_roofTiles']) {\n next[key] = this[key];\n delete this[key];\n }\n for (const layer of next._layers) layer._shared = next;\n L.Layer.types['3d']._renderers.set(map, next);\n map.on('move zoom rotate pitch resize viewreset layeradd layerremove', next._onMapChange, next);\n map.on('zoomstart', next._startZoom, next);\n map.on('zoomanim', next.update, next);\n map.on('zoomend', next._endZoom, next);\n next.update();\n } else {\n if (this._roofRaster) this._destroyTexture(this._roofRaster.texture.texture);\n this._roofRaster = null;\n for (const source of this._roofTiles?.values() || []) this._destroyTexture(source.texture);\n this._roofTiles = null;\n for (const animation of this._zoomTransitions?.keys() || []) animation.play();\n this._zoomTransitions = null;\n this.renderer.canvas.remove();\n const renderer = this.renderer;\n const resources = [renderer.depthTexture, renderer.roofFallbackTexture.texture, renderer.uniformBuffer,\n renderer.sunlight?.texture, renderer.sunlight?.buffer, renderer.sunlight?.lights].filter(Boolean);\n renderer.device.queue.onSubmittedWorkDone().then(() => {\n for (const resource of resources) resource.destroy();\n renderer.device.destroy();\n }, error => {\n this.fire('error', { error });\n renderer.device.destroy();\n });\n L.Layer.types['3d']._renderers.delete(map);\n for (const key of ['_layers', '_sceneOrigin', '_size', '_zoomLevel', '_cursor']) delete this[key];\n }\n } else shared.update();\n this._shared = null;\n this.renderer = this.scene = this.camera = null;\n },\n\n /**\n * Adds a scene node or mesh in layer-local coordinates and schedules a redraw.\n * Requires initialization and a compatible scene node.\n * @param {Object} object\n * @returns {L.Layer} This layer.\n */\n add(object) {\n this.setParent(object, this.root);\n return this.update();\n },\n\n _setTerrainHeight() {\n if (!this.root || !this.location) return;\n this._terrainBaseY ??= this.root.position[1];\n this.root.position[1] = this._terrainBaseY + (this._map?._terrain3D?._getElevation(this.location) ?? 0);\n },\n\n /**\n * Without an argument, removes this Leaflet layer. With an object, only detaches it:\n * geometry/program resources are not disposed, so it can be added again.\n * @param {Object} [object]\n * @returns {L.Layer}\n */\n remove(object) {\n if (object === undefined) return L.Layer.prototype.remove.call(this);\n this.setParent(object, null);\n return this.update();\n },\n});\n\nL.Layer.types['3d']._nextId = 0;\n"],
5
- "mappings": "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",
6
- "names": ["shapes", "gpu", "lighting", "model", "picking", "pmtiles", "archive", "render", "graph", "sources", "value", "mesh", "start", "end", "color", "contour", "holes", "points", "point", "style", "addTriangle", "map", "texture", "material", "program", "data", "usage", "geometry", "pass", "cullMode", "frontFace", "size", "encoder", "meshes", "sunlight", "event", "objects", "recursive", "feature", "offset", "length", "signal", "compression", "z", "x", "y", "node", "parent", "callback", "camera", "area", "enabled", "options", "error", "center", "shared", "next", "key", "layer", "source", "animation", "renderer", "resources", "resource", "object"]
7
- }
@@ -1,2 +0,0 @@
1
- import"./3d.js";L.Layer.types.geojson=L.Layer.types["3d"].extend({_geojson:!0,async _loadSource(r){const{data:e,url:t}=this.options;if(typeof this.options.featureStyle!="function")throw new Error("featureStyle must be a function");if(e!==void 0==(t!==void 0))throw new Error("GeoJSON source requires either data or url");if(e!==void 0)return e;if(typeof t!="string"||!t.trim())throw new Error("Invalid GeoJSON URL");const s=await fetch(new URL(t,document.baseURI),{signal:r.request.signal});if(!s.ok)throw new Error(`Unable to load GeoJSON: HTTP ${s.status}`);return s.json()},_updateArea(){!this._map||!this._shared||(this._areas.has("geojson")||this._areas.set("geojson",{request:new AbortController}),this._pump())},getEvents(){return{terrainchange:this._onTerrainChange}},setData(r){this.options.data=r,delete this.options.url;for(const e of this._areas.values())this._releaseArea(e);return this._areas.clear(),this._updateArea(),this}});
2
- //# sourceMappingURL=geojson.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/types/geojson.js"],
4
- "sourcesContent": ["import './3d.js';\r\n\r\n/** One GeoJSON batch, independent of the viewport, using the existing extrusion pipeline. */\r\nL.Layer.types.geojson = L.Layer.types['3d'].extend({\r\n _geojson: true,\r\n\r\n async _loadSource(area) {\r\n const { data, url } = this.options;\r\n if (typeof this.options.featureStyle !== 'function') {\r\n throw new Error('featureStyle must be a function');\r\n }\r\n if ((data !== undefined) === (url !== undefined)) {\r\n throw new Error('GeoJSON source requires either data or url');\r\n }\r\n if (data !== undefined) return data;\r\n if (typeof url !== 'string' || !url.trim()) throw new Error('Invalid GeoJSON URL');\r\n const response = await fetch(new URL(url, document.baseURI), { signal: area.request.signal });\r\n if (!response.ok) throw new Error(`Unable to load GeoJSON: HTTP ${response.status}`);\r\n return response.json();\r\n },\r\n\r\n _updateArea() {\r\n if (!this._map || !this._shared) return;\r\n if (!this._areas.has('geojson')) {\r\n this._areas.set('geojson', { request: new AbortController() });\r\n }\r\n this._pump();\r\n },\r\n\r\n getEvents() {\r\n return { terrainchange: this._onTerrainChange };\r\n },\r\n\r\n setData(data) {\r\n this.options.data = data;\r\n delete this.options.url;\r\n for (const area of this._areas.values()) this._releaseArea(area);\r\n this._areas.clear();\r\n this._updateArea();\r\n return this;\r\n },\r\n});\r\n"],
5
- "mappings": "AAAA,MAAO,UAGP,EAAE,MAAM,MAAM,QAAU,EAAE,MAAM,MAAM,IAAI,EAAE,OAAO,CACjD,SAAU,GAEV,MAAM,YAAYA,EAAM,CACtB,KAAM,CAAE,KAAAC,EAAM,IAAAC,CAAI,EAAI,KAAK,QAC3B,GAAI,OAAO,KAAK,QAAQ,cAAiB,WACvC,MAAM,IAAI,MAAM,iCAAiC,EAEnD,GAAKD,IAAS,SAAgBC,IAAQ,QACpC,MAAM,IAAI,MAAM,4CAA4C,EAE9D,GAAID,IAAS,OAAW,OAAOA,EAC/B,GAAI,OAAOC,GAAQ,UAAY,CAACA,EAAI,KAAK,EAAG,MAAM,IAAI,MAAM,qBAAqB,EACjF,MAAMC,EAAW,MAAM,MAAM,IAAI,IAAID,EAAK,SAAS,OAAO,EAAG,CAAE,OAAQF,EAAK,QAAQ,MAAO,CAAC,EAC5F,GAAI,CAACG,EAAS,GAAI,MAAM,IAAI,MAAM,gCAAgCA,EAAS,MAAM,EAAE,EACnF,OAAOA,EAAS,KAAK,CACvB,EAEA,aAAc,CACR,CAAC,KAAK,MAAQ,CAAC,KAAK,UACnB,KAAK,OAAO,IAAI,SAAS,GAC5B,KAAK,OAAO,IAAI,UAAW,CAAE,QAAS,IAAI,eAAkB,CAAC,EAE/D,KAAK,MAAM,EACb,EAEA,WAAY,CACV,MAAO,CAAE,cAAe,KAAK,gBAAiB,CAChD,EAEA,QAAQF,EAAM,CACZ,KAAK,QAAQ,KAAOA,EACpB,OAAO,KAAK,QAAQ,IACpB,UAAWD,KAAQ,KAAK,OAAO,OAAO,EAAG,KAAK,aAAaA,CAAI,EAC/D,YAAK,OAAO,MAAM,EAClB,KAAK,YAAY,EACV,IACT,CACF,CAAC",
6
- "names": ["area", "data", "url", "response"]
7
- }
@@ -1,2 +0,0 @@
1
- import"./3d.js";import{read as h,getHeader as c,getZxy as d}from"../scene/pmtiles.js";import{decompress as u}from"../utils/pmtiles.js";L.Layer.types.pmtiles=L.TileLayer.extend({_read(e,r,t){return h(this,e,r,t)},_decompress(e,r){return u(e,r)},getHeader(){return c(this)},getZxy(e,r,t,i){return d(this,e,r,t,i)},initialize(e){L.TileLayer.prototype.initialize.call(this,e.url,e),this.url=new URL(e.url,document.baseURI).href,this._directories=new Map,this.on("tileunload",this._releaseTile,this),this.on("load tileunload",()=>L.Layer.types["3d"]._renderers.get(this._map)?.update()),this.ready=Promise.resolve(this.options.archive||this).then(async r=>{const t=await r.getHeader();return this.options.archive=r,this.header=t,this.options.maxNativeZoom===void 0&&(this.options.maxNativeZoom=t.maxZoom),this.fire("ready"),this}).catch(r=>{throw this.fire("error",{error:r}),r})},onAdd(e){this.header?(L.TileLayer.prototype.onAdd.call(this,e),this._setTerrain3D(e._terrain3D)):this.ready=this.ready.then(r=>(this._map===e&&e.hasLayer(this)&&!this._container&&(L.TileLayer.prototype.onAdd.call(this,e),this._setTerrain3D(e._terrain3D)),r))},onRemove(e){this._setTerrain3D(null),this._container&&L.TileLayer.prototype.onRemove.call(this,e)},setOpacity(e){return L.TileLayer.prototype.setOpacity.call(this,e),L.Layer.types["3d"]._renderers.get(this._map)?.update(),this},setZIndex(e){return L.TileLayer.prototype.setZIndex.call(this,e),L.Layer.types["3d"]._renderers.get(this._map)?.update(),this},createTile(e,r){const t=document.createElement("img");return t.alt="",(this.options.crossOrigin||this.options.crossOrigin==="")&&(t.crossOrigin=this.options.crossOrigin===!0?"":this.options.crossOrigin),typeof this.options.referrerPolicy=="string"&&(t.referrerPolicy=this.options.referrerPolicy),t.request=new AbortController,this.ready.then(()=>{if(!t.request.signal.aborted)return this.options.archive.getZxy(e.z,e.x,e.y,t.request.signal)}).then(async i=>{if(!t.request.signal.aborted){if(!i)throw new Error(`Tile ${e.z}/${e.x}/${e.y} is not in the offline archive`);await new Promise((o,l)=>{const s=a=>{t.request.signal.removeEventListener("abort",n),t.onload=t.onerror=null,this._releaseURL(t),a?l(a):o()},n=()=>s();t.request.signal.addEventListener("abort",n,{once:!0}),t.objectURL=URL.createObjectURL(new Blob([i.data])),t.onload=()=>s(),t.onerror=()=>s(new Error(`Unable to decode tile ${e.z}/${e.x}/${e.y}`)),t.src=t.objectURL}),!t.request.signal.aborted&&(t.done=!0,this._registerTerrainTile(e,t),r(null,t))}}).catch(i=>{t.request.signal.aborted||(t.error=i.message,this._tileOnError(r,t,i))}),t},_abortLoading(){for(const{coords:e,el:r}of Object.values(this._tiles))e.z!==this._tileZoom&&this._releaseTile({tile:r});L.TileLayer.prototype._abortLoading.call(this)},_setTerrain3D(e){if(this._terrain3D!==e){for(const{el:r}of Object.values(this._tiles||{}))this._terrain3D?.removeRasterTile(r);if(this._terrain3D=e||null,this._terrain3D)for(const{coords:r,el:t}of Object.values(this._tiles||{}))t.done&&this._registerTerrainTile(r,t)}},_registerTerrainTile(e,r){if(!this._terrain3D)return;const t=this._terrain3D;t.addRasterTile(this,e,r).catch(i=>{this._terrain3D===t&&r.isConnected&&this.fire("tileerror",{tile:r,coords:e,error:i})})},_releaseURL(e){e.objectURL&&(URL.revokeObjectURL(e.objectURL),e.objectURL=null)},_releaseTile({tile:e}){this._terrain3D?.removeRasterTile(e),e.request.abort(),this._releaseURL(e)}});
2
- //# sourceMappingURL=pmtiles.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/types/pmtiles.js"],
4
- "sourcesContent": ["import './3d.js';\nimport { read, getHeader, getZxy } from '../scene/pmtiles.js';\nimport { decompress } from '../utils/pmtiles.js';\n\n/** A raster TileLayer backed by the shared PMTiles reader. */\nL.Layer.types.pmtiles = L.TileLayer.extend({\n _read(offset, length, signal) { return read(this, offset, length, signal); },\n _decompress(data, compression) { return decompress(data, compression); },\n getHeader() { return getHeader(this); },\n getZxy(z, x, y, signal) { return getZxy(this, z, x, y, signal); },\n\n initialize(options) {\n L.TileLayer.prototype.initialize.call(this, options.url, options);\n this.url = new URL(options.url, document.baseURI).href;\n this._directories = new Map();\n this.on('tileunload', this._releaseTile, this);\n this.on('load tileunload', () => L.Layer.types['3d']._renderers.get(this._map)?.update());\n this.ready = Promise.resolve(this.options.archive || this).then(async archive => {\n const header = await archive.getHeader();\n this.options.archive = archive;\n this.header = header;\n if (this.options.maxNativeZoom === undefined) this.options.maxNativeZoom = header.maxZoom;\n this.fire('ready');\n return this;\n }).catch(error => {\n this.fire('error', { error });\n throw error;\n });\n },\n\n onAdd(map) {\n if (this.header) {\n L.TileLayer.prototype.onAdd.call(this, map);\n this._setTerrain3D(map._terrain3D);\n } else {\n this.ready = this.ready.then(layer => {\n if (this._map === map && map.hasLayer(this) && !this._container) {\n L.TileLayer.prototype.onAdd.call(this, map);\n this._setTerrain3D(map._terrain3D);\n }\n return layer;\n });\n }\n },\n\n onRemove(map) {\n this._setTerrain3D(null);\n if (this._container) L.TileLayer.prototype.onRemove.call(this, map);\n },\n\n setOpacity(opacity) {\n L.TileLayer.prototype.setOpacity.call(this, opacity);\n L.Layer.types['3d']._renderers.get(this._map)?.update();\n return this;\n },\n\n setZIndex(zIndex) {\n L.TileLayer.prototype.setZIndex.call(this, zIndex);\n L.Layer.types['3d']._renderers.get(this._map)?.update();\n return this;\n },\n\n createTile(coords, done) {\n const tile = document.createElement('img');\n tile.alt = '';\n if (this.options.crossOrigin || this.options.crossOrigin === '') {\n tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;\n }\n if (typeof this.options.referrerPolicy === 'string') tile.referrerPolicy = this.options.referrerPolicy;\n tile.request = new AbortController();\n this.ready.then(() => {\n if (tile.request.signal.aborted) return;\n return this.options.archive.getZxy(coords.z, coords.x, coords.y, tile.request.signal);\n }).then(async result => {\n if (tile.request.signal.aborted) return;\n if (!result) throw new Error(`Tile ${coords.z}/${coords.x}/${coords.y} is not in the offline archive`);\n await new Promise((resolve, reject) => {\n const finish = error => {\n tile.request.signal.removeEventListener('abort', abort);\n tile.onload = tile.onerror = null;\n this._releaseURL(tile);\n if (error) reject(error);\n else resolve();\n };\n const abort = () => finish();\n tile.request.signal.addEventListener('abort', abort, { once: true });\n tile.objectURL = URL.createObjectURL(new Blob([result.data]));\n tile.onload = () => finish();\n tile.onerror = () => finish(new Error(`Unable to decode tile ${coords.z}/${coords.x}/${coords.y}`));\n tile.src = tile.objectURL;\n });\n if (tile.request.signal.aborted) return;\n tile.done = true;\n this._registerTerrainTile(coords, tile);\n done(null, tile);\n }).catch(error => {\n if (tile.request.signal.aborted) return;\n tile.error = error.message;\n this._tileOnError(done, tile, error);\n });\n return tile;\n },\n\n _abortLoading() {\n // Requests can still be pending while an image with no src reports complete.\n for (const { coords, el } of Object.values(this._tiles)) {\n if (coords.z !== this._tileZoom) this._releaseTile({ tile: el });\n }\n L.TileLayer.prototype._abortLoading.call(this);\n },\n\n _setTerrain3D(terrain) {\n if (this._terrain3D === terrain) return;\n for (const { el } of Object.values(this._tiles || {})) this._terrain3D?.removeRasterTile(el);\n this._terrain3D = terrain || null;\n if (this._terrain3D) {\n for (const { coords, el } of Object.values(this._tiles || {})) {\n if (el.done) this._registerTerrainTile(coords, el);\n }\n }\n },\n\n _registerTerrainTile(coords, tile) {\n if (!this._terrain3D) return;\n const terrain = this._terrain3D;\n terrain.addRasterTile(this, coords, tile).catch(error => {\n if (this._terrain3D === terrain && tile.isConnected) this.fire('tileerror', { tile, coords, error });\n });\n },\n\n _releaseURL(tile) {\n if (tile.objectURL) {\n URL.revokeObjectURL(tile.objectURL);\n tile.objectURL = null;\n }\n },\n\n _releaseTile({ tile }) {\n this._terrain3D?.removeRasterTile(tile);\n tile.request.abort();\n this._releaseURL(tile);\n },\n});\n"],
5
- "mappings": "AAAA,MAAO,UACP,OAAS,QAAAA,EAAM,aAAAC,EAAW,UAAAC,MAAc,sBACxC,OAAS,cAAAC,MAAkB,sBAG3B,EAAE,MAAM,MAAM,QAAU,EAAE,UAAU,OAAO,CACzC,MAAMC,EAAQC,EAAQC,EAAQ,CAAE,OAAON,EAAK,KAAMI,EAAQC,EAAQC,CAAM,CAAG,EAC3E,YAAYC,EAAMC,EAAa,CAAE,OAAOL,EAAWI,EAAMC,CAAW,CAAG,EACvE,WAAY,CAAE,OAAOP,EAAU,IAAI,CAAG,EACtC,OAAOQ,EAAGC,EAAGC,EAAGL,EAAQ,CAAE,OAAOJ,EAAO,KAAMO,EAAGC,EAAGC,EAAGL,CAAM,CAAG,EAEhE,WAAWM,EAAS,CAClB,EAAE,UAAU,UAAU,WAAW,KAAK,KAAMA,EAAQ,IAAKA,CAAO,EAChE,KAAK,IAAM,IAAI,IAAIA,EAAQ,IAAK,SAAS,OAAO,EAAE,KAClD,KAAK,aAAe,IAAI,IACxB,KAAK,GAAG,aAAc,KAAK,aAAc,IAAI,EAC7C,KAAK,GAAG,kBAAmB,IAAM,EAAE,MAAM,MAAM,IAAI,EAAE,WAAW,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,EACxF,KAAK,MAAQ,QAAQ,QAAQ,KAAK,QAAQ,SAAW,IAAI,EAAE,KAAK,MAAMC,GAAW,CAC/E,MAAMC,EAAS,MAAMD,EAAQ,UAAU,EACvC,YAAK,QAAQ,QAAUA,EACvB,KAAK,OAASC,EACV,KAAK,QAAQ,gBAAkB,SAAW,KAAK,QAAQ,cAAgBA,EAAO,SAClF,KAAK,KAAK,OAAO,EACV,IACT,CAAC,EAAE,MAAMC,GAAS,CAChB,WAAK,KAAK,QAAS,CAAE,MAAAA,CAAM,CAAC,EACtBA,CACR,CAAC,CACH,EAEA,MAAMC,EAAK,CACL,KAAK,QACP,EAAE,UAAU,UAAU,MAAM,KAAK,KAAMA,CAAG,EAC1C,KAAK,cAAcA,EAAI,UAAU,GAEjC,KAAK,MAAQ,KAAK,MAAM,KAAKC,IACvB,KAAK,OAASD,GAAOA,EAAI,SAAS,IAAI,GAAK,CAAC,KAAK,aACnD,EAAE,UAAU,UAAU,MAAM,KAAK,KAAMA,CAAG,EAC1C,KAAK,cAAcA,EAAI,UAAU,GAE5BC,EACR,CAEL,EAEA,SAASD,EAAK,CACZ,KAAK,cAAc,IAAI,EACnB,KAAK,YAAY,EAAE,UAAU,UAAU,SAAS,KAAK,KAAMA,CAAG,CACpE,EAEA,WAAWE,EAAS,CAClB,SAAE,UAAU,UAAU,WAAW,KAAK,KAAMA,CAAO,EACnD,EAAE,MAAM,MAAM,IAAI,EAAE,WAAW,IAAI,KAAK,IAAI,GAAG,OAAO,EAC/C,IACT,EAEA,UAAUC,EAAQ,CAChB,SAAE,UAAU,UAAU,UAAU,KAAK,KAAMA,CAAM,EACjD,EAAE,MAAM,MAAM,IAAI,EAAE,WAAW,IAAI,KAAK,IAAI,GAAG,OAAO,EAC/C,IACT,EAEA,WAAWC,EAAQC,EAAM,CACvB,MAAMC,EAAO,SAAS,cAAc,KAAK,EACzC,OAAAA,EAAK,IAAM,IACP,KAAK,QAAQ,aAAe,KAAK,QAAQ,cAAgB,MAC3DA,EAAK,YAAc,KAAK,QAAQ,cAAgB,GAAO,GAAK,KAAK,QAAQ,aAEvE,OAAO,KAAK,QAAQ,gBAAmB,WAAUA,EAAK,eAAiB,KAAK,QAAQ,gBACxFA,EAAK,QAAU,IAAI,gBACnB,KAAK,MAAM,KAAK,IAAM,CACpB,GAAI,CAAAA,EAAK,QAAQ,OAAO,QACxB,OAAO,KAAK,QAAQ,QAAQ,OAAOF,EAAO,EAAGA,EAAO,EAAGA,EAAO,EAAGE,EAAK,QAAQ,MAAM,CACtF,CAAC,EAAE,KAAK,MAAMC,GAAU,CACtB,GAAI,CAAAD,EAAK,QAAQ,OAAO,QACxB,IAAI,CAACC,EAAQ,MAAM,IAAI,MAAM,QAAQH,EAAO,CAAC,IAAIA,EAAO,CAAC,IAAIA,EAAO,CAAC,gCAAgC,EACrG,MAAM,IAAI,QAAQ,CAACI,EAASC,IAAW,CACrC,MAAMC,EAASX,GAAS,CACtBO,EAAK,QAAQ,OAAO,oBAAoB,QAASK,CAAK,EACtDL,EAAK,OAASA,EAAK,QAAU,KAC7B,KAAK,YAAYA,CAAI,EACjBP,EAAOU,EAAOV,CAAK,EAClBS,EAAQ,CACf,EACMG,EAAQ,IAAMD,EAAO,EAC3BJ,EAAK,QAAQ,OAAO,iBAAiB,QAASK,EAAO,CAAE,KAAM,EAAK,CAAC,EACnEL,EAAK,UAAY,IAAI,gBAAgB,IAAI,KAAK,CAACC,EAAO,IAAI,CAAC,CAAC,EAC5DD,EAAK,OAAS,IAAMI,EAAO,EAC3BJ,EAAK,QAAU,IAAMI,EAAO,IAAI,MAAM,yBAAyBN,EAAO,CAAC,IAAIA,EAAO,CAAC,IAAIA,EAAO,CAAC,EAAE,CAAC,EAClGE,EAAK,IAAMA,EAAK,SAClB,CAAC,EACG,CAAAA,EAAK,QAAQ,OAAO,UACxBA,EAAK,KAAO,GACZ,KAAK,qBAAqBF,EAAQE,CAAI,EACtCD,EAAK,KAAMC,CAAI,GACjB,CAAC,EAAE,MAAMP,GAAS,CACZO,EAAK,QAAQ,OAAO,UACxBA,EAAK,MAAQP,EAAM,QACnB,KAAK,aAAaM,EAAMC,EAAMP,CAAK,EACrC,CAAC,EACMO,CACT,EAEA,eAAgB,CAEd,SAAW,CAAE,OAAAF,EAAQ,GAAAQ,CAAG,IAAK,OAAO,OAAO,KAAK,MAAM,EAChDR,EAAO,IAAM,KAAK,WAAW,KAAK,aAAa,CAAE,KAAMQ,CAAG,CAAC,EAEjE,EAAE,UAAU,UAAU,cAAc,KAAK,IAAI,CAC/C,EAEA,cAAcC,EAAS,CACrB,GAAI,KAAK,aAAeA,EACxB,UAAW,CAAE,GAAAD,CAAG,IAAK,OAAO,OAAO,KAAK,QAAU,CAAC,CAAC,EAAG,KAAK,YAAY,iBAAiBA,CAAE,EAE3F,GADA,KAAK,WAAaC,GAAW,KACzB,KAAK,WACP,SAAW,CAAE,OAAAT,EAAQ,GAAAQ,CAAG,IAAK,OAAO,OAAO,KAAK,QAAU,CAAC,CAAC,EACtDA,EAAG,MAAM,KAAK,qBAAqBR,EAAQQ,CAAE,EAGvD,EAEA,qBAAqBR,EAAQE,EAAM,CACjC,GAAI,CAAC,KAAK,WAAY,OACtB,MAAMO,EAAU,KAAK,WACrBA,EAAQ,cAAc,KAAMT,EAAQE,CAAI,EAAE,MAAMP,GAAS,CACnD,KAAK,aAAec,GAAWP,EAAK,aAAa,KAAK,KAAK,YAAa,CAAE,KAAAA,EAAM,OAAAF,EAAQ,MAAAL,CAAM,CAAC,CACrG,CAAC,CACH,EAEA,YAAYO,EAAM,CACZA,EAAK,YACP,IAAI,gBAAgBA,EAAK,SAAS,EAClCA,EAAK,UAAY,KAErB,EAEA,aAAa,CAAE,KAAAA,CAAK,EAAG,CACrB,KAAK,YAAY,iBAAiBA,CAAI,EACtCA,EAAK,QAAQ,MAAM,EACnB,KAAK,YAAYA,CAAI,CACvB,CACF,CAAC",
6
- "names": ["read", "getHeader", "getZxy", "decompress", "offset", "length", "signal", "data", "compression", "z", "x", "y", "options", "archive", "header", "error", "map", "layer", "opacity", "zIndex", "coords", "done", "tile", "result", "resolve", "reject", "finish", "abort", "el", "terrain"]
7
- }
@@ -1,2 +0,0 @@
1
- import{atmosphere as E,moonPosition as D,solarPosition as P,projectCelestialBody as A}from"../utils/sun.js";import{underEntry as U}from"../utils/control.js";function N(t){const s=globalThis.L,e=new s.Control({position:"bottomright"});e.live=!0;let r,l,g,a,v;const C=t.getContainer().style.getPropertyValue("--leaflet-sky-background"),w="position:absolute;width:18px;height:18px;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;",m=s.DomUtil.create("div","sunlight-sun"),f=s.DomUtil.create("div","sunlight-moon");m.style.cssText=w+"background:#fff3bd;box-shadow:0 0 18px 7px #ffd27699;",f.style.cssText=w+"background:#dce5f2;box-shadow:0 0 10px 2px #cbdcff55;",m.setAttribute("role","img"),m.setAttribute("aria-label","Sun"),f.setAttribute("role","img"),f.setAttribute("aria-label","Moon");const c=()=>{const n=t._sunlight,o=t._pitchSky;n?t.getContainer().style.setProperty("--leaflet-sky-background",n.background):C?t.getContainer().style.setProperty("--leaflet-sky-background",C):t.getContainer().style.removeProperty("--leaflet-sky-background");const i=t.getSize(),h=t.getPitch()*Math.PI/180,S=t.getBearing()*Math.PI/180;for(const[d,y]of[[m,n],[f,n?.moon]]){if(d.hidden=!0,!o||!y||y.altitude<=0||!n)continue;d.parentNode!==o&&o.append(d);const T=A(y.direction,i,h,S);if(!T)continue;const{left:p,top:x}=T;d.hidden=p<0||p>i.x||x<0||x>o.clientHeight||o.style.display==="none",d.style.left=`${p}px`,d.style.top=`${x}px`}},b=()=>s.Layer.types["3d"]?._renderers.get(t)?.update(),u=()=>{try{e.live&&(e.time=new Date);const n=e.time.toISOString();r.value=n.slice(0,10),l.value=String(e.time.getUTCHours()*60+e.time.getUTCMinutes()),g.textContent=`${n.slice(11,16)} UTC${e.live?" \xB7 now":""}`;const o=t.getCenter(),i=t._sunlight=P(e.time,o.lat,o.lng);Object.assign(i,E(i.altitude)),i.moon=D(e.time,o.lat,o.lng),a.textContent=i.altitude<=0?"Night \xB7 no direct sunlight":i.altitude<3?"Low sun \xB7 shadows paused":`Sun altitude ${i.altitude.toFixed(1)}\xB0`,t.fire("simulationtimechange",{time:new Date(e.time),live:e.live}),c(),b()}catch(n){delete t._sunlight,c(),b(),a.textContent=`Error: ${n.message}`,console.error("Solar simulation",n)}},k=()=>{if(e.live=!1,!r.value||!r.validity.valid){e.time=new Date(NaN),t.fire("simulationtimechange",{time:null,live:!1}),delete t._sunlight,c(),b(),a.textContent="Error: choose a valid solar date";return}e.time=new Date(`${r.value}T00:00:00Z`),e.time.setUTCMinutes(Number(l.value)),u()};return e.onAdd=()=>{const n=s.DomUtil.create("div","sunlight-control");n.style.cssText="color:#222;width:min(200px,calc(100vw - 60px));font:12px/1.4 sans-serif;",r=document.createElement("input"),r.type="date",r.style.cssText="width:100%;box-sizing:border-box;",r.setAttribute("aria-label","Solar date (UTC)"),l=document.createElement("input"),l.type="range",l.style.cssText="width:100%;box-sizing:border-box;margin:10px 0 4px;cursor:pointer;",l.min="0",l.max="1439",l.step="1",l.setAttribute("aria-label","Time of day (UTC)"),g=document.createElement("output"),g.style.cssText="font-weight:bold;font-variant-numeric:tabular-nums;",g.setAttribute("aria-live","off");const o=document.createElement("button");o.type="button",o.textContent="Now",o.onclick=()=>{e.live=!0,u()};const i=document.createElement("div");i.className="sunlight-time",i.style.cssText="display:flex;justify-content:space-between;align-items:center;",i.append(g,o),a=document.createElement("div"),a.className="sunlight-status",a.style.marginTop="5px",a.setAttribute("role","status");const h=document.createElement("small");return h.style.color="#555",h.textContent="Indicative \xB7 loaded geometry only. Streetlight illumination is estimated, not measured lux.",n.append(r,l,i,a,h),l.oninput=k,r.onchange=k,s.DomEvent.disableClickPropagation(n),s.DomEvent.disableScrollPropagation(n),u(),v=setInterval(()=>{e.live&&u()},6e4),t.on("moveend",u),t.on("move rotate pitch resize",c),n},e.onRemove=()=>{clearInterval(v),t.fire("simulationtimechange",{time:null,live:!1}),t.off("moveend",u),t.off("move rotate pitch resize",c),delete t._sunlight,c(),m.remove(),f.remove(),b()},e}L.Layer.types.sunlight=L.Layer.extend({onAdd(t){this.control=this.control||N(t),this.control._map||this.control.addTo(t);const s=this.control.getContainer(),e=U(this,s);s.classList.toggle("leaflet-control",!e),s.classList.toggle("leaflet-bar",!e),Object.assign(s.style,e?{background:"",padding:"2px 0 6px 20px",margin:"0"}:{background:"#fff",padding:"8px",margin:""})},onRemove(){this.control.remove()}});
2
- //# sourceMappingURL=sunlight.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/types/sunlight.js"],
4
- "sourcesContent": ["import { atmosphere, moonPosition, solarPosition, projectCelestialBody } from '../utils/sun.js';\nimport { underEntry } from '../utils/control.js';\n\nfunction installSunlight(map) {\n const L = globalThis.L;\n const control = new L.Control({ position: 'bottomright' });\n control.live = true;\n let date, slider, output, status, timer;\n const originalSky = map.getContainer().style.getPropertyValue('--leaflet-sky-background');\n const disc = 'position:absolute;width:18px;height:18px;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;';\n const sunDisc = L.DomUtil.create('div', 'sunlight-sun');\n const moonDisc = L.DomUtil.create('div', 'sunlight-moon');\n sunDisc.style.cssText = disc + 'background:#fff3bd;box-shadow:0 0 18px 7px #ffd27699;';\n moonDisc.style.cssText = disc + 'background:#dce5f2;box-shadow:0 0 10px 2px #cbdcff55;';\n sunDisc.setAttribute('role', 'img'); sunDisc.setAttribute('aria-label', 'Sun');\n moonDisc.setAttribute('role', 'img'); moonDisc.setAttribute('aria-label', 'Moon');\n const updateSky = () => {\n const sun = map._sunlight, sky = map._pitchSky;\n if (sun) map.getContainer().style.setProperty('--leaflet-sky-background', sun.background);\n else if (originalSky) map.getContainer().style.setProperty('--leaflet-sky-background', originalSky);\n else map.getContainer().style.removeProperty('--leaflet-sky-background');\n const size = map.getSize(), pitch = map.getPitch() * Math.PI / 180, bearing = map.getBearing() * Math.PI / 180;\n for (const [disc, body] of [[sunDisc, sun], [moonDisc, sun?.moon]]) {\n disc.hidden = true;\n if (!sky || !body || body.altitude <= 0 || !sun) continue;\n if (disc.parentNode !== sky) sky.append(disc);\n const point = projectCelestialBody(body.direction, size, pitch, bearing);\n if (!point) continue;\n const { left, top } = point;\n disc.hidden = left < 0 || left > size.x || top < 0 || top > sky.clientHeight || sky.style.display === 'none';\n disc.style.left = `${left}px`; disc.style.top = `${top}px`;\n }\n };\n const render = () => L.Layer.types['3d']?._renderers.get(map)?.update();\n const update = () => {\n try {\n if (control.live) control.time = new Date();\n const time = control.time.toISOString();\n date.value = time.slice(0, 10);\n slider.value = String(control.time.getUTCHours() * 60 + control.time.getUTCMinutes());\n output.textContent = `${time.slice(11, 16)} UTC${control.live ? ' \u00B7 now' : ''}`;\n const center = map.getCenter();\n const sun = map._sunlight = solarPosition(control.time, center.lat, center.lng);\n Object.assign(sun, atmosphere(sun.altitude));\n sun.moon = moonPosition(control.time, center.lat, center.lng);\n status.textContent = sun.altitude <= 0 ? 'Night \u00B7 no direct sunlight' :\n sun.altitude < 3 ? 'Low sun \u00B7 shadows paused' : `Sun altitude ${sun.altitude.toFixed(1)}\u00B0`;\n map.fire('simulationtimechange', { time: new Date(control.time), live: control.live });\n updateSky(); render();\n } catch (error) {\n delete map._sunlight;\n updateSky();\n render();\n status.textContent = `Error: ${error.message}`;\n console.error('Solar simulation', error);\n }\n };\n const selectTime = () => {\n control.live = false;\n if (!date.value || !date.validity.valid) {\n control.time = new Date(NaN);\n map.fire('simulationtimechange', { time: null, live: false });\n delete map._sunlight;\n updateSky();\n render();\n status.textContent = 'Error: choose a valid solar date';\n return;\n }\n control.time = new Date(`${date.value}T00:00:00Z`);\n control.time.setUTCMinutes(Number(slider.value));\n update();\n };\n control.onAdd = () => {\n const container = L.DomUtil.create('div', 'sunlight-control');\n container.style.cssText = 'color:#222;width:min(200px,calc(100vw - 60px));font:12px/1.4 sans-serif;';\n date = document.createElement('input');\n date.type = 'date';\n date.style.cssText = 'width:100%;box-sizing:border-box;';\n date.setAttribute('aria-label', 'Solar date (UTC)');\n slider = document.createElement('input');\n slider.type = 'range';\n slider.style.cssText = 'width:100%;box-sizing:border-box;margin:10px 0 4px;cursor:pointer;';\n slider.min = '0'; slider.max = '1439'; slider.step = '1';\n slider.setAttribute('aria-label', 'Time of day (UTC)');\n output = document.createElement('output');\n output.style.cssText = 'font-weight:bold;font-variant-numeric:tabular-nums;';\n output.setAttribute('aria-live', 'off');\n const now = document.createElement('button');\n now.type = 'button'; now.textContent = 'Now';\n now.onclick = () => { control.live = true; update(); };\n const timeRow = document.createElement('div');\n timeRow.className = 'sunlight-time';\n timeRow.style.cssText = 'display:flex;justify-content:space-between;align-items:center;';\n timeRow.append(output, now);\n status = document.createElement('div');\n status.className = 'sunlight-status';\n status.style.marginTop = '5px';\n status.setAttribute('role', 'status');\n const note = document.createElement('small');\n note.style.color = '#555';\n note.textContent = 'Indicative \u00B7 loaded geometry only. Streetlight illumination is estimated, not measured lux.';\n container.append(date, slider, timeRow, status, note);\n slider.oninput = selectTime;\n date.onchange = selectTime;\n L.DomEvent.disableClickPropagation(container);\n L.DomEvent.disableScrollPropagation(container);\n update();\n timer = setInterval(() => { if (control.live) update(); }, 60000);\n map.on('moveend', update);\n map.on('move rotate pitch resize', updateSky);\n return container;\n };\n control.onRemove = () => {\n clearInterval(timer);\n map.fire('simulationtimechange', { time: null, live: false });\n map.off('moveend', update);\n map.off('move rotate pitch resize', updateSky);\n delete map._sunlight;\n updateSky();\n sunDisc.remove(); moonDisc.remove();\n render();\n };\n return control;\n}\n\n// Sun/moon clock control and sky colours; the control is created on first add (`layer.control`).\nL.Layer.types.sunlight = L.Layer.extend({\n onAdd(map) {\n this.control = this.control || installSunlight(map);\n if (!this.control._map) this.control.addTo(map);\n // Shown under this layer's entry in the layers control; a standalone control without one.\n const container = this.control.getContainer(), nested = underEntry(this, container);\n container.classList.toggle('leaflet-control', !nested);\n container.classList.toggle('leaflet-bar', !nested);\n Object.assign(container.style, nested\n ? { background: '', padding: '2px 0 6px 20px', margin: '0' }\n : { background: '#fff', padding: '8px', margin: '' });\n },\n onRemove() {\n this.control.remove();\n },\n});\n"],
5
- "mappings": "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",
6
- "names": ["atmosphere", "moonPosition", "solarPosition", "projectCelestialBody", "underEntry", "installSunlight", "map", "L", "control", "date", "slider", "output", "status", "timer", "originalSky", "disc", "sunDisc", "moonDisc", "updateSky", "sun", "sky", "size", "pitch", "bearing", "body", "point", "left", "top", "render", "update", "time", "center", "error", "selectTime", "container", "now", "timeRow", "note", "nested"]
7
- }
@@ -1,24 +0,0 @@
1
- import{bridgeElevation as G,terrainElevation as R,terrainGrid as z,terrainAtlas as O}from"../utils/terrain.js";import{triangulate as S}from"../utils/geometry.js";import"./3d.js";import"./pmtiles.js";L.Layer.types.terrain=L.Layer.types["3d"].extend({initialize(t={}){const e=t.url,s={...t};delete s.url,L.Layer.types["3d"].prototype.initialize.call(this,s),this.terrainSource=e,this._terrainTiles=new Map,this._rasterTiles=new Map,this._terrainReady=!1},onAdd(t){if(t._terrain3D&&t._terrain3D!==this)throw new Error("Only one terrain layer can be active per map");t._terrain3D=this,L.Layer.types["3d"].prototype.onAdd.call(this,t),this._terrainPromise=this.root?this._loadTerrain():new Promise(e=>this.once("ready",()=>this._loadTerrain().then(e),this)),t.eachLayer(e=>e._setTerrain3D?.(this)),t.fire("terrainchange")},onRemove(t){this._terrainController?.abort(),this._terrainLoading=!1,this._terrainReady=!1,t.eachLayer(e=>e._setTerrain3D?.(null));for(const e of this._rasterTiles.keys())this.removeRasterTile(e);t._terrain3D===this&&delete t._terrain3D;for(const e of Object.values(t._layers))e._setTerrainHeight?.();t.fire("terrainchange"),this._terrainTiles.clear(),this._terrainOriginElevation=0,this._terrainPromise=null,this._rasterProgram&&this._removeProgram(this._rasterProgram),this._rasterProgram=null,this._dem&&this._destroyTexture(this._dem.texture),this._dem=null;for(const e of this._terrainGrids?.values()||[])for(const s of Object.values(e))this._destroyTexture(s.buffer);this._terrainGrids=null,this._bridges=null,this._disposeMesh(this._bridgeMesh),this._bridgeMesh=null,L.Layer.types["3d"].prototype.onRemove.call(this,t)},async _loadTerrain(){if(this._terrainLoading||!this._map)return;this._terrainLoading=!0,this._terrainReady=!1;const t=this._terrainController=new AbortController;try{if(!this.terrainSource)throw new Error("Terrain layer requires a PMTiles elevation archive");const e=this._terrainArchive=new L.Layer({source:{type:"pmtiles",url:this.terrainSource}});await e.ready;const s=e.header;if(s.tileType!==0||s.minZoom!==s.maxZoom)throw new Error("Expected a single-zoom Float32 PMTiles terrain archive");this._terrainZoom=s.maxZoom;const x=this._map,p=x.project([s.maxLat,s.minLon],this._terrainZoom).divideBy(256).floor(),y=x.project([s.minLat,s.maxLon],this._terrainZoom).divideBy(256).floor();this._terrainBounds=new L.Bounds(p,y);const T=[];for(let n=p.x;n<=y.x;n++)for(let _=p.y;_<=y.y;_++)T.push({z:this._terrainZoom,x:n,y:_});let g=0;await Promise.all(Array.from({length:Math.min(4,T.length)},async()=>{for(;g<T.length;){t.signal.throwIfAborted();const n=T[g++],_=await e.getZxy(n.z,n.x,n.y,t.signal);if(!_||_.data.byteLength!==256*256*4)throw new Error(`Missing or invalid Float32 terrain tile ${n.z}/${n.x}/${n.y}`);this._terrainTiles.set(`${n.x}/${n.y}`,new Float32Array(_.data))}}));const w=this.options.bridges&&await fetch(this.options.bridges,{signal:t.signal}).then(n=>{if(!n.ok)throw new Error(`Bridges: HTTP ${n.status}`);return n.json()});if(t.signal.aborted||this._map!==x)return;this._terrainReady=!0,this._terrainOriginElevation=this._getElevation(this.location)??0;for(const n of Object.values(x._layers))n._setTerrainHeight?.();return w&&this._addBridges(w),x.fire("terrainchange"),this.update(),this.fire("terrainready"),!0}catch(e){return t.signal.aborted||this.fire("error",{error:e}),!1}finally{this._terrainLoading=!1}},_getElevation(t){if(!this._map||!this._terrainReady)return null;const e=t instanceof L.Point?t:this._map.project(t,this._terrainZoom);return G(e,this._bridges)??R(e,this._terrainTiles)},_addBridges(t){const e=this._map,s=e.options.crs,x=this._terrainZoom,p=s.project(this.location),y=Math.cos(this.location.lat*Math.PI/180),T=this.root.position[1],g=[],w=[],n=[],_=([m,M,h])=>{const l=s.project(new L.LatLng(M,m));return[(l.x-p.x)*y,h-T,-(l.y-p.y)*y]},E=(m,M)=>{g.push(...m),w.push(...M),n.push(.6,.58,.54)};this._bridges=new Map;for(const{geometry:m}of t.features){const M=m.type==="Polygon"?[m.coordinates]:m.type==="MultiPolygon"?m.coordinates:[];for(const h of M){const l=h.map(r=>r.slice(0,-1)).filter(r=>r.length>=3);if(!l.length)continue;const c=l.flat().map(([r,o,a])=>{const i=e.project([o,r],x);return[i.x,i.y,a]}),d=l.flat().map(_);let U;try{const r=l.map((i,u)=>l.slice(0,u).reduce((b,f)=>b+f.length,0)),[o,...a]=l.map((i,u)=>i.map((b,f)=>({x:c[r[u]+f][0],y:c[r[u]+f][1]})));U=S(o,a)}catch{continue}const v={triangles:U.map(r=>r.map(o=>c[o])),min:[Math.min(...c.map(r=>r[0])),Math.min(...c.map(r=>r[1]))],max:[Math.max(...c.map(r=>r[0])),Math.max(...c.map(r=>r[1]))]};for(let r=Math.floor(v.min[0]/64);r<=Math.floor(v.max[0]/64);r++)for(let o=Math.floor(v.min[1]/64);o<=Math.floor(v.max[1]/64);o++){const a=`${r}/${o}`;this._bridges.set(a,[...this._bridges.get(a)||[],v])}const P=r=>[r[0],r[1]-1.2,r[2]];for(let[r,o,a]of U){const[i,u,b]=[d[r],d[o],d[a]];(u[2]-i[2])*(b[0]-i[0])-(u[0]-i[0])*(b[2]-i[2])<0&&([o,a]=[a,o]);for(const f of[r,o,a])E(d[f],[0,1,0]);for(const f of[r,a,o])E(P(d[f]),[0,-1,0])}let B=0;for(const r of l){for(let o=0;o<r.length;o++){const a=d[B+o],i=d[B+(o+1)%r.length],u=Math.hypot(i[0]-a[0],i[2]-a[2])||1,b=[(i[2]-a[2])/u,0,-(i[0]-a[0])/u];for(const f of[a,i,P(i),a,P(i),P(a)])E(f,b)}B+=r.length}}}g.length&&(this._bridgeMesh=this._createMesh({position:g,normal:w,color:n}))},async addRasterTile(t,e,s){const[x,p]=await Promise.all([this._terrainPromise,createImageBitmap(s)]);if(!x||!this._map||this._map._terrain3D!==this||t._terrain3D!==this||s.request.signal.aborted||!s.isConnected||this._rasterTiles.has(s)){p.close();return}const y=Math.max(1,Math.min(64,256/2**(e.z-this._terrainZoom))),T=this._map,g=T.options.crs,w=g.project(this.location),n=Math.cos(this.location.lat*Math.PI/180),_=g.scale(e.z),E=2**(this._terrainZoom-e.z),m=g.transformation.untransform(new L.Point(e.x*256,e.y*256),_),M=g.transformation.untransform(new L.Point((e.x+1)*256,(e.y+1)*256),_),h=this.renderer.device,l={device:h,texture:h.createTexture({size:[s.width,s.height],format:"rgba8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT}),sampler:h.createSampler({addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"}),samplerOptions:{addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge"},image:s,format:"rgba8unorm",srgb:!1,flipY:!1,uploaded:s};if(h.queue.copyExternalImageToTexture({source:p},{texture:l.texture},[s.width,s.height]),p.close(),!this._rasterProgram||this._rasterProgram.device!==h){const a=this._terrainBounds,i=a.max.x-a.min.x+1,u=a.max.y-a.min.y+1,{elevations:b,low:f,high:D}=O(this._terrainTiles,a);this._dem&&this._destroyTexture(this._dem.texture),this._dem={texture:h.createTexture({size:[i*256,u*256],format:"r32float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),low:Number.isFinite(f)?f:this._terrainOriginElevation,high:Number.isFinite(D)?D:this._terrainOriginElevation},h.queue.writeTexture({texture:this._dem.texture},b,{bytesPerRow:i*1024},[i*256,u*256]),this._terrainGrids=new Map,this._rasterProgram=this._createProgram({baseTexture:l,unlit:!0,alphaMode:"BLEND",terrain:this._dem})}let c=this._terrainGrids.get(y);if(!c){c=z(y);for(const[a,i]of Object.entries(c))i.size||=1,i.count=i.data.length/i.size,i.indexFormat="uint16",i.buffer=h.createBuffer({size:Math.max(4,i.data.byteLength),usage:a==="index"?GPUBufferUsage.INDEX|GPUBufferUsage.COPY_DST:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST}),h.queue.writeBuffer(i.buffer,0,i.data);this._terrainGrids.set(y,c)}const d=this._terrainOriginElevation,U=Math.min(this._dem.low,d)-d,v=Math.max(this._dem.high,d)-d,P=(M.x-m.x)*n,B=-(M.y-m.y)*n,r={device:h,attributes:c,drawRange:{start:0,count:c.index.count},bounds:{min:[0,U,0],max:[1,v,1],center:[.5,(U+v)/2,.5],radius:Math.hypot(P,v-U,B)/2/Math.max(P,1,B)}},o={position:[(m.x-w.x)*n,0,-(m.y-w.y)*n],rotation:[0,0,0],scale:[P,1,B],worldMatrix:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],children:[],visible:!0,device:h,geometry:r,program:this._rasterProgram,texture:l,terrain:[e.x*256*E-this._terrainBounds.min.x*256,e.y*256*E-this._terrainBounds.min.y*256,256*E,d],tile:s,opacity:t.options.opacity??1,id:L.Layer.types["3d"]._nextId++,renderOrder:-1};this.add(o),this._rasterTiles.set(s,o),s._terrainVisibility=s.style.visibility},removeRasterTile(t){t._terrainRequest?.abort();const e=this._rasterTiles.get(t);e&&(this.remove(e),this._destroyTexture(e.texture.texture),this._rasterTiles.delete(t),t.style.visibility=t._terrainVisibility,delete t._terrainVisibility)}}),L.Layer.types.terrain.elevationWGSL=`
2
- fn demSample(pixel: vec2<i32>) -> f32 {
3
- if (any(pixel < vec2<i32>(0)) || any(pixel >= vec2<i32>(textureDimensions(dem)))) { return -1e9; }
4
- return textureLoad(dem, pixel, 0).r;
5
- }
6
- fn elevation(pixel: vec2<f32>, base: f32) -> f32 {
7
- let p = pixel - vec2<f32>(0.5);
8
- let f = fract(p);
9
- let i = vec2<i32>(floor(p));
10
- let v00 = demSample(i);
11
- let v10 = demSample(i + vec2<i32>(1, 0));
12
- let v01 = demSample(i + vec2<i32>(0, 1));
13
- let v11 = demSample(i + vec2<i32>(1, 1));
14
- if (v00 > -1000.0 && v10 > -1000.0 && v01 > -1000.0 && v11 > -1000.0) {
15
- return mix(mix(v00, v10, f.x), mix(v01, v11, f.x), f.y);
16
- }
17
- if (v00 > -1000.0) { return v00; }
18
- if (v10 > -1000.0) { return v10; }
19
- if (v01 > -1000.0) { return v01; }
20
- if (v11 > -1000.0) { return v11; }
21
- return base;
22
- }
23
- `;
24
- //# sourceMappingURL=terrain.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/types/terrain.js"],
4
- "sourcesContent": ["import { bridgeElevation, terrainElevation, terrainGrid, terrainAtlas } from '../utils/terrain.js';\nimport { triangulate } from '../utils/geometry.js';\nimport './3d.js';\nimport './pmtiles.js';\n\n/**\n * Renders IGN Float32 DEM tiles and PMTiles raster basemaps in the shared WebGPU scene.\n * Source options: `url` (single-zoom Float32 PMTiles DEM); `bridges` (optional GeoJSON deck polygons with Z, see _addBridges).\n */\nL.Layer.types.terrain = L.Layer.types['3d'].extend({\n initialize(options = {}) {\n const terrainSource = options.url;\n const layerOptions = { ...options };\n delete layerOptions.url;\n L.Layer.types['3d'].prototype.initialize.call(this, layerOptions);\n this.terrainSource = terrainSource;\n this._terrainTiles = new Map();\n this._rasterTiles = new Map();\n this._terrainReady = false;\n },\n\n onAdd(map) {\n if (map._terrain3D && map._terrain3D !== this) throw new Error('Only one terrain layer can be active per map');\n map._terrain3D = this;\n L.Layer.types['3d'].prototype.onAdd.call(this, map);\n this._terrainPromise = this.root\n ? this._loadTerrain()\n : new Promise(resolve => this.once('ready', () => this._loadTerrain().then(resolve), this));\n map.eachLayer(layer => layer._setTerrain3D?.(this));\n map.fire('terrainchange');\n },\n\n onRemove(map) {\n this._terrainController?.abort();\n this._terrainLoading = false;\n this._terrainReady = false;\n map.eachLayer(layer => layer._setTerrain3D?.(null));\n for (const tile of this._rasterTiles.keys()) this.removeRasterTile(tile);\n if (map._terrain3D === this) delete map._terrain3D;\n for (const layer of Object.values(map._layers)) layer._setTerrainHeight?.();\n map.fire('terrainchange');\n this._terrainTiles.clear();\n this._terrainOriginElevation = 0;\n this._terrainPromise = null;\n if (this._rasterProgram) this._removeProgram(this._rasterProgram);\n this._rasterProgram = null;\n if (this._dem) this._destroyTexture(this._dem.texture);\n this._dem = null;\n for (const grid of this._terrainGrids?.values() || []) {\n for (const attribute of Object.values(grid)) this._destroyTexture(attribute.buffer);\n }\n this._terrainGrids = null;\n this._bridges = null;\n this._disposeMesh(this._bridgeMesh);\n this._bridgeMesh = null;\n L.Layer.types['3d'].prototype.onRemove.call(this, map);\n },\n\n async _loadTerrain() {\n if (this._terrainLoading || !this._map) return;\n this._terrainLoading = true;\n this._terrainReady = false;\n const controller = this._terrainController = new AbortController();\n try {\n if (!this.terrainSource) throw new Error('Terrain layer requires a PMTiles elevation archive');\n const archive = this._terrainArchive = new L.Layer({ source: { type: 'pmtiles', url: this.terrainSource } });\n await archive.ready;\n const header = archive.header;\n if (header.tileType !== 0 || header.minZoom !== header.maxZoom) {\n throw new Error('Expected a single-zoom Float32 PMTiles terrain archive');\n }\n this._terrainZoom = header.maxZoom;\n const map = this._map;\n const northwest = map.project([header.maxLat, header.minLon], this._terrainZoom).divideBy(256).floor();\n const southeast = map.project([header.minLat, header.maxLon], this._terrainZoom).divideBy(256).floor();\n this._terrainBounds = new L.Bounds(northwest, southeast);\n const tiles = [];\n for (let x = northwest.x; x <= southeast.x; x++) {\n for (let y = northwest.y; y <= southeast.y; y++) tiles.push({ z: this._terrainZoom, x, y });\n }\n let next = 0;\n await Promise.all(Array.from({ length: Math.min(4, tiles.length) }, async () => {\n while (next < tiles.length) {\n controller.signal.throwIfAborted();\n const coords = tiles[next++];\n const result = await archive.getZxy(coords.z, coords.x, coords.y, controller.signal);\n if (!result || result.data.byteLength !== 256 * 256 * 4) {\n throw new Error(`Missing or invalid Float32 terrain tile ${coords.z}/${coords.x}/${coords.y}`);\n }\n this._terrainTiles.set(`${coords.x}/${coords.y}`, new Float32Array(result.data));\n }\n }));\n const bridges = this.options.bridges && await fetch(this.options.bridges, { signal: controller.signal })\n .then(response => { if (!response.ok) throw new Error(`Bridges: HTTP ${response.status}`); return response.json(); });\n if (controller.signal.aborted || this._map !== map) return;\n this._terrainReady = true;\n this._terrainOriginElevation = this._getElevation(this.location) ?? 0;\n for (const layer of Object.values(map._layers)) layer._setTerrainHeight?.();\n if (bridges) this._addBridges(bridges);\n map.fire('terrainchange');\n this.update();\n this.fire('terrainready');\n return true;\n } catch (error) {\n if (!controller.signal.aborted) this.fire('error', { error });\n return false;\n } finally {\n this._terrainLoading = false;\n }\n },\n\n /** @param {L.LatLng|L.Point} location LatLng, or a pixel point at the terrain zoom. */\n _getElevation(location) {\n if (!this._map || !this._terrainReady) return null;\n const point = location instanceof L.Point ? location : this._map.project(location, this._terrainZoom);\n return bridgeElevation(point, this._bridges) ?? terrainElevation(point, this._terrainTiles);\n },\n\n /**\n * Bare-earth DEMs drop bridges: `_getElevation` returns the deck height inside these polygons (GeoJSON\n * Polygon/MultiPolygon with Z, e.g. IGN BD TOPO), and one mesh draws the 1.2 m thick decks.\n * ponytail: anything under a deck (quays, boats asking `_getElevation`) also gets the deck height.\n */\n _addBridges(geojson) {\n const map = this._map, crs = map.options.crs, zoom = this._terrainZoom;\n const origin = crs.project(this.location), metres = Math.cos(this.location.lat * Math.PI / 180);\n const base = this.root.position[1], position = [], normal = [], color = [];\n const local = ([lng, lat, z]) => {\n const p = crs.project(new L.LatLng(lat, lng));\n return [(p.x - origin.x) * metres, z - base, -(p.y - origin.y) * metres];\n };\n const push = (p, n) => { position.push(...p); normal.push(...n); color.push(0.6, 0.58, 0.54); };\n this._bridges = new Map();\n for (const { geometry } of geojson.features) {\n const polygons = geometry.type === 'Polygon' ? [geometry.coordinates] : geometry.type === 'MultiPolygon' ? geometry.coordinates : [];\n for (const polygon of polygons) {\n const rings = polygon.map(ring => ring.slice(0, -1)).filter(ring => ring.length >= 3);\n if (!rings.length) continue;\n const pixels = rings.flat().map(([lng, lat, z]) => { const p = map.project([lat, lng], zoom); return [p.x, p.y, z]; });\n const points = rings.flat().map(local);\n let triangles;\n try {\n const starts = rings.map((ring, r) => rings.slice(0, r).reduce((sum, previous) => sum + previous.length, 0));\n const [contour, ...holes] = rings.map((ring, r) => ring.map((c, i) => ({ x: pixels[starts[r] + i][0], y: pixels[starts[r] + i][1] })));\n triangles = triangulate(contour, holes);\n } catch { continue; }\n const bridge = {\n triangles: triangles.map(t => t.map(i => pixels[i])),\n min: [Math.min(...pixels.map(p => p[0])), Math.min(...pixels.map(p => p[1]))],\n max: [Math.max(...pixels.map(p => p[0])), Math.max(...pixels.map(p => p[1]))],\n };\n for (let x = Math.floor(bridge.min[0] / 64); x <= Math.floor(bridge.max[0] / 64); x++) {\n for (let y = Math.floor(bridge.min[1] / 64); y <= Math.floor(bridge.max[1] / 64); y++) {\n const key = `${x}/${y}`;\n this._bridges.set(key, [...this._bridges.get(key) || [], bridge]);\n }\n }\n const below = p => [p[0], p[1] - 1.2, p[2]];\n for (let [a, b, c] of triangles) {\n // Counter-clockwise seen from above, so double-sided shading keeps the top lit.\n const [pa, pb, pc] = [points[a], points[b], points[c]];\n if ((pb[2] - pa[2]) * (pc[0] - pa[0]) - (pb[0] - pa[0]) * (pc[2] - pa[2]) < 0) [b, c] = [c, b];\n for (const i of [a, b, c]) push(points[i], [0, 1, 0]);\n for (const i of [a, c, b]) push(below(points[i]), [0, -1, 0]);\n }\n let start = 0;\n for (const ring of rings) {\n for (let i = 0; i < ring.length; i++) {\n const p = points[start + i], q = points[start + (i + 1) % ring.length];\n const length = Math.hypot(q[0] - p[0], q[2] - p[2]) || 1, n = [(q[2] - p[2]) / length, 0, -(q[0] - p[0]) / length];\n for (const corner of [p, q, below(q), p, below(q), below(p)]) push(corner, n);\n }\n start += ring.length;\n }\n }\n }\n if (position.length) this._bridgeMesh = this._createMesh({ position, normal, color });\n },\n\n async addRasterTile(layer, coords, tile) {\n const [ready, bitmap] = await Promise.all([this._terrainPromise, createImageBitmap(tile)]);\n if (!ready || !this._map || this._map._terrain3D !== this || layer._terrain3D !== this ||\n tile.request.signal.aborted || !tile.isConnected || this._rasterTiles.has(tile)) {\n bitmap.close();\n return;\n }\n // Match DEM pixel spacing, capped at 64 subdivisions per tile.\n const divisions = Math.max(1, Math.min(64, 256 / 2 ** (coords.z - this._terrainZoom)));\n const map = this._map, crs = map.options.crs;\n const origin = crs.project(this.location), metres = Math.cos(this.location.lat * Math.PI / 180);\n // Tile pixels map linearly to projected metres: one scaled unit grid per tile, elevation in the vertex shader.\n const scale = crs.scale(coords.z), terrainScale = 2 ** (this._terrainZoom - coords.z);\n const corner = crs.transformation.untransform(new L.Point(coords.x * 256, coords.y * 256), scale);\n const opposite = crs.transformation.untransform(new L.Point((coords.x + 1) * 256, (coords.y + 1) * 256), scale);\n const device = this.renderer.device;\n const texture = {\n device,\n texture: device.createTexture({\n size: [tile.width, tile.height],\n format: 'rgba8unorm',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n }),\n sampler: device.createSampler({ addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge' }),\n samplerOptions: { addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge' },\n image: tile, format: 'rgba8unorm', srgb: false, flipY: false, uploaded: tile,\n };\n device.queue.copyExternalImageToTexture({ source: bitmap }, { texture: texture.texture }, [tile.width, tile.height]);\n bitmap.close();\n if (!this._rasterProgram || this._rasterProgram.device !== device) {\n // DEM atlas over the archive's tile grid; invalid or missing samples become -1e9 (the shader's no-data).\n // ponytail: one texture, capped by maxTextureDimension2D (32\u00D732 DEM tiles at 8192 px); split it for larger archives.\n const bounds = this._terrainBounds, columns = bounds.max.x - bounds.min.x + 1, rows = bounds.max.y - bounds.min.y + 1;\n const { elevations, low, high } = terrainAtlas(this._terrainTiles, bounds);\n if (this._dem) this._destroyTexture(this._dem.texture);\n this._dem = {\n texture: device.createTexture({\n size: [columns * 256, rows * 256],\n format: 'r32float',\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,\n }),\n low: Number.isFinite(low) ? low : this._terrainOriginElevation,\n high: Number.isFinite(high) ? high : this._terrainOriginElevation,\n };\n device.queue.writeTexture({ texture: this._dem.texture }, elevations,\n { bytesPerRow: columns * 1024 }, [columns * 256, rows * 256]);\n this._terrainGrids = new Map();\n this._rasterProgram = this._createProgram({\n baseTexture: texture,\n unlit: true,\n alphaMode: 'BLEND',\n terrain: this._dem,\n });\n }\n let attributes = this._terrainGrids.get(divisions);\n if (!attributes) {\n attributes = terrainGrid(divisions);\n for (const [name, attribute] of Object.entries(attributes)) {\n attribute.size ||= 1;\n attribute.count = attribute.data.length / attribute.size;\n attribute.indexFormat = 'uint16';\n attribute.buffer = device.createBuffer({\n size: Math.max(4, attribute.data.byteLength),\n usage: name === 'index'\n ? GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST\n : GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,\n });\n device.queue.writeBuffer(attribute.buffer, 0, attribute.data);\n }\n this._terrainGrids.set(divisions, attributes);\n }\n const base = this._terrainOriginElevation;\n const bottom = Math.min(this._dem.low, base) - base, top = Math.max(this._dem.high, base) - base;\n const sizeX = (opposite.x - corner.x) * metres, sizeZ = -(opposite.y - corner.y) * metres;\n // ponytail: ray picking sees the flat unit grid; read the DEM back if terrain must be pickable.\n const geometry = {\n device,\n attributes,\n drawRange: { start: 0, count: attributes.index.count },\n // Local bounds whose radius, scaled by the largest axis, still covers the displaced tile.\n bounds: {\n min: [0, bottom, 0], max: [1, top, 1], center: [0.5, (bottom + top) / 2, 0.5],\n radius: Math.hypot(sizeX, top - bottom, sizeZ) / 2 / Math.max(sizeX, 1, sizeZ),\n },\n };\n const mesh = {\n position: [(corner.x - origin.x) * metres, 0, -(corner.y - origin.y) * metres],\n rotation: [0, 0, 0],\n scale: [sizeX, 1, sizeZ],\n worldMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],\n children: [],\n visible: true,\n device,\n geometry,\n program: this._rasterProgram,\n texture,\n // DEM pixel of the tile's corner, DEM pixels per tile, and the elevation at the layer origin.\n terrain: [\n coords.x * 256 * terrainScale - this._terrainBounds.min.x * 256,\n coords.y * 256 * terrainScale - this._terrainBounds.min.y * 256,\n 256 * terrainScale,\n base,\n ],\n tile,\n opacity: layer.options.opacity ?? 1,\n id: L.Layer.types['3d']._nextId++,\n renderOrder: -1,\n };\n this.add(mesh);\n this._rasterTiles.set(tile, mesh);\n tile._terrainVisibility = tile.style.visibility;\n },\n\n removeRasterTile(tile) {\n tile._terrainRequest?.abort();\n const mesh = this._rasterTiles.get(tile);\n if (!mesh) return;\n this.remove(mesh);\n this._destroyTexture(mesh.texture.texture);\n this._rasterTiles.delete(tile);\n tile.style.visibility = tile._terrainVisibility;\n delete tile._terrainVisibility;\n },\n});\n\n/**\n * WGSL twin of _getElevation for the vertex shader: bilinear DEM pixels, or the first valid\n * neighbour near no-data (stored as -1e9), else `base`. Expects `dem: texture_2d<f32>`.\n */\nL.Layer.types.terrain.elevationWGSL = `\n fn demSample(pixel: vec2<i32>) -> f32 {\n if (any(pixel < vec2<i32>(0)) || any(pixel >= vec2<i32>(textureDimensions(dem)))) { return -1e9; }\n return textureLoad(dem, pixel, 0).r;\n }\n fn elevation(pixel: vec2<f32>, base: f32) -> f32 {\n let p = pixel - vec2<f32>(0.5);\n let f = fract(p);\n let i = vec2<i32>(floor(p));\n let v00 = demSample(i);\n let v10 = demSample(i + vec2<i32>(1, 0));\n let v01 = demSample(i + vec2<i32>(0, 1));\n let v11 = demSample(i + vec2<i32>(1, 1));\n if (v00 > -1000.0 && v10 > -1000.0 && v01 > -1000.0 && v11 > -1000.0) {\n return mix(mix(v00, v10, f.x), mix(v01, v11, f.x), f.y);\n }\n if (v00 > -1000.0) { return v00; }\n if (v10 > -1000.0) { return v10; }\n if (v01 > -1000.0) { return v01; }\n if (v11 > -1000.0) { return v11; }\n return base;\n }\n`;\n"],
5
- "mappings": "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",
6
- "names": ["bridgeElevation", "terrainElevation", "terrainGrid", "terrainAtlas", "triangulate", "options", "terrainSource", "layerOptions", "map", "resolve", "layer", "tile", "grid", "attribute", "controller", "archive", "header", "northwest", "southeast", "tiles", "x", "y", "next", "coords", "result", "bridges", "response", "error", "location", "point", "geojson", "crs", "zoom", "origin", "metres", "base", "position", "normal", "color", "local", "lng", "lat", "z", "p", "push", "n", "geometry", "polygons", "polygon", "rings", "ring", "pixels", "points", "triangles", "starts", "r", "sum", "previous", "contour", "holes", "c", "i", "bridge", "t", "key", "below", "a", "b", "pa", "pb", "pc", "start", "q", "length", "corner", "ready", "bitmap", "divisions", "scale", "terrainScale", "opposite", "device", "texture", "bounds", "columns", "rows", "elevations", "low", "high", "attributes", "name", "bottom", "top", "sizeX", "sizeZ", "mesh"]
7
- }