leaflet-city-mapper 0.0.0-stage → 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 (412) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +78 -2
  3. package/cucumber.mjs +9 -0
  4. package/dist/leaflet-city-mapper.js +2 -0
  5. package/dist/leaflet-city-mapper.js.map +7 -0
  6. package/dist/utils/CELL.js +2 -0
  7. package/dist/utils/CELL.js.map +7 -0
  8. package/dist/utils/addBridges.js +2 -0
  9. package/dist/utils/addBridges.js.map +7 -0
  10. package/dist/utils/addRasterTile.js +2 -0
  11. package/dist/utils/addRasterTile.js.map +7 -0
  12. package/dist/utils/along.js +2 -0
  13. package/dist/utils/along.js.map +7 -0
  14. package/dist/utils/atmosphere.js +2 -0
  15. package/dist/utils/atmosphere.js.map +7 -0
  16. package/dist/utils/attach.js +2 -0
  17. package/dist/utils/attach.js.map +7 -0
  18. package/dist/utils/bindSunlight.js +2 -0
  19. package/dist/utils/bindSunlight.js.map +7 -0
  20. package/dist/utils/box.js +2 -0
  21. package/dist/utils/box.js.map +7 -0
  22. package/dist/utils/bridgeElevation.js +2 -0
  23. package/dist/utils/bridgeElevation.js.map +7 -0
  24. package/dist/utils/build.js +2 -0
  25. package/dist/utils/build.js.map +7 -0
  26. package/dist/utils/cameraControls.js +2 -0
  27. package/dist/utils/cameraControls.js.map +7 -0
  28. package/dist/utils/channel.js +2 -0
  29. package/dist/utils/channel.js.map +7 -0
  30. package/dist/utils/collider.js +2 -0
  31. package/dist/utils/collider.js.map +7 -0
  32. package/dist/utils/colliders.js +2 -0
  33. package/dist/utils/colliders.js.map +7 -0
  34. package/dist/utils/computeBounds.js +2 -0
  35. package/dist/utils/computeBounds.js.map +7 -0
  36. package/dist/utils/conformModelToTerrain.js +2 -0
  37. package/dist/utils/conformModelToTerrain.js.map +7 -0
  38. package/dist/utils/createMesh.js +2 -0
  39. package/dist/utils/createMesh.js.map +7 -0
  40. package/dist/utils/createProgram.js +3 -0
  41. package/dist/utils/createProgram.js.map +7 -0
  42. package/dist/utils/decodeDirectory.js +2 -0
  43. package/dist/utils/decodeDirectory.js.map +7 -0
  44. package/dist/utils/decodeHeader.js +2 -0
  45. package/dist/utils/decodeHeader.js.map +7 -0
  46. package/dist/utils/decodeModel.js +2 -0
  47. package/dist/utils/decodeModel.js.map +7 -0
  48. package/dist/utils/decompress.js +2 -0
  49. package/dist/utils/decompress.js.map +7 -0
  50. package/dist/utils/destroyTexture.js +2 -0
  51. package/dist/utils/destroyTexture.js.map +7 -0
  52. package/dist/utils/disposeMesh.js +2 -0
  53. package/dist/utils/disposeMesh.js.map +7 -0
  54. package/dist/utils/drawGeometry.js +2 -0
  55. package/dist/utils/drawGeometry.js.map +7 -0
  56. package/dist/utils/elevationWGSL.js +24 -0
  57. package/dist/utils/elevationWGSL.js.map +7 -0
  58. package/dist/utils/emptyNode.js +2 -0
  59. package/dist/utils/emptyNode.js.map +7 -0
  60. package/dist/utils/endZoom.js +2 -0
  61. package/dist/utils/endZoom.js.map +7 -0
  62. package/dist/utils/findFeature.js +2 -0
  63. package/dist/utils/findFeature.js.map +7 -0
  64. package/dist/utils/geometry.js +1 -0
  65. package/dist/utils/geometry.js.map +7 -0
  66. package/dist/utils/getElevation.js +2 -0
  67. package/dist/utils/getElevation.js.map +7 -0
  68. package/dist/utils/getHeader.js +2 -0
  69. package/dist/utils/getHeader.js.map +7 -0
  70. package/dist/utils/getZxy.js +2 -0
  71. package/dist/utils/getZxy.js.map +7 -0
  72. package/dist/utils/glass.js +2 -0
  73. package/dist/utils/glass.js.map +7 -0
  74. package/dist/utils/headlight.js +2 -0
  75. package/dist/utils/headlight.js.map +7 -0
  76. package/dist/utils/hit.js +2 -0
  77. package/dist/utils/hit.js.map +7 -0
  78. package/dist/utils/horizontalPosition.js +2 -0
  79. package/dist/utils/horizontalPosition.js.map +7 -0
  80. package/dist/utils/horizontalRay.js +2 -0
  81. package/dist/utils/horizontalRay.js.map +7 -0
  82. package/dist/utils/hull.js +2 -0
  83. package/dist/utils/hull.js.map +7 -0
  84. package/dist/utils/initSunlight.js +2 -0
  85. package/dist/utils/initSunlight.js.map +7 -0
  86. package/dist/utils/initTerrain.js +2 -0
  87. package/dist/utils/initTerrain.js.map +7 -0
  88. package/dist/utils/initTraffic.js +40 -0
  89. package/dist/utils/initTraffic.js.map +7 -0
  90. package/dist/utils/initWalk.js +2 -0
  91. package/dist/utils/initWalk.js.map +7 -0
  92. package/dist/utils/intersectMeshes.js +2 -0
  93. package/dist/utils/intersectMeshes.js.map +7 -0
  94. package/dist/utils/isClockWise.js +2 -0
  95. package/dist/utils/isClockWise.js.map +7 -0
  96. package/dist/utils/lampPostGeometry.js +2 -0
  97. package/dist/utils/lampPostGeometry.js.map +7 -0
  98. package/dist/utils/lightGeometry.js +2 -0
  99. package/dist/utils/lightGeometry.js.map +7 -0
  100. package/dist/utils/lightGrid.js +2 -0
  101. package/dist/utils/lightGrid.js.map +7 -0
  102. package/dist/utils/limbs.js +2 -0
  103. package/dist/utils/limbs.js.map +7 -0
  104. package/dist/utils/loadModel.js +2 -0
  105. package/dist/utils/loadModel.js.map +7 -0
  106. package/dist/utils/loadSource.js +2 -0
  107. package/dist/utils/loadSource.js.map +7 -0
  108. package/dist/utils/loadTerrain.js +2 -0
  109. package/dist/utils/loadTerrain.js.map +7 -0
  110. package/dist/utils/mapCamera.js +2 -0
  111. package/dist/utils/mapCamera.js.map +7 -0
  112. package/dist/utils/materialShaders.js +211 -0
  113. package/dist/utils/materialShaders.js.map +7 -0
  114. package/dist/utils/mirror.js +2 -0
  115. package/dist/utils/mirror.js.map +7 -0
  116. package/dist/utils/moonPosition.js +2 -0
  117. package/dist/utils/moonPosition.js.map +7 -0
  118. package/dist/utils/moves.js +2 -0
  119. package/dist/utils/moves.js.map +7 -0
  120. package/dist/utils/nativeEvents.js +2 -0
  121. package/dist/utils/nativeEvents.js.map +7 -0
  122. package/dist/utils/nativeGeometry.js +2 -0
  123. package/dist/utils/nativeGeometry.js.map +7 -0
  124. package/dist/utils/nativeLayer.js +2 -0
  125. package/dist/utils/nativeLayer.js.map +7 -0
  126. package/dist/utils/nodeMatrix.js +2 -0
  127. package/dist/utils/nodeMatrix.js.map +7 -0
  128. package/dist/utils/onAdd3DLayer.js +2 -0
  129. package/dist/utils/onAdd3DLayer.js.map +7 -0
  130. package/dist/utils/onAddSun.js +2 -0
  131. package/dist/utils/onAddSun.js.map +7 -0
  132. package/dist/utils/onClick.js +2 -0
  133. package/dist/utils/onClick.js.map +7 -0
  134. package/dist/utils/onMapChange.js +2 -0
  135. package/dist/utils/onMapChange.js.map +7 -0
  136. package/dist/utils/onPMTileAdd.js +2 -0
  137. package/dist/utils/onPMTileAdd.js.map +7 -0
  138. package/dist/utils/onPMTileRemove.js +2 -0
  139. package/dist/utils/onPMTileRemove.js.map +7 -0
  140. package/dist/utils/onPointerLeave.js +2 -0
  141. package/dist/utils/onPointerLeave.js.map +7 -0
  142. package/dist/utils/onPointerMove.js +2 -0
  143. package/dist/utils/onPointerMove.js.map +7 -0
  144. package/dist/utils/onRemove3DLayer.js +2 -0
  145. package/dist/utils/onRemove3DLayer.js.map +7 -0
  146. package/dist/utils/onRemoveSun.js +2 -0
  147. package/dist/utils/onRemoveSun.js.map +7 -0
  148. package/dist/utils/onTerrainAdd.js +2 -0
  149. package/dist/utils/onTerrainAdd.js.map +7 -0
  150. package/dist/utils/onTerrainChange.js +2 -0
  151. package/dist/utils/onTerrainChange.js.map +7 -0
  152. package/dist/utils/onTerrainRemove.js +2 -0
  153. package/dist/utils/onTerrainRemove.js.map +7 -0
  154. package/dist/utils/onZoomAnim.js +2 -0
  155. package/dist/utils/onZoomAnim.js.map +7 -0
  156. package/dist/utils/paints.js +2 -0
  157. package/dist/utils/paints.js.map +7 -0
  158. package/dist/utils/parseColor.js +2 -0
  159. package/dist/utils/parseColor.js.map +7 -0
  160. package/dist/utils/parts.js +2 -0
  161. package/dist/utils/parts.js.map +7 -0
  162. package/dist/utils/projectCelestialBody.js +2 -0
  163. package/dist/utils/projectCelestialBody.js.map +7 -0
  164. package/dist/utils/pump.js +2 -0
  165. package/dist/utils/pump.js.map +7 -0
  166. package/dist/utils/rasterTiles.js +2 -0
  167. package/dist/utils/rasterTiles.js.map +7 -0
  168. package/dist/utils/raycast.js +2 -0
  169. package/dist/utils/raycast.js.map +7 -0
  170. package/dist/utils/read.js +2 -0
  171. package/dist/utils/read.js.map +7 -0
  172. package/dist/utils/readAccessor.js +2 -0
  173. package/dist/utils/readAccessor.js.map +7 -0
  174. package/dist/utils/releaseArea.js +2 -0
  175. package/dist/utils/releaseArea.js.map +7 -0
  176. package/dist/utils/removeRasterTile.js +2 -0
  177. package/dist/utils/removeRasterTile.js.map +7 -0
  178. package/dist/utils/render.js +15 -0
  179. package/dist/utils/render.js.map +7 -0
  180. package/dist/utils/renderSunlight.js +13 -0
  181. package/dist/utils/renderSunlight.js.map +7 -0
  182. package/dist/utils/renderers.js +2 -0
  183. package/dist/utils/renderers.js.map +7 -0
  184. package/dist/utils/resizeSunlight.js +2 -0
  185. package/dist/utils/resizeSunlight.js.map +7 -0
  186. package/dist/utils/roofCoverage.js +2 -0
  187. package/dist/utils/roofCoverage.js.map +7 -0
  188. package/dist/utils/routeGeometry.js +2 -0
  189. package/dist/utils/routeGeometry.js.map +7 -0
  190. package/dist/utils/scheduledTrips.js +2 -0
  191. package/dist/utils/scheduledTrips.js.map +7 -0
  192. package/dist/utils/setGeoJSONData.js +2 -0
  193. package/dist/utils/setGeoJSONData.js.map +7 -0
  194. package/dist/utils/setHighlight.js +2 -0
  195. package/dist/utils/setHighlight.js.map +7 -0
  196. package/dist/utils/setPMTileOpacity.js +2 -0
  197. package/dist/utils/setPMTileOpacity.js.map +7 -0
  198. package/dist/utils/setPMTileZIndex.js +2 -0
  199. package/dist/utils/setPMTileZIndex.js.map +7 -0
  200. package/dist/utils/setParent.js +2 -0
  201. package/dist/utils/setParent.js.map +7 -0
  202. package/dist/utils/setTerrainHeight.js +2 -0
  203. package/dist/utils/setTerrainHeight.js.map +7 -0
  204. package/dist/utils/setVertexColor.js +2 -0
  205. package/dist/utils/setVertexColor.js.map +7 -0
  206. package/dist/utils/showFeature.js +2 -0
  207. package/dist/utils/showFeature.js.map +7 -0
  208. package/dist/utils/sizes.js +2 -0
  209. package/dist/utils/sizes.js.map +7 -0
  210. package/dist/utils/skin.js +2 -0
  211. package/dist/utils/skin.js.map +7 -0
  212. package/dist/utils/solarPosition.js +2 -0
  213. package/dist/utils/solarPosition.js.map +7 -0
  214. package/dist/utils/sortMeshes.js +2 -0
  215. package/dist/utils/sortMeshes.js.map +7 -0
  216. package/dist/utils/speed.js +2 -0
  217. package/dist/utils/speed.js.map +7 -0
  218. package/dist/utils/startZoom.js +2 -0
  219. package/dist/utils/startZoom.js.map +7 -0
  220. package/dist/utils/taillight.js +2 -0
  221. package/dist/utils/taillight.js.map +7 -0
  222. package/dist/utils/terrainAtlas.js +2 -0
  223. package/dist/utils/terrainAtlas.js.map +7 -0
  224. package/dist/utils/terrainElevation.js +2 -0
  225. package/dist/utils/terrainElevation.js.map +7 -0
  226. package/dist/utils/terrainGrid.js +2 -0
  227. package/dist/utils/terrainGrid.js.map +7 -0
  228. package/dist/utils/textureSampler.js +2 -0
  229. package/dist/utils/textureSampler.js.map +7 -0
  230. package/dist/utils/tileId.js +2 -0
  231. package/dist/utils/tileId.js.map +7 -0
  232. package/dist/utils/toLanes.js +2 -0
  233. package/dist/utils/toLanes.js.map +7 -0
  234. package/dist/utils/toSRGB.js +2 -0
  235. package/dist/utils/toSRGB.js.map +7 -0
  236. package/dist/utils/tooltip.js +3 -0
  237. package/dist/utils/tooltip.js.map +7 -0
  238. package/dist/utils/traffic.js +2 -0
  239. package/dist/utils/traffic.js.map +7 -0
  240. package/dist/utils/traverse.js +2 -0
  241. package/dist/utils/traverse.js.map +7 -0
  242. package/dist/utils/treeGeometry.js +2 -0
  243. package/dist/utils/treeGeometry.js.map +7 -0
  244. package/dist/utils/triangulate.js +2 -0
  245. package/dist/utils/triangulate.js.map +7 -0
  246. package/dist/utils/tripsAt.js +2 -0
  247. package/dist/utils/tripsAt.js.map +7 -0
  248. package/dist/utils/types.js +2 -0
  249. package/dist/utils/types.js.map +7 -0
  250. package/dist/utils/underEntry.js +2 -0
  251. package/dist/utils/underEntry.js.map +7 -0
  252. package/dist/utils/update.js +2 -0
  253. package/dist/utils/update.js.map +7 -0
  254. package/dist/utils/updateArea.js +2 -0
  255. package/dist/utils/updateArea.js.map +7 -0
  256. package/dist/utils/updateCamera.js +2 -0
  257. package/dist/utils/updateCamera.js.map +7 -0
  258. package/dist/utils/updatePointLights.js +2 -0
  259. package/dist/utils/updatePointLights.js.map +7 -0
  260. package/dist/utils/updateWorldMatrix.js +2 -0
  261. package/dist/utils/updateWorldMatrix.js.map +7 -0
  262. package/dist/utils/vehicleOffsets.js +2 -0
  263. package/dist/utils/vehicleOffsets.js.map +7 -0
  264. package/dist/utils/vehicles.js +2 -0
  265. package/dist/utils/vehicles.js.map +7 -0
  266. package/dist/utils/vertexNormals.js +2 -0
  267. package/dist/utils/vertexNormals.js.map +7 -0
  268. package/dist/utils/walk.js +2 -0
  269. package/dist/utils/walk.js.map +7 -0
  270. package/dist/utils/white.js +2 -0
  271. package/dist/utils/white.js.map +7 -0
  272. package/dist/utils/worldLights.js +2 -0
  273. package/dist/utils/worldLights.js.map +7 -0
  274. package/dist/utils/wrap.js +2 -0
  275. package/dist/utils/wrap.js.map +7 -0
  276. package/package.json +43 -4
  277. package/src/index.js +397 -0
  278. package/src/utils/CELL.js +4 -0
  279. package/src/utils/addBridges.js +66 -0
  280. package/src/utils/addRasterTile.js +112 -0
  281. package/src/utils/along.js +9 -0
  282. package/src/utils/atmosphere.js +20 -0
  283. package/src/utils/attach.js +255 -0
  284. package/src/utils/bindSunlight.js +12 -0
  285. package/src/utils/box.js +1 -0
  286. package/src/utils/bridgeElevation.js +18 -0
  287. package/src/utils/build.js +20 -0
  288. package/src/utils/cameraControls.js +287 -0
  289. package/src/utils/channel.js +4 -0
  290. package/src/utils/collider.js +62 -0
  291. package/src/utils/colliders.js +2 -0
  292. package/src/utils/computeBounds.js +17 -0
  293. package/src/utils/conformModelToTerrain.js +69 -0
  294. package/src/utils/createMesh.js +31 -0
  295. package/src/utils/createProgram.js +92 -0
  296. package/src/utils/decodeDirectory.js +40 -0
  297. package/src/utils/decodeHeader.js +15 -0
  298. package/src/utils/decodeModel.js +43 -0
  299. package/src/utils/decompress.js +5 -0
  300. package/src/utils/destroyTexture.js +7 -0
  301. package/src/utils/disposeMesh.js +13 -0
  302. package/src/utils/drawGeometry.js +122 -0
  303. package/src/utils/elevationWGSL.js +27 -0
  304. package/src/utils/emptyNode.js +9 -0
  305. package/src/utils/endZoom.js +15 -0
  306. package/src/utils/findFeature.js +49 -0
  307. package/src/utils/geometry.js +2 -0
  308. package/src/utils/getElevation.js +10 -0
  309. package/src/utils/getHeader.js +9 -0
  310. package/src/utils/getZxy.js +76 -0
  311. package/src/utils/glass.js +1 -0
  312. package/src/utils/headlight.js +1 -0
  313. package/src/utils/hit.js +41 -0
  314. package/src/utils/horizontalPosition.js +16 -0
  315. package/src/utils/horizontalRay.js +12 -0
  316. package/src/utils/hull.js +1 -0
  317. package/src/utils/initSunlight.js +9 -0
  318. package/src/utils/initTerrain.js +19 -0
  319. package/src/utils/initTraffic.js +93 -0
  320. package/src/utils/initWalk.js +72 -0
  321. package/src/utils/intersectMeshes.js +121 -0
  322. package/src/utils/isClockWise.js +12 -0
  323. package/src/utils/lampPostGeometry.js +26 -0
  324. package/src/utils/lightGeometry.js +22 -0
  325. package/src/utils/lightGrid.js +50 -0
  326. package/src/utils/limbs.js +9 -0
  327. package/src/utils/loadModel.js +217 -0
  328. package/src/utils/loadSource.js +17 -0
  329. package/src/utils/loadTerrain.js +65 -0
  330. package/src/utils/mapCamera.js +432 -0
  331. package/src/utils/materialShaders.js +243 -0
  332. package/src/utils/mirror.js +6 -0
  333. package/src/utils/moonPosition.js +17 -0
  334. package/src/utils/moves.js +11 -0
  335. package/src/utils/nativeEvents.js +77 -0
  336. package/src/utils/nativeGeometry.js +131 -0
  337. package/src/utils/nativeLayer.js +317 -0
  338. package/src/utils/nodeMatrix.js +22 -0
  339. package/src/utils/onAdd3DLayer.js +31 -0
  340. package/src/utils/onAddSun.js +147 -0
  341. package/src/utils/onClick.js +13 -0
  342. package/src/utils/onMapChange.js +16 -0
  343. package/src/utils/onPMTileAdd.js +15 -0
  344. package/src/utils/onPMTileRemove.js +8 -0
  345. package/src/utils/onPointerLeave.js +11 -0
  346. package/src/utils/onPointerMove.js +15 -0
  347. package/src/utils/onRemove3DLayer.js +78 -0
  348. package/src/utils/onRemoveSun.js +3 -0
  349. package/src/utils/onTerrainAdd.js +18 -0
  350. package/src/utils/onTerrainChange.js +13 -0
  351. package/src/utils/onTerrainRemove.js +40 -0
  352. package/src/utils/onZoomAnim.js +14 -0
  353. package/src/utils/paints.js +10 -0
  354. package/src/utils/parseColor.js +42 -0
  355. package/src/utils/parts.js +16 -0
  356. package/src/utils/projectCelestialBody.js +13 -0
  357. package/src/utils/pump.js +226 -0
  358. package/src/utils/rasterTiles.js +285 -0
  359. package/src/utils/raycast.js +60 -0
  360. package/src/utils/read.js +29 -0
  361. package/src/utils/readAccessor.js +68 -0
  362. package/src/utils/releaseArea.js +34 -0
  363. package/src/utils/removeRasterTile.js +13 -0
  364. package/src/utils/render.js +406 -0
  365. package/src/utils/renderSunlight.js +170 -0
  366. package/src/utils/renderers.js +2 -0
  367. package/src/utils/resizeSunlight.js +15 -0
  368. package/src/utils/roofCoverage.js +47 -0
  369. package/src/utils/routeGeometry.js +22 -0
  370. package/src/utils/scheduledTrips.js +29 -0
  371. package/src/utils/setGeoJSONData.js +11 -0
  372. package/src/utils/setHighlight.js +13 -0
  373. package/src/utils/setPMTileOpacity.js +7 -0
  374. package/src/utils/setPMTileZIndex.js +7 -0
  375. package/src/utils/setParent.js +7 -0
  376. package/src/utils/setTerrainHeight.js +10 -0
  377. package/src/utils/setVertexColor.js +14 -0
  378. package/src/utils/showFeature.js +27 -0
  379. package/src/utils/sizes.js +1 -0
  380. package/src/utils/skin.js +2 -0
  381. package/src/utils/solarPosition.js +17 -0
  382. package/src/utils/sortMeshes.js +12 -0
  383. package/src/utils/speed.js +3 -0
  384. package/src/utils/startZoom.js +5 -0
  385. package/src/utils/taillight.js +1 -0
  386. package/src/utils/terrainAtlas.js +21 -0
  387. package/src/utils/terrainElevation.js +20 -0
  388. package/src/utils/terrainGrid.js +23 -0
  389. package/src/utils/textureSampler.js +10 -0
  390. package/src/utils/tileId.js +18 -0
  391. package/src/utils/toLanes.js +7 -0
  392. package/src/utils/toSRGB.js +1 -0
  393. package/src/utils/tooltip.js +6 -0
  394. package/src/utils/traffic.js +315 -0
  395. package/src/utils/traverse.js +6 -0
  396. package/src/utils/treeGeometry.js +45 -0
  397. package/src/utils/triangulate.js +100 -0
  398. package/src/utils/tripsAt.js +16 -0
  399. package/src/utils/types.js +8 -0
  400. package/src/utils/underEntry.js +17 -0
  401. package/src/utils/update.js +18 -0
  402. package/src/utils/updateArea.js +40 -0
  403. package/src/utils/updateCamera.js +32 -0
  404. package/src/utils/updatePointLights.js +38 -0
  405. package/src/utils/updateWorldMatrix.js +47 -0
  406. package/src/utils/vehicleOffsets.js +8 -0
  407. package/src/utils/vehicles.js +65 -0
  408. package/src/utils/vertexNormals.js +30 -0
  409. package/src/utils/walk.js +187 -0
  410. package/src/utils/white.js +1 -0
  411. package/src/utils/worldLights.js +25 -0
  412. package/src/utils/wrap.js +1 -0
@@ -0,0 +1,147 @@
1
+ import { underEntry } from './underEntry.js';
2
+ import { update as updateScene } from "./update.js";
3
+ import { atmosphere } from './atmosphere.js';
4
+ import { moonPosition } from './moonPosition.js';
5
+ import { projectCelestialBody } from './projectCelestialBody.js';
6
+ import { solarPosition } from './solarPosition.js';
7
+
8
+ export function onAddSun(layer, map) {
9
+ if (!layer.control) {
10
+ const control = new L.Control({ position: 'bottomright' });
11
+ control.live = true;
12
+ let date, slider, output, status, timer;
13
+ const originalSky = map.getContainer().style.getPropertyValue('--leaflet-sky-background');
14
+ const disc = 'position:absolute;width:18px;height:18px;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;';
15
+ const sunDisc = L.DomUtil.create('div', 'sunlight-sun');
16
+ const moonDisc = L.DomUtil.create('div', 'sunlight-moon');
17
+ sunDisc.style.cssText = disc + 'background:#fff3bd;box-shadow:0 0 18px 7px #ffd27699;';
18
+ moonDisc.style.cssText = disc + 'background:#dce5f2;box-shadow:0 0 10px 2px #cbdcff55;';
19
+ sunDisc.setAttribute('role', 'img'); sunDisc.setAttribute('aria-label', 'Sun');
20
+ moonDisc.setAttribute('role', 'img'); moonDisc.setAttribute('aria-label', 'Moon');
21
+ const updateSky = () => {
22
+ const sun = map._sunlight, sky = map._pitchSky;
23
+ if (sun) map.getContainer().style.setProperty('--leaflet-sky-background', sun.background);
24
+ else if (originalSky) map.getContainer().style.setProperty('--leaflet-sky-background', originalSky);
25
+ else map.getContainer().style.removeProperty('--leaflet-sky-background');
26
+ const size = map.getSize(), pitch = map.getPitch() * Math.PI / 180, bearing = map.getBearing() * Math.PI / 180;
27
+ for (const [disc, body] of [[sunDisc, sun], [moonDisc, sun?.moon]]) {
28
+ disc.hidden = true;
29
+ if (!sky || !body || body.altitude <= 0 || !sun) continue;
30
+ if (disc.parentNode !== sky) sky.append(disc);
31
+ const point = projectCelestialBody(body.direction, size, pitch, bearing);
32
+ if (!point) continue;
33
+ const { left, top } = point;
34
+ disc.hidden = left < 0 || left > size.x || top < 0 || top > sky.clientHeight || sky.style.display === 'none';
35
+ disc.style.left = `${left}px`; disc.style.top = `${top}px`;
36
+ }
37
+ };
38
+ const render = () => {
39
+ const renderer = L.Layer._renderers.get(map);
40
+ if (renderer) updateScene(renderer);
41
+ };
42
+ const update = () => {
43
+ try {
44
+ if (control.live) control.time = new Date();
45
+ const time = control.time.toISOString();
46
+ date.value = time.slice(0, 10);
47
+ slider.value = String(control.time.getUTCHours() * 60 + control.time.getUTCMinutes());
48
+ output.textContent = `${time.slice(11, 16)} UTC${control.live ? ' · now' : ''}`;
49
+ const center = map.getCenter();
50
+ const sun = map._sunlight = solarPosition(control.time, center.lat, center.lng);
51
+ Object.assign(sun, atmosphere(sun.altitude));
52
+ sun.moon = moonPosition(control.time, center.lat, center.lng);
53
+ status.textContent = sun.altitude <= 0
54
+ ? 'Night · no direct sunlight'
55
+ : sun.altitude < 3
56
+ ? 'Low sun · shadows paused'
57
+ : `Sun altitude ${sun.altitude.toFixed(1)}°`;
58
+ map.fire('simulationtimechange', { time: new Date(control.time), live: control.live });
59
+ updateSky();
60
+ render();
61
+ } catch (error) {
62
+ delete map._sunlight;
63
+ updateSky();
64
+ render();
65
+ status.textContent = `Error: ${error.message}`;
66
+ console.error('Solar simulation', error);
67
+ }
68
+ };
69
+ control.onAdd = () => {
70
+ const container = L.DomUtil.create('div', 'sunlight-control');
71
+ container.style.cssText = 'color:#222;width:min(200px,calc(100vw - 60px));font:12px/1.4 sans-serif;';
72
+ date = document.createElement('input');
73
+ date.type = 'date';
74
+ date.style.cssText = 'width:100%;box-sizing:border-box;';
75
+ date.setAttribute('aria-label', 'Solar date (UTC)');
76
+ slider = document.createElement('input');
77
+ slider.type = 'range';
78
+ slider.style.cssText = 'width:100%;box-sizing:border-box;margin:10px 0 4px;cursor:pointer;';
79
+ slider.min = '0'; slider.max = '1439'; slider.step = '1';
80
+ slider.setAttribute('aria-label', 'Time of day (UTC)');
81
+ output = document.createElement('output');
82
+ output.style.cssText = 'font-weight:bold;font-variant-numeric:tabular-nums;';
83
+ output.setAttribute('aria-live', 'off');
84
+ const now = document.createElement('button');
85
+ now.type = 'button'; now.textContent = 'Now';
86
+ now.onclick = () => { control.live = true; update(); };
87
+ const timeRow = document.createElement('div');
88
+ timeRow.className = 'sunlight-time';
89
+ timeRow.style.cssText = 'display:flex;justify-content:space-between;align-items:center;';
90
+ timeRow.append(output, now);
91
+ status = document.createElement('div');
92
+ status.className = 'sunlight-status';
93
+ status.style.marginTop = '5px';
94
+ status.setAttribute('role', 'status');
95
+ const note = document.createElement('small');
96
+ note.style.color = '#555';
97
+ note.textContent = 'Indicative · loaded geometry only. Streetlight illumination is estimated, not measured lux.';
98
+ container.append(date, slider, timeRow, status, note);
99
+ date.onchange = slider.oninput = () => {
100
+ control.live = false;
101
+ if (!date.value || !date.validity.valid) {
102
+ control.time = new Date(NaN);
103
+ map.fire('simulationtimechange', { time: null, live: false });
104
+ delete map._sunlight;
105
+ updateSky();
106
+ render();
107
+ status.textContent = 'Error: choose a valid solar date';
108
+ return;
109
+ }
110
+ control.time = new Date(`${date.value}T00:00:00Z`);
111
+ control.time.setUTCMinutes(Number(slider.value));
112
+ update();
113
+ };
114
+ L.DomEvent.disableClickPropagation(container);
115
+ L.DomEvent.disableScrollPropagation(container);
116
+ update();
117
+ timer = setInterval(() => { if (control.live) update(); }, 60000);
118
+ map.on('moveend', update);
119
+ map.on('move rotate pitch resize', updateSky);
120
+ return container;
121
+ };
122
+ control.onRemove = () => {
123
+ clearInterval(timer);
124
+ map.fire('simulationtimechange', { time: null, live: false });
125
+ map.off('moveend', update);
126
+ map.off('move rotate pitch resize', updateSky);
127
+ delete map._sunlight;
128
+ updateSky();
129
+ sunDisc.remove(); moonDisc.remove();
130
+ render();
131
+ };
132
+ layer.control = control;
133
+ }
134
+ if (!layer.control._map) {
135
+ layer.control.addTo(map);
136
+ }
137
+ // Shown under this layer's entry in the layers control; a standalone control without one.
138
+ const container = layer.control.getContainer(), nested = underEntry(layer, container);
139
+ container.classList.toggle('leaflet-control', !nested);
140
+ container.classList.toggle('leaflet-bar', !nested);
141
+ Object.assign(
142
+ container.style,
143
+ nested
144
+ ? { background: '', padding: '2px 0 6px 20px', margin: '0' }
145
+ : { background: '#fff', padding: '8px', margin: '' }
146
+ );
147
+ }
@@ -0,0 +1,13 @@
1
+ import { findFeature } from './findFeature.js';
2
+ import { setHighlight } from './setHighlight.js';
3
+ import { showFeature } from './showFeature.js';
4
+
5
+ /** Emit click without moving the map or pinning the tooltip. */
6
+
7
+ export function onClick(layer, event) {
8
+ const feature = findFeature(layer, event);
9
+ layer.hoveredFeature = feature;
10
+ setHighlight(layer, feature);
11
+ showFeature(layer, feature, event);
12
+ layer.fire('featureclick', { feature, originalEvent: event });
13
+ }
@@ -0,0 +1,16 @@
1
+ import { update } from "./update.js";
2
+ import { render } from "./render.js";
3
+
4
+ /** Map movement: render within the frame of Leaflet's CSS transforms, coalescing same-tick events. */
5
+
6
+ export function onMapChange() {
7
+ const layer = this;
8
+ if (layer._queued) return;
9
+ layer._queued = true;
10
+ queueMicrotask(() => {
11
+ layer._queued = false;
12
+ if (layer._shared !== layer || !layer.renderer) return;
13
+ if (layer._map._animatingZoom) update(layer);
14
+ else render(layer);
15
+ });
16
+ }
@@ -0,0 +1,15 @@
1
+ import { attach } from './attach.js';
2
+ import { setRasterTerrain, updateRasterTiles } from './rasterTiles.js';
3
+
4
+ export function onPMTileAdd(backend, map) {
5
+ if (!backend.location) backend.location = map.getCenter();
6
+ const attached = attach(backend, map);
7
+ attached.then(() => {
8
+ backend._added.resolve();
9
+ setRasterTerrain(backend, map._terrain3D);
10
+ })
11
+ .catch(error => backend.fire('error', { error }));
12
+ Promise.all([attached, backend.ready]).then(() => {
13
+ if (backend._map === map && map.hasLayer(backend)) updateRasterTiles(backend);
14
+ }).catch(error => backend.fire('error', { error }));
15
+ }
@@ -0,0 +1,8 @@
1
+ import { releaseRasterTiles } from './rasterTiles.js';
2
+ import { onRemove3DLayer } from './onRemove3DLayer.js';
3
+
4
+ export function onPMTileRemove(backend, map) {
5
+ releaseRasterTiles(backend);
6
+ backend._terrain3D = null;
7
+ onRemove3DLayer(backend, map);
8
+ }
@@ -0,0 +1,11 @@
1
+ import { setHighlight } from './setHighlight.js';
2
+ import { showFeature } from './showFeature.js';
3
+
4
+ /** Clear hover, highlight and tooltip without retaining a selected feature. */
5
+
6
+ export function onPointerLeave(layer) {
7
+ layer.hoveredFeature = null;
8
+ setHighlight(layer, null);
9
+ showFeature(layer, null);
10
+ layer.fire('featurehover', { feature: null });
11
+ }
@@ -0,0 +1,15 @@
1
+ import { findFeature } from './findFeature.js';
2
+ import { setHighlight } from './setHighlight.js';
3
+ import { showFeature } from './showFeature.js';
4
+
5
+ /** Hover is transient; featurehover also reports misses with feature:null. */
6
+
7
+ export function onPointerMove(layer, event) {
8
+ layer.hoveredFeature = findFeature(layer, event);
9
+ setHighlight(layer, layer.hoveredFeature);
10
+ showFeature(layer, layer.hoveredFeature, event);
11
+ layer.fire('featurehover', {
12
+ feature: layer.hoveredFeature,
13
+ originalEvent: event
14
+ });
15
+ }
@@ -0,0 +1,78 @@
1
+ import * as destroyTexture from './destroyTexture.js';
2
+ import * as endZoom from './endZoom.js';
3
+ import * as onMapChange from './onMapChange.js';
4
+ import * as onPointerLeave from './onPointerLeave.js';
5
+ import * as onZoomAnim from './onZoomAnim.js';
6
+ import * as releaseArea from './releaseArea.js';
7
+ import { setParent } from './setParent.js';
8
+ import * as startZoom from './startZoom.js';
9
+ import * as update from './update.js';
10
+
11
+ /** Release source meshes/UI; retain manually added objects and model CPU data. */
12
+ export function onRemove3DLayer(backend, map) {
13
+ backend._added = Promise.withResolvers();
14
+ if (backend.container) {
15
+ onPointerLeave.onPointerLeave(backend);
16
+ L.DomEvent.off(backend.container, backend._pointerEvents);
17
+ backend.container = null;
18
+ }
19
+ for (const area of backend._areas.values()) releaseArea.releaseArea(backend, area);
20
+ backend._areas.clear();
21
+ backend._tooltip?.remove();
22
+ backend._tooltip = null;
23
+ if (backend.url || backend._geojson) releaseArea.updateStatus(backend, false);
24
+ const shared = backend._shared;
25
+ if (!shared) return;
26
+ setParent(backend.root, null);
27
+ shared._layers.delete(backend);
28
+ if (shared === backend) {
29
+ map.off('move zoom rotate pitch resize viewreset layeradd layerremove', onMapChange.onMapChange, backend);
30
+ map.off('zoomstart', startZoom.startZoom, backend);
31
+ map.off('zoomanim', onZoomAnim.onZoomAnim, backend);
32
+ map.off('zoomend', endZoom.endZoom, backend);
33
+ cancelAnimationFrame(backend._frame);
34
+ backend._frame = null;
35
+ backend._queued = false;
36
+ if (backend._layers.size) {
37
+ // Keep the original scene origin and GPU resources when ownership changes.
38
+ const next = backend._layers.values().next().value;
39
+ for (const key of ['_layers', '_sceneOrigin', '_size', '_zoomLevel', '_zoomTransitions', '_zoomView', '_cursor', '_roofRaster']) {
40
+ next[key] = backend[key];
41
+ delete backend[key];
42
+ }
43
+ for (const layer of next._layers) layer._shared = next;
44
+ L.Layer._renderers.set(map, next);
45
+ map.on('move zoom rotate pitch resize viewreset layeradd layerremove', onMapChange.onMapChange, next);
46
+ map.on('zoomstart', startZoom.startZoom, next);
47
+ map.on('zoomanim', onZoomAnim.onZoomAnim, next);
48
+ map.on('zoomend', endZoom.endZoom, next);
49
+ update.update(next);
50
+ } else {
51
+ if (backend._roofRaster) destroyTexture.destroyTexture(backend, backend._roofRaster.texture.texture);
52
+ backend._roofRaster = null;
53
+ for (const animation of backend._zoomTransitions?.keys() || []) animation.play();
54
+ backend._zoomTransitions = null;
55
+ backend._zoomView = null;
56
+ delete map._cameraView;
57
+ map.getContainer().classList.remove('leaflet-camera-zoom');
58
+ const renderer = backend.renderer;
59
+ renderer.canvas.remove();
60
+ renderer.device.queue.onSubmittedWorkDone()
61
+ .then(() => {
62
+ renderer.depthTexture?.destroy();
63
+ renderer.roofFallbackTexture?.texture?.destroy();
64
+ renderer.uniformBuffer?.destroy();
65
+ renderer.sunlight?.texture?.destroy();
66
+ renderer.sunlight?.buffer?.destroy();
67
+ renderer.sunlight?.lights?.destroy();
68
+ renderer.device.destroy();
69
+ }, error => {
70
+ backend.fire('error', { error });
71
+ renderer.device.destroy();
72
+ });
73
+ L.Layer._renderers.delete(map);
74
+ for (const key of ['_layers', '_sceneOrigin', '_size', '_zoomLevel', '_cursor']) delete backend[key];
75
+ }
76
+ } else update.update(shared);
77
+ backend._shared = backend.renderer = backend.scene = backend.camera = null;
78
+ }
@@ -0,0 +1,3 @@
1
+ export function onRemoveSun(layer) {
2
+ layer.control.remove();
3
+ }
@@ -0,0 +1,18 @@
1
+ import { loadTerrain } from "./loadTerrain.js";
2
+ import { setRasterTerrain } from "./rasterTiles.js";
3
+ import { onAdd3DLayer } from './onAdd3DLayer.js';
4
+
5
+ export function onTerrainAdd(backend, map) {
6
+ if (map._terrain3D && map._terrain3D !== backend) {
7
+ throw new Error('Only one terrain layer can be active per map');
8
+ }
9
+ map._terrain3D = backend;
10
+ onAdd3DLayer(backend, map);
11
+ backend._terrainPromise = backend.root
12
+ ? loadTerrain(backend)
13
+ : new Promise(resolve => backend.once('ready', () => loadTerrain(backend).then(resolve), backend));
14
+ map.eachLayer(layer => {
15
+ if (layer._type === 'pmtiles') setRasterTerrain(layer, backend);
16
+ });
17
+ map.fire('terrainchange');
18
+ }
@@ -0,0 +1,13 @@
1
+ import { releaseArea } from "./releaseArea.js";
2
+ import { updateArea } from "./updateArea.js";
3
+
4
+ /** GeoJSON source areas: loading, building and releasing. */
5
+
6
+ export function onTerrainChange(layer) {
7
+ if (!layer._map) return;
8
+ for (const area of layer._areas.values()) {
9
+ releaseArea(layer, area);
10
+ }
11
+ layer._areas.clear();
12
+ updateArea(layer);
13
+ }
@@ -0,0 +1,40 @@
1
+ import { destroyTexture } from './destroyTexture.js';
2
+ import { conformModelToTerrain } from './conformModelToTerrain.js';
3
+ import { disposeMesh } from './disposeMesh.js';
4
+ import { setRasterTerrain } from './rasterTiles.js';
5
+ import { removeRasterTile } from './removeRasterTile.js';
6
+ import { setTerrainHeight } from './setTerrainHeight.js';
7
+ import { onRemove3DLayer } from './onRemove3DLayer.js';
8
+
9
+ export function onTerrainRemove(layer, map) {
10
+ layer._terrainController?.abort();
11
+ layer._terrainLoading = false;
12
+ layer._terrainReady = false;
13
+ map.eachLayer(layer => {
14
+ if (layer._type === 'pmtiles') setRasterTerrain(layer, null);
15
+ });
16
+ for (const tile of layer._rasterTiles.keys()) removeRasterTile(layer, tile);
17
+ if (map._terrain3D === layer) delete map._terrain3D;
18
+ for (const l of Object.values(map._layers)) {
19
+ conformModelToTerrain(l, null);
20
+ setTerrainHeight(l);
21
+ }
22
+ map.fire('terrainchange');
23
+ layer._terrainTiles.clear();
24
+ layer._terrainOriginElevation = 0;
25
+ layer._terrainPromise = null;
26
+ if (layer._rasterProgram) {
27
+ layer._rasterProgram.pipelineCache.clear();
28
+ }
29
+ layer._rasterProgram = null;
30
+ if (layer._dem) destroyTexture(layer, layer._dem.texture);
31
+ layer._dem = null;
32
+ for (const grid of layer._terrainGrids?.values() || []) {
33
+ for (const attribute of Object.values(grid)) destroyTexture(layer, attribute.buffer);
34
+ }
35
+ layer._terrainGrids = null;
36
+ layer._bridges = null;
37
+ disposeMesh(layer, layer._bridgeMesh);
38
+ layer._bridgeMesh = null;
39
+ onRemove3DLayer(layer, map);
40
+ }
@@ -0,0 +1,14 @@
1
+ import { render } from "./render.js";
2
+
3
+
4
+ export function onZoomAnim(event) {
5
+ const map = this._map;
6
+ if (event && !this._zoomView) {
7
+ this._zoomView = { from: map.getCenter(), zoom: map.getZoom(), to: event.center,
8
+ targetZoom: event.zoom, start: performance.now() };
9
+ map.getContainer().classList.add('leaflet-camera-zoom');
10
+ }
11
+ queueMicrotask(() => {
12
+ if (this._shared === this && this.renderer) render(this);
13
+ });
14
+ }
@@ -0,0 +1,10 @@
1
+ // Built-in vehicles for the 'traffic' type. Models are [ring of [x, z], bottom, top, rgb, topRing?] convex prisms in metres;
2
+ // forward is -z, right is +x. `topRing` (same length as `ring`) tapers the prism; rgb components above 1 are self-lit lamps.
3
+ export const paints = [
4
+ [0.86, 0.86, 0.88],
5
+ [0.1, 0.1, 0.12],
6
+ [0.5, 0.53, 0.57],
7
+ [0.65, 0.1, 0.08],
8
+ [0.12, 0.25, 0.55],
9
+ [0.85, 0.7, 0.15]
10
+ ];
@@ -0,0 +1,42 @@
1
+ import { toSRGB } from "./toSRGB.js";
2
+ import { channel } from "./channel.js";
3
+
4
+ /**
5
+ * HSL inputs are linear-space to preserve the original building styling.
6
+ * Numeric/CSS/RGB inputs are already sRGB; CSS alpha is not used for extrusion.
7
+ * @param {number|string|Object} value 0xRRGGBB, CSS color, {r,g,b}, or {h,s,l} in 0..1.
8
+ * @returns {Object} sRGB {r,g,b} components in 0..1.
9
+ */
10
+
11
+ export function parseColor(value) {
12
+ if (value && typeof value === 'object' && 'h' in value) {
13
+ const a = value.s * Math.min(value.l, 1 - value.l);
14
+ return {
15
+ r: toSRGB(channel(0, value.h, value.l, a)),
16
+ g: toSRGB(channel(8, value.h, value.l, a)),
17
+ b: toSRGB(channel(4, value.h, value.l, a))
18
+ };
19
+ }
20
+ if (value && typeof value === 'object' && 'r' in value) {
21
+ return value;
22
+ }
23
+ if (typeof value === 'number') {
24
+ return {
25
+ r: (value >> 16 & 255) / 255,
26
+ g: (value >> 8 & 255) / 255,
27
+ b: (value & 255) / 255,
28
+ };
29
+ }
30
+ if (typeof value !== 'string' || !CSS.supports('color', value)) {
31
+ throw new Error('Invalid 3D color');
32
+ }
33
+ const context = document.createElement('canvas').getContext('2d');
34
+ context.fillStyle = value;
35
+ context.fillRect(0, 0, 1, 1);
36
+ const [r, g, b] = context.getImageData(0, 0, 1, 1).data;
37
+ return {
38
+ r: r / 255,
39
+ g: g / 255,
40
+ b: b / 255
41
+ };
42
+ }
@@ -0,0 +1,16 @@
1
+ import { box } from "./box.js";
2
+ import { trousers, shirt, skin, dark } from "./skin.js";
3
+
4
+
5
+ export const parts = {
6
+ body: [
7
+ [box(-0.17, 0.17, -0.1, 0.1), 0.82, 0.95, trousers],
8
+ [box(-0.19, 0.19, -0.11, 0.11), 0.95, 1.44, shirt],
9
+ [box(-0.05, 0.05, -0.05, 0.05), 1.44, 1.5, skin],
10
+ [box(-0.1, 0.1, -0.11, 0.1), 1.5, 1.72, skin],
11
+ [box(-0.105, 0.105, -0.06, 0.115), 1.58, 1.77, dark],
12
+ [box(-0.105, 0.105, -0.115, -0.06), 1.7, 1.77, dark],
13
+ ],
14
+ leg: [[box(-0.07, 0.07, -0.07, 0.07), -0.82, 0, trousers], [box(-0.07, 0.07, -0.17, 0.07), -0.9, -0.82, dark]],
15
+ arm: [[box(-0.05, 0.05, -0.05, 0.05), -0.55, 0, shirt], [box(-0.045, 0.045, -0.045, 0.045), -0.66, -0.55, skin]],
16
+ };
@@ -0,0 +1,13 @@
1
+ /** Perspective projection of a celestial direction; null when behind the camera. */
2
+
3
+ export function projectCelestialBody(dir, size, pitch, bearing) {
4
+ const [x, y, z] = dir;
5
+ const forward = -x * Math.sin(bearing) * Math.sin(pitch) - y * Math.cos(pitch) - z * Math.cos(bearing) * Math.sin(pitch);
6
+ if (forward > 0) {
7
+ return {
8
+ left: size.x / 2 + size.y * 1.5 * (x * Math.cos(bearing) - z * Math.sin(bearing)) / forward,
9
+ top: size.y / 2 - size.y * 1.5 * (-x * Math.sin(bearing) * Math.cos(pitch) + y * Math.sin(pitch) - z * Math.cos(bearing) * Math.cos(pitch)) / forward
10
+ };
11
+ }
12
+ return null;
13
+ }