@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,149 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { applyMarginToBoundingBox } from '../../shared/math/index.js';
4
+ import { computeBoundingBox, hasZeroArea, resolvePointFrameExtentWith, } from './selection-ui/index.js';
5
+ /**
6
+ * Compute the bounding box with a margin of a feature in geographic coordinates
7
+ *
8
+ * Supports every feature type:
9
+ * - Point: the icon size + the margin are computed in screen coordinates and converted
10
+ * into geographic coordinates
11
+ * - LineString/Polygon: the margin is applied by applyMarginToBoundingBox
12
+ *
13
+ * @param feature The target feature
14
+ * @param transform The coordinate transform
15
+ * @param config The selection UI configuration
16
+ * @returns The bounding box with a margin in geographic coordinates, or null when it
17
+ * cannot be computed
18
+ */
19
+ export function computeFeatureGeoBoundingBox(feature, transform, config, extensions) {
20
+ const margin = config.boundingBox.margin;
21
+ // Compute the bbox for the selection UI (the draw instance's custom types included)
22
+ const selectionBbox = computeBoundingBox(feature, extensions);
23
+ if (!selectionBbox)
24
+ return null;
25
+ // Zero area (a single-coordinate feature such as Point) is expanded in pixels on screen
26
+ if (hasZeroArea(selectionBbox)) {
27
+ return computeSingleCoordGeoBoundingBox(feature, selectionBbox.center, transform, margin, extensions);
28
+ }
29
+ // A bbox that has a size is expanded by the margin
30
+ const marginedBbox = applyMarginToBoundingBox(selectionBbox, margin, transform);
31
+ return {
32
+ ...marginedBbox,
33
+ center: selectionBbox.center,
34
+ };
35
+ }
36
+ /**
37
+ * Compute the combined geographic bounding box of several features (with a margin)
38
+ *
39
+ * @param features The array of target features
40
+ * @param transform The coordinate transform
41
+ * @param config The selection UI configuration
42
+ * @param extensions The draw instance's extension points (custom bounding boxes and point
43
+ * frame extents)
44
+ * @returns The bounding box with a margin in geographic coordinates, or null when it
45
+ * cannot be computed
46
+ */
47
+ export function computeCombinedGeoBoundingBox(features, transform, config, extensions) {
48
+ if (features.length === 0)
49
+ return null;
50
+ // For a single feature the OBB is returned as is
51
+ if (features.length === 1) {
52
+ return computeFeatureGeoBoundingBox(features[0], transform, config, extensions);
53
+ }
54
+ // For several features, an AABB containing all the vertices is computed
55
+ let minLng = Number.POSITIVE_INFINITY;
56
+ let maxLng = Number.NEGATIVE_INFINITY;
57
+ let minLat = Number.POSITIVE_INFINITY;
58
+ let maxLat = Number.NEGATIVE_INFINITY;
59
+ for (const feature of features) {
60
+ const bbox = computeFeatureGeoBoundingBox(feature, transform, config, extensions);
61
+ if (!bbox)
62
+ continue;
63
+ // Update the min/max of the 4 corners
64
+ const corners = [bbox.topLeft, bbox.topRight, bbox.bottomRight, bbox.bottomLeft];
65
+ for (const corner of corners) {
66
+ minLng = Math.min(minLng, corner[0]);
67
+ maxLng = Math.max(maxLng, corner[0]);
68
+ minLat = Math.min(minLat, corner[1]);
69
+ maxLat = Math.max(maxLat, corner[1]);
70
+ }
71
+ }
72
+ if (!Number.isFinite(minLng))
73
+ return null;
74
+ return {
75
+ topLeft: [minLng, maxLat],
76
+ topRight: [maxLng, maxLat],
77
+ bottomRight: [maxLng, minLat],
78
+ bottomLeft: [minLng, minLat],
79
+ center: [(minLng + maxLng) / 2, (minLat + maxLat) / 2],
80
+ };
81
+ }
82
+ /**
83
+ * Compute the bounding box with a margin of a single-coordinate feature in geographic coordinates
84
+ *
85
+ * The extent of the frame of a point (registrable per type; 12px square when unregistered)
86
+ * plus the margin is computed in screen coordinates and converted into geographic ones.
87
+ * The coordinate received is the center of the bbox (since features other than Point can
88
+ * also be zero-area, e.g. a MultiPoint with a single point; coordinates must not be
89
+ * treated as a Coordinate).
90
+ */
91
+ function computeSingleCoordGeoBoundingBox(feature, coord, transform, margin, extensions) {
92
+ const center = transform.project(coord);
93
+ // The half width and half height of the frame of the point + the margin
94
+ const extent = extensions
95
+ ? extensions.resolvePointFrameExtent(feature)
96
+ : resolvePointFrameExtentWith(undefined, feature);
97
+ const halfWidth = extent.halfWidth + margin;
98
+ const halfHeight = extent.halfHeight + margin;
99
+ // Convert the 4 corners in screen coordinates into geographic coordinates
100
+ const topLeft = transform.unproject({ x: center.x - halfWidth, y: center.y - halfHeight });
101
+ const topRight = transform.unproject({ x: center.x + halfWidth, y: center.y - halfHeight });
102
+ const bottomRight = transform.unproject({ x: center.x + halfWidth, y: center.y + halfHeight });
103
+ const bottomLeft = transform.unproject({ x: center.x - halfWidth, y: center.y + halfHeight });
104
+ return {
105
+ topLeft: [topLeft.lng, topLeft.lat],
106
+ topRight: [topRight.lng, topRight.lat],
107
+ bottomRight: [bottomRight.lng, bottomRight.lat],
108
+ bottomLeft: [bottomLeft.lng, bottomLeft.lat],
109
+ center: coord,
110
+ };
111
+ }
112
+ /**
113
+ * Decide whether a point in geographic coordinates is inside a convex quadrilateral
114
+ *
115
+ * Uses the cross product method. It decides whether the point is inside the convex
116
+ * quadrilateral enclosed by the 4 corners.
117
+ *
118
+ * @param lngLat The geographic coordinate to test [lng, lat]
119
+ * @param bbox The bounding box in geographic coordinates
120
+ * @returns true when the point is inside the bbox
121
+ */
122
+ export function isPointInGeoBoundingBox(lngLat, bbox) {
123
+ // Inside test for a convex quadrilateral (the cross product method)
124
+ const corners = [bbox.topLeft, bbox.topRight, bbox.bottomRight, bbox.bottomLeft];
125
+ // For each edge, decide which side the point is on
126
+ // If it is on the same side for every edge, it is inside
127
+ let sign = null;
128
+ for (let i = 0; i < 4; i++) {
129
+ const p1 = corners[i];
130
+ const p2 = corners[(i + 1) % 4];
131
+ // The edge vector
132
+ const edgeX = p2[0] - p1[0];
133
+ const edgeY = p2[1] - p1[1];
134
+ // The vector to the point
135
+ const toPointX = lngLat[0] - p1[0];
136
+ const toPointY = lngLat[1] - p1[1];
137
+ // The cross product (2D)
138
+ const cross = edgeX * toPointY - edgeY * toPointX;
139
+ if (sign === null) {
140
+ sign = cross >= 0 ? 1 : -1;
141
+ }
142
+ else {
143
+ if ((cross >= 0 ? 1 : -1) !== sign) {
144
+ return false;
145
+ }
146
+ }
147
+ }
148
+ return true;
149
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,83 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { DEFAULT_BOX_SELECTION_STYLE_CONFIG } from '../../shared/config/rendering.js';
4
+ import { FillShaderManager } from '../renderers/polygon/fill.js';
5
+ import { StrokeRenderer } from '../renderers/stroke.js';
6
+ /**
7
+ * BoxSelectionRenderer
8
+ *
9
+ * @internal
10
+ */
11
+ export class BoxSelectionRenderer {
12
+ constructor(map, gl, styleConfig, pixelRatio) {
13
+ Object.defineProperty(this, "strokeRenderer", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: void 0
18
+ });
19
+ Object.defineProperty(this, "fillShaderManager", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: void 0
24
+ });
25
+ Object.defineProperty(this, "styleConfig", {
26
+ enumerable: true,
27
+ configurable: true,
28
+ writable: true,
29
+ value: void 0
30
+ });
31
+ // The rubber band is a rectangle on the screen, so it is never given elevation: its
32
+ // renderers are built without the draw instance's terrain (they draw flat)
33
+ this.strokeRenderer = new StrokeRenderer(map, gl, pixelRatio);
34
+ this.fillShaderManager = new FillShaderManager(gl);
35
+ this.styleConfig = styleConfig ?? DEFAULT_BOX_SELECTION_STYLE_CONFIG;
36
+ }
37
+ /**
38
+ * Make sure the shader exists
39
+ */
40
+ ensureShader(shaderData) {
41
+ this.strokeRenderer.ensureShader(shaderData);
42
+ this.fillShaderManager.ensureShader(shaderData);
43
+ }
44
+ /**
45
+ * Set the offset uniforms
46
+ */
47
+ setOffsetUniforms(uniforms) {
48
+ this.strokeRenderer.setOffsetUniforms(uniforms);
49
+ this.fillShaderManager.setOffsetUniforms(uniforms);
50
+ }
51
+ /**
52
+ * Draw the box selection UI
53
+ */
54
+ draw(boxSelection, projectionData, zoom) {
55
+ const { startPoint, endPoint } = boxSelection;
56
+ // Compute the 4 vertices of the rectangle (a closed ring)
57
+ const ring = [
58
+ [startPoint[0], startPoint[1]],
59
+ [endPoint[0], startPoint[1]],
60
+ [endPoint[0], endPoint[1]],
61
+ [startPoint[0], endPoint[1]],
62
+ [startPoint[0], startPoint[1]], // closing it
63
+ ];
64
+ // Draw the fill
65
+ this.fillShaderManager.drawPolygon(ring, this.styleConfig.fillColor, projectionData, zoom);
66
+ // Draw the frame (a dotted line)
67
+ const strokeStyle = {
68
+ width: this.styleConfig.strokeWidth,
69
+ color: this.styleConfig.strokeColor,
70
+ opacity: this.styleConfig.strokeOpacity,
71
+ lineStyle: 'dashed',
72
+ dashArray: this.styleConfig.dashArray,
73
+ };
74
+ this.strokeRenderer.draw(ring, strokeStyle, { widthUnit: 'pixels', closed: true }, zoom, projectionData);
75
+ }
76
+ /**
77
+ * Dispose of the resources
78
+ */
79
+ dispose() {
80
+ this.strokeRenderer.dispose();
81
+ this.fillShaderManager.dispose();
82
+ }
83
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,437 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { applyMarginToBoundingBox } from '../../shared/math/index.js';
4
+ import { nearestLongitude } from '../../shared/math/longitude.js';
5
+ import { computeCombinedGeoBoundingBox, isPointInGeoBoundingBox } from './bounds.js';
6
+ import { resolveMidpointCoordinate, resolveVertexCoordinate } from './handle-thinning.js';
7
+ import { computeCircleRadiusHandle, computeMidpointHandles, computeResizeHandles, computeRotateHandle, computeVertexHandles, supportsVertexEditing, } from './handles.js';
8
+ import { computeBoundingBox, computeCombinedBoundingBox, hasZeroArea, } from './selection-ui/index.js';
9
+ /**
10
+ * A transform that projects every longitude on the copy of the world nearest to the pointer
11
+ *
12
+ * The handles are tested around the pointer. Across the antimeridian the feature on the other
13
+ * side of the line is drawn as a second copy, moved by 360 degrees, while its coordinates stay
14
+ * stored in [-180, 180] and the pointer unprojects to the unwrapped longitude of the view. The
15
+ * copy nearest to the pointer is the copy drawn there, so a handle is projected on it. Away from
16
+ * the antimeridian no longitude moves (nearestLongitude leaves anything within 180 degrees).
17
+ */
18
+ function alignToPointer(transform, screenPoint) {
19
+ const reference = transform.unproject(screenPoint).lng;
20
+ return {
21
+ project: (lngLat) => transform.project([nearestLongitude(lngLat[0], reference), lngLat[1]]),
22
+ unproject: (point) => transform.unproject(point),
23
+ };
24
+ }
25
+ /**
26
+ * Determines, in screen coordinates, whether the point is inside the handle's rectangle
27
+ *
28
+ * Builds a rectangle from the handle's center position and radius (size/2), and determines
29
+ * whether the click position is inside that rectangle.
30
+ */
31
+ function isPointInHandleRect(screenPoint, handleScreenPos, halfSize) {
32
+ return (screenPoint.x >= handleScreenPos.x - halfSize &&
33
+ screenPoint.x <= handleScreenPos.x + halfSize &&
34
+ screenPoint.y >= handleScreenPos.y - halfSize &&
35
+ screenPoint.y <= handleScreenPos.y + halfSize);
36
+ }
37
+ /**
38
+ * Hit test for the rotate handle
39
+ */
40
+ function hitTestRotateHandle(marginedBbox, config, zoom, params) {
41
+ const handle = computeRotateHandle(marginedBbox, config.rotateHandle.distance, zoom);
42
+ const handleScreenPos = params.transform.project(handle.position);
43
+ const halfSize = config.rotateHandle.point.size / 2;
44
+ if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
45
+ return { type: 'rotate' };
46
+ }
47
+ return null;
48
+ }
49
+ /**
50
+ * Hit test for the resize handles
51
+ *
52
+ * @param marginedBbox Bounding box after the margin is applied
53
+ * @param config Configuration of the selection UI
54
+ * @param params Hit test parameters
55
+ * @param getAdditionalHandles Callback that computes the additional handles (it receives
56
+ * the bbox after the margin is applied)
57
+ */
58
+ function hitTestResizeHandles(marginedBbox, config, params, getAdditionalHandles) {
59
+ const additionalHandles = getAdditionalHandles?.(marginedBbox);
60
+ const handles = computeResizeHandles(marginedBbox, additionalHandles);
61
+ const halfSize = config.resizeHandle.point.size / 2;
62
+ for (const handle of handles) {
63
+ const handleScreenPos = params.transform.project(handle.position);
64
+ if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
65
+ return {
66
+ type: 'resize',
67
+ handle: handle.type,
68
+ };
69
+ }
70
+ }
71
+ return null;
72
+ }
73
+ /** Extra margin added to the pointer rectangle used for pre-filtering (pixels) */
74
+ const POINTER_BOUNDS_MARGIN_PX = 2;
75
+ /**
76
+ * Computes the longitude/latitude rectangle around the pointer
77
+ *
78
+ * Unprojects the four corners of the screen rectangle centered on the press point and
79
+ * builds their bounding box. Hit testing while thinning uses it to discard vertices outside
80
+ * this rectangle without projecting them. When it crosses longitude +/-180, pre-filtering
81
+ * is given up (null).
82
+ */
83
+ function computePointerBounds(params, halfSize) {
84
+ const size = halfSize + POINTER_BOUNDS_MARGIN_PX;
85
+ const { x, y } = params.screenPoint;
86
+ const corners = [
87
+ params.transform.unproject({ x: x - size, y: y - size }),
88
+ params.transform.unproject({ x: x + size, y: y - size }),
89
+ params.transform.unproject({ x: x - size, y: y + size }),
90
+ params.transform.unproject({ x: x + size, y: y + size }),
91
+ ];
92
+ let minLng = Number.POSITIVE_INFINITY;
93
+ let minLat = Number.POSITIVE_INFINITY;
94
+ let maxLng = Number.NEGATIVE_INFINITY;
95
+ let maxLat = Number.NEGATIVE_INFINITY;
96
+ for (const corner of corners) {
97
+ minLng = Math.min(minLng, corner.lng);
98
+ maxLng = Math.max(maxLng, corner.lng);
99
+ minLat = Math.min(minLat, corner.lat);
100
+ maxLat = Math.max(maxLat, corner.lat);
101
+ }
102
+ // A large longitude difference despite a tiny screen rectangle means the date line was
103
+ // crossed
104
+ if (maxLng - minLng > 180)
105
+ return null;
106
+ return { minLng, minLat, maxLng, maxLat };
107
+ }
108
+ /**
109
+ * Whether the coordinate falls inside the pre-filter rectangle (always true if it is null)
110
+ */
111
+ function isInPointerBounds(coord, bounds) {
112
+ if (!bounds)
113
+ return true;
114
+ // The rectangle is in the unwrapped longitudes of the pointer (alignToPointer)
115
+ const lng = nearestLongitude(coord[0], (bounds.minLng + bounds.maxLng) / 2);
116
+ return (lng >= bounds.minLng &&
117
+ lng <= bounds.maxLng &&
118
+ coord[1] >= bounds.minLat &&
119
+ coord[1] <= bounds.maxLat);
120
+ }
121
+ /**
122
+ * Hit test against the set of handles currently displayed
123
+ *
124
+ * The path used while thinning. Candidates are narrowed by the pointer rectangle before
125
+ * being projected, so it stays cheap however large the set is. The test itself is the same
126
+ * as in the full-enumeration path (isPointInHandleRect).
127
+ */
128
+ function hitTestVisibleRefs(feature, refs, resolve, halfSize, params) {
129
+ const bounds = computePointerBounds(params, halfSize);
130
+ for (const ref of refs) {
131
+ const position = resolve(feature, ref);
132
+ if (!position)
133
+ continue;
134
+ if (!isInPointerBounds(position, bounds))
135
+ continue;
136
+ const handleScreenPos = params.transform.project(position);
137
+ if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
138
+ // Do not hand out the reference stored in the cache as is (the caller keeps it)
139
+ return { ...ref };
140
+ }
141
+ }
142
+ return null;
143
+ }
144
+ /**
145
+ * Hit test for the vertex handles
146
+ *
147
+ * For a Polygon all rings (outer ring + inner rings) are covered, and for the Multi types
148
+ * the vertices of all parts. Because it uses the same computeVertexHandles as the
149
+ * rendering, every vertex that shows a handle can always be grabbed.
150
+ *
151
+ * While thinning, only the displayed set is covered. Circles that are not visible cannot be
152
+ * grabbed, but in exchange everything that can be grabbed is visible.
153
+ */
154
+ function hitTestVertexHandles(feature, config, params) {
155
+ const halfSize = config.vertexHandle.point.size / 2;
156
+ const displayed = params.scope.thinning.getDisplayedSet(feature);
157
+ if (displayed) {
158
+ const vertexRef = hitTestVisibleRefs(feature, displayed.vertexRefs, resolveVertexCoordinate, halfSize, params);
159
+ return vertexRef ? { type: 'vertex', vertexRef, featureId: feature.id } : null;
160
+ }
161
+ const handles = computeVertexHandles(feature);
162
+ for (const handle of handles) {
163
+ const handleScreenPos = params.transform.project(handle.position);
164
+ if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
165
+ return {
166
+ type: 'vertex',
167
+ vertexRef: handle.vertexRef,
168
+ featureId: feature.id,
169
+ };
170
+ }
171
+ }
172
+ return null;
173
+ }
174
+ /**
175
+ * Hit test for the midpoint handles
176
+ *
177
+ * For a Polygon all rings (outer ring + inner rings) are covered, and for the Multi types
178
+ * the edges of all parts. While thinning, only the displayed midpoints are covered.
179
+ */
180
+ function hitTestMidpointHandles(feature, config, params) {
181
+ const halfSize = config.midpointHandle.point.size / 2;
182
+ const displayed = params.scope.thinning.getDisplayedSet(feature);
183
+ if (displayed) {
184
+ const vertexRef = hitTestVisibleRefs(feature, displayed.midpointRefs, resolveMidpointCoordinate, halfSize, params);
185
+ return vertexRef ? { type: 'midpoint', vertexRef, featureId: feature.id } : null;
186
+ }
187
+ const handles = computeMidpointHandles(feature);
188
+ for (const handle of handles) {
189
+ const handleScreenPos = params.transform.project(handle.position);
190
+ if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
191
+ return {
192
+ type: 'midpoint',
193
+ vertexRef: handle.vertexRef,
194
+ featureId: feature.id,
195
+ };
196
+ }
197
+ }
198
+ return null;
199
+ }
200
+ /**
201
+ * Hit test for the radius handle of a Circle
202
+ */
203
+ function hitTestCircleRadiusHandle(feature, config, params) {
204
+ const handle = computeCircleRadiusHandle(feature);
205
+ if (!handle)
206
+ return null;
207
+ const handleScreenPos = params.transform.project(handle.position);
208
+ const halfSize = config.radiusHandle.point.size / 2;
209
+ if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
210
+ return { type: 'radius', featureId: feature.id };
211
+ }
212
+ return null;
213
+ }
214
+ /**
215
+ * Hit test for the auxiliary handles (provided by an extension implementation)
216
+ *
217
+ * Enumerating the handles is left to the callback (the aggregation of the providers), while
218
+ * the test is done with the same screen-px rectangle as the existing handles. To keep the
219
+ * grab feel uniform, the test size is the same as for the vertex handles (rendering is the
220
+ * provider's responsibility, so core knows only the positions).
221
+ */
222
+ function hitTestAuxiliaryHandles(feature, config, zoom, params, getAuxiliaryHandles) {
223
+ const context = {
224
+ point: params.screenPoint,
225
+ project: (lngLat) => params.transform.project(lngLat),
226
+ unproject: (point) => params.transform.unproject(point),
227
+ zoom,
228
+ };
229
+ const halfSize = config.vertexHandle.point.size / 2;
230
+ for (const { providerId, handle } of getAuxiliaryHandles(context)) {
231
+ const handleScreenPos = params.transform.project(handle.position);
232
+ if (isPointInHandleRect(params.screenPoint, handleScreenPos, halfSize)) {
233
+ return {
234
+ type: 'auxiliary',
235
+ featureId: feature.id,
236
+ auxiliary: { providerId, handleId: handle.id, featureId: feature.id },
237
+ cursor: handle.cursor,
238
+ };
239
+ }
240
+ }
241
+ return null;
242
+ }
243
+ /**
244
+ * Hit test for the selection-independent auxiliary handles
245
+ *
246
+ * It can be called even when the selection is empty (hitTestHandles assumes a selection, so
247
+ * this is a separate entry point). The test size, the handling of the cursor and the shape
248
+ * of the returned HandleHitResult are identical to the auxiliary handles of the selection,
249
+ * and drag delegation goes through the same auxiliary path. The only difference is that
250
+ * "there is no feature it sits on", which is expressed by global / an empty featureId on
251
+ * the hit.
252
+ *
253
+ * @param getGlobalHandles Callback that enumerates the handles (when omitted, no test is
254
+ * performed)
255
+ *
256
+ * @internal
257
+ */
258
+ export function hitTestGlobalAuxiliaryHandles(screenPoint, transform, config, zoom, getGlobalHandles) {
259
+ if (!getGlobalHandles)
260
+ return null;
261
+ transform = alignToPointer(transform, screenPoint);
262
+ const context = {
263
+ point: screenPoint,
264
+ project: (lngLat) => transform.project(lngLat),
265
+ unproject: (point) => transform.unproject(point),
266
+ zoom,
267
+ };
268
+ const halfSize = config.vertexHandle.point.size / 2;
269
+ for (const { providerId, handle } of getGlobalHandles(context)) {
270
+ const handleScreenPos = transform.project(handle.position);
271
+ if (isPointInHandleRect(screenPoint, handleScreenPos, halfSize)) {
272
+ return {
273
+ type: 'auxiliary',
274
+ auxiliary: { providerId, handleId: handle.id, featureId: '', global: true },
275
+ cursor: handle.cursor,
276
+ };
277
+ }
278
+ }
279
+ return null;
280
+ }
281
+ /**
282
+ * Hit test against all handles
283
+ *
284
+ * Priority order:
285
+ * 1. Rotate handle
286
+ * 2. Resize handles (the four corners + the additional handles)
287
+ * 3. Auxiliary handles (provided by an extension implementation; single selection only)
288
+ * 4. Vertex handles
289
+ * 5. Midpoint handles
290
+ * 6. Inside of the bounding box (move)
291
+ *
292
+ * @param screenPoint Screen coordinates
293
+ * @param features The selected features
294
+ * @param transform Coordinate transform
295
+ * @param config Configuration of the selection UI
296
+ * @param zoom Zoom level
297
+ * @param scope The selection scope of the draw instance (extension points of the custom
298
+ * types and the thinned handle sets that are displayed)
299
+ * @param getAdditionalResizeHandles Callback that computes the additional handles (it
300
+ * receives the bbox after the margin is applied)
301
+ * @param getAuxiliaryHandles Callback that enumerates the auxiliary handles (when omitted,
302
+ * the auxiliary handles are not tested)
303
+ *
304
+ * @internal
305
+ */
306
+ export function hitTestHandles(screenPoint, features, transform, config, zoom, scope, getAdditionalResizeHandles, getAuxiliaryHandles) {
307
+ if (features.length === 0) {
308
+ return null;
309
+ }
310
+ transform = alignToPointer(transform, screenPoint);
311
+ // Compute the bbox with the margin in geographic coordinates (for the move test)
312
+ const geoBbox = computeCombinedGeoBoundingBox(features, transform, config, scope.extensions);
313
+ if (!geoBbox) {
314
+ return null;
315
+ }
316
+ // Compute the bbox without the margin (for computing the handle positions)
317
+ const rawBbox = computeCombinedBoundingBox(features, scope.extensions);
318
+ if (!rawBbox) {
319
+ return null;
320
+ }
321
+ // The bbox after the margin is applied (for computing the handle positions)
322
+ const margin = config.boundingBox.margin;
323
+ const marginedBbox = {
324
+ ...applyMarginToBoundingBox(rawBbox, margin, transform),
325
+ center: rawBbox.center,
326
+ };
327
+ const params = {
328
+ screenPoint,
329
+ transform,
330
+ scope,
331
+ };
332
+ // When only single-coordinate features (Point and the like) are selected, skip the rotate
333
+ // and resize handles
334
+ const singleFeatureBbox = features.length === 1 ? computeBoundingBox(features[0], scope.extensions) : null;
335
+ const isPointOnly = singleFeatureBbox !== null && hasZeroArea(singleFeatureBbox);
336
+ // A Circle has no rotate handle; it has a radius handle instead
337
+ const isCircle = features.length === 1 && features[0].type === 'Circle';
338
+ if (!isPointOnly) {
339
+ // For a Circle: the radius handle (in place of the rotate handle)
340
+ if (isCircle) {
341
+ const radiusHit = hitTestCircleRadiusHandle(features[0], config, params);
342
+ if (radiusHit)
343
+ return radiusHit;
344
+ }
345
+ else {
346
+ // 1. Rotate handle (anything other than a Circle)
347
+ const rotateHit = hitTestRotateHandle(marginedBbox, config, zoom, params);
348
+ if (rotateHit)
349
+ return rotateHit;
350
+ }
351
+ // 2. Resize handles (including the additional handles)
352
+ const resizeHit = hitTestResizeHandles(marginedBbox, config, params, getAdditionalResizeHandles);
353
+ if (resizeHit)
354
+ return resizeHit;
355
+ }
356
+ // 3. Auxiliary handles (single selection only; the same restriction as the existing
357
+ // additional handles). They are taken after resize and before vertex. When they
358
+ // overlap a vertex or a midpoint, the auxiliary handle wins (it is enough to move it
359
+ // aside and then grab the vertex).
360
+ if (features.length === 1 && getAuxiliaryHandles) {
361
+ const auxiliaryHit = hitTestAuxiliaryHandles(features[0], config, zoom, params, getAuxiliaryHandles);
362
+ if (auxiliaryHit)
363
+ return auxiliaryHit;
364
+ }
365
+ // 4. Vertex handles (single selection only)
366
+ if (features.length === 1) {
367
+ const feature = features[0];
368
+ // Point, Text, Image, Circle and Freehand have no vertex handles (move only)
369
+ // Freehand does not support vertex editing (because it is a free curve)
370
+ if (supportsVertexEditing(feature.type)) {
371
+ const vertexHit = hitTestVertexHandles(feature, config, params);
372
+ if (vertexHit)
373
+ return vertexHit;
374
+ // 5. Midpoint handles (a MultiPoint has no edges, so the result is empty)
375
+ const midpointHit = hitTestMidpointHandles(feature, config, params);
376
+ if (midpointHit)
377
+ return midpointHit;
378
+ }
379
+ }
380
+ // 6. Inside of the bounding box (move)
381
+ // Convert the click position to geographic coordinates and test it
382
+ const geoLngLat = transform.unproject(screenPoint);
383
+ const geoPoint = [geoLngLat.lng, geoLngLat.lat];
384
+ if (isPointInGeoBoundingBox(geoPoint, geoBbox)) {
385
+ return { type: 'move' };
386
+ }
387
+ return null;
388
+ }
389
+ /**
390
+ * Gets the cursor that corresponds to the handle type
391
+ *
392
+ * @internal
393
+ */
394
+ export function getCursorForHandle(hitResult) {
395
+ if (!hitResult)
396
+ return 'default';
397
+ switch (hitResult.type) {
398
+ case 'rotate':
399
+ return 'grab';
400
+ case 'resize': {
401
+ // The resize cursor that matches the handle position
402
+ switch (hitResult.handle) {
403
+ case 'resize-nw':
404
+ return 'nw-resize';
405
+ case 'resize-n':
406
+ return 'n-resize';
407
+ case 'resize-ne':
408
+ return 'ne-resize';
409
+ case 'resize-e':
410
+ return 'e-resize';
411
+ case 'resize-se':
412
+ return 'se-resize';
413
+ case 'resize-s':
414
+ return 's-resize';
415
+ case 'resize-sw':
416
+ return 'sw-resize';
417
+ case 'resize-w':
418
+ return 'w-resize';
419
+ default:
420
+ return 'default';
421
+ }
422
+ }
423
+ case 'vertex':
424
+ return 'pointer';
425
+ case 'midpoint':
426
+ return 'crosshair';
427
+ case 'move':
428
+ return 'move';
429
+ case 'radius':
430
+ return 'pointer';
431
+ case 'auxiliary':
432
+ // The cursor specified by the auxiliary handle; if unset, 'pointer' as for vertices
433
+ return hitResult.cursor ?? 'pointer';
434
+ default:
435
+ return 'default';
436
+ }
437
+ }