@sakuzu/maplibre-gl-draw 1.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/CHANGELOG.md +1109 -2
  2. package/README.ja.md +83 -50
  3. package/README.md +89 -53
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/dist/api/datasets.d.ts +263 -0
  6. package/dist/api/document.d.ts +66 -0
  7. package/dist/api/draw.d.ts +137 -0
  8. package/dist/api/draw.js +20 -0
  9. package/dist/api/drawing.d.ts +87 -0
  10. package/dist/api/errors.d.ts +35 -0
  11. package/dist/api/errors.js +35 -0
  12. package/dist/api/events.d.ts +316 -0
  13. package/dist/api/extension/context.d.ts +247 -0
  14. package/dist/api/extension/feature-type.d.ts +129 -0
  15. package/dist/api/extension/mode.d.ts +123 -0
  16. package/dist/api/extension/plugin.d.ts +51 -0
  17. package/dist/api/extension/plugin.js +3 -0
  18. package/dist/api/extension/provider.d.ts +119 -0
  19. package/dist/api/extension/provider.js +3 -0
  20. package/dist/api/extension/render.d.ts +176 -0
  21. package/dist/api/extension/render.js +3 -0
  22. package/dist/api/extension/store.d.ts +190 -0
  23. package/dist/api/extension/store.js +3 -0
  24. package/dist/api/extensions.d.ts +306 -0
  25. package/dist/api/extensions.js +3 -0
  26. package/dist/api/features.d.ts +188 -0
  27. package/dist/api/features.js +3 -0
  28. package/dist/api/groups.d.ts +111 -0
  29. package/dist/api/groups.js +3 -0
  30. package/dist/api/hidden.d.ts +45 -0
  31. package/dist/api/hidden.js +3 -0
  32. package/dist/api/impl/adapters.js +463 -0
  33. package/dist/api/impl/contexts.js +466 -0
  34. package/dist/api/impl/create-draw.js +124 -0
  35. package/dist/api/impl/datasets.js +405 -0
  36. package/dist/api/impl/destroy-guard.js +74 -0
  37. package/dist/api/impl/document.js +280 -0
  38. package/dist/api/impl/drawing.js +180 -0
  39. package/dist/api/impl/engine-context.d.ts +7 -0
  40. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  41. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  42. package/dist/api/impl/events.js +423 -0
  43. package/dist/api/impl/extension-host.js +364 -0
  44. package/dist/api/impl/extensions.js +229 -0
  45. package/dist/api/impl/features.js +445 -0
  46. package/dist/api/impl/geometry/apply.d.ts +32 -0
  47. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  48. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  49. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  50. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  51. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  52. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  53. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  54. package/dist/api/impl/geometry/types.js +3 -0
  55. package/dist/api/impl/groups.d.ts +3 -0
  56. package/dist/api/impl/groups.js +268 -0
  57. package/dist/api/impl/hidden.js +60 -0
  58. package/dist/api/impl/import-export/constants.d.ts +22 -0
  59. package/dist/api/impl/import-export/constants.js +24 -0
  60. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  61. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  62. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  63. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  64. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  66. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  68. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  69. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  70. package/dist/api/impl/import-export/image-import.js +73 -0
  71. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  72. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  73. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  74. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  75. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  76. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  77. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  78. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  79. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  80. package/dist/api/impl/import-export/style-validation.js +86 -0
  81. package/dist/api/impl/import-export/types.d.ts +52 -0
  82. package/dist/api/impl/import-export/types.js +3 -0
  83. package/dist/api/impl/input.js +180 -0
  84. package/dist/api/impl/layers.js +307 -0
  85. package/dist/api/impl/metadata.d.ts +1 -0
  86. package/dist/api/impl/metadata.js +22 -0
  87. package/dist/api/impl/options.d.ts +1 -0
  88. package/dist/api/impl/options.js +851 -0
  89. package/dist/api/impl/placement.d.ts +1 -0
  90. package/dist/api/impl/placement.js +138 -0
  91. package/dist/api/impl/render-context.d.ts +13 -0
  92. package/dist/api/impl/render-context.js +272 -0
  93. package/dist/api/impl/rows.d.ts +1 -0
  94. package/dist/api/impl/rows.js +46 -0
  95. package/dist/api/impl/selection.d.ts +1 -0
  96. package/dist/api/impl/selection.js +186 -0
  97. package/dist/api/impl/shared.d.ts +64 -0
  98. package/dist/api/impl/shared.js +178 -0
  99. package/dist/api/impl/validate-extension.d.ts +1 -0
  100. package/dist/api/impl/validate-extension.js +159 -0
  101. package/dist/api/layers.d.ts +130 -0
  102. package/dist/api/layers.js +3 -0
  103. package/dist/api/metadata.d.ts +18 -0
  104. package/dist/api/metadata.js +3 -0
  105. package/dist/api/model.d.ts +487 -0
  106. package/dist/api/model.js +47 -0
  107. package/dist/api/options.d.ts +466 -0
  108. package/dist/api/options.js +3 -0
  109. package/dist/api/selection.d.ts +94 -0
  110. package/dist/api/selection.js +3 -0
  111. package/dist/api/state.d.ts +155 -0
  112. package/dist/api/state.js +12 -0
  113. package/dist/{display → dataset}/chunk.d.ts +1 -1
  114. package/dist/{display → dataset}/chunk.js +4 -3
  115. package/dist/{display → dataset}/dataset.js +21 -21
  116. package/dist/dataset/interaction.d.ts +1 -0
  117. package/dist/{display → dataset}/interaction.js +18 -6
  118. package/dist/dataset/manager.d.ts +1 -0
  119. package/dist/dataset/provider.d.ts +1 -0
  120. package/dist/{display → dataset}/retained.d.ts +1 -1
  121. package/dist/{display → dataset}/retained.js +8 -7
  122. package/dist/dataset/source.d.ts +1 -0
  123. package/dist/{display → dataset}/source.js +17 -4
  124. package/dist/dataset/spatial.d.ts +1 -0
  125. package/dist/{display → dataset}/spatial.js +1 -1
  126. package/dist/dataset/style.d.ts +1 -0
  127. package/dist/{display → dataset}/style.js +1 -1
  128. package/dist/dataset/table-source.d.ts +1 -0
  129. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  130. package/dist/{display → dataset}/thinning.d.ts +0 -10
  131. package/dist/{display → dataset}/thinning.js +3 -2
  132. package/dist/dataset/triangulation.d.ts +1 -0
  133. package/dist/{display → dataset}/triangulation.js +0 -0
  134. package/dist/{display → dataset}/types.d.ts +84 -121
  135. package/dist/dataset/types.js +61 -0
  136. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  137. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  138. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  139. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  140. package/dist/dispatcher/hit-test/service.js +80 -16
  141. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  142. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  143. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  144. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  145. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  146. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  147. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  148. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  149. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  150. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  151. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  152. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  153. package/dist/dispatcher/input-router.js +154 -70
  154. package/dist/dispatcher/normalizer.js +25 -4
  155. package/dist/dispatcher/types.d.ts +6 -1
  156. package/dist/extension/feature-handler.d.ts +1 -182
  157. package/dist/extension/index.d.ts +4 -7
  158. package/dist/extension/renderers.d.ts +1 -208
  159. package/dist/geometry/angle.d.ts +0 -8
  160. package/dist/geometry/angle.js +0 -8
  161. package/dist/geometry/bbox.d.ts +4 -12
  162. package/dist/geometry/bbox.js +4 -12
  163. package/dist/geometry/boolean.d.ts +0 -51
  164. package/dist/geometry/boolean.js +0 -51
  165. package/dist/geometry/buffer.d.ts +0 -26
  166. package/dist/geometry/buffer.js +0 -26
  167. package/dist/geometry/circle.d.ts +0 -9
  168. package/dist/geometry/circle.js +0 -9
  169. package/dist/geometry/coords.d.ts +0 -16
  170. package/dist/geometry/coords.js +0 -16
  171. package/dist/geometry/distance.d.ts +0 -24
  172. package/dist/geometry/distance.js +0 -24
  173. package/dist/geometry/errors.d.ts +21 -36
  174. package/dist/geometry/errors.js +49 -29
  175. package/dist/geometry/geojson.d.ts +85 -0
  176. package/dist/geometry/geojson.js +173 -0
  177. package/dist/geometry/index.d.ts +38 -23
  178. package/dist/geometry/index.js +43 -31
  179. package/dist/geometry/measure.d.ts +0 -27
  180. package/dist/geometry/measure.js +0 -27
  181. package/dist/geometry/predicates.d.ts +0 -9
  182. package/dist/geometry/predicates.js +0 -9
  183. package/dist/geometry/public-bounds.d.ts +26 -0
  184. package/dist/geometry/public-bounds.js +30 -0
  185. package/dist/geometry/public-combine.d.ts +78 -0
  186. package/dist/geometry/public-combine.js +82 -0
  187. package/dist/geometry/public-create.d.ts +54 -0
  188. package/dist/geometry/public-create.js +70 -0
  189. package/dist/geometry/public-measure.d.ts +170 -0
  190. package/dist/geometry/public-measure.js +283 -0
  191. package/dist/geometry/public-predicates.d.ts +54 -0
  192. package/dist/geometry/public-predicates.js +144 -0
  193. package/dist/geometry/public-repair.d.ts +75 -0
  194. package/dist/geometry/public-repair.js +77 -0
  195. package/dist/geometry/simplify.d.ts +0 -7
  196. package/dist/geometry/simplify.js +0 -7
  197. package/dist/geometry/split.d.ts +0 -20
  198. package/dist/geometry/split.js +0 -20
  199. package/dist/geometry/units.d.ts +20 -12
  200. package/dist/geometry/units.js +20 -12
  201. package/dist/index.d.ts +66 -66
  202. package/dist/index.js +6 -18
  203. package/dist/messages.d.ts +7 -7
  204. package/dist/modes/draw/circle.js +83 -207
  205. package/dist/modes/draw/commit-layer.d.ts +5 -16
  206. package/dist/modes/draw/commit-layer.js +2 -13
  207. package/dist/modes/draw/freehand.js +108 -246
  208. package/dist/modes/draw/image.js +4 -2
  209. package/dist/modes/draw/index.d.ts +5 -5
  210. package/dist/modes/draw/index.js +5 -5
  211. package/dist/modes/draw/line.js +18 -354
  212. package/dist/modes/draw/point.js +29 -78
  213. package/dist/modes/draw/polygon.js +23 -368
  214. package/dist/modes/draw/trace-support.d.ts +43 -36
  215. package/dist/modes/draw/trace-support.js +95 -98
  216. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  217. package/dist/modes/draw/vertex-drawing.js +176 -0
  218. package/dist/modes/handler.d.ts +1 -285
  219. package/dist/modes/manager.d.ts +2 -2
  220. package/dist/modes/manager.js +3 -0
  221. package/dist/modes/select/box-selection.d.ts +3 -3
  222. package/dist/modes/select/box-selection.js +2 -1
  223. package/dist/modes/select/click-handler.d.ts +5 -5
  224. package/dist/modes/select/click-handler.js +22 -20
  225. package/dist/modes/select/cursor-handler.d.ts +2 -2
  226. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  227. package/dist/modes/select/drag/move.js +3 -3
  228. package/dist/modes/select/drag/operation.d.ts +3 -3
  229. package/dist/modes/select/drag/radius.js +5 -4
  230. package/dist/modes/select/drag/transform.d.ts +2 -2
  231. package/dist/modes/select/drag/transform.js +11 -5
  232. package/dist/modes/select/drag/vertex.d.ts +2 -2
  233. package/dist/modes/select/drag/vertex.js +13 -8
  234. package/dist/modes/select/drag-handler.js +44 -25
  235. package/dist/modes/select/mode.js +17 -17
  236. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  237. package/dist/modes/select/shortcut-handler.js +9 -7
  238. package/dist/operations/layer-operations.js +29 -168
  239. package/dist/operations/resize.d.ts +2 -2
  240. package/dist/operations/resize.js +5 -5
  241. package/dist/operations/rotate.js +5 -5
  242. package/dist/operations/selection-operations.d.ts +16 -1
  243. package/dist/operations/selection-operations.js +28 -13
  244. package/dist/operations/shared-vertex.js +4 -2
  245. package/dist/operations/trace-graph.d.ts +0 -18
  246. package/dist/operations/trace-graph.js +0 -18
  247. package/dist/operations/vertex.js +36 -35
  248. package/dist/shared/color.d.ts +1 -0
  249. package/dist/shared/color.js +245 -0
  250. package/dist/shared/config/constants.d.ts +1 -54
  251. package/dist/shared/config/constants.js +1 -58
  252. package/dist/shared/config/feature-style.d.ts +16 -13
  253. package/dist/shared/config/feature-style.js +9 -0
  254. package/dist/shared/config/rendering.d.ts +3 -3
  255. package/dist/shared/config/selection-highlight.d.ts +0 -15
  256. package/dist/shared/config/selection-highlight.js +4 -7
  257. package/dist/shared/config/selection.d.ts +2 -32
  258. package/dist/shared/config/selection.js +0 -18
  259. package/dist/shared/config/topology.d.ts +2 -2
  260. package/dist/shared/config/trace.d.ts +4 -4
  261. package/dist/shared/math/angle.d.ts +1 -1
  262. package/dist/shared/math/angle.js +1 -1
  263. package/dist/shared/math/circle.d.ts +1 -1
  264. package/dist/shared/math/circle.js +1 -1
  265. package/dist/shared/math/distance.d.ts +2 -1
  266. package/dist/shared/math/distance.js +3 -2
  267. package/dist/shared/math/index.d.ts +1 -1
  268. package/dist/shared/math/index.js +1 -1
  269. package/dist/shared/math/transform.d.ts +23 -0
  270. package/dist/shared/math/transform.js +47 -28
  271. package/dist/shared/properties.d.ts +18 -0
  272. package/dist/shared/properties.js +129 -0
  273. package/dist/shared/types/events.d.ts +15 -7
  274. package/dist/shared/types/model.d.ts +109 -159
  275. package/dist/shared/types/style.d.ts +1 -1
  276. package/dist/shared/utils/color.d.ts +2 -36
  277. package/dist/shared/utils/color.js +13 -70
  278. package/dist/shared/utils/coordinates.d.ts +30 -4
  279. package/dist/shared/utils/coordinates.js +56 -10
  280. package/dist/shared/utils/event-emitter.d.ts +1 -262
  281. package/dist/shared/utils/event-emitter.js +4 -3
  282. package/dist/shared/utils/feature-bbox.js +8 -7
  283. package/dist/shared/utils/feature-segments.js +5 -4
  284. package/dist/shared/utils/image.d.ts +0 -4
  285. package/dist/shared/utils/image.js +0 -6
  286. package/dist/shared/utils/name-generator.d.ts +14 -20
  287. package/dist/shared/utils/name-generator.js +20 -3
  288. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  289. package/dist/shared/utils/pixel-ratio.js +13 -4
  290. package/dist/shared/utils/property.d.ts +7 -50
  291. package/dist/shared/utils/property.js +22 -87
  292. package/dist/snapping/custom-targets.js +21 -4
  293. package/dist/snapping/indicator.js +20 -11
  294. package/dist/snapping/providers/display.d.ts +6 -1
  295. package/dist/snapping/providers/display.js +2 -1
  296. package/dist/snapping/providers/guide.d.ts +3 -43
  297. package/dist/snapping/providers/guide.js +1 -44
  298. package/dist/snapping/providers/intersection.js +1 -1
  299. package/dist/snapping/providers/store.js +3 -3
  300. package/dist/snapping/service.js +18 -7
  301. package/dist/snapping/types.d.ts +9 -35
  302. package/dist/store/draw-store.js +233 -142
  303. package/dist/store/local-visibility.d.ts +11 -6
  304. package/dist/store/local-visibility.js +38 -7
  305. package/dist/store/lock.d.ts +0 -6
  306. package/dist/store/lock.js +0 -6
  307. package/dist/store/memory/change-bus.d.ts +3 -3
  308. package/dist/store/memory/change-bus.js +12 -0
  309. package/dist/store/memory/file-store.d.ts +2 -2
  310. package/dist/store/memory/ui-state.d.ts +1 -51
  311. package/dist/store/memory/ui-state.js +122 -134
  312. package/dist/store/memory.d.ts +1 -8
  313. package/dist/store/memory.js +249 -45
  314. package/dist/store/ordering.d.ts +9 -0
  315. package/dist/store/ordering.js +17 -0
  316. package/dist/store/spatial/spatial-index.d.ts +1 -1
  317. package/dist/store/spatial/spatial-index.js +1 -1
  318. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  319. package/dist/store/spatial/store-spatial-index.js +9 -3
  320. package/dist/store/store.d.ts +66 -107
  321. package/dist/store/types.d.ts +1 -1
  322. package/dist/store/writable-layer.d.ts +1 -1
  323. package/dist/store/writable-layer.js +2 -2
  324. package/dist/table/builder.d.ts +83 -0
  325. package/dist/table/builder.js +381 -0
  326. package/dist/table/index.d.ts +37 -0
  327. package/dist/table/index.js +5 -0
  328. package/dist/table/packed-rtree.d.ts +1 -0
  329. package/dist/{display → table}/packed-rtree.js +1 -1
  330. package/dist/table/partition.d.ts +1 -0
  331. package/dist/{display → table}/partition.js +3 -3
  332. package/dist/table/prepare.d.ts +44 -0
  333. package/dist/table/prepare.js +136 -0
  334. package/dist/table/table.d.ts +1 -0
  335. package/dist/{display/columnar → table}/table.js +29 -25
  336. package/dist/{display/columnar → table}/types.d.ts +68 -72
  337. package/dist/table/types.js +3 -0
  338. package/dist/view/coordinator.js +4 -3
  339. package/dist/view/feature-companion.d.ts +13 -7
  340. package/dist/view/feature-companion.js +11 -3
  341. package/dist/view/globe-subdivision.js +3 -3
  342. package/dist/view/layer/attach.d.ts +12 -6
  343. package/dist/view/layer/attach.js +86 -10
  344. package/dist/view/layer/custom-layer.js +40 -11
  345. package/dist/view/layer/display-list.js +2 -1
  346. package/dist/view/layer/drape-planner.d.ts +2 -2
  347. package/dist/view/layer/frame-render.d.ts +3 -3
  348. package/dist/view/layer/frame-render.js +7 -2
  349. package/dist/view/layer/frame-state.d.ts +6 -6
  350. package/dist/view/layer/index.d.ts +2 -2
  351. package/dist/view/layer/index.js +1 -1
  352. package/dist/view/layer/render.d.ts +4 -4
  353. package/dist/view/layer/render.js +3 -8
  354. package/dist/view/layer/renderers.d.ts +2 -2
  355. package/dist/view/layer/renderers.js +1 -1
  356. package/dist/view/layer/slot-manager.d.ts +2 -2
  357. package/dist/view/layer/slot-manager.js +4 -4
  358. package/dist/view/layer/slots.d.ts +2 -2
  359. package/dist/view/layer/slots.js +1 -1
  360. package/dist/view/layer/store-retained-bbox.js +3 -2
  361. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  362. package/dist/view/layer/store-retained-classify.js +19 -7
  363. package/dist/view/layer/store-retained-collect.js +8 -7
  364. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  365. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  366. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  367. package/dist/view/layer/store-retained-immediate.js +3 -8
  368. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  369. package/dist/view/layer/store-retained.d.ts +2 -2
  370. package/dist/view/layer/store-retained.js +1 -1
  371. package/dist/view/renderers/batch-manager.js +8 -7
  372. package/dist/view/renderers/drawer.js +21 -15
  373. package/dist/view/renderers/image.js +13 -39
  374. package/dist/view/renderers/line/line-types.d.ts +3 -3
  375. package/dist/view/renderers/line/sdf-line.js +3 -1
  376. package/dist/view/renderers/point/billboard-depth.js +1 -1
  377. package/dist/view/renderers/point/point-instance.js +1 -1
  378. package/dist/view/renderers/point/point-shape.js +2 -2
  379. package/dist/view/renderers/point/point-style.js +48 -4
  380. package/dist/view/renderers/polygon/batch.js +1 -2
  381. package/dist/view/renderers/polygon/fill.js +3 -1
  382. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  383. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  384. package/dist/view/renderers/stroke.js +3 -1
  385. package/dist/view/shaders/helpers.d.ts +2 -42
  386. package/dist/view/shaders/helpers.js +0 -6
  387. package/dist/view/shaders/projection.d.ts +15 -7
  388. package/dist/view/shaders/projection.js +23 -6
  389. package/dist/view/shaders/quad.d.ts +16 -12
  390. package/dist/view/shaders/quad.js +34 -13
  391. package/dist/view/style-rule.d.ts +5 -42
  392. package/dist/view/style-rule.js +20 -44
  393. package/dist/view/terrain/binding.d.ts +1 -0
  394. package/dist/view/terrain/binding.js +29 -0
  395. package/dist/view/terrain/context.d.ts +3 -4
  396. package/dist/view/terrain/context.js +4 -5
  397. package/dist/view/terrain/drape/geometry.js +1 -1
  398. package/dist/view/terrain/drape/pass.d.ts +1 -1
  399. package/dist/view/terrain/drape/pass.js +8 -7
  400. package/dist/view/terrain/polygon.d.ts +9 -5
  401. package/dist/view/terrain/polygon.js +16 -2
  402. package/dist/view/terrain/state.d.ts +1 -1
  403. package/dist/view/terrain/state.js +1 -1
  404. package/dist/view/terrain/tessellation.d.ts +2 -2
  405. package/dist/view/terrain/tessellation.js +1 -1
  406. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  407. package/dist/view/ui/bounds.js +8 -12
  408. package/dist/view/ui/handle-test.js +2 -2
  409. package/dist/view/ui/handle-thinning.js +17 -17
  410. package/dist/view/ui/handles.js +21 -13
  411. package/dist/view/ui/helper.d.ts +1 -1
  412. package/dist/view/ui/helper.js +1 -1
  413. package/dist/view/ui/index.d.ts +1 -1
  414. package/dist/view/ui/selection-scope.js +4 -2
  415. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  416. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  417. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  418. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  419. package/dist/view/ui/selection-ui/index.js +1 -1
  420. package/dist/view/ui/selection-ui/renderer.js +15 -38
  421. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  422. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  423. package/dist/view/ui/selection-ui-drawer.js +63 -2
  424. package/dist/view/ui/tentative.js +1 -1
  425. package/dist/webgl/index.d.ts +65 -0
  426. package/dist/webgl/index.js +62 -0
  427. package/package.json +38 -15
  428. package/dist/api/api.d.ts +0 -1259
  429. package/dist/api/api.js +0 -86
  430. package/dist/api/context.d.ts +0 -173
  431. package/dist/api/display-api.js +0 -23
  432. package/dist/api/event-api.d.ts +0 -13
  433. package/dist/api/event-api.js +0 -17
  434. package/dist/api/extension-api.d.ts +0 -46
  435. package/dist/api/extension-api.js +0 -85
  436. package/dist/api/feature-api.d.ts +0 -11
  437. package/dist/api/feature-api.js +0 -101
  438. package/dist/api/geometry/apply.d.ts +0 -51
  439. package/dist/api/geometry/boolean.d.ts +0 -28
  440. package/dist/api/geometry/boolean.js +0 -65
  441. package/dist/api/geometry/types.d.ts +0 -31
  442. package/dist/api/geometry-operations.d.ts +0 -162
  443. package/dist/api/geometry-operations.js +0 -94
  444. package/dist/api/group-api.d.ts +0 -10
  445. package/dist/api/group-api.js +0 -78
  446. package/dist/api/import-export/constants.d.ts +0 -29
  447. package/dist/api/import-export/constants.js +0 -40
  448. package/dist/api/import-export/file-name.d.ts +0 -10
  449. package/dist/api/import-export/file-name.js +0 -20
  450. package/dist/api/import-export/geojson-export.d.ts +0 -19
  451. package/dist/api/import-export/image-import.d.ts +0 -12
  452. package/dist/api/import-export/image-import.js +0 -53
  453. package/dist/api/import-export/index.d.ts +0 -9
  454. package/dist/api/import-export/index.js +0 -107
  455. package/dist/api/import-export/native-format.d.ts +0 -15
  456. package/dist/api/import-export/style-validation.d.ts +0 -27
  457. package/dist/api/import-export/style-validation.js +0 -49
  458. package/dist/api/import-export/types.d.ts +0 -26
  459. package/dist/api/index.d.ts +0 -15
  460. package/dist/api/index.js +0 -3
  461. package/dist/api/input-api.d.ts +0 -158
  462. package/dist/api/input-api.js +0 -144
  463. package/dist/api/instance-api.d.ts +0 -38
  464. package/dist/api/instance-api.js +0 -136
  465. package/dist/api/layer-api.d.ts +0 -12
  466. package/dist/api/layer-api.js +0 -62
  467. package/dist/api/selection-api.d.ts +0 -7
  468. package/dist/api/selection-api.js +0 -78
  469. package/dist/api/snapping-api.d.ts +0 -125
  470. package/dist/api/snapping-api.js +0 -50
  471. package/dist/api/topology-api.d.ts +0 -30
  472. package/dist/api/topology-api.js +0 -16
  473. package/dist/api/tracing-api.d.ts +0 -31
  474. package/dist/api/tracing-api.js +0 -16
  475. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  476. package/dist/dispatcher/hit-test/index.js +0 -9
  477. package/dist/dispatcher/index.d.ts +0 -15
  478. package/dist/dispatcher/index.js +0 -3
  479. package/dist/display/columnar/index.d.ts +0 -12
  480. package/dist/display/columnar/index.js +0 -13
  481. package/dist/display/columnar/prepare.d.ts +0 -42
  482. package/dist/display/columnar/prepare.js +0 -116
  483. package/dist/display/index.d.ts +0 -13
  484. package/dist/display/types.js +0 -43
  485. package/dist/maplibre-gl-draw.d.ts +0 -47
  486. package/dist/modes/cursor.js +0 -72
  487. package/dist/modes/index.d.ts +0 -7
  488. package/dist/operations/index.d.ts +0 -9
  489. package/dist/operations/index.js +0 -3
  490. package/dist/plugins/index.d.ts +0 -10
  491. package/dist/plugins/mutation-hooks.d.ts +0 -28
  492. package/dist/plugins/mutation-hooks.js +0 -84
  493. package/dist/plugins/plugin-context.js +0 -367
  494. package/dist/plugins/plugin-manager.d.ts +0 -103
  495. package/dist/plugins/plugin-manager.js +0 -316
  496. package/dist/plugins/plugin.d.ts +0 -529
  497. package/dist/shared/config/index.d.ts +0 -17
  498. package/dist/shared/config/index.js +0 -8
  499. package/dist/shared/utils/index.d.ts +0 -15
  500. package/dist/shared/utils/index.js +0 -24
  501. package/dist/snapping/index.d.ts +0 -14
  502. package/dist/snapping/index.js +0 -4
  503. package/dist/store/change-merger.js +0 -102
  504. package/dist/store/event-bridge.js +0 -161
  505. package/dist/store/index.d.ts +0 -12
  506. package/dist/store/index.js +0 -4
  507. package/dist/view/index.d.ts +0 -47
  508. package/dist/view/index.js +0 -20
  509. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  510. /package/dist/api/{import-export/types.js → document.js} +0 -0
  511. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  512. /package/dist/{display/index.js → api/events.js} +0 -0
  513. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  514. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  515. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  516. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  517. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  518. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  519. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  520. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  521. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  522. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  523. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  524. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  525. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  526. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  527. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  528. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  529. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  532. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  533. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  534. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  535. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  536. /package/dist/{display → dataset}/chunk-set.js +0 -0
  537. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  538. /package/dist/{display → dataset}/manager.js +0 -0
  539. /package/dist/{display → dataset}/provider.js +0 -0
  540. /package/dist/{display → dataset}/selection.d.ts +0 -0
  541. /package/dist/{display → dataset}/selection.js +0 -0
@@ -0,0 +1,851 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * `draw.options` and the options of `createDraw`: their checks, their translation into the
5
+ * configuration of the engine, and their application while the instance runs
6
+ *
7
+ * The options are kept as they were given, merged patch by patch. Each change is translated
8
+ * again from the whole of them into the configuration of the engine (`src/shared/config/`),
9
+ * which the renderers, the modes and the services read in place.
10
+ */
11
+ import { MESSAGES_EN, resolveMessages } from '../../messages.js';
12
+ import { formatColor, isColor, toColor } from '../../shared/color.js';
13
+ import { DEFAULT_FEATURE_STYLE_CONFIG } from '../../shared/config/feature-style.js';
14
+ import { DEFAULT_BOX_SELECTION_STYLE_CONFIG } from '../../shared/config/rendering.js';
15
+ import { DEFAULT_SELECTION_CONFIG } from '../../shared/config/selection.js';
16
+ import { DrawStore } from '../../store/draw-store.js';
17
+ import { describeStyleProblem } from './import-export/style-validation.js';
18
+ import { invalidInput, isRecord, onlyKeys } from './shared.js';
19
+ /** The options that can only be given when the instance is created */
20
+ const CREATION_KEYS = ['defaultMode', 'store', 'initDefaultLayer'];
21
+ /** The options that change while the instance runs */
22
+ const RUNTIME_KEYS = [
23
+ 'messages',
24
+ 'autoName',
25
+ 'style',
26
+ 'previewStyle',
27
+ 'selectionStyle',
28
+ 'scaleWithZoom',
29
+ 'snapping',
30
+ 'tracing',
31
+ 'topology',
32
+ 'clickTolerance',
33
+ 'dragThreshold',
34
+ 'rendering',
35
+ 'isExternalEntry',
36
+ ];
37
+ /** Runs a check on each key of the object that is given */
38
+ function checkFields(value, what, checks) {
39
+ onlyKeys(value, Object.keys(checks), what);
40
+ for (const [key, check] of Object.entries(checks)) {
41
+ if (value[key] !== undefined)
42
+ check(value[key], `${what}.${key}`);
43
+ }
44
+ }
45
+ const bool = (value, what) => {
46
+ if (typeof value !== 'boolean')
47
+ throw invalidInput(`${what} must be a boolean`);
48
+ };
49
+ const string = (value, what) => {
50
+ if (typeof value !== 'string')
51
+ throw invalidInput(`${what} must be a string`);
52
+ };
53
+ const func = (value, what) => {
54
+ if (typeof value !== 'function')
55
+ throw invalidInput(`${what} must be a function`);
56
+ };
57
+ const nonNegative = (value, what) => {
58
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
59
+ throw invalidInput(`${what} must be a number from 0`);
60
+ }
61
+ };
62
+ const positive = (value, what) => {
63
+ if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
64
+ throw invalidInput(`${what} must be a number above 0`);
65
+ }
66
+ };
67
+ const opacity = (value, what) => {
68
+ if (typeof value !== 'number' || !Number.isFinite(value) || value < 0 || value > 1) {
69
+ throw invalidInput(`${what} must be a number from 0 to 1`);
70
+ }
71
+ };
72
+ const color = (value, what) => {
73
+ if (!isColor(value))
74
+ throw invalidInput(`${what} must be a CSS color`);
75
+ };
76
+ const oneOf = (...values) => (value, what) => {
77
+ if (typeof value !== 'string' || !values.includes(value)) {
78
+ throw invalidInput(`${what} must be one of ${values.join(', ')}`);
79
+ }
80
+ };
81
+ const record = (checks) => (value, what) => {
82
+ if (!isRecord(value))
83
+ throw invalidInput(`${what} must be an object`);
84
+ checkFields(value, what, checks);
85
+ };
86
+ const featureStyle = (value, what) => {
87
+ const problem = describeStyleProblem(value);
88
+ if (problem)
89
+ throw invalidInput(`${what} is ${problem}`);
90
+ };
91
+ const numbers = (value, what) => {
92
+ if (!Array.isArray(value) || value.some((n) => typeof n !== 'number' || !Number.isFinite(n))) {
93
+ throw invalidInput(`${what} must be an array of numbers`);
94
+ }
95
+ };
96
+ const LINE_STYLE = oneOf('solid', 'dashed', 'dotted');
97
+ const STROKE = record({
98
+ width: nonNegative,
99
+ color,
100
+ opacity,
101
+ lineStyle: LINE_STYLE,
102
+ dashArray: numbers,
103
+ });
104
+ const POINT = record({
105
+ shape: oneOf('circle', 'square', 'triangle', 'star', 'icon'),
106
+ size: nonNegative,
107
+ fillColor: color,
108
+ fillOpacity: opacity,
109
+ strokeColor: color,
110
+ strokeWidth: nonNegative,
111
+ strokeOpacity: opacity,
112
+ iconId: string,
113
+ });
114
+ const MARK = record({
115
+ shape: oneOf('circle', 'square', 'triangle', 'star'),
116
+ size: nonNegative,
117
+ fillColor: color,
118
+ fillOpacity: opacity,
119
+ strokeColor: color,
120
+ strokeWidth: nonNegative,
121
+ strokeOpacity: opacity,
122
+ });
123
+ const SELECTION_STYLE_CHECKS = {
124
+ boundingBox: record({ stroke: STROKE, margin: nonNegative }),
125
+ resizeHandle: record({ point: POINT }),
126
+ rotateHandle: record({ point: POINT, distance: nonNegative, connector: STROKE }),
127
+ vertexHandle: record({ point: POINT, selected: POINT, followed: POINT }),
128
+ midpointHandle: record({ point: POINT }),
129
+ radiusHandle: record({ point: POINT }),
130
+ centerMarker: record({ point: POINT }),
131
+ radiusLine: record({ stroke: STROKE }),
132
+ boxSelection: record({
133
+ fillColor: color,
134
+ fillOpacity: opacity,
135
+ strokeColor: color,
136
+ strokeWidth: nonNegative,
137
+ }),
138
+ };
139
+ const RUNTIME_CHECKS = {
140
+ messages(value, what) {
141
+ if (!isRecord(value))
142
+ throw invalidInput(`${what} must be an object`);
143
+ onlyKeys(value, Object.keys(MESSAGES_EN), what);
144
+ for (const [key, entry] of Object.entries(value)) {
145
+ const expected = typeof MESSAGES_EN[key];
146
+ if (entry !== undefined && typeof entry !== expected) {
147
+ throw invalidInput(`${what}.${key} must be a ${expected}`);
148
+ }
149
+ }
150
+ },
151
+ autoName(value, what) {
152
+ if (value === false)
153
+ return;
154
+ if (!isRecord(value))
155
+ throw invalidInput(`${what} must be false or an object`);
156
+ checkFields(value, what, {
157
+ typeNames(names, where) {
158
+ if (!isRecord(names))
159
+ throw invalidInput(`${where} must be an object`);
160
+ for (const [key, name] of Object.entries(names)) {
161
+ if (name !== undefined)
162
+ string(name, `${where}.${key}`);
163
+ }
164
+ },
165
+ formatter: func,
166
+ });
167
+ },
168
+ style: record({
169
+ point: featureStyle,
170
+ line: featureStyle,
171
+ polygon: featureStyle,
172
+ circle: featureStyle,
173
+ image: featureStyle,
174
+ }),
175
+ previewStyle: featureStyle,
176
+ selectionStyle: record(SELECTION_STYLE_CHECKS),
177
+ scaleWithZoom: bool,
178
+ snapping: record({
179
+ enabled: bool,
180
+ tolerancePx: nonNegative,
181
+ disableKey: oneOf('alt', 'shift', 'ctrl', 'meta', 'none'),
182
+ kinds: record({ vertex: bool, edge: bool, intersection: bool, guide: bool }),
183
+ datasets: bool,
184
+ guideStepDegrees: positive,
185
+ indicator: record({ vertex: MARK, edge: MARK, intersection: MARK, guide: MARK }),
186
+ guideLine: STROKE,
187
+ }),
188
+ tracing: record({ enabled: bool }),
189
+ topology: record({ sharedVertexDrag: bool }),
190
+ clickTolerance: nonNegative,
191
+ dragThreshold: nonNegative,
192
+ rendering: record({
193
+ renderScale: positive,
194
+ pixelRatio: positive,
195
+ cacheGeometry: bool,
196
+ timeSlicing: bool,
197
+ }),
198
+ isExternalEntry: func,
199
+ };
200
+ /** The members of the public Store the instance calls; `abortIntermediateUpdates` is optional */
201
+ const STORE_METHODS = [
202
+ 'getFeature',
203
+ 'listFeatures',
204
+ 'listFeaturesInOrder',
205
+ 'getLayer',
206
+ 'listLayers',
207
+ 'getLayerOrder',
208
+ 'getGroup',
209
+ 'listGroups',
210
+ 'getFile',
211
+ 'listFiles',
212
+ 'getMetadata',
213
+ 'getSelection',
214
+ 'getEditingIds',
215
+ 'getVertexSelection',
216
+ 'getMode',
217
+ 'isReadOnly',
218
+ 'isInteractionLocked',
219
+ 'isHidden',
220
+ 'listHidden',
221
+ 'subscribe',
222
+ 'transact',
223
+ 'createFeature',
224
+ 'updateFeature',
225
+ 'deleteFeature',
226
+ 'createLayer',
227
+ 'updateLayer',
228
+ 'deleteLayer',
229
+ 'setLayerOrder',
230
+ 'reorderInLayer',
231
+ 'reorderInGroup',
232
+ 'createGroup',
233
+ 'updateGroup',
234
+ 'deleteGroup',
235
+ 'createFile',
236
+ 'deleteFile',
237
+ 'setMetadata',
238
+ 'setSelection',
239
+ 'startEditing',
240
+ 'endEditing',
241
+ 'setSelectedVertices',
242
+ 'setMode',
243
+ 'setReadOnly',
244
+ 'setInteractionLock',
245
+ 'setLocallyHidden',
246
+ ];
247
+ /**
248
+ * Checks the options of `createDraw`
249
+ *
250
+ * @throws `DrawError` with the code `invalid-input` for an unknown option or a value of the
251
+ * wrong type
252
+ * @internal
253
+ */
254
+ export function checkDrawOptions(options) {
255
+ if (!isRecord(options))
256
+ throw invalidInput('The options must be an object');
257
+ checkFields(options, 'options', {
258
+ ...RUNTIME_CHECKS,
259
+ defaultMode: string,
260
+ initDefaultLayer: bool,
261
+ store(value, what) {
262
+ if (!isRecord(value) && !(value instanceof DrawStore)) {
263
+ throw invalidInput(`${what} must be a Store`);
264
+ }
265
+ const store = value;
266
+ for (const method of STORE_METHODS) {
267
+ if (typeof store[method] !== 'function') {
268
+ throw invalidInput(`${what} must be a Store: ${method} is missing`, { member: method });
269
+ }
270
+ }
271
+ },
272
+ });
273
+ }
274
+ /**
275
+ * Checks a patch of `draw.options.update`
276
+ *
277
+ * @internal
278
+ */
279
+ function checkPatch(patch) {
280
+ if (!isRecord(patch))
281
+ throw invalidInput('The options must be an object');
282
+ for (const key of CREATION_KEYS) {
283
+ if (key in patch)
284
+ throw invalidInput(`${key} can only be given when the instance is created`);
285
+ }
286
+ checkFields(patch, 'options', RUNTIME_CHECKS);
287
+ }
288
+ // ============================================================================
289
+ // Merging
290
+ // ============================================================================
291
+ /**
292
+ * The options with a patch merged in: plain objects are merged key by key, every other value
293
+ * (a function, an array, `false`) replaces the one before, and a key given as `undefined`
294
+ * keeps it
295
+ *
296
+ * @internal
297
+ */
298
+ export function mergeOptions(base, patch) {
299
+ const result = { ...base };
300
+ for (const [key, value] of Object.entries(patch)) {
301
+ if (value === undefined)
302
+ continue;
303
+ const before = result[key];
304
+ result[key] = isRecord(value) && isRecord(before) ? mergeOptions(before, value) : value;
305
+ }
306
+ return result;
307
+ }
308
+ /** The options that change while the instance runs, out of the options of `createDraw` */
309
+ function runtimePart(options) {
310
+ const result = {};
311
+ for (const key of RUNTIME_KEYS) {
312
+ if (options[key] !== undefined)
313
+ result[key] = options[key];
314
+ }
315
+ return mergeOptions({}, result);
316
+ }
317
+ // ============================================================================
318
+ // The configuration of the engine
319
+ // ============================================================================
320
+ /** The alpha of a CSS color, 1 when there is none */
321
+ function alphaOf(css) {
322
+ return css === undefined ? 1 : toColor(css)[3];
323
+ }
324
+ /** A color with another alpha */
325
+ function withAlpha(color, alpha) {
326
+ return [color[0], color[1], color[2], alpha];
327
+ }
328
+ /**
329
+ * A stroke with the stroke keys of a style: the opacity is folded into the alpha of the color,
330
+ * as the style of a feature does
331
+ */
332
+ function applyStroke(stroke, style, lineStyle = true) {
333
+ if (style.strokeColor !== undefined || style.strokeOpacity !== undefined) {
334
+ const base = style.strokeColor !== undefined ? toColor(style.strokeColor) : stroke.color;
335
+ const alpha = style.strokeOpacity !== undefined
336
+ ? alphaOf(style.strokeColor) * style.strokeOpacity
337
+ : base[3];
338
+ stroke.color = withAlpha(base, alpha);
339
+ }
340
+ if (style.strokeWidth !== undefined)
341
+ stroke.width = style.strokeWidth;
342
+ if (lineStyle && style.lineStyle !== undefined)
343
+ stroke.lineStyle = style.lineStyle;
344
+ }
345
+ /**
346
+ * A point marker with the point keys of a style: `pointStrokeColor` and `pointStrokeWidth` give
347
+ * its outline, and `pointOpacity` is multiplied into its fill and its outline
348
+ */
349
+ function applyPoint(point, style) {
350
+ if (style.pointShape !== undefined)
351
+ point.shape = style.pointShape;
352
+ if (style.pointRadius !== undefined)
353
+ point.size = style.pointRadius * 2;
354
+ if (style.pointColor !== undefined)
355
+ point.fillColor = withAlpha(toColor(style.pointColor), 1);
356
+ if (style.pointColor !== undefined || style.pointOpacity !== undefined) {
357
+ point.fillOpacity = alphaOf(style.pointColor) * (style.pointOpacity ?? 1);
358
+ }
359
+ if (style.pointStrokeColor !== undefined) {
360
+ point.strokeColor = withAlpha(toColor(style.pointStrokeColor), 1);
361
+ }
362
+ if (style.pointStrokeColor !== undefined || style.pointOpacity !== undefined) {
363
+ point.strokeOpacity = alphaOf(style.pointStrokeColor) * (style.pointOpacity ?? 1);
364
+ }
365
+ if (style.pointStrokeWidth !== undefined)
366
+ point.strokeWidth = style.pointStrokeWidth;
367
+ }
368
+ /** A fill with the fill keys of a style; a color without an opacity keeps the alpha before */
369
+ function applyFill(fill, style) {
370
+ if (style.fillColor === undefined && style.fillOpacity === undefined)
371
+ return;
372
+ const base = style.fillColor !== undefined ? toColor(style.fillColor) : fill.color;
373
+ const alpha = alphaOf(style.fillColor) * (style.fillOpacity ?? fill.color[3]);
374
+ fill.color = withAlpha(base, alpha);
375
+ }
376
+ /**
377
+ * The look of the features for the options: the defaults of each type and the look of the
378
+ * geometry being drawn
379
+ *
380
+ * @internal
381
+ */
382
+ export function toFeatureStyleConfig(options) {
383
+ const config = structuredClone(DEFAULT_FEATURE_STYLE_CONFIG);
384
+ const style = options.style ?? {};
385
+ if (style.point)
386
+ applyPoint(config.point.point, style.point);
387
+ if (style.line)
388
+ applyStroke(config.lineString.stroke, style.line);
389
+ if (style.polygon) {
390
+ applyStroke(config.polygon.stroke, style.polygon);
391
+ applyFill(config.polygon.fill, style.polygon);
392
+ }
393
+ if (style.circle) {
394
+ const circle = structuredClone(config.polygon);
395
+ applyStroke(circle.stroke, style.circle);
396
+ applyFill(circle.fill, style.circle);
397
+ config.circle = circle;
398
+ }
399
+ if (style.image?.imageOpacity !== undefined) {
400
+ config.image = { opacity: style.image.imageOpacity };
401
+ }
402
+ const preview = options.previewStyle;
403
+ if (preview) {
404
+ const tentative = config.tentative;
405
+ applyStroke(tentative.stroke, preview);
406
+ // The line to the pointer keeps its dashes
407
+ applyStroke(tentative.tentativeStroke, preview, false);
408
+ for (const vertex of [tentative.vertex, tentative.highlightedVertex]) {
409
+ applyPoint(vertex, preview);
410
+ }
411
+ // The highlighted vertex stays larger than the others
412
+ if (preview.pointRadius !== undefined) {
413
+ tentative.highlightedVertex.size = preview.pointRadius * 2 + 4;
414
+ }
415
+ for (const marker of [tentative.circleCenterMarker, tentative.circleRadiusHandle]) {
416
+ if (preview.pointStrokeColor !== undefined) {
417
+ marker.strokeColor = withAlpha(toColor(preview.pointStrokeColor), 1);
418
+ }
419
+ }
420
+ }
421
+ return config;
422
+ }
423
+ /** A color of the defaults as a CSS color, its alpha left to the opacity */
424
+ function defaultCss(color) {
425
+ return formatColor([color[0], color[1], color[2], 1]);
426
+ }
427
+ /**
428
+ * A paint with the color and the opacity of a style put over it, as {@link applyFill} and
429
+ * {@link applyStroke} fold them into the configuration: a color keeps the string it was given,
430
+ * and takes the opacity given, or `fallback` of the paint before; an opacity on its own sets
431
+ * the alpha the color is drawn with
432
+ */
433
+ function layerPaint(paint, color, opacity, fallback) {
434
+ if (color !== undefined)
435
+ return { color, opacity: opacity ?? fallback(paint) };
436
+ if (opacity === undefined)
437
+ return paint;
438
+ const alpha = alphaOf(paint.color);
439
+ if (alpha === 1)
440
+ return { color: paint.color, opacity };
441
+ // The color before has an alpha of its own, which the opacity replaces
442
+ const rgb = toColor(paint.color);
443
+ return alpha > 0
444
+ ? { color: paint.color, opacity: opacity / alpha }
445
+ : { color: defaultCss(rgb), opacity };
446
+ }
447
+ /** The opacity a fill keeps when a style gives only its color: the alpha it was drawn with */
448
+ const drawnAlpha = (paint) => alphaOf(paint.color) * paint.opacity;
449
+ /** The opacity a stroke takes when a style gives only its color */
450
+ const opaque = () => 1;
451
+ /** The types whose outline takes the stroke of an area */
452
+ const AREA_TYPES = new Set(['Polygon', 'MultiPolygon', 'Circle']);
453
+ /**
454
+ * The look the options give a feature of a type before its layer rule and its own style, in
455
+ * the shape of the style of a feature
456
+ *
457
+ * The colors are the strings the options give, as they were given; a color the options leave
458
+ * out is the default as `#rrggbb`. The opacities are what the colors are drawn with, so that
459
+ * the look drawn is the same as the configuration of {@link toFeatureStyleConfig}.
460
+ *
461
+ * @param style - The `style` option
462
+ * @param type - The type of the feature
463
+ * @internal
464
+ */
465
+ export function toAppliedDefaults(style, type) {
466
+ const defaults = DEFAULT_FEATURE_STYLE_CONFIG;
467
+ const point = style?.point ?? {};
468
+ // A circle takes the look of the circles over the look of the polygons, as it is drawn
469
+ const layers = AREA_TYPES.has(type)
470
+ ? [style?.polygon ?? {}, ...(type === 'Circle' && style?.circle ? [style.circle] : [])]
471
+ : [style?.line ?? {}];
472
+ const defaultStroke = AREA_TYPES.has(type) ? defaults.polygon.stroke : defaults.lineString.stroke;
473
+ const fillDefault = defaults.polygon.fill.color;
474
+ let fill = { color: defaultCss(fillDefault), opacity: fillDefault[3] };
475
+ let stroke = {
476
+ color: defaultCss(defaultStroke.color),
477
+ opacity: defaultStroke.color[3] * defaultStroke.opacity,
478
+ };
479
+ let strokeWidth = defaultStroke.width;
480
+ let lineStyle = defaultStroke.lineStyle;
481
+ for (const layer of layers) {
482
+ if (AREA_TYPES.has(type)) {
483
+ fill = layerPaint(fill, layer.fillColor, layer.fillOpacity, drawnAlpha);
484
+ }
485
+ stroke = layerPaint(stroke, layer.strokeColor, layer.strokeOpacity, opaque);
486
+ strokeWidth = layer.strokeWidth ?? strokeWidth;
487
+ lineStyle = layer.lineStyle ?? lineStyle;
488
+ }
489
+ const marker = defaults.point.point;
490
+ return {
491
+ fillColor: fill.color,
492
+ fillOpacity: fill.opacity,
493
+ strokeColor: stroke.color,
494
+ strokeWidth,
495
+ strokeOpacity: stroke.opacity,
496
+ lineStyle,
497
+ pointColor: point.pointColor ?? defaultCss(marker.fillColor),
498
+ pointRadius: point.pointRadius ?? marker.size / 2,
499
+ pointShape: point.pointShape ?? (marker.shape === 'icon' ? 'circle' : marker.shape),
500
+ pointOpacity: point.pointOpacity ?? 1,
501
+ pointStrokeColor: point.pointStrokeColor ?? defaultCss(marker.strokeColor),
502
+ pointStrokeWidth: point.pointStrokeWidth ?? marker.strokeWidth,
503
+ imageOpacity: style?.image?.imageOpacity ?? defaults.image?.opacity ?? 1,
504
+ };
505
+ }
506
+ /** A stroke of the selection from its options */
507
+ function toStroke(stroke, given) {
508
+ if (!given)
509
+ return;
510
+ if (given.color !== undefined)
511
+ stroke.color = toColor(given.color);
512
+ if (given.width !== undefined)
513
+ stroke.width = given.width;
514
+ if (given.opacity !== undefined)
515
+ stroke.opacity = given.opacity;
516
+ if (given.lineStyle !== undefined)
517
+ stroke.lineStyle = given.lineStyle;
518
+ if (given.dashArray !== undefined)
519
+ stroke.dashArray = [...given.dashArray];
520
+ }
521
+ /** A handle of the selection from its options */
522
+ function toPoint(point, given) {
523
+ if (!given)
524
+ return;
525
+ for (const [key, value] of Object.entries(given)) {
526
+ if (value === undefined)
527
+ continue;
528
+ const target = point;
529
+ target[key] = key === 'fillColor' || key === 'strokeColor' ? toColor(value) : value;
530
+ }
531
+ }
532
+ /**
533
+ * The look of the selection for the options
534
+ *
535
+ * @internal
536
+ */
537
+ export function toSelectionConfig(options) {
538
+ const config = structuredClone(DEFAULT_SELECTION_CONFIG);
539
+ const given = (options.selectionStyle ?? {});
540
+ const part = (key) => given[key] ?? {};
541
+ const sub = (key, name) => part(key)[name];
542
+ toStroke(config.boundingBox.stroke, sub('boundingBox', 'stroke'));
543
+ if (part('boundingBox').margin !== undefined) {
544
+ config.boundingBox.margin = part('boundingBox').margin;
545
+ }
546
+ toPoint(config.resizeHandle.point, sub('resizeHandle', 'point'));
547
+ toPoint(config.rotateHandle.point, sub('rotateHandle', 'point'));
548
+ toStroke(config.rotateHandle.connector, sub('rotateHandle', 'connector'));
549
+ if (part('rotateHandle').distance !== undefined) {
550
+ config.rotateHandle.distance = part('rotateHandle').distance;
551
+ }
552
+ toPoint(config.vertexHandle.point, sub('vertexHandle', 'point'));
553
+ toPoint(config.vertexHandle.selected, sub('vertexHandle', 'selected'));
554
+ toPoint(config.vertexHandle.followed, sub('vertexHandle', 'followed'));
555
+ toPoint(config.midpointHandle.point, sub('midpointHandle', 'point'));
556
+ toPoint(config.radiusHandle.point, sub('radiusHandle', 'point'));
557
+ toPoint(config.centerMarker.point, sub('centerMarker', 'point'));
558
+ toStroke(config.radiusLine.stroke, sub('radiusLine', 'stroke'));
559
+ return config;
560
+ }
561
+ /**
562
+ * The rectangle of a box selection for the options
563
+ *
564
+ * @internal
565
+ */
566
+ export function toBoxSelectionStyle(options) {
567
+ const config = structuredClone(DEFAULT_BOX_SELECTION_STYLE_CONFIG);
568
+ const box = options.selectionStyle?.boxSelection;
569
+ if (!box)
570
+ return config;
571
+ if (box.fillColor !== undefined || box.fillOpacity !== undefined) {
572
+ const base = box.fillColor !== undefined ? toColor(box.fillColor) : config.fillColor;
573
+ config.fillColor = withAlpha(base, alphaOf(box.fillColor) * (box.fillOpacity ?? config.fillColor[3]));
574
+ }
575
+ if (box.strokeColor !== undefined)
576
+ config.strokeColor = toColor(box.strokeColor);
577
+ if (box.strokeWidth !== undefined)
578
+ config.strokeWidth = box.strokeWidth;
579
+ return config;
580
+ }
581
+ /** The configuration of the automatic names */
582
+ function toAutoName(autoName) {
583
+ if (autoName === undefined)
584
+ return true;
585
+ if (autoName === false)
586
+ return false;
587
+ return { enabled: true, typeNames: autoName.typeNames, formatter: autoName.formatter };
588
+ }
589
+ /**
590
+ * The options of the engine for the options of `createDraw`
591
+ *
592
+ * @param isExternalEntry - The function the engine asks about the entries of the stacking
593
+ * order; the one of the options is reached through it, so that it can change
594
+ * @internal
595
+ */
596
+ export function toEngineOptions(options, isExternalEntry) {
597
+ const runtime = runtimePart(options);
598
+ const result = {
599
+ messages: runtime.messages,
600
+ autoName: toAutoName(runtime.autoName),
601
+ // Always given, so that the engine gets copies it can change in place
602
+ style: toFeatureStyleConfig(runtime),
603
+ selectionStyle: toSelectionConfig(runtime),
604
+ renderingStyle: {
605
+ boxSelectionStyle: toBoxSelectionStyle(runtime),
606
+ storeRetained: runtime.rendering?.cacheGeometry ?? true,
607
+ timeSlicing: runtime.rendering?.timeSlicing ?? true,
608
+ },
609
+ snap: runtime.snapping,
610
+ trace: runtime.tracing,
611
+ topology: runtime.topology,
612
+ pixelRatio: runtime.rendering?.pixelRatio,
613
+ isExternalEntry,
614
+ };
615
+ if (options.defaultMode !== undefined)
616
+ result.defaultMode = options.defaultMode;
617
+ if (options.initDefaultLayer !== undefined)
618
+ result.initDefaultLayer = options.initDefaultLayer;
619
+ if (runtime.scaleWithZoom !== undefined)
620
+ result.scaleWithZoom = runtime.scaleWithZoom;
621
+ if (runtime.clickTolerance !== undefined)
622
+ result.clickTolerance = runtime.clickTolerance;
623
+ if (runtime.dragThreshold !== undefined)
624
+ result.dragThreshold = runtime.dragThreshold;
625
+ if (options.store !== undefined) {
626
+ // A Store of the library is used as it is; the Store of an application is read and written
627
+ // through the public contract only, and the instance keeps the drawing state around it
628
+ result.store = options.store;
629
+ }
630
+ return result;
631
+ }
632
+ // ============================================================================
633
+ // draw.options
634
+ // ============================================================================
635
+ /**
636
+ * Changes an object of the configuration in place to the value of another, so that everything
637
+ * holding it sees the new value
638
+ */
639
+ function assignInPlace(target, source) {
640
+ for (const key of Object.keys(target)) {
641
+ if (!(key in source))
642
+ delete target[key];
643
+ }
644
+ for (const [key, value] of Object.entries(source)) {
645
+ const before = target[key];
646
+ if (isRecord(value) && isRecord(before))
647
+ assignInPlace(before, value);
648
+ else
649
+ target[key] = value;
650
+ }
651
+ }
652
+ /**
653
+ * Creates `draw.options` over the engine
654
+ *
655
+ * @param engine - The engine of the instance
656
+ * @param options - The options the instance was created with
657
+ * @param setExternalEntry - Replaces the function that tells the entries from outside the
658
+ * document
659
+ * @param onChanged - Receives the options after and before an update that changed them
660
+ * @internal
661
+ */
662
+ export function createOptions(engine, options, setExternalEntry, onChanged = () => { }) {
663
+ const { context, map, customLayer } = engine;
664
+ let current = runtimePart(options);
665
+ const apply = (patch) => {
666
+ let redraw = false;
667
+ let rebuild = false;
668
+ const next = current;
669
+ if (patch.messages !== undefined) {
670
+ Object.assign(context.messages, resolveMessages(next.messages));
671
+ }
672
+ if (patch.autoName !== undefined) {
673
+ context.autoNameGenerator.configure(toAutoName(next.autoName));
674
+ }
675
+ if (patch.style !== undefined || patch.previewStyle !== undefined) {
676
+ assignInPlace(context.featureStyle, toFeatureStyleConfig(next));
677
+ rebuild = true;
678
+ }
679
+ if (patch.selectionStyle !== undefined) {
680
+ assignInPlace(context.selectionStyle, toSelectionConfig(next));
681
+ assignInPlace(context.renderingConfig.boxSelectionStyle, toBoxSelectionStyle(next));
682
+ rebuild = true;
683
+ }
684
+ if (patch.scaleWithZoom !== undefined)
685
+ context.options.scaleWithZoom = patch.scaleWithZoom;
686
+ const snapping = patch.snapping;
687
+ if (snapping) {
688
+ const { snapService, snapOptions } = context;
689
+ if (snapping.enabled !== undefined)
690
+ snapService.setEnabled(snapping.enabled);
691
+ if (snapping.tolerancePx !== undefined) {
692
+ snapService.setTolerance(snapping.tolerancePx);
693
+ snapOptions.tolerancePx = snapping.tolerancePx;
694
+ }
695
+ if (snapping.disableKey !== undefined) {
696
+ snapService.setDisableKey(snapping.disableKey);
697
+ // The shared vertices read the same key
698
+ snapOptions.disableKey = snapping.disableKey;
699
+ }
700
+ for (const [kind, enabled] of Object.entries(snapping.kinds ?? {})) {
701
+ if (enabled === undefined)
702
+ continue;
703
+ snapService.setKindEnabled(kind, enabled);
704
+ }
705
+ if (snapping.datasets !== undefined)
706
+ snapService.setDatasetsEnabled(snapping.datasets);
707
+ if (snapping.guideStepDegrees !== undefined) {
708
+ snapService.setGuideStep(snapping.guideStepDegrees);
709
+ }
710
+ const look = context.snapIndicator;
711
+ for (const [kind, mark] of Object.entries(snapping.indicator ?? {})) {
712
+ toPoint(look.styles[kind], mark);
713
+ redraw = true;
714
+ }
715
+ if (snapping.guideLine) {
716
+ toStroke(look.guideLine, snapping.guideLine);
717
+ redraw = true;
718
+ }
719
+ }
720
+ if (patch.tracing?.enabled !== undefined)
721
+ context.trace.enabled = patch.tracing.enabled;
722
+ if (patch.topology?.sharedVertexDrag !== undefined) {
723
+ context.topology.sharedVertexDrag = patch.topology.sharedVertexDrag;
724
+ }
725
+ if (patch.clickTolerance !== undefined) {
726
+ context.options.clickTolerance = patch.clickTolerance;
727
+ context.hitTestService.setClickTolerance(patch.clickTolerance);
728
+ }
729
+ if (patch.dragThreshold !== undefined) {
730
+ context.options.dragThreshold = patch.dragThreshold;
731
+ engine.runtime.setDragThreshold(patch.dragThreshold);
732
+ }
733
+ const rendering = patch.rendering;
734
+ if (rendering) {
735
+ if (rendering.renderScale !== undefined) {
736
+ if (context.pixelRatioSource.setScaleFactor(rendering.renderScale))
737
+ redraw = true;
738
+ }
739
+ if (rendering.pixelRatio !== undefined) {
740
+ context.pixelRatio = rendering.pixelRatio;
741
+ if (context.pixelRatioSource.setPixelRatio(rendering.pixelRatio))
742
+ redraw = true;
743
+ }
744
+ if (rendering.cacheGeometry !== undefined) {
745
+ context.renderingConfig.storeRetained = rendering.cacheGeometry;
746
+ rebuild = true;
747
+ }
748
+ if (rendering.timeSlicing !== undefined) {
749
+ engine.runtime.setTimeSlicing(rendering.timeSlicing);
750
+ rebuild = true;
751
+ }
752
+ }
753
+ if (patch.isExternalEntry !== undefined) {
754
+ setExternalEntry(patch.isExternalEntry);
755
+ rebuild = true;
756
+ }
757
+ if (rebuild && 'refresh' in customLayer)
758
+ customLayer.refresh();
759
+ else if (redraw)
760
+ map.triggerRepaint();
761
+ };
762
+ const get = () => {
763
+ const { snapService, trace, topology, pixelRatioSource, renderingConfig } = context;
764
+ const snap = snapService.getOptions();
765
+ const values = {
766
+ ...current,
767
+ scaleWithZoom: context.options.scaleWithZoom,
768
+ clickTolerance: context.options.clickTolerance,
769
+ dragThreshold: context.options.dragThreshold,
770
+ snapping: {
771
+ ...current.snapping,
772
+ enabled: snap.enabled,
773
+ tolerancePx: snap.tolerancePx,
774
+ disableKey: snap.disableKey,
775
+ kinds: { ...snap.kinds },
776
+ datasets: snap.datasets,
777
+ guideStepDegrees: snap.guideStepDegrees,
778
+ },
779
+ tracing: { enabled: trace.enabled },
780
+ topology: { sharedVertexDrag: topology.sharedVertexDrag },
781
+ rendering: {
782
+ ...current.rendering,
783
+ renderScale: pixelRatioSource.getScaleFactor(),
784
+ cacheGeometry: renderingConfig.storeRetained !== false,
785
+ timeSlicing: renderingConfig.timeSlicing !== false,
786
+ },
787
+ };
788
+ return structuredCloneOptions(values);
789
+ };
790
+ return {
791
+ get,
792
+ update(patch) {
793
+ checkPatch(patch);
794
+ const previous = get();
795
+ current = mergeOptions(current, patch);
796
+ apply(patch);
797
+ const next = get();
798
+ if (!sameOptions(previous, next))
799
+ onChanged({ options: next, previous });
800
+ },
801
+ getStyle() {
802
+ return current.style;
803
+ },
804
+ applyCreation() {
805
+ const scale = current.rendering?.renderScale;
806
+ if (scale !== undefined)
807
+ apply({ rendering: { renderScale: scale } });
808
+ // The look of the snapping indicator is not an option of the engine
809
+ const { indicator, guideLine } = current.snapping ?? {};
810
+ if (indicator || guideLine) {
811
+ apply({
812
+ snapping: { ...(indicator && { indicator }), ...(guideLine && { guideLine }) },
813
+ });
814
+ }
815
+ },
816
+ };
817
+ }
818
+ /**
819
+ * Whether two copies of the options hold the same values: plain objects and arrays are
820
+ * compared item by item, a function by identity, and a key given as `undefined` is the same
821
+ * as a key left out
822
+ */
823
+ function sameOptions(a, b) {
824
+ if (Object.is(a, b))
825
+ return true;
826
+ if (Array.isArray(a) || Array.isArray(b)) {
827
+ return (Array.isArray(a) &&
828
+ Array.isArray(b) &&
829
+ a.length === b.length &&
830
+ a.every((item, i) => sameOptions(item, b[i])));
831
+ }
832
+ if (!isRecord(a) || !isRecord(b))
833
+ return false;
834
+ const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
835
+ for (const key of keys) {
836
+ if (!sameOptions(a[key], b[key]))
837
+ return false;
838
+ }
839
+ return true;
840
+ }
841
+ /** A copy of the options that shares the functions and nothing else */
842
+ function structuredCloneOptions(value) {
843
+ if (Array.isArray(value))
844
+ return value.map(structuredCloneOptions);
845
+ if (!isRecord(value))
846
+ return value;
847
+ const copy = {};
848
+ for (const [key, entry] of Object.entries(value))
849
+ copy[key] = structuredCloneOptions(entry);
850
+ return copy;
851
+ }