@sakuzu/maplibre-gl-draw 1.0.0

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 (636) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +661 -0
  3. package/README.ja.md +248 -0
  4. package/README.md +255 -0
  5. package/THIRD_PARTY_NOTICES.md +275 -0
  6. package/dist/api/api.d.ts +1259 -0
  7. package/dist/api/api.js +86 -0
  8. package/dist/api/context.d.ts +173 -0
  9. package/dist/api/context.js +193 -0
  10. package/dist/api/display-api.d.ts +1 -0
  11. package/dist/api/display-api.js +23 -0
  12. package/dist/api/event-api.d.ts +13 -0
  13. package/dist/api/event-api.js +17 -0
  14. package/dist/api/extension-api.d.ts +46 -0
  15. package/dist/api/extension-api.js +85 -0
  16. package/dist/api/feature-api.d.ts +11 -0
  17. package/dist/api/feature-api.js +101 -0
  18. package/dist/api/geometry/apply.d.ts +51 -0
  19. package/dist/api/geometry/apply.js +114 -0
  20. package/dist/api/geometry/boolean.d.ts +28 -0
  21. package/dist/api/geometry/boolean.js +65 -0
  22. package/dist/api/geometry/buffer.d.ts +11 -0
  23. package/dist/api/geometry/buffer.js +105 -0
  24. package/dist/api/geometry/split.d.ts +16 -0
  25. package/dist/api/geometry/split.js +75 -0
  26. package/dist/api/geometry/targets.d.ts +76 -0
  27. package/dist/api/geometry/targets.js +158 -0
  28. package/dist/api/geometry/types.d.ts +31 -0
  29. package/dist/api/geometry/types.js +3 -0
  30. package/dist/api/geometry-operations.d.ts +162 -0
  31. package/dist/api/geometry-operations.js +94 -0
  32. package/dist/api/group-api.d.ts +10 -0
  33. package/dist/api/group-api.js +78 -0
  34. package/dist/api/import-export/constants.d.ts +29 -0
  35. package/dist/api/import-export/constants.js +40 -0
  36. package/dist/api/import-export/embedded-file.d.ts +13 -0
  37. package/dist/api/import-export/embedded-file.js +31 -0
  38. package/dist/api/import-export/file-name.d.ts +10 -0
  39. package/dist/api/import-export/file-name.js +20 -0
  40. package/dist/api/import-export/format-detection.d.ts +12 -0
  41. package/dist/api/import-export/format-detection.js +29 -0
  42. package/dist/api/import-export/geojson-export.d.ts +19 -0
  43. package/dist/api/import-export/geojson-export.js +262 -0
  44. package/dist/api/import-export/geojson-import.d.ts +34 -0
  45. package/dist/api/import-export/geojson-import.js +538 -0
  46. package/dist/api/import-export/geometry-validation.d.ts +20 -0
  47. package/dist/api/import-export/geometry-validation.js +107 -0
  48. package/dist/api/import-export/image-import.d.ts +12 -0
  49. package/dist/api/import-export/image-import.js +53 -0
  50. package/dist/api/import-export/index.d.ts +9 -0
  51. package/dist/api/import-export/index.js +107 -0
  52. package/dist/api/import-export/native-format.d.ts +15 -0
  53. package/dist/api/import-export/native-format.js +126 -0
  54. package/dist/api/import-export/native-validation.d.ts +28 -0
  55. package/dist/api/import-export/native-validation.js +212 -0
  56. package/dist/api/import-export/own-property.d.ts +10 -0
  57. package/dist/api/import-export/own-property.js +19 -0
  58. package/dist/api/import-export/style-validation.d.ts +27 -0
  59. package/dist/api/import-export/style-validation.js +49 -0
  60. package/dist/api/import-export/types.d.ts +26 -0
  61. package/dist/api/import-export/types.js +3 -0
  62. package/dist/api/index.d.ts +15 -0
  63. package/dist/api/index.js +3 -0
  64. package/dist/api/input-api.d.ts +158 -0
  65. package/dist/api/input-api.js +144 -0
  66. package/dist/api/instance-api.d.ts +38 -0
  67. package/dist/api/instance-api.js +136 -0
  68. package/dist/api/layer-api.d.ts +12 -0
  69. package/dist/api/layer-api.js +62 -0
  70. package/dist/api/selection-api.d.ts +7 -0
  71. package/dist/api/selection-api.js +78 -0
  72. package/dist/api/snapping-api.d.ts +125 -0
  73. package/dist/api/snapping-api.js +50 -0
  74. package/dist/api/topology-api.d.ts +30 -0
  75. package/dist/api/topology-api.js +16 -0
  76. package/dist/api/tracing-api.d.ts +31 -0
  77. package/dist/api/tracing-api.js +16 -0
  78. package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
  79. package/dist/dispatcher/hit-test/box-strategies.js +275 -0
  80. package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
  81. package/dist/dispatcher/hit-test/box-strategy.js +37 -0
  82. package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
  83. package/dist/dispatcher/hit-test/globe-shape.js +70 -0
  84. package/dist/dispatcher/hit-test/index.d.ts +14 -0
  85. package/dist/dispatcher/hit-test/index.js +9 -0
  86. package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
  87. package/dist/dispatcher/hit-test/local-frame.js +112 -0
  88. package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
  89. package/dist/dispatcher/hit-test/segment-grid.js +79 -0
  90. package/dist/dispatcher/hit-test/service.d.ts +120 -0
  91. package/dist/dispatcher/hit-test/service.js +333 -0
  92. package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
  93. package/dist/dispatcher/hit-test/strategies/base.js +66 -0
  94. package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
  95. package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
  96. package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
  97. package/dist/dispatcher/hit-test/strategies/image.js +115 -0
  98. package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
  99. package/dist/dispatcher/hit-test/strategies/index.js +10 -0
  100. package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
  101. package/dist/dispatcher/hit-test/strategies/line.js +30 -0
  102. package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
  103. package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
  104. package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
  105. package/dist/dispatcher/hit-test/strategies/point.js +29 -0
  106. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
  107. package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
  108. package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
  109. package/dist/dispatcher/hit-test/topmost.js +157 -0
  110. package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
  111. package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
  112. package/dist/dispatcher/index.d.ts +15 -0
  113. package/dist/dispatcher/index.js +3 -0
  114. package/dist/dispatcher/input-router.d.ts +1 -0
  115. package/dist/dispatcher/input-router.js +288 -0
  116. package/dist/dispatcher/normalizer.d.ts +1 -0
  117. package/dist/dispatcher/normalizer.js +513 -0
  118. package/dist/dispatcher/types.d.ts +144 -0
  119. package/dist/dispatcher/types.js +15 -0
  120. package/dist/display/chunk-set.d.ts +24 -0
  121. package/dist/display/chunk-set.js +533 -0
  122. package/dist/display/chunk.d.ts +1 -0
  123. package/dist/display/chunk.js +104 -0
  124. package/dist/display/columnar/index.d.ts +12 -0
  125. package/dist/display/columnar/index.js +13 -0
  126. package/dist/display/columnar/prepare.d.ts +42 -0
  127. package/dist/display/columnar/prepare.js +116 -0
  128. package/dist/display/columnar/source.d.ts +1 -0
  129. package/dist/display/columnar/source.js +531 -0
  130. package/dist/display/columnar/table.d.ts +1 -0
  131. package/dist/display/columnar/table.js +471 -0
  132. package/dist/display/columnar/types.d.ts +223 -0
  133. package/dist/display/columnar/types.js +3 -0
  134. package/dist/display/dataset.d.ts +2 -0
  135. package/dist/display/dataset.js +891 -0
  136. package/dist/display/index.d.ts +13 -0
  137. package/dist/display/index.js +3 -0
  138. package/dist/display/interaction.d.ts +1 -0
  139. package/dist/display/interaction.js +90 -0
  140. package/dist/display/manager.d.ts +1 -0
  141. package/dist/display/manager.js +440 -0
  142. package/dist/display/packed-rtree.d.ts +1 -0
  143. package/dist/display/packed-rtree.js +244 -0
  144. package/dist/display/partition.d.ts +1 -0
  145. package/dist/display/partition.js +226 -0
  146. package/dist/display/provider.d.ts +1 -0
  147. package/dist/display/provider.js +342 -0
  148. package/dist/display/retained.d.ts +40 -0
  149. package/dist/display/retained.js +898 -0
  150. package/dist/display/selection.d.ts +13 -0
  151. package/dist/display/selection.js +226 -0
  152. package/dist/display/source.d.ts +1 -0
  153. package/dist/display/source.js +119 -0
  154. package/dist/display/spatial.d.ts +1 -0
  155. package/dist/display/spatial.js +71 -0
  156. package/dist/display/style.d.ts +1 -0
  157. package/dist/display/style.js +126 -0
  158. package/dist/display/thinning.d.ts +65 -0
  159. package/dist/display/thinning.js +910 -0
  160. package/dist/display/triangulation.d.ts +1 -0
  161. package/dist/display/triangulation.js +0 -0
  162. package/dist/display/types.d.ts +561 -0
  163. package/dist/display/types.js +43 -0
  164. package/dist/extension/feature-handler.d.ts +182 -0
  165. package/dist/extension/feature-handler.js +3 -0
  166. package/dist/extension/index.d.ts +9 -0
  167. package/dist/extension/index.js +3 -0
  168. package/dist/extension/renderers.d.ts +208 -0
  169. package/dist/extension/renderers.js +3 -0
  170. package/dist/geometry/angle.d.ts +47 -0
  171. package/dist/geometry/angle.js +44 -0
  172. package/dist/geometry/bbox.d.ts +48 -0
  173. package/dist/geometry/bbox.js +83 -0
  174. package/dist/geometry/boolean.d.ts +162 -0
  175. package/dist/geometry/boolean.js +331 -0
  176. package/dist/geometry/buffer.d.ts +72 -0
  177. package/dist/geometry/buffer.js +218 -0
  178. package/dist/geometry/circle.d.ts +55 -0
  179. package/dist/geometry/circle.js +107 -0
  180. package/dist/geometry/coords.d.ts +97 -0
  181. package/dist/geometry/coords.js +149 -0
  182. package/dist/geometry/distance.d.ts +79 -0
  183. package/dist/geometry/distance.js +111 -0
  184. package/dist/geometry/errors.d.ts +74 -0
  185. package/dist/geometry/errors.js +104 -0
  186. package/dist/geometry/index.d.ts +28 -0
  187. package/dist/geometry/index.js +38 -0
  188. package/dist/geometry/measure.d.ts +81 -0
  189. package/dist/geometry/measure.js +236 -0
  190. package/dist/geometry/predicates.d.ts +62 -0
  191. package/dist/geometry/predicates.js +132 -0
  192. package/dist/geometry/simplify.d.ts +74 -0
  193. package/dist/geometry/simplify.js +159 -0
  194. package/dist/geometry/split.d.ts +68 -0
  195. package/dist/geometry/split.js +430 -0
  196. package/dist/geometry/types.d.ts +95 -0
  197. package/dist/geometry/types.js +3 -0
  198. package/dist/geometry/units.d.ts +35 -0
  199. package/dist/geometry/units.js +41 -0
  200. package/dist/index.d.ts +72 -0
  201. package/dist/index.js +20 -0
  202. package/dist/maplibre-gl-draw.d.ts +47 -0
  203. package/dist/maplibre-gl-draw.js +407 -0
  204. package/dist/messages.d.ts +64 -0
  205. package/dist/messages.js +36 -0
  206. package/dist/modes/cursor.d.ts +1 -0
  207. package/dist/modes/cursor.js +72 -0
  208. package/dist/modes/draw/circle.d.ts +1 -0
  209. package/dist/modes/draw/circle.js +222 -0
  210. package/dist/modes/draw/commit-layer.d.ts +26 -0
  211. package/dist/modes/draw/commit-layer.js +31 -0
  212. package/dist/modes/draw/freehand.d.ts +1 -0
  213. package/dist/modes/draw/freehand.js +264 -0
  214. package/dist/modes/draw/image.d.ts +1 -0
  215. package/dist/modes/draw/image.js +60 -0
  216. package/dist/modes/draw/index.d.ts +9 -0
  217. package/dist/modes/draw/index.js +11 -0
  218. package/dist/modes/draw/line.d.ts +1 -0
  219. package/dist/modes/draw/line.js +363 -0
  220. package/dist/modes/draw/point.d.ts +1 -0
  221. package/dist/modes/draw/point.js +87 -0
  222. package/dist/modes/draw/polygon.d.ts +1 -0
  223. package/dist/modes/draw/polygon.js +378 -0
  224. package/dist/modes/draw/trace-support.d.ts +79 -0
  225. package/dist/modes/draw/trace-support.js +161 -0
  226. package/dist/modes/handler.d.ts +285 -0
  227. package/dist/modes/handler.js +3 -0
  228. package/dist/modes/index.d.ts +7 -0
  229. package/dist/modes/index.js +3 -0
  230. package/dist/modes/manager.d.ts +15 -0
  231. package/dist/modes/manager.js +196 -0
  232. package/dist/modes/select/box-selection.d.ts +52 -0
  233. package/dist/modes/select/box-selection.js +140 -0
  234. package/dist/modes/select/click-handler.d.ts +32 -0
  235. package/dist/modes/select/click-handler.js +166 -0
  236. package/dist/modes/select/cursor-handler.d.ts +15 -0
  237. package/dist/modes/select/cursor-handler.js +59 -0
  238. package/dist/modes/select/drag/auxiliary.d.ts +26 -0
  239. package/dist/modes/select/drag/auxiliary.js +56 -0
  240. package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
  241. package/dist/modes/select/drag/intermediate-writes.js +171 -0
  242. package/dist/modes/select/drag/move.d.ts +24 -0
  243. package/dist/modes/select/drag/move.js +59 -0
  244. package/dist/modes/select/drag/operation.d.ts +30 -0
  245. package/dist/modes/select/drag/operation.js +18 -0
  246. package/dist/modes/select/drag/radius.d.ts +15 -0
  247. package/dist/modes/select/drag/radius.js +49 -0
  248. package/dist/modes/select/drag/transform.d.ts +17 -0
  249. package/dist/modes/select/drag/transform.js +155 -0
  250. package/dist/modes/select/drag/vertex.d.ts +17 -0
  251. package/dist/modes/select/drag/vertex.js +163 -0
  252. package/dist/modes/select/drag-handler.d.ts +1 -0
  253. package/dist/modes/select/drag-handler.js +254 -0
  254. package/dist/modes/select/hit-helpers.d.ts +40 -0
  255. package/dist/modes/select/hit-helpers.js +51 -0
  256. package/dist/modes/select/mode.d.ts +1 -0
  257. package/dist/modes/select/mode.js +397 -0
  258. package/dist/modes/select/shortcut-handler.d.ts +40 -0
  259. package/dist/modes/select/shortcut-handler.js +128 -0
  260. package/dist/operations/index.d.ts +9 -0
  261. package/dist/operations/index.js +3 -0
  262. package/dist/operations/layer-operations.d.ts +1 -0
  263. package/dist/operations/layer-operations.js +350 -0
  264. package/dist/operations/resize.d.ts +71 -0
  265. package/dist/operations/resize.js +252 -0
  266. package/dist/operations/rotate.d.ts +17 -0
  267. package/dist/operations/rotate.js +166 -0
  268. package/dist/operations/selection-operations.d.ts +20 -0
  269. package/dist/operations/selection-operations.js +159 -0
  270. package/dist/operations/shared-vertex.d.ts +1 -0
  271. package/dist/operations/shared-vertex.js +210 -0
  272. package/dist/operations/trace-graph.d.ts +96 -0
  273. package/dist/operations/trace-graph.js +283 -0
  274. package/dist/operations/vertex.d.ts +1 -0
  275. package/dist/operations/vertex.js +538 -0
  276. package/dist/plugins/index.d.ts +10 -0
  277. package/dist/plugins/index.js +3 -0
  278. package/dist/plugins/mutation-hooks.d.ts +28 -0
  279. package/dist/plugins/mutation-hooks.js +84 -0
  280. package/dist/plugins/plugin-context.d.ts +1 -0
  281. package/dist/plugins/plugin-context.js +367 -0
  282. package/dist/plugins/plugin-manager.d.ts +103 -0
  283. package/dist/plugins/plugin-manager.js +316 -0
  284. package/dist/plugins/plugin.d.ts +529 -0
  285. package/dist/plugins/plugin.js +3 -0
  286. package/dist/shared/config/constants.d.ts +66 -0
  287. package/dist/shared/config/constants.js +60 -0
  288. package/dist/shared/config/feature-style.d.ts +155 -0
  289. package/dist/shared/config/feature-style.js +154 -0
  290. package/dist/shared/config/index.d.ts +17 -0
  291. package/dist/shared/config/index.js +8 -0
  292. package/dist/shared/config/rendering.d.ts +107 -0
  293. package/dist/shared/config/rendering.js +33 -0
  294. package/dist/shared/config/selection-highlight.d.ts +29 -0
  295. package/dist/shared/config/selection-highlight.js +35 -0
  296. package/dist/shared/config/selection.d.ts +273 -0
  297. package/dist/shared/config/selection.js +266 -0
  298. package/dist/shared/config/topology.d.ts +33 -0
  299. package/dist/shared/config/topology.js +17 -0
  300. package/dist/shared/config/trace.d.ts +40 -0
  301. package/dist/shared/config/trace.js +17 -0
  302. package/dist/shared/math/angle.d.ts +21 -0
  303. package/dist/shared/math/angle.js +34 -0
  304. package/dist/shared/math/circle.d.ts +6 -0
  305. package/dist/shared/math/circle.js +10 -0
  306. package/dist/shared/math/constants.d.ts +48 -0
  307. package/dist/shared/math/constants.js +59 -0
  308. package/dist/shared/math/distance.d.ts +78 -0
  309. package/dist/shared/math/distance.js +147 -0
  310. package/dist/shared/math/globe-subdivision.d.ts +62 -0
  311. package/dist/shared/math/globe-subdivision.js +99 -0
  312. package/dist/shared/math/index.d.ts +17 -0
  313. package/dist/shared/math/index.js +21 -0
  314. package/dist/shared/math/intersection.d.ts +63 -0
  315. package/dist/shared/math/intersection.js +236 -0
  316. package/dist/shared/math/longitude.d.ts +20 -0
  317. package/dist/shared/math/longitude.js +31 -0
  318. package/dist/shared/math/mercator-plane.d.ts +27 -0
  319. package/dist/shared/math/mercator-plane.js +26 -0
  320. package/dist/shared/math/obb.d.ts +65 -0
  321. package/dist/shared/math/obb.js +107 -0
  322. package/dist/shared/math/rotation.d.ts +93 -0
  323. package/dist/shared/math/rotation.js +186 -0
  324. package/dist/shared/math/segment-grid.d.ts +69 -0
  325. package/dist/shared/math/segment-grid.js +159 -0
  326. package/dist/shared/math/transform.d.ts +140 -0
  327. package/dist/shared/math/transform.js +189 -0
  328. package/dist/shared/types/events.d.ts +128 -0
  329. package/dist/shared/types/events.js +3 -0
  330. package/dist/shared/types/model.d.ts +950 -0
  331. package/dist/shared/types/model.js +3 -0
  332. package/dist/shared/types/selection-box.d.ts +23 -0
  333. package/dist/shared/types/selection-box.js +3 -0
  334. package/dist/shared/types/style.d.ts +68 -0
  335. package/dist/shared/types/style.js +3 -0
  336. package/dist/shared/utils/color.d.ts +49 -0
  337. package/dist/shared/utils/color.js +180 -0
  338. package/dist/shared/utils/coordinates.d.ts +52 -0
  339. package/dist/shared/utils/coordinates.js +75 -0
  340. package/dist/shared/utils/embedded-image.d.ts +34 -0
  341. package/dist/shared/utils/embedded-image.js +161 -0
  342. package/dist/shared/utils/event-emitter.d.ts +262 -0
  343. package/dist/shared/utils/event-emitter.js +44 -0
  344. package/dist/shared/utils/feature-bbox.d.ts +8 -0
  345. package/dist/shared/utils/feature-bbox.js +207 -0
  346. package/dist/shared/utils/feature-segments.d.ts +23 -0
  347. package/dist/shared/utils/feature-segments.js +179 -0
  348. package/dist/shared/utils/id.d.ts +1 -0
  349. package/dist/shared/utils/id.js +35 -0
  350. package/dist/shared/utils/image.d.ts +34 -0
  351. package/dist/shared/utils/image.js +106 -0
  352. package/dist/shared/utils/index.d.ts +15 -0
  353. package/dist/shared/utils/index.js +24 -0
  354. package/dist/shared/utils/map.d.ts +26 -0
  355. package/dist/shared/utils/map.js +35 -0
  356. package/dist/shared/utils/name-generator.d.ts +197 -0
  357. package/dist/shared/utils/name-generator.js +337 -0
  358. package/dist/shared/utils/pixel-ratio.d.ts +111 -0
  359. package/dist/shared/utils/pixel-ratio.js +85 -0
  360. package/dist/shared/utils/property.d.ts +88 -0
  361. package/dist/shared/utils/property.js +140 -0
  362. package/dist/shared/utils/vertex-ref.d.ts +23 -0
  363. package/dist/shared/utils/vertex-ref.js +20 -0
  364. package/dist/snapping/custom-targets.d.ts +1 -0
  365. package/dist/snapping/custom-targets.js +21 -0
  366. package/dist/snapping/geometry.d.ts +1 -0
  367. package/dist/snapping/geometry.js +61 -0
  368. package/dist/snapping/index.d.ts +14 -0
  369. package/dist/snapping/index.js +4 -0
  370. package/dist/snapping/indicator.d.ts +19 -0
  371. package/dist/snapping/indicator.js +145 -0
  372. package/dist/snapping/providers/display.d.ts +72 -0
  373. package/dist/snapping/providers/display.js +268 -0
  374. package/dist/snapping/providers/guide.d.ts +69 -0
  375. package/dist/snapping/providers/guide.js +187 -0
  376. package/dist/snapping/providers/intersection.d.ts +1 -0
  377. package/dist/snapping/providers/intersection.js +92 -0
  378. package/dist/snapping/providers/shared.d.ts +39 -0
  379. package/dist/snapping/providers/shared.js +146 -0
  380. package/dist/snapping/providers/store.d.ts +1 -0
  381. package/dist/snapping/providers/store.js +132 -0
  382. package/dist/snapping/service.d.ts +1 -0
  383. package/dist/snapping/service.js +272 -0
  384. package/dist/snapping/types.d.ts +267 -0
  385. package/dist/snapping/types.js +66 -0
  386. package/dist/store/change-merger.d.ts +1 -0
  387. package/dist/store/change-merger.js +102 -0
  388. package/dist/store/draw-store.d.ts +1 -0
  389. package/dist/store/draw-store.js +396 -0
  390. package/dist/store/event-bridge.d.ts +1 -0
  391. package/dist/store/event-bridge.js +161 -0
  392. package/dist/store/index.d.ts +12 -0
  393. package/dist/store/index.js +4 -0
  394. package/dist/store/local-visibility.d.ts +21 -0
  395. package/dist/store/local-visibility.js +27 -0
  396. package/dist/store/lock.d.ts +67 -0
  397. package/dist/store/lock.js +54 -0
  398. package/dist/store/memory/change-bus.d.ts +60 -0
  399. package/dist/store/memory/change-bus.js +232 -0
  400. package/dist/store/memory/file-store.d.ts +15 -0
  401. package/dist/store/memory/file-store.js +33 -0
  402. package/dist/store/memory/frozen.d.ts +21 -0
  403. package/dist/store/memory/frozen.js +51 -0
  404. package/dist/store/memory/ui-state.d.ts +51 -0
  405. package/dist/store/memory/ui-state.js +223 -0
  406. package/dist/store/memory.d.ts +26 -0
  407. package/dist/store/memory.js +708 -0
  408. package/dist/store/spatial/index.d.ts +6 -0
  409. package/dist/store/spatial/index.js +4 -0
  410. package/dist/store/spatial/spatial-index.d.ts +90 -0
  411. package/dist/store/spatial/spatial-index.js +148 -0
  412. package/dist/store/spatial/store-spatial-index.d.ts +60 -0
  413. package/dist/store/spatial/store-spatial-index.js +125 -0
  414. package/dist/store/store.d.ts +417 -0
  415. package/dist/store/store.js +3 -0
  416. package/dist/store/types.d.ts +8 -0
  417. package/dist/store/types.js +3 -0
  418. package/dist/store/writable-layer.d.ts +35 -0
  419. package/dist/store/writable-layer.js +20 -0
  420. package/dist/view/cache/buffer.d.ts +28 -0
  421. package/dist/view/cache/buffer.js +176 -0
  422. package/dist/view/cache/earcut.d.ts +1 -0
  423. package/dist/view/cache/earcut.js +122 -0
  424. package/dist/view/cache/style-rule.d.ts +1 -0
  425. package/dist/view/cache/style-rule.js +97 -0
  426. package/dist/view/cache/terrain-fill.d.ts +30 -0
  427. package/dist/view/cache/terrain-fill.js +60 -0
  428. package/dist/view/cache/texture.d.ts +14 -0
  429. package/dist/view/cache/texture.js +292 -0
  430. package/dist/view/coordinator.d.ts +27 -0
  431. package/dist/view/coordinator.js +72 -0
  432. package/dist/view/feature-companion.d.ts +173 -0
  433. package/dist/view/feature-companion.js +108 -0
  434. package/dist/view/globe-subdivision.d.ts +78 -0
  435. package/dist/view/globe-subdivision.js +128 -0
  436. package/dist/view/index.d.ts +47 -0
  437. package/dist/view/index.js +20 -0
  438. package/dist/view/layer/attach.d.ts +20 -0
  439. package/dist/view/layer/attach.js +47 -0
  440. package/dist/view/layer/blend.d.ts +57 -0
  441. package/dist/view/layer/blend.js +14 -0
  442. package/dist/view/layer/custom-layer.d.ts +1 -0
  443. package/dist/view/layer/custom-layer.js +509 -0
  444. package/dist/view/layer/depth-state.d.ts +14 -0
  445. package/dist/view/layer/depth-state.js +44 -0
  446. package/dist/view/layer/display-list.d.ts +1 -0
  447. package/dist/view/layer/display-list.js +111 -0
  448. package/dist/view/layer/drape-planner.d.ts +139 -0
  449. package/dist/view/layer/drape-planner.js +726 -0
  450. package/dist/view/layer/frame-render.d.ts +57 -0
  451. package/dist/view/layer/frame-render.js +209 -0
  452. package/dist/view/layer/frame-state.d.ts +147 -0
  453. package/dist/view/layer/frame-state.js +484 -0
  454. package/dist/view/layer/gl-state.d.ts +77 -0
  455. package/dist/view/layer/gl-state.js +132 -0
  456. package/dist/view/layer/index.d.ts +6 -0
  457. package/dist/view/layer/index.js +5 -0
  458. package/dist/view/layer/render-scope.d.ts +30 -0
  459. package/dist/view/layer/render-scope.js +28 -0
  460. package/dist/view/layer/render.d.ts +87 -0
  461. package/dist/view/layer/render.js +187 -0
  462. package/dist/view/layer/renderers.d.ts +81 -0
  463. package/dist/view/layer/renderers.js +142 -0
  464. package/dist/view/layer/slot-manager.d.ts +26 -0
  465. package/dist/view/layer/slot-manager.js +133 -0
  466. package/dist/view/layer/slots.d.ts +33 -0
  467. package/dist/view/layer/slots.js +50 -0
  468. package/dist/view/layer/store-retained-bbox.d.ts +36 -0
  469. package/dist/view/layer/store-retained-bbox.js +188 -0
  470. package/dist/view/layer/store-retained-chunk.d.ts +97 -0
  471. package/dist/view/layer/store-retained-chunk.js +94 -0
  472. package/dist/view/layer/store-retained-classify.d.ts +34 -0
  473. package/dist/view/layer/store-retained-classify.js +88 -0
  474. package/dist/view/layer/store-retained-collect.d.ts +24 -0
  475. package/dist/view/layer/store-retained-collect.js +121 -0
  476. package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
  477. package/dist/view/layer/store-retained-coord-patch.js +168 -0
  478. package/dist/view/layer/store-retained-immediate.d.ts +63 -0
  479. package/dist/view/layer/store-retained-immediate.js +49 -0
  480. package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
  481. package/dist/view/layer/store-retained-invalidation.js +192 -0
  482. package/dist/view/layer/store-retained.d.ts +198 -0
  483. package/dist/view/layer/store-retained.js +430 -0
  484. package/dist/view/layer/terrain-resolver.d.ts +1 -0
  485. package/dist/view/layer/terrain-resolver.js +174 -0
  486. package/dist/view/renderers/batch-manager.d.ts +61 -0
  487. package/dist/view/renderers/batch-manager.js +718 -0
  488. package/dist/view/renderers/draw-factors.d.ts +60 -0
  489. package/dist/view/renderers/draw-factors.js +35 -0
  490. package/dist/view/renderers/drawer.d.ts +1 -0
  491. package/dist/view/renderers/drawer.js +346 -0
  492. package/dist/view/renderers/image.d.ts +1 -0
  493. package/dist/view/renderers/image.js +255 -0
  494. package/dist/view/renderers/line/dash.d.ts +31 -0
  495. package/dist/view/renderers/line/dash.js +152 -0
  496. package/dist/view/renderers/line/line-geometry.d.ts +39 -0
  497. package/dist/view/renderers/line/line-geometry.js +460 -0
  498. package/dist/view/renderers/line/line-gl.d.ts +1 -0
  499. package/dist/view/renderers/line/line-gl.js +236 -0
  500. package/dist/view/renderers/line/line-shader.d.ts +1 -0
  501. package/dist/view/renderers/line/line-shader.js +364 -0
  502. package/dist/view/renderers/line/line-types.d.ts +43 -0
  503. package/dist/view/renderers/line/line-types.js +3 -0
  504. package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
  505. package/dist/view/renderers/line/line-uniforms.js +390 -0
  506. package/dist/view/renderers/line/sdf-line.d.ts +92 -0
  507. package/dist/view/renderers/line/sdf-line.js +567 -0
  508. package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
  509. package/dist/view/renderers/point/billboard-depth.js +56 -0
  510. package/dist/view/renderers/point/point-instance.d.ts +124 -0
  511. package/dist/view/renderers/point/point-instance.js +738 -0
  512. package/dist/view/renderers/point/point-sdf.d.ts +58 -0
  513. package/dist/view/renderers/point/point-sdf.js +170 -0
  514. package/dist/view/renderers/point/point-shape.d.ts +99 -0
  515. package/dist/view/renderers/point/point-shape.js +504 -0
  516. package/dist/view/renderers/point/point-style.d.ts +1 -0
  517. package/dist/view/renderers/point/point-style.js +46 -0
  518. package/dist/view/renderers/polygon/batch.d.ts +26 -0
  519. package/dist/view/renderers/polygon/batch.js +336 -0
  520. package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
  521. package/dist/view/renderers/polygon/earcut-input.js +55 -0
  522. package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
  523. package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
  524. package/dist/view/renderers/polygon/fill.d.ts +74 -0
  525. package/dist/view/renderers/polygon/fill.js +251 -0
  526. package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
  527. package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
  528. package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
  529. package/dist/view/renderers/polygon/terrain-cull.js +14 -0
  530. package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
  531. package/dist/view/renderers/polygon/triangulator.js +3 -0
  532. package/dist/view/renderers/retained.d.ts +43 -0
  533. package/dist/view/renderers/retained.js +3 -0
  534. package/dist/view/renderers/stroke.d.ts +121 -0
  535. package/dist/view/renderers/stroke.js +621 -0
  536. package/dist/view/shaders/frame.d.ts +8 -0
  537. package/dist/view/shaders/frame.js +37 -0
  538. package/dist/view/shaders/helpers.d.ts +238 -0
  539. package/dist/view/shaders/helpers.js +611 -0
  540. package/dist/view/shaders/initializer.d.ts +27 -0
  541. package/dist/view/shaders/initializer.js +125 -0
  542. package/dist/view/shaders/projection.d.ts +123 -0
  543. package/dist/view/shaders/projection.js +299 -0
  544. package/dist/view/shaders/quad-grid.d.ts +77 -0
  545. package/dist/view/shaders/quad-grid.js +128 -0
  546. package/dist/view/shaders/quad.d.ts +189 -0
  547. package/dist/view/shaders/quad.js +582 -0
  548. package/dist/view/shaders/retained-origin.d.ts +50 -0
  549. package/dist/view/shaders/retained-origin.js +67 -0
  550. package/dist/view/shaders/terrain-shade.d.ts +23 -0
  551. package/dist/view/shaders/terrain-shade.js +93 -0
  552. package/dist/view/style-rule.d.ts +166 -0
  553. package/dist/view/style-rule.js +300 -0
  554. package/dist/view/terrain/anchor.d.ts +135 -0
  555. package/dist/view/terrain/anchor.js +226 -0
  556. package/dist/view/terrain/context.d.ts +132 -0
  557. package/dist/view/terrain/context.js +437 -0
  558. package/dist/view/terrain/dem-atlas.d.ts +97 -0
  559. package/dist/view/terrain/dem-atlas.js +534 -0
  560. package/dist/view/terrain/detect.d.ts +126 -0
  561. package/dist/view/terrain/detect.js +198 -0
  562. package/dist/view/terrain/drape/bin-store.d.ts +179 -0
  563. package/dist/view/terrain/drape/bin-store.js +529 -0
  564. package/dist/view/terrain/drape/binning.d.ts +259 -0
  565. package/dist/view/terrain/drape/binning.js +604 -0
  566. package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
  567. package/dist/view/terrain/drape/edge-constrain.js +175 -0
  568. package/dist/view/terrain/drape/geometry.d.ts +95 -0
  569. package/dist/view/terrain/drape/geometry.js +260 -0
  570. package/dist/view/terrain/drape/mesh.d.ts +50 -0
  571. package/dist/view/terrain/drape/mesh.js +86 -0
  572. package/dist/view/terrain/drape/pass.d.ts +122 -0
  573. package/dist/view/terrain/drape/pass.js +379 -0
  574. package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
  575. package/dist/view/terrain/drape/quad-glyphs.js +117 -0
  576. package/dist/view/terrain/drape/quad.d.ts +249 -0
  577. package/dist/view/terrain/drape/quad.js +835 -0
  578. package/dist/view/terrain/drape/renderer.d.ts +184 -0
  579. package/dist/view/terrain/drape/renderer.js +706 -0
  580. package/dist/view/terrain/drape/shared.d.ts +80 -0
  581. package/dist/view/terrain/drape/shared.js +173 -0
  582. package/dist/view/terrain/drape/stitch.d.ts +155 -0
  583. package/dist/view/terrain/drape/stitch.js +228 -0
  584. package/dist/view/terrain/ground.d.ts +72 -0
  585. package/dist/view/terrain/ground.js +151 -0
  586. package/dist/view/terrain/metrics.d.ts +180 -0
  587. package/dist/view/terrain/metrics.js +231 -0
  588. package/dist/view/terrain/occlusion.d.ts +11 -0
  589. package/dist/view/terrain/occlusion.js +129 -0
  590. package/dist/view/terrain/polygon.d.ts +86 -0
  591. package/dist/view/terrain/polygon.js +301 -0
  592. package/dist/view/terrain/shade.d.ts +48 -0
  593. package/dist/view/terrain/shade.js +45 -0
  594. package/dist/view/terrain/state.d.ts +99 -0
  595. package/dist/view/terrain/state.js +186 -0
  596. package/dist/view/terrain/tessellation.d.ts +265 -0
  597. package/dist/view/terrain/tessellation.js +924 -0
  598. package/dist/view/terrain/tiling.d.ts +56 -0
  599. package/dist/view/terrain/tiling.js +155 -0
  600. package/dist/view/terrain/upstream-terrain.d.ts +82 -0
  601. package/dist/view/terrain/upstream-terrain.js +116 -0
  602. package/dist/view/ui/auxiliary-handles.d.ts +151 -0
  603. package/dist/view/ui/auxiliary-handles.js +22 -0
  604. package/dist/view/ui/bounds.d.ts +53 -0
  605. package/dist/view/ui/bounds.js +149 -0
  606. package/dist/view/ui/box-selection.d.ts +1 -0
  607. package/dist/view/ui/box-selection.js +83 -0
  608. package/dist/view/ui/handle-test.d.ts +1 -0
  609. package/dist/view/ui/handle-test.js +437 -0
  610. package/dist/view/ui/handle-thinning.d.ts +122 -0
  611. package/dist/view/ui/handle-thinning.js +430 -0
  612. package/dist/view/ui/handles.d.ts +25 -0
  613. package/dist/view/ui/handles.js +673 -0
  614. package/dist/view/ui/helper.d.ts +19 -0
  615. package/dist/view/ui/helper.js +76 -0
  616. package/dist/view/ui/index.d.ts +15 -0
  617. package/dist/view/ui/index.js +15 -0
  618. package/dist/view/ui/selection-scope.d.ts +25 -0
  619. package/dist/view/ui/selection-scope.js +34 -0
  620. package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
  621. package/dist/view/ui/selection-ui/bounding-box.js +240 -0
  622. package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
  623. package/dist/view/ui/selection-ui/extension-registry.js +78 -0
  624. package/dist/view/ui/selection-ui/index.d.ts +12 -0
  625. package/dist/view/ui/selection-ui/index.js +12 -0
  626. package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
  627. package/dist/view/ui/selection-ui/renderer.js +227 -0
  628. package/dist/view/ui/selection-ui/types.d.ts +55 -0
  629. package/dist/view/ui/selection-ui/types.js +3 -0
  630. package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
  631. package/dist/view/ui/selection-ui-drawer.js +329 -0
  632. package/dist/view/ui/tentative.d.ts +1 -0
  633. package/dist/view/ui/tentative.js +320 -0
  634. package/dist/view/viewport.d.ts +119 -0
  635. package/dist/view/viewport.js +254 -0
  636. package/package.json +113 -0
@@ -0,0 +1,67 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /** The largest screen error of the baked offsets that is accepted (CSS px) */
4
+ export const RETAINED_ORIGIN_TOLERANCE_PX = 0.1;
5
+ /** The unit roundoff of Float32 */
6
+ const FLOAT32_ROUNDOFF = 2 ** -24;
7
+ /** The width of the world in CSS px at zoom 0 (the tile size of maplibre) */
8
+ const WORLD_SIZE_PX = 512;
9
+ /** The latitude where Web Mercator stops (the scale diverges at the poles) */
10
+ const MAX_MERCATOR_LATITUDE = 85.0511287798;
11
+ /**
12
+ * The center of a bounding box
13
+ */
14
+ export function boundsCenter(bounds) {
15
+ return [(bounds.minX + bounds.maxX) / 2, (bounds.minY + bounds.maxY) / 2];
16
+ }
17
+ /**
18
+ * The screen error (CSS px) that the baked offsets of a batch leave in a region
19
+ *
20
+ * It is the bound described in the module comment, measured at the corner of the region
21
+ * farthest from the origin. A latitude difference is longer on screen by 1 / cos φ, so it is
22
+ * weighted with the highest latitude of the region.
23
+ *
24
+ * @param origin The origin of the batch
25
+ * @param region The region on screen (longitude / latitude)
26
+ * @param zoom The zoom of the camera
27
+ */
28
+ export function retainedOriginErrorPx(origin, region, zoom) {
29
+ const dLng = Math.max(Math.abs(region.minX - origin[0]), Math.abs(region.maxX - origin[0]));
30
+ const dLat = Math.max(Math.abs(region.minY - origin[1]), Math.abs(region.maxY - origin[1]));
31
+ const lat = Math.min(Math.max(Math.abs(region.minY), Math.abs(region.maxY)), MAX_MERCATOR_LATITUDE);
32
+ const latScale = 1 / Math.cos((lat * Math.PI) / 180);
33
+ const pxPerDegree = (WORLD_SIZE_PX * 2 ** zoom) / 360;
34
+ return 2 * FLOAT32_ROUNDOFF * Math.max(dLng, dLat * latScale) * pxPerDegree;
35
+ }
36
+ /**
37
+ * The origin a batch should be built with again for the current view (null = keep it)
38
+ *
39
+ * The region on screen is the extent of the batch clipped to the view. When the current origin
40
+ * leaves more than the tolerance there, the center of that region is proposed, provided it at
41
+ * least halves the error (so that a region that is large on screen, where no origin can do
42
+ * better, does not rebuild every frame).
43
+ *
44
+ * @param origin The origin the batch was built with
45
+ * @param extent The extent of the batch (null when unknown: kept)
46
+ * @param view The view (null when unknown: the whole extent is taken as on screen)
47
+ * @param zoom The zoom of the camera
48
+ */
49
+ export function rebasedRetainedOrigin(origin, extent, view, zoom) {
50
+ if (!extent)
51
+ return null;
52
+ const region = view
53
+ ? {
54
+ minX: Math.max(extent.minX, view.minX),
55
+ minY: Math.max(extent.minY, view.minY),
56
+ maxX: Math.min(extent.maxX, view.maxX),
57
+ maxY: Math.min(extent.maxY, view.maxY),
58
+ }
59
+ : extent;
60
+ if (!(region.minX <= region.maxX && region.minY <= region.maxY))
61
+ return null;
62
+ const error = retainedOriginErrorPx(origin, region, zoom);
63
+ if (!(error > RETAINED_ORIGIN_TOLERANCE_PX))
64
+ return null;
65
+ const candidate = boundsCenter(region);
66
+ return retainedOriginErrorPx(candidate, region, zoom) < error / 2 ? candidate : null;
67
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Vertex side: GLSL that hands over the sample position for the shading
3
+ *
4
+ * Place it after OFFSET_MODE_GLSL and call `emitShadeOffset(a_pos)` inside
5
+ * main. A draw that does not call it leaves the varying undefined, so a shader
6
+ * that has a fill must call it exactly once on every branch.
7
+ */
8
+ export declare const TERRAIN_SHADE_VERTEX_GLSL = "\nout vec2 v_shade_offset;\n\nvoid emitShadeOffset(vec2 lngLatOffset) {\n v_shade_offset = shade_mercator_offset(lngLatOffset);\n}\n";
9
+ /**
10
+ * Fragment side: GLSL that produces the coefficient applied to the polygon fill
11
+ *
12
+ * `terrainFillShade()` returns 1.0 on flat ground and when terrain is
13
+ * disabled. When terrain is disabled (`u_shade_strength` is 0) it returns
14
+ * without reading the DEM, so the cost and the pixels are the same as before
15
+ * terrain was introduced.
16
+ *
17
+ * The shading is applied even on frames that draw polygons and lines flat (the
18
+ * zoomed-out band). Stopping the vertex displacement is a measure to avoid
19
+ * cliffs; it does not mean the relief of the ground surface no longer needs to
20
+ * be readable. If anything, that band is exactly the boundary where the paths
21
+ * swap over.
22
+ */
23
+ export declare const TERRAIN_SHADE_FRAGMENT_GLSL: string;
@@ -0,0 +1,93 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Terrain shading applied to the polygon fill of the vertex displacement path
5
+ *
6
+ * There are two paths for laying a polygon fill onto the ground surface:
7
+ * analytic drape (painting it as pixels of the ground surface) and vertex
8
+ * displacement (lifting the vertices of the feature and painting them). The
9
+ * path is switched by cost, so even on the same map it swaps over depending on
10
+ * the camera angle and the amount of data. If the fill looks different between
11
+ * the paths, the picture jumps at that switch. In practice it showed up as
12
+ * "tilting makes relief appear on the polygon, and straightening it brings
13
+ * back a uniform color".
14
+ *
15
+ * So the same shading as the analytic drape is applied to the fill of the
16
+ * vertex displacement path as well. The formula shares the single place in
17
+ * `terrain/shade.ts` (same light source, same normalization, same clamp); only
18
+ * the way samples are taken differs. The drape reads the DEM in tile
19
+ * coordinates, while this one reads the DEM atlas with the Mercator relative
20
+ * coordinates handed over from the vertex.
21
+ *
22
+ * It is applied only to polygon fills. Lines, points, labels and handles are
23
+ * left unshaded for readability (the same convention as the drape path).
24
+ */
25
+ import { TERRAIN_SHADE_CORE_GLSL } from '../terrain/shade.js';
26
+ import { DEM_SAMPLE_GLSL } from './helpers.js';
27
+ /**
28
+ * Vertex side: GLSL that hands over the sample position for the shading
29
+ *
30
+ * Place it after OFFSET_MODE_GLSL and call `emitShadeOffset(a_pos)` inside
31
+ * main. A draw that does not call it leaves the varying undefined, so a shader
32
+ * that has a fill must call it exactly once on every branch.
33
+ */
34
+ export const TERRAIN_SHADE_VERTEX_GLSL = `
35
+ out vec2 v_shade_offset;
36
+
37
+ void emitShadeOffset(vec2 lngLatOffset) {
38
+ v_shade_offset = shade_mercator_offset(lngLatOffset);
39
+ }
40
+ `;
41
+ /**
42
+ * Fragment side: GLSL that produces the coefficient applied to the polygon fill
43
+ *
44
+ * `terrainFillShade()` returns 1.0 on flat ground and when terrain is
45
+ * disabled. When terrain is disabled (`u_shade_strength` is 0) it returns
46
+ * without reading the DEM, so the cost and the pixels are the same as before
47
+ * terrain was introduced.
48
+ *
49
+ * The shading is applied even on frames that draw polygons and lines flat (the
50
+ * zoomed-out band). Stopping the vertex displacement is a measure to avoid
51
+ * cliffs; it does not mean the relief of the ground surface no longer needs to
52
+ * be readable. If anything, that band is exactly the boundary where the paths
53
+ * swap over.
54
+ */
55
+ export const TERRAIN_SHADE_FRAGMENT_GLSL = `
56
+ in vec2 v_shade_offset;
57
+
58
+ // Shading (an aid for reading the terrain). Same light source and same formula as the ground,
59
+ // applied to the fill only
60
+ uniform vec3 u_light_dir; // unit vector in the map coordinate system (east, north, up)
61
+ uniform float u_shade_strength;
62
+ ` +
63
+ DEM_SAMPLE_GLSL +
64
+ TERRAIN_SHADE_CORE_GLSL +
65
+ `
66
+ float terrainFillShade() {
67
+ if (u_shade_strength <= 0.0) return 1.0;
68
+
69
+ // The sample width is one texel of the DEM atlas. rect.zw = 1/width, 1/height
70
+ // (Mercator), so the Mercator width of a texel is 1/(rect.zw * size).
71
+ vec2 texel = 1.0 / max(u_dem_atlas_rect.zw * u_dem_atlas_size, vec2(1e-9));
72
+
73
+ // The ground distance of Mercator 1.0 (meters). It is exactly the reciprocal of the
74
+ // meters -> Mercator z coefficient (u_elevation_params.x). It uses the same value as the
75
+ // conversion applied when the vertex adds the elevation, so the unit of the gradient
76
+ // never drifts.
77
+ float meters = 1.0 / max(u_elevation_params.x, 1e-12);
78
+
79
+ // Outside the atlas, the clamp in dem_elevation_meters returns the edge value. The
80
+ // gradient goes thin there, but since the atlas covers the terrain tiles in view, this
81
+ // does not happen in the range where the polygon fill is applied (only the coarse tiles
82
+ // on the horizon side fall outside the range).
83
+ float ex1 = dem_elevation_meters(v_shade_offset + vec2(texel.x, 0.0));
84
+ float ex0 = dem_elevation_meters(v_shade_offset - vec2(texel.x, 0.0));
85
+ float ey1 = dem_elevation_meters(v_shade_offset + vec2(0.0, texel.y));
86
+ float ey0 = dem_elevation_meters(v_shade_offset - vec2(0.0, texel.y));
87
+
88
+ float dzdEast = (ex1 - ex0) / (2.0 * texel.x * meters);
89
+ // Mercator y points south, so flip north
90
+ float dzdNorth = -(ey1 - ey0) / (2.0 * texel.y * meters);
91
+ return terrainShadeFromGradient(dzdEast, dzdNorth);
92
+ }
93
+ `;
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Style rules of a layer
3
+ *
4
+ * A set of pure functions that evaluate the declarative style rule a layer holds
5
+ * (`Layer.styleRule`) and derive a color from the attributes of a feature. So that the
6
+ * same functions can be used both from rendering (FeatureDrawer) and from
7
+ * datasets, they depend on neither the Store, nor WebGL, nor the DOM.
8
+ *
9
+ * The priority of evaluation is "the feature's own color > the layer's rule > the default
10
+ * color". Whether a feature has its own color is decided by the presence of the color
11
+ * property of the relevant channel, to match the existing style resolution (FeatureDrawer
12
+ * merges `style.fillColor` and the like into the defaults property by property).
13
+ * Therefore the rule does apply to a feature that only holds things other than colors,
14
+ * such as `{ strokeWidth: 3 }`.
15
+ *
16
+ * When the attribute is missing or its type does not match, it falls back to the rule's
17
+ * `other` rather than to the default color. This is so that the caller can tell
18
+ * "the rule is not taking effect" apart from "there is no value".
19
+ */
20
+ import { type Messages } from '../messages.js';
21
+ import type { Feature, FeatureStyle, FeatureType, StyleRule } from '../store/types.js';
22
+ /**
23
+ * One row of a legend derived by {@link deriveLegend}: a label and a color.
24
+ *
25
+ * It holds only a label and a color. The library does not draw the legend UI.
26
+ */
27
+ export interface LegendEntry {
28
+ /** The displayed label */
29
+ label: string;
30
+ /** The color (in #RRGGBB form) */
31
+ color: string;
32
+ }
33
+ /**
34
+ * Which color property of a feature style the rule color goes to, by geometry type.
35
+ *
36
+ * It expresses which style property the rule's color becomes, per geometry type.
37
+ *
38
+ * - point: `pointColor` (Point / MultiPoint)
39
+ * - stroke: `strokeColor` (LineString / MultiLineString / Freehand)
40
+ * - fill: `fillColor` (Polygon / MultiPolygon / Circle)
41
+ */
42
+ export type StyleRuleChannel = 'point' | 'stroke' | 'fill';
43
+ /**
44
+ * Returns the channel that carries the rule color for a feature type.
45
+ *
46
+ * Types other than the known ones (Image and custom types) return 'fill'.
47
+ *
48
+ * @param type The feature type
49
+ * @returns `'point'`, `'stroke'` or `'fill'`
50
+ */
51
+ export declare function getStyleRuleChannel(type: FeatureType): StyleRuleChannel;
52
+ /**
53
+ * Evaluates a style rule against the attributes of a feature and returns a color.
54
+ *
55
+ * When the attribute is missing or its type does not match, the rule's `other` is
56
+ * returned. `single` does not look at attributes, so it is always the same color.
57
+ * `categorical` matches strings, numbers and booleans by `String(value)`; `graduated` and
58
+ * `continuous` take finite numbers only (a numeric string gives `other`). `continuous`
59
+ * clamps values outside `min`..`max` and returns the first ramp color when `max <= min`. It
60
+ * is a pure function.
61
+ *
62
+ * @param rule The style rule
63
+ * @param properties The attributes of the feature
64
+ * @returns The color in `#RRGGBB` form
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * import { evaluateStyleRule, type StyleRule } from '@sakuzu/maplibre-gl-draw';
69
+ *
70
+ * const rule: StyleRule = {
71
+ * kind: 'graduated',
72
+ * property: 'population',
73
+ * breaks: [1000, 10000],
74
+ * colors: ['#fee8c8', '#fdbb84', '#e34a33'],
75
+ * other: '#cccccc',
76
+ * };
77
+ * evaluateStyleRule(rule, { population: 5000 }); // '#fdbb84'
78
+ * evaluateStyleRule(rule, { population: '5000' }); // '#cccccc' (not a number)
79
+ * evaluateStyleRule(rule, {}); // '#cccccc'
80
+ * ```
81
+ */
82
+ export declare function evaluateStyleRule(rule: StyleRule, properties: Record<string, unknown> | undefined): string;
83
+ /**
84
+ * Returns the rule color of a feature, or null when there is no rule.
85
+ *
86
+ * Returns null when there is no rule. The precedence of the feature's own style is a
87
+ * per-channel decision, so it is not decided here (`applyRuleColor` does it).
88
+ *
89
+ * @param feature The target feature
90
+ * @param rule The style rule of the layer (undefined when it is not set)
91
+ * @returns The rule color (in #RRGGBB form). null when there is no rule
92
+ */
93
+ export declare function resolveRuleColor(feature: Feature, rule: StyleRule | undefined): string | null;
94
+ /**
95
+ * Returns the style of a feature with the rule color put on the color property of a
96
+ * channel.
97
+ *
98
+ * A feature that has its own color property for the relevant channel beats the rule, so
99
+ * in that case the original style is returned as is. Properties other than colors (stroke
100
+ * width, opacity and so on) are used together with the rule color.
101
+ *
102
+ * @param style The feature's own style
103
+ * @param ruleColor The rule color (null means there is no rule)
104
+ * @param channel The channel that carries the rule color
105
+ * @returns The effective style: the input itself when `ruleColor` is null or the feature
106
+ * has its own color for the channel, otherwise a new object
107
+ */
108
+ export declare function applyRuleColor(style: FeatureStyle | undefined, ruleColor: string | null, channel: StyleRuleChannel): FeatureStyle | undefined;
109
+ /**
110
+ * Returns the effective style of a feature under the style rule of its layer.
111
+ *
112
+ * A combination of `resolveRuleColor` and `applyRuleColor`. The rendering path that uses a
113
+ * cache caches only the resolution of the rule color, so it calls the two separately.
114
+ *
115
+ * @param feature The target feature
116
+ * @param rule The style rule of the layer
117
+ * @param channel The channel that carries the rule color
118
+ * @returns The effective style
119
+ */
120
+ export declare function resolveFeatureStyle(feature: Feature, rule: StyleRule | undefined, channel: StyleRuleChannel): FeatureStyle | undefined;
121
+ /**
122
+ * Derives the rows of a legend from a style rule; the library does not draw the legend.
123
+ *
124
+ * Every label that is not a value of the data comes from the messages table (English by
125
+ * default; see `Messages`). The rules for turning labels into strings are as follows.
126
+ *
127
+ * - single: 1 entry. The label is `legendAll` ("All")
128
+ * - categorical: the keys of `map` become the labels as they are, lined up in declaration
129
+ * order. `legendOther` ("Other", the color of `other`) is appended at the end
130
+ * - graduated: the boundary notation of each class (`legendBelow` "Below 10",
131
+ * `legendRange` "10 to below 20", `legendAtLeast` "20 or more"). `legendOther` is
132
+ * appended at the end
133
+ * - continuous: only the 2 end points `min` and `max` (no intermediate colors).
134
+ * `legendOther` is appended at the end
135
+ *
136
+ * Numbers are turned into strings with `String()`. Locale formatting is up to the caller.
137
+ *
138
+ * @param rule The style rule
139
+ * @param messages The entries of the messages table to use (default: `MESSAGES_EN`;
140
+ * missing entries fall back to it)
141
+ * @returns The legend rows, in the order to show them
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * import { deriveLegend, type StyleRule } from '@sakuzu/maplibre-gl-draw';
146
+ *
147
+ * const rule: StyleRule = {
148
+ * kind: 'graduated',
149
+ * property: 'population',
150
+ * breaks: [1000, 10000],
151
+ * colors: ['#fee8c8', '#fdbb84', '#e34a33'],
152
+ * other: '#cccccc',
153
+ * };
154
+ * deriveLegend(rule);
155
+ * // [
156
+ * // { label: 'Below 1000', color: '#fee8c8' },
157
+ * // { label: '1000 to below 10000', color: '#fdbb84' },
158
+ * // { label: '10000 or more', color: '#e34a33' },
159
+ * // { label: 'Other', color: '#cccccc' },
160
+ * // ]
161
+ *
162
+ * // In the language of the host application
163
+ * deriveLegend(rule, { legendOther: 'Autres', legendBelow: (upper) => `Moins de ${upper}` });
164
+ * ```
165
+ */
166
+ export declare function deriveLegend(rule: StyleRule, messages?: Partial<Messages>): LegendEntry[];
@@ -0,0 +1,300 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Style rules of a layer
5
+ *
6
+ * A set of pure functions that evaluate the declarative style rule a layer holds
7
+ * (`Layer.styleRule`) and derive a color from the attributes of a feature. So that the
8
+ * same functions can be used both from rendering (FeatureDrawer) and from
9
+ * datasets, they depend on neither the Store, nor WebGL, nor the DOM.
10
+ *
11
+ * The priority of evaluation is "the feature's own color > the layer's rule > the default
12
+ * color". Whether a feature has its own color is decided by the presence of the color
13
+ * property of the relevant channel, to match the existing style resolution (FeatureDrawer
14
+ * merges `style.fillColor` and the like into the defaults property by property).
15
+ * Therefore the rule does apply to a feature that only holds things other than colors,
16
+ * such as `{ strokeWidth: 3 }`.
17
+ *
18
+ * When the attribute is missing or its type does not match, it falls back to the rule's
19
+ * `other` rather than to the default color. This is so that the caller can tell
20
+ * "the rule is not taking effect" apart from "there is no value".
21
+ */
22
+ import { MESSAGES_EN, resolveMessages } from '../messages.js';
23
+ import { interpolateHexColor } from '../shared/utils/color.js';
24
+ /** The name of the FeatureStyle color property corresponding to each channel */
25
+ const CHANNEL_COLOR_PROPERTY = {
26
+ point: 'pointColor',
27
+ stroke: 'strokeColor',
28
+ fill: 'fillColor',
29
+ };
30
+ /**
31
+ * Returns the channel that carries the rule color for a feature type.
32
+ *
33
+ * Types other than the known ones (Image and custom types) return 'fill'.
34
+ *
35
+ * @param type The feature type
36
+ * @returns `'point'`, `'stroke'` or `'fill'`
37
+ */
38
+ export function getStyleRuleChannel(type) {
39
+ switch (type) {
40
+ case 'Point':
41
+ case 'MultiPoint':
42
+ return 'point';
43
+ case 'LineString':
44
+ case 'MultiLineString':
45
+ case 'Freehand':
46
+ return 'stroke';
47
+ default:
48
+ return 'fill';
49
+ }
50
+ }
51
+ /**
52
+ * Computes the key string of categorical
53
+ *
54
+ * Strings, numbers and booleans are turned into strings with `String()` and matched
55
+ * against the keys of the map. Anything else (objects, arrays, null, undefined) is not
56
+ * matched.
57
+ */
58
+ function toCategoricalKey(value) {
59
+ if (typeof value === 'string')
60
+ return value;
61
+ if (typeof value === 'number')
62
+ return Number.isFinite(value) ? String(value) : null;
63
+ if (typeof value === 'boolean')
64
+ return String(value);
65
+ return null;
66
+ }
67
+ /**
68
+ * Computes the number used by graduated / continuous
69
+ *
70
+ * No type conversion is done. Non-numbers (numeric strings included), NaN and Infinity
71
+ * give null.
72
+ */
73
+ function toFiniteNumber(value) {
74
+ return typeof value === 'number' && Number.isFinite(value) ? value : null;
75
+ }
76
+ /**
77
+ * Computes the class of graduated
78
+ *
79
+ * `breaks` are the boundary values in ascending order (n of them) and `colors` has n + 1
80
+ * entries. If the value v is below `breaks[i]` it is `colors[i]`, and if it is below no
81
+ * boundary at all it is `colors[n]`.
82
+ */
83
+ function graduatedIndex(breaks, value) {
84
+ for (let i = 0; i < breaks.length; i++) {
85
+ if (value < breaks[i])
86
+ return i;
87
+ }
88
+ return breaks.length;
89
+ }
90
+ /**
91
+ * Evaluates a style rule against the attributes of a feature and returns a color.
92
+ *
93
+ * When the attribute is missing or its type does not match, the rule's `other` is
94
+ * returned. `single` does not look at attributes, so it is always the same color.
95
+ * `categorical` matches strings, numbers and booleans by `String(value)`; `graduated` and
96
+ * `continuous` take finite numbers only (a numeric string gives `other`). `continuous`
97
+ * clamps values outside `min`..`max` and returns the first ramp color when `max <= min`. It
98
+ * is a pure function.
99
+ *
100
+ * @param rule The style rule
101
+ * @param properties The attributes of the feature
102
+ * @returns The color in `#RRGGBB` form
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * import { evaluateStyleRule, type StyleRule } from '@sakuzu/maplibre-gl-draw';
107
+ *
108
+ * const rule: StyleRule = {
109
+ * kind: 'graduated',
110
+ * property: 'population',
111
+ * breaks: [1000, 10000],
112
+ * colors: ['#fee8c8', '#fdbb84', '#e34a33'],
113
+ * other: '#cccccc',
114
+ * };
115
+ * evaluateStyleRule(rule, { population: 5000 }); // '#fdbb84'
116
+ * evaluateStyleRule(rule, { population: '5000' }); // '#cccccc' (not a number)
117
+ * evaluateStyleRule(rule, {}); // '#cccccc'
118
+ * ```
119
+ */
120
+ export function evaluateStyleRule(rule, properties) {
121
+ if (rule.kind === 'single') {
122
+ return rule.color;
123
+ }
124
+ return evaluateStyleRuleValue(rule, properties?.[rule.property]);
125
+ }
126
+ /**
127
+ * Evaluates a style rule against the value of the attribute it reads
128
+ *
129
+ * The same result as `evaluateStyleRule(rule, { [rule.property]: value })`, for a caller that
130
+ * holds the attribute as a column rather than as the properties of a feature.
131
+ *
132
+ * @internal
133
+ */
134
+ export function evaluateStyleRuleValue(rule, value) {
135
+ if (rule.kind === 'single') {
136
+ return rule.color;
137
+ }
138
+ if (rule.kind === 'categorical') {
139
+ const key = toCategoricalKey(value);
140
+ if (key === null)
141
+ return rule.other;
142
+ const color = rule.map[key];
143
+ return color ?? rule.other;
144
+ }
145
+ const numeric = toFiniteNumber(value);
146
+ if (numeric === null)
147
+ return rule.other;
148
+ if (rule.kind === 'graduated') {
149
+ const color = rule.colors[graduatedIndex(rule.breaks, numeric)];
150
+ // An invalid rule whose colors count falls short of breaks + 1 falls back to other
151
+ return color ?? rule.other;
152
+ }
153
+ // continuous: linearly interpolates the 2 colors of the ramp over min..max
154
+ // (out-of-range values are clamped)
155
+ const [from, to] = rule.ramp;
156
+ if (!(rule.max > rule.min))
157
+ return from;
158
+ const t = Math.min(1, Math.max(0, (numeric - rule.min) / (rule.max - rule.min)));
159
+ return interpolateHexColor(from, to, t);
160
+ }
161
+ /**
162
+ * Returns the rule color of a feature, or null when there is no rule.
163
+ *
164
+ * Returns null when there is no rule. The precedence of the feature's own style is a
165
+ * per-channel decision, so it is not decided here (`applyRuleColor` does it).
166
+ *
167
+ * @param feature The target feature
168
+ * @param rule The style rule of the layer (undefined when it is not set)
169
+ * @returns The rule color (in #RRGGBB form). null when there is no rule
170
+ */
171
+ export function resolveRuleColor(feature, rule) {
172
+ if (!rule)
173
+ return null;
174
+ return evaluateStyleRule(rule, feature.properties);
175
+ }
176
+ /**
177
+ * Returns the style of a feature with the rule color put on the color property of a
178
+ * channel.
179
+ *
180
+ * A feature that has its own color property for the relevant channel beats the rule, so
181
+ * in that case the original style is returned as is. Properties other than colors (stroke
182
+ * width, opacity and so on) are used together with the rule color.
183
+ *
184
+ * @param style The feature's own style
185
+ * @param ruleColor The rule color (null means there is no rule)
186
+ * @param channel The channel that carries the rule color
187
+ * @returns The effective style: the input itself when `ruleColor` is null or the feature
188
+ * has its own color for the channel, otherwise a new object
189
+ */
190
+ export function applyRuleColor(style, ruleColor, channel) {
191
+ if (ruleColor === null)
192
+ return style;
193
+ const property = CHANNEL_COLOR_PROPERTY[channel];
194
+ if (style?.[property])
195
+ return style;
196
+ return { ...style, [property]: ruleColor };
197
+ }
198
+ /**
199
+ * Returns the effective style of a feature under the style rule of its layer.
200
+ *
201
+ * A combination of `resolveRuleColor` and `applyRuleColor`. The rendering path that uses a
202
+ * cache caches only the resolution of the rule color, so it calls the two separately.
203
+ *
204
+ * @param feature The target feature
205
+ * @param rule The style rule of the layer
206
+ * @param channel The channel that carries the rule color
207
+ * @returns The effective style
208
+ */
209
+ export function resolveFeatureStyle(feature, rule, channel) {
210
+ const style = feature.style;
211
+ return applyRuleColor(style, resolveRuleColor(feature, rule), channel);
212
+ }
213
+ /**
214
+ * Builds the class label of graduated
215
+ *
216
+ * Numbers are turned into strings with `String()` as they are (formatting such as digit
217
+ * grouping and units is the caller's responsibility).
218
+ */
219
+ function graduatedLabel(breaks, index, messages) {
220
+ if (breaks.length === 0)
221
+ return messages.legendAll;
222
+ if (index === 0)
223
+ return messages.legendBelow(String(breaks[0]));
224
+ if (index >= breaks.length)
225
+ return messages.legendAtLeast(String(breaks[breaks.length - 1]));
226
+ return messages.legendRange(String(breaks[index - 1]), String(breaks[index]));
227
+ }
228
+ /**
229
+ * Derives the rows of a legend from a style rule; the library does not draw the legend.
230
+ *
231
+ * Every label that is not a value of the data comes from the messages table (English by
232
+ * default; see `Messages`). The rules for turning labels into strings are as follows.
233
+ *
234
+ * - single: 1 entry. The label is `legendAll` ("All")
235
+ * - categorical: the keys of `map` become the labels as they are, lined up in declaration
236
+ * order. `legendOther` ("Other", the color of `other`) is appended at the end
237
+ * - graduated: the boundary notation of each class (`legendBelow` "Below 10",
238
+ * `legendRange` "10 to below 20", `legendAtLeast` "20 or more"). `legendOther` is
239
+ * appended at the end
240
+ * - continuous: only the 2 end points `min` and `max` (no intermediate colors).
241
+ * `legendOther` is appended at the end
242
+ *
243
+ * Numbers are turned into strings with `String()`. Locale formatting is up to the caller.
244
+ *
245
+ * @param rule The style rule
246
+ * @param messages The entries of the messages table to use (default: `MESSAGES_EN`;
247
+ * missing entries fall back to it)
248
+ * @returns The legend rows, in the order to show them
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * import { deriveLegend, type StyleRule } from '@sakuzu/maplibre-gl-draw';
253
+ *
254
+ * const rule: StyleRule = {
255
+ * kind: 'graduated',
256
+ * property: 'population',
257
+ * breaks: [1000, 10000],
258
+ * colors: ['#fee8c8', '#fdbb84', '#e34a33'],
259
+ * other: '#cccccc',
260
+ * };
261
+ * deriveLegend(rule);
262
+ * // [
263
+ * // { label: 'Below 1000', color: '#fee8c8' },
264
+ * // { label: '1000 to below 10000', color: '#fdbb84' },
265
+ * // { label: '10000 or more', color: '#e34a33' },
266
+ * // { label: 'Other', color: '#cccccc' },
267
+ * // ]
268
+ *
269
+ * // In the language of the host application
270
+ * deriveLegend(rule, { legendOther: 'Autres', legendBelow: (upper) => `Moins de ${upper}` });
271
+ * ```
272
+ */
273
+ export function deriveLegend(rule, messages) {
274
+ const table = messages ? resolveMessages(messages) : MESSAGES_EN;
275
+ if (rule.kind === 'single') {
276
+ return [{ label: table.legendAll, color: rule.color }];
277
+ }
278
+ if (rule.kind === 'categorical') {
279
+ const entries = Object.keys(rule.map).map((key) => ({
280
+ label: key,
281
+ color: rule.map[key],
282
+ }));
283
+ entries.push({ label: table.legendOther, color: rule.other });
284
+ return entries;
285
+ }
286
+ if (rule.kind === 'graduated') {
287
+ const count = Math.min(rule.colors.length, rule.breaks.length + 1);
288
+ const entries = [];
289
+ for (let i = 0; i < count; i++) {
290
+ entries.push({ label: graduatedLabel(rule.breaks, i, table), color: rule.colors[i] });
291
+ }
292
+ entries.push({ label: table.legendOther, color: rule.other });
293
+ return entries;
294
+ }
295
+ return [
296
+ { label: String(rule.min), color: rule.ramp[0] },
297
+ { label: String(rule.max), color: rule.ramp[1] },
298
+ { label: table.legendOther, color: rule.other },
299
+ ];
300
+ }