@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
@@ -1,5 +1,14 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Incremental update of the coordinate texture of a retained line chunk
5
+ *
6
+ * A vertex drag moves only a few vertices. Rebuilding a line chunk with many vertices every frame
7
+ * would overflow the frame, so the diff of the vertices that moved is queued on the chunk and,
8
+ * right before drawing, only the corresponding texels of the coordinate texture are rewritten
9
+ * (see SDFLineRenderer.patchRetainedBatchCoords).
10
+ */
11
+ import { coordinatesOf } from '../../shared/utils/coordinates.js';
3
12
  import { expandBBox } from './store-retained-bbox.js';
4
13
  /**
5
14
  * Upper limit of the number of vertices that one update may put into the incremental update of
@@ -71,14 +80,14 @@ export function computeLineCoordSlots(features) {
71
80
  let offset = 0;
72
81
  for (const feature of features) {
73
82
  if (feature.type === 'MultiLineString') {
74
- for (const part of feature.coordinates ?? []) {
83
+ for (const part of coordinatesOf(feature) ?? []) {
75
84
  if (!part || part.length < 2)
76
85
  continue;
77
86
  offset += part.length;
78
87
  }
79
88
  continue;
80
89
  }
81
- const coords = feature.coordinates;
90
+ const coords = coordinatesOf(feature);
82
91
  if (!coords || coords.length < 2)
83
92
  continue;
84
93
  if (feature.type === 'LineString' || feature.type === 'Freehand') {
@@ -122,12 +131,12 @@ export function queueCoordPatch(chunk, feature, previous, line) {
122
131
  const slot = chunk.lineOffsets.get(feature.id);
123
132
  if (!slot)
124
133
  return false;
125
- const coords = feature.coordinates;
134
+ const coords = coordinatesOf(feature);
126
135
  // If the vertex count differs from when the index table was built, the positions of the
127
136
  // following features are off as well
128
137
  if (!Array.isArray(coords) || coords.length !== slot.count)
129
138
  return false;
130
- const changed = computeCoordinateDiff(previous.coordinates, coords, MAX_PATCHED_VERTICES);
139
+ const changed = computeCoordinateDiff(coordinatesOf(previous), coords, MAX_PATCHED_VERTICES);
131
140
  if (!changed)
132
141
  return false;
133
142
  // An update where no vertex moved (a change of locked, for example) is not treated as a diff;
@@ -6,7 +6,7 @@
6
6
  * as the layer loop of render.ts.
7
7
  */
8
8
  import type { ProjectionData } from 'maplibre-gl';
9
- import type { CustomFeatureHandler, CustomRendererDrawContext } from '../../extension/index.js';
9
+ import type { FeatureTypeHandler, FrameDrawContext } from '../../extension/index.js';
10
10
  import type { Store } from '../../store/store.js';
11
11
  import type { Feature, Layer } from '../../store/types.js';
12
12
  import { type FeatureCompanionRegistry } from '../feature-companion.js';
@@ -28,9 +28,9 @@ export interface StoreRetainedDrawDeps {
28
28
  /** Immediate-mode draw target that draws the features which cannot be retained */
29
29
  batchManager: StoreImmediateTarget;
30
30
  /** Renderers of the custom feature types (type name → renderer) */
31
- customRenderers: Map<string, CustomFeatureHandler['renderer']>;
31
+ customRenderers: Map<string, FeatureTypeHandler['renderer']>;
32
32
  /** Draw context passed to a custom renderer */
33
- customRendererContext: CustomRendererDrawContext;
33
+ customRendererContext: FrameDrawContext;
34
34
  /** Providers of companion drawing and companion hits (those of this draw instance) */
35
35
  companions: FeatureCompanionRegistry;
36
36
  /**
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
3
  import { isLocallyHidden } from '../../store/local-visibility.js';
4
4
  import { drawFeatureCompanionsInFrame, } from '../feature-companion.js';
5
+ import { customRendererOf } from './store-retained-classify.js';
5
6
  /**
6
7
  * Draws a list of features in immediate mode
7
8
  *
@@ -25,18 +26,12 @@ export function drawFeaturesImmediate(store, featureIds, layer, projectionData,
25
26
  // immediate chunk, so going through here makes the z order in retained mode identical to
26
27
  // immediate mode.
27
28
  drawFeatureCompanionsInFrame(deps.companions, feature, batchManager, projectionData, zoom, layer, customRendererContext, deps.restoreBlendState);
28
- const customRenderer = customRenderers.get(feature.type);
29
+ const customRenderer = customRendererOf(customRenderers, feature);
29
30
  if (customRenderer) {
30
31
  // To keep the draw order (painter's algorithm), the core batch that has accumulated is
31
32
  // flushed first and only then the custom feature is drawn immediately.
32
33
  batchManager.endFrame();
33
- customRenderer.draw({
34
- id: feature.id,
35
- type: feature.type,
36
- coordinates: feature.coordinates,
37
- properties: feature.properties,
38
- style: feature.style,
39
- }, projectionData, zoom, customRendererContext);
34
+ customRenderer.draw(feature, projectionData, zoom, customRendererContext);
40
35
  // Re-establish the blend state that the external renderer may have rewritten
41
36
  deps.restoreBlendState?.();
42
37
  batchManager.beginFrame(projectionData, zoom, layer);
@@ -5,7 +5,7 @@
5
5
  * hidden features (updated in place), the registry of companion drawing and the generations of
6
6
  * the terrain. They are checked once per frame, and any change discards the whole cache.
7
7
  */
8
- import type { Layer, StateChanges } from '../../store/types.js';
8
+ import type { Layer, StoreChange } from '../../store/types.js';
9
9
  import type { FeatureCompanionRegistry } from '../feature-companion.js';
10
10
  import type { TerrainContext } from '../terrain/context.js';
11
11
  /**
@@ -93,4 +93,4 @@ export declare function isOpacityOnlyLayerChange(previous: Layer, layer: Layer):
93
93
  * Whether a change of the layers consists only of opacity updates (nothing created, deleted or
94
94
  * reordered, and every update is {@link isOpacityOnlyLayerChange})
95
95
  */
96
- export declare function isOpacityOnlyLayersChange(layers: NonNullable<StateChanges['layers']>): boolean;
96
+ export declare function isOpacityOnlyLayersChange(layers: NonNullable<StoreChange['layers']>): boolean;
@@ -38,7 +38,7 @@
38
38
  */
39
39
  import type { ProjectionData } from 'maplibre-gl';
40
40
  import type { Store } from '../../store/store.js';
41
- import type { BoundingBox, Layer, StateChanges } from '../../store/types.js';
41
+ import type { BoundingBox, Layer, StoreChange } from '../../store/types.js';
42
42
  import type { FeatureCompanionRegistry } from '../feature-companion.js';
43
43
  import type { RetainedRendererSet } from '../renderers/retained.js';
44
44
  import { TerrainContext } from '../terrain/context.js';
@@ -116,7 +116,7 @@ export declare class StoreRetainedCache {
116
116
  * The decisions are conservative (rebuilding too much still renders correctly; rebuilding too
117
117
  * little leaves a stale picture).
118
118
  */
119
- applyChanges(changes: StateChanges): void;
119
+ applyChanges(changes: StoreChange): void;
120
120
  /**
121
121
  * Discards the cache of every layer (the GPU resources are released as well)
122
122
  */
@@ -96,7 +96,7 @@ export class StoreRetainedCache {
96
96
  this.frame++;
97
97
  this.featuresByLayer = null;
98
98
  // Every watch is advanced on every frame (no short circuit), so each keeps its snapshot
99
- const hiddenChanged = this.watch.locallyHiddenChanged(this.store.getLocallyHidden());
99
+ const hiddenChanged = this.watch.locallyHiddenChanged(this.store.listHidden());
100
100
  const companionsChanged = this.watch.companionsChanged(companions);
101
101
  const terrainChanged = this.watch.terrainChanged(this.terrain);
102
102
  if (hiddenChanged || companionsChanged || terrainChanged)
@@ -1,6 +1,7 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
3
  import { generateCirclePolygon } from '../../shared/math/index.js';
4
+ import { coordinatesOf } from '../../shared/utils/coordinates.js';
4
5
  import { getCircleRadius, getCreatedZoom } from '../../shared/utils/property.js';
5
6
  import { densifyPathForGlobe } from '../globe-subdivision.js';
6
7
  import { TerrainContext } from '../terrain/context.js';
@@ -371,7 +372,7 @@ export class BatchManager {
371
372
  }
372
373
  // === Point processing ===
373
374
  processPoint(feature) {
374
- this.processPointCoord(feature, feature.coordinates);
375
+ this.processPointCoord(feature, coordinatesOf(feature));
375
376
  }
376
377
  /**
377
378
  * Add a MultiPoint to the point batch, part by part
@@ -380,7 +381,7 @@ export class BatchManager {
380
381
  * feature, so it is shared across all parts.
381
382
  */
382
383
  processMultiPoint(feature) {
383
- const parts = feature.coordinates;
384
+ const parts = coordinatesOf(feature);
384
385
  for (const coord of parts) {
385
386
  this.processPointCoord(feature, coord);
386
387
  }
@@ -440,7 +441,7 @@ export class BatchManager {
440
441
  }
441
442
  // === LineString processing ===
442
443
  processLineString(feature) {
443
- this.processLineCoords(feature, feature.coordinates);
444
+ this.processLineCoords(feature, coordinatesOf(feature));
444
445
  }
445
446
  /**
446
447
  * Add a MultiLineString to the line batch, part by part
@@ -448,7 +449,7 @@ export class BatchManager {
448
449
  * The coordinates are `Coordinate[][]` (a part = one polyline).
449
450
  */
450
451
  processMultiLineString(feature) {
451
- const parts = feature.coordinates;
452
+ const parts = coordinatesOf(feature);
452
453
  for (const coords of parts) {
453
454
  if (coords.length < 2)
454
455
  continue;
@@ -534,7 +535,7 @@ export class BatchManager {
534
535
  }
535
536
  // === Polygon processing ===
536
537
  processPolygon(feature) {
537
- const rings = feature.coordinates;
538
+ const rings = coordinatesOf(feature);
538
539
  const outerRing = rings[0];
539
540
  if (!outerRing || outerRing.length < 3)
540
541
  return;
@@ -548,7 +549,7 @@ export class BatchManager {
548
549
  * The key of the earcut cache includes the part index as well.
549
550
  */
550
551
  processMultiPolygon(feature) {
551
- const parts = feature.coordinates;
552
+ const parts = coordinatesOf(feature);
552
553
  for (let partIndex = 0; partIndex < parts.length; partIndex++) {
553
554
  const rings = parts[partIndex];
554
555
  const outerRing = rings?.[0];
@@ -559,7 +560,7 @@ export class BatchManager {
559
560
  }
560
561
  // === Circle processing ===
561
562
  processCircle(feature) {
562
- const center = feature.coordinates;
563
+ const center = coordinatesOf(feature);
563
564
  const radiusMeters = getCircleRadius(feature);
564
565
  if (!radiusMeters || radiusMeters <= 0)
565
566
  return;
@@ -1,7 +1,8 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { toColor } from '../../shared/color.js';
3
4
  import { generateCirclePolygon } from '../../shared/math/index.js';
4
- import { hexToColor } from '../../shared/utils/color.js';
5
+ import { coordinatesOf } from '../../shared/utils/coordinates.js';
5
6
  import { getCircleRadius, getCreatedZoom } from '../../shared/utils/property.js';
6
7
  import { StyleRuleCache } from '../cache/style-rule.js';
7
8
  import { applyRuleColor } from '../style-rule.js';
@@ -87,25 +88,25 @@ export class FeatureDrawer {
87
88
  drawFeature(feature, projectionData, zoom, layer) {
88
89
  const opacity = layerDrawFactors(layer).opacity;
89
90
  if (feature.type === 'Point') {
90
- const coord = feature.coordinates;
91
+ const coord = coordinatesOf(feature);
91
92
  const pointStyle = pointWithOpacity(this.getPointStyle(feature, layer), opacity);
92
93
  this.drawPointShape(coord, pointStyle, zoom, feature.id);
93
94
  }
94
95
  else if (feature.type === 'LineString') {
95
- const coords = feature.coordinates;
96
+ const coords = coordinatesOf(feature);
96
97
  const createdZoom = getCreatedZoom(feature) ?? zoom;
97
98
  const strokeStyle = strokeWithOpacity(this.getLineStringStrokeStyle(feature, layer), opacity);
98
99
  this.drawLineStringStroke(coords, strokeStyle, projectionData, zoom, createdZoom, feature.id);
99
100
  }
100
101
  else if (feature.type === 'Polygon') {
101
- const rings = feature.coordinates;
102
+ const rings = coordinatesOf(feature);
102
103
  const createdZoom = getCreatedZoom(feature) ?? zoom;
103
104
  const { fillColor, strokeStyle } = polygonWithOpacity(this.getPolygonStyles(feature, layer), opacity);
104
105
  this.drawPolygonWithStroke(rings, fillColor, strokeStyle, projectionData, zoom, createdZoom, feature.id);
105
106
  }
106
107
  else if (feature.type === 'MultiPoint') {
107
108
  // Draw a point for each part (the style is shared across the feature)
108
- const parts = feature.coordinates;
109
+ const parts = coordinatesOf(feature);
109
110
  const pointStyle = pointWithOpacity(this.getPointStyle(feature, layer), opacity);
110
111
  for (const coord of parts) {
111
112
  this.drawPointShape(coord, pointStyle, zoom, feature.id);
@@ -113,7 +114,7 @@ export class FeatureDrawer {
113
114
  }
114
115
  else if (feature.type === 'MultiLineString') {
115
116
  // Draw a line for each part
116
- const parts = feature.coordinates;
117
+ const parts = coordinatesOf(feature);
117
118
  const createdZoom = getCreatedZoom(feature) ?? zoom;
118
119
  const strokeStyle = strokeWithOpacity(this.getLineStringStrokeStyle(feature, layer), opacity);
119
120
  for (let i = 0; i < parts.length; i++) {
@@ -122,7 +123,7 @@ export class FeatureDrawer {
122
123
  }
123
124
  else if (feature.type === 'MultiPolygon') {
124
125
  // Draw a hole-aware polygon for each part
125
- const parts = feature.coordinates;
126
+ const parts = coordinatesOf(feature);
126
127
  const createdZoom = getCreatedZoom(feature) ?? zoom;
127
128
  const { fillColor, strokeStyle } = polygonWithOpacity(this.getPolygonStyles(feature, layer), opacity);
128
129
  for (let i = 0; i < parts.length; i++) {
@@ -130,14 +131,16 @@ export class FeatureDrawer {
130
131
  }
131
132
  }
132
133
  else if (feature.type === 'Image') {
133
- this.imageRenderer.draw(feature, projectionData, zoom, () => this.map.triggerRepaint(), opacity);
134
+ // An image without an opacity of its own takes the one of the instance
135
+ const imageOpacity = feature.style.imageOpacity === undefined ? (this.featureStyle.image?.opacity ?? 1) : 1;
136
+ this.imageRenderer.draw(feature, projectionData, zoom, () => this.map.triggerRepaint(), opacity * imageOpacity);
134
137
  }
135
138
  else if (feature.type === 'Circle') {
136
139
  this.drawCircle(feature, projectionData, zoom, layer, opacity);
137
140
  }
138
141
  else if (feature.type === 'Freehand') {
139
142
  // Freehand uses the same rendering logic as LineString
140
- const coords = feature.coordinates;
143
+ const coords = coordinatesOf(feature);
141
144
  const createdZoom = getCreatedZoom(feature) ?? zoom;
142
145
  const strokeStyle = strokeWithOpacity(this.getLineStringStrokeStyle(feature, layer), opacity);
143
146
  this.drawLineStringStroke(coords, strokeStyle, projectionData, zoom, createdZoom, feature.id);
@@ -185,7 +188,7 @@ export class FeatureDrawer {
185
188
  // Apply strokeOpacity when it is specified, even if strokeColor is not set
186
189
  // strokeOpacity is set directly rather than multiplied into the default alpha value
187
190
  const color = style.strokeColor
188
- ? hexToColor(style.strokeColor, style.strokeOpacity ?? 1)
191
+ ? toColor(style.strokeColor, style.strokeOpacity ?? 1)
189
192
  : style.strokeOpacity !== undefined
190
193
  ? [defaultStyle.color[0], defaultStyle.color[1], defaultStyle.color[2], style.strokeOpacity]
191
194
  : defaultStyle.color;
@@ -208,8 +211,11 @@ export class FeatureDrawer {
208
211
  * @param layer The layer it belongs to (used to evaluate style rules; no rules when omitted)
209
212
  */
210
213
  getPolygonStyles(feature, layer) {
211
- const defaultFillColor = this.featureStyle.polygon.fill.color;
212
- const defaultStrokeStyle = this.featureStyle.polygon.stroke;
214
+ const look = feature?.type === 'Circle' && this.featureStyle.circle
215
+ ? this.featureStyle.circle
216
+ : this.featureStyle.polygon;
217
+ const defaultFillColor = look.fill.color;
218
+ const defaultStrokeStyle = look.stroke;
213
219
  const style = this.resolveStyle(feature, layer, 'fill');
214
220
  if (!style) {
215
221
  return { fillColor: defaultFillColor, strokeStyle: defaultStrokeStyle };
@@ -220,14 +226,14 @@ export class FeatureDrawer {
220
226
  // So that a feature with only fillColor specified does not become opaque (alpha 1),
221
227
  // it follows the alpha component of the default color rather than a hardcoded 1.
222
228
  const fillColor = style.fillColor
223
- ? hexToColor(style.fillColor, style.fillOpacity ?? defaultFillColor[3])
229
+ ? toColor(style.fillColor, style.fillOpacity ?? defaultFillColor[3])
224
230
  : style.fillOpacity !== undefined
225
231
  ? [defaultFillColor[0], defaultFillColor[1], defaultFillColor[2], style.fillOpacity]
226
232
  : defaultFillColor;
227
233
  // Apply strokeOpacity when it is specified, even if strokeColor is not set
228
234
  // strokeOpacity is set directly rather than multiplied into the default alpha value
229
235
  const strokeColor = style.strokeColor
230
- ? hexToColor(style.strokeColor, style.strokeOpacity ?? 1)
236
+ ? toColor(style.strokeColor, style.strokeOpacity ?? 1)
231
237
  : style.strokeOpacity !== undefined
232
238
  ? [
233
239
  defaultStrokeStyle.color[0],
@@ -292,7 +298,7 @@ export class FeatureDrawer {
292
298
  * Draw a Circle
293
299
  */
294
300
  drawCircle(feature, projectionData, zoom, layer, opacity = 1) {
295
- const center = feature.coordinates;
301
+ const center = coordinatesOf(feature);
296
302
  const radiusMeters = getCircleRadius(feature);
297
303
  if (!radiusMeters || radiusMeters <= 0)
298
304
  return;
@@ -1,20 +1,10 @@
1
1
  // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
2
  // SPDX-License-Identifier: AGPL-3.0-only
3
3
  import { getMetersPerPixel, metersToDegreesLat, metersToDegreesLng, } from '../../shared/math/index.js';
4
+ import { coordinatesOf } from '../../shared/utils/coordinates.js';
4
5
  import { getTileSize } from '../../shared/utils/map.js';
5
6
  import { getImageProperties } from '../../shared/utils/property.js';
6
7
  import { computeQuadVertices } from '../shaders/quad.js';
7
- /**
8
- * The default image style
9
- * width/height: 0 = use the original size
10
- */
11
- const DEFAULT_IMAGE_STYLE = {
12
- width: 0,
13
- height: 0,
14
- rotation: 0,
15
- opacity: 1.0,
16
- imageOpacity: 1,
17
- };
18
8
  /**
19
9
  * ImageRenderer
20
10
  *
@@ -99,9 +89,8 @@ export class ImageRenderer {
99
89
  // its file), so the feature is drawn without its image and nothing is logged.
100
90
  if (!fileData)
101
91
  return;
102
- const coord = feature.coordinates;
92
+ const coord = coordinatesOf(feature);
103
93
  const latitude = coord[1];
104
- const style = this.getImageStyle(feature.style);
105
94
  // The texture is keyed by the dataURL. While the image is decoding nothing is drawn; the
106
95
  // decode (shared per dataURL) requests a redraw when it finishes, and that frame uploads it
107
96
  const imageFileId = properties.imageFileId;
@@ -117,12 +106,9 @@ export class ImageRenderer {
117
106
  this.noteMissingImage(feature.id, src);
118
107
  return;
119
108
  }
120
- // Determine the size (use the size stored in ImageProperties)
121
- const imageWidth = properties.imageWidth || textureInfo.width;
122
- const imageHeight = properties.imageHeight || textureInfo.height;
123
- // Use the size specified by the style, or the original size
124
- const displayWidth = style.width || imageWidth;
125
- const displayHeight = style.height || imageHeight;
109
+ // The size in pixels at the created zoom: the size of the feature, or else of the image
110
+ const displayWidth = properties.imageWidth || textureInfo.width;
111
+ const displayHeight = properties.imageHeight || textureInfo.height;
126
112
  // Scale relative to how it is displayed at createdZoom
127
113
  // At createdZoom the image is displayed at its original pixel size
128
114
  const createdZoom = properties.createdZoom || zoom;
@@ -136,16 +122,13 @@ export class ImageRenderer {
136
122
  const widthDeg = metersToDegreesLng(widthMeters, latitude);
137
123
  const heightDeg = metersToDegreesLat(heightMeters);
138
124
  // Rotation angle (degrees -> radians)
139
- const rotationRad = (((style.rotation || 0) + (properties.rotation || 0)) * Math.PI) / 180;
125
+ const rotationRad = ((properties.rotation || 0) * Math.PI) / 180;
140
126
  // Compute the quad vertices
141
127
  const vertices = computeQuadVertices(coord[0], coord[1], widthDeg, heightDeg, rotationRad);
142
- // Draw (imageOpacity takes precedence; otherwise opacity is used)
143
- const opacity = (style.imageOpacity ?? style.opacity ?? 1.0) * opacityFactor;
128
+ // Draw
129
+ const opacity = (feature.style.imageOpacity ?? 1.0) * opacityFactor;
144
130
  this.quadShader.draw(vertices, textureInfo.texture, opacity, projectionData, zoom);
145
131
  }
146
- /**
147
- * Merge the image style
148
- */
149
132
  /**
150
133
  * Records a feature whose image is not drawn: reports it at once when the image has failed,
151
134
  * otherwise waits for the decode (the cache tells only the caller that started it)
@@ -177,12 +160,6 @@ export class ImageRenderer {
177
160
  this.reportedFailures.set(featureId, src);
178
161
  this.onError?.(featureId, error);
179
162
  }
180
- getImageStyle(style) {
181
- return {
182
- ...DEFAULT_IMAGE_STYLE,
183
- ...style,
184
- };
185
- }
186
163
  /**
187
164
  * Compute the bounding box of an image (in degrees)
188
165
  *
@@ -196,14 +173,11 @@ export class ImageRenderer {
196
173
  const properties = getImageProperties(feature);
197
174
  if (!properties.imageFileId)
198
175
  return null;
199
- const coord = feature.coordinates;
176
+ const coord = coordinatesOf(feature);
200
177
  const latitude = coord[1];
201
- const style = this.getImageStyle(feature.style);
202
- // Determine the size
203
- const imageWidth = properties.imageWidth || style.width;
204
- const imageHeight = properties.imageHeight || style.height;
205
- const displayWidth = style.width || imageWidth;
206
- const displayHeight = style.height || imageHeight;
178
+ // The size in pixels at the created zoom
179
+ const displayWidth = properties.imageWidth;
180
+ const displayHeight = properties.imageHeight;
207
181
  // Scale relative to how it is displayed at createdZoom
208
182
  const createdZoom = properties.createdZoom || zoom;
209
183
  const scale = properties.scale || 1;
@@ -216,7 +190,7 @@ export class ImageRenderer {
216
190
  const widthDeg = metersToDegreesLng(widthMeters, latitude);
217
191
  const heightDeg = metersToDegreesLat(heightMeters);
218
192
  // Rotation angle
219
- const rotationRad = (((style.rotation || 0) + (properties.rotation || 0)) * Math.PI) / 180;
193
+ const rotationRad = ((properties.rotation || 0) * Math.PI) / 180;
220
194
  // Compute the quad vertices
221
195
  const vertices = computeQuadVertices(coord[0], coord[1], widthDeg, heightDeg, rotationRad);
222
196
  // Compute the bounding box
@@ -6,12 +6,12 @@
6
6
  */
7
7
  import type { Color, LineStyle } from '../../../shared/types/style.js';
8
8
  export type { Color, LineStyle };
9
- /** The style of a line drawn by {@link SDFLineRenderer}. */
9
+ /** The style of a line drawn by the shared line renderer. */
10
10
  export interface SDFStrokeStyle {
11
11
  /** The line width in CSS px (at `createdZoom` when the options give one) */
12
12
  width: number;
13
13
  /** The color as `[r, g, b, a]`, each 0..1 */
14
- color: Color;
14
+ color: [number, number, number, number];
15
15
  /** The opacity, 0..1, multiplied into the color */
16
16
  opacity: number;
17
17
  /** Solid, dashed or dotted */
@@ -27,7 +27,7 @@ export interface SDFStrokeStyle {
27
27
  * zoom and the latitude.
28
28
  */
29
29
  export type WidthUnit = 'pixels' | 'meters';
30
- /** The options of one {@link SDFLineRenderer.draw} call. */
30
+ /** The options of one `draw` call of the shared line renderer. */
31
31
  export interface SDFStrokeOptions {
32
32
  /** The unit of the width. The renderer draws `width` in CSS px */
33
33
  widthUnit: WidthUnit;
@@ -141,7 +141,9 @@ export class SDFLineRenderer {
141
141
  this.terrain = terrain;
142
142
  this.uniforms = new LineUniforms(gl);
143
143
  this.immCoordTexture = new ImmediateCoordTexture(gl);
144
- this.projectionUniformManager = new ProjectionUniformManager(gl, { surface: true, terrain });
144
+ this.projectionUniformManager = new ProjectionUniformManager(gl, {
145
+ surface: true,
146
+ }).useTerrainState(terrain);
145
147
  this.initBuffers();
146
148
  }
147
149
  /**
@@ -17,7 +17,7 @@
17
17
  * Billboards are not drawn in a single place. Both the instanced billboard (point-instance) and
18
18
  * the per-point shapes (point-shape: triangle, star, icon, and the degenerate path for the
19
19
  * default circle) draw billboards. Wrapping only the instanced side leaves hand-drawn points as
20
- * half circles. A hand-drawn Point may be taken over by a registered CustomFeatureRenderer,
20
+ * half circles. A hand-drawn Point may be taken over by a registered FeatureTypeRenderer,
21
21
  * and then never goes through the instanced path at all. That is why this function is shared
22
22
  * by every renderer that draws billboards. SDF glyphs laid flat on the map plane (text that is
23
23
  * not painted into a ground quad) go through here for the same reason.
@@ -474,7 +474,7 @@ void main() {
474
474
  opacity: gl.getUniformLocation(program, 'u_opacity'),
475
475
  shape: gl.getUniformLocation(program, 'u_shape'),
476
476
  };
477
- const projection = new ProjectionUniformManager(gl, { terrain: this.terrain });
477
+ const projection = new ProjectionUniformManager(gl).useTerrainState(this.terrain);
478
478
  projection.getLocations(program);
479
479
  const state = { locs, memo: createPointMemo(), projection };
480
480
  this.programStates.set(program, state);
@@ -236,7 +236,7 @@ export class PointShapeRenderer {
236
236
  this.gl = gl;
237
237
  this.pixelRatio = pixelRatio;
238
238
  this.terrain = terrain;
239
- this.projectionUniformManager = new ProjectionUniformManager(gl, { terrain });
239
+ this.projectionUniformManager = new ProjectionUniformManager(gl).useTerrainState(terrain);
240
240
  this.bufferCache = new BufferCache(gl);
241
241
  }
242
242
  /**
@@ -385,7 +385,7 @@ void main() {
385
385
  gl.uniform1f(this.anchorElevationLoc, elevationMeters ?? anchorElevationMeters(this.terrain, lng, lat));
386
386
  }
387
387
  // Billboards are drawn without the depth test (see the note in billboard-depth.ts). A
388
- // hand-drawn Point can arrive here through a CustomFeatureRenderer, so wrapping only the
388
+ // hand-drawn Point can arrive here through a FeatureTypeRenderer, so wrapping only the
389
389
  // instanced side would leave the points of this path as half circles.
390
390
  drawBillboardsWithoutDepth(gl, () => {
391
391
  // Draw the fill
@@ -9,7 +9,7 @@
9
9
  * datasets. The shape in particular decides which run and which batch a point
10
10
  * goes on, so resolving it anywhere else would split the z-order of the paths.
11
11
  */
12
- import { hexToColor } from '../../../shared/utils/color.js';
12
+ import { toColor } from '../../../shared/color.js';
13
13
  /** The shapes a feature may name (`'icon'` belongs to the defaults of an extension) */
14
14
  const FEATURE_POINT_SHAPES = new Set(['circle', 'square', 'triangle', 'star']);
15
15
  /**
@@ -22,12 +22,30 @@ function featurePointShape(style) {
22
22
  const shape = style.pointShape;
23
23
  return shape !== undefined && FEATURE_POINT_SHAPES.has(shape) ? shape : undefined;
24
24
  }
25
+ /**
26
+ * The opacity of the marker a feature names, from 0 to 1 (1 when it names none or a value
27
+ * outside the range)
28
+ */
29
+ function featurePointOpacity(style) {
30
+ const opacity = style.pointOpacity;
31
+ return typeof opacity === 'number' && opacity >= 0 && opacity <= 1 ? opacity : 1;
32
+ }
33
+ /**
34
+ * The width of the outline of the marker a feature names, or undefined when it names none or
35
+ * a value that is not a finite number of 0 or more
36
+ */
37
+ function featurePointStrokeWidth(style) {
38
+ const width = style.pointStrokeWidth;
39
+ return typeof width === 'number' && Number.isFinite(width) && width >= 0 ? width : undefined;
40
+ }
25
41
  /**
26
42
  * Merges the style of a point feature (already carrying the rule color) into the default
27
43
  *
28
44
  * The keys of the feature win key by key: `pointColor` becomes the fill, `pointRadius` the
29
- * size (a diameter), `pointShape` the shape. A key left unset (or a shape that is not one of
30
- * the four a feature may name) keeps the default.
45
+ * size (a diameter), `pointShape` the shape, `pointStrokeColor` and `pointStrokeWidth` the
46
+ * outline. `pointOpacity` is multiplied into the opacity of the fill and of the outline of the
47
+ * marker. A key left unset (or a shape that is not one of the four a feature may name, an
48
+ * opacity outside 0 to 1, or a negative width) keeps the default.
31
49
  *
32
50
  * @param style The style of the feature (undefined when it has none)
33
51
  * @param defaults The point style of the `style` option of the instance
@@ -37,10 +55,36 @@ function featurePointShape(style) {
37
55
  export function resolvePointStyle(style, defaults) {
38
56
  if (!style)
39
57
  return defaults;
58
+ const opacity = featurePointOpacity(style);
40
59
  return {
41
60
  ...defaults,
42
61
  shape: featurePointShape(style) ?? defaults.shape,
43
- fillColor: style.pointColor ? hexToColor(style.pointColor, 1) : defaults.fillColor,
62
+ fillColor: style.pointColor ? toColor(style.pointColor, 1) : defaults.fillColor,
44
63
  size: style.pointRadius ? style.pointRadius * 2 : defaults.size,
64
+ fillOpacity: defaults.fillOpacity * opacity,
65
+ strokeColor: style.pointStrokeColor ? toColor(style.pointStrokeColor, 1) : defaults.strokeColor,
66
+ strokeWidth: featurePointStrokeWidth(style) ?? defaults.strokeWidth,
67
+ strokeOpacity: defaults.strokeOpacity * opacity,
45
68
  };
46
69
  }
70
+ /**
71
+ * How far the marker of a point reaches from its position, in CSS pixels: the radius the
72
+ * marker is drawn with plus its outline when the outline is drawn
73
+ *
74
+ * It reads the keys `resolvePointStyle` reads for the size and the outline, without building
75
+ * the merged style, so the hit test can ask it of every point on every move of the pointer.
76
+ *
77
+ * @param style The style of the feature (undefined when it has none)
78
+ * @param defaults The point style of the `style` option of the instance
79
+ *
80
+ * @internal
81
+ */
82
+ export function pointMarkerReachPx(style, defaults) {
83
+ const radius = style?.pointRadius ? style.pointRadius : defaults.size / 2;
84
+ const strokeOpacity = defaults.strokeOpacity * (style ? featurePointOpacity(style) : 1);
85
+ const stroke = strokeOpacity > 0
86
+ ? ((style ? featurePointStrokeWidth(style) : undefined) ?? defaults.strokeWidth)
87
+ : 0;
88
+ const reach = radius + stroke;
89
+ return Number.isFinite(reach) && reach > 0 ? reach : 0;
90
+ }
@@ -92,8 +92,7 @@ export class PolygonBatchRenderer {
92
92
  this.earcutCache = scope.earcut ?? new EarcutCache();
93
93
  this.projectionUniformManager = new ProjectionUniformManager(gl, {
94
94
  surface: true,
95
- terrain: this.terrain,
96
- });
95
+ }).useTerrainState(this.terrain);
97
96
  this.vertexBuffer = gl.createBuffer();
98
97
  this.indexBuffer = gl.createBuffer();
99
98
  this.vao = gl.createVertexArray();
@@ -83,7 +83,9 @@ export class FillShaderManager {
83
83
  value: null
84
84
  });
85
85
  this.gl = gl;
86
- this.projectionUniformManager = new ProjectionUniformManager(gl, { surface: true, terrain });
86
+ this.projectionUniformManager = new ProjectionUniformManager(gl, {
87
+ surface: true,
88
+ }).useTerrainState(terrain);
87
89
  this.vertexBuffer = gl.createBuffer();
88
90
  this.indexBuffer = gl.createBuffer();
89
91
  this.vao = gl.createVertexArray();
@@ -210,8 +210,7 @@ export class SDFPolygonRenderer {
210
210
  this.earcutCache = scope.earcut ?? new EarcutCache();
211
211
  this.projectionUniformManager = new ProjectionUniformManager(gl, {
212
212
  surface: true,
213
- terrain: this.terrain,
214
- });
213
+ }).useTerrainState(this.terrain);
215
214
  this.vertexBuffer = gl.createBuffer();
216
215
  this.indexBuffer = gl.createBuffer();
217
216
  this.vao = gl.createVertexArray();
@@ -550,7 +549,7 @@ void main() {
550
549
  * the cache used by the drawing of the Store must not be polluted with the features
551
550
  * of datasets). However, when options.triangulator is passed, both the caching and the
552
551
  * time slicing of the triangulation become its responsibility
553
- * (display/triangulation.ts).
552
+ * (dataset/triangulation.ts).
554
553
  *
555
554
  * @returns The built batch. null when the shader is not initialized or there are no
556
555
  * vertices