@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,350 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Deletes the group if it has become empty (the standard behavior of canvas tools).
5
+ * Called at the end of each path that moves or removes a feature out of a group.
6
+ */
7
+ function deleteGroupIfEmpty(store, groupId) {
8
+ const group = store.getGroup(groupId);
9
+ if (group && group.featureIds.length === 0) {
10
+ store.deleteGroup(groupId);
11
+ }
12
+ }
13
+ /**
14
+ * Moves a feature or a group to another layer
15
+ *
16
+ * @internal
17
+ */
18
+ export function moveToLayer(store, itemId, targetLayerId) {
19
+ const feature = store.getFeature(itemId);
20
+ const group = store.getGroup(itemId);
21
+ if (feature) {
22
+ moveFeatureToLayer(store, feature, itemId, targetLayerId);
23
+ }
24
+ else if (group) {
25
+ moveGroupToLayer(store, group, itemId, targetLayerId);
26
+ }
27
+ }
28
+ function moveFeatureToLayer(store, feature, itemId, targetLayerId) {
29
+ const targetLayer = store.getLayer(targetLayerId);
30
+ if (!targetLayer)
31
+ return;
32
+ // Do nothing when it is already in the same layer
33
+ if (feature.layerId === targetLayerId && !feature.groupId)
34
+ return;
35
+ const previousGroupId = feature.groupId;
36
+ store.transact(() => {
37
+ // When it belongs to a group, remove it from the group
38
+ if (feature.groupId) {
39
+ const currentGroup = store.getGroup(feature.groupId);
40
+ if (currentGroup) {
41
+ store.updateGroup(feature.groupId, {
42
+ featureIds: currentGroup.featureIds.filter((id) => id !== itemId),
43
+ });
44
+ }
45
+ }
46
+ else {
47
+ // When it is a standalone feature, remove it from the original layer
48
+ const sourceLayer = store.getLayer(feature.layerId);
49
+ if (sourceLayer) {
50
+ const sourceOrder = sourceLayer.order.filter((id) => id !== itemId);
51
+ store.updateLayer(sourceLayer.id, { order: sourceOrder });
52
+ }
53
+ }
54
+ // Add it to the new layer
55
+ store.updateLayer(targetLayerId, { order: [...targetLayer.order, itemId] });
56
+ // Update the layerId of the feature and clear its groupId
57
+ store.updateFeature(itemId, { layerId: targetLayerId, groupId: undefined });
58
+ // Delete the source group when it has become empty
59
+ if (previousGroupId) {
60
+ deleteGroupIfEmpty(store, previousGroupId);
61
+ }
62
+ });
63
+ }
64
+ function moveGroupToLayer(store, group, itemId, targetLayerId) {
65
+ // Find the layer the group belongs to
66
+ let sourceLayerId = null;
67
+ for (const layer of store.getAllLayers()) {
68
+ if (layer.order.includes(itemId)) {
69
+ sourceLayerId = layer.id;
70
+ break;
71
+ }
72
+ }
73
+ if (sourceLayerId && sourceLayerId !== targetLayerId) {
74
+ const sourceLayer = store.getLayer(sourceLayerId);
75
+ const targetLayer = store.getLayer(targetLayerId);
76
+ if (sourceLayer && targetLayer) {
77
+ store.transact(() => {
78
+ // Remove it from the original layer
79
+ const sourceOrder = sourceLayer.order.filter((id) => id !== itemId);
80
+ store.updateLayer(sourceLayerId, { order: sourceOrder });
81
+ // Add it to the new layer
82
+ store.updateLayer(targetLayerId, { order: [...targetLayer.order, itemId] });
83
+ // Update the layerId of the features inside the group
84
+ for (const featureId of group.featureIds) {
85
+ store.updateFeature(featureId, { layerId: targetLayerId });
86
+ }
87
+ });
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * Adds a feature to a group
93
+ *
94
+ * @internal
95
+ */
96
+ export function addFeatureToGroup(store, featureId, groupId, index) {
97
+ const feature = store.getFeature(featureId);
98
+ const group = store.getGroup(groupId);
99
+ if (!feature || !group)
100
+ return;
101
+ // Do nothing when it is already included in this group
102
+ if (group.featureIds.includes(featureId))
103
+ return;
104
+ // Find the layer the group belongs to
105
+ let targetLayerId = null;
106
+ for (const layer of store.getAllLayers()) {
107
+ if (layer.order.includes(groupId)) {
108
+ targetLayerId = layer.id;
109
+ break;
110
+ }
111
+ }
112
+ store.transact(() => {
113
+ // When the feature already belongs to another group, remove it from that group
114
+ if (feature.groupId && feature.groupId !== groupId) {
115
+ const oldGroupId = feature.groupId;
116
+ const oldGroup = store.getGroup(oldGroupId);
117
+ if (oldGroup) {
118
+ store.updateGroup(oldGroupId, {
119
+ featureIds: oldGroup.featureIds.filter((id) => id !== featureId),
120
+ });
121
+ // Delete the source group when it has become empty
122
+ deleteGroupIfEmpty(store, oldGroupId);
123
+ }
124
+ }
125
+ // Remove the feature from the order of the layer (when it is included in order on its own)
126
+ const layer = store.getLayer(feature.layerId);
127
+ if (layer?.order.includes(featureId)) {
128
+ const newOrder = layer.order.filter((id) => id !== featureId);
129
+ store.updateLayer(layer.id, { order: newOrder });
130
+ }
131
+ // Add the feature to the group (when an index is given, insert it at that position)
132
+ const newFeatureIds = [...group.featureIds];
133
+ if (index !== undefined && index >= 0 && index <= newFeatureIds.length) {
134
+ newFeatureIds.splice(index, 0, featureId);
135
+ }
136
+ else {
137
+ newFeatureIds.push(featureId);
138
+ }
139
+ store.updateGroup(groupId, { featureIds: newFeatureIds });
140
+ // Set the groupId and the layerId (when needed) on the feature
141
+ const updates = { groupId };
142
+ if (targetLayerId && feature.layerId !== targetLayerId) {
143
+ updates.layerId = targetLayerId;
144
+ }
145
+ store.updateFeature(featureId, updates);
146
+ });
147
+ }
148
+ /**
149
+ * Removes a feature from a group
150
+ *
151
+ * @internal
152
+ */
153
+ export function removeFeatureFromGroup(store, featureId) {
154
+ const feature = store.getFeature(featureId);
155
+ if (!feature?.groupId)
156
+ return;
157
+ const group = store.getGroup(feature.groupId);
158
+ if (!group)
159
+ return;
160
+ // Find the layer the group belongs to
161
+ let layerId = null;
162
+ for (const layer of store.getAllLayers()) {
163
+ if (layer.order.includes(group.id)) {
164
+ layerId = layer.id;
165
+ break;
166
+ }
167
+ }
168
+ store.transact(() => {
169
+ // Remove the feature from the group
170
+ const newFeatureIds = group.featureIds.filter((id) => id !== featureId);
171
+ store.updateGroup(group.id, { featureIds: newFeatureIds });
172
+ // Remove the groupId from the feature
173
+ store.updateFeature(featureId, { groupId: undefined });
174
+ // Add the feature to the order of the layer (right after the group)
175
+ if (layerId) {
176
+ const layer = store.getLayer(layerId);
177
+ if (layer) {
178
+ const groupIndex = layer.order.indexOf(group.id);
179
+ const newOrder = [...layer.order];
180
+ newOrder.splice(groupIndex + 1, 0, featureId);
181
+ store.updateLayer(layerId, { order: newOrder });
182
+ }
183
+ }
184
+ // Delete the group when it has become empty (after the feature has been moved out
185
+ // directly under the layer)
186
+ deleteGroupIfEmpty(store, group.id);
187
+ });
188
+ }
189
+ /**
190
+ * Groups the selected features
191
+ *
192
+ * @returns The group ID, or null when grouping was not possible
193
+ *
194
+ * @internal
195
+ */
196
+ export function groupSelection(store, generateFeatureId, autoNameGenerator) {
197
+ const selection = store.getSelection();
198
+ // Do nothing when it is not a feature selection
199
+ if (selection.type !== 'feature')
200
+ return null;
201
+ const selectedIds = selection.ids;
202
+ // Condition 1: two or more features are selected
203
+ const features = selectedIds
204
+ .map((id) => store.getFeature(id))
205
+ .filter((f) => f !== undefined);
206
+ if (features.length < 2)
207
+ return null;
208
+ // Condition 2: they all belong to the same layer
209
+ const layerIds = new Set(features.map((f) => f.layerId));
210
+ if (layerIds.size !== 1)
211
+ return null;
212
+ const layerId = features[0].layerId;
213
+ // Condition 3: they do not yet belong to a group that actually exists.
214
+ // When the groupId is a stale value that points to a deleted group, it is regarded as
215
+ // belonging to nothing and regrouping is allowed (createGroup overwrites the groupId of the
216
+ // members with the new value, so it is repaired automatically here).
217
+ if (features.some((f) => f.groupId !== undefined && store.getGroup(f.groupId) !== undefined)) {
218
+ return null;
219
+ }
220
+ // Create the group
221
+ const groupId = generateFeatureId();
222
+ const groupName = autoNameGenerator.generateGroupName();
223
+ const group = {
224
+ id: groupId,
225
+ name: groupName,
226
+ featureIds: [...selectedIds],
227
+ locked: false,
228
+ visible: true,
229
+ };
230
+ store.transact(() => {
231
+ // Remove the feature IDs from the order of the layer and add the group ID
232
+ const layer = store.getLayer(layerId);
233
+ if (layer) {
234
+ // Find the frontmost one (the largest index) among the selected features
235
+ let frontmostSelectedId = null;
236
+ for (let i = layer.order.length - 1; i >= 0; i--) {
237
+ if (selectedIds.includes(layer.order[i])) {
238
+ frontmostSelectedId = layer.order[i];
239
+ break;
240
+ }
241
+ }
242
+ // Build the new order (insert the group at the position of the frontmost selected feature)
243
+ const newOrder = [];
244
+ for (const id of layer.order) {
245
+ if (selectedIds.includes(id)) {
246
+ // Insert the group at the position of the frontmost selected feature
247
+ if (id === frontmostSelectedId) {
248
+ newOrder.push(groupId);
249
+ }
250
+ // The selected features are excluded from the order
251
+ }
252
+ else {
253
+ newOrder.push(id);
254
+ }
255
+ }
256
+ // Even when not a single selected feature is included in order (for example when they
257
+ // are missing from order because of stale data), the group is appended at the tail so
258
+ // that it is not left out of order.
259
+ if (frontmostSelectedId === null) {
260
+ newOrder.push(groupId);
261
+ }
262
+ store.updateLayer(layerId, { order: newOrder });
263
+ }
264
+ // Create the group
265
+ store.createGroup(group);
266
+ });
267
+ return groupId;
268
+ }
269
+ /**
270
+ * Dissolves a group (outside a transaction, a pure mutation).
271
+ * It removes the group from the order, expands its member features into the same position,
272
+ * and then deletes the group itself. The caller must wrap it in store.transact.
273
+ */
274
+ function dissolveGroup(store, groupId) {
275
+ const group = store.getGroup(groupId);
276
+ if (!group)
277
+ return;
278
+ // Identify the layer the group belongs to
279
+ let targetLayerId = null;
280
+ for (const layer of store.getAllLayers()) {
281
+ if (layer.order.includes(groupId)) {
282
+ targetLayerId = layer.id;
283
+ break;
284
+ }
285
+ }
286
+ if (!targetLayerId)
287
+ return;
288
+ // Remove the group ID from the order of the layer and expand the feature IDs into the same
289
+ // position
290
+ const layer = store.getLayer(targetLayerId);
291
+ if (layer) {
292
+ const groupIndex = layer.order.indexOf(groupId);
293
+ const newOrder = [...layer.order];
294
+ newOrder.splice(groupIndex, 1, ...group.featureIds);
295
+ store.updateLayer(targetLayerId, { order: newOrder });
296
+ }
297
+ // Delete the group
298
+ store.deleteGroup(groupId);
299
+ }
300
+ /**
301
+ * Dissolves the given group (it does not depend on the selection).
302
+ * For "ungroup that group" in a panel menu and the like.
303
+ *
304
+ * @internal
305
+ */
306
+ export function ungroupGroup(store, groupId) {
307
+ store.transact(() => {
308
+ dissolveGroup(store, groupId);
309
+ });
310
+ }
311
+ /**
312
+ * Takes the selection out of the group structure (following Felt).
313
+ *
314
+ * - When a group is selected -> that group is dissolved (its children are expanded into the
315
+ * original position)
316
+ * - When a member feature of a group is selected -> only that feature is taken out of the
317
+ * group (the group is kept; the member is placed right after the group by
318
+ * removeFeatureFromGroup, and the group is deleted automatically when it becomes empty).
319
+ * The group is not dissolved as a whole
320
+ * - Otherwise (a feature that is not a member / no selection) -> nothing is done
321
+ *
322
+ * Even with several targets it is gathered into one transaction, making it one undo unit.
323
+ *
324
+ * @internal
325
+ */
326
+ export function ungroupSelection(store) {
327
+ const selection = store.getSelection();
328
+ if (selection.ids.length === 0)
329
+ return;
330
+ // A group selection -> dissolve
331
+ if (selection.type === 'group') {
332
+ store.transact(() => {
333
+ for (const groupId of selection.ids) {
334
+ dissolveGroup(store, groupId);
335
+ }
336
+ });
337
+ return;
338
+ }
339
+ // A feature selection -> take only the selected members out of the group (do not dissolve)
340
+ if (selection.type === 'feature') {
341
+ const memberIds = selection.ids.filter((id) => store.getFeature(id)?.groupId !== undefined);
342
+ if (memberIds.length === 0)
343
+ return;
344
+ store.transact(() => {
345
+ for (const id of memberIds) {
346
+ removeFeatureFromGroup(store, id);
347
+ }
348
+ });
349
+ }
350
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Resize operation
3
+ *
4
+ * The operation that resizes features. It computes in Web Mercator (see mercator-plane.ts),
5
+ * so a handle follows the pointer on the map at any latitude. The extension points of the
6
+ * draw instance are passed in as an argument ({@link ResizeExtensions}).
7
+ */
8
+ import type { CustomResizeResult } from '../extension/index.js';
9
+ import type { HandleType } from '../shared/config/constants.js';
10
+ import type { BoundingBoxCoords } from '../shared/types/selection-box.js';
11
+ import type { Feature, FeatureCoordinates } from '../store/types.js';
12
+ /**
13
+ * A custom resize computation of a feature type
14
+ */
15
+ export type ResizeCalculator = (handle: HandleType, state: ResizeState, currentLngLat: {
16
+ lng: number;
17
+ lat: number;
18
+ }, feature: Feature) => CustomResizeResult | null;
19
+ /**
20
+ * The extension points the resize reads from the draw instance
21
+ *
22
+ * The draw instance's selection extension registry satisfies it.
23
+ */
24
+ export interface ResizeExtensions {
25
+ getResizeStrategy(type: string): 'scale' | 'coordinates' | undefined;
26
+ getCustomResizeCalculator(type: string): ResizeCalculator | undefined;
27
+ }
28
+ /**
29
+ * The result of the resize
30
+ */
31
+ export interface ResizeResult {
32
+ coordinates: FeatureCoordinates;
33
+ /** The new scale value of a feature that has a scale property */
34
+ scale?: number;
35
+ /** The new radius for a Circle (meters) */
36
+ radiusMeters?: number;
37
+ /** The width (pixels) - for a custom resize */
38
+ width?: number;
39
+ /** The height (pixels) - for a custom resize */
40
+ height?: number;
41
+ }
42
+ /**
43
+ * The state of a resize drag, captured when the drag starts.
44
+ */
45
+ export interface ResizeState {
46
+ /** The handle being dragged */
47
+ handle: HandleType;
48
+ /** The pointer position at the start, in degrees */
49
+ startLngLat: {
50
+ lng: number;
51
+ lat: number;
52
+ };
53
+ /** The selection box at the start, corners in degrees */
54
+ startBbox: BoundingBoxCoords;
55
+ /** The coordinates of each feature at the start, by feature id */
56
+ initialCoordinates: Map<string, FeatureCoordinates>;
57
+ /** The scale of a feature that has a scale property, at the start */
58
+ initialScales: Map<string, number>;
59
+ /** The radius of a Circle at the start (meters) */
60
+ initialRadiusMeters: Map<string, number>;
61
+ /** The width at the start (pixels) - for a custom resize */
62
+ initialWidth: Map<string, number>;
63
+ /** The height at the start (pixels) - for a custom resize */
64
+ initialHeight: Map<string, number>;
65
+ /**
66
+ * The extent of the bounding box (Web Mercator world units, 1 = the width of the world)
67
+ * below which it is not stretched along that axis. The caller converts a screen distance
68
+ * at the current zoom. 0 when omitted (only a box of no extent is left alone)
69
+ */
70
+ minAxisExtent?: number;
71
+ }
@@ -0,0 +1,252 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { fromPlane, toPlane } from '../shared/math/mercator-plane.js';
4
+ import { mapCoordinatesDeep } from '../shared/utils/coordinates.js';
5
+ import { getCircleRadius, getImageProperties } from '../shared/utils/property.js';
6
+ /**
7
+ * Decides whether a feature has a scale property
8
+ *
9
+ * For features that have a scale property (Text, Image, custom features and so on)
10
+ */
11
+ function hasScaleProperty(feature, extensions) {
12
+ // Get resizeStrategy from the draw instance's registry
13
+ const strategy = extensions?.getResizeStrategy(feature.type);
14
+ if (strategy === 'scale') {
15
+ return true;
16
+ }
17
+ if (strategy === 'coordinates') {
18
+ return false;
19
+ }
20
+ // The built-in types of the core
21
+ if (feature.type === 'Image') {
22
+ return true;
23
+ }
24
+ // Generic check (decided by the presence of a scale property)
25
+ return (feature.properties !== null &&
26
+ typeof feature.properties === 'object' &&
27
+ 'scale' in feature.properties);
28
+ }
29
+ /**
30
+ * Gets the value of the scale property of a feature
31
+ */
32
+ function getFeatureScale(feature) {
33
+ if (feature.type === 'Image') {
34
+ const props = getImageProperties(feature);
35
+ return props.scale ?? 1;
36
+ }
37
+ const props = feature.properties;
38
+ return typeof props.scale === 'number' ? props.scale : 1;
39
+ }
40
+ /**
41
+ * Gets the anchor (the fixed point) from the handle position
42
+ */
43
+ function getAnchorFromHandle(handle, bbox) {
44
+ switch (handle) {
45
+ case 'resize-nw':
46
+ return { anchor: bbox.bottomRight, scaleX: -1, scaleY: 1 };
47
+ case 'resize-n':
48
+ return {
49
+ anchor: [(bbox.bottomLeft[0] + bbox.bottomRight[0]) / 2, bbox.bottomLeft[1]],
50
+ scaleX: 0,
51
+ scaleY: 1,
52
+ };
53
+ case 'resize-ne':
54
+ return { anchor: bbox.bottomLeft, scaleX: 1, scaleY: 1 };
55
+ case 'resize-e':
56
+ return {
57
+ anchor: [
58
+ (bbox.topLeft[0] + bbox.bottomLeft[0]) / 2,
59
+ (bbox.topLeft[1] + bbox.bottomLeft[1]) / 2,
60
+ ],
61
+ scaleX: 1,
62
+ scaleY: 0,
63
+ };
64
+ case 'resize-se':
65
+ return { anchor: bbox.topLeft, scaleX: 1, scaleY: -1 };
66
+ case 'resize-s':
67
+ return {
68
+ anchor: [(bbox.topLeft[0] + bbox.topRight[0]) / 2, bbox.topLeft[1]],
69
+ scaleX: 0,
70
+ scaleY: -1,
71
+ };
72
+ case 'resize-sw':
73
+ return { anchor: bbox.topRight, scaleX: -1, scaleY: -1 };
74
+ case 'resize-w':
75
+ return {
76
+ anchor: [
77
+ (bbox.topRight[0] + bbox.bottomRight[0]) / 2,
78
+ (bbox.topRight[1] + bbox.bottomRight[1]) / 2,
79
+ ],
80
+ scaleX: -1,
81
+ scaleY: 0,
82
+ };
83
+ default:
84
+ return { anchor: bbox.center, scaleX: 1, scaleY: 1 };
85
+ }
86
+ }
87
+ /**
88
+ * Scales a coordinate in the transform plane around an anchor given in the plane
89
+ */
90
+ function scaleCoordinate(coord, anchor, scaleX, scaleY) {
91
+ const [x, y] = toPlane(coord);
92
+ return fromPlane(anchor[0] + (x - anchor[0]) * scaleX, anchor[1] + (y - anchor[1]) * scaleY);
93
+ }
94
+ /**
95
+ * Scales an array of coordinates
96
+ *
97
+ * It uses a common traversal that does not depend on the nesting depth, so Multi
98
+ * geometries (a MultiPolygon is nested 4 levels deep) can be transformed as they
99
+ * are.
100
+ */
101
+ function scaleCoordinates(coords, anchor, scaleX, scaleY) {
102
+ return mapCoordinatesDeep(coords, (coord) => scaleCoordinate(coord, anchor, scaleX, scaleY));
103
+ }
104
+ /**
105
+ * The distance between 2 points of the transform plane
106
+ */
107
+ function planeDistance(a, b) {
108
+ return Math.hypot(a[0] - b[0], a[1] - b[1]);
109
+ }
110
+ /**
111
+ * Computes the resize
112
+ *
113
+ * @param extensions The draw instance's extension points (custom resize calculators)
114
+ *
115
+ * @internal
116
+ */
117
+ export function computeResize(state, currentLngLat, features, extensions) {
118
+ const { handle, startLngLat, startBbox } = state;
119
+ const { anchor: anchorLngLat, scaleX: scaleDirectionX, scaleY: scaleDirectionY, } = getAnchorFromHandle(handle, startBbox);
120
+ const anchor = toPlane(anchorLngLat);
121
+ const start = toPlane([startLngLat.lng, startLngLat.lat]);
122
+ const current = toPlane([currentLngLat.lng, currentLngLat.lat]);
123
+ // Compute the scale from the distance to the anchor (this handles rotation)
124
+ const startDistance = planeDistance(start, anchor);
125
+ const currentDistance = planeDistance(current, anchor);
126
+ // Compute the scale from the rate of change of the distance
127
+ // Note: for a small feature (Text and so on) startDistance becomes a very small value, so
128
+ // only a distance of exactly zero is left alone
129
+ let uniformScale = 1;
130
+ if (startDistance > 0) {
131
+ uniformScale = currentDistance / startDistance;
132
+ }
133
+ // Limit the minimum scale
134
+ uniformScale = Math.max(uniformScale, 0.1);
135
+ // The scale along the axes (for non-rotated features)
136
+ // Compute the amount of movement
137
+ const dx = current[0] - start[0];
138
+ const dy = current[1] - start[1];
139
+ // The size of the bounding box (valid only when it is not rotated). A box thinner than the
140
+ // caller's minimum extent (a screen distance) is not stretched along that axis, because the
141
+ // division would turn a pixel of pointer movement into a huge scale
142
+ const topLeft = toPlane(startBbox.topLeft);
143
+ const bboxWidth = Math.abs(toPlane(startBbox.topRight)[0] - topLeft[0]);
144
+ const bboxHeight = Math.abs(topLeft[1] - toPlane(startBbox.bottomLeft)[1]);
145
+ const minExtent = Math.max(0, state.minAxisExtent ?? 0);
146
+ let scaleX = 1;
147
+ let scaleY = 1;
148
+ if (scaleDirectionX !== 0 && bboxWidth > minExtent) {
149
+ scaleX = 1 + (scaleDirectionX * dx) / bboxWidth;
150
+ }
151
+ if (scaleDirectionY !== 0 && bboxHeight > minExtent) {
152
+ scaleY = 1 + (scaleDirectionY * dy) / bboxHeight;
153
+ }
154
+ // Limit the minimum scale
155
+ scaleX = Math.max(scaleX, 0.1);
156
+ scaleY = Math.max(scaleY, 0.1);
157
+ // Compute the new coordinates of each feature
158
+ const result = new Map();
159
+ for (const feature of features) {
160
+ const initialCoords = state.initialCoordinates.get(feature.id);
161
+ if (!initialCoords)
162
+ continue;
163
+ // Use the custom resize calculator first if there is one
164
+ const customCalculator = extensions?.getCustomResizeCalculator(feature.type);
165
+ if (customCalculator) {
166
+ const customResult = customCalculator(handle, state, currentLngLat, feature);
167
+ if (customResult) {
168
+ result.set(feature.id, {
169
+ coordinates: customResult.coordinates,
170
+ width: customResult.width,
171
+ height: customResult.height,
172
+ });
173
+ continue;
174
+ }
175
+ }
176
+ // Which features scale by property was decided when the resize started (initialScales)
177
+ if (state.initialScales.has(feature.id)) {
178
+ // For a feature that has a scale property:
179
+ // with the anchor as the fixed point, scale the center coordinate too and change scale
180
+ const initialScale = state.initialScales.get(feature.id) ?? 1;
181
+ const newScale = initialScale * uniformScale;
182
+ const newCoords = scaleCoordinates(initialCoords, anchor, uniformScale, uniformScale);
183
+ result.set(feature.id, {
184
+ coordinates: newCoords,
185
+ scale: newScale,
186
+ });
187
+ }
188
+ else if (feature.type === 'Circle') {
189
+ // For a Circle: scale the center coordinate and scale the radius too
190
+ const initialRadius = state.initialRadiusMeters.get(feature.id) ?? 0;
191
+ const newRadius = initialRadius * uniformScale;
192
+ const newCoords = scaleCoordinates(initialCoords, anchor, uniformScale, uniformScale);
193
+ result.set(feature.id, {
194
+ coordinates: newCoords,
195
+ radiusMeters: newRadius,
196
+ });
197
+ }
198
+ else {
199
+ // For Point, LineString, Polygon and Freehand: change only the coordinates
200
+ const newCoords = scaleCoordinates(initialCoords, anchor, scaleX, scaleY);
201
+ result.set(feature.id, { coordinates: newCoords });
202
+ }
203
+ }
204
+ return result;
205
+ }
206
+ /**
207
+ * Starts the resize operation
208
+ *
209
+ * @param extensions The draw instance's extension points (resize strategies of custom types)
210
+ * @param minAxisExtent The extent of the bounding box (Web Mercator world units) below which
211
+ * it is not stretched along that axis; the caller converts a screen distance at its zoom
212
+ *
213
+ * @internal
214
+ */
215
+ export function startResize(handle, startLngLat, bbox, features, extensions, minAxisExtent = 0) {
216
+ const initialCoordinates = new Map();
217
+ const initialScales = new Map();
218
+ const initialRadiusMeters = new Map();
219
+ const initialWidth = new Map();
220
+ const initialHeight = new Map();
221
+ for (const feature of features) {
222
+ initialCoordinates.set(feature.id, JSON.parse(JSON.stringify(feature.coordinates)));
223
+ // For a feature that has a scale property, store the initial scale
224
+ if (hasScaleProperty(feature, extensions)) {
225
+ initialScales.set(feature.id, getFeatureScale(feature));
226
+ }
227
+ // For a Circle, store the initial radius
228
+ if (feature.type === 'Circle') {
229
+ const radiusMeters = getCircleRadius(feature);
230
+ initialRadiusMeters.set(feature.id, radiusMeters ?? 0);
231
+ }
232
+ // For a feature that has width / height properties (Note and so on), store the initial size
233
+ const props = feature.properties;
234
+ if (typeof props.width === 'number') {
235
+ initialWidth.set(feature.id, props.width);
236
+ }
237
+ if (typeof props.height === 'number') {
238
+ initialHeight.set(feature.id, props.height);
239
+ }
240
+ }
241
+ return {
242
+ handle,
243
+ startLngLat,
244
+ startBbox: bbox,
245
+ initialCoordinates,
246
+ initialScales,
247
+ initialRadiusMeters,
248
+ initialWidth,
249
+ initialHeight,
250
+ minAxisExtent,
251
+ };
252
+ }
@@ -0,0 +1,17 @@
1
+ import type { FeatureCoordinates } from '../store/types.js';
2
+ /**
3
+ * The extension points the rotation reads from the draw instance
4
+ *
5
+ * The draw instance's selection extension registry satisfies it.
6
+ */
7
+ export interface RotateExtensions {
8
+ getResizeStrategy(type: string): 'scale' | 'coordinates' | undefined;
9
+ }
10
+ /**
11
+ * The result of the rotation
12
+ */
13
+ export interface RotateResult {
14
+ coordinates: FeatureCoordinates;
15
+ /** The new rotation value of a feature that has a rotation property (degrees) */
16
+ rotation?: number;
17
+ }