@sakuzu/maplibre-gl-draw 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (540) hide show
  1. package/CHANGELOG.md +1016 -2
  2. package/README.ja.md +39 -19
  3. package/README.md +41 -21
  4. package/dist/api/datasets.d.ts +258 -0
  5. package/dist/api/document.d.ts +66 -0
  6. package/dist/api/draw.d.ts +135 -0
  7. package/dist/api/draw.js +18 -0
  8. package/dist/api/drawing.d.ts +87 -0
  9. package/dist/api/errors.d.ts +35 -0
  10. package/dist/api/errors.js +35 -0
  11. package/dist/api/events.d.ts +306 -0
  12. package/dist/api/extension/context.d.ts +247 -0
  13. package/dist/api/extension/feature-type.d.ts +129 -0
  14. package/dist/api/extension/mode.d.ts +123 -0
  15. package/dist/api/extension/plugin.d.ts +51 -0
  16. package/dist/api/extension/plugin.js +3 -0
  17. package/dist/api/extension/provider.d.ts +119 -0
  18. package/dist/api/extension/provider.js +3 -0
  19. package/dist/api/extension/render.d.ts +176 -0
  20. package/dist/api/extension/render.js +3 -0
  21. package/dist/api/extension/store.d.ts +190 -0
  22. package/dist/api/extension/store.js +3 -0
  23. package/dist/api/extensions.d.ts +306 -0
  24. package/dist/api/extensions.js +3 -0
  25. package/dist/api/features.d.ts +188 -0
  26. package/dist/api/features.js +3 -0
  27. package/dist/api/groups.d.ts +111 -0
  28. package/dist/api/groups.js +3 -0
  29. package/dist/api/hidden.d.ts +45 -0
  30. package/dist/api/hidden.js +3 -0
  31. package/dist/api/impl/adapters.js +463 -0
  32. package/dist/api/impl/contexts.js +466 -0
  33. package/dist/api/impl/create-draw.js +124 -0
  34. package/dist/api/impl/datasets.js +404 -0
  35. package/dist/api/impl/destroy-guard.js +74 -0
  36. package/dist/api/impl/document.js +280 -0
  37. package/dist/api/impl/drawing.js +180 -0
  38. package/dist/api/impl/engine-context.d.ts +7 -0
  39. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  40. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  41. package/dist/api/impl/events.js +422 -0
  42. package/dist/api/impl/extension-host.js +361 -0
  43. package/dist/api/impl/extensions.js +229 -0
  44. package/dist/api/impl/features.js +445 -0
  45. package/dist/api/impl/geometry/apply.d.ts +32 -0
  46. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  47. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  48. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  49. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  50. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  51. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  52. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  53. package/dist/api/impl/geometry/types.js +3 -0
  54. package/dist/api/impl/groups.d.ts +3 -0
  55. package/dist/api/impl/groups.js +268 -0
  56. package/dist/api/impl/hidden.js +60 -0
  57. package/dist/api/impl/import-export/constants.d.ts +22 -0
  58. package/dist/api/impl/import-export/constants.js +24 -0
  59. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  60. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  61. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  62. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  63. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  64. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  66. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  68. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  69. package/dist/api/impl/import-export/image-import.js +73 -0
  70. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  71. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  72. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  73. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  74. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  75. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  76. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  77. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  78. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  79. package/dist/api/impl/import-export/style-validation.js +86 -0
  80. package/dist/api/impl/import-export/types.d.ts +52 -0
  81. package/dist/api/impl/import-export/types.js +3 -0
  82. package/dist/api/impl/input.js +180 -0
  83. package/dist/api/impl/layers.js +307 -0
  84. package/dist/api/impl/metadata.d.ts +1 -0
  85. package/dist/api/impl/metadata.js +22 -0
  86. package/dist/api/impl/options.d.ts +1 -0
  87. package/dist/api/impl/options.js +822 -0
  88. package/dist/api/impl/placement.d.ts +1 -0
  89. package/dist/api/impl/placement.js +138 -0
  90. package/dist/api/impl/render-context.d.ts +13 -0
  91. package/dist/api/impl/render-context.js +272 -0
  92. package/dist/api/impl/rows.d.ts +1 -0
  93. package/dist/api/impl/rows.js +46 -0
  94. package/dist/api/impl/selection.d.ts +1 -0
  95. package/dist/api/impl/selection.js +186 -0
  96. package/dist/api/impl/shared.d.ts +64 -0
  97. package/dist/api/impl/shared.js +178 -0
  98. package/dist/api/impl/validate-extension.d.ts +1 -0
  99. package/dist/api/impl/validate-extension.js +159 -0
  100. package/dist/api/layers.d.ts +130 -0
  101. package/dist/api/layers.js +3 -0
  102. package/dist/api/metadata.d.ts +18 -0
  103. package/dist/api/metadata.js +3 -0
  104. package/dist/api/model.d.ts +487 -0
  105. package/dist/api/model.js +47 -0
  106. package/dist/api/options.d.ts +466 -0
  107. package/dist/api/options.js +3 -0
  108. package/dist/api/selection.d.ts +94 -0
  109. package/dist/api/selection.js +3 -0
  110. package/dist/api/state.d.ts +155 -0
  111. package/dist/api/state.js +12 -0
  112. package/dist/{display → dataset}/chunk.d.ts +1 -1
  113. package/dist/{display → dataset}/chunk.js +4 -3
  114. package/dist/{display → dataset}/dataset.js +18 -21
  115. package/dist/dataset/interaction.d.ts +1 -0
  116. package/dist/{display → dataset}/interaction.js +18 -6
  117. package/dist/dataset/manager.d.ts +1 -0
  118. package/dist/dataset/provider.d.ts +1 -0
  119. package/dist/{display → dataset}/retained.d.ts +1 -1
  120. package/dist/{display → dataset}/retained.js +8 -7
  121. package/dist/dataset/source.d.ts +1 -0
  122. package/dist/{display → dataset}/source.js +17 -4
  123. package/dist/dataset/spatial.d.ts +1 -0
  124. package/dist/{display → dataset}/spatial.js +1 -1
  125. package/dist/dataset/style.d.ts +1 -0
  126. package/dist/{display → dataset}/style.js +1 -1
  127. package/dist/dataset/table-source.d.ts +1 -0
  128. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  129. package/dist/{display → dataset}/thinning.d.ts +0 -10
  130. package/dist/{display → dataset}/thinning.js +3 -2
  131. package/dist/dataset/triangulation.d.ts +1 -0
  132. package/dist/{display → dataset}/triangulation.js +0 -0
  133. package/dist/{display → dataset}/types.d.ts +82 -121
  134. package/dist/dataset/types.js +61 -0
  135. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  136. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  137. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  138. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  139. package/dist/dispatcher/hit-test/service.js +80 -16
  140. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  141. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  142. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  143. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  144. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  145. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  146. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  147. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  148. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  149. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  150. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  151. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  152. package/dist/dispatcher/input-router.js +152 -69
  153. package/dist/dispatcher/normalizer.js +6 -2
  154. package/dist/dispatcher/types.d.ts +6 -1
  155. package/dist/extension/feature-handler.d.ts +1 -182
  156. package/dist/extension/index.d.ts +4 -7
  157. package/dist/extension/renderers.d.ts +1 -208
  158. package/dist/geometry/angle.d.ts +0 -8
  159. package/dist/geometry/angle.js +0 -8
  160. package/dist/geometry/bbox.d.ts +4 -12
  161. package/dist/geometry/bbox.js +4 -12
  162. package/dist/geometry/boolean.d.ts +0 -51
  163. package/dist/geometry/boolean.js +0 -51
  164. package/dist/geometry/buffer.d.ts +0 -26
  165. package/dist/geometry/buffer.js +0 -26
  166. package/dist/geometry/circle.d.ts +0 -9
  167. package/dist/geometry/circle.js +0 -9
  168. package/dist/geometry/coords.d.ts +0 -16
  169. package/dist/geometry/coords.js +0 -16
  170. package/dist/geometry/distance.d.ts +0 -24
  171. package/dist/geometry/distance.js +0 -24
  172. package/dist/geometry/errors.d.ts +21 -36
  173. package/dist/geometry/errors.js +49 -29
  174. package/dist/geometry/geojson.d.ts +81 -0
  175. package/dist/geometry/geojson.js +164 -0
  176. package/dist/geometry/index.d.ts +38 -23
  177. package/dist/geometry/index.js +43 -31
  178. package/dist/geometry/measure.d.ts +0 -27
  179. package/dist/geometry/measure.js +0 -27
  180. package/dist/geometry/predicates.d.ts +0 -9
  181. package/dist/geometry/predicates.js +0 -9
  182. package/dist/geometry/public-bounds.d.ts +26 -0
  183. package/dist/geometry/public-bounds.js +30 -0
  184. package/dist/geometry/public-combine.d.ts +78 -0
  185. package/dist/geometry/public-combine.js +82 -0
  186. package/dist/geometry/public-create.d.ts +54 -0
  187. package/dist/geometry/public-create.js +70 -0
  188. package/dist/geometry/public-measure.d.ts +170 -0
  189. package/dist/geometry/public-measure.js +283 -0
  190. package/dist/geometry/public-predicates.d.ts +54 -0
  191. package/dist/geometry/public-predicates.js +144 -0
  192. package/dist/geometry/public-repair.d.ts +75 -0
  193. package/dist/geometry/public-repair.js +77 -0
  194. package/dist/geometry/simplify.d.ts +0 -7
  195. package/dist/geometry/simplify.js +0 -7
  196. package/dist/geometry/split.d.ts +0 -20
  197. package/dist/geometry/split.js +0 -20
  198. package/dist/geometry/units.d.ts +20 -12
  199. package/dist/geometry/units.js +20 -12
  200. package/dist/index.d.ts +52 -66
  201. package/dist/index.js +6 -18
  202. package/dist/messages.d.ts +7 -7
  203. package/dist/modes/draw/circle.js +83 -207
  204. package/dist/modes/draw/commit-layer.d.ts +5 -16
  205. package/dist/modes/draw/commit-layer.js +2 -13
  206. package/dist/modes/draw/freehand.js +108 -246
  207. package/dist/modes/draw/image.js +4 -2
  208. package/dist/modes/draw/index.d.ts +5 -5
  209. package/dist/modes/draw/index.js +5 -5
  210. package/dist/modes/draw/line.js +18 -354
  211. package/dist/modes/draw/point.js +29 -78
  212. package/dist/modes/draw/polygon.js +23 -368
  213. package/dist/modes/draw/trace-support.d.ts +43 -36
  214. package/dist/modes/draw/trace-support.js +95 -98
  215. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  216. package/dist/modes/draw/vertex-drawing.js +176 -0
  217. package/dist/modes/handler.d.ts +1 -285
  218. package/dist/modes/manager.d.ts +2 -2
  219. package/dist/modes/manager.js +3 -0
  220. package/dist/modes/select/box-selection.d.ts +3 -3
  221. package/dist/modes/select/box-selection.js +2 -1
  222. package/dist/modes/select/click-handler.d.ts +5 -5
  223. package/dist/modes/select/click-handler.js +22 -20
  224. package/dist/modes/select/cursor-handler.d.ts +2 -2
  225. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  226. package/dist/modes/select/drag/move.js +3 -3
  227. package/dist/modes/select/drag/operation.d.ts +3 -3
  228. package/dist/modes/select/drag/radius.js +5 -4
  229. package/dist/modes/select/drag/transform.d.ts +2 -2
  230. package/dist/modes/select/drag/transform.js +11 -5
  231. package/dist/modes/select/drag/vertex.d.ts +2 -2
  232. package/dist/modes/select/drag/vertex.js +13 -8
  233. package/dist/modes/select/drag-handler.js +44 -25
  234. package/dist/modes/select/mode.js +17 -17
  235. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  236. package/dist/modes/select/shortcut-handler.js +9 -7
  237. package/dist/operations/layer-operations.js +29 -168
  238. package/dist/operations/resize.d.ts +2 -2
  239. package/dist/operations/resize.js +5 -5
  240. package/dist/operations/rotate.js +5 -5
  241. package/dist/operations/selection-operations.d.ts +16 -1
  242. package/dist/operations/selection-operations.js +28 -13
  243. package/dist/operations/shared-vertex.js +4 -2
  244. package/dist/operations/trace-graph.d.ts +0 -18
  245. package/dist/operations/trace-graph.js +0 -18
  246. package/dist/operations/vertex.js +36 -35
  247. package/dist/shared/color.d.ts +1 -0
  248. package/dist/shared/color.js +245 -0
  249. package/dist/shared/config/constants.d.ts +1 -54
  250. package/dist/shared/config/constants.js +1 -58
  251. package/dist/shared/config/feature-style.d.ts +16 -13
  252. package/dist/shared/config/feature-style.js +9 -0
  253. package/dist/shared/config/rendering.d.ts +3 -3
  254. package/dist/shared/config/selection-highlight.d.ts +0 -15
  255. package/dist/shared/config/selection-highlight.js +4 -7
  256. package/dist/shared/config/selection.d.ts +2 -32
  257. package/dist/shared/config/selection.js +0 -18
  258. package/dist/shared/config/topology.d.ts +2 -2
  259. package/dist/shared/config/trace.d.ts +4 -4
  260. package/dist/shared/math/angle.d.ts +1 -1
  261. package/dist/shared/math/angle.js +1 -1
  262. package/dist/shared/math/circle.d.ts +1 -1
  263. package/dist/shared/math/circle.js +1 -1
  264. package/dist/shared/math/distance.d.ts +2 -1
  265. package/dist/shared/math/distance.js +3 -2
  266. package/dist/shared/math/index.d.ts +1 -1
  267. package/dist/shared/math/index.js +1 -1
  268. package/dist/shared/math/transform.d.ts +23 -0
  269. package/dist/shared/math/transform.js +47 -28
  270. package/dist/shared/properties.d.ts +18 -0
  271. package/dist/shared/properties.js +129 -0
  272. package/dist/shared/types/events.d.ts +15 -7
  273. package/dist/shared/types/model.d.ts +109 -159
  274. package/dist/shared/types/style.d.ts +1 -1
  275. package/dist/shared/utils/color.d.ts +2 -36
  276. package/dist/shared/utils/color.js +13 -70
  277. package/dist/shared/utils/coordinates.d.ts +30 -4
  278. package/dist/shared/utils/coordinates.js +56 -10
  279. package/dist/shared/utils/event-emitter.d.ts +1 -262
  280. package/dist/shared/utils/event-emitter.js +4 -3
  281. package/dist/shared/utils/feature-bbox.js +8 -7
  282. package/dist/shared/utils/feature-segments.js +5 -4
  283. package/dist/shared/utils/image.d.ts +0 -4
  284. package/dist/shared/utils/image.js +0 -6
  285. package/dist/shared/utils/name-generator.d.ts +14 -20
  286. package/dist/shared/utils/name-generator.js +20 -3
  287. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  288. package/dist/shared/utils/pixel-ratio.js +13 -4
  289. package/dist/shared/utils/property.d.ts +7 -50
  290. package/dist/shared/utils/property.js +22 -87
  291. package/dist/snapping/custom-targets.js +21 -4
  292. package/dist/snapping/indicator.js +20 -11
  293. package/dist/snapping/providers/display.d.ts +6 -1
  294. package/dist/snapping/providers/display.js +2 -1
  295. package/dist/snapping/providers/guide.d.ts +3 -43
  296. package/dist/snapping/providers/guide.js +1 -44
  297. package/dist/snapping/providers/intersection.js +1 -1
  298. package/dist/snapping/providers/store.js +3 -3
  299. package/dist/snapping/service.js +18 -7
  300. package/dist/snapping/types.d.ts +9 -35
  301. package/dist/store/draw-store.js +233 -142
  302. package/dist/store/local-visibility.d.ts +11 -6
  303. package/dist/store/local-visibility.js +38 -7
  304. package/dist/store/lock.d.ts +0 -6
  305. package/dist/store/lock.js +0 -6
  306. package/dist/store/memory/change-bus.d.ts +3 -3
  307. package/dist/store/memory/change-bus.js +12 -0
  308. package/dist/store/memory/file-store.d.ts +2 -2
  309. package/dist/store/memory/ui-state.d.ts +1 -51
  310. package/dist/store/memory/ui-state.js +122 -134
  311. package/dist/store/memory.d.ts +1 -8
  312. package/dist/store/memory.js +249 -45
  313. package/dist/store/ordering.d.ts +9 -0
  314. package/dist/store/ordering.js +17 -0
  315. package/dist/store/spatial/spatial-index.d.ts +1 -1
  316. package/dist/store/spatial/spatial-index.js +1 -1
  317. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  318. package/dist/store/spatial/store-spatial-index.js +9 -3
  319. package/dist/store/store.d.ts +66 -107
  320. package/dist/store/types.d.ts +1 -1
  321. package/dist/store/writable-layer.d.ts +1 -1
  322. package/dist/store/writable-layer.js +2 -2
  323. package/dist/table/builder.d.ts +83 -0
  324. package/dist/table/builder.js +381 -0
  325. package/dist/table/index.d.ts +37 -0
  326. package/dist/table/index.js +5 -0
  327. package/dist/table/packed-rtree.d.ts +1 -0
  328. package/dist/{display → table}/packed-rtree.js +1 -1
  329. package/dist/table/partition.d.ts +1 -0
  330. package/dist/{display → table}/partition.js +3 -3
  331. package/dist/table/prepare.d.ts +44 -0
  332. package/dist/table/prepare.js +136 -0
  333. package/dist/table/table.d.ts +1 -0
  334. package/dist/{display/columnar → table}/table.js +29 -25
  335. package/dist/{display/columnar → table}/types.d.ts +68 -72
  336. package/dist/table/types.js +3 -0
  337. package/dist/view/coordinator.js +4 -3
  338. package/dist/view/feature-companion.d.ts +13 -7
  339. package/dist/view/feature-companion.js +11 -3
  340. package/dist/view/globe-subdivision.js +3 -3
  341. package/dist/view/layer/attach.d.ts +1 -1
  342. package/dist/view/layer/attach.js +1 -1
  343. package/dist/view/layer/custom-layer.js +40 -11
  344. package/dist/view/layer/display-list.js +2 -1
  345. package/dist/view/layer/drape-planner.d.ts +2 -2
  346. package/dist/view/layer/frame-render.d.ts +3 -3
  347. package/dist/view/layer/frame-render.js +7 -2
  348. package/dist/view/layer/frame-state.d.ts +6 -6
  349. package/dist/view/layer/index.d.ts +2 -2
  350. package/dist/view/layer/index.js +1 -1
  351. package/dist/view/layer/render.d.ts +4 -4
  352. package/dist/view/layer/render.js +3 -8
  353. package/dist/view/layer/renderers.d.ts +2 -2
  354. package/dist/view/layer/renderers.js +1 -1
  355. package/dist/view/layer/slot-manager.d.ts +2 -2
  356. package/dist/view/layer/slot-manager.js +4 -4
  357. package/dist/view/layer/slots.d.ts +2 -2
  358. package/dist/view/layer/slots.js +1 -1
  359. package/dist/view/layer/store-retained-bbox.js +3 -2
  360. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  361. package/dist/view/layer/store-retained-classify.js +19 -7
  362. package/dist/view/layer/store-retained-collect.js +8 -7
  363. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  364. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  365. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  366. package/dist/view/layer/store-retained-immediate.js +3 -8
  367. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  368. package/dist/view/layer/store-retained.d.ts +2 -2
  369. package/dist/view/layer/store-retained.js +1 -1
  370. package/dist/view/renderers/batch-manager.js +8 -7
  371. package/dist/view/renderers/drawer.js +21 -15
  372. package/dist/view/renderers/image.js +13 -39
  373. package/dist/view/renderers/line/line-types.d.ts +3 -3
  374. package/dist/view/renderers/line/sdf-line.js +3 -1
  375. package/dist/view/renderers/point/billboard-depth.js +1 -1
  376. package/dist/view/renderers/point/point-instance.js +1 -1
  377. package/dist/view/renderers/point/point-shape.js +2 -2
  378. package/dist/view/renderers/point/point-style.js +48 -4
  379. package/dist/view/renderers/polygon/batch.js +1 -2
  380. package/dist/view/renderers/polygon/fill.js +3 -1
  381. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  382. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  383. package/dist/view/renderers/stroke.js +3 -1
  384. package/dist/view/shaders/helpers.d.ts +2 -42
  385. package/dist/view/shaders/helpers.js +0 -6
  386. package/dist/view/shaders/projection.d.ts +15 -7
  387. package/dist/view/shaders/projection.js +23 -6
  388. package/dist/view/shaders/quad.d.ts +16 -12
  389. package/dist/view/shaders/quad.js +34 -13
  390. package/dist/view/style-rule.d.ts +5 -42
  391. package/dist/view/style-rule.js +20 -44
  392. package/dist/view/terrain/binding.d.ts +1 -0
  393. package/dist/view/terrain/binding.js +29 -0
  394. package/dist/view/terrain/context.d.ts +3 -4
  395. package/dist/view/terrain/context.js +4 -5
  396. package/dist/view/terrain/drape/geometry.js +1 -1
  397. package/dist/view/terrain/drape/pass.d.ts +1 -1
  398. package/dist/view/terrain/drape/pass.js +8 -7
  399. package/dist/view/terrain/polygon.d.ts +9 -5
  400. package/dist/view/terrain/polygon.js +16 -2
  401. package/dist/view/terrain/state.d.ts +1 -1
  402. package/dist/view/terrain/state.js +1 -1
  403. package/dist/view/terrain/tessellation.d.ts +2 -2
  404. package/dist/view/terrain/tessellation.js +1 -1
  405. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  406. package/dist/view/ui/bounds.js +8 -12
  407. package/dist/view/ui/handle-test.js +2 -2
  408. package/dist/view/ui/handle-thinning.js +17 -17
  409. package/dist/view/ui/handles.js +21 -13
  410. package/dist/view/ui/helper.d.ts +1 -1
  411. package/dist/view/ui/helper.js +1 -1
  412. package/dist/view/ui/index.d.ts +1 -1
  413. package/dist/view/ui/selection-scope.js +4 -2
  414. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  415. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  416. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  417. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  418. package/dist/view/ui/selection-ui/index.js +1 -1
  419. package/dist/view/ui/selection-ui/renderer.js +15 -38
  420. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  421. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  422. package/dist/view/ui/selection-ui-drawer.js +63 -2
  423. package/dist/view/ui/tentative.js +1 -1
  424. package/dist/webgl/index.d.ts +65 -0
  425. package/dist/webgl/index.js +62 -0
  426. package/package.json +20 -9
  427. package/dist/api/api.d.ts +0 -1259
  428. package/dist/api/api.js +0 -86
  429. package/dist/api/context.d.ts +0 -173
  430. package/dist/api/display-api.js +0 -23
  431. package/dist/api/event-api.d.ts +0 -13
  432. package/dist/api/event-api.js +0 -17
  433. package/dist/api/extension-api.d.ts +0 -46
  434. package/dist/api/extension-api.js +0 -85
  435. package/dist/api/feature-api.d.ts +0 -11
  436. package/dist/api/feature-api.js +0 -101
  437. package/dist/api/geometry/apply.d.ts +0 -51
  438. package/dist/api/geometry/boolean.d.ts +0 -28
  439. package/dist/api/geometry/boolean.js +0 -65
  440. package/dist/api/geometry/types.d.ts +0 -31
  441. package/dist/api/geometry-operations.d.ts +0 -162
  442. package/dist/api/geometry-operations.js +0 -94
  443. package/dist/api/group-api.d.ts +0 -10
  444. package/dist/api/group-api.js +0 -78
  445. package/dist/api/import-export/constants.d.ts +0 -29
  446. package/dist/api/import-export/constants.js +0 -40
  447. package/dist/api/import-export/file-name.d.ts +0 -10
  448. package/dist/api/import-export/file-name.js +0 -20
  449. package/dist/api/import-export/geojson-export.d.ts +0 -19
  450. package/dist/api/import-export/image-import.d.ts +0 -12
  451. package/dist/api/import-export/image-import.js +0 -53
  452. package/dist/api/import-export/index.d.ts +0 -9
  453. package/dist/api/import-export/index.js +0 -107
  454. package/dist/api/import-export/native-format.d.ts +0 -15
  455. package/dist/api/import-export/style-validation.d.ts +0 -27
  456. package/dist/api/import-export/style-validation.js +0 -49
  457. package/dist/api/import-export/types.d.ts +0 -26
  458. package/dist/api/index.d.ts +0 -15
  459. package/dist/api/index.js +0 -3
  460. package/dist/api/input-api.d.ts +0 -158
  461. package/dist/api/input-api.js +0 -144
  462. package/dist/api/instance-api.d.ts +0 -38
  463. package/dist/api/instance-api.js +0 -136
  464. package/dist/api/layer-api.d.ts +0 -12
  465. package/dist/api/layer-api.js +0 -62
  466. package/dist/api/selection-api.d.ts +0 -7
  467. package/dist/api/selection-api.js +0 -78
  468. package/dist/api/snapping-api.d.ts +0 -125
  469. package/dist/api/snapping-api.js +0 -50
  470. package/dist/api/topology-api.d.ts +0 -30
  471. package/dist/api/topology-api.js +0 -16
  472. package/dist/api/tracing-api.d.ts +0 -31
  473. package/dist/api/tracing-api.js +0 -16
  474. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  475. package/dist/dispatcher/hit-test/index.js +0 -9
  476. package/dist/dispatcher/index.d.ts +0 -15
  477. package/dist/dispatcher/index.js +0 -3
  478. package/dist/display/columnar/index.d.ts +0 -12
  479. package/dist/display/columnar/index.js +0 -13
  480. package/dist/display/columnar/prepare.d.ts +0 -42
  481. package/dist/display/columnar/prepare.js +0 -116
  482. package/dist/display/index.d.ts +0 -13
  483. package/dist/display/types.js +0 -43
  484. package/dist/maplibre-gl-draw.d.ts +0 -47
  485. package/dist/modes/cursor.js +0 -72
  486. package/dist/modes/index.d.ts +0 -7
  487. package/dist/operations/index.d.ts +0 -9
  488. package/dist/operations/index.js +0 -3
  489. package/dist/plugins/index.d.ts +0 -10
  490. package/dist/plugins/mutation-hooks.d.ts +0 -28
  491. package/dist/plugins/mutation-hooks.js +0 -84
  492. package/dist/plugins/plugin-context.js +0 -367
  493. package/dist/plugins/plugin-manager.d.ts +0 -103
  494. package/dist/plugins/plugin-manager.js +0 -316
  495. package/dist/plugins/plugin.d.ts +0 -529
  496. package/dist/shared/config/index.d.ts +0 -17
  497. package/dist/shared/config/index.js +0 -8
  498. package/dist/shared/utils/index.d.ts +0 -15
  499. package/dist/shared/utils/index.js +0 -24
  500. package/dist/snapping/index.d.ts +0 -14
  501. package/dist/snapping/index.js +0 -4
  502. package/dist/store/change-merger.js +0 -102
  503. package/dist/store/event-bridge.js +0 -161
  504. package/dist/store/index.d.ts +0 -12
  505. package/dist/store/index.js +0 -4
  506. package/dist/view/index.d.ts +0 -47
  507. package/dist/view/index.js +0 -20
  508. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  509. /package/dist/api/{import-export/types.js → document.js} +0 -0
  510. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  511. /package/dist/{display/index.js → api/events.js} +0 -0
  512. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  513. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  514. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  515. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  516. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  517. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  518. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  519. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  520. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  521. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  522. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  523. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  524. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  525. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  526. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  527. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  528. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  529. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  532. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  533. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  534. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  535. /package/dist/{display → dataset}/chunk-set.js +0 -0
  536. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  537. /package/dist/{display → dataset}/manager.js +0 -0
  538. /package/dist/{display → dataset}/provider.js +0 -0
  539. /package/dist/{display → dataset}/selection.d.ts +0 -0
  540. /package/dist/{display → dataset}/selection.js +0 -0
@@ -47,6 +47,12 @@ export interface AnchorScreenProjector {
47
47
  * draw instance (6 px by default).
48
48
  */
49
49
  export interface HitTestService {
50
+ /**
51
+ * Changes how far from a feature a click still hits it, in CSS pixels
52
+ *
53
+ * @param px The new tolerance
54
+ */
55
+ setClickTolerance(px: number): void;
50
56
  /**
51
57
  * Returns the frontmost feature that is hit, walking `orderedFeatures` from the end
52
58
  *
@@ -84,6 +90,10 @@ export interface HitTestService {
84
90
  * @returns a function that cancels the registration (see HitTestStrategyRegistry.register)
85
91
  */
86
92
  registerStrategy?(strategy: HitTestStrategy): () => void;
93
+ /**
94
+ * The strategy registered for a type, or `undefined`
95
+ */
96
+ getStrategy?(type: string): HitTestStrategy | undefined;
87
97
  /**
88
98
  * Registers, per feature type, the extra reach (in CSS pixels) for narrowing down the
89
99
  * candidates
@@ -117,4 +127,11 @@ export interface HitTestServiceImplOptions extends Partial<HitTestOptions> {
117
127
  * is tested
118
128
  */
119
129
  drawnShape?: DrawnShapeResolver;
130
+ /**
131
+ * How far the marker of a built-in point reaches from its position, in CSS pixels. When
132
+ * given, the built-in `Point` and `MultiPoint` strategies hit a point within that reach plus
133
+ * the tolerance, so a click anywhere on its marker hits it; when omitted a point is hit
134
+ * within the tolerance of its position alone
135
+ */
136
+ pointMarkerReachPx?: (feature: Feature) => number;
120
137
  }
@@ -1,5 +1,6 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { coordinatesOf } from '../../shared/utils/coordinates.js';
3
4
  import { clickCopies, toleranceDegrees } from './local-frame.js';
4
5
  import { DEFAULT_HIT_TEST_OPTIONS, HitTestStrategyRegistry } from './strategies/base.js';
5
6
  import { CircleHitTestStrategy } from './strategies/circle.js';
@@ -22,6 +23,9 @@ const SCREEN_SPACE_TYPES = new Set(['Point', 'MultiPoint']);
22
23
  * @internal
23
24
  */
24
25
  export class HitTestServiceImpl {
26
+ setClickTolerance(px) {
27
+ this.options = { ...this.options, clickTolerance: px };
28
+ }
25
29
  constructor(store, spatialIndex, options = {}) {
26
30
  Object.defineProperty(this, "spatialIndex", {
27
31
  enumerable: true,
@@ -83,13 +87,14 @@ export class HitTestServiceImpl {
83
87
  const tileSize = options.tileSize ?? 512;
84
88
  // Register the default strategies
85
89
  this.registry = new HitTestStrategyRegistry();
86
- this.registry.register(new PointHitTestStrategy());
90
+ const markerReach = options.pointMarkerReachPx;
91
+ this.registry.register(withReach(new PointHitTestStrategy(), markerReach));
87
92
  this.registry.register(new LineHitTestStrategy());
88
93
  this.registry.register(new PolygonHitTestStrategy());
89
94
  this.registry.register(new CircleHitTestStrategy());
90
95
  // The Multi geometries (a hit if any part is hit / the distance is the minimum over the
91
96
  // parts)
92
- this.registry.register(new MultiPointHitTestStrategy());
97
+ this.registry.register(withReach(new MultiPointHitTestStrategy(), markerReach));
93
98
  this.registry.register(new MultiLineStringHitTestStrategy());
94
99
  this.registry.register(new MultiPolygonHitTestStrategy());
95
100
  // Freehand uses the same strategy as LineString
@@ -117,6 +122,12 @@ export class HitTestServiceImpl {
117
122
  registerStrategy(strategy) {
118
123
  return this.registry.register(strategy);
119
124
  }
125
+ /**
126
+ * The strategy registered for a type
127
+ */
128
+ getStrategy(type) {
129
+ return this.registry.get(type);
130
+ }
120
131
  /**
121
132
  * Registers the extra reach for narrowing down the candidates
122
133
  *
@@ -155,12 +166,36 @@ export class HitTestServiceImpl {
155
166
  * The radius is a square box in degrees. A latitude reach needs only radius * cos φ
156
167
  * (local-frame.ts), so the box never misses a candidate.
157
168
  */
158
- expandSearchRadius(toleranceLngLat, tolerancePx, screenPoint, unproject) {
159
- const reachPx = this.maxCandidateReachPx();
169
+ expandSearchRadius(toleranceLngLat, degPerPx, orderedFeatures) {
170
+ const reachPx = this.maxCandidateReachPx() + this.maxFeatureReachPx(orderedFeatures);
160
171
  if (reachPx <= 0)
161
172
  return toleranceLngLat;
162
- const degPerPx = tolerancePx > 0 ? toleranceLngLat / tolerancePx : toleranceDegrees(unproject, screenPoint, 1);
163
- return toleranceLngLat + reachPx * degPerPx;
173
+ return toleranceLngLat + reachPx * degPerPx();
174
+ }
175
+ /**
176
+ * The largest reach beyond its geometry among the features whose strategy has one
177
+ * (`HitTestStrategy.reachPx`, the markers of the points), in CSS pixels
178
+ *
179
+ * The reach depends on the style of each feature, so it is measured at query time like the
180
+ * rest of the appearance (the bounding boxes of the index stay those of the geometry).
181
+ */
182
+ maxFeatureReachPx(orderedFeatures) {
183
+ let max = 0;
184
+ let lastType;
185
+ let reachOf;
186
+ for (const feature of orderedFeatures) {
187
+ if (feature.type !== lastType) {
188
+ lastType = feature.type;
189
+ const strategy = this.registry.get(feature.type);
190
+ reachOf = strategy?.reachPx?.bind(strategy);
191
+ }
192
+ if (!reachOf)
193
+ continue;
194
+ const reach = reachOf(feature);
195
+ if (reach > max)
196
+ max = reach;
197
+ }
198
+ return max;
164
199
  }
165
200
  /**
166
201
  * Returns the frontmost hit in the visual stacking order
@@ -198,9 +233,16 @@ export class HitTestServiceImpl {
198
233
  // The search radius is widened by the registered extra reach
199
234
  // (registerCandidateReach). Unlike the approach of baking the appearance into the bbox
200
235
  // of the index, this does not depend on the state or the zoom. The tolerance passed to
201
- // the second stage is toleranceLngLat as before (only the candidate set widens; the
202
- // semantics of a hit are decided by the strategy).
203
- const searchRadius = this.expandSearchRadius(toleranceLngLat, tolerance, screenPoint, unproject);
236
+ // the second stage is toleranceLngLat as before, widened only by the reach of a strategy
237
+ // (the marker of a point); the registered reach widens only the candidate set.
238
+ // The degrees per CSS pixel at the click, measured once and only when needed (from the
239
+ // tolerance already converted, or from one pixel when the tolerance is 0)
240
+ let degPerPxMemo;
241
+ const degPerPx = () => {
242
+ degPerPxMemo ?? (degPerPxMemo = tolerance > 0 ? toleranceLngLat / tolerance : toleranceDegrees(unproject, screenPoint, 1));
243
+ return degPerPxMemo;
244
+ };
245
+ const searchRadius = this.expandSearchRadius(toleranceLngLat, degPerPx, orderedFeatures);
204
246
  // The click on each copy of the world it can reach (the stored copy alone away from the
205
247
  // antimeridian; local-frame.ts)
206
248
  const copies = clickCopies(coordinate, searchRadius);
@@ -222,8 +264,7 @@ export class HitTestServiceImpl {
222
264
  // Symbols (points) are tested in screen space. This works only while the terrain is
223
265
  // enabled; when it is disabled null is returned and the conventional path is used as
224
266
  // before.
225
- const degPerPx = tolerance > 0 ? toleranceLngLat / tolerance : 0;
226
- const screen = this.hitTestAnchorsInScreenSpace(screenPoint, orderedFeatures, tolerance, degPerPx, selectable);
267
+ const screen = this.hitTestAnchorsInScreenSpace(screenPoint, orderedFeatures, tolerance, tolerance > 0 ? toleranceLngLat / tolerance : 0, selectable);
227
268
  // Stage 2: the precise test
228
269
  const results = screen ? [...screen.results] : [];
229
270
  for (const feature of visibleCandidates) {
@@ -238,6 +279,9 @@ export class HitTestServiceImpl {
238
279
  // nearest hit counts. It is tested in the shape it is drawn with (the result keeps the
239
280
  // stored feature)
240
281
  const shape = this.drawnShape(feature);
282
+ // What is drawn beyond the geometry (the marker of a point) is hit as well
283
+ const reachPx = strategy.reachPx?.(feature) ?? 0;
284
+ const featureTolerance = reachPx > 0 ? toleranceLngLat + reachPx * degPerPx() : toleranceLngLat;
241
285
  let best = null;
242
286
  for (let i = 0; i < copies.length; i++) {
243
287
  if (!candidatesByCopy[i].has(feature.id))
@@ -247,9 +291,9 @@ export class HitTestServiceImpl {
247
291
  // A strategy that has testDistance finishes the test and the distance computation in
248
292
  // a single scan
249
293
  if (strategy.testDistance) {
250
- distance = strategy.testDistance(shape, copy, toleranceLngLat);
294
+ distance = strategy.testDistance(shape, copy, featureTolerance);
251
295
  }
252
- else if (strategy.test(shape, copy, toleranceLngLat)) {
296
+ else if (strategy.test(shape, copy, featureTolerance)) {
253
297
  distance = strategy.distance(shape, copy);
254
298
  }
255
299
  if (distance !== null && (best === null || distance < best))
@@ -289,10 +333,12 @@ export class HitTestServiceImpl {
289
333
  continue;
290
334
  if (!selectable(feature))
291
335
  continue;
292
- const reachPx = tolerancePx + this.candidateReachPx(feature.type);
336
+ const reachPx = tolerancePx +
337
+ this.candidateReachPx(feature.type) +
338
+ (this.registry.get(feature.type)?.reachPx?.(feature) ?? 0);
293
339
  const parts = feature.type === 'MultiPoint'
294
- ? feature.coordinates
295
- : [feature.coordinates];
340
+ ? coordinatesOf(feature)
341
+ : [coordinatesOf(feature)];
296
342
  let nearest = Number.POSITIVE_INFINITY;
297
343
  for (const coord of parts) {
298
344
  const point = projector.project(coord);
@@ -331,3 +377,21 @@ export class HitTestServiceImpl {
331
377
  return strategy.test(this.drawnShape(feature), coordinate, toleranceLngLat);
332
378
  }
333
379
  }
380
+ /**
381
+ * A built-in strategy that reaches as far as the feature is drawn (`HitTestStrategy.reachPx`)
382
+ *
383
+ * Without a reach the strategy is returned as it is.
384
+ */
385
+ function withReach(strategy, reachPx) {
386
+ if (!reachPx)
387
+ return strategy;
388
+ return {
389
+ geometryType: strategy.geometryType,
390
+ test: (feature, coordinate, tolerance) => strategy.test(feature, coordinate, tolerance),
391
+ distance: (feature, coordinate) => strategy.distance(feature, coordinate),
392
+ ...(strategy.testDistance && {
393
+ testDistance: (feature, coordinate, tolerance) => strategy.testDistance?.(feature, coordinate, tolerance) ?? null,
394
+ }),
395
+ reachPx,
396
+ };
397
+ }
@@ -51,7 +51,7 @@ export interface HitTestOptions {
51
51
  export declare const DEFAULT_HIT_TEST_OPTIONS: HitTestOptions;
52
52
  /**
53
53
  * The precise hit test of one feature type, as registered through the `hitTest` of a
54
- * `CustomFeatureHandler`.
54
+ * `FeatureTypeHandler`.
55
55
  *
56
56
  * The library first narrows the candidates with its spatial index and then calls `test` on
57
57
  * each candidate from the front; the first that returns `true` receives the click. The
@@ -60,24 +60,6 @@ export declare const DEFAULT_HIT_TEST_OPTIONS: HitTestOptions;
60
60
  * difference, divide it by cos φ of the click latitude (or multiply the tolerance by cos φ):
61
61
  * one degree of latitude is 1 / cos φ times longer on screen than one degree of longitude.
62
62
  * Distances are returned in the same unit.
63
- *
64
- * @example
65
- * ```ts
66
- * import type { HitTestStrategy } from '@sakuzu/maplibre-gl-draw';
67
- *
68
- * // A marker type hit within the tolerance around its single position
69
- * const markerHitTest: HitTestStrategy = {
70
- * geometryType: 'Marker',
71
- * test(feature, [lng, lat], tolerance) {
72
- * return this.distance(feature, [lng, lat]) <= tolerance;
73
- * },
74
- * distance(feature, [lng, lat]) {
75
- * const [x, y] = feature.coordinates as [number, number];
76
- * const cos = Math.cos((lat * Math.PI) / 180);
77
- * return Math.hypot(x - lng, (y - lat) / cos);
78
- * },
79
- * };
80
- * ```
81
63
  */
82
64
  export interface HitTestStrategy {
83
65
  /** The feature type this strategy tests; a registration replaces the one for the type */
@@ -112,6 +94,18 @@ export interface HitTestStrategy {
112
94
  * @returns The distance (same unit) if within the tolerance, null if outside
113
95
  */
114
96
  testDistance?(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): number | null;
97
+ /**
98
+ * How far beyond its geometry the feature is drawn, in CSS pixels (the radius of the marker
99
+ * of a point)
100
+ *
101
+ * The service adds it to the tolerance it hands to `test` for this feature, and widens the
102
+ * candidate search by it, so that a click on what is drawn hits the feature. Without it,
103
+ * the feature is hit within the tolerance of its geometry alone.
104
+ *
105
+ * @param feature The feature to test
106
+ * @returns The reach in CSS pixels (0 or more)
107
+ */
108
+ reachPx?(feature: Feature): number;
115
109
  }
116
110
  /**
117
111
  * Hit testing strategy registry
@@ -7,6 +7,7 @@
7
7
  * It tests whether the distance from the center is within the radius.
8
8
  */
9
9
  import { haversineDistanceMeters, metersToLng } from '../../../shared/math/index.js';
10
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
10
11
  import { getCircleRadius } from '../../../shared/utils/property.js';
11
12
  /**
12
13
  * Hit testing strategy for the Circle type
@@ -21,7 +22,7 @@ export class CircleHitTestStrategy {
21
22
  });
22
23
  }
23
24
  test(feature, coordinate, toleranceLngLat) {
24
- const center = feature.coordinates;
25
+ const center = coordinatesOf(feature);
25
26
  const radiusMeters = getCircleRadius(feature);
26
27
  if (radiusMeters === undefined || radiusMeters <= 0) {
27
28
  return false;
@@ -39,7 +40,7 @@ export class CircleHitTestStrategy {
39
40
  return distanceMeters <= radiusMeters + effectiveTolerance;
40
41
  }
41
42
  distance(feature, coordinate) {
42
- const center = feature.coordinates;
43
+ const center = coordinatesOf(feature);
43
44
  const radiusMeters = getCircleRadius(feature);
44
45
  if (radiusMeters === undefined || radiusMeters <= 0) {
45
46
  return Number.POSITIVE_INFINITY;
@@ -7,18 +7,8 @@
7
7
  * It tests using an OBB (Oriented Bounding Box).
8
8
  */
9
9
  import { createOBB, DEFAULT_TILE_SIZE, distanceToOBB, getMetersPerPixel, metersToDegreesLat, metersToDegreesLng, } from '../../../shared/math/index.js';
10
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
10
11
  import { getImageProperties } from '../../../shared/utils/property.js';
11
- /**
12
- * Default image style
13
- * width/height: 0 = use the original size (the same as ImageRenderer)
14
- */
15
- const DEFAULT_IMAGE_STYLE = {
16
- width: 0,
17
- height: 0,
18
- rotation: 0,
19
- opacity: 1.0,
20
- imageOpacity: 1,
21
- };
22
12
  /**
23
13
  * ImageHitTestStrategy
24
14
  */
@@ -88,17 +78,15 @@ export class ImageHitTestStrategy {
88
78
  const properties = getImageProperties(feature);
89
79
  if (!properties.imageFileId)
90
80
  return null;
91
- const coord = feature.coordinates;
81
+ const coord = coordinatesOf(feature);
92
82
  const latitude = coord[1];
93
- const style = { ...DEFAULT_IMAGE_STYLE, ...feature.style };
94
83
  // Get the image size (the same logic as ImageRenderer)
95
84
  // The size stored in ImageProperties takes precedence
96
85
  // 100 is used as the fallback (for when the image has not been loaded)
97
86
  const imageWidth = properties.imageWidth || 100;
98
87
  const imageHeight = properties.imageHeight || 100;
99
- // Use the size specified by the style, or the original size
100
- const displayWidth = style.width || imageWidth;
101
- const displayHeight = style.height || imageHeight;
88
+ const displayWidth = imageWidth;
89
+ const displayHeight = imageHeight;
102
90
  // Compute the size based on the display at createdZoom
103
91
  const createdZoom = properties.createdZoom || 14;
104
92
  const scale = properties.scale || 1;
@@ -108,8 +96,8 @@ export class ImageHitTestStrategy {
108
96
  // Convert meters to degrees
109
97
  const widthDeg = metersToDegreesLng(widthMeters, latitude);
110
98
  const heightDeg = metersToDegreesLat(heightMeters);
111
- // Rotation angle (the sum of both the style and the properties)
112
- const rotation = (style.rotation || 0) + (properties.rotation || 0);
99
+ // Rotation angle
100
+ const rotation = properties.rotation || 0;
113
101
  return { center: coord, widthDeg, heightDeg, rotation };
114
102
  }
115
103
  }
@@ -1,9 +1,3 @@
1
- /**
2
- * LineHitTestStrategy
3
- *
4
- * Hit testing strategy for LineString features.
5
- * Distances are measured in the local frame of hit testing (local-frame.ts).
6
- */
7
1
  import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
8
2
  import type { HitTestStrategy } from './base.js';
9
3
  /**
@@ -1,5 +1,12 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * LineHitTestStrategy
5
+ *
6
+ * Hit testing strategy for LineString features.
7
+ * Distances are measured in the local frame of hit testing (local-frame.ts).
8
+ */
9
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
3
10
  import { latitudeScale, localPointToPolylineDistance } from '../local-frame.js';
4
11
  import { polylineDistanceWithin } from '../segment-grid.js';
5
12
  /**
@@ -18,13 +25,13 @@ export class LineHitTestStrategy {
18
25
  return this.testDistance(feature, coordinate, toleranceLngLat) !== null;
19
26
  }
20
27
  distance(feature, coordinate) {
21
- const lineCoords = feature.coordinates;
28
+ const lineCoords = coordinatesOf(feature);
22
29
  // The nearest distance without a tolerance cannot be answered by the index, so this
23
30
  // stays a full scan
24
31
  return localPointToPolylineDistance(coordinate, lineCoords, latitudeScale(coordinate[1]));
25
32
  }
26
33
  testDistance(feature, coordinate, toleranceLngLat) {
27
- const lineCoords = feature.coordinates;
34
+ const lineCoords = coordinatesOf(feature);
28
35
  return polylineDistanceWithin(lineCoords, coordinate, toleranceLngLat, latitudeScale(coordinate[1]));
29
36
  }
30
37
  }
@@ -1,11 +1,3 @@
1
- /**
2
- * Hit testing strategies for the Multi geometries
3
- *
4
- * MultiPoint / MultiLineString / MultiPolygon are tested as "a hit if any part is hit"
5
- * and "the distance is the minimum over the parts". The test logic itself reuses the
6
- * strategy of the single geometry for each part. Distances are measured in the local frame
7
- * of hit testing (local-frame.ts).
8
- */
9
1
  import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
10
2
  import type { HitTestStrategy } from './base.js';
11
3
  /**
@@ -1,5 +1,14 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Hit testing strategies for the Multi geometries
5
+ *
6
+ * MultiPoint / MultiLineString / MultiPolygon are tested as "a hit if any part is hit"
7
+ * and "the distance is the minimum over the parts". The test logic itself reuses the
8
+ * strategy of the single geometry for each part. Distances are measured in the local frame
9
+ * of hit testing (local-frame.ts).
10
+ */
11
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
3
12
  import { latitudeScale, localDistance, localPointToPolylineDistance } from '../local-frame.js';
4
13
  import { polylineDistanceWithin } from '../segment-grid.js';
5
14
  import { PolygonHitTestStrategy } from './polygon.js';
@@ -18,7 +27,7 @@ export class MultiPointHitTestStrategy {
18
27
  });
19
28
  }
20
29
  test(feature, coordinate, toleranceLngLat) {
21
- const parts = feature.coordinates;
30
+ const parts = coordinatesOf(feature);
22
31
  const latScale = latitudeScale(coordinate[1]);
23
32
  for (const part of parts) {
24
33
  if (localDistance(coordinate, part, latScale) <= toleranceLngLat) {
@@ -28,7 +37,7 @@ export class MultiPointHitTestStrategy {
28
37
  return false;
29
38
  }
30
39
  distance(feature, coordinate) {
31
- const parts = feature.coordinates;
40
+ const parts = coordinatesOf(feature);
32
41
  const latScale = latitudeScale(coordinate[1]);
33
42
  let min = Number.POSITIVE_INFINITY;
34
43
  for (const part of parts) {
@@ -52,7 +61,7 @@ export class MultiLineStringHitTestStrategy {
52
61
  });
53
62
  }
54
63
  test(feature, coordinate, toleranceLngLat) {
55
- const parts = feature.coordinates;
64
+ const parts = coordinatesOf(feature);
56
65
  const latScale = latitudeScale(coordinate[1]);
57
66
  for (const part of parts) {
58
67
  if (part.length === 0)
@@ -64,7 +73,7 @@ export class MultiLineStringHitTestStrategy {
64
73
  return false;
65
74
  }
66
75
  distance(feature, coordinate) {
67
- const parts = feature.coordinates;
76
+ const parts = coordinatesOf(feature);
68
77
  const latScale = latitudeScale(coordinate[1]);
69
78
  let min = Number.POSITIVE_INFINITY;
70
79
  for (const part of parts) {
@@ -75,7 +84,7 @@ export class MultiLineStringHitTestStrategy {
75
84
  return min;
76
85
  }
77
86
  testDistance(feature, coordinate, toleranceLngLat) {
78
- const parts = feature.coordinates;
87
+ const parts = coordinatesOf(feature);
79
88
  const latScale = latitudeScale(coordinate[1]);
80
89
  let min = Number.POSITIVE_INFINITY;
81
90
  for (const part of parts) {
@@ -111,7 +120,7 @@ export class MultiPolygonHitTestStrategy {
111
120
  });
112
121
  }
113
122
  test(feature, coordinate, toleranceLngLat) {
114
- const parts = feature.coordinates;
123
+ const parts = coordinatesOf(feature);
115
124
  for (const rings of parts) {
116
125
  if (this.polygonStrategy.testRings(rings, coordinate, toleranceLngLat)) {
117
126
  return true;
@@ -120,7 +129,7 @@ export class MultiPolygonHitTestStrategy {
120
129
  return false;
121
130
  }
122
131
  distance(feature, coordinate) {
123
- const parts = feature.coordinates;
132
+ const parts = coordinatesOf(feature);
124
133
  let min = Number.POSITIVE_INFINITY;
125
134
  for (const rings of parts) {
126
135
  min = Math.min(min, this.polygonStrategy.distanceToRings(rings, coordinate));
@@ -128,7 +137,7 @@ export class MultiPolygonHitTestStrategy {
128
137
  return min;
129
138
  }
130
139
  testDistance(feature, coordinate, toleranceLngLat) {
131
- const parts = feature.coordinates;
140
+ const parts = coordinatesOf(feature);
132
141
  let min = Number.POSITIVE_INFINITY;
133
142
  for (const rings of parts) {
134
143
  const distance = this.polygonStrategy.testDistanceRings(rings, coordinate, toleranceLngLat);
@@ -4,17 +4,19 @@
4
4
  * Hit testing strategy for Point features.
5
5
  * Distances are measured in the local frame of hit testing (local-frame.ts).
6
6
  */
7
- import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
8
- import type { HitTestStrategy } from './base.js';
7
+ import type { Feature, FeatureType } from '../../../api/model.js';
9
8
  /**
10
9
  * The built-in hit test of `Point` features: hit within the tolerance of the position.
11
10
  *
12
- * The distance is measured in the local frame of the click (see {@link HitTestStrategy}).
13
- * A custom type drawn as a point can reuse it, or extend it to widen the hit area.
11
+ * The distance is measured in a local frame around the click, where a degree of longitude is
12
+ * scaled by the cosine of the latitude. A feature type drawn as a point can reuse it, or
13
+ * extend it to widen the hit area. The engine uses it as the hit test of its points.
14
14
  */
15
- export declare class PointHitTestStrategy implements HitTestStrategy {
15
+ export declare class PointHitTestStrategy {
16
16
  /** The feature type, `'Point'` */
17
17
  readonly geometryType: FeatureType;
18
- test(feature: Feature, coordinate: Coordinate, toleranceLngLat: number): boolean;
19
- distance(feature: Feature, coordinate: Coordinate): number;
18
+ /** Whether the feature is within `toleranceLngLat` degrees of the coordinate */
19
+ test(feature: Feature, coordinate: [number, number], toleranceLngLat: number): boolean;
20
+ /** The distance from the coordinate to the feature, in degrees of the local frame */
21
+ distance(feature: Feature, coordinate: [number, number]): number;
20
22
  }
@@ -1,11 +1,13 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
3
4
  import { latitudeScale, localDistance } from '../local-frame.js';
4
5
  /**
5
6
  * The built-in hit test of `Point` features: hit within the tolerance of the position.
6
7
  *
7
- * The distance is measured in the local frame of the click (see {@link HitTestStrategy}).
8
- * A custom type drawn as a point can reuse it, or extend it to widen the hit area.
8
+ * The distance is measured in a local frame around the click, where a degree of longitude is
9
+ * scaled by the cosine of the latitude. A feature type drawn as a point can reuse it, or
10
+ * extend it to widen the hit area. The engine uses it as the hit test of its points.
9
11
  */
10
12
  export class PointHitTestStrategy {
11
13
  constructor() {
@@ -17,13 +19,15 @@ export class PointHitTestStrategy {
17
19
  value: 'Point'
18
20
  });
19
21
  }
22
+ /** Whether the feature is within `toleranceLngLat` degrees of the coordinate */
20
23
  test(feature, coordinate, toleranceLngLat) {
21
- const pointCoord = feature.coordinates;
24
+ const pointCoord = coordinatesOf(feature);
22
25
  const dist = localDistance(coordinate, pointCoord, latitudeScale(coordinate[1]));
23
26
  return dist <= toleranceLngLat;
24
27
  }
28
+ /** The distance from the coordinate to the feature, in degrees of the local frame */
25
29
  distance(feature, coordinate) {
26
- const pointCoord = feature.coordinates;
30
+ const pointCoord = coordinatesOf(feature);
27
31
  return localDistance(coordinate, pointCoord, latitudeScale(coordinate[1]));
28
32
  }
29
33
  }
@@ -1,10 +1,3 @@
1
- /**
2
- * PolygonHitTestStrategy
3
- *
4
- * Hit testing strategy for Polygon features.
5
- * Distances to the edges are measured in the local frame of hit testing (local-frame.ts).
6
- * The inside test is unaffected by that frame (it only scales the latitude axis).
7
- */
8
1
  import type { Coordinate, Feature, FeatureType } from '../../../store/types.js';
9
2
  import type { HitTestStrategy } from './base.js';
10
3
  /**
@@ -1,5 +1,13 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * PolygonHitTestStrategy
5
+ *
6
+ * Hit testing strategy for Polygon features.
7
+ * Distances to the edges are measured in the local frame of hit testing (local-frame.ts).
8
+ * The inside test is unaffected by that frame (it only scales the latitude axis).
9
+ */
10
+ import { coordinatesOf } from '../../../shared/utils/coordinates.js';
3
11
  import { latitudeScale, localPointToSegmentDistance } from '../local-frame.js';
4
12
  import { polylineDistanceWithin } from '../segment-grid.js';
5
13
  /**
@@ -15,15 +23,15 @@ export class PolygonHitTestStrategy {
15
23
  });
16
24
  }
17
25
  test(feature, coordinate, toleranceLngLat) {
18
- const rings = feature.coordinates;
26
+ const rings = coordinatesOf(feature);
19
27
  return this.testRings(rings, coordinate, toleranceLngLat);
20
28
  }
21
29
  distance(feature, coordinate) {
22
- const rings = feature.coordinates;
30
+ const rings = coordinatesOf(feature);
23
31
  return this.distanceToRings(rings, coordinate);
24
32
  }
25
33
  testDistance(feature, coordinate, toleranceLngLat) {
26
- const rings = feature.coordinates;
34
+ const rings = coordinatesOf(feature);
27
35
  return this.testDistanceRings(rings, coordinate, toleranceLngLat);
28
36
  }
29
37
  /**
@@ -1,4 +1,4 @@
1
- import type { Dataset } from '../../display/types.js';
1
+ import type { Dataset } from '../../dataset/types.js';
2
2
  import type { ScreenPoint } from '../../shared/math/index.js';
3
3
  import type { Feature } from '../../store/types.js';
4
4
  import type { FeatureCompanionHitResult } from '../../view/feature-companion.js';