@sakuzu/maplibre-gl-draw 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/CHANGELOG.md +1109 -2
  2. package/README.ja.md +83 -50
  3. package/README.md +89 -53
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/dist/api/datasets.d.ts +263 -0
  6. package/dist/api/document.d.ts +66 -0
  7. package/dist/api/draw.d.ts +137 -0
  8. package/dist/api/draw.js +20 -0
  9. package/dist/api/drawing.d.ts +87 -0
  10. package/dist/api/errors.d.ts +35 -0
  11. package/dist/api/errors.js +35 -0
  12. package/dist/api/events.d.ts +316 -0
  13. package/dist/api/extension/context.d.ts +247 -0
  14. package/dist/api/extension/feature-type.d.ts +129 -0
  15. package/dist/api/extension/mode.d.ts +123 -0
  16. package/dist/api/extension/plugin.d.ts +51 -0
  17. package/dist/api/extension/plugin.js +3 -0
  18. package/dist/api/extension/provider.d.ts +119 -0
  19. package/dist/api/extension/provider.js +3 -0
  20. package/dist/api/extension/render.d.ts +176 -0
  21. package/dist/api/extension/render.js +3 -0
  22. package/dist/api/extension/store.d.ts +190 -0
  23. package/dist/api/extension/store.js +3 -0
  24. package/dist/api/extensions.d.ts +306 -0
  25. package/dist/api/extensions.js +3 -0
  26. package/dist/api/features.d.ts +188 -0
  27. package/dist/api/features.js +3 -0
  28. package/dist/api/groups.d.ts +111 -0
  29. package/dist/api/groups.js +3 -0
  30. package/dist/api/hidden.d.ts +45 -0
  31. package/dist/api/hidden.js +3 -0
  32. package/dist/api/impl/adapters.js +463 -0
  33. package/dist/api/impl/contexts.js +466 -0
  34. package/dist/api/impl/create-draw.js +124 -0
  35. package/dist/api/impl/datasets.js +405 -0
  36. package/dist/api/impl/destroy-guard.js +74 -0
  37. package/dist/api/impl/document.js +280 -0
  38. package/dist/api/impl/drawing.js +180 -0
  39. package/dist/api/impl/engine-context.d.ts +7 -0
  40. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  41. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  42. package/dist/api/impl/events.js +423 -0
  43. package/dist/api/impl/extension-host.js +364 -0
  44. package/dist/api/impl/extensions.js +229 -0
  45. package/dist/api/impl/features.js +445 -0
  46. package/dist/api/impl/geometry/apply.d.ts +32 -0
  47. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  48. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  49. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  50. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  51. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  52. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  53. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  54. package/dist/api/impl/geometry/types.js +3 -0
  55. package/dist/api/impl/groups.d.ts +3 -0
  56. package/dist/api/impl/groups.js +268 -0
  57. package/dist/api/impl/hidden.js +60 -0
  58. package/dist/api/impl/import-export/constants.d.ts +22 -0
  59. package/dist/api/impl/import-export/constants.js +24 -0
  60. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  61. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  62. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  63. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  64. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  66. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  68. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  69. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  70. package/dist/api/impl/import-export/image-import.js +73 -0
  71. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  72. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  73. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  74. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  75. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  76. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  77. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  78. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  79. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  80. package/dist/api/impl/import-export/style-validation.js +86 -0
  81. package/dist/api/impl/import-export/types.d.ts +52 -0
  82. package/dist/api/impl/import-export/types.js +3 -0
  83. package/dist/api/impl/input.js +180 -0
  84. package/dist/api/impl/layers.js +307 -0
  85. package/dist/api/impl/metadata.d.ts +1 -0
  86. package/dist/api/impl/metadata.js +22 -0
  87. package/dist/api/impl/options.d.ts +1 -0
  88. package/dist/api/impl/options.js +851 -0
  89. package/dist/api/impl/placement.d.ts +1 -0
  90. package/dist/api/impl/placement.js +138 -0
  91. package/dist/api/impl/render-context.d.ts +13 -0
  92. package/dist/api/impl/render-context.js +272 -0
  93. package/dist/api/impl/rows.d.ts +1 -0
  94. package/dist/api/impl/rows.js +46 -0
  95. package/dist/api/impl/selection.d.ts +1 -0
  96. package/dist/api/impl/selection.js +186 -0
  97. package/dist/api/impl/shared.d.ts +64 -0
  98. package/dist/api/impl/shared.js +178 -0
  99. package/dist/api/impl/validate-extension.d.ts +1 -0
  100. package/dist/api/impl/validate-extension.js +159 -0
  101. package/dist/api/layers.d.ts +130 -0
  102. package/dist/api/layers.js +3 -0
  103. package/dist/api/metadata.d.ts +18 -0
  104. package/dist/api/metadata.js +3 -0
  105. package/dist/api/model.d.ts +487 -0
  106. package/dist/api/model.js +47 -0
  107. package/dist/api/options.d.ts +466 -0
  108. package/dist/api/options.js +3 -0
  109. package/dist/api/selection.d.ts +94 -0
  110. package/dist/api/selection.js +3 -0
  111. package/dist/api/state.d.ts +155 -0
  112. package/dist/api/state.js +12 -0
  113. package/dist/{display → dataset}/chunk.d.ts +1 -1
  114. package/dist/{display → dataset}/chunk.js +4 -3
  115. package/dist/{display → dataset}/dataset.js +21 -21
  116. package/dist/dataset/interaction.d.ts +1 -0
  117. package/dist/{display → dataset}/interaction.js +18 -6
  118. package/dist/dataset/manager.d.ts +1 -0
  119. package/dist/dataset/provider.d.ts +1 -0
  120. package/dist/{display → dataset}/retained.d.ts +1 -1
  121. package/dist/{display → dataset}/retained.js +8 -7
  122. package/dist/dataset/source.d.ts +1 -0
  123. package/dist/{display → dataset}/source.js +17 -4
  124. package/dist/dataset/spatial.d.ts +1 -0
  125. package/dist/{display → dataset}/spatial.js +1 -1
  126. package/dist/dataset/style.d.ts +1 -0
  127. package/dist/{display → dataset}/style.js +1 -1
  128. package/dist/dataset/table-source.d.ts +1 -0
  129. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  130. package/dist/{display → dataset}/thinning.d.ts +0 -10
  131. package/dist/{display → dataset}/thinning.js +3 -2
  132. package/dist/dataset/triangulation.d.ts +1 -0
  133. package/dist/{display → dataset}/triangulation.js +0 -0
  134. package/dist/{display → dataset}/types.d.ts +84 -121
  135. package/dist/dataset/types.js +61 -0
  136. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  137. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  138. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  139. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  140. package/dist/dispatcher/hit-test/service.js +80 -16
  141. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  142. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  143. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  144. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  145. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  146. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  147. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  148. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  149. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  150. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  151. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  152. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  153. package/dist/dispatcher/input-router.js +154 -70
  154. package/dist/dispatcher/normalizer.js +25 -4
  155. package/dist/dispatcher/types.d.ts +6 -1
  156. package/dist/extension/feature-handler.d.ts +1 -182
  157. package/dist/extension/index.d.ts +4 -7
  158. package/dist/extension/renderers.d.ts +1 -208
  159. package/dist/geometry/angle.d.ts +0 -8
  160. package/dist/geometry/angle.js +0 -8
  161. package/dist/geometry/bbox.d.ts +4 -12
  162. package/dist/geometry/bbox.js +4 -12
  163. package/dist/geometry/boolean.d.ts +0 -51
  164. package/dist/geometry/boolean.js +0 -51
  165. package/dist/geometry/buffer.d.ts +0 -26
  166. package/dist/geometry/buffer.js +0 -26
  167. package/dist/geometry/circle.d.ts +0 -9
  168. package/dist/geometry/circle.js +0 -9
  169. package/dist/geometry/coords.d.ts +0 -16
  170. package/dist/geometry/coords.js +0 -16
  171. package/dist/geometry/distance.d.ts +0 -24
  172. package/dist/geometry/distance.js +0 -24
  173. package/dist/geometry/errors.d.ts +21 -36
  174. package/dist/geometry/errors.js +49 -29
  175. package/dist/geometry/geojson.d.ts +85 -0
  176. package/dist/geometry/geojson.js +173 -0
  177. package/dist/geometry/index.d.ts +38 -23
  178. package/dist/geometry/index.js +43 -31
  179. package/dist/geometry/measure.d.ts +0 -27
  180. package/dist/geometry/measure.js +0 -27
  181. package/dist/geometry/predicates.d.ts +0 -9
  182. package/dist/geometry/predicates.js +0 -9
  183. package/dist/geometry/public-bounds.d.ts +26 -0
  184. package/dist/geometry/public-bounds.js +30 -0
  185. package/dist/geometry/public-combine.d.ts +78 -0
  186. package/dist/geometry/public-combine.js +82 -0
  187. package/dist/geometry/public-create.d.ts +54 -0
  188. package/dist/geometry/public-create.js +70 -0
  189. package/dist/geometry/public-measure.d.ts +170 -0
  190. package/dist/geometry/public-measure.js +283 -0
  191. package/dist/geometry/public-predicates.d.ts +54 -0
  192. package/dist/geometry/public-predicates.js +144 -0
  193. package/dist/geometry/public-repair.d.ts +75 -0
  194. package/dist/geometry/public-repair.js +77 -0
  195. package/dist/geometry/simplify.d.ts +0 -7
  196. package/dist/geometry/simplify.js +0 -7
  197. package/dist/geometry/split.d.ts +0 -20
  198. package/dist/geometry/split.js +0 -20
  199. package/dist/geometry/units.d.ts +20 -12
  200. package/dist/geometry/units.js +20 -12
  201. package/dist/index.d.ts +66 -66
  202. package/dist/index.js +6 -18
  203. package/dist/messages.d.ts +7 -7
  204. package/dist/modes/draw/circle.js +83 -207
  205. package/dist/modes/draw/commit-layer.d.ts +5 -16
  206. package/dist/modes/draw/commit-layer.js +2 -13
  207. package/dist/modes/draw/freehand.js +108 -246
  208. package/dist/modes/draw/image.js +4 -2
  209. package/dist/modes/draw/index.d.ts +5 -5
  210. package/dist/modes/draw/index.js +5 -5
  211. package/dist/modes/draw/line.js +18 -354
  212. package/dist/modes/draw/point.js +29 -78
  213. package/dist/modes/draw/polygon.js +23 -368
  214. package/dist/modes/draw/trace-support.d.ts +43 -36
  215. package/dist/modes/draw/trace-support.js +95 -98
  216. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  217. package/dist/modes/draw/vertex-drawing.js +176 -0
  218. package/dist/modes/handler.d.ts +1 -285
  219. package/dist/modes/manager.d.ts +2 -2
  220. package/dist/modes/manager.js +3 -0
  221. package/dist/modes/select/box-selection.d.ts +3 -3
  222. package/dist/modes/select/box-selection.js +2 -1
  223. package/dist/modes/select/click-handler.d.ts +5 -5
  224. package/dist/modes/select/click-handler.js +22 -20
  225. package/dist/modes/select/cursor-handler.d.ts +2 -2
  226. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  227. package/dist/modes/select/drag/move.js +3 -3
  228. package/dist/modes/select/drag/operation.d.ts +3 -3
  229. package/dist/modes/select/drag/radius.js +5 -4
  230. package/dist/modes/select/drag/transform.d.ts +2 -2
  231. package/dist/modes/select/drag/transform.js +11 -5
  232. package/dist/modes/select/drag/vertex.d.ts +2 -2
  233. package/dist/modes/select/drag/vertex.js +13 -8
  234. package/dist/modes/select/drag-handler.js +44 -25
  235. package/dist/modes/select/mode.js +17 -17
  236. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  237. package/dist/modes/select/shortcut-handler.js +9 -7
  238. package/dist/operations/layer-operations.js +29 -168
  239. package/dist/operations/resize.d.ts +2 -2
  240. package/dist/operations/resize.js +5 -5
  241. package/dist/operations/rotate.js +5 -5
  242. package/dist/operations/selection-operations.d.ts +16 -1
  243. package/dist/operations/selection-operations.js +28 -13
  244. package/dist/operations/shared-vertex.js +4 -2
  245. package/dist/operations/trace-graph.d.ts +0 -18
  246. package/dist/operations/trace-graph.js +0 -18
  247. package/dist/operations/vertex.js +36 -35
  248. package/dist/shared/color.d.ts +1 -0
  249. package/dist/shared/color.js +245 -0
  250. package/dist/shared/config/constants.d.ts +1 -54
  251. package/dist/shared/config/constants.js +1 -58
  252. package/dist/shared/config/feature-style.d.ts +16 -13
  253. package/dist/shared/config/feature-style.js +9 -0
  254. package/dist/shared/config/rendering.d.ts +3 -3
  255. package/dist/shared/config/selection-highlight.d.ts +0 -15
  256. package/dist/shared/config/selection-highlight.js +4 -7
  257. package/dist/shared/config/selection.d.ts +2 -32
  258. package/dist/shared/config/selection.js +0 -18
  259. package/dist/shared/config/topology.d.ts +2 -2
  260. package/dist/shared/config/trace.d.ts +4 -4
  261. package/dist/shared/math/angle.d.ts +1 -1
  262. package/dist/shared/math/angle.js +1 -1
  263. package/dist/shared/math/circle.d.ts +1 -1
  264. package/dist/shared/math/circle.js +1 -1
  265. package/dist/shared/math/distance.d.ts +2 -1
  266. package/dist/shared/math/distance.js +3 -2
  267. package/dist/shared/math/index.d.ts +1 -1
  268. package/dist/shared/math/index.js +1 -1
  269. package/dist/shared/math/transform.d.ts +23 -0
  270. package/dist/shared/math/transform.js +47 -28
  271. package/dist/shared/properties.d.ts +18 -0
  272. package/dist/shared/properties.js +129 -0
  273. package/dist/shared/types/events.d.ts +15 -7
  274. package/dist/shared/types/model.d.ts +109 -159
  275. package/dist/shared/types/style.d.ts +1 -1
  276. package/dist/shared/utils/color.d.ts +2 -36
  277. package/dist/shared/utils/color.js +13 -70
  278. package/dist/shared/utils/coordinates.d.ts +30 -4
  279. package/dist/shared/utils/coordinates.js +56 -10
  280. package/dist/shared/utils/event-emitter.d.ts +1 -262
  281. package/dist/shared/utils/event-emitter.js +4 -3
  282. package/dist/shared/utils/feature-bbox.js +8 -7
  283. package/dist/shared/utils/feature-segments.js +5 -4
  284. package/dist/shared/utils/image.d.ts +0 -4
  285. package/dist/shared/utils/image.js +0 -6
  286. package/dist/shared/utils/name-generator.d.ts +14 -20
  287. package/dist/shared/utils/name-generator.js +20 -3
  288. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  289. package/dist/shared/utils/pixel-ratio.js +13 -4
  290. package/dist/shared/utils/property.d.ts +7 -50
  291. package/dist/shared/utils/property.js +22 -87
  292. package/dist/snapping/custom-targets.js +21 -4
  293. package/dist/snapping/indicator.js +20 -11
  294. package/dist/snapping/providers/display.d.ts +6 -1
  295. package/dist/snapping/providers/display.js +2 -1
  296. package/dist/snapping/providers/guide.d.ts +3 -43
  297. package/dist/snapping/providers/guide.js +1 -44
  298. package/dist/snapping/providers/intersection.js +1 -1
  299. package/dist/snapping/providers/store.js +3 -3
  300. package/dist/snapping/service.js +18 -7
  301. package/dist/snapping/types.d.ts +9 -35
  302. package/dist/store/draw-store.js +233 -142
  303. package/dist/store/local-visibility.d.ts +11 -6
  304. package/dist/store/local-visibility.js +38 -7
  305. package/dist/store/lock.d.ts +0 -6
  306. package/dist/store/lock.js +0 -6
  307. package/dist/store/memory/change-bus.d.ts +3 -3
  308. package/dist/store/memory/change-bus.js +12 -0
  309. package/dist/store/memory/file-store.d.ts +2 -2
  310. package/dist/store/memory/ui-state.d.ts +1 -51
  311. package/dist/store/memory/ui-state.js +122 -134
  312. package/dist/store/memory.d.ts +1 -8
  313. package/dist/store/memory.js +249 -45
  314. package/dist/store/ordering.d.ts +9 -0
  315. package/dist/store/ordering.js +17 -0
  316. package/dist/store/spatial/spatial-index.d.ts +1 -1
  317. package/dist/store/spatial/spatial-index.js +1 -1
  318. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  319. package/dist/store/spatial/store-spatial-index.js +9 -3
  320. package/dist/store/store.d.ts +66 -107
  321. package/dist/store/types.d.ts +1 -1
  322. package/dist/store/writable-layer.d.ts +1 -1
  323. package/dist/store/writable-layer.js +2 -2
  324. package/dist/table/builder.d.ts +83 -0
  325. package/dist/table/builder.js +381 -0
  326. package/dist/table/index.d.ts +37 -0
  327. package/dist/table/index.js +5 -0
  328. package/dist/table/packed-rtree.d.ts +1 -0
  329. package/dist/{display → table}/packed-rtree.js +1 -1
  330. package/dist/table/partition.d.ts +1 -0
  331. package/dist/{display → table}/partition.js +3 -3
  332. package/dist/table/prepare.d.ts +44 -0
  333. package/dist/table/prepare.js +136 -0
  334. package/dist/table/table.d.ts +1 -0
  335. package/dist/{display/columnar → table}/table.js +29 -25
  336. package/dist/{display/columnar → table}/types.d.ts +68 -72
  337. package/dist/table/types.js +3 -0
  338. package/dist/view/coordinator.js +4 -3
  339. package/dist/view/feature-companion.d.ts +13 -7
  340. package/dist/view/feature-companion.js +11 -3
  341. package/dist/view/globe-subdivision.js +3 -3
  342. package/dist/view/layer/attach.d.ts +12 -6
  343. package/dist/view/layer/attach.js +86 -10
  344. package/dist/view/layer/custom-layer.js +40 -11
  345. package/dist/view/layer/display-list.js +2 -1
  346. package/dist/view/layer/drape-planner.d.ts +2 -2
  347. package/dist/view/layer/frame-render.d.ts +3 -3
  348. package/dist/view/layer/frame-render.js +7 -2
  349. package/dist/view/layer/frame-state.d.ts +6 -6
  350. package/dist/view/layer/index.d.ts +2 -2
  351. package/dist/view/layer/index.js +1 -1
  352. package/dist/view/layer/render.d.ts +4 -4
  353. package/dist/view/layer/render.js +3 -8
  354. package/dist/view/layer/renderers.d.ts +2 -2
  355. package/dist/view/layer/renderers.js +1 -1
  356. package/dist/view/layer/slot-manager.d.ts +2 -2
  357. package/dist/view/layer/slot-manager.js +4 -4
  358. package/dist/view/layer/slots.d.ts +2 -2
  359. package/dist/view/layer/slots.js +1 -1
  360. package/dist/view/layer/store-retained-bbox.js +3 -2
  361. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  362. package/dist/view/layer/store-retained-classify.js +19 -7
  363. package/dist/view/layer/store-retained-collect.js +8 -7
  364. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  365. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  366. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  367. package/dist/view/layer/store-retained-immediate.js +3 -8
  368. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  369. package/dist/view/layer/store-retained.d.ts +2 -2
  370. package/dist/view/layer/store-retained.js +1 -1
  371. package/dist/view/renderers/batch-manager.js +8 -7
  372. package/dist/view/renderers/drawer.js +21 -15
  373. package/dist/view/renderers/image.js +13 -39
  374. package/dist/view/renderers/line/line-types.d.ts +3 -3
  375. package/dist/view/renderers/line/sdf-line.js +3 -1
  376. package/dist/view/renderers/point/billboard-depth.js +1 -1
  377. package/dist/view/renderers/point/point-instance.js +1 -1
  378. package/dist/view/renderers/point/point-shape.js +2 -2
  379. package/dist/view/renderers/point/point-style.js +48 -4
  380. package/dist/view/renderers/polygon/batch.js +1 -2
  381. package/dist/view/renderers/polygon/fill.js +3 -1
  382. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  383. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  384. package/dist/view/renderers/stroke.js +3 -1
  385. package/dist/view/shaders/helpers.d.ts +2 -42
  386. package/dist/view/shaders/helpers.js +0 -6
  387. package/dist/view/shaders/projection.d.ts +15 -7
  388. package/dist/view/shaders/projection.js +23 -6
  389. package/dist/view/shaders/quad.d.ts +16 -12
  390. package/dist/view/shaders/quad.js +34 -13
  391. package/dist/view/style-rule.d.ts +5 -42
  392. package/dist/view/style-rule.js +20 -44
  393. package/dist/view/terrain/binding.d.ts +1 -0
  394. package/dist/view/terrain/binding.js +29 -0
  395. package/dist/view/terrain/context.d.ts +3 -4
  396. package/dist/view/terrain/context.js +4 -5
  397. package/dist/view/terrain/drape/geometry.js +1 -1
  398. package/dist/view/terrain/drape/pass.d.ts +1 -1
  399. package/dist/view/terrain/drape/pass.js +8 -7
  400. package/dist/view/terrain/polygon.d.ts +9 -5
  401. package/dist/view/terrain/polygon.js +16 -2
  402. package/dist/view/terrain/state.d.ts +1 -1
  403. package/dist/view/terrain/state.js +1 -1
  404. package/dist/view/terrain/tessellation.d.ts +2 -2
  405. package/dist/view/terrain/tessellation.js +1 -1
  406. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  407. package/dist/view/ui/bounds.js +8 -12
  408. package/dist/view/ui/handle-test.js +2 -2
  409. package/dist/view/ui/handle-thinning.js +17 -17
  410. package/dist/view/ui/handles.js +21 -13
  411. package/dist/view/ui/helper.d.ts +1 -1
  412. package/dist/view/ui/helper.js +1 -1
  413. package/dist/view/ui/index.d.ts +1 -1
  414. package/dist/view/ui/selection-scope.js +4 -2
  415. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  416. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  417. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  418. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  419. package/dist/view/ui/selection-ui/index.js +1 -1
  420. package/dist/view/ui/selection-ui/renderer.js +15 -38
  421. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  422. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  423. package/dist/view/ui/selection-ui-drawer.js +63 -2
  424. package/dist/view/ui/tentative.js +1 -1
  425. package/dist/webgl/index.d.ts +65 -0
  426. package/dist/webgl/index.js +62 -0
  427. package/package.json +38 -15
  428. package/dist/api/api.d.ts +0 -1259
  429. package/dist/api/api.js +0 -86
  430. package/dist/api/context.d.ts +0 -173
  431. package/dist/api/display-api.js +0 -23
  432. package/dist/api/event-api.d.ts +0 -13
  433. package/dist/api/event-api.js +0 -17
  434. package/dist/api/extension-api.d.ts +0 -46
  435. package/dist/api/extension-api.js +0 -85
  436. package/dist/api/feature-api.d.ts +0 -11
  437. package/dist/api/feature-api.js +0 -101
  438. package/dist/api/geometry/apply.d.ts +0 -51
  439. package/dist/api/geometry/boolean.d.ts +0 -28
  440. package/dist/api/geometry/boolean.js +0 -65
  441. package/dist/api/geometry/types.d.ts +0 -31
  442. package/dist/api/geometry-operations.d.ts +0 -162
  443. package/dist/api/geometry-operations.js +0 -94
  444. package/dist/api/group-api.d.ts +0 -10
  445. package/dist/api/group-api.js +0 -78
  446. package/dist/api/import-export/constants.d.ts +0 -29
  447. package/dist/api/import-export/constants.js +0 -40
  448. package/dist/api/import-export/file-name.d.ts +0 -10
  449. package/dist/api/import-export/file-name.js +0 -20
  450. package/dist/api/import-export/geojson-export.d.ts +0 -19
  451. package/dist/api/import-export/image-import.d.ts +0 -12
  452. package/dist/api/import-export/image-import.js +0 -53
  453. package/dist/api/import-export/index.d.ts +0 -9
  454. package/dist/api/import-export/index.js +0 -107
  455. package/dist/api/import-export/native-format.d.ts +0 -15
  456. package/dist/api/import-export/style-validation.d.ts +0 -27
  457. package/dist/api/import-export/style-validation.js +0 -49
  458. package/dist/api/import-export/types.d.ts +0 -26
  459. package/dist/api/index.d.ts +0 -15
  460. package/dist/api/index.js +0 -3
  461. package/dist/api/input-api.d.ts +0 -158
  462. package/dist/api/input-api.js +0 -144
  463. package/dist/api/instance-api.d.ts +0 -38
  464. package/dist/api/instance-api.js +0 -136
  465. package/dist/api/layer-api.d.ts +0 -12
  466. package/dist/api/layer-api.js +0 -62
  467. package/dist/api/selection-api.d.ts +0 -7
  468. package/dist/api/selection-api.js +0 -78
  469. package/dist/api/snapping-api.d.ts +0 -125
  470. package/dist/api/snapping-api.js +0 -50
  471. package/dist/api/topology-api.d.ts +0 -30
  472. package/dist/api/topology-api.js +0 -16
  473. package/dist/api/tracing-api.d.ts +0 -31
  474. package/dist/api/tracing-api.js +0 -16
  475. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  476. package/dist/dispatcher/hit-test/index.js +0 -9
  477. package/dist/dispatcher/index.d.ts +0 -15
  478. package/dist/dispatcher/index.js +0 -3
  479. package/dist/display/columnar/index.d.ts +0 -12
  480. package/dist/display/columnar/index.js +0 -13
  481. package/dist/display/columnar/prepare.d.ts +0 -42
  482. package/dist/display/columnar/prepare.js +0 -116
  483. package/dist/display/index.d.ts +0 -13
  484. package/dist/display/types.js +0 -43
  485. package/dist/maplibre-gl-draw.d.ts +0 -47
  486. package/dist/modes/cursor.js +0 -72
  487. package/dist/modes/index.d.ts +0 -7
  488. package/dist/operations/index.d.ts +0 -9
  489. package/dist/operations/index.js +0 -3
  490. package/dist/plugins/index.d.ts +0 -10
  491. package/dist/plugins/mutation-hooks.d.ts +0 -28
  492. package/dist/plugins/mutation-hooks.js +0 -84
  493. package/dist/plugins/plugin-context.js +0 -367
  494. package/dist/plugins/plugin-manager.d.ts +0 -103
  495. package/dist/plugins/plugin-manager.js +0 -316
  496. package/dist/plugins/plugin.d.ts +0 -529
  497. package/dist/shared/config/index.d.ts +0 -17
  498. package/dist/shared/config/index.js +0 -8
  499. package/dist/shared/utils/index.d.ts +0 -15
  500. package/dist/shared/utils/index.js +0 -24
  501. package/dist/snapping/index.d.ts +0 -14
  502. package/dist/snapping/index.js +0 -4
  503. package/dist/store/change-merger.js +0 -102
  504. package/dist/store/event-bridge.js +0 -161
  505. package/dist/store/index.d.ts +0 -12
  506. package/dist/store/index.js +0 -4
  507. package/dist/view/index.d.ts +0 -47
  508. package/dist/view/index.js +0 -20
  509. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  510. /package/dist/api/{import-export/types.js → document.js} +0 -0
  511. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  512. /package/dist/{display/index.js → api/events.js} +0 -0
  513. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  514. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  515. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  516. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  517. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  518. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  519. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  520. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  521. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  522. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  523. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  524. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  525. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  526. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  527. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  528. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  529. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  532. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  533. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  534. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  535. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  536. /package/dist/{display → dataset}/chunk-set.js +0 -0
  537. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  538. /package/dist/{display → dataset}/manager.js +0 -0
  539. /package/dist/{display → dataset}/provider.js +0 -0
  540. /package/dist/{display → dataset}/selection.d.ts +0 -0
  541. /package/dist/{display → dataset}/selection.js +0 -0
@@ -0,0 +1,82 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { differenceAll, intersectionAll, unionAll } from './boolean.js';
4
+ import { withOperation } from './errors.js';
5
+ import { areaOf, areasOf, lineOf, toAreaGeometry } from './geojson.js';
6
+ import { splitArea } from './split.js';
7
+ /**
8
+ * Returns the union of polygons.
9
+ *
10
+ * @param polygons The Polygons and MultiPolygons, or features whose geometry is one;
11
+ * coordinates in degrees. Rings with fewer than 3 positions or a position that is not finite
12
+ * are left out
13
+ * @returns A Polygon, or a MultiPolygon when the union falls apart, with self-intersections
14
+ * resolved and the rings oriented as RFC 7946 recommends. null when nothing has an area
15
+ * @throws {@link GeometryError} (`invalid-input`) when an element is not a Polygon or a
16
+ * MultiPolygon, and (`engine-failure`) when the boolean operation fails
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { union } from '@sakuzu/maplibre-gl-draw/geometry';
21
+ *
22
+ * union([
23
+ * { type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]] },
24
+ * { type: 'Polygon', coordinates: [[[0.5, 0], [1.5, 0], [1.5, 1], [0.5, 1], [0.5, 0]]] },
25
+ * ]);
26
+ * // { type: 'Polygon', coordinates: [[[0, 0], [1.5, 0], [1.5, 1], [0, 1], [0, 0]]] }
27
+ * ```
28
+ */
29
+ export function union(polygons) {
30
+ const inputs = areasOf(polygons, 'union');
31
+ return withOperation('union', () => toAreaGeometry(unionAll(inputs)));
32
+ }
33
+ /**
34
+ * Returns the part that polygons have in common.
35
+ *
36
+ * @param polygons The Polygons and MultiPolygons, or features whose geometry is one;
37
+ * coordinates in degrees
38
+ * @returns A Polygon or a MultiPolygon in the form {@link union} returns. null when the
39
+ * polygons share no area (touching boundaries included), when one has no area, and for an
40
+ * empty array
41
+ * @throws {@link GeometryError} (`invalid-input`) when an element is not a Polygon or a
42
+ * MultiPolygon, and (`engine-failure`) when the boolean operation fails
43
+ */
44
+ export function intersection(polygons) {
45
+ const inputs = areasOf(polygons, 'intersection');
46
+ return withOperation('intersection', () => toAreaGeometry(intersectionAll(inputs)));
47
+ }
48
+ /**
49
+ * Returns a polygon with other polygons removed from it.
50
+ *
51
+ * @param subject The Polygon or MultiPolygon to remove from, or a feature whose geometry is
52
+ * one; coordinates in degrees
53
+ * @param others The Polygons and MultiPolygons to remove, or features whose geometry is one;
54
+ * coordinates in degrees
55
+ * @returns A Polygon or a MultiPolygon in the form {@link union} returns; a removed area inside
56
+ * the subject becomes a hole. null when nothing remains
57
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a Polygon or a
58
+ * MultiPolygon, and (`engine-failure`) when the boolean operation fails
59
+ */
60
+ export function difference(subject, others) {
61
+ const left = areaOf(subject, 'difference');
62
+ const right = areasOf(others, 'difference');
63
+ return withOperation('difference', () => toAreaGeometry(differenceAll(left, right)));
64
+ }
65
+ /**
66
+ * Cuts a polygon with a line and returns the pieces.
67
+ *
68
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
69
+ * in degrees
70
+ * @param line The cutting LineString, or a feature whose geometry is one; coordinates in
71
+ * degrees. A stretch that runs along the boundary does not cut, and positions closer than
72
+ * 1e-9 degrees count as one
73
+ * @returns One Polygon per piece, holes kept. When the line does not cut across, the polygon
74
+ * itself (one Polygon per part of a MultiPolygon). An empty array when it has no area
75
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not of the expected
76
+ * type, and (`engine-failure`) when the boolean operation fails
77
+ */
78
+ export function split(polygon, line) {
79
+ const area = areaOf(polygon, 'split');
80
+ const path = lineOf(line, 'split');
81
+ return withOperation('split', () => splitArea(area, path).flatMap((piece) => piece.map((coordinates) => ({ type: 'Polygon', coordinates }))));
82
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Create: the public functions that build polygons from distances in meters
3
+ */
4
+ import type { Geometry, MultiPolygon, Point, Polygon, Position } from 'geojson';
5
+ /**
6
+ * Returns a polygon that approximates the geodesic circle of a radius in meters around a
7
+ * center.
8
+ *
9
+ * @param center The center, a position `[lng, lat]` in degrees or a Point
10
+ * @param radiusMeters The radius in meters, 0 or more. Every vertex lies at this great-circle
11
+ * distance from the center
12
+ * @param options `segments`, the number of vertices (64 by default, rounded down and clamped
13
+ * to 3-1024)
14
+ * @returns The Polygon, its ring starting due north of the center and running
15
+ * counter-clockwise, with the first position repeated at the end
16
+ * @throws {@link GeometryError} (`invalid-input`) when the center is not a position or a
17
+ * Point or is not finite, and when the radius is negative or not finite
18
+ */
19
+ export declare function circle(center: Position | Point, radiusMeters: number, options?: {
20
+ segments?: number;
21
+ }): Polygon;
22
+ /**
23
+ * Returns the area within a distance in meters of a geometry, or a polygon shrunk by it when
24
+ * the distance is negative.
25
+ *
26
+ * @param geometry The geometry, or a feature whose geometry it is; coordinates in degrees. The
27
+ * members of a GeometryCollection are buffered one by one and the results merged
28
+ * @param distanceMeters The distance in meters. A negative distance shrinks a polygon and
29
+ * leaves nothing of a point or a line
30
+ * @param options `segments`, the number of segments of each circle (64 by default, rounded
31
+ * down and clamped to 3-1024)
32
+ * @returns A Polygon, or a MultiPolygon when the area falls apart. null when nothing remains,
33
+ * and when a vertex is so close to a pole or an edge so long in longitude (over 180 degrees)
34
+ * that the area cannot be drawn in longitude and latitude
35
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a geometry or a
36
+ * feature with one and when the distance is not a finite number, and (`engine-failure`)
37
+ * when merging the parts fails
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import { buffer } from '@sakuzu/maplibre-gl-draw/geometry';
42
+ *
43
+ * // The area within 100 m of a road
44
+ * const corridor = buffer(
45
+ * { type: 'LineString', coordinates: [[139.76, 35.68], [139.77, 35.69]] },
46
+ * 100,
47
+ * );
48
+ * ```
49
+ */
50
+ export declare function buffer(geometry: Geometry | {
51
+ readonly geometry: Geometry;
52
+ }, distanceMeters: number, options?: {
53
+ segments?: number;
54
+ }): Polygon | MultiPolygon | null;
@@ -0,0 +1,70 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { unionAll } from './boolean.js';
4
+ import { buffer as bufferCoordinates } from './buffer.js';
5
+ import { generateCirclePolygon } from './circle.js';
6
+ import { invalidInput, withOperation } from './errors.js';
7
+ import { geometryOf, positionOf, toAreaGeometry, toPosition } from './geojson.js';
8
+ /**
9
+ * Returns a polygon that approximates the geodesic circle of a radius in meters around a
10
+ * center.
11
+ *
12
+ * @param center The center, a position `[lng, lat]` in degrees or a Point
13
+ * @param radiusMeters The radius in meters, 0 or more. Every vertex lies at this great-circle
14
+ * distance from the center
15
+ * @param options `segments`, the number of vertices (64 by default, rounded down and clamped
16
+ * to 3-1024)
17
+ * @returns The Polygon, its ring starting due north of the center and running
18
+ * counter-clockwise, with the first position repeated at the end
19
+ * @throws {@link GeometryError} (`invalid-input`) when the center is not a position or a
20
+ * Point or is not finite, and when the radius is negative or not finite
21
+ */
22
+ export function circle(center, radiusMeters, options) {
23
+ const ring = generateCirclePolygon(positionOf(center, 'circle'), radiusMeters, options?.segments);
24
+ if (ring.length === 0) {
25
+ throw invalidInput('circle', 'the center or the radius is not a finite number');
26
+ }
27
+ return { type: 'Polygon', coordinates: [ring.map(toPosition).reverse()] };
28
+ }
29
+ /** The buffer of a geometry as MultiPolygon coordinates, each member of a collection alone */
30
+ function bufferOf(geometry, distanceMeters, segments) {
31
+ if (geometry.type === 'GeometryCollection') {
32
+ return unionAll(geometry.geometries.map((member) => bufferOf(geometryOf(member, 'buffer'), distanceMeters, segments)));
33
+ }
34
+ return bufferCoordinates(geometry, distanceMeters, { segments }) ?? [];
35
+ }
36
+ /**
37
+ * Returns the area within a distance in meters of a geometry, or a polygon shrunk by it when
38
+ * the distance is negative.
39
+ *
40
+ * @param geometry The geometry, or a feature whose geometry it is; coordinates in degrees. The
41
+ * members of a GeometryCollection are buffered one by one and the results merged
42
+ * @param distanceMeters The distance in meters. A negative distance shrinks a polygon and
43
+ * leaves nothing of a point or a line
44
+ * @param options `segments`, the number of segments of each circle (64 by default, rounded
45
+ * down and clamped to 3-1024)
46
+ * @returns A Polygon, or a MultiPolygon when the area falls apart. null when nothing remains,
47
+ * and when a vertex is so close to a pole or an edge so long in longitude (over 180 degrees)
48
+ * that the area cannot be drawn in longitude and latitude
49
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a geometry or a
50
+ * feature with one and when the distance is not a finite number, and (`engine-failure`)
51
+ * when merging the parts fails
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { buffer } from '@sakuzu/maplibre-gl-draw/geometry';
56
+ *
57
+ * // The area within 100 m of a road
58
+ * const corridor = buffer(
59
+ * { type: 'LineString', coordinates: [[139.76, 35.68], [139.77, 35.69]] },
60
+ * 100,
61
+ * );
62
+ * ```
63
+ */
64
+ export function buffer(geometry, distanceMeters, options) {
65
+ const input = geometryOf(geometry, 'buffer');
66
+ if (!Number.isFinite(distanceMeters)) {
67
+ throw invalidInput('buffer', 'the distance is not a finite number');
68
+ }
69
+ return withOperation('buffer', () => toAreaGeometry(bufferOf(input, distanceMeters, options?.segments)));
70
+ }
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Measure: the public functions that measure distances, bearings, lengths and areas
3
+ *
4
+ * Every distance is taken along great circles on the sphere of EARTH_RADIUS_METERS, the
5
+ * same as the internal haversine and direct-problem functions.
6
+ */
7
+ import type { Geometry, LineString, MultiLineString, MultiPolygon, Point, Polygon, Position } from 'geojson';
8
+ /**
9
+ * Returns the great-circle distance in meters between two points.
10
+ *
11
+ * @param from The first point, a position `[lng, lat]` in degrees or a Point
12
+ * @param to The second point, a position `[lng, lat]` in degrees or a Point
13
+ * @returns The distance in meters on the sphere of {@link EARTH_RADIUS_METERS}. NaN when a
14
+ * coordinate is not finite
15
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
16
+ * Point
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { distance } from '@sakuzu/maplibre-gl-draw/geometry';
21
+ *
22
+ * distance([139.767, 35.681], [135.495, 34.702]); // about 403,139 m
23
+ * ```
24
+ */
25
+ export declare function distance(from: Position | Point, to: Position | Point): number;
26
+ /**
27
+ * Returns the initial bearing in degrees of the great circle from one point to another.
28
+ *
29
+ * @param from The start, a position `[lng, lat]` in degrees or a Point
30
+ * @param to The end, a position `[lng, lat]` in degrees or a Point
31
+ * @returns The bearing at the start in degrees, clockwise from north, in [0, 360). 0 when the
32
+ * points are identical
33
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
34
+ * Point
35
+ */
36
+ export declare function bearing(from: Position | Point, to: Position | Point): number;
37
+ /**
38
+ * Returns the point reached from an origin after a distance in meters along a great circle
39
+ * that starts at a bearing in degrees.
40
+ *
41
+ * @param origin The start, a position `[lng, lat]` in degrees or a Point
42
+ * @param distanceMeters The distance in meters; a negative value goes the opposite way
43
+ * @param bearingDegrees The initial bearing in degrees, clockwise from north
44
+ * @returns The position `[lng, lat]` in degrees. The longitude continues from the origin
45
+ * and is not wrapped into [-180, 180]
46
+ * @throws {@link GeometryError} (`invalid-input`) when the origin is not a position or a
47
+ * Point
48
+ */
49
+ export declare function destination(origin: Position | Point, distanceMeters: number, bearingDegrees: number): Position;
50
+ /**
51
+ * Returns the point halfway between two points along the great circle that joins them.
52
+ *
53
+ * @param from The first point, a position `[lng, lat]` in degrees or a Point
54
+ * @param to The second point, a position `[lng, lat]` in degrees or a Point
55
+ * @returns The position `[lng, lat]` in degrees, at the same distance in meters from both
56
+ * points. The longitude continues from `from`
57
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
58
+ * Point
59
+ */
60
+ export declare function midpoint(from: Position | Point, to: Position | Point): Position;
61
+ /**
62
+ * Returns the point at a distance in meters along a line, measured from its start.
63
+ *
64
+ * @param line The LineString, or a feature whose geometry is one; coordinates in degrees
65
+ * @param distanceMeters The distance from the start in meters. 0 or less gives the start,
66
+ * and a distance longer than the line gives its end
67
+ * @returns The position `[lng, lat]` in degrees
68
+ * @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or has no
69
+ * position, and when the distance is not a finite number
70
+ */
71
+ export declare function along(line: LineString | {
72
+ readonly geometry: Geometry;
73
+ }, distanceMeters: number): Position;
74
+ /**
75
+ * Returns the point of a line nearest to a given point, with its distance in meters and the
76
+ * index of the segment it lies on.
77
+ *
78
+ * @param line The LineString or MultiLineString, or a feature whose geometry is one;
79
+ * coordinates in degrees. Each segment is taken as a great-circle arc
80
+ * @param point The point, a position `[lng, lat]` in degrees or a Point
81
+ * @returns `position`, the nearest point `[lng, lat]` in degrees; `distanceMeters`, its
82
+ * distance from `point` in meters; and `segmentIndex`, the segment it lies on, counted from
83
+ * 0 across the lines of a MultiLineString in order (segment `i` of a LineString joins its
84
+ * positions `i` and `i + 1`)
85
+ * @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or a
86
+ * MultiLineString or has no position, and when the point is not a position or a Point
87
+ */
88
+ export declare function nearestPointOnLine(line: LineString | MultiLineString | {
89
+ readonly geometry: Geometry;
90
+ }, point: Position | Point): {
91
+ position: Position;
92
+ distanceMeters: number;
93
+ segmentIndex: number;
94
+ };
95
+ /**
96
+ * Returns the length in meters of a line.
97
+ *
98
+ * @param line The LineString or MultiLineString, or a feature whose geometry is one;
99
+ * coordinates in degrees
100
+ * @returns The sum of the great-circle distances of the segments, in meters. 0 for a line
101
+ * with fewer than 2 positions
102
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a LineString or a
103
+ * MultiLineString
104
+ */
105
+ export declare function length(line: LineString | MultiLineString | {
106
+ readonly geometry: Geometry;
107
+ }): number;
108
+ /**
109
+ * Returns the area in square meters of a polygon on the sphere.
110
+ *
111
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
112
+ * in degrees. Self-intersections are resolved and ring orientation does not matter
113
+ * @returns The area in square meters, holes subtracted. 0 when nothing with an area remains
114
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
115
+ * MultiPolygon, and (`engine-failure`) when resolving its self-intersections fails
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * import { area } from '@sakuzu/maplibre-gl-draw/geometry';
120
+ *
121
+ * // A 1 x 1 degree square on the equator
122
+ * area({ type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]] });
123
+ * // about 1.236e10 m²
124
+ * ```
125
+ */
126
+ export declare function area(polygon: Polygon | MultiPolygon | {
127
+ readonly geometry: Geometry;
128
+ }): number;
129
+ /**
130
+ * Returns the length in meters of the boundary of a polygon, the rings of its holes included.
131
+ *
132
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
133
+ * in degrees. An open ring is measured as if closed; a ring with fewer than 3 positions or a
134
+ * position that is not finite is left out
135
+ * @returns The sum of the great-circle lengths of every ring, in meters
136
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
137
+ * MultiPolygon
138
+ */
139
+ export declare function perimeter(polygon: Polygon | MultiPolygon | {
140
+ readonly geometry: Geometry;
141
+ }): number;
142
+ /**
143
+ * Returns the centroid of a polygon, weighted by area.
144
+ *
145
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
146
+ * in degrees. Holes are subtracted and the parts are weighted by their areas on the lng/lat
147
+ * plane
148
+ * @returns The centroid as a Point, in degrees; it can fall outside a concave polygon (see
149
+ * {@link pointOnSurface}). The mean of the positions when the area is 0. null when there is
150
+ * no position
151
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
152
+ * MultiPolygon
153
+ */
154
+ export declare function centroid(polygon: Polygon | MultiPolygon | {
155
+ readonly geometry: Geometry;
156
+ }): Point | null;
157
+ /**
158
+ * Returns a point that always lies inside a polygon, such as the anchor of a label.
159
+ *
160
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
161
+ * in degrees
162
+ * @returns The {@link centroid} when it lies inside, otherwise the middle of the widest
163
+ * section of the polygon along the parallel of the centroid, as a Point in degrees. null
164
+ * when there is no position
165
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
166
+ * MultiPolygon
167
+ */
168
+ export declare function pointOnSurface(polygon: Polygon | MultiPolygon | {
169
+ readonly geometry: Geometry;
170
+ }): Point | null;
@@ -0,0 +1,283 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { closeRing, usableAreaParts } from './coords.js';
4
+ import { destinationPoint, haversineDistanceMeters, initialBearingDegrees } from './distance.js';
5
+ import { invalidInput, withOperation } from './errors.js';
6
+ import { areaOf, lineOf, linesOf, positionOf, toPoint, toPosition } from './geojson.js';
7
+ import { geodesicLength, centroid as planarCentroid, pointOnSurface as planarPointOnSurface, sphericalArea, } from './measure.js';
8
+ import { toDegrees, toRadians } from './units.js';
9
+ /**
10
+ * Returns the great-circle distance in meters between two points.
11
+ *
12
+ * @param from The first point, a position `[lng, lat]` in degrees or a Point
13
+ * @param to The second point, a position `[lng, lat]` in degrees or a Point
14
+ * @returns The distance in meters on the sphere of {@link EARTH_RADIUS_METERS}. NaN when a
15
+ * coordinate is not finite
16
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
17
+ * Point
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { distance } from '@sakuzu/maplibre-gl-draw/geometry';
22
+ *
23
+ * distance([139.767, 35.681], [135.495, 34.702]); // about 403,139 m
24
+ * ```
25
+ */
26
+ export function distance(from, to) {
27
+ return haversineDistanceMeters(positionOf(from, 'distance'), positionOf(to, 'distance'));
28
+ }
29
+ /**
30
+ * Returns the initial bearing in degrees of the great circle from one point to another.
31
+ *
32
+ * @param from The start, a position `[lng, lat]` in degrees or a Point
33
+ * @param to The end, a position `[lng, lat]` in degrees or a Point
34
+ * @returns The bearing at the start in degrees, clockwise from north, in [0, 360). 0 when the
35
+ * points are identical
36
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
37
+ * Point
38
+ */
39
+ export function bearing(from, to) {
40
+ return initialBearingDegrees(positionOf(from, 'bearing'), positionOf(to, 'bearing'));
41
+ }
42
+ /**
43
+ * Returns the point reached from an origin after a distance in meters along a great circle
44
+ * that starts at a bearing in degrees.
45
+ *
46
+ * @param origin The start, a position `[lng, lat]` in degrees or a Point
47
+ * @param distanceMeters The distance in meters; a negative value goes the opposite way
48
+ * @param bearingDegrees The initial bearing in degrees, clockwise from north
49
+ * @returns The position `[lng, lat]` in degrees. The longitude continues from the origin
50
+ * and is not wrapped into [-180, 180]
51
+ * @throws {@link GeometryError} (`invalid-input`) when the origin is not a position or a
52
+ * Point
53
+ */
54
+ export function destination(origin, distanceMeters, bearingDegrees) {
55
+ return toPosition(destinationPoint(positionOf(origin, 'destination'), distanceMeters, bearingDegrees));
56
+ }
57
+ /**
58
+ * Returns the point halfway between two points along the great circle that joins them.
59
+ *
60
+ * @param from The first point, a position `[lng, lat]` in degrees or a Point
61
+ * @param to The second point, a position `[lng, lat]` in degrees or a Point
62
+ * @returns The position `[lng, lat]` in degrees, at the same distance in meters from both
63
+ * points. The longitude continues from `from`
64
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a position or a
65
+ * Point
66
+ */
67
+ export function midpoint(from, to) {
68
+ const [lng1, lat1] = positionOf(from, 'midpoint');
69
+ const [lng2, lat2] = positionOf(to, 'midpoint');
70
+ const phi1 = toRadians(lat1);
71
+ const phi2 = toRadians(lat2);
72
+ const dLambda = toRadians(lng2 - lng1);
73
+ const bx = Math.cos(phi2) * Math.cos(dLambda);
74
+ const by = Math.cos(phi2) * Math.sin(dLambda);
75
+ const phi = Math.atan2(Math.sin(phi1) + Math.sin(phi2), Math.sqrt((Math.cos(phi1) + bx) ** 2 + by ** 2));
76
+ const lambda = Math.atan2(by, Math.cos(phi1) + bx);
77
+ return [lng1 + toDegrees(lambda), toDegrees(phi)];
78
+ }
79
+ /**
80
+ * Returns the point at a distance in meters along a line, measured from its start.
81
+ *
82
+ * @param line The LineString, or a feature whose geometry is one; coordinates in degrees
83
+ * @param distanceMeters The distance from the start in meters. 0 or less gives the start,
84
+ * and a distance longer than the line gives its end
85
+ * @returns The position `[lng, lat]` in degrees
86
+ * @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or has no
87
+ * position, and when the distance is not a finite number
88
+ */
89
+ export function along(line, distanceMeters) {
90
+ const path = lineOf(line, 'along');
91
+ if (path.length === 0) {
92
+ throw invalidInput('along', 'the line has no position');
93
+ }
94
+ if (!Number.isFinite(distanceMeters)) {
95
+ throw invalidInput('along', 'the distance is not a finite number');
96
+ }
97
+ let remaining = distanceMeters;
98
+ if (remaining <= 0)
99
+ return toPosition(path[0]);
100
+ for (let i = 0; i < path.length - 1; i++) {
101
+ const start = path[i];
102
+ const end = path[i + 1];
103
+ const section = haversineDistanceMeters(start, end);
104
+ if (remaining < section) {
105
+ return toPosition(destinationPoint(start, remaining, initialBearingDegrees(start, end)));
106
+ }
107
+ remaining -= section;
108
+ }
109
+ return toPosition(path[path.length - 1]);
110
+ }
111
+ function toVector([lng, lat]) {
112
+ const lambda = toRadians(lng);
113
+ const phi = toRadians(lat);
114
+ return [Math.cos(phi) * Math.cos(lambda), Math.cos(phi) * Math.sin(lambda), Math.sin(phi)];
115
+ }
116
+ function cross(a, b) {
117
+ return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
118
+ }
119
+ function dot(a, b) {
120
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
121
+ }
122
+ function norm(a) {
123
+ return Math.hypot(a[0], a[1], a[2]);
124
+ }
125
+ /** The vectors shorter than this are treated as zero (a degenerate great circle) */
126
+ const VECTOR_EPSILON = 1e-15;
127
+ /**
128
+ * The position of a unit vector, with the longitude taken nearest to a reference longitude
129
+ */
130
+ function toCoordinate(v, nearLng) {
131
+ const lat = toDegrees(Math.atan2(v[2], Math.hypot(v[0], v[1])));
132
+ const lng = toDegrees(Math.atan2(v[1], v[0]));
133
+ return [lng + 360 * Math.round((nearLng - lng) / 360), lat];
134
+ }
135
+ /**
136
+ * The point of the great-circle arc from a to b nearest to p
137
+ *
138
+ * p is projected onto the plane of the great circle through a and b. When the projection
139
+ * falls on the arc between them, it is the nearest point; otherwise the nearer end is.
140
+ */
141
+ function nearestOnSegment(p, a, b) {
142
+ const va = toVector(a);
143
+ const vb = toVector(b);
144
+ const vp = toVector(p);
145
+ const normal = cross(va, vb);
146
+ const normalLength = norm(normal);
147
+ if (normalLength < VECTOR_EPSILON)
148
+ return a;
149
+ const n = [normal[0] / normalLength, normal[1] / normalLength, normal[2] / normalLength];
150
+ const offset = dot(vp, n);
151
+ const projected = [vp[0] - offset * n[0], vp[1] - offset * n[1], vp[2] - offset * n[2]];
152
+ if (norm(projected) >= VECTOR_EPSILON && dot(cross(va, projected), n) >= 0) {
153
+ if (dot(cross(projected, vb), n) >= 0) {
154
+ const size = norm(projected);
155
+ return toCoordinate([projected[0] / size, projected[1] / size, projected[2] / size], a[0]);
156
+ }
157
+ }
158
+ return haversineDistanceMeters(p, a) <= haversineDistanceMeters(p, b) ? a : b;
159
+ }
160
+ /**
161
+ * Returns the point of a line nearest to a given point, with its distance in meters and the
162
+ * index of the segment it lies on.
163
+ *
164
+ * @param line The LineString or MultiLineString, or a feature whose geometry is one;
165
+ * coordinates in degrees. Each segment is taken as a great-circle arc
166
+ * @param point The point, a position `[lng, lat]` in degrees or a Point
167
+ * @returns `position`, the nearest point `[lng, lat]` in degrees; `distanceMeters`, its
168
+ * distance from `point` in meters; and `segmentIndex`, the segment it lies on, counted from
169
+ * 0 across the lines of a MultiLineString in order (segment `i` of a LineString joins its
170
+ * positions `i` and `i + 1`)
171
+ * @throws {@link GeometryError} (`invalid-input`) when the line is not a LineString or a
172
+ * MultiLineString or has no position, and when the point is not a position or a Point
173
+ */
174
+ export function nearestPointOnLine(line, point) {
175
+ const lines = linesOf(line, 'nearestPointOnLine');
176
+ const target = positionOf(point, 'nearestPointOnLine');
177
+ let best = null;
178
+ let segmentIndex = 0;
179
+ for (const path of lines) {
180
+ if (path.length === 0)
181
+ continue;
182
+ const segments = Math.max(1, path.length - 1);
183
+ for (let i = 0; i < segments; i++) {
184
+ const candidate = path.length === 1 ? path[0] : nearestOnSegment(target, path[i], path[i + 1]);
185
+ const distanceMeters = haversineDistanceMeters(target, candidate);
186
+ if (best === null || distanceMeters < best.distanceMeters) {
187
+ best = { position: candidate, distanceMeters, segmentIndex };
188
+ }
189
+ segmentIndex++;
190
+ }
191
+ }
192
+ if (best === null) {
193
+ throw invalidInput('nearestPointOnLine', 'the line has no position');
194
+ }
195
+ return { ...best, position: toPosition(best.position) };
196
+ }
197
+ /**
198
+ * Returns the length in meters of a line.
199
+ *
200
+ * @param line The LineString or MultiLineString, or a feature whose geometry is one;
201
+ * coordinates in degrees
202
+ * @returns The sum of the great-circle distances of the segments, in meters. 0 for a line
203
+ * with fewer than 2 positions
204
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a LineString or a
205
+ * MultiLineString
206
+ */
207
+ export function length(line) {
208
+ let total = 0;
209
+ for (const path of linesOf(line, 'length'))
210
+ total += geodesicLength(path);
211
+ return total;
212
+ }
213
+ /**
214
+ * Returns the area in square meters of a polygon on the sphere.
215
+ *
216
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
217
+ * in degrees. Self-intersections are resolved and ring orientation does not matter
218
+ * @returns The area in square meters, holes subtracted. 0 when nothing with an area remains
219
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
220
+ * MultiPolygon, and (`engine-failure`) when resolving its self-intersections fails
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * import { area } from '@sakuzu/maplibre-gl-draw/geometry';
225
+ *
226
+ * // A 1 x 1 degree square on the equator
227
+ * area({ type: 'Polygon', coordinates: [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]] });
228
+ * // about 1.236e10 m²
229
+ * ```
230
+ */
231
+ export function area(polygon) {
232
+ const coordinates = areaOf(polygon, 'area');
233
+ return withOperation('area', () => sphericalArea(coordinates));
234
+ }
235
+ /**
236
+ * Returns the length in meters of the boundary of a polygon, the rings of its holes included.
237
+ *
238
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
239
+ * in degrees. An open ring is measured as if closed; a ring with fewer than 3 positions or a
240
+ * position that is not finite is left out
241
+ * @returns The sum of the great-circle lengths of every ring, in meters
242
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
243
+ * MultiPolygon
244
+ */
245
+ export function perimeter(polygon) {
246
+ let total = 0;
247
+ for (const part of usableAreaParts(areaOf(polygon, 'perimeter'))) {
248
+ for (const ring of part)
249
+ total += geodesicLength(closeRing(ring));
250
+ }
251
+ return total;
252
+ }
253
+ /**
254
+ * Returns the centroid of a polygon, weighted by area.
255
+ *
256
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
257
+ * in degrees. Holes are subtracted and the parts are weighted by their areas on the lng/lat
258
+ * plane
259
+ * @returns The centroid as a Point, in degrees; it can fall outside a concave polygon (see
260
+ * {@link pointOnSurface}). The mean of the positions when the area is 0. null when there is
261
+ * no position
262
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
263
+ * MultiPolygon
264
+ */
265
+ export function centroid(polygon) {
266
+ const result = planarCentroid(areaOf(polygon, 'centroid'));
267
+ return result === null ? null : toPoint(result);
268
+ }
269
+ /**
270
+ * Returns a point that always lies inside a polygon, such as the anchor of a label.
271
+ *
272
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
273
+ * in degrees
274
+ * @returns The {@link centroid} when it lies inside, otherwise the middle of the widest
275
+ * section of the polygon along the parallel of the centroid, as a Point in degrees. null
276
+ * when there is no position
277
+ * @throws {@link GeometryError} (`invalid-input`) when the input is not a Polygon or a
278
+ * MultiPolygon
279
+ */
280
+ export function pointOnSurface(polygon) {
281
+ const result = planarPointOnSurface(areaOf(polygon, 'pointOnSurface'));
282
+ return result === null ? null : toPoint(result);
283
+ }