@sakuzu/maplibre-gl-draw 1.0.0 → 2.1.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 (541) hide show
  1. package/CHANGELOG.md +1109 -2
  2. package/README.ja.md +83 -50
  3. package/README.md +89 -53
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/dist/api/datasets.d.ts +263 -0
  6. package/dist/api/document.d.ts +66 -0
  7. package/dist/api/draw.d.ts +137 -0
  8. package/dist/api/draw.js +20 -0
  9. package/dist/api/drawing.d.ts +87 -0
  10. package/dist/api/errors.d.ts +35 -0
  11. package/dist/api/errors.js +35 -0
  12. package/dist/api/events.d.ts +316 -0
  13. package/dist/api/extension/context.d.ts +247 -0
  14. package/dist/api/extension/feature-type.d.ts +129 -0
  15. package/dist/api/extension/mode.d.ts +123 -0
  16. package/dist/api/extension/plugin.d.ts +51 -0
  17. package/dist/api/extension/plugin.js +3 -0
  18. package/dist/api/extension/provider.d.ts +119 -0
  19. package/dist/api/extension/provider.js +3 -0
  20. package/dist/api/extension/render.d.ts +176 -0
  21. package/dist/api/extension/render.js +3 -0
  22. package/dist/api/extension/store.d.ts +190 -0
  23. package/dist/api/extension/store.js +3 -0
  24. package/dist/api/extensions.d.ts +306 -0
  25. package/dist/api/extensions.js +3 -0
  26. package/dist/api/features.d.ts +188 -0
  27. package/dist/api/features.js +3 -0
  28. package/dist/api/groups.d.ts +111 -0
  29. package/dist/api/groups.js +3 -0
  30. package/dist/api/hidden.d.ts +45 -0
  31. package/dist/api/hidden.js +3 -0
  32. package/dist/api/impl/adapters.js +463 -0
  33. package/dist/api/impl/contexts.js +466 -0
  34. package/dist/api/impl/create-draw.js +124 -0
  35. package/dist/api/impl/datasets.js +405 -0
  36. package/dist/api/impl/destroy-guard.js +74 -0
  37. package/dist/api/impl/document.js +280 -0
  38. package/dist/api/impl/drawing.js +180 -0
  39. package/dist/api/impl/engine-context.d.ts +7 -0
  40. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  41. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  42. package/dist/api/impl/events.js +423 -0
  43. package/dist/api/impl/extension-host.js +364 -0
  44. package/dist/api/impl/extensions.js +229 -0
  45. package/dist/api/impl/features.js +445 -0
  46. package/dist/api/impl/geometry/apply.d.ts +32 -0
  47. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  48. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  49. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  50. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  51. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  52. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  53. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  54. package/dist/api/impl/geometry/types.js +3 -0
  55. package/dist/api/impl/groups.d.ts +3 -0
  56. package/dist/api/impl/groups.js +268 -0
  57. package/dist/api/impl/hidden.js +60 -0
  58. package/dist/api/impl/import-export/constants.d.ts +22 -0
  59. package/dist/api/impl/import-export/constants.js +24 -0
  60. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  61. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  62. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  63. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  64. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  66. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  68. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  69. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  70. package/dist/api/impl/import-export/image-import.js +73 -0
  71. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  72. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  73. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  74. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  75. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  76. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  77. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  78. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  79. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  80. package/dist/api/impl/import-export/style-validation.js +86 -0
  81. package/dist/api/impl/import-export/types.d.ts +52 -0
  82. package/dist/api/impl/import-export/types.js +3 -0
  83. package/dist/api/impl/input.js +180 -0
  84. package/dist/api/impl/layers.js +307 -0
  85. package/dist/api/impl/metadata.d.ts +1 -0
  86. package/dist/api/impl/metadata.js +22 -0
  87. package/dist/api/impl/options.d.ts +1 -0
  88. package/dist/api/impl/options.js +851 -0
  89. package/dist/api/impl/placement.d.ts +1 -0
  90. package/dist/api/impl/placement.js +138 -0
  91. package/dist/api/impl/render-context.d.ts +13 -0
  92. package/dist/api/impl/render-context.js +272 -0
  93. package/dist/api/impl/rows.d.ts +1 -0
  94. package/dist/api/impl/rows.js +46 -0
  95. package/dist/api/impl/selection.d.ts +1 -0
  96. package/dist/api/impl/selection.js +186 -0
  97. package/dist/api/impl/shared.d.ts +64 -0
  98. package/dist/api/impl/shared.js +178 -0
  99. package/dist/api/impl/validate-extension.d.ts +1 -0
  100. package/dist/api/impl/validate-extension.js +159 -0
  101. package/dist/api/layers.d.ts +130 -0
  102. package/dist/api/layers.js +3 -0
  103. package/dist/api/metadata.d.ts +18 -0
  104. package/dist/api/metadata.js +3 -0
  105. package/dist/api/model.d.ts +487 -0
  106. package/dist/api/model.js +47 -0
  107. package/dist/api/options.d.ts +466 -0
  108. package/dist/api/options.js +3 -0
  109. package/dist/api/selection.d.ts +94 -0
  110. package/dist/api/selection.js +3 -0
  111. package/dist/api/state.d.ts +155 -0
  112. package/dist/api/state.js +12 -0
  113. package/dist/{display → dataset}/chunk.d.ts +1 -1
  114. package/dist/{display → dataset}/chunk.js +4 -3
  115. package/dist/{display → dataset}/dataset.js +21 -21
  116. package/dist/dataset/interaction.d.ts +1 -0
  117. package/dist/{display → dataset}/interaction.js +18 -6
  118. package/dist/dataset/manager.d.ts +1 -0
  119. package/dist/dataset/provider.d.ts +1 -0
  120. package/dist/{display → dataset}/retained.d.ts +1 -1
  121. package/dist/{display → dataset}/retained.js +8 -7
  122. package/dist/dataset/source.d.ts +1 -0
  123. package/dist/{display → dataset}/source.js +17 -4
  124. package/dist/dataset/spatial.d.ts +1 -0
  125. package/dist/{display → dataset}/spatial.js +1 -1
  126. package/dist/dataset/style.d.ts +1 -0
  127. package/dist/{display → dataset}/style.js +1 -1
  128. package/dist/dataset/table-source.d.ts +1 -0
  129. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  130. package/dist/{display → dataset}/thinning.d.ts +0 -10
  131. package/dist/{display → dataset}/thinning.js +3 -2
  132. package/dist/dataset/triangulation.d.ts +1 -0
  133. package/dist/{display → dataset}/triangulation.js +0 -0
  134. package/dist/{display → dataset}/types.d.ts +84 -121
  135. package/dist/dataset/types.js +61 -0
  136. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  137. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  138. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  139. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  140. package/dist/dispatcher/hit-test/service.js +80 -16
  141. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  142. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  143. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  144. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  145. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  146. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  147. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  148. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  149. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  150. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  151. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  152. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  153. package/dist/dispatcher/input-router.js +154 -70
  154. package/dist/dispatcher/normalizer.js +25 -4
  155. package/dist/dispatcher/types.d.ts +6 -1
  156. package/dist/extension/feature-handler.d.ts +1 -182
  157. package/dist/extension/index.d.ts +4 -7
  158. package/dist/extension/renderers.d.ts +1 -208
  159. package/dist/geometry/angle.d.ts +0 -8
  160. package/dist/geometry/angle.js +0 -8
  161. package/dist/geometry/bbox.d.ts +4 -12
  162. package/dist/geometry/bbox.js +4 -12
  163. package/dist/geometry/boolean.d.ts +0 -51
  164. package/dist/geometry/boolean.js +0 -51
  165. package/dist/geometry/buffer.d.ts +0 -26
  166. package/dist/geometry/buffer.js +0 -26
  167. package/dist/geometry/circle.d.ts +0 -9
  168. package/dist/geometry/circle.js +0 -9
  169. package/dist/geometry/coords.d.ts +0 -16
  170. package/dist/geometry/coords.js +0 -16
  171. package/dist/geometry/distance.d.ts +0 -24
  172. package/dist/geometry/distance.js +0 -24
  173. package/dist/geometry/errors.d.ts +21 -36
  174. package/dist/geometry/errors.js +49 -29
  175. package/dist/geometry/geojson.d.ts +85 -0
  176. package/dist/geometry/geojson.js +173 -0
  177. package/dist/geometry/index.d.ts +38 -23
  178. package/dist/geometry/index.js +43 -31
  179. package/dist/geometry/measure.d.ts +0 -27
  180. package/dist/geometry/measure.js +0 -27
  181. package/dist/geometry/predicates.d.ts +0 -9
  182. package/dist/geometry/predicates.js +0 -9
  183. package/dist/geometry/public-bounds.d.ts +26 -0
  184. package/dist/geometry/public-bounds.js +30 -0
  185. package/dist/geometry/public-combine.d.ts +78 -0
  186. package/dist/geometry/public-combine.js +82 -0
  187. package/dist/geometry/public-create.d.ts +54 -0
  188. package/dist/geometry/public-create.js +70 -0
  189. package/dist/geometry/public-measure.d.ts +170 -0
  190. package/dist/geometry/public-measure.js +283 -0
  191. package/dist/geometry/public-predicates.d.ts +54 -0
  192. package/dist/geometry/public-predicates.js +144 -0
  193. package/dist/geometry/public-repair.d.ts +75 -0
  194. package/dist/geometry/public-repair.js +77 -0
  195. package/dist/geometry/simplify.d.ts +0 -7
  196. package/dist/geometry/simplify.js +0 -7
  197. package/dist/geometry/split.d.ts +0 -20
  198. package/dist/geometry/split.js +0 -20
  199. package/dist/geometry/units.d.ts +20 -12
  200. package/dist/geometry/units.js +20 -12
  201. package/dist/index.d.ts +66 -66
  202. package/dist/index.js +6 -18
  203. package/dist/messages.d.ts +7 -7
  204. package/dist/modes/draw/circle.js +83 -207
  205. package/dist/modes/draw/commit-layer.d.ts +5 -16
  206. package/dist/modes/draw/commit-layer.js +2 -13
  207. package/dist/modes/draw/freehand.js +108 -246
  208. package/dist/modes/draw/image.js +4 -2
  209. package/dist/modes/draw/index.d.ts +5 -5
  210. package/dist/modes/draw/index.js +5 -5
  211. package/dist/modes/draw/line.js +18 -354
  212. package/dist/modes/draw/point.js +29 -78
  213. package/dist/modes/draw/polygon.js +23 -368
  214. package/dist/modes/draw/trace-support.d.ts +43 -36
  215. package/dist/modes/draw/trace-support.js +95 -98
  216. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  217. package/dist/modes/draw/vertex-drawing.js +176 -0
  218. package/dist/modes/handler.d.ts +1 -285
  219. package/dist/modes/manager.d.ts +2 -2
  220. package/dist/modes/manager.js +3 -0
  221. package/dist/modes/select/box-selection.d.ts +3 -3
  222. package/dist/modes/select/box-selection.js +2 -1
  223. package/dist/modes/select/click-handler.d.ts +5 -5
  224. package/dist/modes/select/click-handler.js +22 -20
  225. package/dist/modes/select/cursor-handler.d.ts +2 -2
  226. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  227. package/dist/modes/select/drag/move.js +3 -3
  228. package/dist/modes/select/drag/operation.d.ts +3 -3
  229. package/dist/modes/select/drag/radius.js +5 -4
  230. package/dist/modes/select/drag/transform.d.ts +2 -2
  231. package/dist/modes/select/drag/transform.js +11 -5
  232. package/dist/modes/select/drag/vertex.d.ts +2 -2
  233. package/dist/modes/select/drag/vertex.js +13 -8
  234. package/dist/modes/select/drag-handler.js +44 -25
  235. package/dist/modes/select/mode.js +17 -17
  236. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  237. package/dist/modes/select/shortcut-handler.js +9 -7
  238. package/dist/operations/layer-operations.js +29 -168
  239. package/dist/operations/resize.d.ts +2 -2
  240. package/dist/operations/resize.js +5 -5
  241. package/dist/operations/rotate.js +5 -5
  242. package/dist/operations/selection-operations.d.ts +16 -1
  243. package/dist/operations/selection-operations.js +28 -13
  244. package/dist/operations/shared-vertex.js +4 -2
  245. package/dist/operations/trace-graph.d.ts +0 -18
  246. package/dist/operations/trace-graph.js +0 -18
  247. package/dist/operations/vertex.js +36 -35
  248. package/dist/shared/color.d.ts +1 -0
  249. package/dist/shared/color.js +245 -0
  250. package/dist/shared/config/constants.d.ts +1 -54
  251. package/dist/shared/config/constants.js +1 -58
  252. package/dist/shared/config/feature-style.d.ts +16 -13
  253. package/dist/shared/config/feature-style.js +9 -0
  254. package/dist/shared/config/rendering.d.ts +3 -3
  255. package/dist/shared/config/selection-highlight.d.ts +0 -15
  256. package/dist/shared/config/selection-highlight.js +4 -7
  257. package/dist/shared/config/selection.d.ts +2 -32
  258. package/dist/shared/config/selection.js +0 -18
  259. package/dist/shared/config/topology.d.ts +2 -2
  260. package/dist/shared/config/trace.d.ts +4 -4
  261. package/dist/shared/math/angle.d.ts +1 -1
  262. package/dist/shared/math/angle.js +1 -1
  263. package/dist/shared/math/circle.d.ts +1 -1
  264. package/dist/shared/math/circle.js +1 -1
  265. package/dist/shared/math/distance.d.ts +2 -1
  266. package/dist/shared/math/distance.js +3 -2
  267. package/dist/shared/math/index.d.ts +1 -1
  268. package/dist/shared/math/index.js +1 -1
  269. package/dist/shared/math/transform.d.ts +23 -0
  270. package/dist/shared/math/transform.js +47 -28
  271. package/dist/shared/properties.d.ts +18 -0
  272. package/dist/shared/properties.js +129 -0
  273. package/dist/shared/types/events.d.ts +15 -7
  274. package/dist/shared/types/model.d.ts +109 -159
  275. package/dist/shared/types/style.d.ts +1 -1
  276. package/dist/shared/utils/color.d.ts +2 -36
  277. package/dist/shared/utils/color.js +13 -70
  278. package/dist/shared/utils/coordinates.d.ts +30 -4
  279. package/dist/shared/utils/coordinates.js +56 -10
  280. package/dist/shared/utils/event-emitter.d.ts +1 -262
  281. package/dist/shared/utils/event-emitter.js +4 -3
  282. package/dist/shared/utils/feature-bbox.js +8 -7
  283. package/dist/shared/utils/feature-segments.js +5 -4
  284. package/dist/shared/utils/image.d.ts +0 -4
  285. package/dist/shared/utils/image.js +0 -6
  286. package/dist/shared/utils/name-generator.d.ts +14 -20
  287. package/dist/shared/utils/name-generator.js +20 -3
  288. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  289. package/dist/shared/utils/pixel-ratio.js +13 -4
  290. package/dist/shared/utils/property.d.ts +7 -50
  291. package/dist/shared/utils/property.js +22 -87
  292. package/dist/snapping/custom-targets.js +21 -4
  293. package/dist/snapping/indicator.js +20 -11
  294. package/dist/snapping/providers/display.d.ts +6 -1
  295. package/dist/snapping/providers/display.js +2 -1
  296. package/dist/snapping/providers/guide.d.ts +3 -43
  297. package/dist/snapping/providers/guide.js +1 -44
  298. package/dist/snapping/providers/intersection.js +1 -1
  299. package/dist/snapping/providers/store.js +3 -3
  300. package/dist/snapping/service.js +18 -7
  301. package/dist/snapping/types.d.ts +9 -35
  302. package/dist/store/draw-store.js +233 -142
  303. package/dist/store/local-visibility.d.ts +11 -6
  304. package/dist/store/local-visibility.js +38 -7
  305. package/dist/store/lock.d.ts +0 -6
  306. package/dist/store/lock.js +0 -6
  307. package/dist/store/memory/change-bus.d.ts +3 -3
  308. package/dist/store/memory/change-bus.js +12 -0
  309. package/dist/store/memory/file-store.d.ts +2 -2
  310. package/dist/store/memory/ui-state.d.ts +1 -51
  311. package/dist/store/memory/ui-state.js +122 -134
  312. package/dist/store/memory.d.ts +1 -8
  313. package/dist/store/memory.js +249 -45
  314. package/dist/store/ordering.d.ts +9 -0
  315. package/dist/store/ordering.js +17 -0
  316. package/dist/store/spatial/spatial-index.d.ts +1 -1
  317. package/dist/store/spatial/spatial-index.js +1 -1
  318. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  319. package/dist/store/spatial/store-spatial-index.js +9 -3
  320. package/dist/store/store.d.ts +66 -107
  321. package/dist/store/types.d.ts +1 -1
  322. package/dist/store/writable-layer.d.ts +1 -1
  323. package/dist/store/writable-layer.js +2 -2
  324. package/dist/table/builder.d.ts +83 -0
  325. package/dist/table/builder.js +381 -0
  326. package/dist/table/index.d.ts +37 -0
  327. package/dist/table/index.js +5 -0
  328. package/dist/table/packed-rtree.d.ts +1 -0
  329. package/dist/{display → table}/packed-rtree.js +1 -1
  330. package/dist/table/partition.d.ts +1 -0
  331. package/dist/{display → table}/partition.js +3 -3
  332. package/dist/table/prepare.d.ts +44 -0
  333. package/dist/table/prepare.js +136 -0
  334. package/dist/table/table.d.ts +1 -0
  335. package/dist/{display/columnar → table}/table.js +29 -25
  336. package/dist/{display/columnar → table}/types.d.ts +68 -72
  337. package/dist/table/types.js +3 -0
  338. package/dist/view/coordinator.js +4 -3
  339. package/dist/view/feature-companion.d.ts +13 -7
  340. package/dist/view/feature-companion.js +11 -3
  341. package/dist/view/globe-subdivision.js +3 -3
  342. package/dist/view/layer/attach.d.ts +12 -6
  343. package/dist/view/layer/attach.js +86 -10
  344. package/dist/view/layer/custom-layer.js +40 -11
  345. package/dist/view/layer/display-list.js +2 -1
  346. package/dist/view/layer/drape-planner.d.ts +2 -2
  347. package/dist/view/layer/frame-render.d.ts +3 -3
  348. package/dist/view/layer/frame-render.js +7 -2
  349. package/dist/view/layer/frame-state.d.ts +6 -6
  350. package/dist/view/layer/index.d.ts +2 -2
  351. package/dist/view/layer/index.js +1 -1
  352. package/dist/view/layer/render.d.ts +4 -4
  353. package/dist/view/layer/render.js +3 -8
  354. package/dist/view/layer/renderers.d.ts +2 -2
  355. package/dist/view/layer/renderers.js +1 -1
  356. package/dist/view/layer/slot-manager.d.ts +2 -2
  357. package/dist/view/layer/slot-manager.js +4 -4
  358. package/dist/view/layer/slots.d.ts +2 -2
  359. package/dist/view/layer/slots.js +1 -1
  360. package/dist/view/layer/store-retained-bbox.js +3 -2
  361. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  362. package/dist/view/layer/store-retained-classify.js +19 -7
  363. package/dist/view/layer/store-retained-collect.js +8 -7
  364. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  365. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  366. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  367. package/dist/view/layer/store-retained-immediate.js +3 -8
  368. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  369. package/dist/view/layer/store-retained.d.ts +2 -2
  370. package/dist/view/layer/store-retained.js +1 -1
  371. package/dist/view/renderers/batch-manager.js +8 -7
  372. package/dist/view/renderers/drawer.js +21 -15
  373. package/dist/view/renderers/image.js +13 -39
  374. package/dist/view/renderers/line/line-types.d.ts +3 -3
  375. package/dist/view/renderers/line/sdf-line.js +3 -1
  376. package/dist/view/renderers/point/billboard-depth.js +1 -1
  377. package/dist/view/renderers/point/point-instance.js +1 -1
  378. package/dist/view/renderers/point/point-shape.js +2 -2
  379. package/dist/view/renderers/point/point-style.js +48 -4
  380. package/dist/view/renderers/polygon/batch.js +1 -2
  381. package/dist/view/renderers/polygon/fill.js +3 -1
  382. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  383. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  384. package/dist/view/renderers/stroke.js +3 -1
  385. package/dist/view/shaders/helpers.d.ts +2 -42
  386. package/dist/view/shaders/helpers.js +0 -6
  387. package/dist/view/shaders/projection.d.ts +15 -7
  388. package/dist/view/shaders/projection.js +23 -6
  389. package/dist/view/shaders/quad.d.ts +16 -12
  390. package/dist/view/shaders/quad.js +34 -13
  391. package/dist/view/style-rule.d.ts +5 -42
  392. package/dist/view/style-rule.js +20 -44
  393. package/dist/view/terrain/binding.d.ts +1 -0
  394. package/dist/view/terrain/binding.js +29 -0
  395. package/dist/view/terrain/context.d.ts +3 -4
  396. package/dist/view/terrain/context.js +4 -5
  397. package/dist/view/terrain/drape/geometry.js +1 -1
  398. package/dist/view/terrain/drape/pass.d.ts +1 -1
  399. package/dist/view/terrain/drape/pass.js +8 -7
  400. package/dist/view/terrain/polygon.d.ts +9 -5
  401. package/dist/view/terrain/polygon.js +16 -2
  402. package/dist/view/terrain/state.d.ts +1 -1
  403. package/dist/view/terrain/state.js +1 -1
  404. package/dist/view/terrain/tessellation.d.ts +2 -2
  405. package/dist/view/terrain/tessellation.js +1 -1
  406. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  407. package/dist/view/ui/bounds.js +8 -12
  408. package/dist/view/ui/handle-test.js +2 -2
  409. package/dist/view/ui/handle-thinning.js +17 -17
  410. package/dist/view/ui/handles.js +21 -13
  411. package/dist/view/ui/helper.d.ts +1 -1
  412. package/dist/view/ui/helper.js +1 -1
  413. package/dist/view/ui/index.d.ts +1 -1
  414. package/dist/view/ui/selection-scope.js +4 -2
  415. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  416. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  417. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  418. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  419. package/dist/view/ui/selection-ui/index.js +1 -1
  420. package/dist/view/ui/selection-ui/renderer.js +15 -38
  421. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  422. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  423. package/dist/view/ui/selection-ui-drawer.js +63 -2
  424. package/dist/view/ui/tentative.js +1 -1
  425. package/dist/webgl/index.d.ts +65 -0
  426. package/dist/webgl/index.js +62 -0
  427. package/package.json +38 -15
  428. package/dist/api/api.d.ts +0 -1259
  429. package/dist/api/api.js +0 -86
  430. package/dist/api/context.d.ts +0 -173
  431. package/dist/api/display-api.js +0 -23
  432. package/dist/api/event-api.d.ts +0 -13
  433. package/dist/api/event-api.js +0 -17
  434. package/dist/api/extension-api.d.ts +0 -46
  435. package/dist/api/extension-api.js +0 -85
  436. package/dist/api/feature-api.d.ts +0 -11
  437. package/dist/api/feature-api.js +0 -101
  438. package/dist/api/geometry/apply.d.ts +0 -51
  439. package/dist/api/geometry/boolean.d.ts +0 -28
  440. package/dist/api/geometry/boolean.js +0 -65
  441. package/dist/api/geometry/types.d.ts +0 -31
  442. package/dist/api/geometry-operations.d.ts +0 -162
  443. package/dist/api/geometry-operations.js +0 -94
  444. package/dist/api/group-api.d.ts +0 -10
  445. package/dist/api/group-api.js +0 -78
  446. package/dist/api/import-export/constants.d.ts +0 -29
  447. package/dist/api/import-export/constants.js +0 -40
  448. package/dist/api/import-export/file-name.d.ts +0 -10
  449. package/dist/api/import-export/file-name.js +0 -20
  450. package/dist/api/import-export/geojson-export.d.ts +0 -19
  451. package/dist/api/import-export/image-import.d.ts +0 -12
  452. package/dist/api/import-export/image-import.js +0 -53
  453. package/dist/api/import-export/index.d.ts +0 -9
  454. package/dist/api/import-export/index.js +0 -107
  455. package/dist/api/import-export/native-format.d.ts +0 -15
  456. package/dist/api/import-export/style-validation.d.ts +0 -27
  457. package/dist/api/import-export/style-validation.js +0 -49
  458. package/dist/api/import-export/types.d.ts +0 -26
  459. package/dist/api/index.d.ts +0 -15
  460. package/dist/api/index.js +0 -3
  461. package/dist/api/input-api.d.ts +0 -158
  462. package/dist/api/input-api.js +0 -144
  463. package/dist/api/instance-api.d.ts +0 -38
  464. package/dist/api/instance-api.js +0 -136
  465. package/dist/api/layer-api.d.ts +0 -12
  466. package/dist/api/layer-api.js +0 -62
  467. package/dist/api/selection-api.d.ts +0 -7
  468. package/dist/api/selection-api.js +0 -78
  469. package/dist/api/snapping-api.d.ts +0 -125
  470. package/dist/api/snapping-api.js +0 -50
  471. package/dist/api/topology-api.d.ts +0 -30
  472. package/dist/api/topology-api.js +0 -16
  473. package/dist/api/tracing-api.d.ts +0 -31
  474. package/dist/api/tracing-api.js +0 -16
  475. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  476. package/dist/dispatcher/hit-test/index.js +0 -9
  477. package/dist/dispatcher/index.d.ts +0 -15
  478. package/dist/dispatcher/index.js +0 -3
  479. package/dist/display/columnar/index.d.ts +0 -12
  480. package/dist/display/columnar/index.js +0 -13
  481. package/dist/display/columnar/prepare.d.ts +0 -42
  482. package/dist/display/columnar/prepare.js +0 -116
  483. package/dist/display/index.d.ts +0 -13
  484. package/dist/display/types.js +0 -43
  485. package/dist/maplibre-gl-draw.d.ts +0 -47
  486. package/dist/modes/cursor.js +0 -72
  487. package/dist/modes/index.d.ts +0 -7
  488. package/dist/operations/index.d.ts +0 -9
  489. package/dist/operations/index.js +0 -3
  490. package/dist/plugins/index.d.ts +0 -10
  491. package/dist/plugins/mutation-hooks.d.ts +0 -28
  492. package/dist/plugins/mutation-hooks.js +0 -84
  493. package/dist/plugins/plugin-context.js +0 -367
  494. package/dist/plugins/plugin-manager.d.ts +0 -103
  495. package/dist/plugins/plugin-manager.js +0 -316
  496. package/dist/plugins/plugin.d.ts +0 -529
  497. package/dist/shared/config/index.d.ts +0 -17
  498. package/dist/shared/config/index.js +0 -8
  499. package/dist/shared/utils/index.d.ts +0 -15
  500. package/dist/shared/utils/index.js +0 -24
  501. package/dist/snapping/index.d.ts +0 -14
  502. package/dist/snapping/index.js +0 -4
  503. package/dist/store/change-merger.js +0 -102
  504. package/dist/store/event-bridge.js +0 -161
  505. package/dist/store/index.d.ts +0 -12
  506. package/dist/store/index.js +0 -4
  507. package/dist/view/index.d.ts +0 -47
  508. package/dist/view/index.js +0 -20
  509. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  510. /package/dist/api/{import-export/types.js → document.js} +0 -0
  511. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  512. /package/dist/{display/index.js → api/events.js} +0 -0
  513. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  514. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  515. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  516. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  517. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  518. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  519. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  520. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  521. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  522. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  523. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  524. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  525. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  526. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  527. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  528. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  529. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  532. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  533. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  534. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  535. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  536. /package/dist/{display → dataset}/chunk-set.js +0 -0
  537. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  538. /package/dist/{display → dataset}/manager.js +0 -0
  539. /package/dist/{display → dataset}/provider.js +0 -0
  540. /package/dist/{display → dataset}/selection.d.ts +0 -0
  541. /package/dist/{display → dataset}/selection.js +0 -0
@@ -20,6 +20,7 @@
20
20
  * "the rule is not taking effect" apart from "there is no value".
21
21
  */
22
22
  import { MESSAGES_EN, resolveMessages } from '../messages.js';
23
+ import { toHexColor } from '../shared/color.js';
23
24
  import { interpolateHexColor } from '../shared/utils/color.js';
24
25
  /** The name of the FeatureStyle color property corresponding to each channel */
25
26
  const CHANNEL_COLOR_PROPERTY = {
@@ -95,31 +96,16 @@ function graduatedIndex(breaks, value) {
95
96
  * `categorical` matches strings, numbers and booleans by `String(value)`; `graduated` and
96
97
  * `continuous` take finite numbers only (a numeric string gives `other`). `continuous`
97
98
  * clamps values outside `min`..`max` and returns the first ramp color when `max <= min`. It
98
- * is a pure function.
99
+ * is a pure function. The colors of the rule may be any CSS color; the result is normalized
100
+ * to `#rrggbb`.
99
101
  *
100
102
  * @param rule The style rule
101
103
  * @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
- * ```
104
+ * @returns The color in `#rrggbb` form
119
105
  */
120
106
  export function evaluateStyleRule(rule, properties) {
121
107
  if (rule.kind === 'single') {
122
- return rule.color;
108
+ return toHexColor(rule.color);
123
109
  }
124
110
  return evaluateStyleRuleValue(rule, properties?.[rule.property]);
125
111
  }
@@ -132,6 +118,10 @@ export function evaluateStyleRule(rule, properties) {
132
118
  * @internal
133
119
  */
134
120
  export function evaluateStyleRuleValue(rule, value) {
121
+ return toHexColor(ruleColorOf(rule, value));
122
+ }
123
+ /** The color of the rule for a value, as the rule writes it */
124
+ function ruleColorOf(rule, value) {
135
125
  if (rule.kind === 'single') {
136
126
  return rule.color;
137
127
  }
@@ -150,12 +140,16 @@ export function evaluateStyleRuleValue(rule, value) {
150
140
  // An invalid rule whose colors count falls short of breaks + 1 falls back to other
151
141
  return color ?? rule.other;
152
142
  }
153
- // continuous: linearly interpolates the 2 colors of the ramp over min..max
154
- // (out-of-range values are clamped)
143
+ // continuous: linearly interpolates the 2 colors of the ramp over min..max in OKLab
144
+ // (out-of-range values are clamped; the end points are the colors of the ramp)
155
145
  const [from, to] = rule.ramp;
156
146
  if (!(rule.max > rule.min))
157
147
  return from;
158
148
  const t = Math.min(1, Math.max(0, (numeric - rule.min) / (rule.max - rule.min)));
149
+ if (t === 0)
150
+ return from;
151
+ if (t === 1)
152
+ return to;
159
153
  return interpolateHexColor(from, to, t);
160
154
  }
161
155
  /**
@@ -241,36 +235,18 @@ function graduatedLabel(breaks, index, messages) {
241
235
  * `legendOther` is appended at the end
242
236
  *
243
237
  * Numbers are turned into strings with `String()`. Locale formatting is up to the caller.
238
+ * The colors are normalized to `#rrggbb`, as {@link evaluateStyleRule} returns them.
244
239
  *
245
240
  * @param rule The style rule
246
241
  * @param messages The entries of the messages table to use (default: `MESSAGES_EN`;
247
242
  * missing entries fall back to it)
248
243
  * @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
244
  */
273
245
  export function deriveLegend(rule, messages) {
246
+ return legendOf(rule, messages).map(({ label, color }) => ({ label, color: toHexColor(color) }));
247
+ }
248
+ /** The legend rows with the colors as the rule writes them */
249
+ function legendOf(rule, messages) {
274
250
  const table = messages ? resolveMessages(messages) : MESSAGES_EN;
275
251
  if (rule.kind === 'single') {
276
252
  return [{ label: table.legendAll, color: rule.color }];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /** The terrain state behind each render context and each set of anchors */
4
+ const terrainByHandle = new WeakMap();
5
+ /**
6
+ * Binds a render context or a set of anchors to the terrain state it stands for
7
+ *
8
+ * @internal
9
+ */
10
+ export function bindTerrainState(handle, terrain) {
11
+ terrainByHandle.set(handle, terrain);
12
+ }
13
+ /**
14
+ * The terrain state behind a render context or its `terrain`
15
+ *
16
+ * @returns The state, or `null` for `null` and for an object the engine did not hand out
17
+ * @internal
18
+ */
19
+ export function terrainStateOf(source) {
20
+ if (!source)
21
+ return null;
22
+ return terrainByHandle.get(source) ?? terrainByHandle.get(renderTerrainOf(source)) ?? null;
23
+ }
24
+ /** The `terrain` of a render context, or the object itself */
25
+ function renderTerrainOf(source) {
26
+ return 'terrain' in source && typeof source.terrain === 'object' && source.terrain !== null
27
+ ? source.terrain
28
+ : source;
29
+ }
@@ -117,10 +117,9 @@ export declare const INACTIVE_ANCHOR_FRAME: AnchorFrame;
117
117
  /**
118
118
  * The terrain state of one draw instance.
119
119
  *
120
- * Treat it as an opaque handle: a custom renderer receives it as
121
- * `CustomRendererDrawContext.terrain` and passes it to the renderers and to the terrain
122
- * functions (such as {@link anchorElevationMeters} and {@link drawQuadSurfaceOnTerrain}).
123
- * Constructing one gives a state with no terrain.
120
+ * It stays inside the engine: the renderers of a CustomLayer receive it at construction, and
121
+ * the public building blocks of the second entry reach it through the render context an
122
+ * extension receives (`terrain/binding.ts`). Constructing one gives a state with no terrain.
124
123
  */
125
124
  export declare class TerrainContext {
126
125
  /** This frame's terrain state (read by the shaders' projection uniforms) */
@@ -22,7 +22,7 @@
22
22
  * module-level "current" context: every reader (state.ts / anchor.ts / occlusion.ts /
23
23
  * polygon.ts) takes the context explicitly. The renderers of a CustomLayer receive their
24
24
  * instance's context at construction, extension renderers receive it in the draw context
25
- * (`CustomRendererDrawContext.terrain`), hit testing uses the anchor projection bound per map
25
+ * (`FrameDrawContext.terrain`), hit testing uses the anchor projection bound per map
26
26
  * (`installAnchorProjector`), and plugins use the projection bound to their instance
27
27
  * (`PluginContext.projectAnchor`). A read from outside rendering therefore always sees its own
28
28
  * instance, never "the instance drawn last".
@@ -75,10 +75,9 @@ export const INACTIVE_ANCHOR_FRAME = {
75
75
  /**
76
76
  * The terrain state of one draw instance.
77
77
  *
78
- * Treat it as an opaque handle: a custom renderer receives it as
79
- * `CustomRendererDrawContext.terrain` and passes it to the renderers and to the terrain
80
- * functions (such as {@link anchorElevationMeters} and {@link drawQuadSurfaceOnTerrain}).
81
- * Constructing one gives a state with no terrain.
78
+ * It stays inside the engine: the renderers of a CustomLayer receive it at construction, and
79
+ * the public building blocks of the second entry reach it through the render context an
80
+ * extension receives (`terrain/binding.ts`). Constructing one gives a state with no terrain.
82
81
  */
83
82
  export class TerrainContext {
84
83
  constructor() {
@@ -16,7 +16,7 @@ export function drapeMercatorY(lat) {
16
16
  *
17
17
  * The key is decided by the caller. For a feature in the Store the instance is replaced on
18
18
  * every edit, so the feature itself is the key; for a dataset the replacement
19
- * happens per `setFeatures` and the coordinate arrays are not reused, so the coordinate array
19
+ * happens per `setRows` and the coordinate arrays are not reused, so the coordinate array
20
20
  * is the key (when applying a style rule rebuilds only the feature instances, the same
21
21
  * coordinate arrays remain, so merely changing a color does not require converting a million
22
22
  * vertices again).
@@ -71,7 +71,7 @@ export declare function drapeLayerSource(layerIndex: number, datasetCount: numbe
71
71
  /**
72
72
  * The view of a dataset restricted to the part the drape needs
73
73
  *
74
- * The implementation in `display/dataset.ts` satisfies this shape. To keep the type
74
+ * The implementation in `dataset/dataset.ts` satisfies this shape. To keep the type
75
75
  * dependency one-directional, only the structure is declared here.
76
76
  */
77
77
  export interface DrapeDatasetSource {
@@ -16,6 +16,7 @@
16
16
  * When it does not hold, the caller drops to the previous vertex displacement path (a
17
17
  * two-stage arrangement). The condition for dropping is decided here by `canDrape`.
18
18
  */
19
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
19
20
  import { getCreatedZoom } from '../../../shared/utils/property.js';
20
21
  import { getDisplayFeatures, isLocallyHidden } from '../../../store/local-visibility.js';
21
22
  import { layerDrawFactors } from '../../renderers/draw-factors.js';
@@ -229,7 +230,7 @@ function collectStoreFeature(context, feature, layer, source, bakedOpacity) {
229
230
  *
230
231
  * So that the retained batch side does not draw the same features that were put on, the caller
231
232
  * tells the dataset "the polygons and lines are drawn by the drape"
232
- * (`drapedDatasets`). The test here and `collectFeature` in `display/retained.ts` form a
233
+ * (`drapedDatasets`). The test here and `collectFeature` in `dataset/retained.ts` form a
233
234
  * pair, so the condition must never be changed on only one side.
234
235
  */
235
236
  function collectDataset(context, dataset, source) {
@@ -252,7 +253,7 @@ function collectDataset(context, dataset, source) {
252
253
  if (rings.length === 0)
253
254
  continue;
254
255
  const width = widthOf(feature, strokeStyle.width, context.pixelRatio);
255
- pushElement(context, feature.coordinates, 0, rings, {
256
+ pushElement(context, coordinatesOf(feature), 0, rings, {
256
257
  fill: fillColor,
257
258
  stroke: [
258
259
  strokeStyle.color[0],
@@ -281,7 +282,7 @@ function collectDataset(context, dataset, source) {
281
282
  if (paths.length === 0)
282
283
  continue;
283
284
  const width = widthOf(feature, strokeStyle.width, context.pixelRatio);
284
- pushElement(context, feature.coordinates, 1, paths, {
285
+ pushElement(context, coordinatesOf(feature), 1, paths, {
285
286
  fill: [0, 0, 0, 0],
286
287
  stroke: [
287
288
  strokeStyle.color[0],
@@ -313,14 +314,14 @@ function widthOf(feature, width, pixelRatio) {
313
314
  /** The rings of a polygon (with the closing point dropped) */
314
315
  function polygonRings(feature) {
315
316
  return feature.type === 'Polygon'
316
- ? openRings(feature.coordinates)
317
- : feature.coordinates.flatMap((part) => openRings(part));
317
+ ? openRings(coordinatesOf(feature))
318
+ : coordinatesOf(feature).flatMap((part) => openRings(part));
318
319
  }
319
320
  /** The paths of a line */
320
321
  function linePaths(feature) {
321
322
  const paths = feature.type === 'LineString' || feature.type === 'Freehand'
322
- ? [feature.coordinates]
323
- : feature.coordinates;
323
+ ? [coordinatesOf(feature)]
324
+ : coordinatesOf(feature);
324
325
  return paths.filter((path) => path.length >= 2);
325
326
  }
326
327
  /** Pushes an element */
@@ -2,19 +2,23 @@
2
2
  * The injection point for terrain subdivision of polygons
3
3
  *
4
4
  * Called from the polygon renderers (polygon/sdf-polygon.ts and polygon/batch.ts). When the
5
- * terrain is disabled, `getTerrainTessellationStep(context)` returns null and the caller does
5
+ * terrain is disabled, `terrainStepOf(context)` returns null and the caller does
6
6
  * nothing. Rendering without terrain therefore does not change by a single byte.
7
7
  */
8
+ import type { TerrainAnchors } from '../../api/extension/context.js';
9
+ import type { RenderContext } from '../../api/extension/render.js';
8
10
  import type { Coordinate } from '../../store/types.js';
9
11
  import type { TerrainContext } from './context.js';
10
12
  import { type MercatorRect, type TessellationStep } from './tessellation.js';
11
13
  /**
12
- * Returns the subdivision step of the terrain mesh for the current frame.
14
+ * Returns the subdivision step of the terrain mesh for the current frame, to cut a shape so
15
+ * that it follows the terrain (pass it to `densifyPath`).
13
16
  *
14
- * @param context The terrain state of the draw instance
15
- * @returns The step, or `null` when the terrain is disabled
17
+ * @param terrain - The render context of the draw call, or its `terrain`
18
+ * @returns The step, or `null` when the terrain is disabled (or the object was not handed out
19
+ * by the engine)
16
20
  */
17
- export declare function getTerrainTessellationStep(context: TerrainContext): TessellationStep | null;
21
+ export declare function terrainTessellationStep(terrain: RenderContext | TerrainAnchors): TessellationStep | null;
18
22
  /**
19
23
  * Decides the effective step for a single feature
20
24
  *
@@ -1,16 +1,30 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { terrainStateOf } from './binding.js';
3
4
  import { TERRAIN_MAX_BATCH_SUBDIVISION_CELLS, TERRAIN_MAX_COARSEN_STEPS, TERRAIN_MAX_SUBDIVISION_POINTS, TERRAIN_MAX_TILED_SUBDIVISION_POINTS, } from './metrics.js';
4
5
  import { getTerrainRenderState } from './state.js';
5
6
  import { cellsInRegion, densifyRings, mercatorX, mercatorY, rectsIntersect, subdivideTriangles, } from './tessellation.js';
6
7
  import { tilingSignature } from './tiling.js';
7
8
  /**
8
- * Returns the subdivision step of the terrain mesh for the current frame.
9
+ * Returns the subdivision step of the terrain mesh for the current frame, to cut a shape so
10
+ * that it follows the terrain (pass it to `densifyPath`).
11
+ *
12
+ * @param terrain - The render context of the draw call, or its `terrain`
13
+ * @returns The step, or `null` when the terrain is disabled (or the object was not handed out
14
+ * by the engine)
15
+ */
16
+ export function terrainTessellationStep(terrain) {
17
+ const state = terrainStateOf(terrain);
18
+ return state ? terrainStepOf(state) : null;
19
+ }
20
+ /**
21
+ * {@link terrainTessellationStep} over the terrain state of an instance
9
22
  *
10
23
  * @param context The terrain state of the draw instance
11
24
  * @returns The step, or `null` when the terrain is disabled
25
+ * @internal
12
26
  */
13
- export function getTerrainTessellationStep(context) {
27
+ export function terrainStepOf(context) {
14
28
  const terrain = getTerrainRenderState(context);
15
29
  if (!terrain.active || !(terrain.stepGrid > 0))
16
30
  return null;
@@ -6,7 +6,7 @@
6
6
  * (`context.ts`; how a shared global broke with several instances is written there). Every
7
7
  * accessor takes that context explicitly: the renderers of a CustomLayer receive their
8
8
  * instance's context at construction, and extension renderers receive it in the draw context
9
- * (`CustomRendererDrawContext.terrain`). Nothing here reads "the instance drawn last".
9
+ * (`FrameDrawContext.terrain`). Nothing here reads "the instance drawn last".
10
10
  *
11
11
  * When the terrain is disabled, `INACTIVE_TERRAIN_STATE` is held and the shader's
12
12
  * `u_terrain_on` becomes 0. The vertex computation when it is 0 is exactly identical to
@@ -8,7 +8,7 @@
8
8
  * (`context.ts`; how a shared global broke with several instances is written there). Every
9
9
  * accessor takes that context explicitly: the renderers of a CustomLayer receive their
10
10
  * instance's context at construction, and extension renderers receive it in the draw context
11
- * (`CustomRendererDrawContext.terrain`). Nothing here reads "the instance drawn last".
11
+ * (`FrameDrawContext.terrain`). Nothing here reads "the instance drawn last".
12
12
  *
13
13
  * When the terrain is disabled, `INACTIVE_TERRAIN_STATE` is held and the shader's
14
14
  * `u_terrain_on` becomes 0. The vertex computation when it is 0 is exactly identical to
@@ -47,7 +47,7 @@ export interface MercatorRect {
47
47
  }
48
48
  /**
49
49
  * How finely a line or a fill is subdivided to follow the terrain mesh, as
50
- * {@link getTerrainTessellationStep} returns it.
50
+ * {@link terrainTessellationStep} returns it.
51
51
  */
52
52
  export interface TessellationStep {
53
53
  /**
@@ -193,7 +193,7 @@ export declare function latFromMercatorY(y: number): number;
193
193
  * on the original line).
194
194
  *
195
195
  * @param path The vertices `[lng, lat]` in degrees
196
- * @param step The step from {@link getTerrainTessellationStep}
196
+ * @param step The step from {@link terrainTessellationStep}
197
197
  * @returns The densified vertices. The input itself for fewer than 2 positions or a step of
198
198
  * 0; insertion stops when `step.maxPoints` is reached
199
199
  */
@@ -91,7 +91,7 @@ export function latFromMercatorY(y) {
91
91
  * on the original line).
92
92
  *
93
93
  * @param path The vertices `[lng, lat]` in degrees
94
- * @param step The step from {@link getTerrainTessellationStep}
94
+ * @param step The step from {@link terrainTessellationStep}
95
95
  * @returns The densified vertices. The input itself for fewer than 2 positions or a step of
96
96
  * 0; insertion stops when `step.maxPoints` is reached
97
97
  */
@@ -2,10 +2,10 @@
2
2
  * Extension point for the auxiliary handles
3
3
  *
4
4
  * A general-purpose hook for showing and grabbing handles on the selected feature that are
5
- * "neither a vertex nor a resize handle". All core holds is the hit testing and the drag
6
- * delegation; drawing the handles is the responsibility of the registering side (the plugin
7
- * of an extension implementation). core knows nothing at all about the meaning of a handle
8
- * (it only carries the position and the identifier).
5
+ * "neither a vertex nor a resize handle". Core draws them with the look of the vertex handles
6
+ * (the selection UI), hit tests them at the same size and delegates their drags. core knows
7
+ * nothing at all about the meaning of a handle (it only carries the position and the
8
+ * identifier).
9
9
  *
10
10
  * There are two ways to emit handles: those bound to the selected feature (getHandles) and
11
11
  * those that can always be emitted regardless of the selection (getGlobalHandles). The
@@ -72,31 +72,8 @@ export interface AuxiliaryHandleHit {
72
72
  * A source of handles on the selected feature that are neither vertices nor resize handles,
73
73
  * and the receiver of their drags.
74
74
  *
75
- * Register one with `draw.registerAuxiliaryHandleProvider(provider)`. The library hit tests
76
- * the handles and delegates their drags; drawing them is the provider's job (with an overlay
77
- * renderer, for example).
78
- *
79
- * @example
80
- * ```ts
81
- * import type { AuxiliaryHandleProvider } from '@sakuzu/maplibre-gl-draw';
82
- *
83
- * // A handle 20 px above the first vertex of the selected line, which logs its drag
84
- * const labelHandle: AuxiliaryHandleProvider = {
85
- * id: 'label-handle',
86
- * getHandles(feature, ctx) {
87
- * if (feature.type !== 'LineString') return [];
88
- * const first = (feature.coordinates as [number, number][])[0];
89
- * const p = ctx.project(first);
90
- * const { lng, lat } = ctx.unproject({ x: p.x, y: p.y - 20 });
91
- * return [{ id: 'label', position: [lng, lat], cursor: 'move' }];
92
- * },
93
- * onHandleDragStart: () => true,
94
- * onHandleDragMove: (event) => console.log(event.lngLat),
95
- * onHandleDragEnd: () => {},
96
- * };
97
- *
98
- * const unregister = draw.registerAuxiliaryHandleProvider(labelHandle);
99
- * ```
75
+ * A `HandleProvider` of `draw.extensions.handleProviders` is installed as one. The engine draws
76
+ * the handles with the look of the vertex handles, hit tests them and delegates their drags.
100
77
  */
101
78
  export interface AuxiliaryHandleProvider {
102
79
  /** Identifier unique within the registry (re-registering with the same id overwrites) */
@@ -1,7 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
3
  import { applyMarginToBoundingBox } from '../../shared/math/index.js';
4
- import { computeBoundingBox, hasZeroArea, resolvePointFrameExtentWith, } from './selection-ui/index.js';
4
+ import { computeBoundingBox, hasZeroArea, resolvePointFrameCornersWith, } from './selection-ui/index.js';
5
5
  /**
6
6
  * Compute the bounding box with a margin of a feature in geographic coordinates
7
7
  *
@@ -82,7 +82,8 @@ export function computeCombinedGeoBoundingBox(features, transform, config, exten
82
82
  /**
83
83
  * Compute the bounding box with a margin of a single-coordinate feature in geographic coordinates
84
84
  *
85
- * The extent of the frame of a point (registrable per type; 12px square when unregistered)
85
+ * The extent of the frame of a point (registrable per type; the marker of a built-in point, or
86
+ * a 12px square when unregistered)
86
87
  * plus the margin is computed in screen coordinates and converted into geographic ones.
87
88
  * The coordinate received is the center of the bbox (since features other than Point can
88
89
  * also be zero-area, e.g. a MultiPoint with a single point; coordinates must not be
@@ -90,17 +91,12 @@ export function computeCombinedGeoBoundingBox(features, transform, config, exten
90
91
  */
91
92
  function computeSingleCoordGeoBoundingBox(feature, coord, transform, margin, extensions) {
92
93
  const center = transform.project(coord);
93
- // The half width and half height of the frame of the point + the margin
94
- const extent = extensions
95
- ? extensions.resolvePointFrameExtent(feature)
96
- : resolvePointFrameExtentWith(undefined, feature);
97
- const halfWidth = extent.halfWidth + margin;
98
- const halfHeight = extent.halfHeight + margin;
94
+ // The corners of the frame of the point (its outline, or its extent) + the margin
95
+ const corners = extensions
96
+ ? extensions.resolvePointFrameCorners(feature, center, margin)
97
+ : resolvePointFrameCornersWith(undefined, undefined, feature, center, margin);
99
98
  // Convert the 4 corners in screen coordinates into geographic coordinates
100
- const topLeft = transform.unproject({ x: center.x - halfWidth, y: center.y - halfHeight });
101
- const topRight = transform.unproject({ x: center.x + halfWidth, y: center.y - halfHeight });
102
- const bottomRight = transform.unproject({ x: center.x + halfWidth, y: center.y + halfHeight });
103
- const bottomLeft = transform.unproject({ x: center.x - halfWidth, y: center.y + halfHeight });
99
+ const [topLeft, topRight, bottomRight, bottomLeft] = corners.map((corner) => transform.unproject(corner));
104
100
  return {
105
101
  topLeft: [topLeft.lng, topLeft.lat],
106
102
  topRight: [topRight.lng, topRight.lat],
@@ -216,8 +216,8 @@ function hitTestCircleRadiusHandle(feature, config, params) {
216
216
  *
217
217
  * Enumerating the handles is left to the callback (the aggregation of the providers), while
218
218
  * the test is done with the same screen-px rectangle as the existing handles. To keep the
219
- * grab feel uniform, the test size is the same as for the vertex handles (rendering is the
220
- * provider's responsibility, so core knows only the positions).
219
+ * grab feel uniform, the test size is the same as for the vertex handles, which is also the
220
+ * size the selection UI draws them at.
221
221
  */
222
222
  function hitTestAuxiliaryHandles(feature, config, zoom, params, getAuxiliaryHandles) {
223
223
  const context = {
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { HANDLE_THINNING_THRESHOLD, MIDPOINT_MIN_EDGE_PX, MIN_HANDLE_SPACING_PX, THINNING_REFRESH_DEBOUNCE_MS, } from '../../shared/config/selection.js';
16
16
  import { mercatorMidpoint } from '../../shared/math/globe-subdivision.js';
17
- import { supportsVertexEditing } from '../../shared/utils/coordinates.js';
17
+ import { coordinatesOf, supportsVertexEditing } from '../../shared/utils/coordinates.js';
18
18
  import { isSameVertexRef } from '../../shared/utils/vertex-ref.js';
19
19
  /**
20
20
  * Decomposes a feature into scan units
@@ -26,15 +26,15 @@ import { isSameVertexRef } from '../../shared/utils/vertex-ref.js';
26
26
  function collectHandleRuns(feature) {
27
27
  const runs = [];
28
28
  if (feature.type === 'LineString') {
29
- pushLineRun(runs, feature.coordinates);
29
+ pushLineRun(runs, coordinatesOf(feature));
30
30
  }
31
31
  else if (feature.type === 'Polygon') {
32
- pushPolygonRuns(runs, feature.coordinates);
32
+ pushPolygonRuns(runs, coordinatesOf(feature));
33
33
  }
34
34
  else if (feature.type === 'MultiPoint') {
35
35
  // Splitting a MultiPoint per part would adopt every point and defeat the thinning, so
36
36
  // all parts are scanned as a single sequence
37
- const points = feature.coordinates;
37
+ const points = coordinatesOf(feature);
38
38
  runs.push({
39
39
  coords: points,
40
40
  vertexCount: points.length,
@@ -44,13 +44,13 @@ function collectHandleRuns(feature) {
44
44
  });
45
45
  }
46
46
  else if (feature.type === 'MultiLineString') {
47
- const parts = feature.coordinates;
47
+ const parts = coordinatesOf(feature);
48
48
  for (let part = 0; part < parts.length; part++) {
49
49
  pushLineRun(runs, parts[part], part);
50
50
  }
51
51
  }
52
52
  else if (feature.type === 'MultiPolygon') {
53
- const parts = feature.coordinates;
53
+ const parts = coordinatesOf(feature);
54
54
  for (let part = 0; part < parts.length; part++) {
55
55
  pushPolygonRuns(runs, parts[part], part);
56
56
  }
@@ -112,25 +112,25 @@ export function countPotentialHandles(feature) {
112
112
  if (feature.type === 'Point')
113
113
  return 1;
114
114
  if (feature.type === 'LineString') {
115
- return countLineHandles(feature.coordinates.length);
115
+ return countLineHandles(coordinatesOf(feature).length);
116
116
  }
117
117
  if (feature.type === 'Polygon') {
118
- return countPolygonHandles(feature.coordinates);
118
+ return countPolygonHandles(coordinatesOf(feature));
119
119
  }
120
120
  if (feature.type === 'MultiPoint') {
121
121
  // Each coordinate is the vertex handle of one part. There are no edges
122
- return feature.coordinates.length;
122
+ return coordinatesOf(feature).length;
123
123
  }
124
124
  if (feature.type === 'MultiLineString') {
125
125
  let total = 0;
126
- for (const part of feature.coordinates) {
126
+ for (const part of coordinatesOf(feature)) {
127
127
  total += countLineHandles(part.length);
128
128
  }
129
129
  return total;
130
130
  }
131
131
  if (feature.type === 'MultiPolygon') {
132
132
  let total = 0;
133
- for (const part of feature.coordinates) {
133
+ for (const part of coordinatesOf(feature)) {
134
134
  total += countPolygonHandles(part);
135
135
  }
136
136
  return total;
@@ -254,23 +254,23 @@ export function includeRequiredVertexRefs(set, required) {
254
254
  function getRefCoords(feature, ref) {
255
255
  const part = ref.part ?? 0;
256
256
  if (feature.type === 'Point') {
257
- return [feature.coordinates];
257
+ return [coordinatesOf(feature)];
258
258
  }
259
259
  if (feature.type === 'LineString') {
260
- return feature.coordinates;
260
+ return coordinatesOf(feature);
261
261
  }
262
262
  if (feature.type === 'Polygon') {
263
- return feature.coordinates[ref.ring] ?? null;
263
+ return coordinatesOf(feature)[ref.ring] ?? null;
264
264
  }
265
265
  if (feature.type === 'MultiPoint') {
266
- const point = feature.coordinates[part];
266
+ const point = coordinatesOf(feature)[part];
267
267
  return point ? [point] : null;
268
268
  }
269
269
  if (feature.type === 'MultiLineString') {
270
- return feature.coordinates[part] ?? null;
270
+ return coordinatesOf(feature)[part] ?? null;
271
271
  }
272
272
  if (feature.type === 'MultiPolygon') {
273
- return feature.coordinates[part]?.[ref.ring] ?? null;
273
+ return coordinatesOf(feature)[part]?.[ref.ring] ?? null;
274
274
  }
275
275
  return null;
276
276
  }