leaflet-city-mapper 0.0.1 → 0.0.2

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 (472) hide show
  1. package/README.md +15 -13
  2. package/cucumber.mjs +4 -0
  3. package/dist/leaflet-city-mapper.js +1 -1
  4. package/dist/leaflet-city-mapper.js.map +4 -4
  5. package/dist/utils/CELL.js +2 -0
  6. package/dist/utils/CELL.js.map +7 -0
  7. package/dist/utils/addBridges.js +2 -0
  8. package/dist/utils/addBridges.js.map +7 -0
  9. package/dist/utils/addRasterTile.js +2 -0
  10. package/dist/utils/addRasterTile.js.map +7 -0
  11. package/dist/utils/along.js +2 -0
  12. package/dist/utils/along.js.map +7 -0
  13. package/dist/utils/atmosphere.js +2 -0
  14. package/dist/utils/atmosphere.js.map +7 -0
  15. package/dist/utils/attach.js +2 -0
  16. package/dist/utils/attach.js.map +7 -0
  17. package/dist/utils/bindSunlight.js +2 -0
  18. package/dist/utils/bindSunlight.js.map +7 -0
  19. package/dist/utils/box.js +2 -0
  20. package/dist/utils/box.js.map +7 -0
  21. package/dist/utils/bridgeElevation.js +2 -0
  22. package/dist/utils/bridgeElevation.js.map +7 -0
  23. package/dist/utils/build.js +2 -0
  24. package/dist/utils/build.js.map +7 -0
  25. package/dist/utils/cameraControls.js +2 -0
  26. package/dist/utils/cameraControls.js.map +7 -0
  27. package/dist/utils/channel.js +2 -0
  28. package/dist/utils/channel.js.map +7 -0
  29. package/dist/utils/collider.js +2 -0
  30. package/dist/utils/collider.js.map +7 -0
  31. package/dist/utils/colliders.js +2 -0
  32. package/dist/utils/colliders.js.map +7 -0
  33. package/dist/utils/computeBounds.js +2 -0
  34. package/dist/utils/computeBounds.js.map +7 -0
  35. package/dist/utils/conformModelToTerrain.js +2 -0
  36. package/dist/utils/conformModelToTerrain.js.map +7 -0
  37. package/dist/utils/createMesh.js +2 -0
  38. package/dist/utils/createMesh.js.map +7 -0
  39. package/dist/utils/createProgram.js +3 -0
  40. package/dist/utils/createProgram.js.map +7 -0
  41. package/dist/utils/decodeDirectory.js +2 -0
  42. package/dist/utils/decodeDirectory.js.map +7 -0
  43. package/dist/utils/decodeHeader.js +2 -0
  44. package/dist/utils/decodeHeader.js.map +7 -0
  45. package/dist/utils/decodeModel.js +2 -0
  46. package/dist/utils/decodeModel.js.map +7 -0
  47. package/dist/utils/decompress.js +2 -0
  48. package/dist/utils/decompress.js.map +7 -0
  49. package/dist/utils/destroyTexture.js +2 -0
  50. package/dist/utils/destroyTexture.js.map +7 -0
  51. package/dist/utils/disposeMesh.js +2 -0
  52. package/dist/utils/disposeMesh.js.map +7 -0
  53. package/dist/utils/drawGeometry.js +2 -0
  54. package/dist/utils/drawGeometry.js.map +7 -0
  55. package/dist/utils/elevationWGSL.js +24 -0
  56. package/dist/utils/elevationWGSL.js.map +7 -0
  57. package/dist/utils/emptyNode.js +2 -0
  58. package/dist/utils/emptyNode.js.map +7 -0
  59. package/dist/utils/endZoom.js +2 -0
  60. package/dist/utils/endZoom.js.map +7 -0
  61. package/dist/utils/findFeature.js +2 -0
  62. package/dist/utils/findFeature.js.map +7 -0
  63. package/dist/utils/geometry.js +0 -1
  64. package/dist/utils/geometry.js.map +4 -4
  65. package/dist/utils/getElevation.js +2 -0
  66. package/dist/utils/getElevation.js.map +7 -0
  67. package/dist/utils/getHeader.js +2 -0
  68. package/dist/utils/getHeader.js.map +7 -0
  69. package/dist/utils/getZxy.js +2 -0
  70. package/dist/utils/getZxy.js.map +7 -0
  71. package/dist/utils/glass.js +2 -0
  72. package/dist/utils/glass.js.map +7 -0
  73. package/dist/utils/headlight.js +2 -0
  74. package/dist/utils/headlight.js.map +7 -0
  75. package/dist/utils/hit.js +2 -0
  76. package/dist/utils/hit.js.map +7 -0
  77. package/dist/utils/horizontalPosition.js +2 -0
  78. package/dist/utils/horizontalPosition.js.map +7 -0
  79. package/dist/utils/horizontalRay.js +2 -0
  80. package/dist/utils/horizontalRay.js.map +7 -0
  81. package/dist/utils/hull.js +2 -0
  82. package/dist/utils/hull.js.map +7 -0
  83. package/dist/utils/initSunlight.js +2 -0
  84. package/dist/utils/initSunlight.js.map +7 -0
  85. package/dist/utils/initTerrain.js +2 -0
  86. package/dist/utils/initTerrain.js.map +7 -0
  87. package/dist/utils/initTraffic.js +40 -0
  88. package/dist/utils/initTraffic.js.map +7 -0
  89. package/dist/utils/initWalk.js +2 -0
  90. package/dist/utils/initWalk.js.map +7 -0
  91. package/dist/utils/intersectMeshes.js +2 -0
  92. package/dist/utils/intersectMeshes.js.map +7 -0
  93. package/dist/utils/isClockWise.js +2 -0
  94. package/dist/utils/isClockWise.js.map +7 -0
  95. package/dist/utils/lampPostGeometry.js +2 -0
  96. package/dist/utils/lampPostGeometry.js.map +7 -0
  97. package/dist/utils/lightGeometry.js +2 -0
  98. package/dist/utils/lightGeometry.js.map +7 -0
  99. package/dist/utils/lightGrid.js +2 -0
  100. package/dist/utils/lightGrid.js.map +7 -0
  101. package/dist/utils/limbs.js +2 -0
  102. package/dist/utils/limbs.js.map +7 -0
  103. package/dist/utils/loadModel.js +2 -0
  104. package/dist/utils/loadModel.js.map +7 -0
  105. package/dist/utils/loadSource.js +2 -0
  106. package/dist/utils/loadSource.js.map +7 -0
  107. package/dist/utils/loadTerrain.js +2 -0
  108. package/dist/utils/loadTerrain.js.map +7 -0
  109. package/dist/utils/mapCamera.js +2 -0
  110. package/dist/utils/mapCamera.js.map +7 -0
  111. package/dist/utils/{shaders.js → materialShaders.js} +16 -8
  112. package/dist/utils/materialShaders.js.map +7 -0
  113. package/dist/utils/mirror.js +2 -0
  114. package/dist/utils/mirror.js.map +7 -0
  115. package/dist/utils/moonPosition.js +2 -0
  116. package/dist/utils/moonPosition.js.map +7 -0
  117. package/dist/utils/moves.js +2 -0
  118. package/dist/utils/moves.js.map +7 -0
  119. package/dist/utils/nativeEvents.js +2 -0
  120. package/dist/utils/nativeEvents.js.map +7 -0
  121. package/dist/utils/nativeGeometry.js +2 -0
  122. package/dist/utils/nativeGeometry.js.map +7 -0
  123. package/dist/utils/nativeLayer.js +2 -0
  124. package/dist/utils/nativeLayer.js.map +7 -0
  125. package/dist/utils/nodeMatrix.js +2 -0
  126. package/dist/utils/nodeMatrix.js.map +7 -0
  127. package/dist/utils/onAdd3DLayer.js +2 -0
  128. package/dist/utils/onAdd3DLayer.js.map +7 -0
  129. package/dist/utils/onAddSun.js +2 -0
  130. package/dist/utils/onAddSun.js.map +7 -0
  131. package/dist/utils/onClick.js +2 -0
  132. package/dist/utils/onClick.js.map +7 -0
  133. package/dist/utils/onMapChange.js +2 -0
  134. package/dist/utils/onMapChange.js.map +7 -0
  135. package/dist/utils/onPMTileAdd.js +2 -0
  136. package/dist/utils/onPMTileAdd.js.map +7 -0
  137. package/dist/utils/onPMTileRemove.js +2 -0
  138. package/dist/utils/onPMTileRemove.js.map +7 -0
  139. package/dist/utils/onPointerLeave.js +2 -0
  140. package/dist/utils/onPointerLeave.js.map +7 -0
  141. package/dist/utils/onPointerMove.js +2 -0
  142. package/dist/utils/onPointerMove.js.map +7 -0
  143. package/dist/utils/onRemove3DLayer.js +2 -0
  144. package/dist/utils/onRemove3DLayer.js.map +7 -0
  145. package/dist/utils/onRemoveSun.js +2 -0
  146. package/dist/utils/onRemoveSun.js.map +7 -0
  147. package/dist/utils/onTerrainAdd.js +2 -0
  148. package/dist/utils/onTerrainAdd.js.map +7 -0
  149. package/dist/utils/onTerrainChange.js +2 -0
  150. package/dist/utils/onTerrainChange.js.map +7 -0
  151. package/dist/utils/onTerrainRemove.js +2 -0
  152. package/dist/utils/onTerrainRemove.js.map +7 -0
  153. package/dist/utils/onZoomAnim.js +2 -0
  154. package/dist/utils/onZoomAnim.js.map +7 -0
  155. package/dist/utils/paints.js +2 -0
  156. package/dist/utils/paints.js.map +7 -0
  157. package/dist/utils/parseColor.js +2 -0
  158. package/dist/utils/parseColor.js.map +7 -0
  159. package/dist/utils/parts.js +2 -0
  160. package/dist/utils/parts.js.map +7 -0
  161. package/dist/utils/projectCelestialBody.js +2 -0
  162. package/dist/utils/projectCelestialBody.js.map +7 -0
  163. package/dist/utils/pump.js +2 -0
  164. package/dist/utils/pump.js.map +7 -0
  165. package/dist/utils/rasterTiles.js +2 -0
  166. package/dist/utils/rasterTiles.js.map +7 -0
  167. package/dist/utils/raycast.js +2 -0
  168. package/dist/utils/raycast.js.map +7 -0
  169. package/dist/utils/read.js +2 -0
  170. package/dist/utils/read.js.map +7 -0
  171. package/dist/utils/readAccessor.js +2 -0
  172. package/dist/utils/readAccessor.js.map +7 -0
  173. package/dist/utils/releaseArea.js +2 -0
  174. package/dist/utils/releaseArea.js.map +7 -0
  175. package/dist/utils/removeRasterTile.js +2 -0
  176. package/dist/utils/removeRasterTile.js.map +7 -0
  177. package/dist/utils/render.js +15 -0
  178. package/dist/utils/render.js.map +7 -0
  179. package/dist/utils/renderSunlight.js +13 -0
  180. package/dist/utils/renderSunlight.js.map +7 -0
  181. package/dist/utils/renderers.js +2 -0
  182. package/dist/utils/renderers.js.map +7 -0
  183. package/dist/utils/resizeSunlight.js +2 -0
  184. package/dist/utils/resizeSunlight.js.map +7 -0
  185. package/dist/utils/roofCoverage.js +2 -0
  186. package/dist/utils/roofCoverage.js.map +7 -0
  187. package/dist/utils/routeGeometry.js +2 -0
  188. package/dist/utils/routeGeometry.js.map +7 -0
  189. package/dist/utils/scheduledTrips.js +2 -0
  190. package/dist/utils/scheduledTrips.js.map +7 -0
  191. package/dist/utils/setGeoJSONData.js +2 -0
  192. package/dist/utils/setGeoJSONData.js.map +7 -0
  193. package/dist/utils/setHighlight.js +2 -0
  194. package/dist/utils/setHighlight.js.map +7 -0
  195. package/dist/utils/setPMTileOpacity.js +2 -0
  196. package/dist/utils/setPMTileOpacity.js.map +7 -0
  197. package/dist/utils/setPMTileZIndex.js +2 -0
  198. package/dist/utils/setPMTileZIndex.js.map +7 -0
  199. package/dist/utils/setParent.js +2 -0
  200. package/dist/utils/setParent.js.map +7 -0
  201. package/dist/utils/setTerrainHeight.js +2 -0
  202. package/dist/utils/setTerrainHeight.js.map +7 -0
  203. package/dist/utils/setVertexColor.js +2 -0
  204. package/dist/utils/setVertexColor.js.map +7 -0
  205. package/dist/utils/showFeature.js +2 -0
  206. package/dist/utils/showFeature.js.map +7 -0
  207. package/dist/utils/sizes.js +2 -0
  208. package/dist/utils/sizes.js.map +7 -0
  209. package/dist/utils/skin.js +2 -0
  210. package/dist/utils/skin.js.map +7 -0
  211. package/dist/utils/solarPosition.js +2 -0
  212. package/dist/utils/solarPosition.js.map +7 -0
  213. package/dist/utils/sortMeshes.js +2 -0
  214. package/dist/utils/sortMeshes.js.map +7 -0
  215. package/dist/utils/speed.js +2 -0
  216. package/dist/utils/speed.js.map +7 -0
  217. package/dist/utils/startZoom.js +2 -0
  218. package/dist/utils/startZoom.js.map +7 -0
  219. package/dist/utils/taillight.js +2 -0
  220. package/dist/utils/taillight.js.map +7 -0
  221. package/dist/utils/terrainAtlas.js +2 -0
  222. package/dist/utils/terrainAtlas.js.map +7 -0
  223. package/dist/utils/terrainElevation.js +2 -0
  224. package/dist/utils/terrainElevation.js.map +7 -0
  225. package/dist/utils/terrainGrid.js +2 -0
  226. package/dist/utils/terrainGrid.js.map +7 -0
  227. package/dist/utils/textureSampler.js +2 -0
  228. package/dist/utils/textureSampler.js.map +7 -0
  229. package/dist/utils/tileId.js +2 -0
  230. package/dist/utils/tileId.js.map +7 -0
  231. package/dist/utils/toLanes.js +2 -0
  232. package/dist/utils/toLanes.js.map +7 -0
  233. package/dist/utils/toSRGB.js +2 -0
  234. package/dist/utils/toSRGB.js.map +7 -0
  235. package/dist/utils/tooltip.js +3 -0
  236. package/dist/utils/tooltip.js.map +7 -0
  237. package/dist/utils/traffic.js +1 -1
  238. package/dist/utils/traffic.js.map +3 -3
  239. package/dist/utils/traverse.js +2 -0
  240. package/dist/utils/traverse.js.map +7 -0
  241. package/dist/utils/treeGeometry.js +2 -0
  242. package/dist/utils/treeGeometry.js.map +7 -0
  243. package/dist/utils/triangulate.js +2 -0
  244. package/dist/utils/triangulate.js.map +7 -0
  245. package/dist/utils/tripsAt.js +2 -0
  246. package/dist/utils/tripsAt.js.map +7 -0
  247. package/dist/utils/types.js +2 -0
  248. package/dist/utils/types.js.map +7 -0
  249. package/dist/utils/underEntry.js +2 -0
  250. package/dist/utils/underEntry.js.map +7 -0
  251. package/dist/utils/update.js +2 -0
  252. package/dist/utils/update.js.map +7 -0
  253. package/dist/utils/updateArea.js +2 -0
  254. package/dist/utils/updateArea.js.map +7 -0
  255. package/dist/utils/updateCamera.js +2 -0
  256. package/dist/utils/updateCamera.js.map +7 -0
  257. package/dist/utils/updatePointLights.js +2 -0
  258. package/dist/utils/updatePointLights.js.map +7 -0
  259. package/dist/utils/updateWorldMatrix.js +2 -0
  260. package/dist/utils/updateWorldMatrix.js.map +7 -0
  261. package/dist/utils/vehicleOffsets.js +2 -0
  262. package/dist/utils/vehicleOffsets.js.map +7 -0
  263. package/dist/utils/vehicles.js +1 -1
  264. package/dist/utils/vehicles.js.map +3 -3
  265. package/dist/utils/vertexNormals.js +2 -0
  266. package/dist/utils/vertexNormals.js.map +7 -0
  267. package/dist/utils/walk.js +1 -1
  268. package/dist/utils/walk.js.map +3 -3
  269. package/dist/utils/white.js +2 -0
  270. package/dist/utils/white.js.map +7 -0
  271. package/dist/utils/worldLights.js +2 -0
  272. package/dist/utils/worldLights.js.map +7 -0
  273. package/dist/utils/wrap.js +2 -0
  274. package/dist/utils/wrap.js.map +7 -0
  275. package/package.json +2 -4
  276. package/src/index.js +365 -50
  277. package/src/utils/CELL.js +4 -0
  278. package/src/utils/addBridges.js +66 -0
  279. package/src/utils/addRasterTile.js +112 -0
  280. package/src/utils/along.js +9 -0
  281. package/src/utils/atmosphere.js +20 -0
  282. package/src/utils/attach.js +255 -0
  283. package/src/utils/bindSunlight.js +12 -0
  284. package/src/utils/box.js +1 -0
  285. package/src/utils/bridgeElevation.js +18 -0
  286. package/src/utils/build.js +20 -0
  287. package/src/utils/cameraControls.js +287 -0
  288. package/src/utils/channel.js +4 -0
  289. package/src/utils/collider.js +62 -0
  290. package/src/utils/colliders.js +2 -0
  291. package/src/utils/computeBounds.js +17 -0
  292. package/src/utils/conformModelToTerrain.js +69 -0
  293. package/src/utils/createMesh.js +31 -0
  294. package/src/utils/createProgram.js +92 -0
  295. package/src/utils/decodeDirectory.js +40 -0
  296. package/src/utils/decodeHeader.js +15 -0
  297. package/src/utils/decodeModel.js +43 -0
  298. package/src/utils/decompress.js +5 -0
  299. package/src/utils/destroyTexture.js +7 -0
  300. package/src/utils/disposeMesh.js +13 -0
  301. package/src/utils/drawGeometry.js +122 -0
  302. package/src/utils/elevationWGSL.js +27 -0
  303. package/src/utils/emptyNode.js +9 -0
  304. package/src/utils/endZoom.js +15 -0
  305. package/src/utils/findFeature.js +49 -0
  306. package/src/utils/geometry.js +0 -254
  307. package/src/utils/getElevation.js +10 -0
  308. package/src/utils/getHeader.js +9 -0
  309. package/src/utils/getZxy.js +76 -0
  310. package/src/utils/glass.js +1 -0
  311. package/src/utils/headlight.js +1 -0
  312. package/src/utils/hit.js +41 -0
  313. package/src/utils/horizontalPosition.js +16 -0
  314. package/src/utils/horizontalRay.js +12 -0
  315. package/src/utils/hull.js +1 -0
  316. package/src/utils/initSunlight.js +9 -0
  317. package/src/utils/initTerrain.js +19 -0
  318. package/src/utils/initTraffic.js +93 -0
  319. package/src/utils/initWalk.js +72 -0
  320. package/src/utils/{picking.js → intersectMeshes.js} +121 -119
  321. package/src/utils/isClockWise.js +12 -0
  322. package/src/utils/lampPostGeometry.js +26 -0
  323. package/src/utils/lightGeometry.js +22 -0
  324. package/src/utils/{lighting.js → lightGrid.js} +50 -51
  325. package/src/utils/limbs.js +9 -0
  326. package/src/{scene/model.js → utils/loadModel.js} +37 -24
  327. package/src/utils/loadSource.js +17 -0
  328. package/src/utils/loadTerrain.js +65 -0
  329. package/src/utils/mapCamera.js +432 -0
  330. package/src/utils/{shaders.js → materialShaders.js} +243 -237
  331. package/src/utils/mirror.js +6 -0
  332. package/src/utils/moonPosition.js +17 -0
  333. package/src/utils/moves.js +11 -0
  334. package/src/utils/nativeEvents.js +77 -0
  335. package/src/utils/nativeGeometry.js +131 -0
  336. package/src/utils/nativeLayer.js +317 -0
  337. package/src/utils/nodeMatrix.js +22 -0
  338. package/src/utils/onAdd3DLayer.js +31 -0
  339. package/src/utils/onAddSun.js +147 -0
  340. package/src/utils/onClick.js +13 -0
  341. package/src/utils/onMapChange.js +16 -0
  342. package/src/utils/onPMTileAdd.js +15 -0
  343. package/src/utils/onPMTileRemove.js +8 -0
  344. package/src/utils/onPointerLeave.js +11 -0
  345. package/src/utils/onPointerMove.js +15 -0
  346. package/src/utils/onRemove3DLayer.js +78 -0
  347. package/src/utils/onRemoveSun.js +3 -0
  348. package/src/utils/onTerrainAdd.js +18 -0
  349. package/src/utils/onTerrainChange.js +13 -0
  350. package/src/utils/onTerrainRemove.js +40 -0
  351. package/src/utils/onZoomAnim.js +14 -0
  352. package/src/utils/paints.js +10 -0
  353. package/src/utils/parseColor.js +42 -0
  354. package/src/utils/parts.js +16 -0
  355. package/src/utils/projectCelestialBody.js +13 -0
  356. package/src/{scene/sources.js → utils/pump.js} +59 -98
  357. package/src/utils/rasterTiles.js +285 -0
  358. package/src/utils/raycast.js +60 -0
  359. package/src/utils/read.js +29 -0
  360. package/src/utils/readAccessor.js +68 -0
  361. package/src/utils/releaseArea.js +34 -0
  362. package/src/utils/removeRasterTile.js +13 -0
  363. package/src/{scene → utils}/render.js +112 -173
  364. package/src/utils/renderSunlight.js +170 -0
  365. package/src/utils/renderers.js +2 -0
  366. package/src/utils/resizeSunlight.js +15 -0
  367. package/src/utils/roofCoverage.js +47 -0
  368. package/src/utils/routeGeometry.js +22 -0
  369. package/src/utils/scheduledTrips.js +29 -0
  370. package/src/utils/setGeoJSONData.js +11 -0
  371. package/src/utils/setHighlight.js +13 -0
  372. package/src/utils/setPMTileOpacity.js +7 -0
  373. package/src/utils/setPMTileZIndex.js +7 -0
  374. package/src/utils/setParent.js +7 -0
  375. package/src/utils/setTerrainHeight.js +10 -0
  376. package/src/utils/setVertexColor.js +14 -0
  377. package/src/utils/showFeature.js +27 -0
  378. package/src/utils/sizes.js +1 -0
  379. package/src/utils/skin.js +2 -0
  380. package/src/utils/solarPosition.js +17 -0
  381. package/src/utils/sortMeshes.js +12 -0
  382. package/src/utils/speed.js +3 -0
  383. package/src/utils/startZoom.js +5 -0
  384. package/src/utils/taillight.js +1 -0
  385. package/src/utils/terrainAtlas.js +21 -0
  386. package/src/utils/terrainElevation.js +20 -0
  387. package/src/utils/terrainGrid.js +23 -0
  388. package/src/utils/textureSampler.js +10 -0
  389. package/src/utils/tileId.js +18 -0
  390. package/src/utils/toLanes.js +7 -0
  391. package/src/utils/toSRGB.js +1 -0
  392. package/src/utils/tooltip.js +6 -0
  393. package/src/utils/traffic.js +310 -85
  394. package/src/utils/traverse.js +6 -0
  395. package/src/utils/treeGeometry.js +45 -0
  396. package/src/utils/triangulate.js +100 -0
  397. package/src/utils/tripsAt.js +16 -0
  398. package/src/utils/types.js +8 -0
  399. package/src/utils/{control.js → underEntry.js} +1 -2
  400. package/src/utils/update.js +18 -0
  401. package/src/utils/updateArea.js +40 -0
  402. package/src/utils/updateCamera.js +32 -0
  403. package/src/utils/updatePointLights.js +38 -0
  404. package/src/utils/updateWorldMatrix.js +47 -0
  405. package/src/utils/vehicleOffsets.js +8 -0
  406. package/src/utils/vehicles.js +65 -69
  407. package/src/utils/vertexNormals.js +30 -0
  408. package/src/utils/walk.js +181 -66
  409. package/src/utils/white.js +1 -0
  410. package/src/utils/worldLights.js +25 -0
  411. package/src/utils/wrap.js +1 -0
  412. package/dist/scene/gpu.js +0 -3
  413. package/dist/scene/gpu.js.map +0 -7
  414. package/dist/scene/lighting.js +0 -9
  415. package/dist/scene/lighting.js.map +0 -7
  416. package/dist/scene/model.js +0 -2
  417. package/dist/scene/model.js.map +0 -7
  418. package/dist/scene/picking.js +0 -2
  419. package/dist/scene/picking.js.map +0 -7
  420. package/dist/scene/pmtiles.js +0 -2
  421. package/dist/scene/pmtiles.js.map +0 -7
  422. package/dist/scene/render.js +0 -15
  423. package/dist/scene/render.js.map +0 -7
  424. package/dist/scene/sources.js +0 -2
  425. package/dist/scene/sources.js.map +0 -7
  426. package/dist/types/3d.js +0 -2
  427. package/dist/types/3d.js.map +0 -7
  428. package/dist/types/geojson.js +0 -2
  429. package/dist/types/geojson.js.map +0 -7
  430. package/dist/types/pmtiles.js +0 -2
  431. package/dist/types/pmtiles.js.map +0 -7
  432. package/dist/types/sunlight.js +0 -2
  433. package/dist/types/sunlight.js.map +0 -7
  434. package/dist/types/terrain.js +0 -24
  435. package/dist/types/terrain.js.map +0 -7
  436. package/dist/types/traffic.js +0 -41
  437. package/dist/types/traffic.js.map +0 -7
  438. package/dist/types/walk.js +0 -2
  439. package/dist/types/walk.js.map +0 -7
  440. package/dist/utils/control.js +0 -2
  441. package/dist/utils/control.js.map +0 -7
  442. package/dist/utils/lighting.js +0 -2
  443. package/dist/utils/lighting.js.map +0 -7
  444. package/dist/utils/model.js +0 -2
  445. package/dist/utils/model.js.map +0 -7
  446. package/dist/utils/picking.js +0 -2
  447. package/dist/utils/picking.js.map +0 -7
  448. package/dist/utils/pmtiles.js +0 -2
  449. package/dist/utils/pmtiles.js.map +0 -7
  450. package/dist/utils/scene.js +0 -2
  451. package/dist/utils/scene.js.map +0 -7
  452. package/dist/utils/shaders.js.map +0 -7
  453. package/dist/utils/sun.js +0 -2
  454. package/dist/utils/sun.js.map +0 -7
  455. package/dist/utils/terrain.js +0 -2
  456. package/dist/utils/terrain.js.map +0 -7
  457. package/src/scene/gpu.js +0 -438
  458. package/src/scene/lighting.js +0 -193
  459. package/src/scene/picking.js +0 -150
  460. package/src/scene/pmtiles.js +0 -94
  461. package/src/types/3d.js +0 -337
  462. package/src/types/geojson.js +0 -42
  463. package/src/types/pmtiles.js +0 -143
  464. package/src/types/sunlight.js +0 -142
  465. package/src/types/terrain.js +0 -331
  466. package/src/types/traffic.js +0 -356
  467. package/src/types/walk.js +0 -219
  468. package/src/utils/model.js +0 -178
  469. package/src/utils/pmtiles.js +0 -79
  470. package/src/utils/scene.js +0 -102
  471. package/src/utils/sun.js +0 -71
  472. package/src/utils/terrain.js +0 -78
@@ -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
- }
package/src/types/3d.js DELETED
@@ -1,337 +0,0 @@
1
- /**
2
- * The '3d' layer type, loaded on demand by src/index.js.
3
- *
4
- * A native WebGPU scene drawn above the map tiles and kept in sync with the map camera
5
- * (center, zoom, bearing, pitch and zoom animations).
6
- *
7
- * No rendering dependencies. Use the `ready` event before using the helpers.
8
- * All instances on one map share a canvas, scene and camera, with one group per layer.
9
- *
10
- * World coordinates are metres relative to `location`: x east, y up, z south.
11
- * The shared scene instead uses the first attached layer's origin. `root` converts
12
- * each layer's local metres into that shared space, including latitude scaling.
13
- *
14
- * Lifecycle: initialize CPU state -> attach shared GPU device -> load configured
15
- * data/model -> ready. Removal cancels source work and detaches this layer only;
16
- * the last removal destroys the context. Model CPU arrays/images survive for re-add.
17
- *
18
- * This file holds the Leaflet lifecycle and explicit delegates to scene/ operations.
19
- * Stateless computations live in utils/; scene/ owns loading, GPU resources and interaction.
20
- * PMTiles v3 reading is implemented directly by this layer. Models are static triangles, without
21
- * animation, skinning, morph targets, normal maps or required extensions.
22
- *
23
- * Events: ready; error {error}; progress {enabled, loaded, skipped, pending, errors};
24
- * featurehover/featureclick {feature, originalEvent}. A feature may be null on a miss.
25
- * Picking tests geometry, not texture alpha: a transparent texel can still be hit.
26
- *
27
- * @example
28
- * new L.Layer({ source: { url: 'tower.glb', center: [48.8582601, 2.29449985] } }).addTo(map);
29
- * new L.Layer({ source: { type: '3d', url: 'buildings.pmtiles', featureStyle }, attribution }).addTo(map);
30
- * new L.Layer({ source: { type: 'terrain', url: 'terrain.pmtiles' } }).addTo(map);
31
- * new L.Layer({ source: { url: 'orthophotos.pmtiles', maxZoom: 24 } }).addTo(map);
32
- *
33
- * @typedef {Object} Layer3DOptions The `source` object; `pane`/`attribution` stay standard L.Layer options.
34
- * @property {string} [type] 'pmtiles' (raster tiles), '3d' (WebGPU scene) or 'terrain'; see L.Layer.types.
35
- * @property {number[]} [center] Local origin [lat,lng]; defaults to the first map center.
36
- * @property {number[]} [rotation] Model Euler rotation [x,y,z] in radians, YXZ order.
37
- * @property {number[]} [scale] Model scale [x,y,z]; independent of geographic scaling.
38
- * @property {string} [url] GLB/glTF model URL (loaded before ready), or PMTiles URL containing
39
- * Polygon/MultiPolygon or tree/light Point GeoJSON ('3d'), raster tiles ('pmtiles') or Float32 DEM ('terrain').
40
- * @property {function(Object): (ExtrusionStyle|null)} [featureStyle] Source styling; null skips.
41
- * @property {function(PickedFeature): (Node|string)} [tooltipContent] No HTML string evaluation.
42
- * @property {string} [ariaLabel='3D scene'] Shared canvas accessible name.
43
- * @property {boolean} [nightLight=false] Point sources: emissive bulbs and local illumination.
44
- * @property {boolean} [nightSparkle=false] Model: sparse luminous points at night.
45
- *
46
- * @typedef {Object} ExtrusionStyle
47
- * @property {number} top Roof height in metres; must exceed bottom.
48
- * @property {number} [bottom=0] Nonnegative base height; positive values create an underside.
49
- * @property {number|string|Object} [color=0xd9b38c] RGB/CSS color, or linear-space {h,s,l}.
50
- * @property {number} [trunkRadius] Point trees: trunk radius in metres.
51
- * @property {number} [crownRadius] Point trees: maximum crown radius in metres.
52
- * @property {number} [crownBottom] Point trees: crown base in metres, between bottom and top.
53
- * @property {string} [crownShape='round'] Point trees: 'round' or 'cone' schematic crown.
54
- * @property {number|string|Object} [trunkColor=0x72513a] Point trees: bark color.
55
- * @property {number} [lightRadius] Point lights: estimated ground reach in metres; top is emitter height.
56
- * @property {number} [lightFlux] Point lights: luminous flux in lumens.
57
- *
58
- * @typedef {Object} PickedFeature
59
- * @property {string|number} id Source feature id or configured model URL.
60
- * @property {Object} properties GeoJSON properties or model-level glTF extras.
61
- * @property {Object} mesh Intersected mesh.
62
- * @property {number[]} point Intersection [x,y,z] in shared scene metres, not layer-local metres.
63
- * @property {Object} [model] Configured model root; absent for source polygons.
64
- * @property {number} [vertexStart] First polygon vertex in the batched mesh.
65
- * @property {number} [vertexEnd] Exclusive end of the polygon's vertex range.
66
- *
67
- * @typedef {Object} SourceArea
68
- * @property {Object} coords Archive block {z,x,y}; z is header.minZoom, not display zoom.
69
- * @property {AbortController} request Cancellation also prevents attaching obsolete results.
70
- * @property {boolean} [started] Enqueued work has consumed a concurrency slot.
71
- * @property {boolean} [done] Geometry built successfully, including empty blocks.
72
- * @property {Object|null} [mesh] One batched GPU mesh per non-empty block.
73
- * @property {number} [buildings] Emitted feature count, not number of triangles.
74
- * @property {number} [skipped] Features intentionally skipped by featureStyle.
75
- * @property {string} [error] Failed load/build message; reported through error and progress.
76
- *
77
- * @since leaflet-rotate (v0.6.0)
78
- */
79
-
80
- import * as shapes from '../utils/geometry.js';
81
- import * as gpu from '../scene/gpu.js';
82
- import * as lighting from '../scene/lighting.js';
83
- import * as model from '../scene/model.js';
84
- import * as picking from '../scene/picking.js';
85
- import * as pmtiles from '../scene/pmtiles.js';
86
- import * as archive from '../utils/pmtiles.js';
87
- import * as render from '../scene/render.js';
88
- import * as graph from '../utils/scene.js';
89
- import * as sources from '../scene/sources.js';
90
-
91
- L.Layer.types['3d'] = L.Layer.extend({
92
- color(value) { return shapes.parseColor(value); },
93
- _setVertexColor(mesh, start, end, color) { shapes.setVertexColor(mesh, start, end, color); return this.update(); },
94
- _triangulate(contour, holes) { return shapes.triangulate(contour, holes); },
95
- _isClockWise(points) { return shapes.isClockWise(points); },
96
- _treeGeometry(point, style, addTriangle) { return shapes.treeGeometry(point, style, addTriangle); },
97
- _lightGeometry(point, style, addTriangle) { return shapes.lightGeometry(point, style, addTriangle); },
98
- _lampPostGeometry(point, style, addTriangle) { return shapes.lampPostGeometry(point, style, addTriangle); },
99
- _attach(map) { return gpu.attach(this, map); },
100
- _destroyTexture(texture) { return gpu.destroyTexture(this, texture); },
101
- _createProgram(material) { return gpu.createProgram(this, material); },
102
- _removeProgram(program) { return gpu.removeProgram(program); },
103
- _createMesh(data, material, usage) { return gpu.createMesh(this, data, material, usage); },
104
- _disposeMesh(mesh) { return gpu.disposeMesh(this, mesh); },
105
- _computeBounds(geometry) { return shapes.computeBounds(geometry); },
106
- _drawGeometry(mesh, pass, cullMode, frontFace) { return gpu.drawGeometry(this, mesh, pass, cullMode, frontFace); },
107
- _initSunlight() { return lighting.initSunlight(this); },
108
- _resizeSunlight(size) { return lighting.resizeSunlight(this, size); },
109
- _bindSunlight() { return lighting.bindSunlight(this); },
110
- _updatePointLights() { return lighting.updatePointLights(this); },
111
- _renderSunlight(encoder, meshes, sunlight) { return lighting.renderSunlight(this, encoder, meshes, sunlight); },
112
- _loadModel() { return model.loadModel(this); },
113
- raycast(event, objects, recursive) { return picking.raycast(this, event, objects, recursive); },
114
- _findFeature(event) { return picking.findFeature(this, event); },
115
- _setHighlight(feature) { return picking.setHighlight(this, feature); },
116
- _showFeature(feature, event) { return picking.showFeature(this, feature, event); },
117
- _onPointerMove(event) { return picking.onPointerMove(this, event); },
118
- _onClick(event) { return picking.onClick(this, event); },
119
- _onPointerLeave() { return picking.onPointerLeave(this); },
120
- _read(offset, length, signal) { return pmtiles.read(this, offset, length, signal); },
121
- _decompress(data, compression) { return archive.decompress(data, compression); },
122
- getHeader() { return pmtiles.getHeader(this); },
123
- getZxy(z, x, y, signal) { return pmtiles.getZxy(this, z, x, y, signal); },
124
- update() { return render.update(this); },
125
- _onMapChange() { return render.onMapChange(this); },
126
- _getTileLevel() { return render.getTileLevel(this); },
127
- _startZoom() { return render.startZoom(this); },
128
- _endZoom() { return render.endZoom(this); },
129
- _render() { return render.render(this); },
130
- setParent(node, parent) { return graph.setParent(node, parent); },
131
- traverse(node, callback) { return graph.traverse(node, callback); },
132
- _updateWorldMatrix(node) { return graph.updateWorldMatrix(node); },
133
- _updateCamera(camera) { return graph.updateCamera(camera); },
134
- _onTerrainChange() { return sources.onTerrainChange(this); },
135
- _updateArea() { return sources.updateArea(this); },
136
- _pump() { return sources.pump(this); },
137
- _loadSource(area) { return sources.loadSource(this, area); },
138
- _releaseArea(area) { return sources.releaseArea(this, area); },
139
- _updateStatus(enabled) { return sources.updateStatus(this, enabled); },
140
-
141
- statics: {
142
- /** Rendering owner per map; entries are removed on the last layer removal. */
143
- _renderers: new WeakMap(),
144
- },
145
-
146
- options: {
147
- // Accessible description of the canvas.
148
- ariaLabel: '3D scene',
149
- },
150
-
151
- /**
152
- * @param {Layer3DOptions} [options] World origin comes from center or the first map centre.
153
- * Public state: `location` is fixed after first addition; `root` is this layer's
154
- * transform; `group` aliases root only for sources; `model` is the configured
155
- * model wrapper. `_shared` references the rendering owner (a '3d' layer);
156
- * `scene`, `camera` and `renderer` alias its resources while attached.
157
- *
158
- */
159
- initialize(options) {
160
- L.Util.setOptions(this, options);
161
- // ponytail: models are recognised by extension; extensionless model URLs need a .glb/.gltf suffix or query.
162
- const model = !this._geojson && /\.(glb|gltf)(?:[?#]|$)/i.test(this.options.url);
163
- this.modelUrl = model ? this.options.url : null;
164
- this.url = this.options.url && !model && !this._geojson ? new URL(this.options.url, document.baseURI).href : null;
165
- this._directories = new Map();
166
- if (this.options.center) {
167
- this.location = new L.LatLng(this.options.center[0], this.options.center[1]);
168
- }
169
- /** @type {Map<string, SourceArea>} Keys are archive x/y, not screen tiles. */
170
- this._areas = new Map();
171
- // Counts pending archive/build tasks, including ones cancelled after a pan.
172
- this._inflight = 0;
173
- // Gate GPU work on attachment; replaced on removal to support delayed loads.
174
- this._added = Promise.withResolvers();
175
- // Defer initialization so callers can subscribe to ready/error after construction.
176
- queueMicrotask(async () => {
177
- try {
178
- this.root = graph.emptyNode();
179
- this.raycaster = {
180
- origin: [0, 0, 0],
181
- direction: [0, 0, 0]
182
- };
183
- if (this.url || this._geojson) {
184
- this.group = this.root;
185
- if (this.url) this.header = await this.getHeader();
186
- }
187
- if (this._map) {
188
- await this._attach(this._map);
189
- this._added.resolve();
190
- }
191
- if (this.modelUrl) await this._loadModel();
192
- if (this._shared) this.update();
193
- this.fire('ready');
194
- } catch (error) {
195
- this.fire('error', { error });
196
- }
197
- });
198
- },
199
-
200
- /** Attach interaction immediately; initialization may finish before or after onAdd. */
201
- onAdd(map) {
202
- if (!this.location) {
203
- const center = map.getCenter();
204
- this.location = new L.LatLng(center.lat, center.lng);
205
- }
206
- if (this.url || this._geojson || this.options.tooltipContent || this.modelUrl) {
207
- this.container = map.getContainer();
208
- if (this.options.tooltipContent) {
209
- this._tooltip = L.DomUtil.create('div', 'leaflet-3d-tooltip', this.container);
210
- this._tooltip.hidden = true;
211
- this._tooltip.setAttribute('role', 'tooltip');
212
- this._tooltip.setAttribute('aria-live', 'polite');
213
- 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';
214
- }
215
- L.DomEvent.on(this.container, {
216
- mousemove: this._onPointerMove,
217
- click: this._onClick,
218
- mouseleave: this._onPointerLeave,
219
- }, this);
220
- }
221
- if (this.root) {
222
- this._attach(map).then(() => this._added.resolve(), error => this.fire('error', { error }));
223
- }
224
- },
225
-
226
- /** Reconcile source coverage when the visible ground footprint changes. */
227
- getEvents() {
228
- return this.url ? {
229
- moveend: this._updateArea,
230
- zoomend: this._updateArea,
231
- rotate: this._updateArea,
232
- pitch: this._updateArea,
233
- resize: this._updateArea,
234
- terrainchange: this._onTerrainChange,
235
- } : {};
236
- },
237
-
238
- /** Release source meshes/UI; retain manually added objects and model CPU data. */
239
- onRemove(map) {
240
- this._added = Promise.withResolvers();
241
- if (this.container) {
242
- this._onPointerLeave();
243
- L.DomEvent.off(this.container, {
244
- mousemove: this._onPointerMove,
245
- click: this._onClick,
246
- mouseleave: this._onPointerLeave,
247
- }, this);
248
- this.container = null;
249
- }
250
- for (const area of this._areas.values()) this._releaseArea(area);
251
- this._areas.clear();
252
- this._tooltip?.remove();
253
- this._tooltip = null;
254
- if (this.url || this._geojson) this._updateStatus(false);
255
- const shared = this._shared;
256
- if (!shared) return;
257
- this.setParent(this.root, null);
258
- shared._layers.delete(this);
259
- if (shared === this) {
260
- map.off('move zoom rotate pitch resize viewreset layeradd layerremove', this._onMapChange, this);
261
- map.off('zoomstart', this._startZoom, this);
262
- map.off('zoomanim', this.update, this);
263
- map.off('zoomend', this._endZoom, this);
264
- cancelAnimationFrame(this._frame);
265
- this._frame = null;
266
- this._queued = false;
267
- if (this._layers.size) {
268
- // Keep the original scene origin and GPU resources when ownership changes.
269
- const next = this._layers.values().next().value;
270
- for (const key of ['_layers', '_sceneOrigin', '_size', '_zoomLevel', '_zoomTransitions', '_cursor', '_roofRaster', '_roofTiles']) {
271
- next[key] = this[key];
272
- delete this[key];
273
- }
274
- for (const layer of next._layers) layer._shared = next;
275
- L.Layer.types['3d']._renderers.set(map, next);
276
- map.on('move zoom rotate pitch resize viewreset layeradd layerremove', next._onMapChange, next);
277
- map.on('zoomstart', next._startZoom, next);
278
- map.on('zoomanim', next.update, next);
279
- map.on('zoomend', next._endZoom, next);
280
- next.update();
281
- } else {
282
- if (this._roofRaster) this._destroyTexture(this._roofRaster.texture.texture);
283
- this._roofRaster = null;
284
- for (const source of this._roofTiles?.values() || []) this._destroyTexture(source.texture);
285
- this._roofTiles = null;
286
- for (const animation of this._zoomTransitions?.keys() || []) animation.play();
287
- this._zoomTransitions = null;
288
- this.renderer.canvas.remove();
289
- const renderer = this.renderer;
290
- const resources = [renderer.depthTexture, renderer.roofFallbackTexture.texture, renderer.uniformBuffer,
291
- renderer.sunlight?.texture, renderer.sunlight?.buffer, renderer.sunlight?.lights].filter(Boolean);
292
- renderer.device.queue.onSubmittedWorkDone().then(() => {
293
- for (const resource of resources) resource.destroy();
294
- renderer.device.destroy();
295
- }, error => {
296
- this.fire('error', { error });
297
- renderer.device.destroy();
298
- });
299
- L.Layer.types['3d']._renderers.delete(map);
300
- for (const key of ['_layers', '_sceneOrigin', '_size', '_zoomLevel', '_cursor']) delete this[key];
301
- }
302
- } else shared.update();
303
- this._shared = null;
304
- this.renderer = this.scene = this.camera = null;
305
- },
306
-
307
- /**
308
- * Adds a scene node or mesh in layer-local coordinates and schedules a redraw.
309
- * Requires initialization and a compatible scene node.
310
- * @param {Object} object
311
- * @returns {L.Layer} This layer.
312
- */
313
- add(object) {
314
- this.setParent(object, this.root);
315
- return this.update();
316
- },
317
-
318
- _setTerrainHeight() {
319
- if (!this.root || !this.location) return;
320
- this._terrainBaseY ??= this.root.position[1];
321
- this.root.position[1] = this._terrainBaseY + (this._map?._terrain3D?._getElevation(this.location) ?? 0);
322
- },
323
-
324
- /**
325
- * Without an argument, removes this Leaflet layer. With an object, only detaches it:
326
- * geometry/program resources are not disposed, so it can be added again.
327
- * @param {Object} [object]
328
- * @returns {L.Layer}
329
- */
330
- remove(object) {
331
- if (object === undefined) return L.Layer.prototype.remove.call(this);
332
- this.setParent(object, null);
333
- return this.update();
334
- },
335
- });
336
-
337
- L.Layer.types['3d']._nextId = 0;
@@ -1,42 +0,0 @@
1
- import './3d.js';
2
-
3
- /** One GeoJSON batch, independent of the viewport, using the existing extrusion pipeline. */
4
- L.Layer.types.geojson = L.Layer.types['3d'].extend({
5
- _geojson: true,
6
-
7
- async _loadSource(area) {
8
- const { data, url } = this.options;
9
- if (typeof this.options.featureStyle !== 'function') {
10
- throw new Error('featureStyle must be a function');
11
- }
12
- if ((data !== undefined) === (url !== undefined)) {
13
- throw new Error('GeoJSON source requires either data or url');
14
- }
15
- if (data !== undefined) return data;
16
- if (typeof url !== 'string' || !url.trim()) throw new Error('Invalid GeoJSON URL');
17
- const response = await fetch(new URL(url, document.baseURI), { signal: area.request.signal });
18
- if (!response.ok) throw new Error(`Unable to load GeoJSON: HTTP ${response.status}`);
19
- return response.json();
20
- },
21
-
22
- _updateArea() {
23
- if (!this._map || !this._shared) return;
24
- if (!this._areas.has('geojson')) {
25
- this._areas.set('geojson', { request: new AbortController() });
26
- }
27
- this._pump();
28
- },
29
-
30
- getEvents() {
31
- return { terrainchange: this._onTerrainChange };
32
- },
33
-
34
- setData(data) {
35
- this.options.data = data;
36
- delete this.options.url;
37
- for (const area of this._areas.values()) this._releaseArea(area);
38
- this._areas.clear();
39
- this._updateArea();
40
- return this;
41
- },
42
- });