@sakuzu/maplibre-gl-draw 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (540) hide show
  1. package/CHANGELOG.md +1016 -2
  2. package/README.ja.md +39 -19
  3. package/README.md +41 -21
  4. package/dist/api/datasets.d.ts +258 -0
  5. package/dist/api/document.d.ts +66 -0
  6. package/dist/api/draw.d.ts +135 -0
  7. package/dist/api/draw.js +18 -0
  8. package/dist/api/drawing.d.ts +87 -0
  9. package/dist/api/errors.d.ts +35 -0
  10. package/dist/api/errors.js +35 -0
  11. package/dist/api/events.d.ts +306 -0
  12. package/dist/api/extension/context.d.ts +247 -0
  13. package/dist/api/extension/feature-type.d.ts +129 -0
  14. package/dist/api/extension/mode.d.ts +123 -0
  15. package/dist/api/extension/plugin.d.ts +51 -0
  16. package/dist/api/extension/plugin.js +3 -0
  17. package/dist/api/extension/provider.d.ts +119 -0
  18. package/dist/api/extension/provider.js +3 -0
  19. package/dist/api/extension/render.d.ts +176 -0
  20. package/dist/api/extension/render.js +3 -0
  21. package/dist/api/extension/store.d.ts +190 -0
  22. package/dist/api/extension/store.js +3 -0
  23. package/dist/api/extensions.d.ts +306 -0
  24. package/dist/api/extensions.js +3 -0
  25. package/dist/api/features.d.ts +188 -0
  26. package/dist/api/features.js +3 -0
  27. package/dist/api/groups.d.ts +111 -0
  28. package/dist/api/groups.js +3 -0
  29. package/dist/api/hidden.d.ts +45 -0
  30. package/dist/api/hidden.js +3 -0
  31. package/dist/api/impl/adapters.js +463 -0
  32. package/dist/api/impl/contexts.js +466 -0
  33. package/dist/api/impl/create-draw.js +124 -0
  34. package/dist/api/impl/datasets.js +404 -0
  35. package/dist/api/impl/destroy-guard.js +74 -0
  36. package/dist/api/impl/document.js +280 -0
  37. package/dist/api/impl/drawing.js +180 -0
  38. package/dist/api/impl/engine-context.d.ts +7 -0
  39. package/dist/api/{context.js → impl/engine-context.js} +49 -38
  40. package/dist/{maplibre-gl-draw.js → api/impl/engine.js} +145 -177
  41. package/dist/api/impl/events.js +422 -0
  42. package/dist/api/impl/extension-host.js +361 -0
  43. package/dist/api/impl/extensions.js +229 -0
  44. package/dist/api/impl/features.js +445 -0
  45. package/dist/api/impl/geometry/apply.d.ts +32 -0
  46. package/dist/api/{geometry → impl/geometry}/apply.js +10 -27
  47. package/dist/api/{geometry → impl/geometry}/buffer.d.ts +4 -3
  48. package/dist/api/{geometry → impl/geometry}/buffer.js +12 -23
  49. package/dist/api/{geometry → impl/geometry}/split.d.ts +4 -3
  50. package/dist/api/{geometry → impl/geometry}/split.js +10 -21
  51. package/dist/api/{geometry → impl/geometry}/targets.d.ts +2 -20
  52. package/dist/api/{geometry → impl/geometry}/targets.js +8 -35
  53. package/dist/api/impl/geometry/types.js +3 -0
  54. package/dist/api/impl/groups.d.ts +3 -0
  55. package/dist/api/impl/groups.js +268 -0
  56. package/dist/api/impl/hidden.js +60 -0
  57. package/dist/api/impl/import-export/constants.d.ts +22 -0
  58. package/dist/api/impl/import-export/constants.js +24 -0
  59. package/dist/api/{import-export → impl/import-export}/embedded-file.js +2 -2
  60. package/dist/api/{import-export → impl/import-export}/format-detection.d.ts +1 -1
  61. package/dist/api/{import-export → impl/import-export}/format-detection.js +2 -1
  62. package/dist/api/impl/import-export/geojson-export.d.ts +19 -0
  63. package/dist/api/{import-export → impl/import-export}/geojson-export.js +71 -104
  64. package/dist/api/{import-export → impl/import-export}/geojson-import.d.ts +11 -7
  65. package/dist/api/{import-export → impl/import-export}/geojson-import.js +139 -97
  66. package/dist/api/{import-export → impl/import-export}/geometry-validation.d.ts +14 -0
  67. package/dist/api/{import-export → impl/import-export}/geometry-validation.js +45 -0
  68. package/dist/api/impl/import-export/image-import.d.ts +16 -0
  69. package/dist/api/impl/import-export/image-import.js +73 -0
  70. package/dist/api/impl/import-export/legacy-image-style.d.ts +16 -0
  71. package/dist/api/impl/import-export/legacy-image-style.js +49 -0
  72. package/dist/api/impl/import-export/native-format.d.ts +14 -0
  73. package/dist/api/{import-export → impl/import-export}/native-format.js +32 -22
  74. package/dist/api/impl/import-export/native-upgrade.d.ts +8 -0
  75. package/dist/api/impl/import-export/native-upgrade.js +139 -0
  76. package/dist/api/{import-export → impl/import-export}/native-validation.d.ts +1 -1
  77. package/dist/api/{import-export → impl/import-export}/native-validation.js +15 -14
  78. package/dist/api/impl/import-export/style-validation.d.ts +24 -0
  79. package/dist/api/impl/import-export/style-validation.js +86 -0
  80. package/dist/api/impl/import-export/types.d.ts +52 -0
  81. package/dist/api/impl/import-export/types.js +3 -0
  82. package/dist/api/impl/input.js +180 -0
  83. package/dist/api/impl/layers.js +307 -0
  84. package/dist/api/impl/metadata.d.ts +1 -0
  85. package/dist/api/impl/metadata.js +22 -0
  86. package/dist/api/impl/options.d.ts +1 -0
  87. package/dist/api/impl/options.js +822 -0
  88. package/dist/api/impl/placement.d.ts +1 -0
  89. package/dist/api/impl/placement.js +138 -0
  90. package/dist/api/impl/render-context.d.ts +13 -0
  91. package/dist/api/impl/render-context.js +272 -0
  92. package/dist/api/impl/rows.d.ts +1 -0
  93. package/dist/api/impl/rows.js +46 -0
  94. package/dist/api/impl/selection.d.ts +1 -0
  95. package/dist/api/impl/selection.js +186 -0
  96. package/dist/api/impl/shared.d.ts +64 -0
  97. package/dist/api/impl/shared.js +178 -0
  98. package/dist/api/impl/validate-extension.d.ts +1 -0
  99. package/dist/api/impl/validate-extension.js +159 -0
  100. package/dist/api/layers.d.ts +130 -0
  101. package/dist/api/layers.js +3 -0
  102. package/dist/api/metadata.d.ts +18 -0
  103. package/dist/api/metadata.js +3 -0
  104. package/dist/api/model.d.ts +487 -0
  105. package/dist/api/model.js +47 -0
  106. package/dist/api/options.d.ts +466 -0
  107. package/dist/api/options.js +3 -0
  108. package/dist/api/selection.d.ts +94 -0
  109. package/dist/api/selection.js +3 -0
  110. package/dist/api/state.d.ts +155 -0
  111. package/dist/api/state.js +12 -0
  112. package/dist/{display → dataset}/chunk.d.ts +1 -1
  113. package/dist/{display → dataset}/chunk.js +4 -3
  114. package/dist/{display → dataset}/dataset.js +18 -21
  115. package/dist/dataset/interaction.d.ts +1 -0
  116. package/dist/{display → dataset}/interaction.js +18 -6
  117. package/dist/dataset/manager.d.ts +1 -0
  118. package/dist/dataset/provider.d.ts +1 -0
  119. package/dist/{display → dataset}/retained.d.ts +1 -1
  120. package/dist/{display → dataset}/retained.js +8 -7
  121. package/dist/dataset/source.d.ts +1 -0
  122. package/dist/{display → dataset}/source.js +17 -4
  123. package/dist/dataset/spatial.d.ts +1 -0
  124. package/dist/{display → dataset}/spatial.js +1 -1
  125. package/dist/dataset/style.d.ts +1 -0
  126. package/dist/{display → dataset}/style.js +1 -1
  127. package/dist/dataset/table-source.d.ts +1 -0
  128. package/dist/{display/columnar/source.js → dataset/table-source.js} +53 -25
  129. package/dist/{display → dataset}/thinning.d.ts +0 -10
  130. package/dist/{display → dataset}/thinning.js +3 -2
  131. package/dist/dataset/triangulation.d.ts +1 -0
  132. package/dist/{display → dataset}/triangulation.js +0 -0
  133. package/dist/{display → dataset}/types.d.ts +82 -121
  134. package/dist/dataset/types.js +61 -0
  135. package/dist/dispatcher/hit-test/box-strategies.js +13 -13
  136. package/dist/dispatcher/hit-test/box-strategy.d.ts +2 -15
  137. package/dist/dispatcher/hit-test/globe-shape.js +5 -4
  138. package/dist/dispatcher/hit-test/service.d.ts +17 -0
  139. package/dist/dispatcher/hit-test/service.js +80 -16
  140. package/dist/dispatcher/hit-test/strategies/base.d.ts +13 -19
  141. package/dist/dispatcher/hit-test/strategies/circle.js +3 -2
  142. package/dist/dispatcher/hit-test/strategies/image.js +6 -18
  143. package/dist/dispatcher/hit-test/strategies/line.d.ts +0 -6
  144. package/dist/dispatcher/hit-test/strategies/line.js +9 -2
  145. package/dist/dispatcher/hit-test/strategies/multi.d.ts +0 -8
  146. package/dist/dispatcher/hit-test/strategies/multi.js +17 -8
  147. package/dist/dispatcher/hit-test/strategies/point.d.ts +9 -7
  148. package/dist/dispatcher/hit-test/strategies/point.js +8 -4
  149. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +0 -7
  150. package/dist/dispatcher/hit-test/strategies/polygon.js +11 -3
  151. package/dist/dispatcher/hit-test/topmost.d.ts +1 -1
  152. package/dist/dispatcher/input-router.js +152 -69
  153. package/dist/dispatcher/normalizer.js +6 -2
  154. package/dist/dispatcher/types.d.ts +6 -1
  155. package/dist/extension/feature-handler.d.ts +1 -182
  156. package/dist/extension/index.d.ts +4 -7
  157. package/dist/extension/renderers.d.ts +1 -208
  158. package/dist/geometry/angle.d.ts +0 -8
  159. package/dist/geometry/angle.js +0 -8
  160. package/dist/geometry/bbox.d.ts +4 -12
  161. package/dist/geometry/bbox.js +4 -12
  162. package/dist/geometry/boolean.d.ts +0 -51
  163. package/dist/geometry/boolean.js +0 -51
  164. package/dist/geometry/buffer.d.ts +0 -26
  165. package/dist/geometry/buffer.js +0 -26
  166. package/dist/geometry/circle.d.ts +0 -9
  167. package/dist/geometry/circle.js +0 -9
  168. package/dist/geometry/coords.d.ts +0 -16
  169. package/dist/geometry/coords.js +0 -16
  170. package/dist/geometry/distance.d.ts +0 -24
  171. package/dist/geometry/distance.js +0 -24
  172. package/dist/geometry/errors.d.ts +21 -36
  173. package/dist/geometry/errors.js +49 -29
  174. package/dist/geometry/geojson.d.ts +81 -0
  175. package/dist/geometry/geojson.js +164 -0
  176. package/dist/geometry/index.d.ts +38 -23
  177. package/dist/geometry/index.js +43 -31
  178. package/dist/geometry/measure.d.ts +0 -27
  179. package/dist/geometry/measure.js +0 -27
  180. package/dist/geometry/predicates.d.ts +0 -9
  181. package/dist/geometry/predicates.js +0 -9
  182. package/dist/geometry/public-bounds.d.ts +26 -0
  183. package/dist/geometry/public-bounds.js +30 -0
  184. package/dist/geometry/public-combine.d.ts +78 -0
  185. package/dist/geometry/public-combine.js +82 -0
  186. package/dist/geometry/public-create.d.ts +54 -0
  187. package/dist/geometry/public-create.js +70 -0
  188. package/dist/geometry/public-measure.d.ts +170 -0
  189. package/dist/geometry/public-measure.js +283 -0
  190. package/dist/geometry/public-predicates.d.ts +54 -0
  191. package/dist/geometry/public-predicates.js +144 -0
  192. package/dist/geometry/public-repair.d.ts +75 -0
  193. package/dist/geometry/public-repair.js +77 -0
  194. package/dist/geometry/simplify.d.ts +0 -7
  195. package/dist/geometry/simplify.js +0 -7
  196. package/dist/geometry/split.d.ts +0 -20
  197. package/dist/geometry/split.js +0 -20
  198. package/dist/geometry/units.d.ts +20 -12
  199. package/dist/geometry/units.js +20 -12
  200. package/dist/index.d.ts +52 -66
  201. package/dist/index.js +6 -18
  202. package/dist/messages.d.ts +7 -7
  203. package/dist/modes/draw/circle.js +83 -207
  204. package/dist/modes/draw/commit-layer.d.ts +5 -16
  205. package/dist/modes/draw/commit-layer.js +2 -13
  206. package/dist/modes/draw/freehand.js +108 -246
  207. package/dist/modes/draw/image.js +4 -2
  208. package/dist/modes/draw/index.d.ts +5 -5
  209. package/dist/modes/draw/index.js +5 -5
  210. package/dist/modes/draw/line.js +18 -354
  211. package/dist/modes/draw/point.js +29 -78
  212. package/dist/modes/draw/polygon.js +23 -368
  213. package/dist/modes/draw/trace-support.d.ts +43 -36
  214. package/dist/modes/draw/trace-support.js +95 -98
  215. package/dist/modes/draw/vertex-drawing.d.ts +1 -0
  216. package/dist/modes/draw/vertex-drawing.js +176 -0
  217. package/dist/modes/handler.d.ts +1 -285
  218. package/dist/modes/manager.d.ts +2 -2
  219. package/dist/modes/manager.js +3 -0
  220. package/dist/modes/select/box-selection.d.ts +3 -3
  221. package/dist/modes/select/box-selection.js +2 -1
  222. package/dist/modes/select/click-handler.d.ts +5 -5
  223. package/dist/modes/select/click-handler.js +22 -20
  224. package/dist/modes/select/cursor-handler.d.ts +2 -2
  225. package/dist/modes/select/drag/intermediate-writes.js +1 -1
  226. package/dist/modes/select/drag/move.js +3 -3
  227. package/dist/modes/select/drag/operation.d.ts +3 -3
  228. package/dist/modes/select/drag/radius.js +5 -4
  229. package/dist/modes/select/drag/transform.d.ts +2 -2
  230. package/dist/modes/select/drag/transform.js +11 -5
  231. package/dist/modes/select/drag/vertex.d.ts +2 -2
  232. package/dist/modes/select/drag/vertex.js +13 -8
  233. package/dist/modes/select/drag-handler.js +44 -25
  234. package/dist/modes/select/mode.js +17 -17
  235. package/dist/modes/select/shortcut-handler.d.ts +8 -8
  236. package/dist/modes/select/shortcut-handler.js +9 -7
  237. package/dist/operations/layer-operations.js +29 -168
  238. package/dist/operations/resize.d.ts +2 -2
  239. package/dist/operations/resize.js +5 -5
  240. package/dist/operations/rotate.js +5 -5
  241. package/dist/operations/selection-operations.d.ts +16 -1
  242. package/dist/operations/selection-operations.js +28 -13
  243. package/dist/operations/shared-vertex.js +4 -2
  244. package/dist/operations/trace-graph.d.ts +0 -18
  245. package/dist/operations/trace-graph.js +0 -18
  246. package/dist/operations/vertex.js +36 -35
  247. package/dist/shared/color.d.ts +1 -0
  248. package/dist/shared/color.js +245 -0
  249. package/dist/shared/config/constants.d.ts +1 -54
  250. package/dist/shared/config/constants.js +1 -58
  251. package/dist/shared/config/feature-style.d.ts +16 -13
  252. package/dist/shared/config/feature-style.js +9 -0
  253. package/dist/shared/config/rendering.d.ts +3 -3
  254. package/dist/shared/config/selection-highlight.d.ts +0 -15
  255. package/dist/shared/config/selection-highlight.js +4 -7
  256. package/dist/shared/config/selection.d.ts +2 -32
  257. package/dist/shared/config/selection.js +0 -18
  258. package/dist/shared/config/topology.d.ts +2 -2
  259. package/dist/shared/config/trace.d.ts +4 -4
  260. package/dist/shared/math/angle.d.ts +1 -1
  261. package/dist/shared/math/angle.js +1 -1
  262. package/dist/shared/math/circle.d.ts +1 -1
  263. package/dist/shared/math/circle.js +1 -1
  264. package/dist/shared/math/distance.d.ts +2 -1
  265. package/dist/shared/math/distance.js +3 -2
  266. package/dist/shared/math/index.d.ts +1 -1
  267. package/dist/shared/math/index.js +1 -1
  268. package/dist/shared/math/transform.d.ts +23 -0
  269. package/dist/shared/math/transform.js +47 -28
  270. package/dist/shared/properties.d.ts +18 -0
  271. package/dist/shared/properties.js +129 -0
  272. package/dist/shared/types/events.d.ts +15 -7
  273. package/dist/shared/types/model.d.ts +109 -159
  274. package/dist/shared/types/style.d.ts +1 -1
  275. package/dist/shared/utils/color.d.ts +2 -36
  276. package/dist/shared/utils/color.js +13 -70
  277. package/dist/shared/utils/coordinates.d.ts +30 -4
  278. package/dist/shared/utils/coordinates.js +56 -10
  279. package/dist/shared/utils/event-emitter.d.ts +1 -262
  280. package/dist/shared/utils/event-emitter.js +4 -3
  281. package/dist/shared/utils/feature-bbox.js +8 -7
  282. package/dist/shared/utils/feature-segments.js +5 -4
  283. package/dist/shared/utils/image.d.ts +0 -4
  284. package/dist/shared/utils/image.js +0 -6
  285. package/dist/shared/utils/name-generator.d.ts +14 -20
  286. package/dist/shared/utils/name-generator.js +20 -3
  287. package/dist/shared/utils/pixel-ratio.d.ts +9 -3
  288. package/dist/shared/utils/pixel-ratio.js +13 -4
  289. package/dist/shared/utils/property.d.ts +7 -50
  290. package/dist/shared/utils/property.js +22 -87
  291. package/dist/snapping/custom-targets.js +21 -4
  292. package/dist/snapping/indicator.js +20 -11
  293. package/dist/snapping/providers/display.d.ts +6 -1
  294. package/dist/snapping/providers/display.js +2 -1
  295. package/dist/snapping/providers/guide.d.ts +3 -43
  296. package/dist/snapping/providers/guide.js +1 -44
  297. package/dist/snapping/providers/intersection.js +1 -1
  298. package/dist/snapping/providers/store.js +3 -3
  299. package/dist/snapping/service.js +18 -7
  300. package/dist/snapping/types.d.ts +9 -35
  301. package/dist/store/draw-store.js +233 -142
  302. package/dist/store/local-visibility.d.ts +11 -6
  303. package/dist/store/local-visibility.js +38 -7
  304. package/dist/store/lock.d.ts +0 -6
  305. package/dist/store/lock.js +0 -6
  306. package/dist/store/memory/change-bus.d.ts +3 -3
  307. package/dist/store/memory/change-bus.js +12 -0
  308. package/dist/store/memory/file-store.d.ts +2 -2
  309. package/dist/store/memory/ui-state.d.ts +1 -51
  310. package/dist/store/memory/ui-state.js +122 -134
  311. package/dist/store/memory.d.ts +1 -8
  312. package/dist/store/memory.js +249 -45
  313. package/dist/store/ordering.d.ts +9 -0
  314. package/dist/store/ordering.js +17 -0
  315. package/dist/store/spatial/spatial-index.d.ts +1 -1
  316. package/dist/store/spatial/spatial-index.js +1 -1
  317. package/dist/store/spatial/store-spatial-index.d.ts +3 -1
  318. package/dist/store/spatial/store-spatial-index.js +9 -3
  319. package/dist/store/store.d.ts +66 -107
  320. package/dist/store/types.d.ts +1 -1
  321. package/dist/store/writable-layer.d.ts +1 -1
  322. package/dist/store/writable-layer.js +2 -2
  323. package/dist/table/builder.d.ts +83 -0
  324. package/dist/table/builder.js +381 -0
  325. package/dist/table/index.d.ts +37 -0
  326. package/dist/table/index.js +5 -0
  327. package/dist/table/packed-rtree.d.ts +1 -0
  328. package/dist/{display → table}/packed-rtree.js +1 -1
  329. package/dist/table/partition.d.ts +1 -0
  330. package/dist/{display → table}/partition.js +3 -3
  331. package/dist/table/prepare.d.ts +44 -0
  332. package/dist/table/prepare.js +136 -0
  333. package/dist/table/table.d.ts +1 -0
  334. package/dist/{display/columnar → table}/table.js +29 -25
  335. package/dist/{display/columnar → table}/types.d.ts +68 -72
  336. package/dist/table/types.js +3 -0
  337. package/dist/view/coordinator.js +4 -3
  338. package/dist/view/feature-companion.d.ts +13 -7
  339. package/dist/view/feature-companion.js +11 -3
  340. package/dist/view/globe-subdivision.js +3 -3
  341. package/dist/view/layer/attach.d.ts +1 -1
  342. package/dist/view/layer/attach.js +1 -1
  343. package/dist/view/layer/custom-layer.js +40 -11
  344. package/dist/view/layer/display-list.js +2 -1
  345. package/dist/view/layer/drape-planner.d.ts +2 -2
  346. package/dist/view/layer/frame-render.d.ts +3 -3
  347. package/dist/view/layer/frame-render.js +7 -2
  348. package/dist/view/layer/frame-state.d.ts +6 -6
  349. package/dist/view/layer/index.d.ts +2 -2
  350. package/dist/view/layer/index.js +1 -1
  351. package/dist/view/layer/render.d.ts +4 -4
  352. package/dist/view/layer/render.js +3 -8
  353. package/dist/view/layer/renderers.d.ts +2 -2
  354. package/dist/view/layer/renderers.js +1 -1
  355. package/dist/view/layer/slot-manager.d.ts +2 -2
  356. package/dist/view/layer/slot-manager.js +4 -4
  357. package/dist/view/layer/slots.d.ts +2 -2
  358. package/dist/view/layer/slots.js +1 -1
  359. package/dist/view/layer/store-retained-bbox.js +3 -2
  360. package/dist/view/layer/store-retained-classify.d.ts +5 -7
  361. package/dist/view/layer/store-retained-classify.js +19 -7
  362. package/dist/view/layer/store-retained-collect.js +8 -7
  363. package/dist/view/layer/store-retained-coord-patch.d.ts +0 -8
  364. package/dist/view/layer/store-retained-coord-patch.js +13 -4
  365. package/dist/view/layer/store-retained-immediate.d.ts +3 -3
  366. package/dist/view/layer/store-retained-immediate.js +3 -8
  367. package/dist/view/layer/store-retained-invalidation.d.ts +2 -2
  368. package/dist/view/layer/store-retained.d.ts +2 -2
  369. package/dist/view/layer/store-retained.js +1 -1
  370. package/dist/view/renderers/batch-manager.js +8 -7
  371. package/dist/view/renderers/drawer.js +21 -15
  372. package/dist/view/renderers/image.js +13 -39
  373. package/dist/view/renderers/line/line-types.d.ts +3 -3
  374. package/dist/view/renderers/line/sdf-line.js +3 -1
  375. package/dist/view/renderers/point/billboard-depth.js +1 -1
  376. package/dist/view/renderers/point/point-instance.js +1 -1
  377. package/dist/view/renderers/point/point-shape.js +2 -2
  378. package/dist/view/renderers/point/point-style.js +48 -4
  379. package/dist/view/renderers/polygon/batch.js +1 -2
  380. package/dist/view/renderers/polygon/fill.js +3 -1
  381. package/dist/view/renderers/polygon/sdf-polygon.js +2 -3
  382. package/dist/view/renderers/polygon/triangulator.d.ts +1 -1
  383. package/dist/view/renderers/stroke.js +3 -1
  384. package/dist/view/shaders/helpers.d.ts +2 -42
  385. package/dist/view/shaders/helpers.js +0 -6
  386. package/dist/view/shaders/projection.d.ts +15 -7
  387. package/dist/view/shaders/projection.js +23 -6
  388. package/dist/view/shaders/quad.d.ts +16 -12
  389. package/dist/view/shaders/quad.js +34 -13
  390. package/dist/view/style-rule.d.ts +5 -42
  391. package/dist/view/style-rule.js +20 -44
  392. package/dist/view/terrain/binding.d.ts +1 -0
  393. package/dist/view/terrain/binding.js +29 -0
  394. package/dist/view/terrain/context.d.ts +3 -4
  395. package/dist/view/terrain/context.js +4 -5
  396. package/dist/view/terrain/drape/geometry.js +1 -1
  397. package/dist/view/terrain/drape/pass.d.ts +1 -1
  398. package/dist/view/terrain/drape/pass.js +8 -7
  399. package/dist/view/terrain/polygon.d.ts +9 -5
  400. package/dist/view/terrain/polygon.js +16 -2
  401. package/dist/view/terrain/state.d.ts +1 -1
  402. package/dist/view/terrain/state.js +1 -1
  403. package/dist/view/terrain/tessellation.d.ts +2 -2
  404. package/dist/view/terrain/tessellation.js +1 -1
  405. package/dist/view/ui/auxiliary-handles.d.ts +6 -29
  406. package/dist/view/ui/bounds.js +8 -12
  407. package/dist/view/ui/handle-test.js +2 -2
  408. package/dist/view/ui/handle-thinning.js +17 -17
  409. package/dist/view/ui/handles.js +21 -13
  410. package/dist/view/ui/helper.d.ts +1 -1
  411. package/dist/view/ui/helper.js +1 -1
  412. package/dist/view/ui/index.d.ts +1 -1
  413. package/dist/view/ui/selection-scope.js +4 -2
  414. package/dist/view/ui/selection-ui/bounding-box.js +6 -6
  415. package/dist/view/ui/selection-ui/extension-registry.d.ts +31 -20
  416. package/dist/view/ui/selection-ui/extension-registry.js +70 -7
  417. package/dist/view/ui/selection-ui/index.d.ts +2 -2
  418. package/dist/view/ui/selection-ui/index.js +1 -1
  419. package/dist/view/ui/selection-ui/renderer.js +15 -38
  420. package/dist/view/ui/selection-ui/types.d.ts +17 -2
  421. package/dist/view/ui/selection-ui-drawer.d.ts +8 -0
  422. package/dist/view/ui/selection-ui-drawer.js +63 -2
  423. package/dist/view/ui/tentative.js +1 -1
  424. package/dist/webgl/index.d.ts +65 -0
  425. package/dist/webgl/index.js +62 -0
  426. package/package.json +20 -9
  427. package/dist/api/api.d.ts +0 -1259
  428. package/dist/api/api.js +0 -86
  429. package/dist/api/context.d.ts +0 -173
  430. package/dist/api/display-api.js +0 -23
  431. package/dist/api/event-api.d.ts +0 -13
  432. package/dist/api/event-api.js +0 -17
  433. package/dist/api/extension-api.d.ts +0 -46
  434. package/dist/api/extension-api.js +0 -85
  435. package/dist/api/feature-api.d.ts +0 -11
  436. package/dist/api/feature-api.js +0 -101
  437. package/dist/api/geometry/apply.d.ts +0 -51
  438. package/dist/api/geometry/boolean.d.ts +0 -28
  439. package/dist/api/geometry/boolean.js +0 -65
  440. package/dist/api/geometry/types.d.ts +0 -31
  441. package/dist/api/geometry-operations.d.ts +0 -162
  442. package/dist/api/geometry-operations.js +0 -94
  443. package/dist/api/group-api.d.ts +0 -10
  444. package/dist/api/group-api.js +0 -78
  445. package/dist/api/import-export/constants.d.ts +0 -29
  446. package/dist/api/import-export/constants.js +0 -40
  447. package/dist/api/import-export/file-name.d.ts +0 -10
  448. package/dist/api/import-export/file-name.js +0 -20
  449. package/dist/api/import-export/geojson-export.d.ts +0 -19
  450. package/dist/api/import-export/image-import.d.ts +0 -12
  451. package/dist/api/import-export/image-import.js +0 -53
  452. package/dist/api/import-export/index.d.ts +0 -9
  453. package/dist/api/import-export/index.js +0 -107
  454. package/dist/api/import-export/native-format.d.ts +0 -15
  455. package/dist/api/import-export/style-validation.d.ts +0 -27
  456. package/dist/api/import-export/style-validation.js +0 -49
  457. package/dist/api/import-export/types.d.ts +0 -26
  458. package/dist/api/index.d.ts +0 -15
  459. package/dist/api/index.js +0 -3
  460. package/dist/api/input-api.d.ts +0 -158
  461. package/dist/api/input-api.js +0 -144
  462. package/dist/api/instance-api.d.ts +0 -38
  463. package/dist/api/instance-api.js +0 -136
  464. package/dist/api/layer-api.d.ts +0 -12
  465. package/dist/api/layer-api.js +0 -62
  466. package/dist/api/selection-api.d.ts +0 -7
  467. package/dist/api/selection-api.js +0 -78
  468. package/dist/api/snapping-api.d.ts +0 -125
  469. package/dist/api/snapping-api.js +0 -50
  470. package/dist/api/topology-api.d.ts +0 -30
  471. package/dist/api/topology-api.js +0 -16
  472. package/dist/api/tracing-api.d.ts +0 -31
  473. package/dist/api/tracing-api.js +0 -16
  474. package/dist/dispatcher/hit-test/index.d.ts +0 -14
  475. package/dist/dispatcher/hit-test/index.js +0 -9
  476. package/dist/dispatcher/index.d.ts +0 -15
  477. package/dist/dispatcher/index.js +0 -3
  478. package/dist/display/columnar/index.d.ts +0 -12
  479. package/dist/display/columnar/index.js +0 -13
  480. package/dist/display/columnar/prepare.d.ts +0 -42
  481. package/dist/display/columnar/prepare.js +0 -116
  482. package/dist/display/index.d.ts +0 -13
  483. package/dist/display/types.js +0 -43
  484. package/dist/maplibre-gl-draw.d.ts +0 -47
  485. package/dist/modes/cursor.js +0 -72
  486. package/dist/modes/index.d.ts +0 -7
  487. package/dist/operations/index.d.ts +0 -9
  488. package/dist/operations/index.js +0 -3
  489. package/dist/plugins/index.d.ts +0 -10
  490. package/dist/plugins/mutation-hooks.d.ts +0 -28
  491. package/dist/plugins/mutation-hooks.js +0 -84
  492. package/dist/plugins/plugin-context.js +0 -367
  493. package/dist/plugins/plugin-manager.d.ts +0 -103
  494. package/dist/plugins/plugin-manager.js +0 -316
  495. package/dist/plugins/plugin.d.ts +0 -529
  496. package/dist/shared/config/index.d.ts +0 -17
  497. package/dist/shared/config/index.js +0 -8
  498. package/dist/shared/utils/index.d.ts +0 -15
  499. package/dist/shared/utils/index.js +0 -24
  500. package/dist/snapping/index.d.ts +0 -14
  501. package/dist/snapping/index.js +0 -4
  502. package/dist/store/change-merger.js +0 -102
  503. package/dist/store/event-bridge.js +0 -161
  504. package/dist/store/index.d.ts +0 -12
  505. package/dist/store/index.js +0 -4
  506. package/dist/view/index.d.ts +0 -47
  507. package/dist/view/index.js +0 -20
  508. /package/dist/api/{geometry/types.js → datasets.js} +0 -0
  509. /package/dist/api/{import-export/types.js → document.js} +0 -0
  510. /package/dist/{display/columnar/types.js → api/drawing.js} +0 -0
  511. /package/dist/{display/index.js → api/events.js} +0 -0
  512. /package/dist/{modes/index.js → api/extension/context.js} +0 -0
  513. /package/dist/{plugins/index.js → api/extension/feature-type.js} +0 -0
  514. /package/dist/{plugins/plugin.js → api/extension/mode.js} +0 -0
  515. /package/dist/api/{display-api.d.ts → impl/adapters.d.ts} +0 -0
  516. /package/dist/{display/columnar/source.d.ts → api/impl/contexts.d.ts} +0 -0
  517. /package/dist/{display/columnar/table.d.ts → api/impl/create-draw.d.ts} +0 -0
  518. /package/dist/{display/interaction.d.ts → api/impl/datasets.d.ts} +0 -0
  519. /package/dist/{display/manager.d.ts → api/impl/destroy-guard.d.ts} +0 -0
  520. /package/dist/{display/packed-rtree.d.ts → api/impl/document.d.ts} +0 -0
  521. /package/dist/{display/partition.d.ts → api/impl/drawing.d.ts} +0 -0
  522. /package/dist/{display/provider.d.ts → api/impl/engine.d.ts} +0 -0
  523. /package/dist/{display/source.d.ts → api/impl/events.d.ts} +0 -0
  524. /package/dist/{display/spatial.d.ts → api/impl/extension-host.d.ts} +0 -0
  525. /package/dist/{display/style.d.ts → api/impl/extensions.d.ts} +0 -0
  526. /package/dist/{display/triangulation.d.ts → api/impl/features.d.ts} +0 -0
  527. /package/dist/{modes/cursor.d.ts → api/impl/geometry/types.d.ts} +0 -0
  528. /package/dist/{plugins/plugin-context.d.ts → api/impl/hidden.d.ts} +0 -0
  529. /package/dist/api/{import-export → impl/import-export}/embedded-file.d.ts +0 -0
  530. /package/dist/api/{import-export → impl/import-export}/own-property.d.ts +0 -0
  531. /package/dist/api/{import-export → impl/import-export}/own-property.js +0 -0
  532. /package/dist/{store/change-merger.d.ts → api/impl/input.d.ts} +0 -0
  533. /package/dist/{store/event-bridge.d.ts → api/impl/layers.d.ts} +0 -0
  534. /package/dist/{display → dataset}/chunk-set.d.ts +0 -0
  535. /package/dist/{display → dataset}/chunk-set.js +0 -0
  536. /package/dist/{display → dataset}/dataset.d.ts +0 -0
  537. /package/dist/{display → dataset}/manager.js +0 -0
  538. /package/dist/{display → dataset}/provider.js +0 -0
  539. /package/dist/{display → dataset}/selection.d.ts +0 -0
  540. /package/dist/{display → dataset}/selection.js +0 -0
@@ -0,0 +1,822 @@
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
+ * @internal
660
+ */
661
+ export function createOptions(engine, options, setExternalEntry) {
662
+ const { context, map, customLayer } = engine;
663
+ let current = runtimePart(options);
664
+ const apply = (patch) => {
665
+ let redraw = false;
666
+ let rebuild = false;
667
+ const next = current;
668
+ if (patch.messages !== undefined) {
669
+ Object.assign(context.messages, resolveMessages(next.messages));
670
+ }
671
+ if (patch.autoName !== undefined) {
672
+ context.autoNameGenerator.configure(toAutoName(next.autoName));
673
+ }
674
+ if (patch.style !== undefined || patch.previewStyle !== undefined) {
675
+ assignInPlace(context.featureStyle, toFeatureStyleConfig(next));
676
+ rebuild = true;
677
+ }
678
+ if (patch.selectionStyle !== undefined) {
679
+ assignInPlace(context.selectionStyle, toSelectionConfig(next));
680
+ assignInPlace(context.renderingConfig.boxSelectionStyle, toBoxSelectionStyle(next));
681
+ rebuild = true;
682
+ }
683
+ if (patch.scaleWithZoom !== undefined)
684
+ context.options.scaleWithZoom = patch.scaleWithZoom;
685
+ const snapping = patch.snapping;
686
+ if (snapping) {
687
+ const { snapService, snapOptions } = context;
688
+ if (snapping.enabled !== undefined)
689
+ snapService.setEnabled(snapping.enabled);
690
+ if (snapping.tolerancePx !== undefined) {
691
+ snapService.setTolerance(snapping.tolerancePx);
692
+ snapOptions.tolerancePx = snapping.tolerancePx;
693
+ }
694
+ if (snapping.disableKey !== undefined) {
695
+ snapService.setDisableKey(snapping.disableKey);
696
+ // The shared vertices read the same key
697
+ snapOptions.disableKey = snapping.disableKey;
698
+ }
699
+ for (const [kind, enabled] of Object.entries(snapping.kinds ?? {})) {
700
+ if (enabled === undefined)
701
+ continue;
702
+ snapService.setKindEnabled(kind, enabled);
703
+ }
704
+ if (snapping.datasets !== undefined)
705
+ snapService.setDatasetsEnabled(snapping.datasets);
706
+ if (snapping.guideStepDegrees !== undefined) {
707
+ snapService.setGuideStep(snapping.guideStepDegrees);
708
+ }
709
+ const look = context.snapIndicator;
710
+ for (const [kind, mark] of Object.entries(snapping.indicator ?? {})) {
711
+ toPoint(look.styles[kind], mark);
712
+ redraw = true;
713
+ }
714
+ if (snapping.guideLine) {
715
+ toStroke(look.guideLine, snapping.guideLine);
716
+ redraw = true;
717
+ }
718
+ }
719
+ if (patch.tracing?.enabled !== undefined)
720
+ context.trace.enabled = patch.tracing.enabled;
721
+ if (patch.topology?.sharedVertexDrag !== undefined) {
722
+ context.topology.sharedVertexDrag = patch.topology.sharedVertexDrag;
723
+ }
724
+ if (patch.clickTolerance !== undefined) {
725
+ context.options.clickTolerance = patch.clickTolerance;
726
+ context.hitTestService.setClickTolerance(patch.clickTolerance);
727
+ }
728
+ if (patch.dragThreshold !== undefined) {
729
+ context.options.dragThreshold = patch.dragThreshold;
730
+ engine.runtime.setDragThreshold(patch.dragThreshold);
731
+ }
732
+ const rendering = patch.rendering;
733
+ if (rendering) {
734
+ if (rendering.renderScale !== undefined) {
735
+ if (context.pixelRatioSource.setScaleFactor(rendering.renderScale))
736
+ redraw = true;
737
+ }
738
+ if (rendering.pixelRatio !== undefined) {
739
+ context.pixelRatio = rendering.pixelRatio;
740
+ if (context.pixelRatioSource.setPixelRatio(rendering.pixelRatio))
741
+ redraw = true;
742
+ }
743
+ if (rendering.cacheGeometry !== undefined) {
744
+ context.renderingConfig.storeRetained = rendering.cacheGeometry;
745
+ rebuild = true;
746
+ }
747
+ if (rendering.timeSlicing !== undefined) {
748
+ engine.runtime.setTimeSlicing(rendering.timeSlicing);
749
+ rebuild = true;
750
+ }
751
+ }
752
+ if (patch.isExternalEntry !== undefined) {
753
+ setExternalEntry(patch.isExternalEntry);
754
+ rebuild = true;
755
+ }
756
+ if (rebuild && 'refresh' in customLayer)
757
+ customLayer.refresh();
758
+ else if (redraw)
759
+ map.triggerRepaint();
760
+ };
761
+ return {
762
+ 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
+ update(patch) {
791
+ checkPatch(patch);
792
+ current = mergeOptions(current, patch);
793
+ apply(patch);
794
+ },
795
+ getStyle() {
796
+ return current.style;
797
+ },
798
+ applyCreation() {
799
+ const scale = current.rendering?.renderScale;
800
+ if (scale !== undefined)
801
+ apply({ rendering: { renderScale: scale } });
802
+ // The look of the snapping indicator is not an option of the engine
803
+ const { indicator, guideLine } = current.snapping ?? {};
804
+ if (indicator || guideLine) {
805
+ apply({
806
+ snapping: { ...(indicator && { indicator }), ...(guideLine && { guideLine }) },
807
+ });
808
+ }
809
+ },
810
+ };
811
+ }
812
+ /** A copy of the options that shares the functions and nothing else */
813
+ function structuredCloneOptions(value) {
814
+ if (Array.isArray(value))
815
+ return value.map(structuredCloneOptions);
816
+ if (!isRecord(value))
817
+ return value;
818
+ const copy = {};
819
+ for (const [key, entry] of Object.entries(value))
820
+ copy[key] = structuredCloneOptions(entry);
821
+ return copy;
822
+ }