@sakuzu/maplibre-gl-draw 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +661 -0
  3. package/README.ja.md +248 -0
  4. package/README.md +255 -0
  5. package/THIRD_PARTY_NOTICES.md +275 -0
  6. package/dist/api/api.d.ts +1259 -0
  7. package/dist/api/api.js +86 -0
  8. package/dist/api/context.d.ts +173 -0
  9. package/dist/api/context.js +193 -0
  10. package/dist/api/display-api.d.ts +1 -0
  11. package/dist/api/display-api.js +23 -0
  12. package/dist/api/event-api.d.ts +13 -0
  13. package/dist/api/event-api.js +17 -0
  14. package/dist/api/extension-api.d.ts +46 -0
  15. package/dist/api/extension-api.js +85 -0
  16. package/dist/api/feature-api.d.ts +11 -0
  17. package/dist/api/feature-api.js +101 -0
  18. package/dist/api/geometry/apply.d.ts +51 -0
  19. package/dist/api/geometry/apply.js +114 -0
  20. package/dist/api/geometry/boolean.d.ts +28 -0
  21. package/dist/api/geometry/boolean.js +65 -0
  22. package/dist/api/geometry/buffer.d.ts +11 -0
  23. package/dist/api/geometry/buffer.js +105 -0
  24. package/dist/api/geometry/split.d.ts +16 -0
  25. package/dist/api/geometry/split.js +75 -0
  26. package/dist/api/geometry/targets.d.ts +76 -0
  27. package/dist/api/geometry/targets.js +158 -0
  28. package/dist/api/geometry/types.d.ts +31 -0
  29. package/dist/api/geometry/types.js +3 -0
  30. package/dist/api/geometry-operations.d.ts +162 -0
  31. package/dist/api/geometry-operations.js +94 -0
  32. package/dist/api/group-api.d.ts +10 -0
  33. package/dist/api/group-api.js +78 -0
  34. package/dist/api/import-export/constants.d.ts +29 -0
  35. package/dist/api/import-export/constants.js +40 -0
  36. package/dist/api/import-export/embedded-file.d.ts +13 -0
  37. package/dist/api/import-export/embedded-file.js +31 -0
  38. package/dist/api/import-export/file-name.d.ts +10 -0
  39. package/dist/api/import-export/file-name.js +20 -0
  40. package/dist/api/import-export/format-detection.d.ts +12 -0
  41. package/dist/api/import-export/format-detection.js +29 -0
  42. package/dist/api/import-export/geojson-export.d.ts +19 -0
  43. package/dist/api/import-export/geojson-export.js +262 -0
  44. package/dist/api/import-export/geojson-import.d.ts +34 -0
  45. package/dist/api/import-export/geojson-import.js +538 -0
  46. package/dist/api/import-export/geometry-validation.d.ts +20 -0
  47. package/dist/api/import-export/geometry-validation.js +107 -0
  48. package/dist/api/import-export/image-import.d.ts +12 -0
  49. package/dist/api/import-export/image-import.js +53 -0
  50. package/dist/api/import-export/index.d.ts +9 -0
  51. package/dist/api/import-export/index.js +107 -0
  52. package/dist/api/import-export/native-format.d.ts +15 -0
  53. package/dist/api/import-export/native-format.js +126 -0
  54. package/dist/api/import-export/native-validation.d.ts +28 -0
  55. package/dist/api/import-export/native-validation.js +212 -0
  56. package/dist/api/import-export/own-property.d.ts +10 -0
  57. package/dist/api/import-export/own-property.js +19 -0
  58. package/dist/api/import-export/style-validation.d.ts +27 -0
  59. package/dist/api/import-export/style-validation.js +49 -0
  60. package/dist/api/import-export/types.d.ts +26 -0
  61. package/dist/api/import-export/types.js +3 -0
  62. package/dist/api/index.d.ts +15 -0
  63. package/dist/api/index.js +3 -0
  64. package/dist/api/input-api.d.ts +158 -0
  65. package/dist/api/input-api.js +144 -0
  66. package/dist/api/instance-api.d.ts +38 -0
  67. package/dist/api/instance-api.js +136 -0
  68. package/dist/api/layer-api.d.ts +12 -0
  69. package/dist/api/layer-api.js +62 -0
  70. package/dist/api/selection-api.d.ts +7 -0
  71. package/dist/api/selection-api.js +78 -0
  72. package/dist/api/snapping-api.d.ts +125 -0
  73. package/dist/api/snapping-api.js +50 -0
  74. package/dist/api/topology-api.d.ts +30 -0
  75. package/dist/api/topology-api.js +16 -0
  76. package/dist/api/tracing-api.d.ts +31 -0
  77. package/dist/api/tracing-api.js +16 -0
  78. package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
  79. package/dist/dispatcher/hit-test/box-strategies.js +275 -0
  80. package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
  81. package/dist/dispatcher/hit-test/box-strategy.js +37 -0
  82. package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
  83. package/dist/dispatcher/hit-test/globe-shape.js +70 -0
  84. package/dist/dispatcher/hit-test/index.d.ts +14 -0
  85. package/dist/dispatcher/hit-test/index.js +9 -0
  86. package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
  87. package/dist/dispatcher/hit-test/local-frame.js +112 -0
  88. package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
  89. package/dist/dispatcher/hit-test/segment-grid.js +79 -0
  90. package/dist/dispatcher/hit-test/service.d.ts +120 -0
  91. package/dist/dispatcher/hit-test/service.js +333 -0
  92. package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
  93. package/dist/dispatcher/hit-test/strategies/base.js +66 -0
  94. package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
  95. package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
  96. package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
  97. package/dist/dispatcher/hit-test/strategies/image.js +115 -0
  98. package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
  99. package/dist/dispatcher/hit-test/strategies/index.js +10 -0
  100. package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
  101. package/dist/dispatcher/hit-test/strategies/line.js +30 -0
  102. package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
  103. package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
  104. package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
  105. package/dist/dispatcher/hit-test/strategies/point.js +29 -0
  106. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
  107. package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
  108. package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
  109. package/dist/dispatcher/hit-test/topmost.js +157 -0
  110. package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
  111. package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
  112. package/dist/dispatcher/index.d.ts +15 -0
  113. package/dist/dispatcher/index.js +3 -0
  114. package/dist/dispatcher/input-router.d.ts +1 -0
  115. package/dist/dispatcher/input-router.js +288 -0
  116. package/dist/dispatcher/normalizer.d.ts +1 -0
  117. package/dist/dispatcher/normalizer.js +513 -0
  118. package/dist/dispatcher/types.d.ts +144 -0
  119. package/dist/dispatcher/types.js +15 -0
  120. package/dist/display/chunk-set.d.ts +24 -0
  121. package/dist/display/chunk-set.js +533 -0
  122. package/dist/display/chunk.d.ts +1 -0
  123. package/dist/display/chunk.js +104 -0
  124. package/dist/display/columnar/index.d.ts +12 -0
  125. package/dist/display/columnar/index.js +13 -0
  126. package/dist/display/columnar/prepare.d.ts +42 -0
  127. package/dist/display/columnar/prepare.js +116 -0
  128. package/dist/display/columnar/source.d.ts +1 -0
  129. package/dist/display/columnar/source.js +531 -0
  130. package/dist/display/columnar/table.d.ts +1 -0
  131. package/dist/display/columnar/table.js +471 -0
  132. package/dist/display/columnar/types.d.ts +223 -0
  133. package/dist/display/columnar/types.js +3 -0
  134. package/dist/display/dataset.d.ts +2 -0
  135. package/dist/display/dataset.js +891 -0
  136. package/dist/display/index.d.ts +13 -0
  137. package/dist/display/index.js +3 -0
  138. package/dist/display/interaction.d.ts +1 -0
  139. package/dist/display/interaction.js +90 -0
  140. package/dist/display/manager.d.ts +1 -0
  141. package/dist/display/manager.js +440 -0
  142. package/dist/display/packed-rtree.d.ts +1 -0
  143. package/dist/display/packed-rtree.js +244 -0
  144. package/dist/display/partition.d.ts +1 -0
  145. package/dist/display/partition.js +226 -0
  146. package/dist/display/provider.d.ts +1 -0
  147. package/dist/display/provider.js +342 -0
  148. package/dist/display/retained.d.ts +40 -0
  149. package/dist/display/retained.js +898 -0
  150. package/dist/display/selection.d.ts +13 -0
  151. package/dist/display/selection.js +226 -0
  152. package/dist/display/source.d.ts +1 -0
  153. package/dist/display/source.js +119 -0
  154. package/dist/display/spatial.d.ts +1 -0
  155. package/dist/display/spatial.js +71 -0
  156. package/dist/display/style.d.ts +1 -0
  157. package/dist/display/style.js +126 -0
  158. package/dist/display/thinning.d.ts +65 -0
  159. package/dist/display/thinning.js +910 -0
  160. package/dist/display/triangulation.d.ts +1 -0
  161. package/dist/display/triangulation.js +0 -0
  162. package/dist/display/types.d.ts +561 -0
  163. package/dist/display/types.js +43 -0
  164. package/dist/extension/feature-handler.d.ts +182 -0
  165. package/dist/extension/feature-handler.js +3 -0
  166. package/dist/extension/index.d.ts +9 -0
  167. package/dist/extension/index.js +3 -0
  168. package/dist/extension/renderers.d.ts +208 -0
  169. package/dist/extension/renderers.js +3 -0
  170. package/dist/geometry/angle.d.ts +47 -0
  171. package/dist/geometry/angle.js +44 -0
  172. package/dist/geometry/bbox.d.ts +48 -0
  173. package/dist/geometry/bbox.js +83 -0
  174. package/dist/geometry/boolean.d.ts +162 -0
  175. package/dist/geometry/boolean.js +331 -0
  176. package/dist/geometry/buffer.d.ts +72 -0
  177. package/dist/geometry/buffer.js +218 -0
  178. package/dist/geometry/circle.d.ts +55 -0
  179. package/dist/geometry/circle.js +107 -0
  180. package/dist/geometry/coords.d.ts +97 -0
  181. package/dist/geometry/coords.js +149 -0
  182. package/dist/geometry/distance.d.ts +79 -0
  183. package/dist/geometry/distance.js +111 -0
  184. package/dist/geometry/errors.d.ts +74 -0
  185. package/dist/geometry/errors.js +104 -0
  186. package/dist/geometry/index.d.ts +28 -0
  187. package/dist/geometry/index.js +38 -0
  188. package/dist/geometry/measure.d.ts +81 -0
  189. package/dist/geometry/measure.js +236 -0
  190. package/dist/geometry/predicates.d.ts +62 -0
  191. package/dist/geometry/predicates.js +132 -0
  192. package/dist/geometry/simplify.d.ts +74 -0
  193. package/dist/geometry/simplify.js +159 -0
  194. package/dist/geometry/split.d.ts +68 -0
  195. package/dist/geometry/split.js +430 -0
  196. package/dist/geometry/types.d.ts +95 -0
  197. package/dist/geometry/types.js +3 -0
  198. package/dist/geometry/units.d.ts +35 -0
  199. package/dist/geometry/units.js +41 -0
  200. package/dist/index.d.ts +72 -0
  201. package/dist/index.js +20 -0
  202. package/dist/maplibre-gl-draw.d.ts +47 -0
  203. package/dist/maplibre-gl-draw.js +407 -0
  204. package/dist/messages.d.ts +64 -0
  205. package/dist/messages.js +36 -0
  206. package/dist/modes/cursor.d.ts +1 -0
  207. package/dist/modes/cursor.js +72 -0
  208. package/dist/modes/draw/circle.d.ts +1 -0
  209. package/dist/modes/draw/circle.js +222 -0
  210. package/dist/modes/draw/commit-layer.d.ts +26 -0
  211. package/dist/modes/draw/commit-layer.js +31 -0
  212. package/dist/modes/draw/freehand.d.ts +1 -0
  213. package/dist/modes/draw/freehand.js +264 -0
  214. package/dist/modes/draw/image.d.ts +1 -0
  215. package/dist/modes/draw/image.js +60 -0
  216. package/dist/modes/draw/index.d.ts +9 -0
  217. package/dist/modes/draw/index.js +11 -0
  218. package/dist/modes/draw/line.d.ts +1 -0
  219. package/dist/modes/draw/line.js +363 -0
  220. package/dist/modes/draw/point.d.ts +1 -0
  221. package/dist/modes/draw/point.js +87 -0
  222. package/dist/modes/draw/polygon.d.ts +1 -0
  223. package/dist/modes/draw/polygon.js +378 -0
  224. package/dist/modes/draw/trace-support.d.ts +79 -0
  225. package/dist/modes/draw/trace-support.js +161 -0
  226. package/dist/modes/handler.d.ts +285 -0
  227. package/dist/modes/handler.js +3 -0
  228. package/dist/modes/index.d.ts +7 -0
  229. package/dist/modes/index.js +3 -0
  230. package/dist/modes/manager.d.ts +15 -0
  231. package/dist/modes/manager.js +196 -0
  232. package/dist/modes/select/box-selection.d.ts +52 -0
  233. package/dist/modes/select/box-selection.js +140 -0
  234. package/dist/modes/select/click-handler.d.ts +32 -0
  235. package/dist/modes/select/click-handler.js +166 -0
  236. package/dist/modes/select/cursor-handler.d.ts +15 -0
  237. package/dist/modes/select/cursor-handler.js +59 -0
  238. package/dist/modes/select/drag/auxiliary.d.ts +26 -0
  239. package/dist/modes/select/drag/auxiliary.js +56 -0
  240. package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
  241. package/dist/modes/select/drag/intermediate-writes.js +171 -0
  242. package/dist/modes/select/drag/move.d.ts +24 -0
  243. package/dist/modes/select/drag/move.js +59 -0
  244. package/dist/modes/select/drag/operation.d.ts +30 -0
  245. package/dist/modes/select/drag/operation.js +18 -0
  246. package/dist/modes/select/drag/radius.d.ts +15 -0
  247. package/dist/modes/select/drag/radius.js +49 -0
  248. package/dist/modes/select/drag/transform.d.ts +17 -0
  249. package/dist/modes/select/drag/transform.js +155 -0
  250. package/dist/modes/select/drag/vertex.d.ts +17 -0
  251. package/dist/modes/select/drag/vertex.js +163 -0
  252. package/dist/modes/select/drag-handler.d.ts +1 -0
  253. package/dist/modes/select/drag-handler.js +254 -0
  254. package/dist/modes/select/hit-helpers.d.ts +40 -0
  255. package/dist/modes/select/hit-helpers.js +51 -0
  256. package/dist/modes/select/mode.d.ts +1 -0
  257. package/dist/modes/select/mode.js +397 -0
  258. package/dist/modes/select/shortcut-handler.d.ts +40 -0
  259. package/dist/modes/select/shortcut-handler.js +128 -0
  260. package/dist/operations/index.d.ts +9 -0
  261. package/dist/operations/index.js +3 -0
  262. package/dist/operations/layer-operations.d.ts +1 -0
  263. package/dist/operations/layer-operations.js +350 -0
  264. package/dist/operations/resize.d.ts +71 -0
  265. package/dist/operations/resize.js +252 -0
  266. package/dist/operations/rotate.d.ts +17 -0
  267. package/dist/operations/rotate.js +166 -0
  268. package/dist/operations/selection-operations.d.ts +20 -0
  269. package/dist/operations/selection-operations.js +159 -0
  270. package/dist/operations/shared-vertex.d.ts +1 -0
  271. package/dist/operations/shared-vertex.js +210 -0
  272. package/dist/operations/trace-graph.d.ts +96 -0
  273. package/dist/operations/trace-graph.js +283 -0
  274. package/dist/operations/vertex.d.ts +1 -0
  275. package/dist/operations/vertex.js +538 -0
  276. package/dist/plugins/index.d.ts +10 -0
  277. package/dist/plugins/index.js +3 -0
  278. package/dist/plugins/mutation-hooks.d.ts +28 -0
  279. package/dist/plugins/mutation-hooks.js +84 -0
  280. package/dist/plugins/plugin-context.d.ts +1 -0
  281. package/dist/plugins/plugin-context.js +367 -0
  282. package/dist/plugins/plugin-manager.d.ts +103 -0
  283. package/dist/plugins/plugin-manager.js +316 -0
  284. package/dist/plugins/plugin.d.ts +529 -0
  285. package/dist/plugins/plugin.js +3 -0
  286. package/dist/shared/config/constants.d.ts +66 -0
  287. package/dist/shared/config/constants.js +60 -0
  288. package/dist/shared/config/feature-style.d.ts +155 -0
  289. package/dist/shared/config/feature-style.js +154 -0
  290. package/dist/shared/config/index.d.ts +17 -0
  291. package/dist/shared/config/index.js +8 -0
  292. package/dist/shared/config/rendering.d.ts +107 -0
  293. package/dist/shared/config/rendering.js +33 -0
  294. package/dist/shared/config/selection-highlight.d.ts +29 -0
  295. package/dist/shared/config/selection-highlight.js +35 -0
  296. package/dist/shared/config/selection.d.ts +273 -0
  297. package/dist/shared/config/selection.js +266 -0
  298. package/dist/shared/config/topology.d.ts +33 -0
  299. package/dist/shared/config/topology.js +17 -0
  300. package/dist/shared/config/trace.d.ts +40 -0
  301. package/dist/shared/config/trace.js +17 -0
  302. package/dist/shared/math/angle.d.ts +21 -0
  303. package/dist/shared/math/angle.js +34 -0
  304. package/dist/shared/math/circle.d.ts +6 -0
  305. package/dist/shared/math/circle.js +10 -0
  306. package/dist/shared/math/constants.d.ts +48 -0
  307. package/dist/shared/math/constants.js +59 -0
  308. package/dist/shared/math/distance.d.ts +78 -0
  309. package/dist/shared/math/distance.js +147 -0
  310. package/dist/shared/math/globe-subdivision.d.ts +62 -0
  311. package/dist/shared/math/globe-subdivision.js +99 -0
  312. package/dist/shared/math/index.d.ts +17 -0
  313. package/dist/shared/math/index.js +21 -0
  314. package/dist/shared/math/intersection.d.ts +63 -0
  315. package/dist/shared/math/intersection.js +236 -0
  316. package/dist/shared/math/longitude.d.ts +20 -0
  317. package/dist/shared/math/longitude.js +31 -0
  318. package/dist/shared/math/mercator-plane.d.ts +27 -0
  319. package/dist/shared/math/mercator-plane.js +26 -0
  320. package/dist/shared/math/obb.d.ts +65 -0
  321. package/dist/shared/math/obb.js +107 -0
  322. package/dist/shared/math/rotation.d.ts +93 -0
  323. package/dist/shared/math/rotation.js +186 -0
  324. package/dist/shared/math/segment-grid.d.ts +69 -0
  325. package/dist/shared/math/segment-grid.js +159 -0
  326. package/dist/shared/math/transform.d.ts +140 -0
  327. package/dist/shared/math/transform.js +189 -0
  328. package/dist/shared/types/events.d.ts +128 -0
  329. package/dist/shared/types/events.js +3 -0
  330. package/dist/shared/types/model.d.ts +950 -0
  331. package/dist/shared/types/model.js +3 -0
  332. package/dist/shared/types/selection-box.d.ts +23 -0
  333. package/dist/shared/types/selection-box.js +3 -0
  334. package/dist/shared/types/style.d.ts +68 -0
  335. package/dist/shared/types/style.js +3 -0
  336. package/dist/shared/utils/color.d.ts +49 -0
  337. package/dist/shared/utils/color.js +180 -0
  338. package/dist/shared/utils/coordinates.d.ts +52 -0
  339. package/dist/shared/utils/coordinates.js +75 -0
  340. package/dist/shared/utils/embedded-image.d.ts +34 -0
  341. package/dist/shared/utils/embedded-image.js +161 -0
  342. package/dist/shared/utils/event-emitter.d.ts +262 -0
  343. package/dist/shared/utils/event-emitter.js +44 -0
  344. package/dist/shared/utils/feature-bbox.d.ts +8 -0
  345. package/dist/shared/utils/feature-bbox.js +207 -0
  346. package/dist/shared/utils/feature-segments.d.ts +23 -0
  347. package/dist/shared/utils/feature-segments.js +179 -0
  348. package/dist/shared/utils/id.d.ts +1 -0
  349. package/dist/shared/utils/id.js +35 -0
  350. package/dist/shared/utils/image.d.ts +34 -0
  351. package/dist/shared/utils/image.js +106 -0
  352. package/dist/shared/utils/index.d.ts +15 -0
  353. package/dist/shared/utils/index.js +24 -0
  354. package/dist/shared/utils/map.d.ts +26 -0
  355. package/dist/shared/utils/map.js +35 -0
  356. package/dist/shared/utils/name-generator.d.ts +197 -0
  357. package/dist/shared/utils/name-generator.js +337 -0
  358. package/dist/shared/utils/pixel-ratio.d.ts +111 -0
  359. package/dist/shared/utils/pixel-ratio.js +85 -0
  360. package/dist/shared/utils/property.d.ts +88 -0
  361. package/dist/shared/utils/property.js +140 -0
  362. package/dist/shared/utils/vertex-ref.d.ts +23 -0
  363. package/dist/shared/utils/vertex-ref.js +20 -0
  364. package/dist/snapping/custom-targets.d.ts +1 -0
  365. package/dist/snapping/custom-targets.js +21 -0
  366. package/dist/snapping/geometry.d.ts +1 -0
  367. package/dist/snapping/geometry.js +61 -0
  368. package/dist/snapping/index.d.ts +14 -0
  369. package/dist/snapping/index.js +4 -0
  370. package/dist/snapping/indicator.d.ts +19 -0
  371. package/dist/snapping/indicator.js +145 -0
  372. package/dist/snapping/providers/display.d.ts +72 -0
  373. package/dist/snapping/providers/display.js +268 -0
  374. package/dist/snapping/providers/guide.d.ts +69 -0
  375. package/dist/snapping/providers/guide.js +187 -0
  376. package/dist/snapping/providers/intersection.d.ts +1 -0
  377. package/dist/snapping/providers/intersection.js +92 -0
  378. package/dist/snapping/providers/shared.d.ts +39 -0
  379. package/dist/snapping/providers/shared.js +146 -0
  380. package/dist/snapping/providers/store.d.ts +1 -0
  381. package/dist/snapping/providers/store.js +132 -0
  382. package/dist/snapping/service.d.ts +1 -0
  383. package/dist/snapping/service.js +272 -0
  384. package/dist/snapping/types.d.ts +267 -0
  385. package/dist/snapping/types.js +66 -0
  386. package/dist/store/change-merger.d.ts +1 -0
  387. package/dist/store/change-merger.js +102 -0
  388. package/dist/store/draw-store.d.ts +1 -0
  389. package/dist/store/draw-store.js +396 -0
  390. package/dist/store/event-bridge.d.ts +1 -0
  391. package/dist/store/event-bridge.js +161 -0
  392. package/dist/store/index.d.ts +12 -0
  393. package/dist/store/index.js +4 -0
  394. package/dist/store/local-visibility.d.ts +21 -0
  395. package/dist/store/local-visibility.js +27 -0
  396. package/dist/store/lock.d.ts +67 -0
  397. package/dist/store/lock.js +54 -0
  398. package/dist/store/memory/change-bus.d.ts +60 -0
  399. package/dist/store/memory/change-bus.js +232 -0
  400. package/dist/store/memory/file-store.d.ts +15 -0
  401. package/dist/store/memory/file-store.js +33 -0
  402. package/dist/store/memory/frozen.d.ts +21 -0
  403. package/dist/store/memory/frozen.js +51 -0
  404. package/dist/store/memory/ui-state.d.ts +51 -0
  405. package/dist/store/memory/ui-state.js +223 -0
  406. package/dist/store/memory.d.ts +26 -0
  407. package/dist/store/memory.js +708 -0
  408. package/dist/store/spatial/index.d.ts +6 -0
  409. package/dist/store/spatial/index.js +4 -0
  410. package/dist/store/spatial/spatial-index.d.ts +90 -0
  411. package/dist/store/spatial/spatial-index.js +148 -0
  412. package/dist/store/spatial/store-spatial-index.d.ts +60 -0
  413. package/dist/store/spatial/store-spatial-index.js +125 -0
  414. package/dist/store/store.d.ts +417 -0
  415. package/dist/store/store.js +3 -0
  416. package/dist/store/types.d.ts +8 -0
  417. package/dist/store/types.js +3 -0
  418. package/dist/store/writable-layer.d.ts +35 -0
  419. package/dist/store/writable-layer.js +20 -0
  420. package/dist/view/cache/buffer.d.ts +28 -0
  421. package/dist/view/cache/buffer.js +176 -0
  422. package/dist/view/cache/earcut.d.ts +1 -0
  423. package/dist/view/cache/earcut.js +122 -0
  424. package/dist/view/cache/style-rule.d.ts +1 -0
  425. package/dist/view/cache/style-rule.js +97 -0
  426. package/dist/view/cache/terrain-fill.d.ts +30 -0
  427. package/dist/view/cache/terrain-fill.js +60 -0
  428. package/dist/view/cache/texture.d.ts +14 -0
  429. package/dist/view/cache/texture.js +292 -0
  430. package/dist/view/coordinator.d.ts +27 -0
  431. package/dist/view/coordinator.js +72 -0
  432. package/dist/view/feature-companion.d.ts +173 -0
  433. package/dist/view/feature-companion.js +108 -0
  434. package/dist/view/globe-subdivision.d.ts +78 -0
  435. package/dist/view/globe-subdivision.js +128 -0
  436. package/dist/view/index.d.ts +47 -0
  437. package/dist/view/index.js +20 -0
  438. package/dist/view/layer/attach.d.ts +20 -0
  439. package/dist/view/layer/attach.js +47 -0
  440. package/dist/view/layer/blend.d.ts +57 -0
  441. package/dist/view/layer/blend.js +14 -0
  442. package/dist/view/layer/custom-layer.d.ts +1 -0
  443. package/dist/view/layer/custom-layer.js +509 -0
  444. package/dist/view/layer/depth-state.d.ts +14 -0
  445. package/dist/view/layer/depth-state.js +44 -0
  446. package/dist/view/layer/display-list.d.ts +1 -0
  447. package/dist/view/layer/display-list.js +111 -0
  448. package/dist/view/layer/drape-planner.d.ts +139 -0
  449. package/dist/view/layer/drape-planner.js +726 -0
  450. package/dist/view/layer/frame-render.d.ts +57 -0
  451. package/dist/view/layer/frame-render.js +209 -0
  452. package/dist/view/layer/frame-state.d.ts +147 -0
  453. package/dist/view/layer/frame-state.js +484 -0
  454. package/dist/view/layer/gl-state.d.ts +77 -0
  455. package/dist/view/layer/gl-state.js +132 -0
  456. package/dist/view/layer/index.d.ts +6 -0
  457. package/dist/view/layer/index.js +5 -0
  458. package/dist/view/layer/render-scope.d.ts +30 -0
  459. package/dist/view/layer/render-scope.js +28 -0
  460. package/dist/view/layer/render.d.ts +87 -0
  461. package/dist/view/layer/render.js +187 -0
  462. package/dist/view/layer/renderers.d.ts +81 -0
  463. package/dist/view/layer/renderers.js +142 -0
  464. package/dist/view/layer/slot-manager.d.ts +26 -0
  465. package/dist/view/layer/slot-manager.js +133 -0
  466. package/dist/view/layer/slots.d.ts +33 -0
  467. package/dist/view/layer/slots.js +50 -0
  468. package/dist/view/layer/store-retained-bbox.d.ts +36 -0
  469. package/dist/view/layer/store-retained-bbox.js +188 -0
  470. package/dist/view/layer/store-retained-chunk.d.ts +97 -0
  471. package/dist/view/layer/store-retained-chunk.js +94 -0
  472. package/dist/view/layer/store-retained-classify.d.ts +34 -0
  473. package/dist/view/layer/store-retained-classify.js +88 -0
  474. package/dist/view/layer/store-retained-collect.d.ts +24 -0
  475. package/dist/view/layer/store-retained-collect.js +121 -0
  476. package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
  477. package/dist/view/layer/store-retained-coord-patch.js +168 -0
  478. package/dist/view/layer/store-retained-immediate.d.ts +63 -0
  479. package/dist/view/layer/store-retained-immediate.js +49 -0
  480. package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
  481. package/dist/view/layer/store-retained-invalidation.js +192 -0
  482. package/dist/view/layer/store-retained.d.ts +198 -0
  483. package/dist/view/layer/store-retained.js +430 -0
  484. package/dist/view/layer/terrain-resolver.d.ts +1 -0
  485. package/dist/view/layer/terrain-resolver.js +174 -0
  486. package/dist/view/renderers/batch-manager.d.ts +61 -0
  487. package/dist/view/renderers/batch-manager.js +718 -0
  488. package/dist/view/renderers/draw-factors.d.ts +60 -0
  489. package/dist/view/renderers/draw-factors.js +35 -0
  490. package/dist/view/renderers/drawer.d.ts +1 -0
  491. package/dist/view/renderers/drawer.js +346 -0
  492. package/dist/view/renderers/image.d.ts +1 -0
  493. package/dist/view/renderers/image.js +255 -0
  494. package/dist/view/renderers/line/dash.d.ts +31 -0
  495. package/dist/view/renderers/line/dash.js +152 -0
  496. package/dist/view/renderers/line/line-geometry.d.ts +39 -0
  497. package/dist/view/renderers/line/line-geometry.js +460 -0
  498. package/dist/view/renderers/line/line-gl.d.ts +1 -0
  499. package/dist/view/renderers/line/line-gl.js +236 -0
  500. package/dist/view/renderers/line/line-shader.d.ts +1 -0
  501. package/dist/view/renderers/line/line-shader.js +364 -0
  502. package/dist/view/renderers/line/line-types.d.ts +43 -0
  503. package/dist/view/renderers/line/line-types.js +3 -0
  504. package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
  505. package/dist/view/renderers/line/line-uniforms.js +390 -0
  506. package/dist/view/renderers/line/sdf-line.d.ts +92 -0
  507. package/dist/view/renderers/line/sdf-line.js +567 -0
  508. package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
  509. package/dist/view/renderers/point/billboard-depth.js +56 -0
  510. package/dist/view/renderers/point/point-instance.d.ts +124 -0
  511. package/dist/view/renderers/point/point-instance.js +738 -0
  512. package/dist/view/renderers/point/point-sdf.d.ts +58 -0
  513. package/dist/view/renderers/point/point-sdf.js +170 -0
  514. package/dist/view/renderers/point/point-shape.d.ts +99 -0
  515. package/dist/view/renderers/point/point-shape.js +504 -0
  516. package/dist/view/renderers/point/point-style.d.ts +1 -0
  517. package/dist/view/renderers/point/point-style.js +46 -0
  518. package/dist/view/renderers/polygon/batch.d.ts +26 -0
  519. package/dist/view/renderers/polygon/batch.js +336 -0
  520. package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
  521. package/dist/view/renderers/polygon/earcut-input.js +55 -0
  522. package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
  523. package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
  524. package/dist/view/renderers/polygon/fill.d.ts +74 -0
  525. package/dist/view/renderers/polygon/fill.js +251 -0
  526. package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
  527. package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
  528. package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
  529. package/dist/view/renderers/polygon/terrain-cull.js +14 -0
  530. package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
  531. package/dist/view/renderers/polygon/triangulator.js +3 -0
  532. package/dist/view/renderers/retained.d.ts +43 -0
  533. package/dist/view/renderers/retained.js +3 -0
  534. package/dist/view/renderers/stroke.d.ts +121 -0
  535. package/dist/view/renderers/stroke.js +621 -0
  536. package/dist/view/shaders/frame.d.ts +8 -0
  537. package/dist/view/shaders/frame.js +37 -0
  538. package/dist/view/shaders/helpers.d.ts +238 -0
  539. package/dist/view/shaders/helpers.js +611 -0
  540. package/dist/view/shaders/initializer.d.ts +27 -0
  541. package/dist/view/shaders/initializer.js +125 -0
  542. package/dist/view/shaders/projection.d.ts +123 -0
  543. package/dist/view/shaders/projection.js +299 -0
  544. package/dist/view/shaders/quad-grid.d.ts +77 -0
  545. package/dist/view/shaders/quad-grid.js +128 -0
  546. package/dist/view/shaders/quad.d.ts +189 -0
  547. package/dist/view/shaders/quad.js +582 -0
  548. package/dist/view/shaders/retained-origin.d.ts +50 -0
  549. package/dist/view/shaders/retained-origin.js +67 -0
  550. package/dist/view/shaders/terrain-shade.d.ts +23 -0
  551. package/dist/view/shaders/terrain-shade.js +93 -0
  552. package/dist/view/style-rule.d.ts +166 -0
  553. package/dist/view/style-rule.js +300 -0
  554. package/dist/view/terrain/anchor.d.ts +135 -0
  555. package/dist/view/terrain/anchor.js +226 -0
  556. package/dist/view/terrain/context.d.ts +132 -0
  557. package/dist/view/terrain/context.js +437 -0
  558. package/dist/view/terrain/dem-atlas.d.ts +97 -0
  559. package/dist/view/terrain/dem-atlas.js +534 -0
  560. package/dist/view/terrain/detect.d.ts +126 -0
  561. package/dist/view/terrain/detect.js +198 -0
  562. package/dist/view/terrain/drape/bin-store.d.ts +179 -0
  563. package/dist/view/terrain/drape/bin-store.js +529 -0
  564. package/dist/view/terrain/drape/binning.d.ts +259 -0
  565. package/dist/view/terrain/drape/binning.js +604 -0
  566. package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
  567. package/dist/view/terrain/drape/edge-constrain.js +175 -0
  568. package/dist/view/terrain/drape/geometry.d.ts +95 -0
  569. package/dist/view/terrain/drape/geometry.js +260 -0
  570. package/dist/view/terrain/drape/mesh.d.ts +50 -0
  571. package/dist/view/terrain/drape/mesh.js +86 -0
  572. package/dist/view/terrain/drape/pass.d.ts +122 -0
  573. package/dist/view/terrain/drape/pass.js +379 -0
  574. package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
  575. package/dist/view/terrain/drape/quad-glyphs.js +117 -0
  576. package/dist/view/terrain/drape/quad.d.ts +249 -0
  577. package/dist/view/terrain/drape/quad.js +835 -0
  578. package/dist/view/terrain/drape/renderer.d.ts +184 -0
  579. package/dist/view/terrain/drape/renderer.js +706 -0
  580. package/dist/view/terrain/drape/shared.d.ts +80 -0
  581. package/dist/view/terrain/drape/shared.js +173 -0
  582. package/dist/view/terrain/drape/stitch.d.ts +155 -0
  583. package/dist/view/terrain/drape/stitch.js +228 -0
  584. package/dist/view/terrain/ground.d.ts +72 -0
  585. package/dist/view/terrain/ground.js +151 -0
  586. package/dist/view/terrain/metrics.d.ts +180 -0
  587. package/dist/view/terrain/metrics.js +231 -0
  588. package/dist/view/terrain/occlusion.d.ts +11 -0
  589. package/dist/view/terrain/occlusion.js +129 -0
  590. package/dist/view/terrain/polygon.d.ts +86 -0
  591. package/dist/view/terrain/polygon.js +301 -0
  592. package/dist/view/terrain/shade.d.ts +48 -0
  593. package/dist/view/terrain/shade.js +45 -0
  594. package/dist/view/terrain/state.d.ts +99 -0
  595. package/dist/view/terrain/state.js +186 -0
  596. package/dist/view/terrain/tessellation.d.ts +265 -0
  597. package/dist/view/terrain/tessellation.js +924 -0
  598. package/dist/view/terrain/tiling.d.ts +56 -0
  599. package/dist/view/terrain/tiling.js +155 -0
  600. package/dist/view/terrain/upstream-terrain.d.ts +82 -0
  601. package/dist/view/terrain/upstream-terrain.js +116 -0
  602. package/dist/view/ui/auxiliary-handles.d.ts +151 -0
  603. package/dist/view/ui/auxiliary-handles.js +22 -0
  604. package/dist/view/ui/bounds.d.ts +53 -0
  605. package/dist/view/ui/bounds.js +149 -0
  606. package/dist/view/ui/box-selection.d.ts +1 -0
  607. package/dist/view/ui/box-selection.js +83 -0
  608. package/dist/view/ui/handle-test.d.ts +1 -0
  609. package/dist/view/ui/handle-test.js +437 -0
  610. package/dist/view/ui/handle-thinning.d.ts +122 -0
  611. package/dist/view/ui/handle-thinning.js +430 -0
  612. package/dist/view/ui/handles.d.ts +25 -0
  613. package/dist/view/ui/handles.js +673 -0
  614. package/dist/view/ui/helper.d.ts +19 -0
  615. package/dist/view/ui/helper.js +76 -0
  616. package/dist/view/ui/index.d.ts +15 -0
  617. package/dist/view/ui/index.js +15 -0
  618. package/dist/view/ui/selection-scope.d.ts +25 -0
  619. package/dist/view/ui/selection-scope.js +34 -0
  620. package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
  621. package/dist/view/ui/selection-ui/bounding-box.js +240 -0
  622. package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
  623. package/dist/view/ui/selection-ui/extension-registry.js +78 -0
  624. package/dist/view/ui/selection-ui/index.d.ts +12 -0
  625. package/dist/view/ui/selection-ui/index.js +12 -0
  626. package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
  627. package/dist/view/ui/selection-ui/renderer.js +227 -0
  628. package/dist/view/ui/selection-ui/types.d.ts +55 -0
  629. package/dist/view/ui/selection-ui/types.js +3 -0
  630. package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
  631. package/dist/view/ui/selection-ui-drawer.js +329 -0
  632. package/dist/view/ui/tentative.d.ts +1 -0
  633. package/dist/view/ui/tentative.js +320 -0
  634. package/dist/view/viewport.d.ts +119 -0
  635. package/dist/view/viewport.js +254 -0
  636. package/package.json +113 -0
@@ -0,0 +1,140 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Box selection logic
5
+ *
6
+ * Responsible for handling box selection in select mode
7
+ */
8
+ import { isLocallyHidden } from '../../store/local-visibility.js';
9
+ /**
10
+ * Detect the features inside the box
11
+ *
12
+ * First the candidates are obtained quickly through the SpatialIndex (rbush),
13
+ * and then a precise inside-the-box test is performed.
14
+ */
15
+ export function queryFeaturesInBox(boxSelection, context) {
16
+ const { store, spatialIndex, boxSelectionRegistry } = context;
17
+ const rects = boxRects(boxSelection.startPoint, boxSelection.endPoint);
18
+ // First obtain the candidates quickly with rbush (from each part of a box that crosses the
19
+ // antimeridian)
20
+ const candidateIds = new Set();
21
+ for (const rect of rects) {
22
+ for (const id of spatialIndex.findInBounds(rect))
23
+ candidateIds.add(id);
24
+ }
25
+ // Perform the precise inside-the-box test on the candidates.
26
+ // As with the click hit test (HitTestService.hitTestAll), hidden or locked features / their
27
+ // layer / their group are excluded from the selection targets (this prevents the
28
+ // inconsistency where box selection alone could select while ignoring locks and hiding).
29
+ const hitIds = [];
30
+ for (const id of candidateIds) {
31
+ const feature = store.getFeature(id);
32
+ if (!feature)
33
+ continue;
34
+ if (!feature.visible || feature.locked)
35
+ continue;
36
+ // What this client has hidden locally is excluded from the box selection targets too
37
+ // (this prevents the inconsistency of being hit by the box while invisible).
38
+ if (isLocallyHidden(feature, store))
39
+ continue;
40
+ const layer = store.getLayer(feature.layerId);
41
+ if (layer && (!layer.visible || layer.locked))
42
+ continue;
43
+ if (feature.groupId) {
44
+ const group = store.getGroup(feature.groupId);
45
+ if (group && (!group.visible || group.locked))
46
+ continue;
47
+ }
48
+ if (rects.some((rect) => isFeatureInBox(feature, rect, boxSelectionRegistry))) {
49
+ hitIds.push(feature.id);
50
+ }
51
+ }
52
+ return hitIds;
53
+ }
54
+ /**
55
+ * The rectangles, in longitudes within [-180, 180], that a box drawn on the screen covers
56
+ *
57
+ * The corners come from the map unprojected as they are, so a box drawn across the
58
+ * antimeridian has a longitude beyond ±180 at one side. It is brought back into [-180, 180]
59
+ * and split at the line into two rectangles, and the box as drawn is kept as well; a box as
60
+ * wide as the world covers every longitude.
61
+ */
62
+ export function boxRects(start, end) {
63
+ const minY = Math.min(start[1], end[1]);
64
+ const maxY = Math.max(start[1], end[1]);
65
+ let minX = Math.min(start[0], end[0]);
66
+ let maxX = Math.max(start[0], end[0]);
67
+ if (maxX - minX >= 360)
68
+ return [{ minX: -180, minY, maxX: 180, maxY }];
69
+ // Features whose coordinates were stored beyond ±180 are still found by the box as drawn
70
+ const drawn = { minX, minY, maxX, maxY };
71
+ // Shift whole turns so that the west side is within [-180, 180)
72
+ const turns = Math.floor((minX + 180) / 360);
73
+ minX -= turns * 360;
74
+ maxX -= turns * 360;
75
+ const parts = maxX <= 180
76
+ ? [{ minX, minY, maxX, maxY }]
77
+ : [
78
+ { minX, minY, maxX: 180, maxY },
79
+ { minX: -180, minY, maxX: maxX - 360, maxY },
80
+ ];
81
+ return turns === 0 && parts.length === 1 ? parts : [...parts, drawn];
82
+ }
83
+ /**
84
+ * Decide whether a feature is inside the box
85
+ *
86
+ * Uses BoxSelectionStrategyRegistry to perform the appropriate test per feature type.
87
+ * - Point: whether the center coordinate is inside the box
88
+ * - LineString: intersection test between the geometry and the box
89
+ * - Polygon: intersection test between the geometry and the box
90
+ * - Text/Image: intersection test between the OBB (the bounding box that accounts for rotation)
91
+ * and the box
92
+ */
93
+ export function isFeatureInBox(feature, rect, boxSelectionRegistry) {
94
+ // Get the Strategy from the registry
95
+ const strategy = boxSelectionRegistry.get(feature.type);
96
+ if (strategy) {
97
+ return strategy.intersects(feature, rect);
98
+ }
99
+ // Fallback for custom types (a coordinate-based test)
100
+ return fallbackBoxSelection(feature, rect);
101
+ }
102
+ /**
103
+ * The fallback box selection test
104
+ *
105
+ * Performs a simple coordinate-based test for feature types that are not registered.
106
+ */
107
+ export function fallbackBoxSelection(feature, rect) {
108
+ const isPointInBox = (coord) => {
109
+ return (coord[0] >= rect.minX &&
110
+ coord[0] <= rect.maxX &&
111
+ coord[1] >= rect.minY &&
112
+ coord[1] <= rect.maxY);
113
+ };
114
+ const coords = feature.coordinates;
115
+ // When the coordinates are a single point
116
+ if (Array.isArray(coords) &&
117
+ coords.length === 2 &&
118
+ typeof coords[0] === 'number' &&
119
+ typeof coords[1] === 'number') {
120
+ return isPointInBox(coords);
121
+ }
122
+ // When the coordinates are an array
123
+ if (Array.isArray(coords) && coords.length > 0) {
124
+ const firstElement = coords[0];
125
+ // LineString form: Coordinate[]
126
+ if (Array.isArray(firstElement) &&
127
+ firstElement.length === 2 &&
128
+ typeof firstElement[0] === 'number') {
129
+ return coords.some((coord) => isPointInBox(coord));
130
+ }
131
+ // Polygon form: Coordinate[][]
132
+ if (Array.isArray(firstElement) && Array.isArray(firstElement[0])) {
133
+ const rings = coords;
134
+ if (rings.length === 0)
135
+ return false;
136
+ return rings[0].some((coord) => isPointInBox(coord));
137
+ }
138
+ }
139
+ return false;
140
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * click / dblclick handling for SelectMode
3
+ *
4
+ * Single click: the priority order is plugin intercept -> vertex click -> feature selection
5
+ * 1. While a plugin is interacting, clicks inside its container are consumed; anything else
6
+ * finishes it
7
+ * 2. A click on a vertex handle of a singly selected feature that supports vertex editing
8
+ * (LineString / Polygon / the Multi types) -> vertex selection
9
+ * 3. Unified z traversal (hitTestTopmost) -> if it is a Store feature, the selection is
10
+ * updated / shift+click toggles / re-clicking an already selected feature is delegated to
11
+ * pluginManager.handleFeatureClick.
12
+ * If a dataset is in the foreground, Store features are not grabbed and it
13
+ * is treated as clearing the selection.
14
+ * If a feature companion is in the foreground, the click is consumed and passed to the
15
+ * provider (the selection is left unchanged)
16
+ *
17
+ * Double click: selects the feature and notifies pluginManager.handleFeatureDoubleClick
18
+ */
19
+ import type { MouseNormalizedEvent } from '../../dispatcher/types.js';
20
+ import type { SelectionUIConfig } from '../../shared/config/selection.js';
21
+ import type { ModeContext } from '../handler.js';
22
+ /**
23
+ * The main logic of onClick
24
+ */
25
+ export declare function handleSelectClick(event: MouseNormalizedEvent, context: ModeContext, config: SelectionUIConfig): void;
26
+ /**
27
+ * The main logic of onDoubleClick
28
+ *
29
+ * A double click on a feature is consumed (its default action is prevented, so MapLibre does
30
+ * not zoom); a double click on the empty map is left to MapLibre.
31
+ */
32
+ export declare function handleSelectDoubleClick(event: MouseNormalizedEvent, context: ModeContext): void;
@@ -0,0 +1,166 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { createCoordinateTransform } from '../../shared/math/index.js';
4
+ import { supportsVertexEditing } from '../../shared/utils/coordinates.js';
5
+ import { hasVertexRef, isSameVertexRef } from '../../shared/utils/vertex-ref.js';
6
+ import { getDisplayFeatures } from '../../store/local-visibility.js';
7
+ import { notifyFeatureCompanionClick } from '../../view/feature-companion.js';
8
+ import { hitTestHandles } from '../../view/ui/handle-test.js';
9
+ import { getSelectedFeatures } from '../../view/ui/helper.js';
10
+ /**
11
+ * The main logic of onClick
12
+ */
13
+ export function handleSelectClick(event, context, config) {
14
+ if (handlePluginInteractionClick(event, context)) {
15
+ return;
16
+ }
17
+ const { store } = context;
18
+ const selection = store.getSelection();
19
+ const selectedIds = selection.type === 'feature' ? selection.ids : [];
20
+ if (handleVertexClick(event, selectedIds, context, config)) {
21
+ return;
22
+ }
23
+ store.setSelectedVertices(null);
24
+ handleFeatureClick(event, selection, selectedIds, context);
25
+ }
26
+ /**
27
+ * The main logic of onDoubleClick
28
+ *
29
+ * A double click on a feature is consumed (its default action is prevented, so MapLibre does
30
+ * not zoom); a double click on the empty map is left to MapLibre.
31
+ */
32
+ export function handleSelectDoubleClick(event, context) {
33
+ if (context.pluginManager?.isPluginInteracting())
34
+ return;
35
+ const { store } = context;
36
+ const orderedFeatures = getDisplayFeatures(store);
37
+ // Store features are not grabbed when a dataset is in the foreground
38
+ const top = context.hitTestTopmost(event.point, { orderedFeatures });
39
+ if (top?.kind !== 'store')
40
+ return;
41
+ event.originalEvent.preventDefault();
42
+ const filtered = context.pluginManager?.filterSelectionCandidates([top.feature.id]) ?? [
43
+ top.feature.id,
44
+ ];
45
+ if (filtered.length > 0) {
46
+ store.setSelection('feature', filtered);
47
+ }
48
+ context.pluginManager?.handleFeatureDoubleClick(top.feature.id);
49
+ }
50
+ /**
51
+ * Click handling during a plugin interaction
52
+ *
53
+ * @returns true when the click was consumed (= the caller skips the rest of the handling)
54
+ */
55
+ function handlePluginInteractionClick(event, context) {
56
+ const pm = context.pluginManager;
57
+ if (!pm?.isPluginInteracting())
58
+ return false;
59
+ const container = pm.getPluginInteractionContainer();
60
+ if (container) {
61
+ const target = event.originalEvent.target;
62
+ if (container.contains(target)) {
63
+ return true;
64
+ }
65
+ }
66
+ pm.finishPluginInteraction();
67
+ return true;
68
+ }
69
+ /**
70
+ * Click handling for vertex handles
71
+ *
72
+ * @returns true when a vertex was selected
73
+ */
74
+ function handleVertexClick(event, selectedIds, context, config) {
75
+ if (selectedIds.length !== 1)
76
+ return false;
77
+ const { store, map } = context;
78
+ const selectedFeatures = getSelectedFeatures(store);
79
+ const feature = selectedFeatures[0];
80
+ // Only types that support vertex editing (LineString / Polygon / the Multi types) are subject
81
+ // to vertex selection
82
+ if (!feature || !supportsVertexEditing(feature.type))
83
+ return false;
84
+ const transform = createCoordinateTransform(map);
85
+ const zoom = map.getZoom();
86
+ const handleHit = hitTestHandles(event.point, selectedFeatures, transform, config, zoom, context.selectionScope);
87
+ if (handleHit?.type !== 'vertex' || handleHit.vertexRef === undefined) {
88
+ return false;
89
+ }
90
+ const featureId = handleHit.featureId;
91
+ if (!featureId)
92
+ return false;
93
+ const vertexRef = handleHit.vertexRef;
94
+ const currentVertexSelection = store.getSelectedVertices();
95
+ if (event.modifiers.shift && currentVertexSelection?.featureId === featureId) {
96
+ // Shift+click: add / remove a vertex of the same feature
97
+ const refs = currentVertexSelection.vertexIndices;
98
+ if (hasVertexRef(refs, vertexRef)) {
99
+ const newRefs = refs.filter((r) => !isSameVertexRef(r, vertexRef));
100
+ store.setSelectedVertices(newRefs.length === 0 ? null : { featureId, vertexIndices: newRefs });
101
+ }
102
+ else {
103
+ store.setSelectedVertices({ featureId, vertexIndices: [...refs, vertexRef] });
104
+ }
105
+ }
106
+ else {
107
+ store.setSelectedVertices({ featureId, vertexIndices: [vertexRef] });
108
+ }
109
+ return true;
110
+ }
111
+ /**
112
+ * Feature selection handling
113
+ */
114
+ function handleFeatureClick(event, selection, selectedIds, context) {
115
+ const { store } = context;
116
+ const orderedFeatures = getDisplayFeatures(store);
117
+ const top = context.hitTestTopmost(event.point, { orderedFeatures });
118
+ // A feature companion is in the foreground: the provider receives the click and core changes
119
+ // the selection in no way at all (not even clearing it as an empty click would). Core does not
120
+ // know what the companion is, so its job ends at consuming the click and reporting it.
121
+ if (top?.kind === 'companion') {
122
+ notifyFeatureCompanionClick(context.featureCompanions, top.companion);
123
+ return;
124
+ }
125
+ // When there is nothing, and when a dataset is in the foreground, Store
126
+ // features are not grabbed. A dataset's click fires only when the intercepting side
127
+ // (display/interaction) is interactive.
128
+ if (top?.kind !== 'store') {
129
+ if (!event.modifiers.shift) {
130
+ store.setSelection(null, []);
131
+ }
132
+ return;
133
+ }
134
+ const feature = top.feature;
135
+ // Re-clicking an already selected feature -> delegate to the plugins
136
+ if (!event.modifiers.shift && selectedIds.length === 1 && selectedIds.includes(feature.id)) {
137
+ if (context.pluginManager?.handleFeatureClick(feature.id)) {
138
+ return;
139
+ }
140
+ }
141
+ // Update the selection
142
+ const candidateIds = event.modifiers.shift
143
+ ? toggleSelection(selection, feature.id)
144
+ : [feature.id];
145
+ const filtered = context.pluginManager?.filterSelectionCandidates(candidateIds) ?? candidateIds;
146
+ if (filtered.length === 0) {
147
+ store.setSelection(null, []);
148
+ }
149
+ else {
150
+ store.setSelection('feature', filtered);
151
+ }
152
+ }
153
+ /**
154
+ * Toggling the selection with Shift+click
155
+ */
156
+ function toggleSelection(selection, featureId) {
157
+ const current = selection.type === 'feature' ? [...selection.ids] : [];
158
+ const index = current.indexOf(featureId);
159
+ if (index === -1) {
160
+ current.push(featureId);
161
+ }
162
+ else {
163
+ current.splice(index, 1);
164
+ }
165
+ return current;
166
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * cursor control for SelectMode (onMouseMove)
3
+ *
4
+ * 1. There is a selected feature and a handle was hit -> the cursor that matches the handle kind
5
+ * (move / resize / vertex, etc.)
6
+ * 1.5. A selection-independent auxiliary handle (provided by an extension implementation) was
7
+ * hit -> that handle's cursor
8
+ * 2. Otherwise, a Store feature or an interactive dataset is in the very
9
+ * foreground -> 'pointer'
10
+ * 3. Otherwise (a dataset that merely occludes / nothing) -> 'default'
11
+ */
12
+ import type { MouseNormalizedEvent } from '../../dispatcher/types.js';
13
+ import type { SelectionUIConfig } from '../../shared/config/selection.js';
14
+ import type { ModeContext } from '../handler.js';
15
+ export declare function updateCursorForSelection(event: MouseNormalizedEvent, context: ModeContext, config: SelectionUIConfig): void;
@@ -0,0 +1,59 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { createCoordinateTransform } from '../../shared/math/index.js';
4
+ import { getDisplayFeatures } from '../../store/local-visibility.js';
5
+ import { isInteractionBlocked } from '../../store/lock.js';
6
+ import { getCursorForHandle, hitTestGlobalAuxiliaryHandles, hitTestHandles, } from '../../view/ui/handle-test.js';
7
+ import { computeSelectionBoundingBox, getSelectedFeatureIds, getSelectedFeatures, } from '../../view/ui/helper.js';
8
+ import { getAdditionalResizeHandlesCallback, getAuxiliaryHandlesCallback, getGlobalAuxiliaryHandlesCallback, } from './hit-helpers.js';
9
+ export function updateCursorForSelection(event, context, config) {
10
+ const { store, map } = context;
11
+ // Group / layer selections are also resolved to their members (so the operation cursor is
12
+ // shown over a group).
13
+ const selectedIds = getSelectedFeatureIds(store);
14
+ const canvas = map.getCanvas();
15
+ const transform = createCoordinateTransform(map);
16
+ // Handle hit test on the selected features
17
+ // No operation cursor (move / resize, etc.) is shown for a selection whose editing operations
18
+ // are suppressed (effective lock / read-only / interaction lock). Dragging is rejected by
19
+ // startDrag with the same predicate, so the cursor alone would be a lie suggesting it is
20
+ // possible. It falls through to the feature hit test below (pointer), matching the operation
21
+ // that is actually possible: "it can be selected by clicking".
22
+ if (selectedIds.length > 0) {
23
+ const selectedFeatures = getSelectedFeatures(store);
24
+ const blocked = selectedFeatures.some((f) => isInteractionBlocked(f, store));
25
+ const bbox = blocked
26
+ ? null
27
+ : computeSelectionBoundingBox(selectedFeatures, context.selectionScope.extensions);
28
+ if (bbox) {
29
+ const zoom = map.getZoom();
30
+ const getAdditionalHandles = getAdditionalResizeHandlesCallback(selectedFeatures, context.selectionScope);
31
+ const getAuxiliaryHandles = getAuxiliaryHandlesCallback(selectedFeatures, context.selectionScope);
32
+ const handleHit = hitTestHandles(event.point, selectedFeatures, transform, config, zoom, context.selectionScope, getAdditionalHandles, getAuxiliaryHandles);
33
+ if (handleHit) {
34
+ canvas.style.cursor = getCursorForHandle(handleHit);
35
+ return;
36
+ }
37
+ }
38
+ }
39
+ // Selection-independent auxiliary handles (an extension implementation's focus, etc.). They
40
+ // appear regardless of whether there is a selection, so they are looked at after the selection
41
+ // handles and before the feature hit. They are not shown in a state where they cannot be
42
+ // grabbed (readOnly / interaction lock) (the cursor alone would be a lie suggesting it is
43
+ // possible).
44
+ if (!store.isReadOnly() && !store.isInteractionLocked()) {
45
+ const globalHit = hitTestGlobalAuxiliaryHandles(event.point, transform, config, map.getZoom(), getGlobalAuxiliaryHandlesCallback(context.selectionScope));
46
+ if (globalHit) {
47
+ canvas.style.cursor = getCursorForHandle(globalHit);
48
+ return;
49
+ }
50
+ }
51
+ // Feature hit test (unified z traversal)
52
+ // When a dataset is in the foreground, the cursor becomes pointer only when it
53
+ // can fire click / hover (interactive). Showing pointer for a dataset that merely occludes
54
+ // would be a lie suggesting "it can be pressed".
55
+ const orderedFeatures = getDisplayFeatures(store);
56
+ const top = context.hitTestTopmost(event.point, { orderedFeatures });
57
+ canvas.style.cursor =
58
+ top === null || (top.kind === 'dataset' && !top.dataset.interactive) ? 'default' : 'pointer';
59
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Auxiliary handle drag: delegated to the extension implementation that provides the handle
3
+ */
4
+ import type { DragNormalizedEvent } from '../../../dispatcher/types.js';
5
+ import type { AuxiliaryHandleHit, AuxiliaryHandleProvider } from '../../../view/ui/auxiliary-handles.js';
6
+ import type { HandleHitResult } from '../../../view/ui/handle-test.js';
7
+ import type { DragScope } from './operation.js';
8
+ /**
9
+ * Drag state for an auxiliary handle (provided by an extension implementation)
10
+ *
11
+ * Holds the grabbed handle and the provider it is delegated to. The meaning of the coordinates
12
+ * lives on the provider side, so core merely forwards move / end and writes nothing to the Store.
13
+ */
14
+ export interface AuxiliaryState {
15
+ provider: AuxiliaryHandleProvider;
16
+ hit: AuxiliaryHandleHit;
17
+ /** The last drag event forwarded (for cleanup on paths where dragend is not delivered) */
18
+ lastEvent: DragNormalizedEvent;
19
+ }
20
+ /**
21
+ * Check whether an auxiliary handle drag can be delegated to a provider
22
+ *
23
+ * When no provider is found, or when onHandleDragStart returns false, null is returned and the
24
+ * caller does not start a drag (it falls through to the normal handling).
25
+ */
26
+ export declare function resolveAuxiliaryDrag(hitResult: HandleHitResult, event: DragNormalizedEvent, scope: DragScope): AuxiliaryDrag | null;
@@ -0,0 +1,56 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /** @internal */
4
+ export class AuxiliaryDrag {
5
+ constructor(state) {
6
+ Object.defineProperty(this, "type", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: 'auxiliary'
11
+ });
12
+ Object.defineProperty(this, "state", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: void 0
17
+ });
18
+ this.state = state;
19
+ }
20
+ update(event) {
21
+ if (!this.state)
22
+ return;
23
+ this.state.lastEvent = event;
24
+ this.state.provider.onHandleDragMove(event);
25
+ }
26
+ /**
27
+ * Tell the delegate that the auxiliary handle drag has ended
28
+ *
29
+ * On paths where no end event is delivered (when the mode side does not have an event), the
30
+ * last event that was forwarded is used instead. The delegate always receives end exactly once.
31
+ */
32
+ finish(event) {
33
+ if (!this.state)
34
+ return;
35
+ const { provider, lastEvent } = this.state;
36
+ this.state = null;
37
+ provider.onHandleDragEnd(event ?? lastEvent);
38
+ }
39
+ }
40
+ /**
41
+ * Check whether an auxiliary handle drag can be delegated to a provider
42
+ *
43
+ * When no provider is found, or when onHandleDragStart returns false, null is returned and the
44
+ * caller does not start a drag (it falls through to the normal handling).
45
+ */
46
+ export function resolveAuxiliaryDrag(hitResult, event, scope) {
47
+ const hit = hitResult.auxiliary;
48
+ if (!hit)
49
+ return null;
50
+ const provider = scope?.auxiliaryHandles.get(hit.providerId);
51
+ if (!provider)
52
+ return null;
53
+ if (!provider.onHandleDragStart(hit, event))
54
+ return null;
55
+ return new AuxiliaryDrag({ provider, hit, lastEvent: event });
56
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,171 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Whether a feature still holds every field a drag wrote to it
5
+ *
6
+ * The values are plain data (coordinates and properties), so a structural comparison is
7
+ * enough. It runs only when a drag is aborted.
8
+ */
9
+ function holdsFields(feature, fields) {
10
+ const source = feature;
11
+ for (const [key, value] of Object.entries(fields)) {
12
+ if (JSON.stringify(source[key]) !== JSON.stringify(value))
13
+ return false;
14
+ }
15
+ return true;
16
+ }
17
+ /**
18
+ * The intermediate writes of one drag
19
+ *
20
+ * @internal
21
+ */
22
+ export class IntermediateWrites {
23
+ constructor() {
24
+ /**
25
+ * The last update applied to each feature touched during the drag (feature ID -> last diff
26
+ * written)
27
+ *
28
+ * Writes during a drag are issued as an intermediate state (isIntermediate), so the final
29
+ * state is rewritten as committed using the values recorded here in commit. It holds the diff
30
+ * as-is, including properties and not only coordinates, so scale / rotation from resize and
31
+ * rotate and radiusMeters from a radius change can all be committed through the same container.
32
+ */
33
+ Object.defineProperty(this, "pending", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: new Map()
38
+ });
39
+ /**
40
+ * The value each touched field had before the drag first wrote it (feature ID -> fields)
41
+ *
42
+ * An aborted drag writes these back, so the feature returns to the shape it had when the
43
+ * drag started, whether or not the Store applied the intermediate updates to the real data.
44
+ */
45
+ Object.defineProperty(this, "origins", {
46
+ enumerable: true,
47
+ configurable: true,
48
+ writable: true,
49
+ value: new Map()
50
+ });
51
+ /** Every field the drag has written so far, merged (feature ID -> fields) */
52
+ Object.defineProperty(this, "written", {
53
+ enumerable: true,
54
+ configurable: true,
55
+ writable: true,
56
+ value: new Map()
57
+ });
58
+ }
59
+ /**
60
+ * Write one intermediate update during the drag and record the last value for the commit
61
+ *
62
+ * During a drag, writes are issued as "an intermediate state partway through an editing
63
+ * operation", and the final state is committed together by commit when the drag ends.
64
+ * Deciding whether something is intermediate is core's responsibility; how that declaration
65
+ * is handled (persisted as-is, or routed through a temporary sharing path) is left to the
66
+ * Store implementation.
67
+ */
68
+ write(store, id, updates) {
69
+ this.recordOrigin(store, id, updates);
70
+ store.updateFeature(id, updates, { isIntermediate: true });
71
+ this.pending.set(id, updates);
72
+ this.written.set(id, { ...this.written.get(id), ...updates });
73
+ }
74
+ /**
75
+ * Remember the value of each field before the drag writes it for the first time
76
+ */
77
+ recordOrigin(store, id, updates) {
78
+ const feature = store.getFeature(id);
79
+ if (!feature)
80
+ return;
81
+ const origin = this.origins.get(id) ?? {};
82
+ const target = origin;
83
+ const source = feature;
84
+ for (const key of Object.keys(updates)) {
85
+ if (key in target)
86
+ continue;
87
+ target[key] = structuredClone(source[key]);
88
+ }
89
+ this.origins.set(id, origin);
90
+ }
91
+ /**
92
+ * Abort the intermediate updates that never reached a commit, restoring the features
93
+ *
94
+ * On a reset that does not go through the end of the drag (a cancel, a mode switch during a
95
+ * drag, or an external state change applied from outside), the intermediate state
96
+ * ends without being committed. Each feature gets the fields it had when the drag started
97
+ * written back as a last intermediate update, and the discard is then announced with
98
+ * abortIntermediateUpdates. A store that applies intermediate updates to the real data
99
+ * (MemoryStore) is back at the start by the restore; one that holds them apart drops them on
100
+ * the discard. A feature that something else changed during the drag (a change from
101
+ * outside) no longer holds what the drag wrote, and is left as it is. Once committed (after
102
+ * commit) the record is empty, so nothing happens.
103
+ */
104
+ discard(store) {
105
+ if (this.pending.size === 0) {
106
+ this.clearRecords();
107
+ return;
108
+ }
109
+ if (store) {
110
+ const ids = [...this.pending.keys()];
111
+ store.transact(() => {
112
+ for (const id of ids) {
113
+ const origin = this.origins.get(id);
114
+ const written = this.written.get(id);
115
+ const feature = store.getFeature(id);
116
+ if (!origin || !written || !feature || !holdsFields(feature, written))
117
+ continue;
118
+ store.updateFeature(id, origin, { isIntermediate: true });
119
+ }
120
+ });
121
+ store.abortIntermediateUpdates?.(ids);
122
+ }
123
+ this.pending.clear();
124
+ this.clearRecords();
125
+ }
126
+ /**
127
+ * Commit the intermediate updates made during the drag
128
+ *
129
+ * The last value of every feature that was touched (including features that followed along
130
+ * through a shared vertex) is rewritten as a committed update (no options), gathered into a
131
+ * single store.transact. Because it is notified as one StateChanges, a subscriber that records
132
+ * changes can treat this batch as a single step with its existing mechanism.
133
+ *
134
+ * The committed value is simply the last diff that was recorded. That way it does not depend
135
+ * on whether the intermediate updates during the drag were applied to the Store (some Store
136
+ * implementations do not apply intermediate updates to the real data).
137
+ *
138
+ * Only the features that still exist are committed. A feature can disappear during a drag (a
139
+ * deletion from outside, the public API, a plugin); its record is not committed but discarded like
140
+ * an aborted drag, so the commit never updates a missing feature and never lands halfway.
141
+ */
142
+ commit(store) {
143
+ if (this.pending.size === 0)
144
+ return;
145
+ const vanished = [];
146
+ for (const id of this.pending.keys()) {
147
+ if (!store.getFeature(id))
148
+ vanished.push(id);
149
+ }
150
+ if (vanished.length > 0) {
151
+ store.abortIntermediateUpdates?.(vanished);
152
+ for (const id of vanished)
153
+ this.pending.delete(id);
154
+ }
155
+ if (this.pending.size > 0) {
156
+ store.transact(() => {
157
+ for (const [id, updates] of this.pending) {
158
+ store.updateFeature(id, updates);
159
+ }
160
+ });
161
+ }
162
+ // A committed record is not a discard target (distinguished from the abort notification in
163
+ // reset)
164
+ this.pending.clear();
165
+ this.clearRecords();
166
+ }
167
+ clearRecords() {
168
+ this.origins.clear();
169
+ this.written.clear();
170
+ }
171
+ }