@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
@@ -1,8 +1,9 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
- import { destinationPoint } from '../../geometry/index.js';
3
+ import { destinationPoint } from '../../geometry/distance.js';
4
4
  import { mercatorMidpoint } from '../../shared/math/globe-subdivision.js';
5
5
  import { applyMarginToBoundingBox, clampLatitude } from '../../shared/math/index.js';
6
+ import { coordinatesOf } from '../../shared/utils/coordinates.js';
6
7
  import { getCircleRadius, getRadiusHandleAngle } from '../../shared/utils/property.js';
7
8
  import { hasVertexRef, isSameVertexRef } from '../../shared/utils/vertex-ref.js';
8
9
  import { includeRequiredVertexRefs, resolveMidpointCoordinate, resolveVertexCoordinate, } from './handle-thinning.js';
@@ -164,18 +165,18 @@ export function computeVertexHandles(feature, visibleSet) {
164
165
  const handles = [];
165
166
  if (feature.type === 'Point') {
166
167
  // A Point is a single vertex
167
- const coord = feature.coordinates;
168
+ const coord = coordinatesOf(feature);
168
169
  handles.push({ type: 'vertex', position: coord, vertexRef: { ring: 0, index: 0 } });
169
170
  }
170
171
  else if (feature.type === 'LineString') {
171
- collectLineVertexHandles(feature.coordinates, handles);
172
+ collectLineVertexHandles(coordinatesOf(feature), handles);
172
173
  }
173
174
  else if (feature.type === 'Polygon') {
174
- collectPolygonVertexHandles(feature.coordinates, handles);
175
+ collectPolygonVertexHandles(coordinatesOf(feature), handles);
175
176
  }
176
177
  else if (feature.type === 'MultiPoint') {
177
178
  // Each coordinate is one part. ring / index are always 0
178
- const points = feature.coordinates;
179
+ const points = coordinatesOf(feature);
179
180
  for (let part = 0; part < points.length; part++) {
180
181
  handles.push({
181
182
  type: 'vertex',
@@ -185,13 +186,13 @@ export function computeVertexHandles(feature, visibleSet) {
185
186
  }
186
187
  }
187
188
  else if (feature.type === 'MultiLineString') {
188
- const parts = feature.coordinates;
189
+ const parts = coordinatesOf(feature);
189
190
  for (let part = 0; part < parts.length; part++) {
190
191
  collectLineVertexHandles(parts[part], handles, part);
191
192
  }
192
193
  }
193
194
  else if (feature.type === 'MultiPolygon') {
194
- const parts = feature.coordinates;
195
+ const parts = coordinatesOf(feature);
195
196
  for (let part = 0; part < parts.length; part++) {
196
197
  collectPolygonVertexHandles(parts[part], handles, part);
197
198
  }
@@ -208,7 +209,7 @@ export function computeCircleRadiusHandle(feature) {
208
209
  if (feature.type !== 'Circle') {
209
210
  return null;
210
211
  }
211
- const center = feature.coordinates;
212
+ const center = coordinatesOf(feature);
212
213
  const radiusMeters = getCircleRadius(feature);
213
214
  const radiusHandleAngle = getRadiusHandleAngle(feature);
214
215
  if (!radiusMeters || radiusMeters <= 0) {
@@ -227,7 +228,7 @@ export function computeCircleCenterHandle(feature) {
227
228
  if (feature.type !== 'Circle') {
228
229
  return null;
229
230
  }
230
- const center = feature.coordinates;
231
+ const center = coordinatesOf(feature);
231
232
  return {
232
233
  type: 'center',
233
234
  position: center,
@@ -283,19 +284,19 @@ export function computeMidpointHandles(feature, visibleSet) {
283
284
  }
284
285
  const handles = [];
285
286
  if (feature.type === 'LineString') {
286
- collectLineMidpointHandles(feature.coordinates, handles);
287
+ collectLineMidpointHandles(coordinatesOf(feature), handles);
287
288
  }
288
289
  else if (feature.type === 'Polygon') {
289
- collectPolygonMidpointHandles(feature.coordinates, handles);
290
+ collectPolygonMidpointHandles(coordinatesOf(feature), handles);
290
291
  }
291
292
  else if (feature.type === 'MultiLineString') {
292
- const parts = feature.coordinates;
293
+ const parts = coordinatesOf(feature);
293
294
  for (let part = 0; part < parts.length; part++) {
294
295
  collectLineMidpointHandles(parts[part], handles, part);
295
296
  }
296
297
  }
297
298
  else if (feature.type === 'MultiPolygon') {
298
- const parts = feature.coordinates;
299
+ const parts = coordinatesOf(feature);
299
300
  for (let part = 0; part < parts.length; part++) {
300
301
  collectPolygonMidpointHandles(parts[part], handles, part);
301
302
  }
@@ -528,6 +529,13 @@ export class SelectionHandlesRenderer {
528
529
  const handles = computeVertexHandles(feature).filter((h) => hasVertexRef(followedVertices, h.vertexRef));
529
530
  this.drawHandlesWithStyle(handles, this.config.vertexHandle.followed, zoom);
530
531
  }
532
+ /**
533
+ * Draws the auxiliary handles of the extensions with the look of the vertex handles, the
534
+ * size their hit test uses
535
+ */
536
+ drawAuxiliaryHandles(positions, zoom) {
537
+ this.drawHandlesWithStyle(positions.map((position) => ({ position })), this.config.vertexHandle.point, zoom);
538
+ }
531
539
  /**
532
540
  * Draws a group of handles with a single style
533
541
  *
@@ -16,4 +16,4 @@ import type { Store } from '../../store/store.js';
16
16
  * @param store The Store to read the selection from
17
17
  * @returns The feature ids. An empty array when nothing is selected
18
18
  */
19
- export declare function getSelectedFeatureIds(store: Store): string[];
19
+ export declare function getSelectedFeatureIds(store: Store): readonly string[];
@@ -32,7 +32,7 @@ function featureIdsInLayer(store, layerId) {
32
32
  if (!layer)
33
33
  return [];
34
34
  const ids = [];
35
- for (const itemId of layer.order) {
35
+ for (const itemId of layer.items) {
36
36
  if (store.getFeature(itemId)) {
37
37
  ids.push(itemId);
38
38
  }
@@ -9,7 +9,7 @@ export { getCursorForHandle, hitTestGlobalAuxiliaryHandles, hitTestHandles, } fr
9
9
  export type { HandleInfo } from './handles.js';
10
10
  export { computeMidpointHandles, computeResizeHandles, computeRotateHandle, computeVertexHandles, SelectionHandlesRenderer, } from './handles.js';
11
11
  export { computeSelectionBoundingBox, getSelectedFeatureIds, getSelectedFeatures, } from './helper.js';
12
- export type { AdditionalHandleInfo, AdditionalResizeHandlesCalculator, BoundingBoxCoords, CustomBoundingBoxCalculator, CustomResizeCalculator, PointFrameExtent, PointFrameExtentProvider, ResizeStrategy, SelectionExtensionRegistry, } from './selection-ui/index.js';
12
+ export type { AdditionalHandleInfo, AdditionalResizeHandlesCalculator, BoundingBoxCoords, CustomBoundingBoxCalculator, PointFrameExtent, PointFrameExtentProvider, ResizeStrategy, SelectionExtensionRegistry, TypeResizeCalculator, } from './selection-ui/index.js';
13
13
  export { computeBoundingBox, computeCombinedBoundingBox, createSelectionExtensionRegistry, DEFAULT_POINT_FRAME_SIZE, rotateBoundingBox, SelectionUIRenderer, } from './selection-ui/index.js';
14
14
  export type { TentativeRendererDeps } from './tentative.js';
15
15
  export { TentativeRenderer } from './tentative.js';
@@ -15,10 +15,12 @@ import { createSelectionExtensionRegistry, } from './selection-ui/extension-regi
15
15
  /**
16
16
  * Creates the selection scope of one draw instance
17
17
  *
18
+ * @param options.defaultPointFrameExtent - The extent of the frame of a point whose type
19
+ * registers none (see createSelectionExtensionRegistry)
18
20
  * @internal
19
21
  */
20
- export function createSelectionScope() {
21
- const extensions = createSelectionExtensionRegistry();
22
+ export function createSelectionScope(options = {}) {
23
+ const extensions = createSelectionExtensionRegistry(options.defaultPointFrameExtent);
22
24
  const auxiliaryHandles = createAuxiliaryHandleRegistry();
23
25
  const thinning = new HandleThinningCache();
24
26
  return {
@@ -13,6 +13,7 @@
13
13
  import { circleBoundingBox } from '../../../geometry/circle.js';
14
14
  import { pixelsToDegreesLat, pixelsToDegreesLng } from '../../../shared/math/index.js';
15
15
  import { fromPlane, toPlane } from '../../../shared/math/mercator-plane.js';
16
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
16
17
  import { getCircleRadius, getCreatedZoom, getImageProperties, } from '../../../shared/utils/property.js';
17
18
  import { getBoundingBox } from '../../../store/spatial/index.js';
18
19
  /**
@@ -45,7 +46,7 @@ export function computeBoundingBox(feature, extensions) {
45
46
  return customCalculator(feature, extensions.getTileSize());
46
47
  }
47
48
  if (feature.type === 'Point') {
48
- const coord = feature.coordinates;
49
+ const coord = coordinatesOf(feature);
49
50
  return {
50
51
  topLeft: coord,
51
52
  topRight: coord,
@@ -80,7 +81,7 @@ export function computeBoundingBox(feature, extensions) {
80
81
  * The frame of a Circle: the extent of the geodesic circle as it is drawn, around its center
81
82
  */
82
83
  function computeCircleBoundingBox(feature) {
83
- const center = feature.coordinates;
84
+ const center = coordinatesOf(feature);
84
85
  const radiusMeters = getCircleRadius(feature);
85
86
  const extent = radiusMeters && radiusMeters > 0 ? circleBoundingBox(center, radiusMeters) : null;
86
87
  if (!extent) {
@@ -108,13 +109,12 @@ function computeCircleBoundingBox(feature) {
108
109
  * (the same method as computeQuadVertices in quad-shader.ts).
109
110
  */
110
111
  function computeOrientedBoundingBox(feature) {
111
- const coord = feature.coordinates;
112
+ const coord = coordinatesOf(feature);
112
113
  const [lng, lat] = coord;
113
114
  const tileSize = 512;
114
115
  const props = getImageProperties(feature);
115
- const style = feature.style;
116
- const imageWidth = style?.width || props.imageWidth || 100;
117
- const imageHeight = style?.height || props.imageHeight || 100;
116
+ const imageWidth = props.imageWidth || 100;
117
+ const imageHeight = props.imageHeight || 100;
118
118
  const scale = props.scale ?? 1;
119
119
  // getImageProperties().createdZoom returns 0 when it is missing, so ?? does not work.
120
120
  // getCreatedZoom(number|undefined) is used so that 14 is the default when it is missing.
@@ -1,22 +1,11 @@
1
- /**
2
- * The registry of the Selection UI extension points
3
- *
4
- * A mechanism for the custom feature types of extension implementations to provide their own
5
- * boundingBox computation / resize handles / resize strategy / point frame extent.
6
- *
7
- * One registry belongs to one draw instance (it is created by createMapLibreGLDraw and handed
8
- * to the CustomLayer, the modes and the extension API). Two draw instances on the same page
9
- * never see each other's registrations, and destroying an instance clears its registry.
10
- * The tile size of the instance's map is held here as well, because the custom bounding box
11
- * calculators take it as an argument.
12
- */
13
1
  import type { Feature } from '../../../store/types.js';
14
- import type { AdditionalResizeHandlesCalculator, CustomBoundingBoxCalculator, CustomResizeCalculator, PointFrameExtent, PointFrameExtentProvider, ResizeStrategy } from './types.js';
2
+ import type { AdditionalResizeHandlesCalculator, CustomBoundingBoxCalculator, FramePoint, PointFrameExtent, PointFrameExtentProvider, PointFrameOutlineProvider, ResizeStrategy, TypeResizeCalculator } from './types.js';
15
3
  /**
16
4
  * The side of the square selection frame of a point, in CSS px: 12.
17
5
  *
18
- * The same value as DEFAULT_POINT_STYLE.size. Types with no registered extent become this
19
- * square (the same look as the former fixed value).
6
+ * The same value as DEFAULT_POINT_STYLE.size. Types with neither a registered extent nor a
7
+ * default extent of the registry become this square. A draw instance gives its registry the
8
+ * extent of the marker of a built-in point as the default.
20
9
  */
21
10
  export declare const DEFAULT_POINT_FRAME_SIZE = 12;
22
11
  /**
@@ -35,9 +24,9 @@ export interface SelectionExtensionRegistry {
35
24
  /** Returns the additional resize handles calculator of a type, or `undefined` */
36
25
  getAdditionalResizeHandlesCalculator(type: string): AdditionalResizeHandlesCalculator | undefined;
37
26
  /** Registers how a feature type is resized, replacing the built-in computation */
38
- registerCustomResize(type: string, calculator: CustomResizeCalculator): () => void;
27
+ registerCustomResize(type: string, calculator: TypeResizeCalculator): () => void;
39
28
  /** Returns the custom resize calculator of a type, or `undefined` */
40
- getCustomResizeCalculator(type: string): CustomResizeCalculator | undefined;
29
+ getCustomResizeCalculator(type: string): TypeResizeCalculator | undefined;
41
30
  /** Registers whether a feature type resizes by its coordinates or by its scale */
42
31
  registerResizeStrategy(type: string, strategy: ResizeStrategy): () => void;
43
32
  /** Returns the resize strategy of a type, or `undefined` */
@@ -50,10 +39,21 @@ export interface SelectionExtensionRegistry {
50
39
  * Resolve the half width and half height of the selection box of a zero-area point
51
40
  *
52
41
  * Types with no registration, types that return null and values that are not finite
53
- * degrade to the default square (the frame is not broken while the actual size on the
54
- * extension side is not yet determined).
42
+ * degrade to the default extent of the registry, and then to the default square (the frame
43
+ * is not broken while the actual size on the extension side is not yet determined).
55
44
  */
56
45
  resolvePointFrameExtent(feature: Feature): PointFrameExtent;
46
+ /** Registers the outline of the selection frame of a point-like feature type */
47
+ registerPointFrameOutline(type: string, provider: PointFrameOutlineProvider): () => void;
48
+ /**
49
+ * The four corners of the selection frame of a zero-area feature on the screen, expanded by
50
+ * the margin: the registered outline when it gives four finite corners, else the rectangle
51
+ * of {@link resolvePointFrameExtent} around the center
52
+ *
53
+ * @param center The center of the frame on the screen, in CSS px
54
+ * @param margin The margin of the frame, in CSS px
55
+ */
56
+ resolvePointFrameCorners(feature: Feature, center: FramePoint, margin: number): FramePoint[];
57
57
  /** The tile size in px of the instance's map (passed to the custom bounding box calculators) */
58
58
  getTileSize(): number;
59
59
  /** Sets the tile size in px (the draw instance sets it from the map) */
@@ -65,12 +65,23 @@ export interface SelectionExtensionRegistry {
65
65
  * Creates an empty {@link SelectionExtensionRegistry} with a tile size of 512 px, for testing a
66
66
  * custom feature handler in isolation.
67
67
  *
68
+ * @param defaultPointFrameExtent - The extent of the frame of a point whose type registers
69
+ * none, or whose provider gives none; without it (or when it returns null) the frame is the
70
+ * square of DEFAULT_POINT_FRAME_SIZE
68
71
  * @returns A new registry with no registration
69
72
  */
70
- export declare function createSelectionExtensionRegistry(): SelectionExtensionRegistry;
73
+ export declare function createSelectionExtensionRegistry(defaultPointFrameExtent?: PointFrameExtentProvider): SelectionExtensionRegistry;
71
74
  /**
72
75
  * Resolve the extent of a point's selection box with an optional provider
73
76
  *
74
77
  * Without a registry (callers outside a draw instance) the default square is returned.
75
78
  */
76
79
  export declare function resolvePointFrameExtentWith(provider: PointFrameExtentProvider | undefined, feature: Feature): PointFrameExtent;
80
+ /**
81
+ * The four corners of the selection frame of a zero-area feature on the screen, expanded by
82
+ * the margin, with optional providers
83
+ *
84
+ * An outline of four finite corners has every edge moved outward by the margin; any other
85
+ * outline, or none, gives the rectangle of the extent around the center, widened the same way.
86
+ */
87
+ export declare function resolvePointFrameCornersWith(extentProvider: PointFrameExtentProvider | undefined, outlineProvider: PointFrameOutlineProvider | undefined, feature: Feature, center: FramePoint, margin: number): FramePoint[];
@@ -1,10 +1,24 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * The registry of the Selection UI extension points
5
+ *
6
+ * A mechanism for the custom feature types of extension implementations to provide their own
7
+ * boundingBox computation / resize handles / resize strategy / point frame extent.
8
+ *
9
+ * One registry belongs to one draw instance (it is created by its engine and handed to the
10
+ * CustomLayer, the modes and the extension host). Two draw instances on the same page
11
+ * never see each other's registrations, and destroying an instance clears its registry.
12
+ * The tile size of the instance's map is held here as well, because the custom bounding box
13
+ * calculators take it as an argument.
14
+ */
15
+ import { expandQuad } from '../../../shared/math/transform.js';
3
16
  /**
4
17
  * The side of the square selection frame of a point, in CSS px: 12.
5
18
  *
6
- * The same value as DEFAULT_POINT_STYLE.size. Types with no registered extent become this
7
- * square (the same look as the former fixed value).
19
+ * The same value as DEFAULT_POINT_STYLE.size. Types with neither a registered extent nor a
20
+ * default extent of the registry become this square. A draw instance gives its registry the
21
+ * extent of the marker of a built-in point as the default.
8
22
  */
9
23
  export const DEFAULT_POINT_FRAME_SIZE = 12;
10
24
  /** The tile size used until the map reports its own (maplibre's default) */
@@ -23,15 +37,28 @@ function registerIn(map, type, value) {
23
37
  * Creates an empty {@link SelectionExtensionRegistry} with a tile size of 512 px, for testing a
24
38
  * custom feature handler in isolation.
25
39
  *
40
+ * @param defaultPointFrameExtent - The extent of the frame of a point whose type registers
41
+ * none, or whose provider gives none; without it (or when it returns null) the frame is the
42
+ * square of DEFAULT_POINT_FRAME_SIZE
26
43
  * @returns A new registry with no registration
27
44
  */
28
- export function createSelectionExtensionRegistry() {
45
+ export function createSelectionExtensionRegistry(defaultPointFrameExtent) {
29
46
  const boundingBoxes = new Map();
30
47
  const additionalHandles = new Map();
31
48
  const customResizes = new Map();
32
49
  const resizeStrategies = new Map();
33
50
  const pointFrameExtents = new Map();
51
+ const pointFrameOutlines = new Map();
34
52
  let tileSize = DEFAULT_REGISTRY_TILE_SIZE;
53
+ /** The extent provider of a type, falling back to the default extent of the registry */
54
+ const extentProviderOf = (type) => {
55
+ const own = pointFrameExtents.get(type);
56
+ if (!defaultPointFrameExtent)
57
+ return own;
58
+ if (!own)
59
+ return defaultPointFrameExtent;
60
+ return (feature) => validExtent(own(feature)) ?? defaultPointFrameExtent(feature);
61
+ };
35
62
  return {
36
63
  registerBoundingBox: (type, calculator) => registerIn(boundingBoxes, type, calculator),
37
64
  getBoundingBoxCalculator: (type) => boundingBoxes.get(type),
@@ -44,7 +71,11 @@ export function createSelectionExtensionRegistry() {
44
71
  registerPointFrameExtent: (type, provider) => registerIn(pointFrameExtents, type, provider),
45
72
  getPointFrameExtentProvider: (type) => pointFrameExtents.get(type),
46
73
  resolvePointFrameExtent(feature) {
47
- return resolvePointFrameExtentWith(pointFrameExtents.get(feature.type), feature);
74
+ return resolvePointFrameExtentWith(extentProviderOf(feature.type), feature);
75
+ },
76
+ registerPointFrameOutline: (type, provider) => registerIn(pointFrameOutlines, type, provider),
77
+ resolvePointFrameCorners(feature, center, margin) {
78
+ return resolvePointFrameCornersWith(extentProviderOf(feature.type), pointFrameOutlines.get(feature.type), feature, center, margin);
48
79
  },
49
80
  getTileSize: () => tileSize,
50
81
  setTileSize(value) {
@@ -56,6 +87,7 @@ export function createSelectionExtensionRegistry() {
56
87
  customResizes.clear();
57
88
  resizeStrategies.clear();
58
89
  pointFrameExtents.clear();
90
+ pointFrameOutlines.clear();
59
91
  },
60
92
  };
61
93
  }
@@ -65,14 +97,45 @@ export function createSelectionExtensionRegistry() {
65
97
  * Without a registry (callers outside a draw instance) the default square is returned.
66
98
  */
67
99
  export function resolvePointFrameExtentWith(provider, feature) {
68
- const extent = provider?.(feature);
100
+ const extent = validExtent(provider?.(feature));
101
+ if (!extent) {
102
+ const half = DEFAULT_POINT_FRAME_SIZE / 2;
103
+ return { halfWidth: half, halfHeight: half };
104
+ }
105
+ return extent;
106
+ }
107
+ /** The extent when it is one (finite and not negative), else null */
108
+ function validExtent(extent) {
69
109
  if (!extent ||
70
110
  !Number.isFinite(extent.halfWidth) ||
71
111
  !Number.isFinite(extent.halfHeight) ||
72
112
  extent.halfWidth < 0 ||
73
113
  extent.halfHeight < 0) {
74
- const half = DEFAULT_POINT_FRAME_SIZE / 2;
75
- return { halfWidth: half, halfHeight: half };
114
+ return null;
76
115
  }
77
116
  return extent;
78
117
  }
118
+ /**
119
+ * The four corners of the selection frame of a zero-area feature on the screen, expanded by
120
+ * the margin, with optional providers
121
+ *
122
+ * An outline of four finite corners has every edge moved outward by the margin; any other
123
+ * outline, or none, gives the rectangle of the extent around the center, widened the same way.
124
+ */
125
+ export function resolvePointFrameCornersWith(extentProvider, outlineProvider, feature, center, margin) {
126
+ const outline = outlineProvider?.(feature);
127
+ if (outline &&
128
+ outline.length === 4 &&
129
+ outline.every((corner) => Number.isFinite(corner.x) && Number.isFinite(corner.y))) {
130
+ return expandQuad(outline, margin);
131
+ }
132
+ const extent = resolvePointFrameExtentWith(extentProvider, feature);
133
+ const halfWidth = extent.halfWidth + margin;
134
+ const halfHeight = extent.halfHeight + margin;
135
+ return [
136
+ { x: center.x - halfWidth, y: center.y - halfHeight },
137
+ { x: center.x + halfWidth, y: center.y - halfHeight },
138
+ { x: center.x + halfWidth, y: center.y + halfHeight },
139
+ { x: center.x - halfWidth, y: center.y + halfHeight },
140
+ ];
141
+ }
@@ -7,6 +7,6 @@
7
7
  */
8
8
  export { computeBoundingBox, computeCombinedBoundingBox, hasZeroArea, rotateBoundingBox, } from './bounding-box.js';
9
9
  export type { SelectionExtensionRegistry } from './extension-registry.js';
10
- export { createSelectionExtensionRegistry, DEFAULT_POINT_FRAME_SIZE, resolvePointFrameExtentWith, } from './extension-registry.js';
10
+ export { createSelectionExtensionRegistry, DEFAULT_POINT_FRAME_SIZE, resolvePointFrameCornersWith, resolvePointFrameExtentWith, } from './extension-registry.js';
11
11
  export { SelectionUIRenderer } from './renderer.js';
12
- export type { AdditionalHandleInfo, AdditionalResizeHandlesCalculator, BoundingBoxCoords, CustomBoundingBoxCalculator, CustomResizeCalculator, PointFrameExtent, PointFrameExtentProvider, ResizeStrategy, } from './types.js';
12
+ export type { AdditionalHandleInfo, AdditionalResizeHandlesCalculator, BoundingBoxCoords, CustomBoundingBoxCalculator, FramePoint, PointFrameExtent, PointFrameExtentProvider, PointFrameOutlineProvider, ResizeStrategy, TypeResizeCalculator, } from './types.js';
@@ -8,5 +8,5 @@
8
8
  * symbols.
9
9
  */
10
10
  export { computeBoundingBox, computeCombinedBoundingBox, hasZeroArea, rotateBoundingBox, } from './bounding-box.js';
11
- export { createSelectionExtensionRegistry, DEFAULT_POINT_FRAME_SIZE, resolvePointFrameExtentWith, } from './extension-registry.js';
11
+ export { createSelectionExtensionRegistry, DEFAULT_POINT_FRAME_SIZE, resolvePointFrameCornersWith, resolvePointFrameExtentWith, } from './extension-registry.js';
12
12
  export { SelectionUIRenderer } from './renderer.js';
@@ -129,18 +129,13 @@ _SelectionUIRenderer_strokeRenderer = new WeakMap(), _SelectionUIRenderer_extens
129
129
  // coordinates must not be treated as a Coordinate)
130
130
  if (hasZeroArea(bbox)) {
131
131
  const center = transform.project(bbox.center);
132
- const extent = __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f").resolvePointFrameExtent(feature);
133
- const halfWidth = extent.halfWidth + margin;
134
- const halfHeight = extent.halfHeight + margin;
135
- const topLeft = transform.unproject({ x: center.x - halfWidth, y: center.y - halfHeight });
136
- const bottomRight = transform.unproject({
137
- x: center.x + halfWidth,
138
- y: center.y + halfHeight,
139
- });
140
- minLng = Math.min(minLng, topLeft.lng, bottomRight.lng);
141
- maxLng = Math.max(maxLng, topLeft.lng, bottomRight.lng);
142
- minLat = Math.min(minLat, topLeft.lat, bottomRight.lat);
143
- maxLat = Math.max(maxLat, topLeft.lat, bottomRight.lat);
132
+ for (const corner of __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f").resolvePointFrameCorners(feature, center, margin)) {
133
+ const at = transform.unproject(corner);
134
+ minLng = Math.min(minLng, at.lng);
135
+ maxLng = Math.max(maxLng, at.lng);
136
+ minLat = Math.min(minLat, at.lat);
137
+ maxLat = Math.max(maxLat, at.lat);
138
+ }
144
139
  continue;
145
140
  }
146
141
  const marginedBbox = applyMarginToBoundingBox(bbox, margin, transform, zoom);
@@ -175,34 +170,16 @@ _SelectionUIRenderer_strokeRenderer = new WeakMap(), _SelectionUIRenderer_extens
175
170
  }, _SelectionUIRenderer_drawPointBoundingBox = function _SelectionUIRenderer_drawPointBoundingBox(feature, coord, zoom) {
176
171
  if (!__classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f"))
177
172
  return;
178
- const center = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f").project(coord);
173
+ const transform = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f");
174
+ const center = transform.project(coord);
179
175
  const margin = __classPrivateFieldGet(this, _SelectionUIRenderer_config, "f").boundingBox.margin;
180
- const extent = __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f").resolvePointFrameExtent(feature);
181
- const halfWidth = extent.halfWidth + margin;
182
- const halfHeight = extent.halfHeight + margin;
183
- const topLeft = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f").unproject({
184
- x: center.x - halfWidth,
185
- y: center.y - halfHeight,
186
- });
187
- const topRight = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f").unproject({
188
- x: center.x + halfWidth,
189
- y: center.y - halfHeight,
190
- });
191
- const bottomRight = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f").unproject({
192
- x: center.x + halfWidth,
193
- y: center.y + halfHeight,
176
+ const coords = __classPrivateFieldGet(this, _SelectionUIRenderer_extensions, "f")
177
+ .resolvePointFrameCorners(feature, center, margin)
178
+ .map((corner) => {
179
+ const at = transform.unproject(corner);
180
+ return [at.lng, at.lat];
194
181
  });
195
- const bottomLeft = __classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f").unproject({
196
- x: center.x - halfWidth,
197
- y: center.y + halfHeight,
198
- });
199
- const coords = [
200
- [topLeft.lng, topLeft.lat],
201
- [topRight.lng, topRight.lat],
202
- [bottomRight.lng, bottomRight.lat],
203
- [bottomLeft.lng, bottomLeft.lat],
204
- [topLeft.lng, topLeft.lat],
205
- ];
182
+ coords.push(coords[0]);
206
183
  __classPrivateFieldGet(this, _SelectionUIRenderer_instances, "m", _SelectionUIRenderer_strokePath).call(this, coords, zoom);
207
184
  }, _SelectionUIRenderer_applyMargin = function _SelectionUIRenderer_applyMargin(bbox, zoom) {
208
185
  if (!__classPrivateFieldGet(this, _SelectionUIRenderer_transform, "f"))
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import type { BoundingBoxCoords } from '../../../shared/types/selection-box.js';
7
7
  import type { Coordinate, Feature } from '../../../store/types.js';
8
- export type { CustomResizeCalculator } from '../../../extension/index.js';
8
+ export type { TypeResizeCalculator } from '../../../extension/index.js';
9
9
  export type { BoundingBoxCoords } from '../../../shared/types/selection-box.js';
10
10
  /**
11
11
  * Computes the selection box of a feature of a custom type.
@@ -29,9 +29,24 @@ export interface PointFrameExtent {
29
29
  /**
30
30
  * Returns the size of the selection frame of a point-like feature.
31
31
  *
32
- * Returning null gives the default dimensions (the square of DEFAULT_POINT_FRAME_SIZE).
32
+ * Returning null gives the default dimensions: the extent of the marker for a point the
33
+ * built-in type draws, else the square of DEFAULT_POINT_FRAME_SIZE.
33
34
  */
34
35
  export type PointFrameExtentProvider = (feature: Feature) => PointFrameExtent | null;
36
+ /** A point on the screen in CSS px, from the top left of the map */
37
+ export interface FramePoint {
38
+ x: number;
39
+ y: number;
40
+ }
41
+ /**
42
+ * Returns the outline of the selection frame of a point-like feature: its four corners on the
43
+ * screen in CSS px, in the order top left, top right, bottom right, bottom left of the shape.
44
+ *
45
+ * The frame of a rotated shape is drawn along it. The point stays zero-area: no resize or
46
+ * rotate handle appears. Returning null (or anything but four finite corners) gives the frame
47
+ * of {@link PointFrameExtentProvider}.
48
+ */
49
+ export type PointFrameOutlineProvider = (feature: Feature) => readonly FramePoint[] | null;
35
50
  /**
36
51
  * A resize handle a custom feature type adds to the built-in ones (the same shape as
37
52
  * {@link HandleInfo}).
@@ -32,6 +32,14 @@ export declare function renderSelectionUI(selectedFeatures: Feature[], zoom: num
32
32
  * not suggest editing).
33
33
  */
34
34
  isLocked?: boolean): void;
35
+ /**
36
+ * Draw the auxiliary handles that belong to no feature (`getGlobalHandles`), whatever is
37
+ * selected
38
+ *
39
+ * The caller draws them only while they can be grabbed (the select mode, and the document
40
+ * neither read-only nor under the interaction lock).
41
+ */
42
+ export declare function renderGlobalAuxiliaryHandles(zoom: number, projectionData: CustomRenderMethodInput['defaultProjectionData'], deps: SelectionUIDrawerDeps, dragState: DragState | null): void;
35
43
  /**
36
44
  * The minimal interface of the Store that drawing the following vertices needs
37
45
  *
@@ -57,14 +57,75 @@ isLocked = false) {
57
57
  if (selectedFeatures.length === 1) {
58
58
  // Get the selected vertex reference (only for the target feature)
59
59
  const selectedVertexRefs = selectedVertices?.featureId === selectedFeatures[0].id
60
- ? selectedVertices.vertexIndices
60
+ ? selectedVertices.vertices
61
61
  : undefined;
62
62
  renderSingleSelectionHandles(selectedFeatures[0], zoom, selectionUIRenderer, selectionHandlesRenderer, operation, dragState, selectedVertexRefs, prepareVisibleHandleSet(selectedFeatures[0], map, scope), scope);
63
+ // The handles of the extensions, shown as the other handles are (hidden while another
64
+ // operation runs)
65
+ if (operation === null || operation === 'auxiliary') {
66
+ const context = auxiliaryHandleContext(map, zoom);
67
+ const positions = scope.auxiliaryHandles
68
+ .list()
69
+ .flatMap((provider) => provider.getHandles(selectedFeatures[0], context).map((handle) => handle.position));
70
+ if (positions.length > 0)
71
+ selectionHandlesRenderer.drawAuxiliaryHandles(positions, zoom);
72
+ }
63
73
  }
64
74
  else {
65
75
  renderMultiSelectionHandles(selectedFeatures, bbox, zoom, selectionHandlesRenderer, operation, scope);
66
76
  }
67
77
  }
78
+ /**
79
+ * Draw the auxiliary handles that belong to no feature (`getGlobalHandles`), whatever is
80
+ * selected
81
+ *
82
+ * The caller draws them only while they can be grabbed (the select mode, and the document
83
+ * neither read-only nor under the interaction lock).
84
+ */
85
+ export function renderGlobalAuxiliaryHandles(zoom, projectionData, deps, dragState) {
86
+ const { selectionHandlesRenderer, pointInstanceRenderer, map, scope } = deps;
87
+ if (!selectionHandlesRenderer)
88
+ return;
89
+ const operation = dragState?.operation ?? null;
90
+ if (operation !== null && operation !== 'auxiliary')
91
+ return;
92
+ const providers = scope.auxiliaryHandles.list();
93
+ if (!providers.some((provider) => provider.getGlobalHandles !== undefined))
94
+ return;
95
+ const context = auxiliaryHandleContext(map, zoom);
96
+ const positions = providers.flatMap((provider) => provider.getGlobalHandles?.(context).map((handle) => handle.position) ?? []);
97
+ if (positions.length === 0)
98
+ return;
99
+ if (pointInstanceRenderer)
100
+ pointInstanceRenderer.setProjectionData(projectionData);
101
+ selectionHandlesRenderer.setTransform(coordinateTransformOf(map));
102
+ selectionHandlesRenderer.setProjectionData(projectionData);
103
+ selectionHandlesRenderer.drawAuxiliaryHandles(positions, zoom);
104
+ }
105
+ /** The coordinate transform of the map */
106
+ function coordinateTransformOf(map) {
107
+ return {
108
+ project: (lngLat) => map.project([lngLat[0], lngLat[1]]),
109
+ unproject: (point) => {
110
+ const ll = map.unproject([point.x, point.y]);
111
+ return { lng: ll.lng, lat: ll.lat };
112
+ },
113
+ };
114
+ }
115
+ /**
116
+ * The context the providers of auxiliary handles get when their handles are drawn: the
117
+ * point is the center of the canvas, as there is no pointer to test
118
+ */
119
+ function auxiliaryHandleContext(map, zoom) {
120
+ const transform = coordinateTransformOf(map);
121
+ const canvas = map.getCanvas();
122
+ return {
123
+ point: { x: canvas.clientWidth / 2, y: canvas.clientHeight / 2 },
124
+ project: (lngLat) => transform.project(lngLat),
125
+ unproject: (point) => transform.unproject(point),
126
+ zoom,
127
+ };
128
+ }
68
129
  /**
69
130
  * Prepare the thinning set
70
131
  *
@@ -153,7 +214,7 @@ export function renderFollowedVertices(followedVertices, store, zoom, projection
153
214
  // The handles of features that disappeared or were hidden during the drag are not drawn
154
215
  if (!feature?.visible || isLocallyHidden(feature, store))
155
216
  continue;
156
- selectionHandlesRenderer.drawFollowedVertexHandles(feature, followed.vertexIndices, zoom);
217
+ selectionHandlesRenderer.drawFollowedVertexHandles(feature, followed.vertices, zoom);
157
218
  }
158
219
  }
159
220
  /**
@@ -1,6 +1,6 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
- import { destinationPoint } from '../../geometry/index.js';
3
+ import { destinationPoint } from '../../geometry/distance.js';
4
4
  import { generateCirclePolygon } from '../../shared/math/index.js';
5
5
  import { FillShaderManager } from '../renderers/polygon/fill.js';
6
6
  /**