@sakuzu/maplibre-gl-draw 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (540) hide show
  1. package/CHANGELOG.md +1016 -2
  2. package/README.ja.md +39 -19
  3. package/README.md +41 -21
  4. package/dist/api/datasets.d.ts +258 -0
  5. package/dist/api/document.d.ts +66 -0
  6. package/dist/api/draw.d.ts +135 -0
  7. package/dist/api/draw.js +18 -0
  8. package/dist/api/drawing.d.ts +87 -0
  9. package/dist/api/errors.d.ts +35 -0
  10. package/dist/api/errors.js +35 -0
  11. package/dist/api/events.d.ts +306 -0
  12. package/dist/api/extension/context.d.ts +247 -0
  13. package/dist/api/extension/feature-type.d.ts +129 -0
  14. package/dist/api/extension/mode.d.ts +123 -0
  15. package/dist/api/extension/plugin.d.ts +51 -0
  16. package/dist/api/extension/plugin.js +3 -0
  17. package/dist/api/extension/provider.d.ts +119 -0
  18. package/dist/api/extension/provider.js +3 -0
  19. package/dist/api/extension/render.d.ts +176 -0
  20. package/dist/api/extension/render.js +3 -0
  21. package/dist/api/extension/store.d.ts +190 -0
  22. package/dist/api/extension/store.js +3 -0
  23. package/dist/api/extensions.d.ts +306 -0
  24. package/dist/api/extensions.js +3 -0
  25. package/dist/api/features.d.ts +188 -0
  26. package/dist/api/features.js +3 -0
  27. package/dist/api/groups.d.ts +111 -0
  28. package/dist/api/groups.js +3 -0
  29. package/dist/api/hidden.d.ts +45 -0
  30. package/dist/api/hidden.js +3 -0
  31. package/dist/api/impl/adapters.js +463 -0
  32. package/dist/api/impl/contexts.js +466 -0
  33. package/dist/api/impl/create-draw.js +124 -0
  34. package/dist/api/impl/datasets.js +404 -0
  35. package/dist/api/impl/destroy-guard.js +74 -0
  36. package/dist/api/impl/document.js +280 -0
  37. package/dist/api/impl/drawing.js +180 -0
  38. package/dist/api/impl/engine-context.d.ts +7 -0
  39. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  40. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  41. package/dist/api/impl/events.js +422 -0
  42. package/dist/api/impl/extension-host.js +361 -0
  43. package/dist/api/impl/extensions.js +229 -0
  44. package/dist/api/impl/features.js +445 -0
  45. package/dist/api/impl/geometry/apply.d.ts +32 -0
  46. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  47. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  48. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  49. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  50. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  51. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  52. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  53. package/dist/api/impl/geometry/types.js +3 -0
  54. package/dist/api/impl/groups.d.ts +3 -0
  55. package/dist/api/impl/groups.js +268 -0
  56. package/dist/api/impl/hidden.js +60 -0
  57. package/dist/api/impl/import-export/constants.d.ts +22 -0
  58. package/dist/api/impl/import-export/constants.js +24 -0
  59. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  60. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  61. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  62. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  63. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  64. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  66. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  68. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  69. package/dist/api/impl/import-export/image-import.js +73 -0
  70. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  71. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  72. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  73. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  74. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  75. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  76. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  77. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  78. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  79. package/dist/api/impl/import-export/style-validation.js +86 -0
  80. package/dist/api/impl/import-export/types.d.ts +52 -0
  81. package/dist/api/impl/import-export/types.js +3 -0
  82. package/dist/api/impl/input.js +180 -0
  83. package/dist/api/impl/layers.js +307 -0
  84. package/dist/api/impl/metadata.d.ts +1 -0
  85. package/dist/api/impl/metadata.js +22 -0
  86. package/dist/api/impl/options.d.ts +1 -0
  87. package/dist/api/impl/options.js +822 -0
  88. package/dist/api/impl/placement.d.ts +1 -0
  89. package/dist/api/impl/placement.js +138 -0
  90. package/dist/api/impl/render-context.d.ts +13 -0
  91. package/dist/api/impl/render-context.js +272 -0
  92. package/dist/api/impl/rows.d.ts +1 -0
  93. package/dist/api/impl/rows.js +46 -0
  94. package/dist/api/impl/selection.d.ts +1 -0
  95. package/dist/api/impl/selection.js +186 -0
  96. package/dist/api/impl/shared.d.ts +64 -0
  97. package/dist/api/impl/shared.js +178 -0
  98. package/dist/api/impl/validate-extension.d.ts +1 -0
  99. package/dist/api/impl/validate-extension.js +159 -0
  100. package/dist/api/layers.d.ts +130 -0
  101. package/dist/api/layers.js +3 -0
  102. package/dist/api/metadata.d.ts +18 -0
  103. package/dist/api/metadata.js +3 -0
  104. package/dist/api/model.d.ts +487 -0
  105. package/dist/api/model.js +47 -0
  106. package/dist/api/options.d.ts +466 -0
  107. package/dist/api/options.js +3 -0
  108. package/dist/api/selection.d.ts +94 -0
  109. package/dist/api/selection.js +3 -0
  110. package/dist/api/state.d.ts +155 -0
  111. package/dist/api/state.js +12 -0
  112. package/dist/{display → dataset}/chunk.d.ts +1 -1
  113. package/dist/{display → dataset}/chunk.js +4 -3
  114. package/dist/{display → dataset}/dataset.js +18 -21
  115. package/dist/dataset/interaction.d.ts +1 -0
  116. package/dist/{display → dataset}/interaction.js +18 -6
  117. package/dist/dataset/manager.d.ts +1 -0
  118. package/dist/dataset/provider.d.ts +1 -0
  119. package/dist/{display → dataset}/retained.d.ts +1 -1
  120. package/dist/{display → dataset}/retained.js +8 -7
  121. package/dist/dataset/source.d.ts +1 -0
  122. package/dist/{display → dataset}/source.js +17 -4
  123. package/dist/dataset/spatial.d.ts +1 -0
  124. package/dist/{display → dataset}/spatial.js +1 -1
  125. package/dist/dataset/style.d.ts +1 -0
  126. package/dist/{display → dataset}/style.js +1 -1
  127. package/dist/dataset/table-source.d.ts +1 -0
  128. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  129. package/dist/{display → dataset}/thinning.d.ts +0 -10
  130. package/dist/{display → dataset}/thinning.js +3 -2
  131. package/dist/dataset/triangulation.d.ts +1 -0
  132. package/dist/{display → dataset}/triangulation.js +0 -0
  133. package/dist/{display → dataset}/types.d.ts +82 -121
  134. package/dist/dataset/types.js +61 -0
  135. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  136. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  137. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  138. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  139. package/dist/dispatcher/hit-test/service.js +80 -16
  140. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  141. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  142. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  143. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  144. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  145. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  146. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  147. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  148. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  149. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  150. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  151. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  152. package/dist/dispatcher/input-router.js +152 -69
  153. package/dist/dispatcher/normalizer.js +6 -2
  154. package/dist/dispatcher/types.d.ts +6 -1
  155. package/dist/extension/feature-handler.d.ts +1 -182
  156. package/dist/extension/index.d.ts +4 -7
  157. package/dist/extension/renderers.d.ts +1 -208
  158. package/dist/geometry/angle.d.ts +0 -8
  159. package/dist/geometry/angle.js +0 -8
  160. package/dist/geometry/bbox.d.ts +4 -12
  161. package/dist/geometry/bbox.js +4 -12
  162. package/dist/geometry/boolean.d.ts +0 -51
  163. package/dist/geometry/boolean.js +0 -51
  164. package/dist/geometry/buffer.d.ts +0 -26
  165. package/dist/geometry/buffer.js +0 -26
  166. package/dist/geometry/circle.d.ts +0 -9
  167. package/dist/geometry/circle.js +0 -9
  168. package/dist/geometry/coords.d.ts +0 -16
  169. package/dist/geometry/coords.js +0 -16
  170. package/dist/geometry/distance.d.ts +0 -24
  171. package/dist/geometry/distance.js +0 -24
  172. package/dist/geometry/errors.d.ts +21 -36
  173. package/dist/geometry/errors.js +49 -29
  174. package/dist/geometry/geojson.d.ts +81 -0
  175. package/dist/geometry/geojson.js +164 -0
  176. package/dist/geometry/index.d.ts +38 -23
  177. package/dist/geometry/index.js +43 -31
  178. package/dist/geometry/measure.d.ts +0 -27
  179. package/dist/geometry/measure.js +0 -27
  180. package/dist/geometry/predicates.d.ts +0 -9
  181. package/dist/geometry/predicates.js +0 -9
  182. package/dist/geometry/public-bounds.d.ts +26 -0
  183. package/dist/geometry/public-bounds.js +30 -0
  184. package/dist/geometry/public-combine.d.ts +78 -0
  185. package/dist/geometry/public-combine.js +82 -0
  186. package/dist/geometry/public-create.d.ts +54 -0
  187. package/dist/geometry/public-create.js +70 -0
  188. package/dist/geometry/public-measure.d.ts +170 -0
  189. package/dist/geometry/public-measure.js +283 -0
  190. package/dist/geometry/public-predicates.d.ts +54 -0
  191. package/dist/geometry/public-predicates.js +144 -0
  192. package/dist/geometry/public-repair.d.ts +75 -0
  193. package/dist/geometry/public-repair.js +77 -0
  194. package/dist/geometry/simplify.d.ts +0 -7
  195. package/dist/geometry/simplify.js +0 -7
  196. package/dist/geometry/split.d.ts +0 -20
  197. package/dist/geometry/split.js +0 -20
  198. package/dist/geometry/units.d.ts +20 -12
  199. package/dist/geometry/units.js +20 -12
  200. package/dist/index.d.ts +52 -66
  201. package/dist/index.js +6 -18
  202. package/dist/messages.d.ts +7 -7
  203. package/dist/modes/draw/circle.js +83 -207
  204. package/dist/modes/draw/commit-layer.d.ts +5 -16
  205. package/dist/modes/draw/commit-layer.js +2 -13
  206. package/dist/modes/draw/freehand.js +108 -246
  207. package/dist/modes/draw/image.js +4 -2
  208. package/dist/modes/draw/index.d.ts +5 -5
  209. package/dist/modes/draw/index.js +5 -5
  210. package/dist/modes/draw/line.js +18 -354
  211. package/dist/modes/draw/point.js +29 -78
  212. package/dist/modes/draw/polygon.js +23 -368
  213. package/dist/modes/draw/trace-support.d.ts +43 -36
  214. package/dist/modes/draw/trace-support.js +95 -98
  215. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  216. package/dist/modes/draw/vertex-drawing.js +176 -0
  217. package/dist/modes/handler.d.ts +1 -285
  218. package/dist/modes/manager.d.ts +2 -2
  219. package/dist/modes/manager.js +3 -0
  220. package/dist/modes/select/box-selection.d.ts +3 -3
  221. package/dist/modes/select/box-selection.js +2 -1
  222. package/dist/modes/select/click-handler.d.ts +5 -5
  223. package/dist/modes/select/click-handler.js +22 -20
  224. package/dist/modes/select/cursor-handler.d.ts +2 -2
  225. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  226. package/dist/modes/select/drag/move.js +3 -3
  227. package/dist/modes/select/drag/operation.d.ts +3 -3
  228. package/dist/modes/select/drag/radius.js +5 -4
  229. package/dist/modes/select/drag/transform.d.ts +2 -2
  230. package/dist/modes/select/drag/transform.js +11 -5
  231. package/dist/modes/select/drag/vertex.d.ts +2 -2
  232. package/dist/modes/select/drag/vertex.js +13 -8
  233. package/dist/modes/select/drag-handler.js +44 -25
  234. package/dist/modes/select/mode.js +17 -17
  235. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  236. package/dist/modes/select/shortcut-handler.js +9 -7
  237. package/dist/operations/layer-operations.js +29 -168
  238. package/dist/operations/resize.d.ts +2 -2
  239. package/dist/operations/resize.js +5 -5
  240. package/dist/operations/rotate.js +5 -5
  241. package/dist/operations/selection-operations.d.ts +16 -1
  242. package/dist/operations/selection-operations.js +28 -13
  243. package/dist/operations/shared-vertex.js +4 -2
  244. package/dist/operations/trace-graph.d.ts +0 -18
  245. package/dist/operations/trace-graph.js +0 -18
  246. package/dist/operations/vertex.js +36 -35
  247. package/dist/shared/color.d.ts +1 -0
  248. package/dist/shared/color.js +245 -0
  249. package/dist/shared/config/constants.d.ts +1 -54
  250. package/dist/shared/config/constants.js +1 -58
  251. package/dist/shared/config/feature-style.d.ts +16 -13
  252. package/dist/shared/config/feature-style.js +9 -0
  253. package/dist/shared/config/rendering.d.ts +3 -3
  254. package/dist/shared/config/selection-highlight.d.ts +0 -15
  255. package/dist/shared/config/selection-highlight.js +4 -7
  256. package/dist/shared/config/selection.d.ts +2 -32
  257. package/dist/shared/config/selection.js +0 -18
  258. package/dist/shared/config/topology.d.ts +2 -2
  259. package/dist/shared/config/trace.d.ts +4 -4
  260. package/dist/shared/math/angle.d.ts +1 -1
  261. package/dist/shared/math/angle.js +1 -1
  262. package/dist/shared/math/circle.d.ts +1 -1
  263. package/dist/shared/math/circle.js +1 -1
  264. package/dist/shared/math/distance.d.ts +2 -1
  265. package/dist/shared/math/distance.js +3 -2
  266. package/dist/shared/math/index.d.ts +1 -1
  267. package/dist/shared/math/index.js +1 -1
  268. package/dist/shared/math/transform.d.ts +23 -0
  269. package/dist/shared/math/transform.js +47 -28
  270. package/dist/shared/properties.d.ts +18 -0
  271. package/dist/shared/properties.js +129 -0
  272. package/dist/shared/types/events.d.ts +15 -7
  273. package/dist/shared/types/model.d.ts +109 -159
  274. package/dist/shared/types/style.d.ts +1 -1
  275. package/dist/shared/utils/color.d.ts +2 -36
  276. package/dist/shared/utils/color.js +13 -70
  277. package/dist/shared/utils/coordinates.d.ts +30 -4
  278. package/dist/shared/utils/coordinates.js +56 -10
  279. package/dist/shared/utils/event-emitter.d.ts +1 -262
  280. package/dist/shared/utils/event-emitter.js +4 -3
  281. package/dist/shared/utils/feature-bbox.js +8 -7
  282. package/dist/shared/utils/feature-segments.js +5 -4
  283. package/dist/shared/utils/image.d.ts +0 -4
  284. package/dist/shared/utils/image.js +0 -6
  285. package/dist/shared/utils/name-generator.d.ts +14 -20
  286. package/dist/shared/utils/name-generator.js +20 -3
  287. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  288. package/dist/shared/utils/pixel-ratio.js +13 -4
  289. package/dist/shared/utils/property.d.ts +7 -50
  290. package/dist/shared/utils/property.js +22 -87
  291. package/dist/snapping/custom-targets.js +21 -4
  292. package/dist/snapping/indicator.js +20 -11
  293. package/dist/snapping/providers/display.d.ts +6 -1
  294. package/dist/snapping/providers/display.js +2 -1
  295. package/dist/snapping/providers/guide.d.ts +3 -43
  296. package/dist/snapping/providers/guide.js +1 -44
  297. package/dist/snapping/providers/intersection.js +1 -1
  298. package/dist/snapping/providers/store.js +3 -3
  299. package/dist/snapping/service.js +18 -7
  300. package/dist/snapping/types.d.ts +9 -35
  301. package/dist/store/draw-store.js +233 -142
  302. package/dist/store/local-visibility.d.ts +11 -6
  303. package/dist/store/local-visibility.js +38 -7
  304. package/dist/store/lock.d.ts +0 -6
  305. package/dist/store/lock.js +0 -6
  306. package/dist/store/memory/change-bus.d.ts +3 -3
  307. package/dist/store/memory/change-bus.js +12 -0
  308. package/dist/store/memory/file-store.d.ts +2 -2
  309. package/dist/store/memory/ui-state.d.ts +1 -51
  310. package/dist/store/memory/ui-state.js +122 -134
  311. package/dist/store/memory.d.ts +1 -8
  312. package/dist/store/memory.js +249 -45
  313. package/dist/store/ordering.d.ts +9 -0
  314. package/dist/store/ordering.js +17 -0
  315. package/dist/store/spatial/spatial-index.d.ts +1 -1
  316. package/dist/store/spatial/spatial-index.js +1 -1
  317. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  318. package/dist/store/spatial/store-spatial-index.js +9 -3
  319. package/dist/store/store.d.ts +66 -107
  320. package/dist/store/types.d.ts +1 -1
  321. package/dist/store/writable-layer.d.ts +1 -1
  322. package/dist/store/writable-layer.js +2 -2
  323. package/dist/table/builder.d.ts +83 -0
  324. package/dist/table/builder.js +381 -0
  325. package/dist/table/index.d.ts +37 -0
  326. package/dist/table/index.js +5 -0
  327. package/dist/table/packed-rtree.d.ts +1 -0
  328. package/dist/{display → table}/packed-rtree.js +1 -1
  329. package/dist/table/partition.d.ts +1 -0
  330. package/dist/{display → table}/partition.js +3 -3
  331. package/dist/table/prepare.d.ts +44 -0
  332. package/dist/table/prepare.js +136 -0
  333. package/dist/table/table.d.ts +1 -0
  334. package/dist/{display/columnar → table}/table.js +29 -25
  335. package/dist/{display/columnar → table}/types.d.ts +68 -72
  336. package/dist/table/types.js +3 -0
  337. package/dist/view/coordinator.js +4 -3
  338. package/dist/view/feature-companion.d.ts +13 -7
  339. package/dist/view/feature-companion.js +11 -3
  340. package/dist/view/globe-subdivision.js +3 -3
  341. package/dist/view/layer/attach.d.ts +1 -1
  342. package/dist/view/layer/attach.js +1 -1
  343. package/dist/view/layer/custom-layer.js +40 -11
  344. package/dist/view/layer/display-list.js +2 -1
  345. package/dist/view/layer/drape-planner.d.ts +2 -2
  346. package/dist/view/layer/frame-render.d.ts +3 -3
  347. package/dist/view/layer/frame-render.js +7 -2
  348. package/dist/view/layer/frame-state.d.ts +6 -6
  349. package/dist/view/layer/index.d.ts +2 -2
  350. package/dist/view/layer/index.js +1 -1
  351. package/dist/view/layer/render.d.ts +4 -4
  352. package/dist/view/layer/render.js +3 -8
  353. package/dist/view/layer/renderers.d.ts +2 -2
  354. package/dist/view/layer/renderers.js +1 -1
  355. package/dist/view/layer/slot-manager.d.ts +2 -2
  356. package/dist/view/layer/slot-manager.js +4 -4
  357. package/dist/view/layer/slots.d.ts +2 -2
  358. package/dist/view/layer/slots.js +1 -1
  359. package/dist/view/layer/store-retained-bbox.js +3 -2
  360. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  361. package/dist/view/layer/store-retained-classify.js +19 -7
  362. package/dist/view/layer/store-retained-collect.js +8 -7
  363. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  364. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  365. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  366. package/dist/view/layer/store-retained-immediate.js +3 -8
  367. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  368. package/dist/view/layer/store-retained.d.ts +2 -2
  369. package/dist/view/layer/store-retained.js +1 -1
  370. package/dist/view/renderers/batch-manager.js +8 -7
  371. package/dist/view/renderers/drawer.js +21 -15
  372. package/dist/view/renderers/image.js +13 -39
  373. package/dist/view/renderers/line/line-types.d.ts +3 -3
  374. package/dist/view/renderers/line/sdf-line.js +3 -1
  375. package/dist/view/renderers/point/billboard-depth.js +1 -1
  376. package/dist/view/renderers/point/point-instance.js +1 -1
  377. package/dist/view/renderers/point/point-shape.js +2 -2
  378. package/dist/view/renderers/point/point-style.js +48 -4
  379. package/dist/view/renderers/polygon/batch.js +1 -2
  380. package/dist/view/renderers/polygon/fill.js +3 -1
  381. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  382. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  383. package/dist/view/renderers/stroke.js +3 -1
  384. package/dist/view/shaders/helpers.d.ts +2 -42
  385. package/dist/view/shaders/helpers.js +0 -6
  386. package/dist/view/shaders/projection.d.ts +15 -7
  387. package/dist/view/shaders/projection.js +23 -6
  388. package/dist/view/shaders/quad.d.ts +16 -12
  389. package/dist/view/shaders/quad.js +34 -13
  390. package/dist/view/style-rule.d.ts +5 -42
  391. package/dist/view/style-rule.js +20 -44
  392. package/dist/view/terrain/binding.d.ts +1 -0
  393. package/dist/view/terrain/binding.js +29 -0
  394. package/dist/view/terrain/context.d.ts +3 -4
  395. package/dist/view/terrain/context.js +4 -5
  396. package/dist/view/terrain/drape/geometry.js +1 -1
  397. package/dist/view/terrain/drape/pass.d.ts +1 -1
  398. package/dist/view/terrain/drape/pass.js +8 -7
  399. package/dist/view/terrain/polygon.d.ts +9 -5
  400. package/dist/view/terrain/polygon.js +16 -2
  401. package/dist/view/terrain/state.d.ts +1 -1
  402. package/dist/view/terrain/state.js +1 -1
  403. package/dist/view/terrain/tessellation.d.ts +2 -2
  404. package/dist/view/terrain/tessellation.js +1 -1
  405. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  406. package/dist/view/ui/bounds.js +8 -12
  407. package/dist/view/ui/handle-test.js +2 -2
  408. package/dist/view/ui/handle-thinning.js +17 -17
  409. package/dist/view/ui/handles.js +21 -13
  410. package/dist/view/ui/helper.d.ts +1 -1
  411. package/dist/view/ui/helper.js +1 -1
  412. package/dist/view/ui/index.d.ts +1 -1
  413. package/dist/view/ui/selection-scope.js +4 -2
  414. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  415. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  416. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  417. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  418. package/dist/view/ui/selection-ui/index.js +1 -1
  419. package/dist/view/ui/selection-ui/renderer.js +15 -38
  420. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  421. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  422. package/dist/view/ui/selection-ui-drawer.js +63 -2
  423. package/dist/view/ui/tentative.js +1 -1
  424. package/dist/webgl/index.d.ts +65 -0
  425. package/dist/webgl/index.js +62 -0
  426. package/package.json +20 -9
  427. package/dist/api/api.d.ts +0 -1259
  428. package/dist/api/api.js +0 -86
  429. package/dist/api/context.d.ts +0 -173
  430. package/dist/api/display-api.js +0 -23
  431. package/dist/api/event-api.d.ts +0 -13
  432. package/dist/api/event-api.js +0 -17
  433. package/dist/api/extension-api.d.ts +0 -46
  434. package/dist/api/extension-api.js +0 -85
  435. package/dist/api/feature-api.d.ts +0 -11
  436. package/dist/api/feature-api.js +0 -101
  437. package/dist/api/geometry/apply.d.ts +0 -51
  438. package/dist/api/geometry/boolean.d.ts +0 -28
  439. package/dist/api/geometry/boolean.js +0 -65
  440. package/dist/api/geometry/types.d.ts +0 -31
  441. package/dist/api/geometry-operations.d.ts +0 -162
  442. package/dist/api/geometry-operations.js +0 -94
  443. package/dist/api/group-api.d.ts +0 -10
  444. package/dist/api/group-api.js +0 -78
  445. package/dist/api/import-export/constants.d.ts +0 -29
  446. package/dist/api/import-export/constants.js +0 -40
  447. package/dist/api/import-export/file-name.d.ts +0 -10
  448. package/dist/api/import-export/file-name.js +0 -20
  449. package/dist/api/import-export/geojson-export.d.ts +0 -19
  450. package/dist/api/import-export/image-import.d.ts +0 -12
  451. package/dist/api/import-export/image-import.js +0 -53
  452. package/dist/api/import-export/index.d.ts +0 -9
  453. package/dist/api/import-export/index.js +0 -107
  454. package/dist/api/import-export/native-format.d.ts +0 -15
  455. package/dist/api/import-export/style-validation.d.ts +0 -27
  456. package/dist/api/import-export/style-validation.js +0 -49
  457. package/dist/api/import-export/types.d.ts +0 -26
  458. package/dist/api/index.d.ts +0 -15
  459. package/dist/api/index.js +0 -3
  460. package/dist/api/input-api.d.ts +0 -158
  461. package/dist/api/input-api.js +0 -144
  462. package/dist/api/instance-api.d.ts +0 -38
  463. package/dist/api/instance-api.js +0 -136
  464. package/dist/api/layer-api.d.ts +0 -12
  465. package/dist/api/layer-api.js +0 -62
  466. package/dist/api/selection-api.d.ts +0 -7
  467. package/dist/api/selection-api.js +0 -78
  468. package/dist/api/snapping-api.d.ts +0 -125
  469. package/dist/api/snapping-api.js +0 -50
  470. package/dist/api/topology-api.d.ts +0 -30
  471. package/dist/api/topology-api.js +0 -16
  472. package/dist/api/tracing-api.d.ts +0 -31
  473. package/dist/api/tracing-api.js +0 -16
  474. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  475. package/dist/dispatcher/hit-test/index.js +0 -9
  476. package/dist/dispatcher/index.d.ts +0 -15
  477. package/dist/dispatcher/index.js +0 -3
  478. package/dist/display/columnar/index.d.ts +0 -12
  479. package/dist/display/columnar/index.js +0 -13
  480. package/dist/display/columnar/prepare.d.ts +0 -42
  481. package/dist/display/columnar/prepare.js +0 -116
  482. package/dist/display/index.d.ts +0 -13
  483. package/dist/display/types.js +0 -43
  484. package/dist/maplibre-gl-draw.d.ts +0 -47
  485. package/dist/modes/cursor.js +0 -72
  486. package/dist/modes/index.d.ts +0 -7
  487. package/dist/operations/index.d.ts +0 -9
  488. package/dist/operations/index.js +0 -3
  489. package/dist/plugins/index.d.ts +0 -10
  490. package/dist/plugins/mutation-hooks.d.ts +0 -28
  491. package/dist/plugins/mutation-hooks.js +0 -84
  492. package/dist/plugins/plugin-context.js +0 -367
  493. package/dist/plugins/plugin-manager.d.ts +0 -103
  494. package/dist/plugins/plugin-manager.js +0 -316
  495. package/dist/plugins/plugin.d.ts +0 -529
  496. package/dist/shared/config/index.d.ts +0 -17
  497. package/dist/shared/config/index.js +0 -8
  498. package/dist/shared/utils/index.d.ts +0 -15
  499. package/dist/shared/utils/index.js +0 -24
  500. package/dist/snapping/index.d.ts +0 -14
  501. package/dist/snapping/index.js +0 -4
  502. package/dist/store/change-merger.js +0 -102
  503. package/dist/store/event-bridge.js +0 -161
  504. package/dist/store/index.d.ts +0 -12
  505. package/dist/store/index.js +0 -4
  506. package/dist/view/index.d.ts +0 -47
  507. package/dist/view/index.js +0 -20
  508. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  509. /package/dist/api/{import-export/types.js → document.js} +0 -0
  510. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  511. /package/dist/{display/index.js → api/events.js} +0 -0
  512. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  513. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  514. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  515. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  516. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  517. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  518. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  519. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  520. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  521. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  522. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  523. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  524. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  525. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  526. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  527. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  528. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  529. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  532. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  533. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  534. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  535. /package/dist/{display → dataset}/chunk-set.js +0 -0
  536. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  537. /package/dist/{display → dataset}/manager.js +0 -0
  538. /package/dist/{display → dataset}/provider.js +0 -0
  539. /package/dist/{display → dataset}/selection.d.ts +0 -0
  540. /package/dist/{display → dataset}/selection.js +0 -0
@@ -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
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Test: the public predicates between points, lines and polygons
3
+ *
4
+ * The tests run on the lng/lat plane. A point or a line is contained when it lies inside the
5
+ * polygon or on its boundary; a polygon is contained when no part of it lies outside.
6
+ */
7
+ import type { Geometry, MultiPolygon, Point, Polygon, Position } from 'geojson';
8
+ /**
9
+ * Determines whether a point lies inside a polygon, holes taken into account.
10
+ *
11
+ * @param point The point, a position `[lng, lat]` in degrees or a Point
12
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
13
+ * in degrees
14
+ * @returns `true` when the point lies inside an outer ring and inside none of its holes. The
15
+ * result for a point exactly on the boundary is not defined
16
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not of the expected type
17
+ */
18
+ export declare function pointInPolygon(point: Position | Point, polygon: Polygon | MultiPolygon | {
19
+ readonly geometry: Geometry;
20
+ }): boolean;
21
+ /**
22
+ * Determines whether two polygons share an area.
23
+ *
24
+ * @param a The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates in
25
+ * degrees
26
+ * @param b The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates in
27
+ * degrees
28
+ * @returns `true` when the common part has an area. `false` when they only touch along an edge
29
+ * or at a vertex
30
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a Polygon or a
31
+ * MultiPolygon, and (`engine-failure`) when the boolean operation fails
32
+ */
33
+ export declare function overlaps(a: Polygon | MultiPolygon | {
34
+ readonly geometry: Geometry;
35
+ }, b: Polygon | MultiPolygon | {
36
+ readonly geometry: Geometry;
37
+ }): boolean;
38
+ /**
39
+ * Determines whether a polygon completely contains a geometry.
40
+ *
41
+ * @param outer The containing Polygon or MultiPolygon, or a feature whose geometry is one;
42
+ * coordinates in degrees
43
+ * @param inner The contained geometry, or a feature whose geometry it is; coordinates in
44
+ * degrees. It may share the boundary of `outer`
45
+ * @returns `true` when no part of `inner` lies outside `outer`. `false` for a polygon without
46
+ * an area and for an empty geometry
47
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not of the expected
48
+ * type, and (`engine-failure`) when the boolean operation fails
49
+ */
50
+ export declare function contains(outer: Polygon | MultiPolygon | {
51
+ readonly geometry: Geometry;
52
+ }, inner: Geometry | {
53
+ readonly geometry: Geometry;
54
+ }): boolean;
@@ -0,0 +1,144 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { usableAreaParts } from './coords.js';
4
+ import { withOperation } from './errors.js';
5
+ import { areaOf, geometryOf, positionOf } from './geojson.js';
6
+ import { contains as containsArea, intersects, pointInPolygon as pointInArea, } from './predicates.js';
7
+ import { segmentIntersection } from './split.js';
8
+ /**
9
+ * Determines whether a point lies inside a polygon, holes taken into account.
10
+ *
11
+ * @param point The point, a position `[lng, lat]` in degrees or a Point
12
+ * @param polygon The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates
13
+ * in degrees
14
+ * @returns `true` when the point lies inside an outer ring and inside none of its holes. The
15
+ * result for a point exactly on the boundary is not defined
16
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not of the expected type
17
+ */
18
+ export function pointInPolygon(point, polygon) {
19
+ return pointInArea(positionOf(point, 'pointInPolygon'), areaOf(polygon, 'pointInPolygon'));
20
+ }
21
+ /**
22
+ * Determines whether two polygons share an area.
23
+ *
24
+ * @param a The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates in
25
+ * degrees
26
+ * @param b The Polygon or MultiPolygon, or a feature whose geometry is one; coordinates in
27
+ * degrees
28
+ * @returns `true` when the common part has an area. `false` when they only touch along an edge
29
+ * or at a vertex
30
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not a Polygon or a
31
+ * MultiPolygon, and (`engine-failure`) when the boolean operation fails
32
+ */
33
+ export function overlaps(a, b) {
34
+ const left = areaOf(a, 'overlaps');
35
+ const right = areaOf(b, 'overlaps');
36
+ return withOperation('overlaps', () => intersects(left, right));
37
+ }
38
+ /** The distance in degrees within which a point counts as on the boundary */
39
+ const BOUNDARY_EPSILON = 1e-12;
40
+ /** The square of the planar distance from a point to a segment */
41
+ function squaredSegmentDistance(p, a, b) {
42
+ const dx = b[0] - a[0];
43
+ const dy = b[1] - a[1];
44
+ const lengthSquared = dx * dx + dy * dy;
45
+ const t = lengthSquared === 0
46
+ ? 0
47
+ : Math.min(1, Math.max(0, ((p[0] - a[0]) * dx + (p[1] - a[1]) * dy) / lengthSquared));
48
+ const x = p[0] - (a[0] + t * dx);
49
+ const y = p[1] - (a[1] + t * dy);
50
+ return x * x + y * y;
51
+ }
52
+ /** Calls a function with every edge of every ring, the closing edge included */
53
+ function forEachEdge(parts, visit) {
54
+ for (const part of parts) {
55
+ for (const ring of part) {
56
+ for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
57
+ if (visit(ring[j], ring[i]) === true)
58
+ return true;
59
+ }
60
+ }
61
+ }
62
+ return false;
63
+ }
64
+ function onBoundary(point, parts) {
65
+ const limit = BOUNDARY_EPSILON * BOUNDARY_EPSILON;
66
+ return forEachEdge(parts, (a, b) => squaredSegmentDistance(point, a, b) <= limit);
67
+ }
68
+ function coversPoint(parts, point) {
69
+ return pointInArea(point, parts) || onBoundary(point, parts);
70
+ }
71
+ /**
72
+ * Whether a line lies inside the polygon or on its boundary
73
+ *
74
+ * Each segment is cut where it crosses an edge; every vertex and the middle of every piece
75
+ * must be covered.
76
+ */
77
+ function coversLine(parts, line) {
78
+ if (line.length === 0)
79
+ return false;
80
+ if (!line.every((vertex) => coversPoint(parts, vertex)))
81
+ return false;
82
+ for (let i = 0; i < line.length - 1; i++) {
83
+ const a = line[i];
84
+ const b = line[i + 1];
85
+ const dx = b[0] - a[0];
86
+ const dy = b[1] - a[1];
87
+ const alongX = Math.abs(dx) >= Math.abs(dy);
88
+ const cuts = [0, 1];
89
+ forEachEdge(parts, (c, d) => {
90
+ const crossing = segmentIntersection(a, b, c, d);
91
+ if (crossing !== null) {
92
+ cuts.push(alongX ? (crossing[0] - a[0]) / dx : (crossing[1] - a[1]) / dy);
93
+ }
94
+ return undefined;
95
+ });
96
+ cuts.sort((x, y) => x - y);
97
+ for (let k = 0; k < cuts.length - 1; k++) {
98
+ if (cuts[k + 1] - cuts[k] <= BOUNDARY_EPSILON)
99
+ continue;
100
+ const t = (cuts[k] + cuts[k + 1]) / 2;
101
+ if (!coversPoint(parts, [a[0] + t * dx, a[1] + t * dy]))
102
+ return false;
103
+ }
104
+ }
105
+ return true;
106
+ }
107
+ function containsGeometry(outer, inner) {
108
+ const parts = usableAreaParts(outer);
109
+ switch (inner.type) {
110
+ case 'Polygon':
111
+ case 'MultiPolygon':
112
+ return containsArea(outer, inner.coordinates);
113
+ case 'Point':
114
+ return coversPoint(parts, inner.coordinates);
115
+ case 'MultiPoint':
116
+ return (inner.coordinates.length > 0 &&
117
+ inner.coordinates.every((point) => coversPoint(parts, point)));
118
+ case 'LineString':
119
+ return coversLine(parts, inner.coordinates);
120
+ case 'MultiLineString':
121
+ return (inner.coordinates.length > 0 &&
122
+ inner.coordinates.every((line) => coversLine(parts, line)));
123
+ case 'GeometryCollection':
124
+ return (inner.geometries.length > 0 &&
125
+ inner.geometries.every((member) => containsGeometry(outer, geometryOf(member, 'contains'))));
126
+ }
127
+ }
128
+ /**
129
+ * Determines whether a polygon completely contains a geometry.
130
+ *
131
+ * @param outer The containing Polygon or MultiPolygon, or a feature whose geometry is one;
132
+ * coordinates in degrees
133
+ * @param inner The contained geometry, or a feature whose geometry it is; coordinates in
134
+ * degrees. It may share the boundary of `outer`
135
+ * @returns `true` when no part of `inner` lies outside `outer`. `false` for a polygon without
136
+ * an area and for an empty geometry
137
+ * @throws {@link GeometryError} (`invalid-input`) when an argument is not of the expected
138
+ * type, and (`engine-failure`) when the boolean operation fails
139
+ */
140
+ export function contains(outer, inner) {
141
+ const area = areaOf(outer, 'contains');
142
+ const geometry = geometryOf(inner, 'contains');
143
+ return withOperation('contains', () => containsGeometry(area, geometry));
144
+ }