@sakuzu/maplibre-gl-draw 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +661 -0
  3. package/README.ja.md +248 -0
  4. package/README.md +255 -0
  5. package/THIRD_PARTY_NOTICES.md +275 -0
  6. package/dist/api/api.d.ts +1259 -0
  7. package/dist/api/api.js +86 -0
  8. package/dist/api/context.d.ts +173 -0
  9. package/dist/api/context.js +193 -0
  10. package/dist/api/display-api.d.ts +1 -0
  11. package/dist/api/display-api.js +23 -0
  12. package/dist/api/event-api.d.ts +13 -0
  13. package/dist/api/event-api.js +17 -0
  14. package/dist/api/extension-api.d.ts +46 -0
  15. package/dist/api/extension-api.js +85 -0
  16. package/dist/api/feature-api.d.ts +11 -0
  17. package/dist/api/feature-api.js +101 -0
  18. package/dist/api/geometry/apply.d.ts +51 -0
  19. package/dist/api/geometry/apply.js +114 -0
  20. package/dist/api/geometry/boolean.d.ts +28 -0
  21. package/dist/api/geometry/boolean.js +65 -0
  22. package/dist/api/geometry/buffer.d.ts +11 -0
  23. package/dist/api/geometry/buffer.js +105 -0
  24. package/dist/api/geometry/split.d.ts +16 -0
  25. package/dist/api/geometry/split.js +75 -0
  26. package/dist/api/geometry/targets.d.ts +76 -0
  27. package/dist/api/geometry/targets.js +158 -0
  28. package/dist/api/geometry/types.d.ts +31 -0
  29. package/dist/api/geometry/types.js +3 -0
  30. package/dist/api/geometry-operations.d.ts +162 -0
  31. package/dist/api/geometry-operations.js +94 -0
  32. package/dist/api/group-api.d.ts +10 -0
  33. package/dist/api/group-api.js +78 -0
  34. package/dist/api/import-export/constants.d.ts +29 -0
  35. package/dist/api/import-export/constants.js +40 -0
  36. package/dist/api/import-export/embedded-file.d.ts +13 -0
  37. package/dist/api/import-export/embedded-file.js +31 -0
  38. package/dist/api/import-export/file-name.d.ts +10 -0
  39. package/dist/api/import-export/file-name.js +20 -0
  40. package/dist/api/import-export/format-detection.d.ts +12 -0
  41. package/dist/api/import-export/format-detection.js +29 -0
  42. package/dist/api/import-export/geojson-export.d.ts +19 -0
  43. package/dist/api/import-export/geojson-export.js +262 -0
  44. package/dist/api/import-export/geojson-import.d.ts +34 -0
  45. package/dist/api/import-export/geojson-import.js +538 -0
  46. package/dist/api/import-export/geometry-validation.d.ts +20 -0
  47. package/dist/api/import-export/geometry-validation.js +107 -0
  48. package/dist/api/import-export/image-import.d.ts +12 -0
  49. package/dist/api/import-export/image-import.js +53 -0
  50. package/dist/api/import-export/index.d.ts +9 -0
  51. package/dist/api/import-export/index.js +107 -0
  52. package/dist/api/import-export/native-format.d.ts +15 -0
  53. package/dist/api/import-export/native-format.js +126 -0
  54. package/dist/api/import-export/native-validation.d.ts +28 -0
  55. package/dist/api/import-export/native-validation.js +212 -0
  56. package/dist/api/import-export/own-property.d.ts +10 -0
  57. package/dist/api/import-export/own-property.js +19 -0
  58. package/dist/api/import-export/style-validation.d.ts +27 -0
  59. package/dist/api/import-export/style-validation.js +49 -0
  60. package/dist/api/import-export/types.d.ts +26 -0
  61. package/dist/api/import-export/types.js +3 -0
  62. package/dist/api/index.d.ts +15 -0
  63. package/dist/api/index.js +3 -0
  64. package/dist/api/input-api.d.ts +158 -0
  65. package/dist/api/input-api.js +144 -0
  66. package/dist/api/instance-api.d.ts +38 -0
  67. package/dist/api/instance-api.js +136 -0
  68. package/dist/api/layer-api.d.ts +12 -0
  69. package/dist/api/layer-api.js +62 -0
  70. package/dist/api/selection-api.d.ts +7 -0
  71. package/dist/api/selection-api.js +78 -0
  72. package/dist/api/snapping-api.d.ts +125 -0
  73. package/dist/api/snapping-api.js +50 -0
  74. package/dist/api/topology-api.d.ts +30 -0
  75. package/dist/api/topology-api.js +16 -0
  76. package/dist/api/tracing-api.d.ts +31 -0
  77. package/dist/api/tracing-api.js +16 -0
  78. package/dist/dispatcher/hit-test/box-strategies.d.ts +19 -0
  79. package/dist/dispatcher/hit-test/box-strategies.js +275 -0
  80. package/dist/dispatcher/hit-test/box-strategy.d.ts +59 -0
  81. package/dist/dispatcher/hit-test/box-strategy.js +37 -0
  82. package/dist/dispatcher/hit-test/globe-shape.d.ts +46 -0
  83. package/dist/dispatcher/hit-test/globe-shape.js +70 -0
  84. package/dist/dispatcher/hit-test/index.d.ts +14 -0
  85. package/dist/dispatcher/hit-test/index.js +9 -0
  86. package/dist/dispatcher/hit-test/local-frame.d.ts +77 -0
  87. package/dist/dispatcher/hit-test/local-frame.js +112 -0
  88. package/dist/dispatcher/hit-test/segment-grid.d.ts +32 -0
  89. package/dist/dispatcher/hit-test/segment-grid.js +79 -0
  90. package/dist/dispatcher/hit-test/service.d.ts +120 -0
  91. package/dist/dispatcher/hit-test/service.js +333 -0
  92. package/dist/dispatcher/hit-test/strategies/base.d.ts +136 -0
  93. package/dist/dispatcher/hit-test/strategies/base.js +66 -0
  94. package/dist/dispatcher/hit-test/strategies/circle.d.ts +10 -0
  95. package/dist/dispatcher/hit-test/strategies/circle.js +56 -0
  96. package/dist/dispatcher/hit-test/strategies/image.d.ts +22 -0
  97. package/dist/dispatcher/hit-test/strategies/image.js +115 -0
  98. package/dist/dispatcher/hit-test/strategies/index.d.ts +11 -0
  99. package/dist/dispatcher/hit-test/strategies/index.js +10 -0
  100. package/dist/dispatcher/hit-test/strategies/line.d.ts +17 -0
  101. package/dist/dispatcher/hit-test/strategies/line.js +30 -0
  102. package/dist/dispatcher/hit-test/strategies/multi.d.ts +44 -0
  103. package/dist/dispatcher/hit-test/strategies/multi.js +141 -0
  104. package/dist/dispatcher/hit-test/strategies/point.d.ts +20 -0
  105. package/dist/dispatcher/hit-test/strategies/point.js +29 -0
  106. package/dist/dispatcher/hit-test/strategies/polygon.d.ts +52 -0
  107. package/dist/dispatcher/hit-test/strategies/polygon.js +138 -0
  108. package/dist/dispatcher/hit-test/topmost.d.ts +48 -0
  109. package/dist/dispatcher/hit-test/topmost.js +157 -0
  110. package/dist/dispatcher/hit-test/visibility-lookup.d.ts +23 -0
  111. package/dist/dispatcher/hit-test/visibility-lookup.js +40 -0
  112. package/dist/dispatcher/index.d.ts +15 -0
  113. package/dist/dispatcher/index.js +3 -0
  114. package/dist/dispatcher/input-router.d.ts +1 -0
  115. package/dist/dispatcher/input-router.js +288 -0
  116. package/dist/dispatcher/normalizer.d.ts +1 -0
  117. package/dist/dispatcher/normalizer.js +513 -0
  118. package/dist/dispatcher/types.d.ts +144 -0
  119. package/dist/dispatcher/types.js +15 -0
  120. package/dist/display/chunk-set.d.ts +24 -0
  121. package/dist/display/chunk-set.js +533 -0
  122. package/dist/display/chunk.d.ts +1 -0
  123. package/dist/display/chunk.js +104 -0
  124. package/dist/display/columnar/index.d.ts +12 -0
  125. package/dist/display/columnar/index.js +13 -0
  126. package/dist/display/columnar/prepare.d.ts +42 -0
  127. package/dist/display/columnar/prepare.js +116 -0
  128. package/dist/display/columnar/source.d.ts +1 -0
  129. package/dist/display/columnar/source.js +531 -0
  130. package/dist/display/columnar/table.d.ts +1 -0
  131. package/dist/display/columnar/table.js +471 -0
  132. package/dist/display/columnar/types.d.ts +223 -0
  133. package/dist/display/columnar/types.js +3 -0
  134. package/dist/display/dataset.d.ts +2 -0
  135. package/dist/display/dataset.js +891 -0
  136. package/dist/display/index.d.ts +13 -0
  137. package/dist/display/index.js +3 -0
  138. package/dist/display/interaction.d.ts +1 -0
  139. package/dist/display/interaction.js +90 -0
  140. package/dist/display/manager.d.ts +1 -0
  141. package/dist/display/manager.js +440 -0
  142. package/dist/display/packed-rtree.d.ts +1 -0
  143. package/dist/display/packed-rtree.js +244 -0
  144. package/dist/display/partition.d.ts +1 -0
  145. package/dist/display/partition.js +226 -0
  146. package/dist/display/provider.d.ts +1 -0
  147. package/dist/display/provider.js +342 -0
  148. package/dist/display/retained.d.ts +40 -0
  149. package/dist/display/retained.js +898 -0
  150. package/dist/display/selection.d.ts +13 -0
  151. package/dist/display/selection.js +226 -0
  152. package/dist/display/source.d.ts +1 -0
  153. package/dist/display/source.js +119 -0
  154. package/dist/display/spatial.d.ts +1 -0
  155. package/dist/display/spatial.js +71 -0
  156. package/dist/display/style.d.ts +1 -0
  157. package/dist/display/style.js +126 -0
  158. package/dist/display/thinning.d.ts +65 -0
  159. package/dist/display/thinning.js +910 -0
  160. package/dist/display/triangulation.d.ts +1 -0
  161. package/dist/display/triangulation.js +0 -0
  162. package/dist/display/types.d.ts +561 -0
  163. package/dist/display/types.js +43 -0
  164. package/dist/extension/feature-handler.d.ts +182 -0
  165. package/dist/extension/feature-handler.js +3 -0
  166. package/dist/extension/index.d.ts +9 -0
  167. package/dist/extension/index.js +3 -0
  168. package/dist/extension/renderers.d.ts +208 -0
  169. package/dist/extension/renderers.js +3 -0
  170. package/dist/geometry/angle.d.ts +47 -0
  171. package/dist/geometry/angle.js +44 -0
  172. package/dist/geometry/bbox.d.ts +48 -0
  173. package/dist/geometry/bbox.js +83 -0
  174. package/dist/geometry/boolean.d.ts +162 -0
  175. package/dist/geometry/boolean.js +331 -0
  176. package/dist/geometry/buffer.d.ts +72 -0
  177. package/dist/geometry/buffer.js +218 -0
  178. package/dist/geometry/circle.d.ts +55 -0
  179. package/dist/geometry/circle.js +107 -0
  180. package/dist/geometry/coords.d.ts +97 -0
  181. package/dist/geometry/coords.js +149 -0
  182. package/dist/geometry/distance.d.ts +79 -0
  183. package/dist/geometry/distance.js +111 -0
  184. package/dist/geometry/errors.d.ts +74 -0
  185. package/dist/geometry/errors.js +104 -0
  186. package/dist/geometry/index.d.ts +28 -0
  187. package/dist/geometry/index.js +38 -0
  188. package/dist/geometry/measure.d.ts +81 -0
  189. package/dist/geometry/measure.js +236 -0
  190. package/dist/geometry/predicates.d.ts +62 -0
  191. package/dist/geometry/predicates.js +132 -0
  192. package/dist/geometry/simplify.d.ts +74 -0
  193. package/dist/geometry/simplify.js +159 -0
  194. package/dist/geometry/split.d.ts +68 -0
  195. package/dist/geometry/split.js +430 -0
  196. package/dist/geometry/types.d.ts +95 -0
  197. package/dist/geometry/types.js +3 -0
  198. package/dist/geometry/units.d.ts +35 -0
  199. package/dist/geometry/units.js +41 -0
  200. package/dist/index.d.ts +72 -0
  201. package/dist/index.js +20 -0
  202. package/dist/maplibre-gl-draw.d.ts +47 -0
  203. package/dist/maplibre-gl-draw.js +407 -0
  204. package/dist/messages.d.ts +64 -0
  205. package/dist/messages.js +36 -0
  206. package/dist/modes/cursor.d.ts +1 -0
  207. package/dist/modes/cursor.js +72 -0
  208. package/dist/modes/draw/circle.d.ts +1 -0
  209. package/dist/modes/draw/circle.js +222 -0
  210. package/dist/modes/draw/commit-layer.d.ts +26 -0
  211. package/dist/modes/draw/commit-layer.js +31 -0
  212. package/dist/modes/draw/freehand.d.ts +1 -0
  213. package/dist/modes/draw/freehand.js +264 -0
  214. package/dist/modes/draw/image.d.ts +1 -0
  215. package/dist/modes/draw/image.js +60 -0
  216. package/dist/modes/draw/index.d.ts +9 -0
  217. package/dist/modes/draw/index.js +11 -0
  218. package/dist/modes/draw/line.d.ts +1 -0
  219. package/dist/modes/draw/line.js +363 -0
  220. package/dist/modes/draw/point.d.ts +1 -0
  221. package/dist/modes/draw/point.js +87 -0
  222. package/dist/modes/draw/polygon.d.ts +1 -0
  223. package/dist/modes/draw/polygon.js +378 -0
  224. package/dist/modes/draw/trace-support.d.ts +79 -0
  225. package/dist/modes/draw/trace-support.js +161 -0
  226. package/dist/modes/handler.d.ts +285 -0
  227. package/dist/modes/handler.js +3 -0
  228. package/dist/modes/index.d.ts +7 -0
  229. package/dist/modes/index.js +3 -0
  230. package/dist/modes/manager.d.ts +15 -0
  231. package/dist/modes/manager.js +196 -0
  232. package/dist/modes/select/box-selection.d.ts +52 -0
  233. package/dist/modes/select/box-selection.js +140 -0
  234. package/dist/modes/select/click-handler.d.ts +32 -0
  235. package/dist/modes/select/click-handler.js +166 -0
  236. package/dist/modes/select/cursor-handler.d.ts +15 -0
  237. package/dist/modes/select/cursor-handler.js +59 -0
  238. package/dist/modes/select/drag/auxiliary.d.ts +26 -0
  239. package/dist/modes/select/drag/auxiliary.js +56 -0
  240. package/dist/modes/select/drag/intermediate-writes.d.ts +1 -0
  241. package/dist/modes/select/drag/intermediate-writes.js +171 -0
  242. package/dist/modes/select/drag/move.d.ts +24 -0
  243. package/dist/modes/select/drag/move.js +59 -0
  244. package/dist/modes/select/drag/operation.d.ts +30 -0
  245. package/dist/modes/select/drag/operation.js +18 -0
  246. package/dist/modes/select/drag/radius.d.ts +15 -0
  247. package/dist/modes/select/drag/radius.js +49 -0
  248. package/dist/modes/select/drag/transform.d.ts +17 -0
  249. package/dist/modes/select/drag/transform.js +155 -0
  250. package/dist/modes/select/drag/vertex.d.ts +17 -0
  251. package/dist/modes/select/drag/vertex.js +163 -0
  252. package/dist/modes/select/drag-handler.d.ts +1 -0
  253. package/dist/modes/select/drag-handler.js +254 -0
  254. package/dist/modes/select/hit-helpers.d.ts +40 -0
  255. package/dist/modes/select/hit-helpers.js +51 -0
  256. package/dist/modes/select/mode.d.ts +1 -0
  257. package/dist/modes/select/mode.js +397 -0
  258. package/dist/modes/select/shortcut-handler.d.ts +40 -0
  259. package/dist/modes/select/shortcut-handler.js +128 -0
  260. package/dist/operations/index.d.ts +9 -0
  261. package/dist/operations/index.js +3 -0
  262. package/dist/operations/layer-operations.d.ts +1 -0
  263. package/dist/operations/layer-operations.js +350 -0
  264. package/dist/operations/resize.d.ts +71 -0
  265. package/dist/operations/resize.js +252 -0
  266. package/dist/operations/rotate.d.ts +17 -0
  267. package/dist/operations/rotate.js +166 -0
  268. package/dist/operations/selection-operations.d.ts +20 -0
  269. package/dist/operations/selection-operations.js +159 -0
  270. package/dist/operations/shared-vertex.d.ts +1 -0
  271. package/dist/operations/shared-vertex.js +210 -0
  272. package/dist/operations/trace-graph.d.ts +96 -0
  273. package/dist/operations/trace-graph.js +283 -0
  274. package/dist/operations/vertex.d.ts +1 -0
  275. package/dist/operations/vertex.js +538 -0
  276. package/dist/plugins/index.d.ts +10 -0
  277. package/dist/plugins/index.js +3 -0
  278. package/dist/plugins/mutation-hooks.d.ts +28 -0
  279. package/dist/plugins/mutation-hooks.js +84 -0
  280. package/dist/plugins/plugin-context.d.ts +1 -0
  281. package/dist/plugins/plugin-context.js +367 -0
  282. package/dist/plugins/plugin-manager.d.ts +103 -0
  283. package/dist/plugins/plugin-manager.js +316 -0
  284. package/dist/plugins/plugin.d.ts +529 -0
  285. package/dist/plugins/plugin.js +3 -0
  286. package/dist/shared/config/constants.d.ts +66 -0
  287. package/dist/shared/config/constants.js +60 -0
  288. package/dist/shared/config/feature-style.d.ts +155 -0
  289. package/dist/shared/config/feature-style.js +154 -0
  290. package/dist/shared/config/index.d.ts +17 -0
  291. package/dist/shared/config/index.js +8 -0
  292. package/dist/shared/config/rendering.d.ts +107 -0
  293. package/dist/shared/config/rendering.js +33 -0
  294. package/dist/shared/config/selection-highlight.d.ts +29 -0
  295. package/dist/shared/config/selection-highlight.js +35 -0
  296. package/dist/shared/config/selection.d.ts +273 -0
  297. package/dist/shared/config/selection.js +266 -0
  298. package/dist/shared/config/topology.d.ts +33 -0
  299. package/dist/shared/config/topology.js +17 -0
  300. package/dist/shared/config/trace.d.ts +40 -0
  301. package/dist/shared/config/trace.js +17 -0
  302. package/dist/shared/math/angle.d.ts +21 -0
  303. package/dist/shared/math/angle.js +34 -0
  304. package/dist/shared/math/circle.d.ts +6 -0
  305. package/dist/shared/math/circle.js +10 -0
  306. package/dist/shared/math/constants.d.ts +48 -0
  307. package/dist/shared/math/constants.js +59 -0
  308. package/dist/shared/math/distance.d.ts +78 -0
  309. package/dist/shared/math/distance.js +147 -0
  310. package/dist/shared/math/globe-subdivision.d.ts +62 -0
  311. package/dist/shared/math/globe-subdivision.js +99 -0
  312. package/dist/shared/math/index.d.ts +17 -0
  313. package/dist/shared/math/index.js +21 -0
  314. package/dist/shared/math/intersection.d.ts +63 -0
  315. package/dist/shared/math/intersection.js +236 -0
  316. package/dist/shared/math/longitude.d.ts +20 -0
  317. package/dist/shared/math/longitude.js +31 -0
  318. package/dist/shared/math/mercator-plane.d.ts +27 -0
  319. package/dist/shared/math/mercator-plane.js +26 -0
  320. package/dist/shared/math/obb.d.ts +65 -0
  321. package/dist/shared/math/obb.js +107 -0
  322. package/dist/shared/math/rotation.d.ts +93 -0
  323. package/dist/shared/math/rotation.js +186 -0
  324. package/dist/shared/math/segment-grid.d.ts +69 -0
  325. package/dist/shared/math/segment-grid.js +159 -0
  326. package/dist/shared/math/transform.d.ts +140 -0
  327. package/dist/shared/math/transform.js +189 -0
  328. package/dist/shared/types/events.d.ts +128 -0
  329. package/dist/shared/types/events.js +3 -0
  330. package/dist/shared/types/model.d.ts +950 -0
  331. package/dist/shared/types/model.js +3 -0
  332. package/dist/shared/types/selection-box.d.ts +23 -0
  333. package/dist/shared/types/selection-box.js +3 -0
  334. package/dist/shared/types/style.d.ts +68 -0
  335. package/dist/shared/types/style.js +3 -0
  336. package/dist/shared/utils/color.d.ts +49 -0
  337. package/dist/shared/utils/color.js +180 -0
  338. package/dist/shared/utils/coordinates.d.ts +52 -0
  339. package/dist/shared/utils/coordinates.js +75 -0
  340. package/dist/shared/utils/embedded-image.d.ts +34 -0
  341. package/dist/shared/utils/embedded-image.js +161 -0
  342. package/dist/shared/utils/event-emitter.d.ts +262 -0
  343. package/dist/shared/utils/event-emitter.js +44 -0
  344. package/dist/shared/utils/feature-bbox.d.ts +8 -0
  345. package/dist/shared/utils/feature-bbox.js +207 -0
  346. package/dist/shared/utils/feature-segments.d.ts +23 -0
  347. package/dist/shared/utils/feature-segments.js +179 -0
  348. package/dist/shared/utils/id.d.ts +1 -0
  349. package/dist/shared/utils/id.js +35 -0
  350. package/dist/shared/utils/image.d.ts +34 -0
  351. package/dist/shared/utils/image.js +106 -0
  352. package/dist/shared/utils/index.d.ts +15 -0
  353. package/dist/shared/utils/index.js +24 -0
  354. package/dist/shared/utils/map.d.ts +26 -0
  355. package/dist/shared/utils/map.js +35 -0
  356. package/dist/shared/utils/name-generator.d.ts +197 -0
  357. package/dist/shared/utils/name-generator.js +337 -0
  358. package/dist/shared/utils/pixel-ratio.d.ts +111 -0
  359. package/dist/shared/utils/pixel-ratio.js +85 -0
  360. package/dist/shared/utils/property.d.ts +88 -0
  361. package/dist/shared/utils/property.js +140 -0
  362. package/dist/shared/utils/vertex-ref.d.ts +23 -0
  363. package/dist/shared/utils/vertex-ref.js +20 -0
  364. package/dist/snapping/custom-targets.d.ts +1 -0
  365. package/dist/snapping/custom-targets.js +21 -0
  366. package/dist/snapping/geometry.d.ts +1 -0
  367. package/dist/snapping/geometry.js +61 -0
  368. package/dist/snapping/index.d.ts +14 -0
  369. package/dist/snapping/index.js +4 -0
  370. package/dist/snapping/indicator.d.ts +19 -0
  371. package/dist/snapping/indicator.js +145 -0
  372. package/dist/snapping/providers/display.d.ts +72 -0
  373. package/dist/snapping/providers/display.js +268 -0
  374. package/dist/snapping/providers/guide.d.ts +69 -0
  375. package/dist/snapping/providers/guide.js +187 -0
  376. package/dist/snapping/providers/intersection.d.ts +1 -0
  377. package/dist/snapping/providers/intersection.js +92 -0
  378. package/dist/snapping/providers/shared.d.ts +39 -0
  379. package/dist/snapping/providers/shared.js +146 -0
  380. package/dist/snapping/providers/store.d.ts +1 -0
  381. package/dist/snapping/providers/store.js +132 -0
  382. package/dist/snapping/service.d.ts +1 -0
  383. package/dist/snapping/service.js +272 -0
  384. package/dist/snapping/types.d.ts +267 -0
  385. package/dist/snapping/types.js +66 -0
  386. package/dist/store/change-merger.d.ts +1 -0
  387. package/dist/store/change-merger.js +102 -0
  388. package/dist/store/draw-store.d.ts +1 -0
  389. package/dist/store/draw-store.js +396 -0
  390. package/dist/store/event-bridge.d.ts +1 -0
  391. package/dist/store/event-bridge.js +161 -0
  392. package/dist/store/index.d.ts +12 -0
  393. package/dist/store/index.js +4 -0
  394. package/dist/store/local-visibility.d.ts +21 -0
  395. package/dist/store/local-visibility.js +27 -0
  396. package/dist/store/lock.d.ts +67 -0
  397. package/dist/store/lock.js +54 -0
  398. package/dist/store/memory/change-bus.d.ts +60 -0
  399. package/dist/store/memory/change-bus.js +232 -0
  400. package/dist/store/memory/file-store.d.ts +15 -0
  401. package/dist/store/memory/file-store.js +33 -0
  402. package/dist/store/memory/frozen.d.ts +21 -0
  403. package/dist/store/memory/frozen.js +51 -0
  404. package/dist/store/memory/ui-state.d.ts +51 -0
  405. package/dist/store/memory/ui-state.js +223 -0
  406. package/dist/store/memory.d.ts +26 -0
  407. package/dist/store/memory.js +708 -0
  408. package/dist/store/spatial/index.d.ts +6 -0
  409. package/dist/store/spatial/index.js +4 -0
  410. package/dist/store/spatial/spatial-index.d.ts +90 -0
  411. package/dist/store/spatial/spatial-index.js +148 -0
  412. package/dist/store/spatial/store-spatial-index.d.ts +60 -0
  413. package/dist/store/spatial/store-spatial-index.js +125 -0
  414. package/dist/store/store.d.ts +417 -0
  415. package/dist/store/store.js +3 -0
  416. package/dist/store/types.d.ts +8 -0
  417. package/dist/store/types.js +3 -0
  418. package/dist/store/writable-layer.d.ts +35 -0
  419. package/dist/store/writable-layer.js +20 -0
  420. package/dist/view/cache/buffer.d.ts +28 -0
  421. package/dist/view/cache/buffer.js +176 -0
  422. package/dist/view/cache/earcut.d.ts +1 -0
  423. package/dist/view/cache/earcut.js +122 -0
  424. package/dist/view/cache/style-rule.d.ts +1 -0
  425. package/dist/view/cache/style-rule.js +97 -0
  426. package/dist/view/cache/terrain-fill.d.ts +30 -0
  427. package/dist/view/cache/terrain-fill.js +60 -0
  428. package/dist/view/cache/texture.d.ts +14 -0
  429. package/dist/view/cache/texture.js +292 -0
  430. package/dist/view/coordinator.d.ts +27 -0
  431. package/dist/view/coordinator.js +72 -0
  432. package/dist/view/feature-companion.d.ts +173 -0
  433. package/dist/view/feature-companion.js +108 -0
  434. package/dist/view/globe-subdivision.d.ts +78 -0
  435. package/dist/view/globe-subdivision.js +128 -0
  436. package/dist/view/index.d.ts +47 -0
  437. package/dist/view/index.js +20 -0
  438. package/dist/view/layer/attach.d.ts +20 -0
  439. package/dist/view/layer/attach.js +47 -0
  440. package/dist/view/layer/blend.d.ts +57 -0
  441. package/dist/view/layer/blend.js +14 -0
  442. package/dist/view/layer/custom-layer.d.ts +1 -0
  443. package/dist/view/layer/custom-layer.js +509 -0
  444. package/dist/view/layer/depth-state.d.ts +14 -0
  445. package/dist/view/layer/depth-state.js +44 -0
  446. package/dist/view/layer/display-list.d.ts +1 -0
  447. package/dist/view/layer/display-list.js +111 -0
  448. package/dist/view/layer/drape-planner.d.ts +139 -0
  449. package/dist/view/layer/drape-planner.js +726 -0
  450. package/dist/view/layer/frame-render.d.ts +57 -0
  451. package/dist/view/layer/frame-render.js +209 -0
  452. package/dist/view/layer/frame-state.d.ts +147 -0
  453. package/dist/view/layer/frame-state.js +484 -0
  454. package/dist/view/layer/gl-state.d.ts +77 -0
  455. package/dist/view/layer/gl-state.js +132 -0
  456. package/dist/view/layer/index.d.ts +6 -0
  457. package/dist/view/layer/index.js +5 -0
  458. package/dist/view/layer/render-scope.d.ts +30 -0
  459. package/dist/view/layer/render-scope.js +28 -0
  460. package/dist/view/layer/render.d.ts +87 -0
  461. package/dist/view/layer/render.js +187 -0
  462. package/dist/view/layer/renderers.d.ts +81 -0
  463. package/dist/view/layer/renderers.js +142 -0
  464. package/dist/view/layer/slot-manager.d.ts +26 -0
  465. package/dist/view/layer/slot-manager.js +133 -0
  466. package/dist/view/layer/slots.d.ts +33 -0
  467. package/dist/view/layer/slots.js +50 -0
  468. package/dist/view/layer/store-retained-bbox.d.ts +36 -0
  469. package/dist/view/layer/store-retained-bbox.js +188 -0
  470. package/dist/view/layer/store-retained-chunk.d.ts +97 -0
  471. package/dist/view/layer/store-retained-chunk.js +94 -0
  472. package/dist/view/layer/store-retained-classify.d.ts +34 -0
  473. package/dist/view/layer/store-retained-classify.js +88 -0
  474. package/dist/view/layer/store-retained-collect.d.ts +24 -0
  475. package/dist/view/layer/store-retained-collect.js +121 -0
  476. package/dist/view/layer/store-retained-coord-patch.d.ts +119 -0
  477. package/dist/view/layer/store-retained-coord-patch.js +168 -0
  478. package/dist/view/layer/store-retained-immediate.d.ts +63 -0
  479. package/dist/view/layer/store-retained-immediate.js +49 -0
  480. package/dist/view/layer/store-retained-invalidation.d.ts +96 -0
  481. package/dist/view/layer/store-retained-invalidation.js +192 -0
  482. package/dist/view/layer/store-retained.d.ts +198 -0
  483. package/dist/view/layer/store-retained.js +430 -0
  484. package/dist/view/layer/terrain-resolver.d.ts +1 -0
  485. package/dist/view/layer/terrain-resolver.js +174 -0
  486. package/dist/view/renderers/batch-manager.d.ts +61 -0
  487. package/dist/view/renderers/batch-manager.js +718 -0
  488. package/dist/view/renderers/draw-factors.d.ts +60 -0
  489. package/dist/view/renderers/draw-factors.js +35 -0
  490. package/dist/view/renderers/drawer.d.ts +1 -0
  491. package/dist/view/renderers/drawer.js +346 -0
  492. package/dist/view/renderers/image.d.ts +1 -0
  493. package/dist/view/renderers/image.js +255 -0
  494. package/dist/view/renderers/line/dash.d.ts +31 -0
  495. package/dist/view/renderers/line/dash.js +152 -0
  496. package/dist/view/renderers/line/line-geometry.d.ts +39 -0
  497. package/dist/view/renderers/line/line-geometry.js +460 -0
  498. package/dist/view/renderers/line/line-gl.d.ts +1 -0
  499. package/dist/view/renderers/line/line-gl.js +236 -0
  500. package/dist/view/renderers/line/line-shader.d.ts +1 -0
  501. package/dist/view/renderers/line/line-shader.js +364 -0
  502. package/dist/view/renderers/line/line-types.d.ts +43 -0
  503. package/dist/view/renderers/line/line-types.js +3 -0
  504. package/dist/view/renderers/line/line-uniforms.d.ts +1 -0
  505. package/dist/view/renderers/line/line-uniforms.js +390 -0
  506. package/dist/view/renderers/line/sdf-line.d.ts +92 -0
  507. package/dist/view/renderers/line/sdf-line.js +567 -0
  508. package/dist/view/renderers/point/billboard-depth.d.ts +10 -0
  509. package/dist/view/renderers/point/billboard-depth.js +56 -0
  510. package/dist/view/renderers/point/point-instance.d.ts +124 -0
  511. package/dist/view/renderers/point/point-instance.js +738 -0
  512. package/dist/view/renderers/point/point-sdf.d.ts +58 -0
  513. package/dist/view/renderers/point/point-sdf.js +170 -0
  514. package/dist/view/renderers/point/point-shape.d.ts +99 -0
  515. package/dist/view/renderers/point/point-shape.js +504 -0
  516. package/dist/view/renderers/point/point-style.d.ts +1 -0
  517. package/dist/view/renderers/point/point-style.js +46 -0
  518. package/dist/view/renderers/polygon/batch.d.ts +26 -0
  519. package/dist/view/renderers/polygon/batch.js +336 -0
  520. package/dist/view/renderers/polygon/earcut-input.d.ts +37 -0
  521. package/dist/view/renderers/polygon/earcut-input.js +55 -0
  522. package/dist/view/renderers/polygon/earcut-sliced.d.ts +69 -0
  523. package/dist/view/renderers/polygon/earcut-sliced.js +960 -0
  524. package/dist/view/renderers/polygon/fill.d.ts +74 -0
  525. package/dist/view/renderers/polygon/fill.js +251 -0
  526. package/dist/view/renderers/polygon/sdf-polygon.d.ts +62 -0
  527. package/dist/view/renderers/polygon/sdf-polygon.js +919 -0
  528. package/dist/view/renderers/polygon/terrain-cull.d.ts +3 -0
  529. package/dist/view/renderers/polygon/terrain-cull.js +14 -0
  530. package/dist/view/renderers/polygon/triangulator.d.ts +41 -0
  531. package/dist/view/renderers/polygon/triangulator.js +3 -0
  532. package/dist/view/renderers/retained.d.ts +43 -0
  533. package/dist/view/renderers/retained.js +3 -0
  534. package/dist/view/renderers/stroke.d.ts +121 -0
  535. package/dist/view/renderers/stroke.js +621 -0
  536. package/dist/view/shaders/frame.d.ts +8 -0
  537. package/dist/view/shaders/frame.js +37 -0
  538. package/dist/view/shaders/helpers.d.ts +238 -0
  539. package/dist/view/shaders/helpers.js +611 -0
  540. package/dist/view/shaders/initializer.d.ts +27 -0
  541. package/dist/view/shaders/initializer.js +125 -0
  542. package/dist/view/shaders/projection.d.ts +123 -0
  543. package/dist/view/shaders/projection.js +299 -0
  544. package/dist/view/shaders/quad-grid.d.ts +77 -0
  545. package/dist/view/shaders/quad-grid.js +128 -0
  546. package/dist/view/shaders/quad.d.ts +189 -0
  547. package/dist/view/shaders/quad.js +582 -0
  548. package/dist/view/shaders/retained-origin.d.ts +50 -0
  549. package/dist/view/shaders/retained-origin.js +67 -0
  550. package/dist/view/shaders/terrain-shade.d.ts +23 -0
  551. package/dist/view/shaders/terrain-shade.js +93 -0
  552. package/dist/view/style-rule.d.ts +166 -0
  553. package/dist/view/style-rule.js +300 -0
  554. package/dist/view/terrain/anchor.d.ts +135 -0
  555. package/dist/view/terrain/anchor.js +226 -0
  556. package/dist/view/terrain/context.d.ts +132 -0
  557. package/dist/view/terrain/context.js +437 -0
  558. package/dist/view/terrain/dem-atlas.d.ts +97 -0
  559. package/dist/view/terrain/dem-atlas.js +534 -0
  560. package/dist/view/terrain/detect.d.ts +126 -0
  561. package/dist/view/terrain/detect.js +198 -0
  562. package/dist/view/terrain/drape/bin-store.d.ts +179 -0
  563. package/dist/view/terrain/drape/bin-store.js +529 -0
  564. package/dist/view/terrain/drape/binning.d.ts +259 -0
  565. package/dist/view/terrain/drape/binning.js +604 -0
  566. package/dist/view/terrain/drape/edge-constrain.d.ts +37 -0
  567. package/dist/view/terrain/drape/edge-constrain.js +175 -0
  568. package/dist/view/terrain/drape/geometry.d.ts +95 -0
  569. package/dist/view/terrain/drape/geometry.js +260 -0
  570. package/dist/view/terrain/drape/mesh.d.ts +50 -0
  571. package/dist/view/terrain/drape/mesh.js +86 -0
  572. package/dist/view/terrain/drape/pass.d.ts +122 -0
  573. package/dist/view/terrain/drape/pass.js +379 -0
  574. package/dist/view/terrain/drape/quad-glyphs.d.ts +64 -0
  575. package/dist/view/terrain/drape/quad-glyphs.js +117 -0
  576. package/dist/view/terrain/drape/quad.d.ts +249 -0
  577. package/dist/view/terrain/drape/quad.js +835 -0
  578. package/dist/view/terrain/drape/renderer.d.ts +184 -0
  579. package/dist/view/terrain/drape/renderer.js +706 -0
  580. package/dist/view/terrain/drape/shared.d.ts +80 -0
  581. package/dist/view/terrain/drape/shared.js +173 -0
  582. package/dist/view/terrain/drape/stitch.d.ts +155 -0
  583. package/dist/view/terrain/drape/stitch.js +228 -0
  584. package/dist/view/terrain/ground.d.ts +72 -0
  585. package/dist/view/terrain/ground.js +151 -0
  586. package/dist/view/terrain/metrics.d.ts +180 -0
  587. package/dist/view/terrain/metrics.js +231 -0
  588. package/dist/view/terrain/occlusion.d.ts +11 -0
  589. package/dist/view/terrain/occlusion.js +129 -0
  590. package/dist/view/terrain/polygon.d.ts +86 -0
  591. package/dist/view/terrain/polygon.js +301 -0
  592. package/dist/view/terrain/shade.d.ts +48 -0
  593. package/dist/view/terrain/shade.js +45 -0
  594. package/dist/view/terrain/state.d.ts +99 -0
  595. package/dist/view/terrain/state.js +186 -0
  596. package/dist/view/terrain/tessellation.d.ts +265 -0
  597. package/dist/view/terrain/tessellation.js +924 -0
  598. package/dist/view/terrain/tiling.d.ts +56 -0
  599. package/dist/view/terrain/tiling.js +155 -0
  600. package/dist/view/terrain/upstream-terrain.d.ts +82 -0
  601. package/dist/view/terrain/upstream-terrain.js +116 -0
  602. package/dist/view/ui/auxiliary-handles.d.ts +151 -0
  603. package/dist/view/ui/auxiliary-handles.js +22 -0
  604. package/dist/view/ui/bounds.d.ts +53 -0
  605. package/dist/view/ui/bounds.js +149 -0
  606. package/dist/view/ui/box-selection.d.ts +1 -0
  607. package/dist/view/ui/box-selection.js +83 -0
  608. package/dist/view/ui/handle-test.d.ts +1 -0
  609. package/dist/view/ui/handle-test.js +437 -0
  610. package/dist/view/ui/handle-thinning.d.ts +122 -0
  611. package/dist/view/ui/handle-thinning.js +430 -0
  612. package/dist/view/ui/handles.d.ts +25 -0
  613. package/dist/view/ui/handles.js +673 -0
  614. package/dist/view/ui/helper.d.ts +19 -0
  615. package/dist/view/ui/helper.js +76 -0
  616. package/dist/view/ui/index.d.ts +15 -0
  617. package/dist/view/ui/index.js +15 -0
  618. package/dist/view/ui/selection-scope.d.ts +25 -0
  619. package/dist/view/ui/selection-scope.js +34 -0
  620. package/dist/view/ui/selection-ui/bounding-box.d.ts +44 -0
  621. package/dist/view/ui/selection-ui/bounding-box.js +240 -0
  622. package/dist/view/ui/selection-ui/extension-registry.d.ts +76 -0
  623. package/dist/view/ui/selection-ui/extension-registry.js +78 -0
  624. package/dist/view/ui/selection-ui/index.d.ts +12 -0
  625. package/dist/view/ui/selection-ui/index.js +12 -0
  626. package/dist/view/ui/selection-ui/renderer.d.ts +29 -0
  627. package/dist/view/ui/selection-ui/renderer.js +227 -0
  628. package/dist/view/ui/selection-ui/types.d.ts +55 -0
  629. package/dist/view/ui/selection-ui/types.js +3 -0
  630. package/dist/view/ui/selection-ui-drawer.d.ts +52 -0
  631. package/dist/view/ui/selection-ui-drawer.js +329 -0
  632. package/dist/view/ui/tentative.d.ts +1 -0
  633. package/dist/view/ui/tentative.js +320 -0
  634. package/dist/view/viewport.d.ts +119 -0
  635. package/dist/view/viewport.js +254 -0
  636. package/package.json +113 -0
@@ -0,0 +1,706 @@
1
+ // SPDX-FileCopyrightText: 2026 SAKAIDA Atsushi
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ import { SELECTION_HIGHLIGHT_FILL_OPACITY, SELECTION_HIGHLIGHT_RGB, SELECTION_HIGHLIGHT_STROKE_EXTRA, } from '../../../shared/config/selection-highlight.js';
4
+ import { createProgram } from '../../shaders/helpers.js';
5
+ import { DRAPE_SELECTION_TEXEL, DRAPE_STYLE_TEXELS } from './bin-store.js';
6
+ import { applyEdgeConstrainUniforms, EDGE_CONSTRAIN_GLSL, EDGE_CONSTRAIN_UNIFORMS, EDGE_UNITS, } from './edge-constrain.js';
7
+ import { createTerrainMeshBuffers, disposeTerrainMeshBuffers, TILE_EXTENT, } from './mesh.js';
8
+ import { applyDrapeProjectionUniforms, applyDrapeTerrainUniforms, DRAPE_PROJECTION_UNIFORMS, DRAPE_TERRAIN_UNIFORMS, TERRAIN_SAMPLE_GLSL, TERRAIN_SHADE_GLSL, } from './shared.js';
9
+ export { EDGE_UNITS };
10
+ /**
11
+ * Width of the data textures (texels)
12
+ *
13
+ * The maximum texture dimension WebGL2 is guaranteed to provide is 2048. The wider
14
+ * it is taken, the fewer rows the same number of edges fits into, and the better
15
+ * the mechanism that transfers only the increment works.
16
+ */
17
+ const DATA_TEX_WIDTH = 2048;
18
+ /** Texture units */
19
+ const UNIT_TERRAIN = 0;
20
+ const UNIT_EDGE = 1;
21
+ const UNIT_RUN = 2;
22
+ const UNIT_CELL = 3;
23
+ const UNIT_STYLE = 4;
24
+ /**
25
+ * Upper limit on the sources of the factors
26
+ *
27
+ * 0 = neutral (factor 1), then the datasets, then the Store layers
28
+ * (their opacity; see `drapeLayerSource` in pass.ts). A dataset past the limit is
29
+ * drawn with a factor of 1 (the plain color), and a layer past it has its opacity
30
+ * baked into its colors. 64 vec2 stay well inside the 224 fragment uniform vectors
31
+ * WebGL2 guarantees.
32
+ */
33
+ export const DRAPE_MAX_SOURCES = 64;
34
+ /**
35
+ * The defaults of the shading, 335 degrees as seen on screen (northwest), an
36
+ * altitude of 45 degrees and a strength of 0.45
37
+ */
38
+ export const DRAPE_LIGHT_AZIMUTH_DEG = 335;
39
+ export const DRAPE_LIGHT_ALTITUDE_DEG = 45;
40
+ export const DRAPE_LIGHT_STRENGTH = 0.45;
41
+ /**
42
+ * Converts a screen-anchored (anchor viewport) light source into a vector in the
43
+ * map coordinate system
44
+ *
45
+ * So that the light always comes from the top left on screen, the map's rotation
46
+ * (bearing) is added to convert it into an azimuth in the map coordinate system.
47
+ */
48
+ export function resolveDrapeLight(bearingDeg) {
49
+ const azimuth = ((DRAPE_LIGHT_AZIMUTH_DEG + bearingDeg) * Math.PI) / 180;
50
+ const altitude = (DRAPE_LIGHT_ALTITUDE_DEG * Math.PI) / 180;
51
+ const horizontal = Math.cos(altitude);
52
+ return {
53
+ direction: [Math.sin(azimuth) * horizontal, Math.cos(azimuth) * horizontal, Math.sin(altitude)],
54
+ strength: DRAPE_LIGHT_STRENGTH,
55
+ };
56
+ }
57
+ /**
58
+ * The ratio of the lift from the ground surface (a proportion of the tile's ground
59
+ * size)
60
+ *
61
+ * One ten-thousandth. That amounts to 2 m for a z11 tile (about 19 km) and 6 cm
62
+ * for z16 (about 600 m). On screen it is less than 0.1 pixel, so it is invisible,
63
+ * yet in depth it reliably wins against the terrain surface.
64
+ */
65
+ export const DRAPE_LIFT_RATIO = 1 / 2500;
66
+ const VERTEX_SOURCE = (prelude, define) => `#version 300 es
67
+ ${prelude}
68
+ ${define}
69
+ layout(location = 0) in vec2 a_pos;
70
+ // A very slight lift from the ground surface (meters), in order to win against the
71
+ // terrain surface in depth
72
+ uniform float u_drape_lift_m;
73
+ out vec2 v_tile;
74
+ ${TERRAIN_SAMPLE_GLSL}
75
+ ${EDGE_CONSTRAIN_GLSL}
76
+
77
+ void main() {
78
+ // A boundary vertex is constrained to the coarser side's polyline only when the
79
+ // neighbor is coarser (edge-constrain.ts)
80
+ float ele = drape_edge_constrained(a_pos, drape_get_elevation(a_pos));
81
+
82
+ // The boundary is not moved. Neither an overhang nor a skirt is created; it is
83
+ // closed only in the form where adjacent tiles share the same polyline.
84
+ gl_Position = projectTileWithElevation(a_pos, ele + u_drape_lift_m);
85
+ v_tile = a_pos / ${TILE_EXTENT}.0;
86
+ }`;
87
+ /**
88
+ * The shader that paints the pixels (exported because a test watches its structure)
89
+ */
90
+ export const DRAPE_FRAGMENT_SOURCE = `#version 300 es
91
+ precision highp float;
92
+ precision highp int;
93
+ precision highp sampler2D;
94
+
95
+ in vec2 v_tile;
96
+
97
+ uniform sampler2D u_edge_tex;
98
+ uniform sampler2D u_run_tex;
99
+ uniform sampler2D u_cell_tex;
100
+ uniform sampler2D u_style_tex;
101
+ uniform int u_data_width;
102
+ uniform int u_cell_base;
103
+ uniform float u_cells;
104
+ uniform float u_opacity;
105
+ uniform float u_zoom;
106
+ // The factors per source (x = opacity, y = size). The zoom response of a
107
+ // dataset is applied here (baking it into the elements would mean
108
+ // rebuilding the index on every zoom)
109
+ uniform vec2 u_source_factors[${DRAPE_MAX_SOURCES}];
110
+ // Shading (an aid to reading the terrain). It is applied only to the fill, with
111
+ // the same light source and the same formula as the ground. This is not 3D
112
+ // lighting that illuminates symbols with an arbitrary light. It is also distinct
113
+ // from vertical exaggeration of the terrain (which follows the map's own factor), and
114
+ // it does not change the dimensions of the relief at all.
115
+ uniform vec3 u_light_dir; // a unit vector in the map coordinate system (east, north, up)
116
+ uniform float u_shade_strength;
117
+ uniform float u_tile_meters; // the ground size of this tile (meters)
118
+ // The selection highlight (rgb = the base color, a = the opacity of the area fill)
119
+ uniform vec4 u_selection_color;
120
+ // The extra outline thickness added by the selection highlight (physical pixels)
121
+ uniform float u_selection_stroke_extra;
122
+ // The range of elements to paint, [x, y). In order to insert an image (a quad)
123
+ // between polygons and lines following the stacking order, the element sequence is
124
+ // split at the image's position and drawn range by range. Elements outside the
125
+ // range still count toward the coverage of the selection highlight (the final
126
+ // segment composes the coverage of all elements)
127
+ uniform vec2 u_paint_range;
128
+ // Whether to compose the selection highlight in this draw (1 only for the final
129
+ // segment)
130
+ uniform float u_emit_selection;
131
+
132
+ out vec4 fragColor;
133
+
134
+ ` +
135
+ TERRAIN_SAMPLE_GLSL +
136
+ TERRAIN_SHADE_GLSL +
137
+ `
138
+
139
+ vec4 fetchData(sampler2D tex, int i) {
140
+ return texelFetch(tex, ivec2(i % u_data_width, i / u_data_width), 0);
141
+ }
142
+
143
+ float cross2(vec2 a, vec2 b) {
144
+ return a.x * b.y - a.y * b.x;
145
+ }
146
+
147
+ // Whether the segment (p, q) and the segment (a, b) intersect
148
+ bool crosses(vec2 p, vec2 q, vec2 a, vec2 b) {
149
+ float d1 = cross2(b - a, p - a);
150
+ float d2 = cross2(b - a, q - a);
151
+ float d3 = cross2(q - p, a - p);
152
+ float d4 = cross2(q - p, b - p);
153
+ return (d1 * d2 < 0.0) && (d3 * d4 < 0.0);
154
+ }
155
+
156
+ // The shortest vector from a point to a segment (in tile-local coordinates)
157
+ vec2 closestVector(vec2 p, vec2 a, vec2 b) {
158
+ vec2 ab = b - a;
159
+ float len2 = dot(ab, ab);
160
+ float t = len2 > 0.0 ? clamp(dot(p - a, ab) / len2, 0.0, 1.0) : 0.0;
161
+ return p - (a + ab * t);
162
+ }
163
+
164
+ // Compose on top (premultiplied alpha)
165
+ vec4 over(vec4 below, vec3 rgb, float a) {
166
+ return vec4(rgb * a + below.rgb * (1.0 - a), a + below.a * (1.0 - a));
167
+ }
168
+
169
+ void main() {
170
+ vec2 p = v_tile;
171
+
172
+ // The inverse Jacobian, mapping a displacement in tile-local coordinates to a
173
+ // displacement in screen pixels. The derivatives are taken before entering a
174
+ // branch (under uniform control flow).
175
+ vec2 dpdx = dFdx(p);
176
+ vec2 dpdy = dFdy(p);
177
+ float det = dpdx.x * dpdy.y - dpdy.x * dpdx.y;
178
+ mat2 jacobianInverse;
179
+ if (abs(det) < 1e-24) {
180
+ // When the derivatives vanish, for instance on a surface seen exactly edge
181
+ // on, the matrix cannot be built. An isotropic approximation stands in for
182
+ // it (discarding would leave that pixel unpainted)
183
+ float s = max(max(length(dpdx), length(dpdy)), 1e-12);
184
+ jacobianInverse = mat2(1.0 / s, 0.0, 0.0, 1.0 / s);
185
+ } else {
186
+ jacobianInverse = mat2(dpdy.y, -dpdx.y, -dpdy.x, dpdx.x) / det;
187
+ }
188
+
189
+ ivec2 cell = ivec2(clamp(floor(p * u_cells), vec2(0.0), vec2(u_cells - 1.0)));
190
+ int cellIndex = u_cell_base + cell.y * int(u_cells) + cell.x;
191
+ vec4 cellData = fetchData(u_cell_tex, cellIndex);
192
+ int runStart = int(cellData.x);
193
+ int runCount = int(cellData.y);
194
+ if (runCount == 0) discard;
195
+
196
+ vec2 origin = vec2(cell) / u_cells;
197
+
198
+ vec4 acc = vec4(0.0);
199
+ float shade = -1.0;
200
+ // The coverage of the selection highlight (the maximum over the features that
201
+ // are selected at this pixel)
202
+ float selFill = 0.0;
203
+ float selStroke = 0.0;
204
+
205
+ for (int r = 0; r < runCount; r++) {
206
+ vec4 run = fetchData(u_run_tex, runStart + r);
207
+ int elementIndex = int(run.x);
208
+ int edgeStart = int(run.y);
209
+ int edgeCount = int(run.z);
210
+ bool inside = run.w > 0.5;
211
+
212
+ // Range drawing. Only the elements in u_paint_range are painted. The coverage
213
+ // of the selection is accumulated from outside the range as well, but only by
214
+ // the segment that composes it (u_emit_selection); the other segments skip it.
215
+ // The runs of a cell are in draw order (binning.ts), so a segment that does not
216
+ // compose the selection is done once it passes the end of its range: with k
217
+ // images between the sections, a section no longer pays for the runs of the
218
+ // sections after it
219
+ if (u_emit_selection < 0.5 && float(elementIndex) >= u_paint_range.y) break;
220
+ bool paints = float(elementIndex) >= u_paint_range.x
221
+ && float(elementIndex) < u_paint_range.y;
222
+ bool selected = u_emit_selection > 0.5
223
+ && fetchData(u_style_tex, elementIndex * ${DRAPE_STYLE_TEXELS} + ${DRAPE_SELECTION_TEXEL}).x
224
+ > 0.5;
225
+ if (!paints && !selected) continue;
226
+
227
+ float minDist = 1.0e9;
228
+ for (int e = 0; e < edgeCount; e++) {
229
+ vec4 seg = fetchData(u_edge_tex, edgeStart + e);
230
+ vec2 a = seg.xy;
231
+ vec2 b = seg.zw;
232
+ if (crosses(origin, p, a, b)) inside = !inside;
233
+ vec2 offset = closestVector(p, a, b);
234
+ minDist = min(minDist, length(jacobianInverse * offset));
235
+ }
236
+
237
+ int styleAt = elementIndex * ${DRAPE_STYLE_TEXELS};
238
+ vec4 fill = fetchData(u_style_tex, styleAt);
239
+ vec4 stroke = fetchData(u_style_tex, styleAt + 1);
240
+ vec4 params = fetchData(u_style_tex, styleAt + 2);
241
+ int source = int(params.z);
242
+ vec2 factors = source >= 0 && source < ${DRAPE_MAX_SOURCES}
243
+ ? u_source_factors[source]
244
+ : vec2(1.0, 1.0);
245
+ // An element that has a reference zoom for its line width changes its
246
+ // thickness with the same formula as the retained batch path
247
+ float widthScale = params.w >= 0.0 ? exp2(u_zoom - params.w) : 1.0;
248
+ float halfWidth = params.x * 0.5 * factors.y * widthScale;
249
+ bool isPolygon = params.y < 0.5;
250
+
251
+ if (paints && isPolygon && fill.a > 0.0) {
252
+ // A signed distance, negative inside and positive outside (screen pixels)
253
+ float signedDist = inside ? -minDist : minDist;
254
+ float coverage = clamp(0.5 - signedDist, 0.0, 1.0);
255
+ if (coverage > 0.0) {
256
+ // Apply the same shading as the ground only to the fill (lines,
257
+ // points and handles are unshaded)
258
+ if (shade < 0.0) shade = terrainShade(p);
259
+ acc = over(acc, fill.rgb * shade, fill.a * coverage * factors.x);
260
+ }
261
+ }
262
+
263
+ if (paints && halfWidth > 0.0 && stroke.a > 0.0) {
264
+ float coverage = clamp(halfWidth + 0.5 - minDist, 0.0, 1.0);
265
+ if (coverage > 0.0) acc = over(acc, stroke.rgb, stroke.a * coverage * factors.x);
266
+ }
267
+
268
+ // Accumulate the coverage of the selection highlight. It is not composed
269
+ // here.
270
+ //
271
+ // Composing it at the stacking order of the selected feature buries the
272
+ // highlight under the fill of the features stacked above it (the
273
+ // municipalities when a prefecture is selected). Small features appear as
274
+ // the zoom is raised, so it showed up as "the red disappears when you zoom
275
+ // in". The immediate mode always overpainted it last, so this is aligned
276
+ // with the same "compose last" convention.
277
+ if (selected) {
278
+ if (isPolygon) {
279
+ float signedDist = inside ? -minDist : minDist;
280
+ float coverage = clamp(0.5 - signedDist, 0.0, 1.0);
281
+ selFill = max(selFill, coverage * factors.x);
282
+ }
283
+ // The added thickness is kept constant in screen pixels (so that "an
284
+ // outline one size thicker" always looks the same regardless of the
285
+ // unit of the original thickness). The highlight outline is also drawn
286
+ // for features that have no outline (the same as the immediate mode)
287
+ float selHalf = halfWidth + u_selection_stroke_extra * 0.5;
288
+ selStroke = max(selStroke, clamp(selHalf + 0.5 - minDist, 0.0, 1.0) * factors.x);
289
+ }
290
+ }
291
+
292
+ // The selection highlight is composed at the end of the pixel (so it is not
293
+ // buried under the features stacked above). In range drawing only the final
294
+ // segment composes it (composing per segment would bury it under the fill of
295
+ // later segments, and the overlapping places would also turn darker)
296
+ if (u_emit_selection > 0.5 && selFill > 0.0) {
297
+ // The fill gets the same shading as the ground (the same convention as the
298
+ // underlying fill)
299
+ if (shade < 0.0) shade = terrainShade(p);
300
+ acc = over(acc, u_selection_color.rgb * shade, u_selection_color.a * selFill);
301
+ }
302
+ if (u_emit_selection > 0.5 && selStroke > 0.0) acc = over(acc, u_selection_color.rgb, selStroke);
303
+
304
+ if (acc.a <= 0.0) discard;
305
+ fragColor = acc * u_opacity;
306
+ }`;
307
+ /**
308
+ * The renderer of the analytic drape
309
+ */
310
+ export class DrapeRenderer {
311
+ constructor(gl) {
312
+ Object.defineProperty(this, "gl", {
313
+ enumerable: true,
314
+ configurable: true,
315
+ writable: true,
316
+ value: void 0
317
+ });
318
+ Object.defineProperty(this, "program", {
319
+ enumerable: true,
320
+ configurable: true,
321
+ writable: true,
322
+ value: null
323
+ });
324
+ Object.defineProperty(this, "variantName", {
325
+ enumerable: true,
326
+ configurable: true,
327
+ writable: true,
328
+ value: ''
329
+ });
330
+ Object.defineProperty(this, "mesh", {
331
+ enumerable: true,
332
+ configurable: true,
333
+ writable: true,
334
+ value: null
335
+ });
336
+ Object.defineProperty(this, "edgeTex", {
337
+ enumerable: true,
338
+ configurable: true,
339
+ writable: true,
340
+ value: null
341
+ });
342
+ Object.defineProperty(this, "runTex", {
343
+ enumerable: true,
344
+ configurable: true,
345
+ writable: true,
346
+ value: null
347
+ });
348
+ Object.defineProperty(this, "cellTex", {
349
+ enumerable: true,
350
+ configurable: true,
351
+ writable: true,
352
+ value: null
353
+ });
354
+ Object.defineProperty(this, "styleTex", {
355
+ enumerable: true,
356
+ configurable: true,
357
+ writable: true,
358
+ value: null
359
+ });
360
+ Object.defineProperty(this, "edgeTexSize", {
361
+ enumerable: true,
362
+ configurable: true,
363
+ writable: true,
364
+ value: [0, 0]
365
+ });
366
+ Object.defineProperty(this, "runTexSize", {
367
+ enumerable: true,
368
+ configurable: true,
369
+ writable: true,
370
+ value: [0, 0]
371
+ });
372
+ Object.defineProperty(this, "cellTexSize", {
373
+ enumerable: true,
374
+ configurable: true,
375
+ writable: true,
376
+ value: [0, 0]
377
+ });
378
+ Object.defineProperty(this, "styleTexSize", {
379
+ enumerable: true,
380
+ configurable: true,
381
+ writable: true,
382
+ value: [0, 0]
383
+ });
384
+ Object.defineProperty(this, "uploaded", {
385
+ enumerable: true,
386
+ configurable: true,
387
+ writable: true,
388
+ value: { builderId: -1, edges: 0, runs: 0, cells: 0, styles: 0 }
389
+ });
390
+ /** The selection version the transferred style table reflects (-1 = not transferred) */
391
+ Object.defineProperty(this, "uploadedSelection", {
392
+ enumerable: true,
393
+ configurable: true,
394
+ writable: true,
395
+ value: -1
396
+ });
397
+ Object.defineProperty(this, "locations", {
398
+ enumerable: true,
399
+ configurable: true,
400
+ writable: true,
401
+ value: {}
402
+ });
403
+ /** The most recent failure reason (for diagnostics) */
404
+ Object.defineProperty(this, "lastError", {
405
+ enumerable: true,
406
+ configurable: true,
407
+ writable: true,
408
+ value: ''
409
+ });
410
+ /** MAX_TEXTURE_SIZE of the context (read once, 0 = not read yet) */
411
+ Object.defineProperty(this, "maxTextureSize", {
412
+ enumerable: true,
413
+ configurable: true,
414
+ writable: true,
415
+ value: 0
416
+ });
417
+ this.gl = gl;
418
+ }
419
+ /**
420
+ * Allocates the shader and the mesh
421
+ */
422
+ ensure(shaderData, meshSize) {
423
+ const gl = this.gl;
424
+ if (!this.mesh || this.mesh.meshSize !== meshSize) {
425
+ if (this.mesh)
426
+ disposeTerrainMeshBuffers(gl, this.mesh);
427
+ this.mesh = createTerrainMeshBuffers(gl, meshSize);
428
+ if (!this.mesh) {
429
+ this.lastError = 'mesh-alloc-failed';
430
+ return false;
431
+ }
432
+ }
433
+ if (this.program && this.variantName === shaderData.variantName)
434
+ return true;
435
+ if (this.program)
436
+ gl.deleteProgram(this.program);
437
+ try {
438
+ this.program = createProgram(gl, VERTEX_SOURCE(shaderData.vertexShaderPrelude, shaderData.define), DRAPE_FRAGMENT_SOURCE);
439
+ }
440
+ catch (error) {
441
+ this.lastError = `shader: ${String(error)}`;
442
+ this.program = null;
443
+ return false;
444
+ }
445
+ this.variantName = shaderData.variantName;
446
+ const names = [
447
+ ...DRAPE_PROJECTION_UNIFORMS,
448
+ ...DRAPE_TERRAIN_UNIFORMS,
449
+ 'u_edge_tex',
450
+ 'u_run_tex',
451
+ 'u_cell_tex',
452
+ 'u_style_tex',
453
+ 'u_data_width',
454
+ 'u_cell_base',
455
+ 'u_cells',
456
+ 'u_opacity',
457
+ 'u_zoom',
458
+ 'u_source_factors[0]',
459
+ 'u_light_dir',
460
+ 'u_shade_strength',
461
+ 'u_tile_meters',
462
+ 'u_drape_lift_m',
463
+ 'u_selection_color',
464
+ 'u_selection_stroke_extra',
465
+ 'u_paint_range',
466
+ 'u_emit_selection',
467
+ ...EDGE_CONSTRAIN_UNIFORMS,
468
+ ];
469
+ this.locations = {};
470
+ for (const name of names) {
471
+ this.locations[name] = gl.getUniformLocation(this.program, name);
472
+ }
473
+ return true;
474
+ }
475
+ /**
476
+ * Transfers the part of the packed arrays that has not been sent yet to the GPU
477
+ *
478
+ * The arrays are append-only, so sending only the rows that were added is
479
+ * enough. Everything is sent only when the version has been swapped (it became a
480
+ * different builder) and when the textures have been recreated.
481
+ *
482
+ * @returns false when a table does not fit in a texture of this GPU (taller than
483
+ * MAX_TEXTURE_SIZE, or the allocation failed). The caller then draws the frame
484
+ * without the analytic drape, the same way as when the index is over its budget
485
+ */
486
+ upload(pack) {
487
+ if (this.uploaded.builderId !== pack.id) {
488
+ this.uploaded = { builderId: pack.id, edges: 0, runs: 0, cells: 0, styles: 0 };
489
+ this.uploadedSelection = -1;
490
+ }
491
+ // The selection highlight rewrites rows that have already been sent (it is not
492
+ // an append), so when the version moves only the style table is sent again from
493
+ // the beginning. The style table is 4 texels per element, orders of magnitude
494
+ // smaller than the edge table
495
+ if (this.uploadedSelection !== pack.selectionVersion) {
496
+ this.uploaded.styles = 0;
497
+ this.uploadedSelection = pack.selectionVersion;
498
+ }
499
+ this.edgeTex = this.uploadTexture(this.edgeTex, 'edgeTexSize', 'edges', DATA_TEX_WIDTH, pack.edges, pack.edgeCount);
500
+ this.runTex = this.uploadTexture(this.runTex, 'runTexSize', 'runs', DATA_TEX_WIDTH, pack.runs, pack.runCount);
501
+ this.cellTex = this.uploadTexture(this.cellTex, 'cellTexSize', 'cells', DATA_TEX_WIDTH, pack.cells, pack.cellCount);
502
+ // The style table is laid out like the others (4 texels per element in rows of
503
+ // DATA_TEX_WIDTH, a multiple of 4), so its height grows with elements / 512, not elements
504
+ this.styleTex = this.uploadTexture(this.styleTex, 'styleTexSize', 'styles', DATA_TEX_WIDTH, pack.styles, DRAPE_STYLE_TEXELS * Math.max(1, pack.elementCount));
505
+ return (this.edgeTex !== null &&
506
+ this.runTex !== null &&
507
+ this.cellTex !== null &&
508
+ this.styleTex !== null);
509
+ }
510
+ /**
511
+ * Draws a single tile
512
+ *
513
+ * @param projectionData The ProjectionData of that tile
514
+ * @param sourceFactors The factors per source (x = opacity, y = size)
515
+ * @param opacity The overall opacity (default 1)
516
+ * @param segment The segment of range drawing (omitted = all elements + the
517
+ * selection highlight). When inserting an image between polygons and lines
518
+ * following the stacking order, the caller splits the element sequence at the
519
+ * image's position and draws it segment by segment
520
+ */
521
+ drawTile(draw, projectionData, light, zoom, sourceFactors, pixelRatio = 1, opacity = 1, segment) {
522
+ const gl = this.gl;
523
+ const program = this.program;
524
+ const mesh = this.mesh;
525
+ if (!program || !mesh || !this.edgeTex || !this.cellTex || !this.styleTex) {
526
+ this.lastError = 'draw: missing resources';
527
+ return;
528
+ }
529
+ gl.useProgram(program);
530
+ const set = this.locations;
531
+ applyDrapeProjectionUniforms(gl, set, projectionData);
532
+ applyDrapeTerrainUniforms(gl, set, draw.terrain, UNIT_TERRAIN);
533
+ this.bindData(UNIT_EDGE, this.edgeTex, set.u_edge_tex);
534
+ this.bindData(UNIT_RUN, this.runTex, set.u_run_tex);
535
+ this.bindData(UNIT_CELL, this.cellTex, set.u_cell_tex);
536
+ this.bindData(UNIT_STYLE, this.styleTex, set.u_style_tex);
537
+ if (set.u_data_width)
538
+ gl.uniform1i(set.u_data_width, DATA_TEX_WIDTH);
539
+ if (set.u_cell_base)
540
+ gl.uniform1i(set.u_cell_base, draw.cellOffset);
541
+ if (set.u_cells)
542
+ gl.uniform1f(set.u_cells, draw.grid);
543
+ if (set.u_opacity)
544
+ gl.uniform1f(set.u_opacity, opacity);
545
+ if (set.u_zoom)
546
+ gl.uniform1f(set.u_zoom, zoom);
547
+ if (set['u_source_factors[0]']) {
548
+ gl.uniform2fv(set['u_source_factors[0]'], sourceFactors);
549
+ }
550
+ if (set.u_light_dir) {
551
+ gl.uniform3f(set.u_light_dir, light.direction[0], light.direction[1], light.direction[2]);
552
+ }
553
+ if (set.u_shade_strength)
554
+ gl.uniform1f(set.u_shade_strength, light.strength);
555
+ if (set.u_tile_meters)
556
+ gl.uniform1f(set.u_tile_meters, draw.groundMeters);
557
+ // The lift is made proportional to the tile's ground size. It then amounts to
558
+ // the same quantity on screen, so at any zoom it stays within "too small to
559
+ // see, yet reliably winning in depth". A constant depth bias (polygonOffset)
560
+ // depends on the on-screen gradient of the depth and on the resolution of the
561
+ // depth buffer, so on a shallow-angle slope it works too strongly or not at all
562
+ if (set.u_drape_lift_m) {
563
+ gl.uniform1f(set.u_drape_lift_m, draw.groundMeters * DRAPE_LIFT_RATIO);
564
+ }
565
+ // The appearance of the selection highlight is constant, so the values
566
+ // themselves are the same every frame (a uniform is state that persists per
567
+ // program, so writing it once per tile is enough)
568
+ if (set.u_selection_color) {
569
+ gl.uniform4f(set.u_selection_color, SELECTION_HIGHLIGHT_RGB[0], SELECTION_HIGHLIGHT_RGB[1], SELECTION_HIGHLIGHT_RGB[2], SELECTION_HIGHLIGHT_FILL_OPACITY);
570
+ }
571
+ if (set.u_selection_stroke_extra) {
572
+ gl.uniform1f(set.u_selection_stroke_extra, SELECTION_HIGHLIGHT_STROKE_EXTRA * pixelRatio);
573
+ }
574
+ // The segment of range drawing. When omitted, all elements are painted and the
575
+ // selection highlight is composed as well (a uniform is state that persists per
576
+ // program, so it is written explicitly every time)
577
+ if (set.u_paint_range) {
578
+ gl.uniform2f(set.u_paint_range, segment?.paintFrom ?? 0, segment?.paintTo ?? 1e9);
579
+ }
580
+ if (set.u_emit_selection) {
581
+ gl.uniform1f(set.u_emit_selection, (segment?.emitSelection ?? true) ? 1 : 0);
582
+ }
583
+ // The step and the DEM are written from one and the same value (see the note in
584
+ // edge-constrain.ts)
585
+ applyEdgeConstrainUniforms(gl, set, draw.edges, draw.terrain);
586
+ // The ground surface is one-sided, but a slope is sometimes seen from behind.
587
+ // No culling is applied
588
+ gl.disable(gl.CULL_FACE);
589
+ gl.bindVertexArray(mesh.vao);
590
+ gl.drawElements(gl.TRIANGLES, mesh.indexCount, gl.UNSIGNED_INT, 0);
591
+ gl.bindVertexArray(null);
592
+ gl.activeTexture(gl.TEXTURE0);
593
+ }
594
+ /**
595
+ * Releases the resources
596
+ */
597
+ dispose() {
598
+ const gl = this.gl;
599
+ if (this.program) {
600
+ gl.deleteProgram(this.program);
601
+ this.program = null;
602
+ }
603
+ if (this.mesh) {
604
+ disposeTerrainMeshBuffers(gl, this.mesh);
605
+ this.mesh = null;
606
+ }
607
+ for (const texture of [this.edgeTex, this.runTex, this.cellTex, this.styleTex]) {
608
+ if (texture)
609
+ gl.deleteTexture(texture);
610
+ }
611
+ this.edgeTex = null;
612
+ this.runTex = null;
613
+ this.cellTex = null;
614
+ this.styleTex = null;
615
+ this.edgeTexSize = [0, 0];
616
+ this.runTexSize = [0, 0];
617
+ this.cellTexSize = [0, 0];
618
+ this.styleTexSize = [0, 0];
619
+ this.uploaded = { builderId: -1, edges: 0, runs: 0, cells: 0, styles: 0 };
620
+ this.uploadedSelection = -1;
621
+ }
622
+ bindData(unit, texture, location) {
623
+ const gl = this.gl;
624
+ gl.activeTexture(gl.TEXTURE0 + unit);
625
+ gl.bindTexture(gl.TEXTURE_2D, texture);
626
+ if (location)
627
+ gl.uniform1i(location, unit);
628
+ }
629
+ /** The tallest data texture this GPU allows (MAX_TEXTURE_SIZE, read once) */
630
+ textureSizeLimit() {
631
+ if (this.maxTextureSize === 0) {
632
+ const max = Number(this.gl.getParameter(this.gl.MAX_TEXTURE_SIZE));
633
+ this.maxTextureSize = Number.isFinite(max) && max > 0 ? max : 4096;
634
+ }
635
+ return this.maxTextureSize;
636
+ }
637
+ /**
638
+ * Allocates a data texture and transfers the rows that have not been sent yet
639
+ *
640
+ * texStorage2D is immutable, so the texture is recreated whenever the required
641
+ * size changes (once recreated, everything is sent again).
642
+ */
643
+ uploadTexture(texture, sizeField, markField, width, data, texelCount) {
644
+ const gl = this.gl;
645
+ const size = this[sizeField];
646
+ const neededRows = Math.max(1, Math.ceil(texelCount / width));
647
+ const maxRows = this.textureSizeLimit();
648
+ let target = texture;
649
+ if (!target || size[0] !== width || size[1] < neededRows) {
650
+ if (target)
651
+ gl.deleteTexture(target);
652
+ this[sizeField] = [0, 0];
653
+ this.uploaded[markField] = 0;
654
+ // A table taller than the GPU allows cannot be allocated (texStorage2D would fail with
655
+ // INVALID_VALUE and leave a texture that samples as zeros)
656
+ if (neededRows > maxRows) {
657
+ this.lastError = `texture-limit: ${markField} needs ${neededRows} rows of ${maxRows}`;
658
+ return null;
659
+ }
660
+ target = gl.createTexture();
661
+ if (!target)
662
+ return null;
663
+ // Allocate a few extra rows (so it is not recreated on every increase)
664
+ const rows = Math.min(maxRows, Math.max(1, Math.ceil(neededRows * 1.5)));
665
+ gl.bindTexture(gl.TEXTURE_2D, target);
666
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, width, rows);
667
+ // Only the allocation is checked (it is rare; getError is a synchronous round trip)
668
+ if (gl.getError() !== gl.NO_ERROR) {
669
+ gl.deleteTexture(target);
670
+ this.lastError = `texture-alloc-failed: ${markField}`;
671
+ return null;
672
+ }
673
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
674
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
675
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
676
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
677
+ this[sizeField] = [width, rows];
678
+ this.uploaded[markField] = 0;
679
+ }
680
+ else {
681
+ gl.bindTexture(gl.TEXTURE_2D, target);
682
+ }
683
+ const uploaded = this.uploaded[markField];
684
+ if (texelCount <= uploaded)
685
+ return target;
686
+ // Writing continues from the middle of an already transferred row, so the
687
+ // transfer starts at the beginning of that row
688
+ const fromRow = Math.floor(uploaded / width);
689
+ const toRow = Math.ceil(texelCount / width);
690
+ const rows = toRow - fromRow;
691
+ const needed = rows * width * 4;
692
+ const offset = fromRow * width * 4;
693
+ const payload = data.length >= offset + needed
694
+ ? data.subarray(offset, offset + needed)
695
+ : padTo(data.subarray(offset), needed);
696
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, fromRow, width, rows, gl.RGBA, gl.FLOAT, payload);
697
+ this.uploaded[markField] = texelCount;
698
+ return target;
699
+ }
700
+ }
701
+ /** Pads with 0 up to the length required for the transfer */
702
+ function padTo(data, length) {
703
+ const out = new Float32Array(length);
704
+ out.set(data.subarray(0, Math.min(data.length, length)));
705
+ return out;
706
+ }