@sakuzu/maplibre-gl-draw 1.0.0 → 2.1.0

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