@sakuzu/maplibre-gl-draw 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +661 -0
  3. package/README.ja.md +248 -0
  4. package/README.md +255 -0
  5. package/THIRD_PARTY_NOTICES.md +275 -0
  6. package/dist/api/api.d.ts +1259 -0
  7. package/dist/api/api.js +86 -0
  8. package/dist/api/context.d.ts +173 -0
  9. package/dist/api/context.js +193 -0
  10. package/dist/api/display-api.d.ts +1 -0
  11. package/dist/api/display-api.js +23 -0
  12. package/dist/api/event-api.d.ts +13 -0
  13. package/dist/api/event-api.js +17 -0
  14. package/dist/api/extension-api.d.ts +46 -0
  15. package/dist/api/extension-api.js +85 -0
  16. package/dist/api/feature-api.d.ts +11 -0
  17. package/dist/api/feature-api.js +101 -0
  18. package/dist/api/geometry/apply.d.ts +51 -0
  19. package/dist/api/geometry/apply.js +114 -0
  20. package/dist/api/geometry/boolean.d.ts +28 -0
  21. package/dist/api/geometry/boolean.js +65 -0
  22. package/dist/api/geometry/buffer.d.ts +11 -0
  23. package/dist/api/geometry/buffer.js +105 -0
  24. package/dist/api/geometry/split.d.ts +16 -0
  25. package/dist/api/geometry/split.js +75 -0
  26. package/dist/api/geometry/targets.d.ts +76 -0
  27. package/dist/api/geometry/targets.js +158 -0
  28. package/dist/api/geometry/types.d.ts +31 -0
  29. package/dist/api/geometry/types.js +3 -0
  30. package/dist/api/geometry-operations.d.ts +162 -0
  31. package/dist/api/geometry-operations.js +94 -0
  32. package/dist/api/group-api.d.ts +10 -0
  33. package/dist/api/group-api.js +78 -0
  34. package/dist/api/import-export/constants.d.ts +29 -0
  35. package/dist/api/import-export/constants.js +40 -0
  36. package/dist/api/import-export/embedded-file.d.ts +13 -0
  37. package/dist/api/import-export/embedded-file.js +31 -0
  38. package/dist/api/import-export/file-name.d.ts +10 -0
  39. package/dist/api/import-export/file-name.js +20 -0
  40. package/dist/api/import-export/format-detection.d.ts +12 -0
  41. package/dist/api/import-export/format-detection.js +29 -0
  42. package/dist/api/import-export/geojson-export.d.ts +19 -0
  43. package/dist/api/import-export/geojson-export.js +262 -0
  44. package/dist/api/import-export/geojson-import.d.ts +34 -0
  45. package/dist/api/import-export/geojson-import.js +538 -0
  46. package/dist/api/import-export/geometry-validation.d.ts +20 -0
  47. package/dist/api/import-export/geometry-validation.js +107 -0
  48. package/dist/api/import-export/image-import.d.ts +12 -0
  49. package/dist/api/import-export/image-import.js +53 -0
  50. package/dist/api/import-export/index.d.ts +9 -0
  51. package/dist/api/import-export/index.js +107 -0
  52. package/dist/api/import-export/native-format.d.ts +15 -0
  53. package/dist/api/import-export/native-format.js +126 -0
  54. package/dist/api/import-export/native-validation.d.ts +28 -0
  55. package/dist/api/import-export/native-validation.js +212 -0
  56. package/dist/api/import-export/own-property.d.ts +10 -0
  57. package/dist/api/import-export/own-property.js +19 -0
  58. package/dist/api/import-export/style-validation.d.ts +27 -0
  59. package/dist/api/import-export/style-validation.js +49 -0
  60. package/dist/api/import-export/types.d.ts +26 -0
  61. package/dist/api/import-export/types.js +3 -0
  62. package/dist/api/index.d.ts +15 -0
  63. package/dist/api/index.js +3 -0
  64. package/dist/api/input-api.d.ts +158 -0
  65. package/dist/api/input-api.js +144 -0
  66. package/dist/api/instance-api.d.ts +38 -0
  67. package/dist/api/instance-api.js +136 -0
  68. package/dist/api/layer-api.d.ts +12 -0
  69. package/dist/api/layer-api.js +62 -0
  70. package/dist/api/selection-api.d.ts +7 -0
  71. package/dist/api/selection-api.js +78 -0
  72. package/dist/api/snapping-api.d.ts +125 -0
  73. package/dist/api/snapping-api.js +50 -0
  74. package/dist/api/topology-api.d.ts +30 -0
  75. package/dist/api/topology-api.js +16 -0
  76. package/dist/api/tracing-api.d.ts +31 -0
  77. package/dist/api/tracing-api.js +16 -0
  78. package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
  79. package/dist/dispatcher/hit-test/box-strategies.js +275 -0
  80. package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
  81. package/dist/dispatcher/hit-test/box-strategy.js +37 -0
  82. package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
  83. package/dist/dispatcher/hit-test/globe-shape.js +70 -0
  84. package/dist/dispatcher/hit-test/index.d.ts +14 -0
  85. package/dist/dispatcher/hit-test/index.js +9 -0
  86. package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
  87. package/dist/dispatcher/hit-test/local-frame.js +112 -0
  88. package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
  89. package/dist/dispatcher/hit-test/segment-grid.js +79 -0
  90. package/dist/dispatcher/hit-test/service.d.ts +120 -0
  91. package/dist/dispatcher/hit-test/service.js +333 -0
  92. package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
  93. package/dist/dispatcher/hit-test/strategies/base.js +66 -0
  94. package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
  95. package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
  96. package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
  97. package/dist/dispatcher/hit-test/strategies/image.js +115 -0
  98. package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
  99. package/dist/dispatcher/hit-test/strategies/index.js +10 -0
  100. package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
  101. package/dist/dispatcher/hit-test/strategies/line.js +30 -0
  102. package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
  103. package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
  104. package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
  105. package/dist/dispatcher/hit-test/strategies/point.js +29 -0
  106. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
  107. package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
  108. package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
  109. package/dist/dispatcher/hit-test/topmost.js +157 -0
  110. package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
  111. package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
  112. package/dist/dispatcher/index.d.ts +15 -0
  113. package/dist/dispatcher/index.js +3 -0
  114. package/dist/dispatcher/input-router.d.ts +1 -0
  115. package/dist/dispatcher/input-router.js +288 -0
  116. package/dist/dispatcher/normalizer.d.ts +1 -0
  117. package/dist/dispatcher/normalizer.js +513 -0
  118. package/dist/dispatcher/types.d.ts +144 -0
  119. package/dist/dispatcher/types.js +15 -0
  120. package/dist/display/chunk-set.d.ts +24 -0
  121. package/dist/display/chunk-set.js +533 -0
  122. package/dist/display/chunk.d.ts +1 -0
  123. package/dist/display/chunk.js +104 -0
  124. package/dist/display/columnar/index.d.ts +12 -0
  125. package/dist/display/columnar/index.js +13 -0
  126. package/dist/display/columnar/prepare.d.ts +42 -0
  127. package/dist/display/columnar/prepare.js +116 -0
  128. package/dist/display/columnar/source.d.ts +1 -0
  129. package/dist/display/columnar/source.js +531 -0
  130. package/dist/display/columnar/table.d.ts +1 -0
  131. package/dist/display/columnar/table.js +471 -0
  132. package/dist/display/columnar/types.d.ts +223 -0
  133. package/dist/display/columnar/types.js +3 -0
  134. package/dist/display/dataset.d.ts +2 -0
  135. package/dist/display/dataset.js +891 -0
  136. package/dist/display/index.d.ts +13 -0
  137. package/dist/display/index.js +3 -0
  138. package/dist/display/interaction.d.ts +1 -0
  139. package/dist/display/interaction.js +90 -0
  140. package/dist/display/manager.d.ts +1 -0
  141. package/dist/display/manager.js +440 -0
  142. package/dist/display/packed-rtree.d.ts +1 -0
  143. package/dist/display/packed-rtree.js +244 -0
  144. package/dist/display/partition.d.ts +1 -0
  145. package/dist/display/partition.js +226 -0
  146. package/dist/display/provider.d.ts +1 -0
  147. package/dist/display/provider.js +342 -0
  148. package/dist/display/retained.d.ts +40 -0
  149. package/dist/display/retained.js +898 -0
  150. package/dist/display/selection.d.ts +13 -0
  151. package/dist/display/selection.js +226 -0
  152. package/dist/display/source.d.ts +1 -0
  153. package/dist/display/source.js +119 -0
  154. package/dist/display/spatial.d.ts +1 -0
  155. package/dist/display/spatial.js +71 -0
  156. package/dist/display/style.d.ts +1 -0
  157. package/dist/display/style.js +126 -0
  158. package/dist/display/thinning.d.ts +65 -0
  159. package/dist/display/thinning.js +910 -0
  160. package/dist/display/triangulation.d.ts +1 -0
  161. package/dist/display/triangulation.js +0 -0
  162. package/dist/display/types.d.ts +561 -0
  163. package/dist/display/types.js +43 -0
  164. package/dist/extension/feature-handler.d.ts +182 -0
  165. package/dist/extension/feature-handler.js +3 -0
  166. package/dist/extension/index.d.ts +9 -0
  167. package/dist/extension/index.js +3 -0
  168. package/dist/extension/renderers.d.ts +208 -0
  169. package/dist/extension/renderers.js +3 -0
  170. package/dist/geometry/angle.d.ts +47 -0
  171. package/dist/geometry/angle.js +44 -0
  172. package/dist/geometry/bbox.d.ts +48 -0
  173. package/dist/geometry/bbox.js +83 -0
  174. package/dist/geometry/boolean.d.ts +162 -0
  175. package/dist/geometry/boolean.js +331 -0
  176. package/dist/geometry/buffer.d.ts +72 -0
  177. package/dist/geometry/buffer.js +218 -0
  178. package/dist/geometry/circle.d.ts +55 -0
  179. package/dist/geometry/circle.js +107 -0
  180. package/dist/geometry/coords.d.ts +97 -0
  181. package/dist/geometry/coords.js +149 -0
  182. package/dist/geometry/distance.d.ts +79 -0
  183. package/dist/geometry/distance.js +111 -0
  184. package/dist/geometry/errors.d.ts +74 -0
  185. package/dist/geometry/errors.js +104 -0
  186. package/dist/geometry/index.d.ts +28 -0
  187. package/dist/geometry/index.js +38 -0
  188. package/dist/geometry/measure.d.ts +81 -0
  189. package/dist/geometry/measure.js +236 -0
  190. package/dist/geometry/predicates.d.ts +62 -0
  191. package/dist/geometry/predicates.js +132 -0
  192. package/dist/geometry/simplify.d.ts +74 -0
  193. package/dist/geometry/simplify.js +159 -0
  194. package/dist/geometry/split.d.ts +68 -0
  195. package/dist/geometry/split.js +430 -0
  196. package/dist/geometry/types.d.ts +95 -0
  197. package/dist/geometry/types.js +3 -0
  198. package/dist/geometry/units.d.ts +35 -0
  199. package/dist/geometry/units.js +41 -0
  200. package/dist/index.d.ts +72 -0
  201. package/dist/index.js +20 -0
  202. package/dist/maplibre-gl-draw.d.ts +47 -0
  203. package/dist/maplibre-gl-draw.js +407 -0
  204. package/dist/messages.d.ts +64 -0
  205. package/dist/messages.js +36 -0
  206. package/dist/modes/cursor.d.ts +1 -0
  207. package/dist/modes/cursor.js +72 -0
  208. package/dist/modes/draw/circle.d.ts +1 -0
  209. package/dist/modes/draw/circle.js +222 -0
  210. package/dist/modes/draw/commit-layer.d.ts +26 -0
  211. package/dist/modes/draw/commit-layer.js +31 -0
  212. package/dist/modes/draw/freehand.d.ts +1 -0
  213. package/dist/modes/draw/freehand.js +264 -0
  214. package/dist/modes/draw/image.d.ts +1 -0
  215. package/dist/modes/draw/image.js +60 -0
  216. package/dist/modes/draw/index.d.ts +9 -0
  217. package/dist/modes/draw/index.js +11 -0
  218. package/dist/modes/draw/line.d.ts +1 -0
  219. package/dist/modes/draw/line.js +363 -0
  220. package/dist/modes/draw/point.d.ts +1 -0
  221. package/dist/modes/draw/point.js +87 -0
  222. package/dist/modes/draw/polygon.d.ts +1 -0
  223. package/dist/modes/draw/polygon.js +378 -0
  224. package/dist/modes/draw/trace-support.d.ts +79 -0
  225. package/dist/modes/draw/trace-support.js +161 -0
  226. package/dist/modes/handler.d.ts +285 -0
  227. package/dist/modes/handler.js +3 -0
  228. package/dist/modes/index.d.ts +7 -0
  229. package/dist/modes/index.js +3 -0
  230. package/dist/modes/manager.d.ts +15 -0
  231. package/dist/modes/manager.js +196 -0
  232. package/dist/modes/select/box-selection.d.ts +52 -0
  233. package/dist/modes/select/box-selection.js +140 -0
  234. package/dist/modes/select/click-handler.d.ts +32 -0
  235. package/dist/modes/select/click-handler.js +166 -0
  236. package/dist/modes/select/cursor-handler.d.ts +15 -0
  237. package/dist/modes/select/cursor-handler.js +59 -0
  238. package/dist/modes/select/drag/auxiliary.d.ts +26 -0
  239. package/dist/modes/select/drag/auxiliary.js +56 -0
  240. package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
  241. package/dist/modes/select/drag/intermediate-writes.js +171 -0
  242. package/dist/modes/select/drag/move.d.ts +24 -0
  243. package/dist/modes/select/drag/move.js +59 -0
  244. package/dist/modes/select/drag/operation.d.ts +30 -0
  245. package/dist/modes/select/drag/operation.js +18 -0
  246. package/dist/modes/select/drag/radius.d.ts +15 -0
  247. package/dist/modes/select/drag/radius.js +49 -0
  248. package/dist/modes/select/drag/transform.d.ts +17 -0
  249. package/dist/modes/select/drag/transform.js +155 -0
  250. package/dist/modes/select/drag/vertex.d.ts +17 -0
  251. package/dist/modes/select/drag/vertex.js +163 -0
  252. package/dist/modes/select/drag-handler.d.ts +1 -0
  253. package/dist/modes/select/drag-handler.js +254 -0
  254. package/dist/modes/select/hit-helpers.d.ts +40 -0
  255. package/dist/modes/select/hit-helpers.js +51 -0
  256. package/dist/modes/select/mode.d.ts +1 -0
  257. package/dist/modes/select/mode.js +397 -0
  258. package/dist/modes/select/shortcut-handler.d.ts +40 -0
  259. package/dist/modes/select/shortcut-handler.js +128 -0
  260. package/dist/operations/index.d.ts +9 -0
  261. package/dist/operations/index.js +3 -0
  262. package/dist/operations/layer-operations.d.ts +1 -0
  263. package/dist/operations/layer-operations.js +350 -0
  264. package/dist/operations/resize.d.ts +71 -0
  265. package/dist/operations/resize.js +252 -0
  266. package/dist/operations/rotate.d.ts +17 -0
  267. package/dist/operations/rotate.js +166 -0
  268. package/dist/operations/selection-operations.d.ts +20 -0
  269. package/dist/operations/selection-operations.js +159 -0
  270. package/dist/operations/shared-vertex.d.ts +1 -0
  271. package/dist/operations/shared-vertex.js +210 -0
  272. package/dist/operations/trace-graph.d.ts +96 -0
  273. package/dist/operations/trace-graph.js +283 -0
  274. package/dist/operations/vertex.d.ts +1 -0
  275. package/dist/operations/vertex.js +538 -0
  276. package/dist/plugins/index.d.ts +10 -0
  277. package/dist/plugins/index.js +3 -0
  278. package/dist/plugins/mutation-hooks.d.ts +28 -0
  279. package/dist/plugins/mutation-hooks.js +84 -0
  280. package/dist/plugins/plugin-context.d.ts +1 -0
  281. package/dist/plugins/plugin-context.js +367 -0
  282. package/dist/plugins/plugin-manager.d.ts +103 -0
  283. package/dist/plugins/plugin-manager.js +316 -0
  284. package/dist/plugins/plugin.d.ts +529 -0
  285. package/dist/plugins/plugin.js +3 -0
  286. package/dist/shared/config/constants.d.ts +66 -0
  287. package/dist/shared/config/constants.js +60 -0
  288. package/dist/shared/config/feature-style.d.ts +155 -0
  289. package/dist/shared/config/feature-style.js +154 -0
  290. package/dist/shared/config/index.d.ts +17 -0
  291. package/dist/shared/config/index.js +8 -0
  292. package/dist/shared/config/rendering.d.ts +107 -0
  293. package/dist/shared/config/rendering.js +33 -0
  294. package/dist/shared/config/selection-highlight.d.ts +29 -0
  295. package/dist/shared/config/selection-highlight.js +35 -0
  296. package/dist/shared/config/selection.d.ts +273 -0
  297. package/dist/shared/config/selection.js +266 -0
  298. package/dist/shared/config/topology.d.ts +33 -0
  299. package/dist/shared/config/topology.js +17 -0
  300. package/dist/shared/config/trace.d.ts +40 -0
  301. package/dist/shared/config/trace.js +17 -0
  302. package/dist/shared/math/angle.d.ts +21 -0
  303. package/dist/shared/math/angle.js +34 -0
  304. package/dist/shared/math/circle.d.ts +6 -0
  305. package/dist/shared/math/circle.js +10 -0
  306. package/dist/shared/math/constants.d.ts +48 -0
  307. package/dist/shared/math/constants.js +59 -0
  308. package/dist/shared/math/distance.d.ts +78 -0
  309. package/dist/shared/math/distance.js +147 -0
  310. package/dist/shared/math/globe-subdivision.d.ts +62 -0
  311. package/dist/shared/math/globe-subdivision.js +99 -0
  312. package/dist/shared/math/index.d.ts +17 -0
  313. package/dist/shared/math/index.js +21 -0
  314. package/dist/shared/math/intersection.d.ts +63 -0
  315. package/dist/shared/math/intersection.js +236 -0
  316. package/dist/shared/math/longitude.d.ts +20 -0
  317. package/dist/shared/math/longitude.js +31 -0
  318. package/dist/shared/math/mercator-plane.d.ts +27 -0
  319. package/dist/shared/math/mercator-plane.js +26 -0
  320. package/dist/shared/math/obb.d.ts +65 -0
  321. package/dist/shared/math/obb.js +107 -0
  322. package/dist/shared/math/rotation.d.ts +93 -0
  323. package/dist/shared/math/rotation.js +186 -0
  324. package/dist/shared/math/segment-grid.d.ts +69 -0
  325. package/dist/shared/math/segment-grid.js +159 -0
  326. package/dist/shared/math/transform.d.ts +140 -0
  327. package/dist/shared/math/transform.js +189 -0
  328. package/dist/shared/types/events.d.ts +128 -0
  329. package/dist/shared/types/events.js +3 -0
  330. package/dist/shared/types/model.d.ts +950 -0
  331. package/dist/shared/types/model.js +3 -0
  332. package/dist/shared/types/selection-box.d.ts +23 -0
  333. package/dist/shared/types/selection-box.js +3 -0
  334. package/dist/shared/types/style.d.ts +68 -0
  335. package/dist/shared/types/style.js +3 -0
  336. package/dist/shared/utils/color.d.ts +49 -0
  337. package/dist/shared/utils/color.js +180 -0
  338. package/dist/shared/utils/coordinates.d.ts +52 -0
  339. package/dist/shared/utils/coordinates.js +75 -0
  340. package/dist/shared/utils/embedded-image.d.ts +34 -0
  341. package/dist/shared/utils/embedded-image.js +161 -0
  342. package/dist/shared/utils/event-emitter.d.ts +262 -0
  343. package/dist/shared/utils/event-emitter.js +44 -0
  344. package/dist/shared/utils/feature-bbox.d.ts +8 -0
  345. package/dist/shared/utils/feature-bbox.js +207 -0
  346. package/dist/shared/utils/feature-segments.d.ts +23 -0
  347. package/dist/shared/utils/feature-segments.js +179 -0
  348. package/dist/shared/utils/id.d.ts +1 -0
  349. package/dist/shared/utils/id.js +35 -0
  350. package/dist/shared/utils/image.d.ts +34 -0
  351. package/dist/shared/utils/image.js +106 -0
  352. package/dist/shared/utils/index.d.ts +15 -0
  353. package/dist/shared/utils/index.js +24 -0
  354. package/dist/shared/utils/map.d.ts +26 -0
  355. package/dist/shared/utils/map.js +35 -0
  356. package/dist/shared/utils/name-generator.d.ts +197 -0
  357. package/dist/shared/utils/name-generator.js +337 -0
  358. package/dist/shared/utils/pixel-ratio.d.ts +111 -0
  359. package/dist/shared/utils/pixel-ratio.js +85 -0
  360. package/dist/shared/utils/property.d.ts +88 -0
  361. package/dist/shared/utils/property.js +140 -0
  362. package/dist/shared/utils/vertex-ref.d.ts +23 -0
  363. package/dist/shared/utils/vertex-ref.js +20 -0
  364. package/dist/snapping/custom-targets.d.ts +1 -0
  365. package/dist/snapping/custom-targets.js +21 -0
  366. package/dist/snapping/geometry.d.ts +1 -0
  367. package/dist/snapping/geometry.js +61 -0
  368. package/dist/snapping/index.d.ts +14 -0
  369. package/dist/snapping/index.js +4 -0
  370. package/dist/snapping/indicator.d.ts +19 -0
  371. package/dist/snapping/indicator.js +145 -0
  372. package/dist/snapping/providers/display.d.ts +72 -0
  373. package/dist/snapping/providers/display.js +268 -0
  374. package/dist/snapping/providers/guide.d.ts +69 -0
  375. package/dist/snapping/providers/guide.js +187 -0
  376. package/dist/snapping/providers/intersection.d.ts +1 -0
  377. package/dist/snapping/providers/intersection.js +92 -0
  378. package/dist/snapping/providers/shared.d.ts +39 -0
  379. package/dist/snapping/providers/shared.js +146 -0
  380. package/dist/snapping/providers/store.d.ts +1 -0
  381. package/dist/snapping/providers/store.js +132 -0
  382. package/dist/snapping/service.d.ts +1 -0
  383. package/dist/snapping/service.js +272 -0
  384. package/dist/snapping/types.d.ts +267 -0
  385. package/dist/snapping/types.js +66 -0
  386. package/dist/store/change-merger.d.ts +1 -0
  387. package/dist/store/change-merger.js +102 -0
  388. package/dist/store/draw-store.d.ts +1 -0
  389. package/dist/store/draw-store.js +396 -0
  390. package/dist/store/event-bridge.d.ts +1 -0
  391. package/dist/store/event-bridge.js +161 -0
  392. package/dist/store/index.d.ts +12 -0
  393. package/dist/store/index.js +4 -0
  394. package/dist/store/local-visibility.d.ts +21 -0
  395. package/dist/store/local-visibility.js +27 -0
  396. package/dist/store/lock.d.ts +67 -0
  397. package/dist/store/lock.js +54 -0
  398. package/dist/store/memory/change-bus.d.ts +60 -0
  399. package/dist/store/memory/change-bus.js +232 -0
  400. package/dist/store/memory/file-store.d.ts +15 -0
  401. package/dist/store/memory/file-store.js +33 -0
  402. package/dist/store/memory/frozen.d.ts +21 -0
  403. package/dist/store/memory/frozen.js +51 -0
  404. package/dist/store/memory/ui-state.d.ts +51 -0
  405. package/dist/store/memory/ui-state.js +223 -0
  406. package/dist/store/memory.d.ts +26 -0
  407. package/dist/store/memory.js +708 -0
  408. package/dist/store/spatial/index.d.ts +6 -0
  409. package/dist/store/spatial/index.js +4 -0
  410. package/dist/store/spatial/spatial-index.d.ts +90 -0
  411. package/dist/store/spatial/spatial-index.js +148 -0
  412. package/dist/store/spatial/store-spatial-index.d.ts +60 -0
  413. package/dist/store/spatial/store-spatial-index.js +125 -0
  414. package/dist/store/store.d.ts +417 -0
  415. package/dist/store/store.js +3 -0
  416. package/dist/store/types.d.ts +8 -0
  417. package/dist/store/types.js +3 -0
  418. package/dist/store/writable-layer.d.ts +35 -0
  419. package/dist/store/writable-layer.js +20 -0
  420. package/dist/view/cache/buffer.d.ts +28 -0
  421. package/dist/view/cache/buffer.js +176 -0
  422. package/dist/view/cache/earcut.d.ts +1 -0
  423. package/dist/view/cache/earcut.js +122 -0
  424. package/dist/view/cache/style-rule.d.ts +1 -0
  425. package/dist/view/cache/style-rule.js +97 -0
  426. package/dist/view/cache/terrain-fill.d.ts +30 -0
  427. package/dist/view/cache/terrain-fill.js +60 -0
  428. package/dist/view/cache/texture.d.ts +14 -0
  429. package/dist/view/cache/texture.js +292 -0
  430. package/dist/view/coordinator.d.ts +27 -0
  431. package/dist/view/coordinator.js +72 -0
  432. package/dist/view/feature-companion.d.ts +173 -0
  433. package/dist/view/feature-companion.js +108 -0
  434. package/dist/view/globe-subdivision.d.ts +78 -0
  435. package/dist/view/globe-subdivision.js +128 -0
  436. package/dist/view/index.d.ts +47 -0
  437. package/dist/view/index.js +20 -0
  438. package/dist/view/layer/attach.d.ts +20 -0
  439. package/dist/view/layer/attach.js +47 -0
  440. package/dist/view/layer/blend.d.ts +57 -0
  441. package/dist/view/layer/blend.js +14 -0
  442. package/dist/view/layer/custom-layer.d.ts +1 -0
  443. package/dist/view/layer/custom-layer.js +509 -0
  444. package/dist/view/layer/depth-state.d.ts +14 -0
  445. package/dist/view/layer/depth-state.js +44 -0
  446. package/dist/view/layer/display-list.d.ts +1 -0
  447. package/dist/view/layer/display-list.js +111 -0
  448. package/dist/view/layer/drape-planner.d.ts +139 -0
  449. package/dist/view/layer/drape-planner.js +726 -0
  450. package/dist/view/layer/frame-render.d.ts +57 -0
  451. package/dist/view/layer/frame-render.js +209 -0
  452. package/dist/view/layer/frame-state.d.ts +147 -0
  453. package/dist/view/layer/frame-state.js +484 -0
  454. package/dist/view/layer/gl-state.d.ts +77 -0
  455. package/dist/view/layer/gl-state.js +132 -0
  456. package/dist/view/layer/index.d.ts +6 -0
  457. package/dist/view/layer/index.js +5 -0
  458. package/dist/view/layer/render-scope.d.ts +30 -0
  459. package/dist/view/layer/render-scope.js +28 -0
  460. package/dist/view/layer/render.d.ts +87 -0
  461. package/dist/view/layer/render.js +187 -0
  462. package/dist/view/layer/renderers.d.ts +81 -0
  463. package/dist/view/layer/renderers.js +142 -0
  464. package/dist/view/layer/slot-manager.d.ts +26 -0
  465. package/dist/view/layer/slot-manager.js +133 -0
  466. package/dist/view/layer/slots.d.ts +33 -0
  467. package/dist/view/layer/slots.js +50 -0
  468. package/dist/view/layer/store-retained-bbox.d.ts +36 -0
  469. package/dist/view/layer/store-retained-bbox.js +188 -0
  470. package/dist/view/layer/store-retained-chunk.d.ts +97 -0
  471. package/dist/view/layer/store-retained-chunk.js +94 -0
  472. package/dist/view/layer/store-retained-classify.d.ts +34 -0
  473. package/dist/view/layer/store-retained-classify.js +88 -0
  474. package/dist/view/layer/store-retained-collect.d.ts +24 -0
  475. package/dist/view/layer/store-retained-collect.js +121 -0
  476. package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
  477. package/dist/view/layer/store-retained-coord-patch.js +168 -0
  478. package/dist/view/layer/store-retained-immediate.d.ts +63 -0
  479. package/dist/view/layer/store-retained-immediate.js +49 -0
  480. package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
  481. package/dist/view/layer/store-retained-invalidation.js +192 -0
  482. package/dist/view/layer/store-retained.d.ts +198 -0
  483. package/dist/view/layer/store-retained.js +430 -0
  484. package/dist/view/layer/terrain-resolver.d.ts +1 -0
  485. package/dist/view/layer/terrain-resolver.js +174 -0
  486. package/dist/view/renderers/batch-manager.d.ts +61 -0
  487. package/dist/view/renderers/batch-manager.js +718 -0
  488. package/dist/view/renderers/draw-factors.d.ts +60 -0
  489. package/dist/view/renderers/draw-factors.js +35 -0
  490. package/dist/view/renderers/drawer.d.ts +1 -0
  491. package/dist/view/renderers/drawer.js +346 -0
  492. package/dist/view/renderers/image.d.ts +1 -0
  493. package/dist/view/renderers/image.js +255 -0
  494. package/dist/view/renderers/line/dash.d.ts +31 -0
  495. package/dist/view/renderers/line/dash.js +152 -0
  496. package/dist/view/renderers/line/line-geometry.d.ts +39 -0
  497. package/dist/view/renderers/line/line-geometry.js +460 -0
  498. package/dist/view/renderers/line/line-gl.d.ts +1 -0
  499. package/dist/view/renderers/line/line-gl.js +236 -0
  500. package/dist/view/renderers/line/line-shader.d.ts +1 -0
  501. package/dist/view/renderers/line/line-shader.js +364 -0
  502. package/dist/view/renderers/line/line-types.d.ts +43 -0
  503. package/dist/view/renderers/line/line-types.js +3 -0
  504. package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
  505. package/dist/view/renderers/line/line-uniforms.js +390 -0
  506. package/dist/view/renderers/line/sdf-line.d.ts +92 -0
  507. package/dist/view/renderers/line/sdf-line.js +567 -0
  508. package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
  509. package/dist/view/renderers/point/billboard-depth.js +56 -0
  510. package/dist/view/renderers/point/point-instance.d.ts +124 -0
  511. package/dist/view/renderers/point/point-instance.js +738 -0
  512. package/dist/view/renderers/point/point-sdf.d.ts +58 -0
  513. package/dist/view/renderers/point/point-sdf.js +170 -0
  514. package/dist/view/renderers/point/point-shape.d.ts +99 -0
  515. package/dist/view/renderers/point/point-shape.js +504 -0
  516. package/dist/view/renderers/point/point-style.d.ts +1 -0
  517. package/dist/view/renderers/point/point-style.js +46 -0
  518. package/dist/view/renderers/polygon/batch.d.ts +26 -0
  519. package/dist/view/renderers/polygon/batch.js +336 -0
  520. package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
  521. package/dist/view/renderers/polygon/earcut-input.js +55 -0
  522. package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
  523. package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
  524. package/dist/view/renderers/polygon/fill.d.ts +74 -0
  525. package/dist/view/renderers/polygon/fill.js +251 -0
  526. package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
  527. package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
  528. package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
  529. package/dist/view/renderers/polygon/terrain-cull.js +14 -0
  530. package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
  531. package/dist/view/renderers/polygon/triangulator.js +3 -0
  532. package/dist/view/renderers/retained.d.ts +43 -0
  533. package/dist/view/renderers/retained.js +3 -0
  534. package/dist/view/renderers/stroke.d.ts +121 -0
  535. package/dist/view/renderers/stroke.js +621 -0
  536. package/dist/view/shaders/frame.d.ts +8 -0
  537. package/dist/view/shaders/frame.js +37 -0
  538. package/dist/view/shaders/helpers.d.ts +238 -0
  539. package/dist/view/shaders/helpers.js +611 -0
  540. package/dist/view/shaders/initializer.d.ts +27 -0
  541. package/dist/view/shaders/initializer.js +125 -0
  542. package/dist/view/shaders/projection.d.ts +123 -0
  543. package/dist/view/shaders/projection.js +299 -0
  544. package/dist/view/shaders/quad-grid.d.ts +77 -0
  545. package/dist/view/shaders/quad-grid.js +128 -0
  546. package/dist/view/shaders/quad.d.ts +189 -0
  547. package/dist/view/shaders/quad.js +582 -0
  548. package/dist/view/shaders/retained-origin.d.ts +50 -0
  549. package/dist/view/shaders/retained-origin.js +67 -0
  550. package/dist/view/shaders/terrain-shade.d.ts +23 -0
  551. package/dist/view/shaders/terrain-shade.js +93 -0
  552. package/dist/view/style-rule.d.ts +166 -0
  553. package/dist/view/style-rule.js +300 -0
  554. package/dist/view/terrain/anchor.d.ts +135 -0
  555. package/dist/view/terrain/anchor.js +226 -0
  556. package/dist/view/terrain/context.d.ts +132 -0
  557. package/dist/view/terrain/context.js +437 -0
  558. package/dist/view/terrain/dem-atlas.d.ts +97 -0
  559. package/dist/view/terrain/dem-atlas.js +534 -0
  560. package/dist/view/terrain/detect.d.ts +126 -0
  561. package/dist/view/terrain/detect.js +198 -0
  562. package/dist/view/terrain/drape/bin-store.d.ts +179 -0
  563. package/dist/view/terrain/drape/bin-store.js +529 -0
  564. package/dist/view/terrain/drape/binning.d.ts +259 -0
  565. package/dist/view/terrain/drape/binning.js +604 -0
  566. package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
  567. package/dist/view/terrain/drape/edge-constrain.js +175 -0
  568. package/dist/view/terrain/drape/geometry.d.ts +95 -0
  569. package/dist/view/terrain/drape/geometry.js +260 -0
  570. package/dist/view/terrain/drape/mesh.d.ts +50 -0
  571. package/dist/view/terrain/drape/mesh.js +86 -0
  572. package/dist/view/terrain/drape/pass.d.ts +122 -0
  573. package/dist/view/terrain/drape/pass.js +379 -0
  574. package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
  575. package/dist/view/terrain/drape/quad-glyphs.js +117 -0
  576. package/dist/view/terrain/drape/quad.d.ts +249 -0
  577. package/dist/view/terrain/drape/quad.js +835 -0
  578. package/dist/view/terrain/drape/renderer.d.ts +184 -0
  579. package/dist/view/terrain/drape/renderer.js +706 -0
  580. package/dist/view/terrain/drape/shared.d.ts +80 -0
  581. package/dist/view/terrain/drape/shared.js +173 -0
  582. package/dist/view/terrain/drape/stitch.d.ts +155 -0
  583. package/dist/view/terrain/drape/stitch.js +228 -0
  584. package/dist/view/terrain/ground.d.ts +72 -0
  585. package/dist/view/terrain/ground.js +151 -0
  586. package/dist/view/terrain/metrics.d.ts +180 -0
  587. package/dist/view/terrain/metrics.js +231 -0
  588. package/dist/view/terrain/occlusion.d.ts +11 -0
  589. package/dist/view/terrain/occlusion.js +129 -0
  590. package/dist/view/terrain/polygon.d.ts +86 -0
  591. package/dist/view/terrain/polygon.js +301 -0
  592. package/dist/view/terrain/shade.d.ts +48 -0
  593. package/dist/view/terrain/shade.js +45 -0
  594. package/dist/view/terrain/state.d.ts +99 -0
  595. package/dist/view/terrain/state.js +186 -0
  596. package/dist/view/terrain/tessellation.d.ts +265 -0
  597. package/dist/view/terrain/tessellation.js +924 -0
  598. package/dist/view/terrain/tiling.d.ts +56 -0
  599. package/dist/view/terrain/tiling.js +155 -0
  600. package/dist/view/terrain/upstream-terrain.d.ts +82 -0
  601. package/dist/view/terrain/upstream-terrain.js +116 -0
  602. package/dist/view/ui/auxiliary-handles.d.ts +151 -0
  603. package/dist/view/ui/auxiliary-handles.js +22 -0
  604. package/dist/view/ui/bounds.d.ts +53 -0
  605. package/dist/view/ui/bounds.js +149 -0
  606. package/dist/view/ui/box-selection.d.ts +1 -0
  607. package/dist/view/ui/box-selection.js +83 -0
  608. package/dist/view/ui/handle-test.d.ts +1 -0
  609. package/dist/view/ui/handle-test.js +437 -0
  610. package/dist/view/ui/handle-thinning.d.ts +122 -0
  611. package/dist/view/ui/handle-thinning.js +430 -0
  612. package/dist/view/ui/handles.d.ts +25 -0
  613. package/dist/view/ui/handles.js +673 -0
  614. package/dist/view/ui/helper.d.ts +19 -0
  615. package/dist/view/ui/helper.js +76 -0
  616. package/dist/view/ui/index.d.ts +15 -0
  617. package/dist/view/ui/index.js +15 -0
  618. package/dist/view/ui/selection-scope.d.ts +25 -0
  619. package/dist/view/ui/selection-scope.js +34 -0
  620. package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
  621. package/dist/view/ui/selection-ui/bounding-box.js +240 -0
  622. package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
  623. package/dist/view/ui/selection-ui/extension-registry.js +78 -0
  624. package/dist/view/ui/selection-ui/index.d.ts +12 -0
  625. package/dist/view/ui/selection-ui/index.js +12 -0
  626. package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
  627. package/dist/view/ui/selection-ui/renderer.js +227 -0
  628. package/dist/view/ui/selection-ui/types.d.ts +55 -0
  629. package/dist/view/ui/selection-ui/types.js +3 -0
  630. package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
  631. package/dist/view/ui/selection-ui-drawer.js +329 -0
  632. package/dist/view/ui/tentative.d.ts +1 -0
  633. package/dist/view/ui/tentative.js +320 -0
  634. package/dist/view/viewport.d.ts +119 -0
  635. package/dist/view/viewport.js +254 -0
  636. package/package.json +113 -0
@@ -0,0 +1,236 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Measurement
5
+ *
6
+ * The length is the sum of haversine distances, and the area is based on the spherical
7
+ * excess of a spherical polygon. The centroid and the representative point are computed
8
+ * on the lng/lat plane, assuming shapes of the scale of an edit.
9
+ */
10
+ import { boundingBox } from './bbox.js';
11
+ import { normalizeArea } from './boolean.js';
12
+ import { toMultiPolygonCoordinates } from './coords.js';
13
+ import { haversineDistanceMeters } from './distance.js';
14
+ import { pointInPolygon } from './predicates.js';
15
+ import { EARTH_RADIUS_METERS, toRadians } from './units.js';
16
+ /**
17
+ * Returns the geodesic length of a path in meters.
18
+ *
19
+ * The sum of the {@link haversineDistanceMeters} of each section. For the perimeter of a
20
+ * polygon pass its closed ring.
21
+ *
22
+ * @param path The vertices `[lng, lat]` in degrees
23
+ * @returns The length in meters. 0 for fewer than 2 positions. NaN when a position is not
24
+ * finite
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { geodesicLength } from '@sakuzu/maplibre-gl-draw/geometry';
29
+ *
30
+ * geodesicLength([[0, 0], [1, 0], [1, 1]]); // about 222,390 m
31
+ * ```
32
+ */
33
+ export function geodesicLength(path) {
34
+ let total = 0;
35
+ for (let i = 0; i < path.length - 1; i++) {
36
+ total += haversineDistanceMeters(path[i], path[i + 1]);
37
+ }
38
+ return total;
39
+ }
40
+ /**
41
+ * The spherical area of a ring (signed, square meters)
42
+ */
43
+ function sphericalRingArea(ring) {
44
+ if (ring.length < 3) {
45
+ return 0;
46
+ }
47
+ let total = 0;
48
+ const n = ring.length;
49
+ for (let i = 0; i < n; i++) {
50
+ const lower = ring[i];
51
+ const middle = ring[(i + 1) % n];
52
+ const upper = ring[(i + 2) % n];
53
+ total += (toRadians(upper[0]) - toRadians(lower[0])) * Math.sin(toRadians(middle[1]));
54
+ }
55
+ return (total * EARTH_RADIUS_METERS * EARTH_RADIUS_METERS) / 2;
56
+ }
57
+ /**
58
+ * Returns the area of a polygon on the sphere in square meters.
59
+ *
60
+ * The input is normalized with {@link normalizeArea} first, so self-intersections are
61
+ * resolved, a hole outside its outer ring is dropped, a hole larger than its outer ring
62
+ * empties the part, and rings that cannot bound an area are dropped. The holes of the
63
+ * normalized form lie inside their outer ring, so subtracting them never makes the result
64
+ * negative. For a MultiPolygon the sum of each part is returned. Ring orientation does not
65
+ * matter. The area is based on the spherical excess on a sphere of radius
66
+ * {@link EARTH_RADIUS_METERS}.
67
+ *
68
+ * @param polygon Polygon or MultiPolygon coordinates in degrees
69
+ * @returns The area in square meters. 0 when nothing with an area remains
70
+ * @throws {@link GeometryError} when the boolean operation engine fails even after the
71
+ * retry on the 1e-9 degree grid
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { sphericalArea } from '@sakuzu/maplibre-gl-draw/geometry';
76
+ *
77
+ * // A 1 x 1 degree square on the equator
78
+ * sphericalArea([[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]]); // about 1.236e10 m²
79
+ * ```
80
+ */
81
+ export function sphericalArea(polygon) {
82
+ let total = 0;
83
+ for (const part of normalizeArea(polygon)) {
84
+ for (let i = 0; i < part.length; i++) {
85
+ const ringArea = Math.abs(sphericalRingArea(part[i]));
86
+ total += i === 0 ? ringArea : -ringArea;
87
+ }
88
+ }
89
+ return total;
90
+ }
91
+ /**
92
+ * Returns the centroid of a ring (weighted by area) and its signed area
93
+ */
94
+ function ringCentroid(ring) {
95
+ if (ring.length < 3) {
96
+ return null;
97
+ }
98
+ let cx = 0;
99
+ let cy = 0;
100
+ let doubleArea = 0;
101
+ for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
102
+ const cross = ring[j][0] * ring[i][1] - ring[i][0] * ring[j][1];
103
+ doubleArea += cross;
104
+ cx += (ring[j][0] + ring[i][0]) * cross;
105
+ cy += (ring[j][1] + ring[i][1]) * cross;
106
+ }
107
+ if (doubleArea === 0) {
108
+ return null;
109
+ }
110
+ const area = doubleArea / 2;
111
+ return { centroid: [cx / (6 * area), cy / (6 * area)], area };
112
+ }
113
+ /**
114
+ * The mean coordinate of all the vertices (the fallback for a shape whose area is 0)
115
+ */
116
+ function verticesMean(polygon) {
117
+ let sumLng = 0;
118
+ let sumLat = 0;
119
+ let count = 0;
120
+ for (const part of toMultiPolygonCoordinates(polygon)) {
121
+ for (const ring of part) {
122
+ for (const [lng, lat] of ring) {
123
+ sumLng += lng;
124
+ sumLat += lat;
125
+ count++;
126
+ }
127
+ }
128
+ }
129
+ return count === 0 ? null : [sumLng / count, sumLat / count];
130
+ }
131
+ /**
132
+ * Returns the area-weighted centroid of a polygon.
133
+ *
134
+ * The area of the holes is subtracted, and the parts of a MultiPolygon are combined with
135
+ * their areas as the weights. The computation is on the lng/lat plane, an approximation
136
+ * meant for shapes of the scale of an edit. The centroid of a concave shape can fall
137
+ * outside it; use {@link pointOnSurface} for a point that is always inside.
138
+ *
139
+ * @param polygon Polygon or MultiPolygon coordinates in degrees
140
+ * @returns The centroid `[lng, lat]` in degrees. The mean of all the vertices when the area
141
+ * is 0. `null` when there is not a single position
142
+ */
143
+ export function centroid(polygon) {
144
+ let sumLng = 0;
145
+ let sumLat = 0;
146
+ let sumArea = 0;
147
+ for (const part of toMultiPolygonCoordinates(polygon)) {
148
+ for (let i = 0; i < part.length; i++) {
149
+ const result = ringCentroid(part[i]);
150
+ if (result === null) {
151
+ continue;
152
+ }
153
+ // Give the outer ring a positive weight and the inner rings a negative one
154
+ const weight = i === 0 ? Math.abs(result.area) : -Math.abs(result.area);
155
+ sumLng += result.centroid[0] * weight;
156
+ sumLat += result.centroid[1] * weight;
157
+ sumArea += weight;
158
+ }
159
+ }
160
+ if (sumArea === 0) {
161
+ return verticesMean(polygon);
162
+ }
163
+ return [sumLng / sumArea, sumLat / sumArea];
164
+ }
165
+ /**
166
+ * Returns, in ascending order, the longitudes of the intersections of the horizontal
167
+ * scanline at the given latitude with each ring
168
+ */
169
+ function scanlineCrossings(polygon, lat) {
170
+ const crossings = [];
171
+ for (const part of toMultiPolygonCoordinates(polygon)) {
172
+ for (const ring of part) {
173
+ for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
174
+ const [xi, yi] = ring[i];
175
+ const [xj, yj] = ring[j];
176
+ // Counting on a half-open interval avoids double-counting a vertex
177
+ if (yi > lat !== yj > lat) {
178
+ crossings.push(xi + ((lat - yi) / (yj - yi)) * (xj - xi));
179
+ }
180
+ }
181
+ }
182
+ }
183
+ return crossings.sort((a, b) => a - b);
184
+ }
185
+ /**
186
+ * Returns a representative point that lies inside a polygon, such as a label anchor.
187
+ *
188
+ * If the {@link centroid} is inside the polygon, it is returned. If it is outside (a
189
+ * concave shape, or a centroid in a hole), a horizontal scanline is drawn at the latitude of
190
+ * the centroid and the midpoint of the longest interior section is returned. For a
191
+ * degenerate shape the scanline does not cross, the center of the bounding box is returned.
192
+ *
193
+ * @param polygon Polygon or MultiPolygon coordinates in degrees
194
+ * @returns The point `[lng, lat]` in degrees. `null` when there is not a single position
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * import { centroid, pointOnSurface } from '@sakuzu/maplibre-gl-draw/geometry';
199
+ *
200
+ * // A U shape: the centroid falls in the gap between the arms
201
+ * const u: [number, number][][] = [
202
+ * [[0, 0], [3, 0], [3, 3], [2, 3], [2, 1], [1, 1], [1, 3], [0, 3], [0, 0]],
203
+ * ];
204
+ * centroid(u); // [1.5, 1.357...] (outside)
205
+ * pointOnSurface(u); // [0.5, 1.357...] (inside the left arm)
206
+ * ```
207
+ */
208
+ export function pointOnSurface(polygon) {
209
+ const center = centroid(polygon);
210
+ if (center === null) {
211
+ return null;
212
+ }
213
+ if (pointInPolygon(center, polygon)) {
214
+ return center;
215
+ }
216
+ const lat = center[1];
217
+ const crossings = scanlineCrossings(polygon, lat);
218
+ let bestStart = Number.NaN;
219
+ let bestWidth = -1;
220
+ // By the even-odd rule, the intervals formed by pairing the intersections two at a
221
+ // time in ascending order are the interior
222
+ for (let i = 0; i + 1 < crossings.length; i += 2) {
223
+ const width = crossings[i + 1] - crossings[i];
224
+ if (width > bestWidth) {
225
+ bestWidth = width;
226
+ bestStart = crossings[i];
227
+ }
228
+ }
229
+ if (bestWidth < 0) {
230
+ // A degenerate shape in which the scanline does not pass through the interior.
231
+ // Fall back to the center of the bbox
232
+ const box = boundingBox(polygon);
233
+ return box === null ? center : [(box[0] + box[2]) / 2, (box[1] + box[3]) / 2];
234
+ }
235
+ return [bestStart + bestWidth / 2, lat];
236
+ }
@@ -0,0 +1,62 @@
1
+ import type { AreaCoordinates, Coordinate } from './types.js';
2
+ /**
3
+ * Determines whether a point is inside a polygon, holes taken into account.
4
+ *
5
+ * The test is ray casting on the lng/lat plane; the result for a point exactly on the
6
+ * boundary is undefined. Ring orientation does not matter. No boolean operation is run, so
7
+ * it never throws.
8
+ *
9
+ * @param point The position `[lng, lat]` in degrees
10
+ * @param polygon Polygon or MultiPolygon coordinates in degrees
11
+ * @returns `true` when the point is inside an outer ring and inside none of its holes (in
12
+ * any part of a MultiPolygon). `false` for empty coordinates
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { pointInPolygon } from '@sakuzu/maplibre-gl-draw/geometry';
17
+ *
18
+ * const square: [number, number][][] = [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]];
19
+ * pointInPolygon([0.5, 0.5], square); // true
20
+ * pointInPolygon([2, 0.5], square); // false
21
+ * ```
22
+ */
23
+ export declare function pointInPolygon(point: Coordinate, polygon: AreaCoordinates): boolean;
24
+ /**
25
+ * Determines whether two polygons overlap with a positive area.
26
+ *
27
+ * A touch that shares only the boundary has no area, so it gives `false`. The bounding boxes
28
+ * are compared first, and the boolean operation runs only when they overlap.
29
+ *
30
+ * @param a Polygon or MultiPolygon coordinates in degrees
31
+ * @param b Polygon or MultiPolygon coordinates in degrees
32
+ * @returns `true` when the common part has an area. `false` when either input has no
33
+ * finite position
34
+ * @throws {@link GeometryError} when the boolean operation engine fails even after the
35
+ * retry on the 1e-9 degree grid
36
+ */
37
+ export declare function intersects(a: AreaCoordinates, b: AreaCoordinates): boolean;
38
+ /**
39
+ * Determines whether one polygon completely contains another.
40
+ *
41
+ * Sharing the boundary is allowed. The bounding boxes are compared first.
42
+ *
43
+ * @param outer The containing Polygon or MultiPolygon coordinates, in degrees
44
+ * @param inner The contained Polygon or MultiPolygon coordinates, in degrees
45
+ * @returns `true` when no part of `inner` lies outside `outer`. `false` when `inner` has no
46
+ * area
47
+ * @throws {@link GeometryError} when the boolean operation engine fails even after the
48
+ * retry on the 1e-9 degree grid
49
+ */
50
+ export declare function contains(outer: AreaCoordinates, inner: AreaCoordinates): boolean;
51
+ /**
52
+ * Determines whether one polygon lies completely inside another; {@link contains} with its
53
+ * arguments swapped.
54
+ *
55
+ * @param inner The contained Polygon or MultiPolygon coordinates, in degrees
56
+ * @param outer The containing Polygon or MultiPolygon coordinates, in degrees
57
+ * @returns `true` when no part of `inner` lies outside `outer`. `false` when `inner` has no
58
+ * area
59
+ * @throws {@link GeometryError} when the boolean operation engine fails even after the
60
+ * retry on the 1e-9 degree grid
61
+ */
62
+ export declare function within(inner: AreaCoordinates, outer: AreaCoordinates): boolean;
@@ -0,0 +1,132 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Predicates
5
+ *
6
+ * A test between polygons returns false early with the preliminary check on the bbox
7
+ * before proceeding to the topological test by polygon-clipping. Every test is
8
+ * area-based, so a touch that shares only the boundary is not regarded as an
9
+ * intersection.
10
+ */
11
+ import { bboxContains, bboxIntersects, boundingBox } from './bbox.js';
12
+ import { difference, intersection, normalizeArea } from './boolean.js';
13
+ import { toMultiPolygonCoordinates } from './coords.js';
14
+ /**
15
+ * Whether a point is inside a ring (ray casting; the treatment on the boundary is
16
+ * undefined)
17
+ */
18
+ function pointInRing(point, ring) {
19
+ const [x, y] = point;
20
+ let inside = false;
21
+ for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
22
+ const [xi, yi] = ring[i];
23
+ const [xj, yj] = ring[j];
24
+ // Whether the scanline y crosses the edge (counted on a half-open interval, which
25
+ // avoids double-counting a vertex)
26
+ if (yi > y !== yj > y) {
27
+ const t = (y - yi) / (yj - yi);
28
+ if (x < xi + t * (xj - xi)) {
29
+ inside = !inside;
30
+ }
31
+ }
32
+ }
33
+ return inside;
34
+ }
35
+ /**
36
+ * Determines whether a point is inside a polygon, holes taken into account.
37
+ *
38
+ * The test is ray casting on the lng/lat plane; the result for a point exactly on the
39
+ * boundary is undefined. Ring orientation does not matter. No boolean operation is run, so
40
+ * it never throws.
41
+ *
42
+ * @param point The position `[lng, lat]` in degrees
43
+ * @param polygon Polygon or MultiPolygon coordinates in degrees
44
+ * @returns `true` when the point is inside an outer ring and inside none of its holes (in
45
+ * any part of a MultiPolygon). `false` for empty coordinates
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { pointInPolygon } from '@sakuzu/maplibre-gl-draw/geometry';
50
+ *
51
+ * const square: [number, number][][] = [[[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]];
52
+ * pointInPolygon([0.5, 0.5], square); // true
53
+ * pointInPolygon([2, 0.5], square); // false
54
+ * ```
55
+ */
56
+ export function pointInPolygon(point, polygon) {
57
+ for (const part of toMultiPolygonCoordinates(polygon)) {
58
+ if (part.length === 0 || !pointInRing(point, part[0])) {
59
+ continue;
60
+ }
61
+ let inHole = false;
62
+ for (let i = 1; i < part.length; i++) {
63
+ if (pointInRing(point, part[i])) {
64
+ inHole = true;
65
+ break;
66
+ }
67
+ }
68
+ if (!inHole) {
69
+ return true;
70
+ }
71
+ }
72
+ return false;
73
+ }
74
+ /**
75
+ * Determines whether two polygons overlap with a positive area.
76
+ *
77
+ * A touch that shares only the boundary has no area, so it gives `false`. The bounding boxes
78
+ * are compared first, and the boolean operation runs only when they overlap.
79
+ *
80
+ * @param a Polygon or MultiPolygon coordinates in degrees
81
+ * @param b Polygon or MultiPolygon coordinates in degrees
82
+ * @returns `true` when the common part has an area. `false` when either input has no
83
+ * finite position
84
+ * @throws {@link GeometryError} when the boolean operation engine fails even after the
85
+ * retry on the 1e-9 degree grid
86
+ */
87
+ export function intersects(a, b) {
88
+ const boxA = boundingBox(a);
89
+ const boxB = boundingBox(b);
90
+ if (boxA === null || boxB === null || !bboxIntersects(boxA, boxB)) {
91
+ return false;
92
+ }
93
+ return intersection(a, b).length > 0;
94
+ }
95
+ /**
96
+ * Determines whether one polygon completely contains another.
97
+ *
98
+ * Sharing the boundary is allowed. The bounding boxes are compared first.
99
+ *
100
+ * @param outer The containing Polygon or MultiPolygon coordinates, in degrees
101
+ * @param inner The contained Polygon or MultiPolygon coordinates, in degrees
102
+ * @returns `true` when no part of `inner` lies outside `outer`. `false` when `inner` has no
103
+ * area
104
+ * @throws {@link GeometryError} when the boolean operation engine fails even after the
105
+ * retry on the 1e-9 degree grid
106
+ */
107
+ export function contains(outer, inner) {
108
+ const boxOuter = boundingBox(outer);
109
+ const boxInner = boundingBox(inner);
110
+ if (boxOuter === null || boxInner === null || !bboxContains(boxOuter, boxInner)) {
111
+ return false;
112
+ }
113
+ // When inner has no area, it is not subject to the test
114
+ if (normalizeArea(inner).length === 0) {
115
+ return false;
116
+ }
117
+ return difference(inner, outer).length === 0;
118
+ }
119
+ /**
120
+ * Determines whether one polygon lies completely inside another; {@link contains} with its
121
+ * arguments swapped.
122
+ *
123
+ * @param inner The contained Polygon or MultiPolygon coordinates, in degrees
124
+ * @param outer The containing Polygon or MultiPolygon coordinates, in degrees
125
+ * @returns `true` when no part of `inner` lies outside `outer`. `false` when `inner` has no
126
+ * area
127
+ * @throws {@link GeometryError} when the boolean operation engine fails even after the
128
+ * retry on the 1e-9 degree grid
129
+ */
130
+ export function within(inner, outer) {
131
+ return contains(outer, inner);
132
+ }
@@ -0,0 +1,74 @@
1
+ import type { Coordinate, MultiPolygonCoordinates, PolygonCoordinates, Ring } from './types.js';
2
+ /**
3
+ * Simplifies a coordinate sequence by the Douglas-Peucker algorithm.
4
+ *
5
+ * The tolerance is a distance on the lng/lat plane in degrees, not in meters: 0.00001
6
+ * degrees is about 1.1 m of latitude, and a degree of longitude shrinks with `cos(lat)`.
7
+ * The endpoints always remain. When the input is a closed ring, it is returned still
8
+ * closed. When the ring would collapse to fewer than 4 points it would lose its area, so
9
+ * the input is returned as it is. A tolerance that is not a positive number (0, a negative value or NaN) simplifies
10
+ * nothing and returns a copy of the input.
11
+ *
12
+ * @param path The vertices `[lng, lat]` in degrees
13
+ * @param toleranceDegrees The largest distance in degrees a dropped vertex may lie from the
14
+ * simplified line
15
+ * @returns The simplified vertices as a new array. A copy of the input for 2 positions or
16
+ * fewer, for a tolerance that is not positive, and for a ring that would collapse
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { simplify } from '@sakuzu/maplibre-gl-draw/geometry';
21
+ *
22
+ * simplify([[0, 0], [1, 0.00001], [2, 0], [3, 1]], 0.001); // [[0, 0], [2, 0], [3, 1]]
23
+ * ```
24
+ */
25
+ export declare function simplify(path: Coordinate[], toleranceDegrees: number): Coordinate[];
26
+ /**
27
+ * Returns the signed planar area of a ring in square degrees; counter-clockwise is
28
+ * positive.
29
+ *
30
+ * The shoelace formula on the lng/lat plane, meant for orientation tests. For an area in
31
+ * square meters use {@link sphericalArea}. The ring may be open or closed.
32
+ *
33
+ * @param ring The ring `[lng, lat][]` in degrees
34
+ * @returns The signed area in square degrees. 0 for fewer than 3 positions
35
+ */
36
+ export declare function signedRingArea(ring: Ring): number;
37
+ /**
38
+ * Determines whether a ring runs clockwise on the lng/lat plane.
39
+ *
40
+ * @param ring The ring `[lng, lat][]` in degrees
41
+ * @returns `true` when it is clockwise. `false` when it is counter-clockwise and for a
42
+ * degenerate ring whose area is 0
43
+ */
44
+ export declare function isRingClockwise(ring: Ring): boolean;
45
+ /**
46
+ * Returns a ring in the given orientation.
47
+ *
48
+ * A degenerate ring with area 0 counts as counter-clockwise.
49
+ *
50
+ * @param ring The ring `[lng, lat][]` in degrees
51
+ * @param clockwise `true` for clockwise and `false` for counter-clockwise
52
+ * @returns The input itself when it already has the orientation, otherwise a new reversed
53
+ * array
54
+ */
55
+ export declare function normalizeRingOrientation(ring: Ring, clockwise: boolean): Ring;
56
+ /**
57
+ * Orients the rings of a Polygon as GeoJSON (RFC 7946) recommends: the outer ring
58
+ * counter-clockwise and the holes clockwise.
59
+ *
60
+ * Only the orientation changes; self-intersections and degenerate rings are left as they
61
+ * are (use {@link normalizeArea} for those).
62
+ *
63
+ * @param polygon Polygon coordinates in degrees
64
+ * @returns New Polygon coordinates; rings already in the orientation are reused
65
+ */
66
+ export declare function normalizePolygonOrientation(polygon: PolygonCoordinates): PolygonCoordinates;
67
+ /**
68
+ * Orients the rings of every part of a MultiPolygon as
69
+ * {@link normalizePolygonOrientation} does.
70
+ *
71
+ * @param multiPolygon MultiPolygon coordinates in degrees
72
+ * @returns New MultiPolygon coordinates; rings already in the orientation are reused
73
+ */
74
+ export declare function normalizeMultiPolygonOrientation(multiPolygon: MultiPolygonCoordinates): MultiPolygonCoordinates;
@@ -0,0 +1,159 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Shaping
5
+ *
6
+ * Simplification by Douglas-Peucker, and the normalization of the ring orientations.
7
+ * The tolerance is given in degrees (a distance on the lng/lat plane).
8
+ */
9
+ import { isRingClosed } from './coords.js';
10
+ /**
11
+ * The square of the distance from a point to a segment (square degrees)
12
+ */
13
+ function squaredSegmentDistance(point, start, end) {
14
+ let x = start[0];
15
+ let y = start[1];
16
+ const dx = end[0] - x;
17
+ const dy = end[1] - y;
18
+ if (dx !== 0 || dy !== 0) {
19
+ const t = ((point[0] - x) * dx + (point[1] - y) * dy) / (dx * dx + dy * dy);
20
+ if (t > 1) {
21
+ x = end[0];
22
+ y = end[1];
23
+ }
24
+ else if (t > 0) {
25
+ x += dx * t;
26
+ y += dy * t;
27
+ }
28
+ }
29
+ const px = point[0] - x;
30
+ const py = point[1] - y;
31
+ return px * px + py * py;
32
+ }
33
+ /**
34
+ * The recursive body of Douglas-Peucker (marks the indices that are adopted)
35
+ */
36
+ function markKeep(path, first, last, squaredTolerance, keep) {
37
+ let maxSquared = squaredTolerance;
38
+ let index = -1;
39
+ for (let i = first + 1; i < last; i++) {
40
+ const squared = squaredSegmentDistance(path[i], path[first], path[last]);
41
+ if (squared > maxSquared) {
42
+ maxSquared = squared;
43
+ index = i;
44
+ }
45
+ }
46
+ if (index === -1) {
47
+ return;
48
+ }
49
+ keep[index] = true;
50
+ if (index - first > 1) {
51
+ markKeep(path, first, index, squaredTolerance, keep);
52
+ }
53
+ if (last - index > 1) {
54
+ markKeep(path, index, last, squaredTolerance, keep);
55
+ }
56
+ }
57
+ /**
58
+ * Simplifies a coordinate sequence by the Douglas-Peucker algorithm.
59
+ *
60
+ * The tolerance is a distance on the lng/lat plane in degrees, not in meters: 0.00001
61
+ * degrees is about 1.1 m of latitude, and a degree of longitude shrinks with `cos(lat)`.
62
+ * The endpoints always remain. When the input is a closed ring, it is returned still
63
+ * closed. When the ring would collapse to fewer than 4 points it would lose its area, so
64
+ * the input is returned as it is. A tolerance that is not a positive number (0, a negative value or NaN) simplifies
65
+ * nothing and returns a copy of the input.
66
+ *
67
+ * @param path The vertices `[lng, lat]` in degrees
68
+ * @param toleranceDegrees The largest distance in degrees a dropped vertex may lie from the
69
+ * simplified line
70
+ * @returns The simplified vertices as a new array. A copy of the input for 2 positions or
71
+ * fewer, for a tolerance that is not positive, and for a ring that would collapse
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { simplify } from '@sakuzu/maplibre-gl-draw/geometry';
76
+ *
77
+ * simplify([[0, 0], [1, 0.00001], [2, 0], [3, 1]], 0.001); // [[0, 0], [2, 0], [3, 1]]
78
+ * ```
79
+ */
80
+ export function simplify(path, toleranceDegrees) {
81
+ if (path.length <= 2 || !(toleranceDegrees > 0)) {
82
+ return [...path];
83
+ }
84
+ const keep = new Array(path.length).fill(false);
85
+ keep[0] = true;
86
+ keep[path.length - 1] = true;
87
+ markKeep(path, 0, path.length - 1, toleranceDegrees * toleranceDegrees, keep);
88
+ const result = path.filter((_, index) => keep[index]);
89
+ if (isRingClosed(path) && result.length < 4) {
90
+ return [...path];
91
+ }
92
+ return result;
93
+ }
94
+ /**
95
+ * Returns the signed planar area of a ring in square degrees; counter-clockwise is
96
+ * positive.
97
+ *
98
+ * The shoelace formula on the lng/lat plane, meant for orientation tests. For an area in
99
+ * square meters use {@link sphericalArea}. The ring may be open or closed.
100
+ *
101
+ * @param ring The ring `[lng, lat][]` in degrees
102
+ * @returns The signed area in square degrees. 0 for fewer than 3 positions
103
+ */
104
+ export function signedRingArea(ring) {
105
+ if (ring.length < 3) {
106
+ return 0;
107
+ }
108
+ let total = 0;
109
+ for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
110
+ total += (ring[j][0] + ring[i][0]) * (ring[j][1] - ring[i][1]);
111
+ }
112
+ return -total / 2;
113
+ }
114
+ /**
115
+ * Determines whether a ring runs clockwise on the lng/lat plane.
116
+ *
117
+ * @param ring The ring `[lng, lat][]` in degrees
118
+ * @returns `true` when it is clockwise. `false` when it is counter-clockwise and for a
119
+ * degenerate ring whose area is 0
120
+ */
121
+ export function isRingClockwise(ring) {
122
+ return signedRingArea(ring) < 0;
123
+ }
124
+ /**
125
+ * Returns a ring in the given orientation.
126
+ *
127
+ * A degenerate ring with area 0 counts as counter-clockwise.
128
+ *
129
+ * @param ring The ring `[lng, lat][]` in degrees
130
+ * @param clockwise `true` for clockwise and `false` for counter-clockwise
131
+ * @returns The input itself when it already has the orientation, otherwise a new reversed
132
+ * array
133
+ */
134
+ export function normalizeRingOrientation(ring, clockwise) {
135
+ return isRingClockwise(ring) === clockwise ? ring : [...ring].reverse();
136
+ }
137
+ /**
138
+ * Orients the rings of a Polygon as GeoJSON (RFC 7946) recommends: the outer ring
139
+ * counter-clockwise and the holes clockwise.
140
+ *
141
+ * Only the orientation changes; self-intersections and degenerate rings are left as they
142
+ * are (use {@link normalizeArea} for those).
143
+ *
144
+ * @param polygon Polygon coordinates in degrees
145
+ * @returns New Polygon coordinates; rings already in the orientation are reused
146
+ */
147
+ export function normalizePolygonOrientation(polygon) {
148
+ return polygon.map((ring, index) => normalizeRingOrientation(ring, index > 0));
149
+ }
150
+ /**
151
+ * Orients the rings of every part of a MultiPolygon as
152
+ * {@link normalizePolygonOrientation} does.
153
+ *
154
+ * @param multiPolygon MultiPolygon coordinates in degrees
155
+ * @returns New MultiPolygon coordinates; rings already in the orientation are reused
156
+ */
157
+ export function normalizeMultiPolygonOrientation(multiPolygon) {
158
+ return multiPolygon.map(normalizePolygonOrientation);
159
+ }