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,204 +0,0 @@
1
- import { decodeModel, readAccessor, nodeMatrix, vertexNormals, textureSampler } from '../utils/model.js';
2
- import { emptyNode, setParent } from '../utils/scene.js';
3
-
4
- /** glTF/GLB model loading. */
5
- /** Load the configured GLB/glTF (static triangles) under `root`; GPU resources need attachment. */
6
- export async function loadModel(backend) {
7
- await backend._added.promise;
8
- const url = new URL(backend.modelUrl, document.baseURI).href;
9
- const response = await fetch(url);
10
- if (!response.ok) {
11
- throw new Error(`Unable to load model: HTTP ${response.status}`);
12
- }
13
- const data = await response.arrayBuffer();
14
- const description = decodeModel(data);
15
- const directory = new URL('.', url).href;
16
- await Promise.all((description.buffers || []).map(async buffer => {
17
- if (buffer.binary) {
18
- return;
19
- }
20
- const response = await fetch(new URL(buffer.uri, directory).href);
21
- if (!response.ok) {
22
- throw new Error(`Unable to load model buffer: HTTP ${response.status}`);
23
- }
24
- buffer.binary = await response.arrayBuffer();
25
- }));
26
- await backend._added.promise;
27
- const images = await Promise.all((description.images || []).map(async image => {
28
- let blob;
29
- if (image.bufferView !== undefined) {
30
- const view = description.bufferViews[image.bufferView];
31
- const buffer = description.buffers[view.buffer].binary;
32
- blob = new Blob([buffer.slice(view.byteOffset || 0, (view.byteOffset || 0) + view.byteLength)],
33
- { type: image.mimeType });
34
- } else {
35
- const response = await fetch(new URL(image.uri, directory).href);
36
- if (!response.ok) throw new Error(`Unable to load model texture: HTTP ${response.status}`);
37
- blob = await response.blob();
38
- }
39
- // Preserve straight alpha and raw samples; GPU sRGB formats do color decoding.
40
- return createImageBitmap(blob, { premultiplyAlpha: 'none', colorSpaceConversion: 'none' });
41
- }));
42
- const textures = new Map();
43
- const textureFor = (reference, color = false) => {
44
- if (!reference) return null;
45
- if ((reference.texCoord || 0) !== 0 || reference.extensions) {
46
- throw new Error('Model textures currently require untransformed TEXCOORD_0 UVs');
47
- }
48
- const device = backend.renderer.device;
49
- // A glTF image may serve both color and data maps: those cannot share a GPU format.
50
- const key = `${reference.index}:${color}`;
51
- if (!textures.has(key)) {
52
- const texture = description.textures[reference.index];
53
- const sampler = description.samplers?.[texture.sampler] || {};
54
- const image = images[texture.source];
55
- const format = color ? 'rgba8unorm-srgb' : 'rgba8unorm';
56
- const samplerOptions = textureSampler(sampler);
57
- textures.set(key, {
58
- device,
59
- texture: device.createTexture({
60
- size: [image.width, image.height],
61
- format,
62
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
63
- }),
64
- sampler: device.createSampler(samplerOptions),
65
- samplerOptions,
66
- format,
67
- srgb: color,
68
- image,
69
- flipY: false,
70
- uploaded: null,
71
- });
72
- }
73
- return textures.get(key);
74
- };
75
- // Convert glTF materials directly to the shader's retained CPU styles.
76
- const materials = (description.materials || []).map(material => {
77
- const pbr = material.pbrMetallicRoughness || {};
78
- return {
79
- color: (pbr.baseColorFactor || [1, 1, 1, 1]).slice(0, 3),
80
- opacity: pbr.baseColorFactor?.[3] ?? 1,
81
- metallic: pbr.metallicFactor ?? 1,
82
- roughness: pbr.roughnessFactor ?? 1,
83
- baseTexture: textureFor(pbr.baseColorTexture, true),
84
- metalTexture: textureFor(pbr.metallicRoughnessTexture),
85
- emissiveTexture: textureFor(material.emissiveTexture, true),
86
- occlusionTexture: textureFor(material.occlusionTexture),
87
- emissive: material.emissiveFactor || [0, 0, 0],
88
- occlusionStrength: material.occlusionTexture?.strength ?? 1,
89
- alphaMode: material.alphaMode || 'OPAQUE',
90
- alphaCutoff: material.alphaCutoff ?? 0.5,
91
- doubleSided: material.doubleSided,
92
- };
93
- });
94
- let nodes;
95
- {
96
- // Track only the recursion path: shared mesh references are valid, cycles are not.
97
- const active = new Set(), resources = [];
98
- const node = index => {
99
- if (active.has(index)) throw new Error('Cyclic glTF nodes');
100
- const spec = description.nodes[index];
101
- if (!spec) throw new Error('Invalid glTF node');
102
- active.add(index);
103
- const group = {
104
- ...emptyNode(),
105
- name: spec.name
106
- };
107
- group.matrix = nodeMatrix(spec);
108
- if (spec.mesh !== undefined) {
109
- for (const primitive of description.meshes[spec.mesh].primitives) {
110
- const attributes = {};
111
- for (const [semantic, name] of [['POSITION', 'position'], ['NORMAL', 'normal'], ['TEXCOORD_0', 'uv']]) {
112
- if (primitive.attributes[semantic] !== undefined) attributes[name] = readAccessor(description, primitive.attributes[semantic]);
113
- }
114
- if (!attributes.position) throw new Error('glTF mesh has no positions');
115
- const vertexCount = attributes.position.data.length / 3;
116
- if (attributes.position.size !== 3 || vertexCount < 3 ||
117
- Object.values(attributes).some(attribute => attribute.data.length / attribute.size !== vertexCount)) throw new Error('Invalid glTF vertex attributes');
118
- if (primitive.indices !== undefined) {
119
- const index = readAccessor(description, primitive.indices);
120
- attributes.index = { size: 1, data: index.indices };
121
- if (![Uint8Array, Uint16Array, Uint32Array].some(Type => index.indices instanceof Type) ||
122
- index.size !== 1 || index.indices.length % 3 || [...index.indices].some(i => i >= vertexCount)) throw new Error('Invalid glTF triangle indices');
123
- }
124
- if (!attributes.index && vertexCount % 3) throw new Error('Incomplete glTF triangle');
125
- if (!attributes.normal) {
126
- const normals = vertexNormals(attributes.position.data, attributes.index?.data);
127
- attributes.normal = { size: 3, data: normals };
128
- }
129
- const style = materials[primitive.material] || { color: [1, 1, 1], metallic: 1 };
130
- if ([style.baseTexture, style.metalTexture, style.emissiveTexture, style.occlusionTexture].some(Boolean) && !attributes.uv) {
131
- throw new Error('Textured model mesh requires UV coordinates');
132
- }
133
- const program = backend._createProgram(style);
134
- resources.push(program);
135
- const device = backend.renderer.device;
136
- if (attributes.index?.data instanceof Uint8Array) {
137
- attributes.index.data = Uint16Array.from(attributes.index.data);
138
- }
139
- for (const [name, attribute] of Object.entries(attributes)) {
140
- attribute.size ||= 1;
141
- attribute.count = attribute.data.length / attribute.size;
142
- attribute.indexFormat = attribute.data instanceof Uint32Array ? 'uint32' : 'uint16';
143
- attribute.buffer = device.createBuffer({
144
- size: Math.max(4, attribute.data.byteLength),
145
- usage: name === 'index'
146
- ? GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST
147
- : GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
148
- });
149
- device.queue.writeBuffer(attribute.buffer, 0, attribute.data);
150
- }
151
- const geometry = {
152
- device,
153
- attributes,
154
- drawRange: { start: 0, count: attributes.index?.count || attributes.position.count },
155
- };
156
- resources.push(geometry);
157
- const mesh = {
158
- ...emptyNode(),
159
- device,
160
- geometry,
161
- program,
162
- id: L.Layer.types['3d']._nextId++,
163
- renderOrder: 0
164
- };
165
- mesh.name = description.meshes[spec.mesh].name; mesh.extras = spec.extras || {};
166
- setParent(mesh, group);
167
- }
168
- }
169
- for (const child of spec.children || []) setParent(node(child), group);
170
- active.delete(index);
171
- return group;
172
- };
173
- const scene = description.scenes?.[description.scene || 0];
174
- if (!scene) throw new Error('Missing glTF scene');
175
- try {
176
- nodes = scene.nodes.map(node);
177
- } catch (error) {
178
- // Parsing can fail after earlier primitives allocated buffers/programs.
179
- for (const resource of resources) {
180
- if (resource.attributes) {
181
- for (const attribute of Object.values(resource.attributes)) attribute.buffer.destroy();
182
- } else backend._removeProgram(resource);
183
- }
184
- throw error;
185
- }
186
- }
187
- const model = {
188
- ...emptyNode(),
189
- id: url,
190
- extras: description.extras || {},
191
- };
192
- if (!nodes.length) throw new Error('Expected a glTF model with a non-empty scene');
193
- for (const node of nodes) setParent(node, model);
194
- backend.model = model;
195
- if (backend.options.rotation) {
196
- const [x, y = x, z = x] = backend.options.rotation;
197
- backend.model.rotation[0] = x; backend.model.rotation[1] = y; backend.model.rotation[2] = z;
198
- }
199
- if (backend.options.scale) {
200
- const [x, y = x, z = x] = backend.options.scale;
201
- backend.model.scale[0] = x; backend.model.scale[1] = y; backend.model.scale[2] = z;
202
- }
203
- setParent(backend.model, backend.root);
204
- }
@@ -1,150 +0,0 @@
1
- import { intersectMeshes } from '../utils/picking.js';
2
- import { traverse, updateWorldMatrix, updateCamera } from '../utils/scene.js';
3
-
4
- /** Raycasting, hover/click highlight and tooltips. */
5
- /**
6
- * Finds the objects under a mouse or pointer event, nearest first.
7
- *
8
- * @param {MouseEvent} event
9
- * @param {Object[]} [objects] Defaults to this layer's root children, not all map layers.
10
- * @param {boolean} [recursive] Also test the descendants of `objects`.
11
- * @returns {Object[]} Nearest hit per mesh: object, shared-world point/distance and triangle faceIndex.
12
- */
13
- export function raycast(backend, event, objects = backend.root.children, recursive = true) {
14
- if (!backend.renderer) {
15
- return [];
16
- }
17
- const rect = backend._map.getContainer().getBoundingClientRect();
18
- updateWorldMatrix(backend.scene);
19
- updateCamera(backend.camera);
20
- // Unproject the mouse (-1..1) into a world-space ray from the camera.
21
- const inverseCamera = new DOMMatrix(backend.camera.projectionViewMatrix).inverse();
22
- const inverseCameraValues = inverseCamera.toFloat64Array();
23
- if (![...inverseCameraValues].every(Number.isFinite)) {
24
- throw new Error('Singular 3D transform');
25
- }
26
- backend.raycaster.origin[0] = backend.camera.position[0];
27
- backend.raycaster.origin[1] = backend.camera.position[1];
28
- backend.raycaster.origin[2] = backend.camera.position[2];
29
- const unprojected = new DOMPoint(
30
- ((event.clientX - rect.left) / rect.width) * 2 - 1,
31
- -((event.clientY - rect.top) / rect.height) * 2 + 1,
32
- 0,
33
- 1
34
- ).matrixTransform(inverseCamera);
35
- const end = [
36
- unprojected.x / unprojected.w,
37
- unprojected.y / unprojected.w,
38
- unprojected.z / unprojected.w
39
- ];
40
- backend.raycaster.direction[0] = end[0] - backend.raycaster.origin[0];
41
- backend.raycaster.direction[1] = end[1] - backend.raycaster.origin[1];
42
- backend.raycaster.direction[2] = end[2] - backend.raycaster.origin[2];
43
- const rayLength = Math.hypot(...backend.raycaster.direction) || 1;
44
- backend.raycaster.direction[0] /= rayLength;
45
- backend.raycaster.direction[1] /= rayLength;
46
- backend.raycaster.direction[2] /= rayLength;
47
- const meshes = [];
48
- for (const object of objects) {
49
- if (recursive) traverse(object, mesh => { if
50
- (mesh.geometry && mesh.visible) meshes.push(mesh);
51
- });
52
- else if (object.geometry && object.visible) meshes.push(object);
53
- }
54
- return intersectMeshes(backend.raycaster, meshes, backend.renderer.uniformData?.[55]);
55
- }
56
-
57
- /**
58
- * Translate a geometry hit into a configured model or batched source feature.
59
- * Sorted half-open face ranges permit binary search without a feature per triangle.
60
- * @returns {PickedFeature|null}
61
- */
62
- export function findFeature(backend, event) {
63
- if (!backend.root || !backend.camera) return null;
64
- for (const hit of backend.raycast(event, backend.root.children, Boolean(backend.model))) {
65
- if (backend.model) {
66
- let object = hit.object;
67
- while (object && object !== backend.model) object = object.parent;
68
- if (object === backend.model) {
69
- return {
70
- id: backend.model.id, properties: backend.model.extras,
71
- model: backend.model, mesh: hit.object, point: hit.point
72
- };
73
- }
74
- }
75
- const ranges = hit.object.extras?.featureFaces;
76
- if (!ranges) continue;
77
- let low = 0, high = ranges.length - 1;
78
- while (low <= high) {
79
- const middle = (low + high) >> 1;
80
- const range = ranges[middle];
81
- if (hit.faceIndex < range.faceStart) high = middle - 1;
82
- else if (hit.faceIndex >= range.faceEnd) low = middle + 1;
83
- else return { ...range, mesh: hit.object, point: hit.point };
84
- }
85
- }
86
- return null;
87
- }
88
-
89
- /** Highlight a source vertex range in the shader; vertex colors stay untouched. */
90
- export function setHighlight(backend, feature) {
91
- if (feature?.model) feature = null;
92
- if (backend.highlightedFeature?.mesh === feature?.mesh &&
93
- backend.highlightedFeature?.vertexStart === feature?.vertexStart) return;
94
- if (backend.highlightedFeature) backend.highlightedFeature.mesh.highlight = null;
95
- backend.highlightedFeature = feature;
96
- if (feature) feature.mesh.highlight = [feature.vertexStart, feature.vertexEnd];
97
- backend.update();
98
- }
99
-
100
- /** Update tooltip content/position and arbitrate cursor ownership across shared layers. */
101
- export function showFeature(backend, feature, event) {
102
- const tooltip = backend._tooltip;
103
- if (!tooltip) return;
104
- if (feature) {
105
- tooltip.replaceChildren(backend.options.tooltipContent(feature));
106
- tooltip.hidden = false;
107
- const rect = backend.container.getBoundingClientRect();
108
- const x = event.clientX - rect.left, y = event.clientY - rect.top;
109
- tooltip.style.left = `${x + tooltip.offsetWidth + 16 > rect.width ? x - tooltip.offsetWidth - 12 : x + 12}px`;
110
- tooltip.style.top = `${y + tooltip.offsetHeight + 16 > rect.height ? y - tooltip.offsetHeight - 12 : y + 12}px`;
111
- } else {
112
- tooltip.hidden = true;
113
- }
114
- const shared = backend._shared;
115
- if (shared) {
116
- const visible = [...shared._layers].some(layer => layer._tooltip && !layer._tooltip.hidden);
117
- if (visible) {
118
- if (shared._cursor === undefined) shared._cursor = backend.container.style.cursor;
119
- backend.container.style.cursor = 'pointer';
120
- } else if (shared._cursor !== undefined) {
121
- backend.container.style.cursor = shared._cursor;
122
- delete shared._cursor;
123
- }
124
- }
125
- }
126
-
127
- /** Hover is transient; featurehover also reports misses with feature:null. */
128
- export function onPointerMove(backend, event) {
129
- backend.hoveredFeature = backend._findFeature(event);
130
- backend._setHighlight(backend.hoveredFeature);
131
- backend._showFeature(backend.hoveredFeature, event);
132
- backend.fire('featurehover', { feature: backend.hoveredFeature, originalEvent: event });
133
- }
134
-
135
- /** Emit click without moving the map or pinning the tooltip. */
136
- export function onClick(backend, event) {
137
- const feature = backend._findFeature(event);
138
- backend.hoveredFeature = feature;
139
- backend._setHighlight(feature);
140
- backend._showFeature(feature, event);
141
- backend.fire('featureclick', { feature, originalEvent: event });
142
- }
143
-
144
- /** Clear hover, highlight and tooltip without retaining a selected feature. */
145
- export function onPointerLeave(backend) {
146
- backend.hoveredFeature = null;
147
- backend._setHighlight(null);
148
- backend._showFeature(null);
149
- backend.fire('featurehover', { feature: null });
150
- }
@@ -1,94 +0,0 @@
1
- import { decodeHeader, decodeDirectory, decompress, tileId } from '../utils/pmtiles.js';
2
-
3
- /**
4
- * PMTiles v3 range reader.
5
- * Supports uncompressed/gzip sections. Other compression methods fail explicitly.
6
- * Specification: https://github.com/protomaps/PMTiles/blob/main/spec/v3/spec.md
7
- */
8
- /** Read exactly one archive range; reject changed archives rather than mix revisions. */
9
- export async function read(backend, offset, length, signal) {
10
- signal?.throwIfAborted();
11
- if (!Number.isSafeInteger(offset) || !Number.isSafeInteger(length) ||
12
- offset < 0 || length <= 0 || !Number.isSafeInteger(offset + length)) {
13
- throw new Error('Invalid PMTiles byte range');
14
- }
15
- const response = await fetch(backend.url, {
16
- headers: { Range: `bytes=${offset}-${offset + length - 1}` }, signal,
17
- });
18
- if (!response.ok) throw new Error(`Unable to read PMTiles: HTTP ${response.status}`);
19
- const etag = response.headers.get('ETag');
20
- if (backend._etag && etag !== backend._etag) {
21
- throw new Error('PMTiles archive changed; recreate the layer');
22
- }
23
- if (etag) {
24
- backend._etag = etag;
25
- }
26
- let data = await response.arrayBuffer();
27
- if (response.status === 200) {
28
- data = data.slice(offset, offset + length);
29
- } else if (response.status !== 206 || !response.headers.get('Content-Range')?.startsWith(`bytes ${offset}-${offset + length - 1}/`)) {
30
- throw new Error('Invalid PMTiles range response');
31
- }
32
- if (data.byteLength !== length) {
33
- throw new Error('Truncated PMTiles range');
34
- }
35
- return data;
36
- }
37
-
38
- /** Cache header initialization; failures remain visible to all callers. */
39
- export function getHeader(backend) {
40
- return backend._header ||= backend._read(0, 127).then(decodeHeader);
41
- }
42
-
43
- /** Nearest directory entry at/before the Hilbert ID, then follow leaf pointers. */
44
- export async function getZxy(backend, z, x, y, signal) {
45
- const id = tileId(z, x, y);
46
- signal?.throwIfAborted();
47
- const header = await backend.getHeader();
48
- signal?.throwIfAborted();
49
- if (z < header.minZoom || z > header.maxZoom) return;
50
- let offset = header.rootDirectoryOffset, length = header.rootDirectoryLength;
51
- const visited = new Set();
52
- for (let depth = 0; depth < 4; depth++) {
53
- if (visited.has(offset)) {
54
- throw new Error('Cyclic PMTiles directory');
55
- }
56
- visited.add(offset);
57
- const key = `${offset}:${length}`;
58
- if (!backend._directories.has(key)) {
59
- if (backend._directories.size >= 32) {
60
- backend._directories.delete(backend._directories.keys().next().value);
61
- }
62
- const pending = backend._read(offset, length)
63
- .then(data => decompress(data, header.internalCompression))
64
- .then(decodeDirectory)
65
- .catch(error => {
66
- if (backend._directories.get(key) === pending) backend._directories.delete(key);
67
- throw error;
68
- });
69
- backend._directories.set(key, pending);
70
- }
71
- const entries = await backend._directories.get(key);
72
- signal?.throwIfAborted();
73
- let low = 0,
74
- high = entries.length - 1;
75
- while (low <= high) {
76
- const mid = (low + high) >> 1;
77
- if (entries[mid].tileId <= id) low = mid + 1;
78
- else high = mid - 1;
79
- }
80
- const entry = entries[high];
81
- if (!entry) return;
82
- if (entry.runLength) {
83
- if (id - entry.tileId >= entry.runLength) return;
84
- if (entry.offset + entry.length > header.tileDataLength) throw new Error('PMTiles tile outside data section');
85
- const data = await decompress(await backend._read(header.tileDataOffset + entry.offset, entry.length, signal), header.tileCompression);
86
- signal?.throwIfAborted();
87
- return { data };
88
- }
89
- if (entry.offset + entry.length > header.leafDirectoryLength) throw new Error('PMTiles directory outside leaf section');
90
- offset = header.leafDirectoryOffset + entry.offset;
91
- length = entry.length;
92
- }
93
- throw new Error('PMTiles directory depth exceeds four levels');
94
- }