@scoova/mgl 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 (565) hide show
  1. package/LICENSE.txt +116 -0
  2. package/README.md +174 -0
  3. package/build/banner.ts +12 -0
  4. package/build/bump-version-changelog.js +26 -0
  5. package/build/check-bundle-size.js +77 -0
  6. package/build/generate-dist-package.js +26 -0
  7. package/build/generate-doc-images.ts +78 -0
  8. package/build/generate-docs.ts +190 -0
  9. package/build/generate-shaders.ts +68 -0
  10. package/build/generate-struct-arrays.ts +438 -0
  11. package/build/generate-style-code.ts +283 -0
  12. package/build/readme.md +56 -0
  13. package/build/release-notes.js +45 -0
  14. package/build/rollup/bundle_prelude.js +29 -0
  15. package/build/rollup/maplibregl.js +22 -0
  16. package/build/rollup_plugins.ts +58 -0
  17. package/dist/LICENSE.txt +116 -0
  18. package/dist/maplibre-gl.css +1 -0
  19. package/dist/maplibre-gl.d.ts +13304 -0
  20. package/dist/maplibre-gl.js +59 -0
  21. package/dist/maplibre-gl.js.map +1 -0
  22. package/dist/package.json +1 -0
  23. package/package.json +192 -0
  24. package/src/css/maplibre-gl.css +854 -0
  25. package/src/css/svg/maplibregl-ctrl-attrib.svg +3 -0
  26. package/src/css/svg/maplibregl-ctrl-compass.svg +4 -0
  27. package/src/css/svg/maplibregl-ctrl-fullscreen.svg +3 -0
  28. package/src/css/svg/maplibregl-ctrl-geolocate.svg +5 -0
  29. package/src/css/svg/maplibregl-ctrl-logo.svg +11 -0
  30. package/src/css/svg/maplibregl-ctrl-shrink.svg +3 -0
  31. package/src/css/svg/maplibregl-ctrl-terrain.svg +3 -0
  32. package/src/css/svg/maplibregl-ctrl-zoom-in.svg +3 -0
  33. package/src/css/svg/maplibregl-ctrl-zoom-out.svg +3 -0
  34. package/src/data/array_types.g.ts +1130 -0
  35. package/src/data/bucket/circle_attributes.ts +8 -0
  36. package/src/data/bucket/circle_bucket.ts +197 -0
  37. package/src/data/bucket/fill_attributes.ts +8 -0
  38. package/src/data/bucket/fill_bucket.test.ts +95 -0
  39. package/src/data/bucket/fill_bucket.ts +228 -0
  40. package/src/data/bucket/fill_extrusion_attributes.ts +13 -0
  41. package/src/data/bucket/fill_extrusion_bucket.ts +305 -0
  42. package/src/data/bucket/heatmap_bucket.ts +12 -0
  43. package/src/data/bucket/line_attributes.ts +8 -0
  44. package/src/data/bucket/line_attributes_ext.ts +8 -0
  45. package/src/data/bucket/line_bucket.test.ts +142 -0
  46. package/src/data/bucket/line_bucket.ts +592 -0
  47. package/src/data/bucket/pattern_attributes.ts +9 -0
  48. package/src/data/bucket/pattern_bucket_features.ts +57 -0
  49. package/src/data/bucket/symbol_attributes.ts +122 -0
  50. package/src/data/bucket/symbol_bucket.test.ts +243 -0
  51. package/src/data/bucket/symbol_bucket.ts +975 -0
  52. package/src/data/bucket.ts +123 -0
  53. package/src/data/dem_data.test.ts +237 -0
  54. package/src/data/dem_data.ts +171 -0
  55. package/src/data/evaluation_feature.ts +18 -0
  56. package/src/data/extent.ts +13 -0
  57. package/src/data/feature_index.ts +337 -0
  58. package/src/data/feature_position_map.test.ts +33 -0
  59. package/src/data/feature_position_map.ts +126 -0
  60. package/src/data/index_array_type.ts +9 -0
  61. package/src/data/load_geometry.test.ts +49 -0
  62. package/src/data/load_geometry.ts +44 -0
  63. package/src/data/pos3d_attributes.ts +5 -0
  64. package/src/data/pos_attributes.ts +5 -0
  65. package/src/data/program_configuration.ts +735 -0
  66. package/src/data/raster_bounds_attributes.ts +6 -0
  67. package/src/data/segment.ts +89 -0
  68. package/src/geo/edge_insets.test.ts +83 -0
  69. package/src/geo/edge_insets.ts +146 -0
  70. package/src/geo/lng_lat.test.ts +65 -0
  71. package/src/geo/lng_lat.ts +169 -0
  72. package/src/geo/lng_lat_bounds.test.ts +357 -0
  73. package/src/geo/lng_lat_bounds.ts +356 -0
  74. package/src/geo/mercator_coordinate.test.ts +34 -0
  75. package/src/geo/mercator_coordinate.ts +157 -0
  76. package/src/geo/projection/projection.ts +72 -0
  77. package/src/geo/transform.test.ts +509 -0
  78. package/src/geo/transform.ts +1072 -0
  79. package/src/gl/color_mode.ts +31 -0
  80. package/src/gl/context.ts +321 -0
  81. package/src/gl/cull_face_mode.ts +22 -0
  82. package/src/gl/depth_mode.ts +26 -0
  83. package/src/gl/framebuffer.ts +48 -0
  84. package/src/gl/index_buffer.ts +55 -0
  85. package/src/gl/render_pool.test.ts +69 -0
  86. package/src/gl/render_pool.ts +93 -0
  87. package/src/gl/state.test.ts +125 -0
  88. package/src/gl/stencil_mode.ts +27 -0
  89. package/src/gl/types.ts +59 -0
  90. package/src/gl/value.ts +534 -0
  91. package/src/gl/vertex_buffer.test.ts +57 -0
  92. package/src/gl/vertex_buffer.ts +111 -0
  93. package/src/gl/webgl2.ts +12 -0
  94. package/src/index.test.ts +121 -0
  95. package/src/index.ts +250 -0
  96. package/src/render/draw_background.ts +53 -0
  97. package/src/render/draw_circle.ts +113 -0
  98. package/src/render/draw_collision_debug.ts +168 -0
  99. package/src/render/draw_custom.test.ts +73 -0
  100. package/src/render/draw_custom.ts +45 -0
  101. package/src/render/draw_debug.test.ts +122 -0
  102. package/src/render/draw_debug.ts +148 -0
  103. package/src/render/draw_fill.test.ts +137 -0
  104. package/src/render/draw_fill.ts +128 -0
  105. package/src/render/draw_fill_extrusion.ts +97 -0
  106. package/src/render/draw_heatmap.ts +228 -0
  107. package/src/render/draw_hillshade.ts +119 -0
  108. package/src/render/draw_line.ts +125 -0
  109. package/src/render/draw_raster.ts +133 -0
  110. package/src/render/draw_sky.ts +44 -0
  111. package/src/render/draw_symbol.test.ts +223 -0
  112. package/src/render/draw_symbol.ts +499 -0
  113. package/src/render/draw_terrain.ts +99 -0
  114. package/src/render/glyph_atlas.ts +83 -0
  115. package/src/render/glyph_manager.test.ts +147 -0
  116. package/src/render/glyph_manager.ts +198 -0
  117. package/src/render/image_atlas.ts +159 -0
  118. package/src/render/image_manager.ts +337 -0
  119. package/src/render/line_atlas.test.ts +38 -0
  120. package/src/render/line_atlas.ts +214 -0
  121. package/src/render/mesh.ts +25 -0
  122. package/src/render/painter.test.ts +51 -0
  123. package/src/render/painter.ts +666 -0
  124. package/src/render/program/background_program.ts +100 -0
  125. package/src/render/program/circle_program.ts +61 -0
  126. package/src/render/program/clipping_mask_program.ts +19 -0
  127. package/src/render/program/collision_program.ts +47 -0
  128. package/src/render/program/debug_program.ts +29 -0
  129. package/src/render/program/fill_extrusion_program.ts +120 -0
  130. package/src/render/program/fill_program.ts +121 -0
  131. package/src/render/program/heatmap_program.ts +76 -0
  132. package/src/render/program/hillshade_program.ts +116 -0
  133. package/src/render/program/line_program.ts +207 -0
  134. package/src/render/program/pattern.ts +102 -0
  135. package/src/render/program/program_uniforms.ts +46 -0
  136. package/src/render/program/raster_program.ts +88 -0
  137. package/src/render/program/sky_program.ts +28 -0
  138. package/src/render/program/symbol_program.ts +266 -0
  139. package/src/render/program/terrain_program.ts +116 -0
  140. package/src/render/program.ts +233 -0
  141. package/src/render/render_to_texture.test.ts +151 -0
  142. package/src/render/render_to_texture.ts +197 -0
  143. package/src/render/terrain.test.ts +322 -0
  144. package/src/render/terrain.ts +464 -0
  145. package/src/render/texture.ts +114 -0
  146. package/src/render/uniform_binding.test.ts +122 -0
  147. package/src/render/uniform_binding.ts +157 -0
  148. package/src/render/update_pattern_positions_in_program.test.ts +74 -0
  149. package/src/render/update_pattern_positions_in_program.ts +50 -0
  150. package/src/render/vertex_array_object.ts +163 -0
  151. package/src/shaders/README.md +42 -0
  152. package/src/shaders/_prelude.fragment.glsl +19 -0
  153. package/src/shaders/_prelude.fragment.glsl.g.ts +2 -0
  154. package/src/shaders/_prelude.vertex.glsl +148 -0
  155. package/src/shaders/_prelude.vertex.glsl.g.ts +2 -0
  156. package/src/shaders/background.fragment.glsl +10 -0
  157. package/src/shaders/background.fragment.glsl.g.ts +2 -0
  158. package/src/shaders/background.vertex.glsl +7 -0
  159. package/src/shaders/background.vertex.glsl.g.ts +2 -0
  160. package/src/shaders/background_pattern.fragment.glsl +28 -0
  161. package/src/shaders/background_pattern.fragment.glsl.g.ts +2 -0
  162. package/src/shaders/background_pattern.vertex.glsl +19 -0
  163. package/src/shaders/background_pattern.vertex.glsl.g.ts +2 -0
  164. package/src/shaders/circle.fragment.glsl +34 -0
  165. package/src/shaders/circle.fragment.glsl.g.ts +2 -0
  166. package/src/shaders/circle.vertex.glsl +68 -0
  167. package/src/shaders/circle.vertex.glsl.g.ts +2 -0
  168. package/src/shaders/clipping_mask.fragment.glsl +3 -0
  169. package/src/shaders/clipping_mask.fragment.glsl.g.ts +2 -0
  170. package/src/shaders/clipping_mask.vertex.glsl +7 -0
  171. package/src/shaders/clipping_mask.vertex.glsl.g.ts +2 -0
  172. package/src/shaders/collision_box.fragment.glsl +20 -0
  173. package/src/shaders/collision_box.fragment.glsl.g.ts +2 -0
  174. package/src/shaders/collision_box.vertex.glsl +27 -0
  175. package/src/shaders/collision_box.vertex.glsl.g.ts +2 -0
  176. package/src/shaders/collision_circle.fragment.glsl +17 -0
  177. package/src/shaders/collision_circle.fragment.glsl.g.ts +2 -0
  178. package/src/shaders/collision_circle.vertex.glsl +59 -0
  179. package/src/shaders/collision_circle.vertex.glsl.g.ts +2 -0
  180. package/src/shaders/debug.fragment.glsl +9 -0
  181. package/src/shaders/debug.fragment.glsl.g.ts +2 -0
  182. package/src/shaders/debug.vertex.glsl +12 -0
  183. package/src/shaders/debug.vertex.glsl.g.ts +2 -0
  184. package/src/shaders/encode_attribute.test.ts +11 -0
  185. package/src/shaders/encode_attribute.ts +13 -0
  186. package/src/shaders/fill.fragment.glsl +13 -0
  187. package/src/shaders/fill.fragment.glsl.g.ts +2 -0
  188. package/src/shaders/fill.vertex.glsl +13 -0
  189. package/src/shaders/fill.vertex.glsl.g.ts +2 -0
  190. package/src/shaders/fill_extrusion.fragment.glsl +9 -0
  191. package/src/shaders/fill_extrusion.fragment.glsl.g.ts +2 -0
  192. package/src/shaders/fill_extrusion.vertex.glsl +84 -0
  193. package/src/shaders/fill_extrusion.vertex.glsl.g.ts +2 -0
  194. package/src/shaders/fill_extrusion_pattern.fragment.glsl +47 -0
  195. package/src/shaders/fill_extrusion_pattern.fragment.glsl.g.ts +2 -0
  196. package/src/shaders/fill_extrusion_pattern.vertex.glsl +96 -0
  197. package/src/shaders/fill_extrusion_pattern.vertex.glsl.g.ts +2 -0
  198. package/src/shaders/fill_outline.fragment.glsl +17 -0
  199. package/src/shaders/fill_outline.fragment.glsl.g.ts +2 -0
  200. package/src/shaders/fill_outline.vertex.glsl +17 -0
  201. package/src/shaders/fill_outline.vertex.glsl.g.ts +2 -0
  202. package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
  203. package/src/shaders/fill_outline_pattern.fragment.glsl.g.ts +2 -0
  204. package/src/shaders/fill_outline_pattern.vertex.glsl +44 -0
  205. package/src/shaders/fill_outline_pattern.vertex.glsl.g.ts +2 -0
  206. package/src/shaders/fill_pattern.fragment.glsl +39 -0
  207. package/src/shaders/fill_pattern.fragment.glsl.g.ts +2 -0
  208. package/src/shaders/fill_pattern.vertex.glsl +39 -0
  209. package/src/shaders/fill_pattern.vertex.glsl.g.ts +2 -0
  210. package/src/shaders/heatmap.fragment.glsl +22 -0
  211. package/src/shaders/heatmap.fragment.glsl.g.ts +2 -0
  212. package/src/shaders/heatmap.vertex.glsl +54 -0
  213. package/src/shaders/heatmap.vertex.glsl.g.ts +2 -0
  214. package/src/shaders/heatmap_texture.fragment.glsl +15 -0
  215. package/src/shaders/heatmap_texture.fragment.glsl.g.ts +2 -0
  216. package/src/shaders/heatmap_texture.vertex.glsl +11 -0
  217. package/src/shaders/heatmap_texture.vertex.glsl.g.ts +2 -0
  218. package/src/shaders/hillshade.fragment.glsl +52 -0
  219. package/src/shaders/hillshade.fragment.glsl.g.ts +2 -0
  220. package/src/shaders/hillshade.vertex.glsl +11 -0
  221. package/src/shaders/hillshade.vertex.glsl.g.ts +2 -0
  222. package/src/shaders/hillshade_prepare.fragment.glsl +77 -0
  223. package/src/shaders/hillshade_prepare.fragment.glsl.g.ts +2 -0
  224. package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
  225. package/src/shaders/hillshade_prepare.vertex.glsl.g.ts +2 -0
  226. package/src/shaders/line.fragment.glsl +30 -0
  227. package/src/shaders/line.fragment.glsl.g.ts +2 -0
  228. package/src/shaders/line.vertex.glsl +89 -0
  229. package/src/shaders/line.vertex.glsl.g.ts +2 -0
  230. package/src/shaders/line_gradient.fragment.glsl +34 -0
  231. package/src/shaders/line_gradient.fragment.glsl.g.ts +2 -0
  232. package/src/shaders/line_gradient.vertex.glsl +92 -0
  233. package/src/shaders/line_gradient.vertex.glsl.g.ts +2 -0
  234. package/src/shaders/line_pattern.fragment.glsl +77 -0
  235. package/src/shaders/line_pattern.fragment.glsl.g.ts +2 -0
  236. package/src/shaders/line_pattern.vertex.glsl +103 -0
  237. package/src/shaders/line_pattern.vertex.glsl.g.ts +2 -0
  238. package/src/shaders/line_sdf.fragment.glsl +45 -0
  239. package/src/shaders/line_sdf.fragment.glsl.g.ts +2 -0
  240. package/src/shaders/line_sdf.vertex.glsl +101 -0
  241. package/src/shaders/line_sdf.vertex.glsl.g.ts +2 -0
  242. package/src/shaders/raster.fragment.glsl +53 -0
  243. package/src/shaders/raster.fragment.glsl.g.ts +2 -0
  244. package/src/shaders/raster.vertex.glsl +21 -0
  245. package/src/shaders/raster.vertex.glsl.g.ts +2 -0
  246. package/src/shaders/shaders.ts +197 -0
  247. package/src/shaders/sky.fragment.glsl +17 -0
  248. package/src/shaders/sky.fragment.glsl.g.ts +2 -0
  249. package/src/shaders/sky.vertex.glsl +5 -0
  250. package/src/shaders/sky.vertex.glsl.g.ts +2 -0
  251. package/src/shaders/symbol_icon.fragment.glsl +17 -0
  252. package/src/shaders/symbol_icon.fragment.glsl.g.ts +2 -0
  253. package/src/shaders/symbol_icon.vertex.glsl +117 -0
  254. package/src/shaders/symbol_icon.vertex.glsl.g.ts +2 -0
  255. package/src/shaders/symbol_sdf.fragment.glsl +58 -0
  256. package/src/shaders/symbol_sdf.fragment.glsl.g.ts +2 -0
  257. package/src/shaders/symbol_sdf.vertex.glsl +142 -0
  258. package/src/shaders/symbol_sdf.vertex.glsl.g.ts +2 -0
  259. package/src/shaders/symbol_text_and_icon.fragment.glsl +68 -0
  260. package/src/shaders/symbol_text_and_icon.fragment.glsl.g.ts +2 -0
  261. package/src/shaders/symbol_text_and_icon.vertex.glsl +140 -0
  262. package/src/shaders/symbol_text_and_icon.vertex.glsl.g.ts +2 -0
  263. package/src/shaders/terrain.fragment.glsl +32 -0
  264. package/src/shaders/terrain.fragment.glsl.g.ts +2 -0
  265. package/src/shaders/terrain.vertex.glsl +17 -0
  266. package/src/shaders/terrain.vertex.glsl.g.ts +2 -0
  267. package/src/shaders/terrain_coords.fragment.glsl +11 -0
  268. package/src/shaders/terrain_coords.fragment.glsl.g.ts +2 -0
  269. package/src/shaders/terrain_coords.vertex.glsl +13 -0
  270. package/src/shaders/terrain_coords.vertex.glsl.g.ts +2 -0
  271. package/src/shaders/terrain_depth.fragment.glsl +15 -0
  272. package/src/shaders/terrain_depth.fragment.glsl.g.ts +2 -0
  273. package/src/shaders/terrain_depth.vertex.glsl +13 -0
  274. package/src/shaders/terrain_depth.vertex.glsl.g.ts +2 -0
  275. package/src/source/canvas_source.test.ts +210 -0
  276. package/src/source/canvas_source.ts +227 -0
  277. package/src/source/geojson_source.test.ts +492 -0
  278. package/src/source/geojson_source.ts +431 -0
  279. package/src/source/geojson_source_diff.test.ts +364 -0
  280. package/src/source/geojson_source_diff.ts +172 -0
  281. package/src/source/geojson_worker_source.test.ts +399 -0
  282. package/src/source/geojson_worker_source.ts +303 -0
  283. package/src/source/geojson_wrapper.test.ts +32 -0
  284. package/src/source/geojson_wrapper.ts +81 -0
  285. package/src/source/image_source.test.ts +235 -0
  286. package/src/source/image_source.ts +338 -0
  287. package/src/source/load_tilejson.ts +47 -0
  288. package/src/source/pixels_to_tile_units.ts +25 -0
  289. package/src/source/protocol_crud.ts +48 -0
  290. package/src/source/query_features.test.ts +31 -0
  291. package/src/source/query_features.ts +252 -0
  292. package/src/source/raster_dem_tile_source.test.ts +158 -0
  293. package/src/source/raster_dem_tile_source.ts +166 -0
  294. package/src/source/raster_dem_tile_worker_source.test.ts +36 -0
  295. package/src/source/raster_dem_tile_worker_source.ts +38 -0
  296. package/src/source/raster_tile_source.test.ts +206 -0
  297. package/src/source/raster_tile_source.ts +227 -0
  298. package/src/source/rtl_text_plugin_main_thread.test.ts +170 -0
  299. package/src/source/rtl_text_plugin_main_thread.ts +89 -0
  300. package/src/source/rtl_text_plugin_status.ts +33 -0
  301. package/src/source/rtl_text_plugin_worker.ts +49 -0
  302. package/src/source/source.test.ts +41 -0
  303. package/src/source/source.ts +186 -0
  304. package/src/source/source_cache.test.ts +2069 -0
  305. package/src/source/source_cache.ts +1102 -0
  306. package/src/source/source_state.ts +157 -0
  307. package/src/source/terrain_source_cache.test.ts +105 -0
  308. package/src/source/terrain_source_cache.ts +204 -0
  309. package/src/source/tile.test.ts +290 -0
  310. package/src/source/tile.ts +478 -0
  311. package/src/source/tile_bounds.ts +34 -0
  312. package/src/source/tile_cache.test.ts +130 -0
  313. package/src/source/tile_cache.ts +208 -0
  314. package/src/source/tile_id.test.ts +112 -0
  315. package/src/source/tile_id.ts +221 -0
  316. package/src/source/vector_tile_source.test.ts +401 -0
  317. package/src/source/vector_tile_source.ts +283 -0
  318. package/src/source/vector_tile_worker_source.test.ts +396 -0
  319. package/src/source/vector_tile_worker_source.ts +199 -0
  320. package/src/source/video_source.test.ts +124 -0
  321. package/src/source/video_source.ts +204 -0
  322. package/src/source/worker.test.ts +233 -0
  323. package/src/source/worker.ts +301 -0
  324. package/src/source/worker_source.ts +117 -0
  325. package/src/source/worker_tile.test.ts +226 -0
  326. package/src/source/worker_tile.ts +208 -0
  327. package/src/style/create_style_layer.ts +39 -0
  328. package/src/style/evaluation_parameters.ts +62 -0
  329. package/src/style/format_section_override.test.ts +62 -0
  330. package/src/style/format_section_override.ts +50 -0
  331. package/src/style/light.test.ts +86 -0
  332. package/src/style/light.ts +135 -0
  333. package/src/style/load_glyph_range.test.ts +40 -0
  334. package/src/style/load_glyph_range.ts +32 -0
  335. package/src/style/load_sprite.test.ts +227 -0
  336. package/src/style/load_sprite.ts +71 -0
  337. package/src/style/parse_glyph_pbf.ts +42 -0
  338. package/src/style/pauseable_placement.ts +138 -0
  339. package/src/style/properties.ts +726 -0
  340. package/src/style/query_utils.test.ts +107 -0
  341. package/src/style/query_utils.ts +70 -0
  342. package/src/style/sky.ts +127 -0
  343. package/src/style/style.test.ts +2654 -0
  344. package/src/style/style.ts +1814 -0
  345. package/src/style/style_glyph.ts +25 -0
  346. package/src/style/style_image.ts +188 -0
  347. package/src/style/style_layer/background_style_layer.ts +17 -0
  348. package/src/style/style_layer/background_style_layer_properties.g.ts +40 -0
  349. package/src/style/style_layer/circle_style_layer.ts +98 -0
  350. package/src/style/style_layer/circle_style_layer_properties.g.ts +76 -0
  351. package/src/style/style_layer/custom_style_layer.ts +233 -0
  352. package/src/style/style_layer/fill_extrusion_style_layer.ts +224 -0
  353. package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +55 -0
  354. package/src/style/style_layer/fill_style_layer.test.ts +37 -0
  355. package/src/style/style_layer/fill_style_layer.ts +65 -0
  356. package/src/style/style_layer/fill_style_layer_properties.g.ts +64 -0
  357. package/src/style/style_layer/heatmap_style_layer.ts +74 -0
  358. package/src/style/style_layer/heatmap_style_layer_properties.g.ts +46 -0
  359. package/src/style/style_layer/hillshade_style_layer.ts +21 -0
  360. package/src/style/style_layer/hillshade_style_layer_properties.g.ts +49 -0
  361. package/src/style/style_layer/line_style_layer.test.ts +50 -0
  362. package/src/style/style_layer/line_style_layer.ts +131 -0
  363. package/src/style/style_layer/line_style_layer_properties.g.ts +88 -0
  364. package/src/style/style_layer/overlap_mode.test.ts +57 -0
  365. package/src/style/style_layer/overlap_mode.ts +25 -0
  366. package/src/style/style_layer/raster_style_layer.ts +17 -0
  367. package/src/style/style_layer/raster_style_layer_properties.g.ts +55 -0
  368. package/src/style/style_layer/symbol_style_layer.ts +195 -0
  369. package/src/style/style_layer/symbol_style_layer_properties.g.ts +218 -0
  370. package/src/style/style_layer/typed_style_layer.ts +9 -0
  371. package/src/style/style_layer/variable_text_anchor.test.ts +117 -0
  372. package/src/style/style_layer/variable_text_anchor.ts +163 -0
  373. package/src/style/style_layer.test.ts +372 -0
  374. package/src/style/style_layer.ts +287 -0
  375. package/src/style/style_layer_index.test.ts +99 -0
  376. package/src/style/style_layer_index.ts +78 -0
  377. package/src/style/validate_style.ts +53 -0
  378. package/src/style/zoom_history.ts +40 -0
  379. package/src/symbol/anchor.test.ts +14 -0
  380. package/src/symbol/anchor.ts +22 -0
  381. package/src/symbol/check_max_angle.test.ts +54 -0
  382. package/src/symbol/check_max_angle.ts +76 -0
  383. package/src/symbol/clip_line.test.ts +154 -0
  384. package/src/symbol/clip_line.ts +66 -0
  385. package/src/symbol/collision_feature.test.ts +98 -0
  386. package/src/symbol/collision_feature.ts +114 -0
  387. package/src/symbol/collision_index.test.ts +19 -0
  388. package/src/symbol/collision_index.ts +618 -0
  389. package/src/symbol/cross_tile_symbol_index.test.ts +260 -0
  390. package/src/symbol/cross_tile_symbol_index.ts +367 -0
  391. package/src/symbol/get_anchors.test.ts +113 -0
  392. package/src/symbol/get_anchors.ts +167 -0
  393. package/src/symbol/grid_index.test.ts +75 -0
  394. package/src/symbol/grid_index.ts +414 -0
  395. package/src/symbol/merge_lines.test.ts +30 -0
  396. package/src/symbol/merge_lines.ts +80 -0
  397. package/src/symbol/one_em.ts +3 -0
  398. package/src/symbol/opacity_state.ts +23 -0
  399. package/src/symbol/path_interpolator.test.ts +134 -0
  400. package/src/symbol/path_interpolator.ts +55 -0
  401. package/src/symbol/placement.ts +1371 -0
  402. package/src/symbol/projection.test.ts +171 -0
  403. package/src/symbol/projection.ts +833 -0
  404. package/src/symbol/quads.test.ts +157 -0
  405. package/src/symbol/quads.ts +349 -0
  406. package/src/symbol/shaping.test.ts +360 -0
  407. package/src/symbol/shaping.ts +911 -0
  408. package/src/symbol/symbol_layout.ts +739 -0
  409. package/src/symbol/symbol_size.ts +129 -0
  410. package/src/symbol/symbol_style_layer.test.ts +103 -0
  411. package/src/symbol/transform_text.ts +27 -0
  412. package/src/ui/anchor.ts +27 -0
  413. package/src/ui/camera.test.ts +2301 -0
  414. package/src/ui/camera.ts +1520 -0
  415. package/src/ui/control/attribution_control.test.ts +543 -0
  416. package/src/ui/control/attribution_control.ts +209 -0
  417. package/src/ui/control/control.ts +67 -0
  418. package/src/ui/control/fullscreen_control.test.ts +114 -0
  419. package/src/ui/control/fullscreen_control.ts +189 -0
  420. package/src/ui/control/geolocate_control.test.ts +619 -0
  421. package/src/ui/control/geolocate_control.ts +725 -0
  422. package/src/ui/control/logo_control.test.ts +88 -0
  423. package/src/ui/control/logo_control.ts +86 -0
  424. package/src/ui/control/navigation_control.test.ts +238 -0
  425. package/src/ui/control/navigation_control.ts +294 -0
  426. package/src/ui/control/scale_control.test.ts +52 -0
  427. package/src/ui/control/scale_control.ts +152 -0
  428. package/src/ui/control/terrain_control.test.ts +58 -0
  429. package/src/ui/control/terrain_control.ts +74 -0
  430. package/src/ui/default_locale.ts +25 -0
  431. package/src/ui/events.ts +758 -0
  432. package/src/ui/handler/box_zoom.test.ts +163 -0
  433. package/src/ui/handler/box_zoom.ts +171 -0
  434. package/src/ui/handler/click_zoom.ts +55 -0
  435. package/src/ui/handler/cooperative_gestures.test.ts +338 -0
  436. package/src/ui/handler/cooperative_gestures.ts +111 -0
  437. package/src/ui/handler/dblclick_zoom.test.ts +151 -0
  438. package/src/ui/handler/drag_handler.ts +174 -0
  439. package/src/ui/handler/drag_move_state_manager.ts +115 -0
  440. package/src/ui/handler/drag_pan.test.ts +487 -0
  441. package/src/ui/handler/drag_rotate.test.ts +859 -0
  442. package/src/ui/handler/handler_util.ts +10 -0
  443. package/src/ui/handler/keyboard.test.ts +235 -0
  444. package/src/ui/handler/keyboard.ts +212 -0
  445. package/src/ui/handler/map_event.test.ts +158 -0
  446. package/src/ui/handler/map_event.ts +161 -0
  447. package/src/ui/handler/mouse.ts +92 -0
  448. package/src/ui/handler/mouse_handler_interface.test.ts +111 -0
  449. package/src/ui/handler/mouse_rotate.test.ts +62 -0
  450. package/src/ui/handler/one_finger_touch_drag.ts +45 -0
  451. package/src/ui/handler/one_finger_touch_drag_handler_interface.test.ts +77 -0
  452. package/src/ui/handler/scroll_zoom.test.ts +382 -0
  453. package/src/ui/handler/scroll_zoom.ts +379 -0
  454. package/src/ui/handler/shim/dblclick_zoom.ts +64 -0
  455. package/src/ui/handler/shim/drag_pan.ts +104 -0
  456. package/src/ui/handler/shim/drag_rotate.ts +76 -0
  457. package/src/ui/handler/shim/two_fingers_touch.ts +112 -0
  458. package/src/ui/handler/tap_drag_zoom.test.ts +113 -0
  459. package/src/ui/handler/tap_drag_zoom.ts +112 -0
  460. package/src/ui/handler/tap_recognizer.ts +138 -0
  461. package/src/ui/handler/tap_zoom.ts +98 -0
  462. package/src/ui/handler/touch_pan.ts +115 -0
  463. package/src/ui/handler/transform-provider.ts +44 -0
  464. package/src/ui/handler/two_fingers_touch.test.ts +283 -0
  465. package/src/ui/handler/two_fingers_touch.ts +336 -0
  466. package/src/ui/handler_inertia.ts +157 -0
  467. package/src/ui/handler_manager.ts +637 -0
  468. package/src/ui/hash.test.ts +404 -0
  469. package/src/ui/hash.ts +153 -0
  470. package/src/ui/map.ts +3393 -0
  471. package/src/ui/map_tests/map_animation.test.ts +61 -0
  472. package/src/ui/map_tests/map_basic.test.ts +223 -0
  473. package/src/ui/map_tests/map_bounds.test.ts +123 -0
  474. package/src/ui/map_tests/map_calculate_camera_options.test.ts +113 -0
  475. package/src/ui/map_tests/map_canvas.test.ts +59 -0
  476. package/src/ui/map_tests/map_control.test.ts +61 -0
  477. package/src/ui/map_tests/map_disable_handlers.test.ts +38 -0
  478. package/src/ui/map_tests/map_events.test.ts +1001 -0
  479. package/src/ui/map_tests/map_feature_state.test.ts +421 -0
  480. package/src/ui/map_tests/map_images.test.ts +175 -0
  481. package/src/ui/map_tests/map_is_moving.test.ts +164 -0
  482. package/src/ui/map_tests/map_is_rotating.test.ts +62 -0
  483. package/src/ui/map_tests/map_is_zooming.test.ts +86 -0
  484. package/src/ui/map_tests/map_layer.test.ts +457 -0
  485. package/src/ui/map_tests/map_options.test.ts +64 -0
  486. package/src/ui/map_tests/map_pitch.test.ts +90 -0
  487. package/src/ui/map_tests/map_pixel_ratio.test.ts +75 -0
  488. package/src/ui/map_tests/map_query_rendered_features.test.ts +93 -0
  489. package/src/ui/map_tests/map_render.test.ts +90 -0
  490. package/src/ui/map_tests/map_request_render_frame.test.ts +51 -0
  491. package/src/ui/map_tests/map_resize.test.ts +120 -0
  492. package/src/ui/map_tests/map_style.test.ts +541 -0
  493. package/src/ui/map_tests/map_terrian.test.ts +104 -0
  494. package/src/ui/map_tests/map_webgl.test.ts +72 -0
  495. package/src/ui/map_tests/map_world_copies.test.ts +103 -0
  496. package/src/ui/map_tests/map_zoom.test.ts +95 -0
  497. package/src/ui/marker.test.ts +1149 -0
  498. package/src/ui/marker.ts +880 -0
  499. package/src/ui/popup.test.ts +827 -0
  500. package/src/ui/popup.ts +717 -0
  501. package/src/util/abort_error.ts +21 -0
  502. package/src/util/actor.test.ts +218 -0
  503. package/src/util/actor.ts +241 -0
  504. package/src/util/actor_messages.ts +149 -0
  505. package/src/util/ajax.test.ts +237 -0
  506. package/src/util/ajax.ts +297 -0
  507. package/src/util/browser.test.ts +23 -0
  508. package/src/util/browser.ts +63 -0
  509. package/src/util/color_ramp.test.ts +105 -0
  510. package/src/util/color_ramp.ts +56 -0
  511. package/src/util/config.ts +29 -0
  512. package/src/util/dictionary_coder.ts +23 -0
  513. package/src/util/dispatcher.test.ts +76 -0
  514. package/src/util/dispatcher.ts +78 -0
  515. package/src/util/dom.ts +135 -0
  516. package/src/util/evented.test.ts +231 -0
  517. package/src/util/evented.ts +178 -0
  518. package/src/util/find_pole_of_inaccessibility.test.ts +21 -0
  519. package/src/util/find_pole_of_inaccessibility.ts +130 -0
  520. package/src/util/geolocation_support.test.ts +43 -0
  521. package/src/util/geolocation_support.ts +23 -0
  522. package/src/util/global_worker_pool.ts +65 -0
  523. package/src/util/image.ts +150 -0
  524. package/src/util/image_request.test.ts +408 -0
  525. package/src/util/image_request.ts +246 -0
  526. package/src/util/intersection_tests.ts +206 -0
  527. package/src/util/is_char_in_unicode_block.test.ts +15 -0
  528. package/src/util/is_char_in_unicode_block.ts +345 -0
  529. package/src/util/offscreen_canvas_distorted.test.ts +13 -0
  530. package/src/util/offscreen_canvas_distorted.ts +39 -0
  531. package/src/util/offscreen_canvas_supported.ts +11 -0
  532. package/src/util/performance.ts +117 -0
  533. package/src/util/primitives.test.ts +140 -0
  534. package/src/util/primitives.ts +143 -0
  535. package/src/util/request_manager.ts +42 -0
  536. package/src/util/resolve_tokens.test.ts +45 -0
  537. package/src/util/resolve_tokens.ts +17 -0
  538. package/src/util/script_detection.test.ts +138 -0
  539. package/src/util/script_detection.ts +376 -0
  540. package/src/util/smart_wrap.test.ts +97 -0
  541. package/src/util/smart_wrap.ts +58 -0
  542. package/src/util/struct_array.test.ts +101 -0
  543. package/src/util/struct_array.ts +246 -0
  544. package/src/util/style.test.ts +34 -0
  545. package/src/util/style.ts +28 -0
  546. package/src/util/task_queue.test.ts +114 -0
  547. package/src/util/task_queue.ts +64 -0
  548. package/src/util/test/util.ts +185 -0
  549. package/src/util/throttle.test.ts +42 -0
  550. package/src/util/throttle.ts +28 -0
  551. package/src/util/throttled_invoker.ts +41 -0
  552. package/src/util/transferable_grid_index.test.ts +56 -0
  553. package/src/util/transferable_grid_index.ts +214 -0
  554. package/src/util/util.test.ts +414 -0
  555. package/src/util/util.ts +724 -0
  556. package/src/util/vectortile_to_geojson.ts +72 -0
  557. package/src/util/verticalize_punctuation.ts +110 -0
  558. package/src/util/web_worker.ts +16 -0
  559. package/src/util/web_worker_transfer.test.ts +153 -0
  560. package/src/util/web_worker_transfer.ts +254 -0
  561. package/src/util/webp_supported.ts +63 -0
  562. package/src/util/worker_pool.test.ts +43 -0
  563. package/src/util/worker_pool.ts +58 -0
  564. package/src/util/world_bounds.test.ts +59 -0
  565. package/src/util/world_bounds.ts +46 -0
@@ -0,0 +1,975 @@
1
+ import {
2
+ symbolLayoutAttributes,
3
+ collisionVertexAttributes,
4
+ collisionBoxLayout,
5
+ dynamicLayoutAttributes,
6
+ } from './symbol_attributes';
7
+
8
+ import {SymbolLayoutArray,
9
+ SymbolDynamicLayoutArray,
10
+ SymbolOpacityArray,
11
+ CollisionBoxLayoutArray,
12
+ CollisionVertexArray,
13
+ PlacedSymbolArray,
14
+ SymbolInstanceArray,
15
+ GlyphOffsetArray,
16
+ SymbolLineVertexArray,
17
+ TextAnchorOffsetArray
18
+ } from '../array_types.g';
19
+
20
+ import Point from '@mapbox/point-geometry';
21
+ import {SegmentVector} from '../segment';
22
+ import {ProgramConfigurationSet} from '../program_configuration';
23
+ import {TriangleIndexArray, LineIndexArray} from '../index_array_type';
24
+ import {transformText} from '../../symbol/transform_text';
25
+ import {mergeLines} from '../../symbol/merge_lines';
26
+ import {allowsVerticalWritingMode, stringContainsRTLText} from '../../util/script_detection';
27
+ import {WritingMode} from '../../symbol/shaping';
28
+ import {loadGeometry} from '../load_geometry';
29
+ import {toEvaluationFeature} from '../evaluation_feature';
30
+ import mvt from '@mapbox/vector-tile';
31
+ const vectorTileFeatureTypes = mvt.VectorTileFeature.types;
32
+ import {verticalizedCharacterMap} from '../../util/verticalize_punctuation';
33
+ import {Anchor} from '../../symbol/anchor';
34
+ import {getSizeData, MAX_PACKED_SIZE} from '../../symbol/symbol_size';
35
+
36
+ import {register} from '../../util/web_worker_transfer';
37
+ import {EvaluationParameters} from '../../style/evaluation_parameters';
38
+ import {Formatted, ResolvedImage} from '@maplibre/maplibre-gl-style-spec';
39
+ import {rtlWorkerPlugin} from '../../source/rtl_text_plugin_worker';
40
+ import {mat4} from 'gl-matrix';
41
+ import {getOverlapMode} from '../../style/style_layer/overlap_mode';
42
+ import type {CanonicalTileID} from '../../source/tile_id';
43
+ import type {
44
+ Bucket,
45
+ BucketParameters,
46
+ IndexedFeature,
47
+ PopulateParameters
48
+ } from '../bucket';
49
+ import type {CollisionBoxArray, CollisionBox, SymbolInstance} from '../array_types.g';
50
+ import type {StructArray, StructArrayMember, ViewType} from '../../util/struct_array';
51
+ import type {SymbolStyleLayer} from '../../style/style_layer/symbol_style_layer';
52
+ import type {Context} from '../../gl/context';
53
+ import type {IndexBuffer} from '../../gl/index_buffer';
54
+ import type {VertexBuffer} from '../../gl/vertex_buffer';
55
+ import type {SymbolQuad} from '../../symbol/quads';
56
+ import type {SizeData} from '../../symbol/symbol_size';
57
+ import type {FeatureStates} from '../../source/source_state';
58
+ import type {ImagePosition} from '../../render/image_atlas';
59
+ import type {VectorTileLayer} from '@mapbox/vector-tile';
60
+
61
+ export type SingleCollisionBox = {
62
+ x1: number;
63
+ y1: number;
64
+ x2: number;
65
+ y2: number;
66
+ anchorPointX: number;
67
+ anchorPointY: number;
68
+ };
69
+
70
+ export type CollisionArrays = {
71
+ textBox?: SingleCollisionBox;
72
+ verticalTextBox?: SingleCollisionBox;
73
+ iconBox?: SingleCollisionBox;
74
+ verticalIconBox?: SingleCollisionBox;
75
+ textFeatureIndex?: number;
76
+ verticalTextFeatureIndex?: number;
77
+ iconFeatureIndex?: number;
78
+ verticalIconFeatureIndex?: number;
79
+ };
80
+
81
+ export type SymbolFeature = {
82
+ sortKey: number | void;
83
+ text: Formatted | void;
84
+ icon: ResolvedImage;
85
+ index: number;
86
+ sourceLayerIndex: number;
87
+ geometry: Array<Array<Point>>;
88
+ properties: any;
89
+ type: 'Unknown' | 'Point' | 'LineString' | 'Polygon';
90
+ id?: any;
91
+ };
92
+
93
+ export type SortKeyRange = {
94
+ sortKey: number;
95
+ symbolInstanceStart: number;
96
+ symbolInstanceEnd: number;
97
+ };
98
+
99
+ // Opacity arrays are frequently updated but don't contain a lot of information, so we pack them
100
+ // tight. Each Uint32 is actually four duplicate Uint8s for the four corners of a glyph
101
+ // 7 bits are for the current opacity, and the lowest bit is the target opacity
102
+
103
+ // actually defined in symbol_attributes.js
104
+ // const placementOpacityAttributes = [
105
+ // { name: 'a_fade_opacity', components: 1, type: 'Uint32' }
106
+ // ];
107
+ const shaderOpacityAttributes = [
108
+ {name: 'a_fade_opacity', components: 1, type: 'Uint8' as ViewType, offset: 0}
109
+ ];
110
+
111
+ function addVertex(
112
+ array: StructArray,
113
+ anchorX: number,
114
+ anchorY: number,
115
+ ox: number,
116
+ oy: number,
117
+ tx: number,
118
+ ty: number,
119
+ sizeVertex: number,
120
+ isSDF: boolean,
121
+ pixelOffsetX: number,
122
+ pixelOffsetY: number,
123
+ minFontScaleX: number,
124
+ minFontScaleY: number
125
+ ) {
126
+ const aSizeX = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[0])) : 0;
127
+ const aSizeY = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[1])) : 0;
128
+ array.emplaceBack(
129
+ // a_pos_offset
130
+ anchorX,
131
+ anchorY,
132
+ Math.round(ox * 32),
133
+ Math.round(oy * 32),
134
+
135
+ // a_data
136
+ tx, // x coordinate of symbol on glyph atlas texture
137
+ ty, // y coordinate of symbol on glyph atlas texture
138
+ (aSizeX << 1) + (isSDF ? 1 : 0),
139
+ aSizeY,
140
+ pixelOffsetX * 16,
141
+ pixelOffsetY * 16,
142
+ minFontScaleX * 256,
143
+ minFontScaleY * 256
144
+ );
145
+ }
146
+
147
+ function addDynamicAttributes(dynamicLayoutVertexArray: StructArray, p: Point, angle: number) {
148
+ dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle);
149
+ dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle);
150
+ dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle);
151
+ dynamicLayoutVertexArray.emplaceBack(p.x, p.y, angle);
152
+ }
153
+
154
+ function containsRTLText(formattedText: Formatted): boolean {
155
+ for (const section of formattedText.sections) {
156
+ if (stringContainsRTLText(section.text)) {
157
+ return true;
158
+ }
159
+ }
160
+ return false;
161
+ }
162
+
163
+ export class SymbolBuffers {
164
+ layoutVertexArray: SymbolLayoutArray;
165
+ layoutVertexBuffer: VertexBuffer;
166
+
167
+ indexArray: TriangleIndexArray;
168
+ indexBuffer: IndexBuffer;
169
+
170
+ programConfigurations: ProgramConfigurationSet<SymbolStyleLayer>;
171
+ segments: SegmentVector;
172
+
173
+ dynamicLayoutVertexArray: SymbolDynamicLayoutArray;
174
+ dynamicLayoutVertexBuffer: VertexBuffer;
175
+
176
+ opacityVertexArray: SymbolOpacityArray;
177
+ opacityVertexBuffer: VertexBuffer;
178
+ hasVisibleVertices: boolean;
179
+
180
+ collisionVertexArray: CollisionVertexArray;
181
+ collisionVertexBuffer: VertexBuffer;
182
+
183
+ placedSymbolArray: PlacedSymbolArray;
184
+
185
+ constructor(programConfigurations: ProgramConfigurationSet<SymbolStyleLayer>) {
186
+ this.layoutVertexArray = new SymbolLayoutArray();
187
+ this.indexArray = new TriangleIndexArray();
188
+ this.programConfigurations = programConfigurations;
189
+ this.segments = new SegmentVector();
190
+ this.dynamicLayoutVertexArray = new SymbolDynamicLayoutArray();
191
+ this.opacityVertexArray = new SymbolOpacityArray();
192
+ this.hasVisibleVertices = false;
193
+ this.placedSymbolArray = new PlacedSymbolArray();
194
+ }
195
+
196
+ isEmpty() {
197
+ return this.layoutVertexArray.length === 0 &&
198
+ this.indexArray.length === 0 &&
199
+ this.dynamicLayoutVertexArray.length === 0 &&
200
+ this.opacityVertexArray.length === 0;
201
+ }
202
+
203
+ upload(context: Context, dynamicIndexBuffer: boolean, upload?: boolean, update?: boolean) {
204
+ if (this.isEmpty()) {
205
+ return;
206
+ }
207
+
208
+ if (upload) {
209
+ this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, symbolLayoutAttributes.members);
210
+ this.indexBuffer = context.createIndexBuffer(this.indexArray, dynamicIndexBuffer);
211
+ this.dynamicLayoutVertexBuffer = context.createVertexBuffer(this.dynamicLayoutVertexArray, dynamicLayoutAttributes.members, true);
212
+ this.opacityVertexBuffer = context.createVertexBuffer(this.opacityVertexArray, shaderOpacityAttributes, true);
213
+ // This is a performance hack so that we can write to opacityVertexArray with uint32s
214
+ // even though the shaders read uint8s
215
+ this.opacityVertexBuffer.itemSize = 1;
216
+ }
217
+ if (upload || update) {
218
+ this.programConfigurations.upload(context);
219
+ }
220
+ }
221
+
222
+ destroy() {
223
+ if (!this.layoutVertexBuffer) return;
224
+ this.layoutVertexBuffer.destroy();
225
+ this.indexBuffer.destroy();
226
+ this.programConfigurations.destroy();
227
+ this.segments.destroy();
228
+ this.dynamicLayoutVertexBuffer.destroy();
229
+ this.opacityVertexBuffer.destroy();
230
+ }
231
+ }
232
+
233
+ register('SymbolBuffers', SymbolBuffers);
234
+
235
+ class CollisionBuffers {
236
+ layoutVertexArray: StructArray;
237
+ layoutAttributes: Array<StructArrayMember>;
238
+ layoutVertexBuffer: VertexBuffer;
239
+
240
+ indexArray: TriangleIndexArray | LineIndexArray;
241
+ indexBuffer: IndexBuffer;
242
+
243
+ segments: SegmentVector;
244
+
245
+ collisionVertexArray: CollisionVertexArray;
246
+ collisionVertexBuffer: VertexBuffer;
247
+
248
+ constructor(LayoutArray: {
249
+ new (...args: any): StructArray;
250
+ },
251
+ layoutAttributes: Array<StructArrayMember>,
252
+ IndexArray: {
253
+ new (...args: any): TriangleIndexArray | LineIndexArray;
254
+ }) {
255
+ this.layoutVertexArray = new LayoutArray();
256
+ this.layoutAttributes = layoutAttributes;
257
+ this.indexArray = new IndexArray();
258
+ this.segments = new SegmentVector();
259
+ this.collisionVertexArray = new CollisionVertexArray();
260
+ }
261
+
262
+ upload(context: Context) {
263
+ this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, this.layoutAttributes);
264
+ this.indexBuffer = context.createIndexBuffer(this.indexArray);
265
+ this.collisionVertexBuffer = context.createVertexBuffer(this.collisionVertexArray, collisionVertexAttributes.members, true);
266
+ }
267
+
268
+ destroy() {
269
+ if (!this.layoutVertexBuffer) return;
270
+ this.layoutVertexBuffer.destroy();
271
+ this.indexBuffer.destroy();
272
+ this.segments.destroy();
273
+ this.collisionVertexBuffer.destroy();
274
+ }
275
+ }
276
+
277
+ register('CollisionBuffers', CollisionBuffers);
278
+
279
+ /**
280
+ * @internal
281
+ * Unlike other buckets, which simply implement #addFeature with type-specific
282
+ * logic for (essentially) triangulating feature geometries, SymbolBucket
283
+ * requires specialized behavior:
284
+ *
285
+ * 1. WorkerTile#parse(), the logical owner of the bucket creation process,
286
+ * calls SymbolBucket#populate(), which resolves text and icon tokens on
287
+ * each feature, adds each glyphs and symbols needed to the passed-in
288
+ * collections options.glyphDependencies and options.iconDependencies, and
289
+ * stores the feature data for use in subsequent step (this.features).
290
+ *
291
+ * 2. WorkerTile asynchronously requests from the main thread all of the glyphs
292
+ * and icons needed (by this bucket and any others). When glyphs and icons
293
+ * have been received, the WorkerTile creates a CollisionIndex and invokes:
294
+ *
295
+ * 3. performSymbolLayout(bucket, stacks, icons) perform texts shaping and
296
+ * layout on a Symbol Bucket. This step populates:
297
+ * `this.symbolInstances`: metadata on generated symbols
298
+ * `this.collisionBoxArray`: collision data for use by foreground
299
+ * `this.text`: SymbolBuffers for text symbols
300
+ * `this.icons`: SymbolBuffers for icons
301
+ * `this.iconCollisionBox`: Debug SymbolBuffers for icon collision boxes
302
+ * `this.textCollisionBox`: Debug SymbolBuffers for text collision boxes
303
+ * The results are sent to the foreground for rendering
304
+ *
305
+ * 4. placement.ts is run on the foreground,
306
+ * and uses the CollisionIndex along with current camera settings to determine
307
+ * which symbols can actually show on the map. Collided symbols are hidden
308
+ * using a dynamic "OpacityVertexArray".
309
+ */
310
+ export class SymbolBucket implements Bucket {
311
+ static MAX_GLYPHS: number;
312
+ static addDynamicAttributes: typeof addDynamicAttributes;
313
+
314
+ collisionBoxArray: CollisionBoxArray;
315
+ zoom: number;
316
+ overscaling: number;
317
+ layers: Array<SymbolStyleLayer>;
318
+ layerIds: Array<string>;
319
+ stateDependentLayers: Array<SymbolStyleLayer>;
320
+ stateDependentLayerIds: Array<string>;
321
+
322
+ index: number;
323
+ sdfIcons: boolean;
324
+ iconsInText: boolean;
325
+ iconsNeedLinear: boolean;
326
+ bucketInstanceId: number;
327
+ justReloaded: boolean;
328
+ hasPattern: boolean;
329
+
330
+ textSizeData: SizeData;
331
+ iconSizeData: SizeData;
332
+
333
+ glyphOffsetArray: GlyphOffsetArray;
334
+ lineVertexArray: SymbolLineVertexArray;
335
+ features: Array<SymbolFeature>;
336
+ symbolInstances: SymbolInstanceArray;
337
+ textAnchorOffsets: TextAnchorOffsetArray;
338
+ collisionArrays: Array<CollisionArrays>;
339
+ sortKeyRanges: Array<SortKeyRange>;
340
+ pixelRatio: number;
341
+ tilePixelRatio: number;
342
+ compareText: {[_: string]: Array<Point>};
343
+ fadeStartTime: number;
344
+ sortFeaturesByKey: boolean;
345
+ sortFeaturesByY: boolean;
346
+ canOverlap: boolean;
347
+ sortedAngle: number;
348
+ featureSortOrder: Array<number>;
349
+
350
+ collisionCircleArray: Array<number>;
351
+ placementInvProjMatrix: mat4;
352
+ placementViewportMatrix: mat4;
353
+
354
+ text: SymbolBuffers;
355
+ icon: SymbolBuffers;
356
+ textCollisionBox: CollisionBuffers;
357
+ iconCollisionBox: CollisionBuffers;
358
+ uploaded: boolean;
359
+ sourceLayerIndex: number;
360
+ sourceID: string;
361
+ symbolInstanceIndexes: Array<number>;
362
+ writingModes: WritingMode[];
363
+ allowVerticalPlacement: boolean;
364
+ hasRTLText: boolean;
365
+
366
+ constructor(options: BucketParameters<SymbolStyleLayer>) {
367
+ this.collisionBoxArray = options.collisionBoxArray;
368
+ this.zoom = options.zoom;
369
+ this.overscaling = options.overscaling;
370
+ this.layers = options.layers;
371
+ this.layerIds = this.layers.map(layer => layer.id);
372
+ this.index = options.index;
373
+ this.pixelRatio = options.pixelRatio;
374
+ this.sourceLayerIndex = options.sourceLayerIndex;
375
+ this.hasPattern = false;
376
+ this.hasRTLText = false;
377
+ this.sortKeyRanges = [];
378
+
379
+ this.collisionCircleArray = [];
380
+ this.placementInvProjMatrix = mat4.identity([] as any);
381
+ this.placementViewportMatrix = mat4.identity([] as any);
382
+
383
+ const layer = this.layers[0];
384
+ const unevaluatedLayoutValues = layer._unevaluatedLayout._values;
385
+
386
+ this.textSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['text-size']);
387
+ this.iconSizeData = getSizeData(this.zoom, unevaluatedLayoutValues['icon-size']);
388
+
389
+ const layout = this.layers[0].layout;
390
+ const sortKey = layout.get('symbol-sort-key');
391
+ const zOrder = layout.get('symbol-z-order');
392
+ this.canOverlap =
393
+ getOverlapMode(layout, 'text-overlap', 'text-allow-overlap') !== 'never' ||
394
+ getOverlapMode(layout, 'icon-overlap', 'icon-allow-overlap') !== 'never' ||
395
+ layout.get('text-ignore-placement') ||
396
+ layout.get('icon-ignore-placement');
397
+ this.sortFeaturesByKey = zOrder !== 'viewport-y' && !sortKey.isConstant();
398
+ const zOrderByViewportY = zOrder === 'viewport-y' || (zOrder === 'auto' && !this.sortFeaturesByKey);
399
+ this.sortFeaturesByY = zOrderByViewportY && this.canOverlap;
400
+
401
+ if (layout.get('symbol-placement') === 'point') {
402
+ this.writingModes = layout.get('text-writing-mode').map(wm => WritingMode[wm]);
403
+ }
404
+
405
+ this.stateDependentLayerIds = this.layers.filter((l) => l.isStateDependent()).map((l) => l.id);
406
+
407
+ this.sourceID = options.sourceID;
408
+ }
409
+
410
+ createArrays() {
411
+ this.text = new SymbolBuffers(new ProgramConfigurationSet(this.layers, this.zoom, property => /^text/.test(property)));
412
+ this.icon = new SymbolBuffers(new ProgramConfigurationSet(this.layers, this.zoom, property => /^icon/.test(property)));
413
+
414
+ this.glyphOffsetArray = new GlyphOffsetArray();
415
+ this.lineVertexArray = new SymbolLineVertexArray();
416
+ this.symbolInstances = new SymbolInstanceArray();
417
+ this.textAnchorOffsets = new TextAnchorOffsetArray();
418
+ }
419
+
420
+ private calculateGlyphDependencies(
421
+ text: string,
422
+ stack: {[_: number]: boolean},
423
+ textAlongLine: boolean,
424
+ allowVerticalPlacement: boolean,
425
+ doesAllowVerticalWritingMode: boolean) {
426
+
427
+ for (let i = 0; i < text.length; i++) {
428
+ stack[text.charCodeAt(i)] = true;
429
+ if ((textAlongLine || allowVerticalPlacement) && doesAllowVerticalWritingMode) {
430
+ const verticalChar = verticalizedCharacterMap[text.charAt(i)];
431
+ if (verticalChar) {
432
+ stack[verticalChar.charCodeAt(0)] = true;
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ populate(features: Array<IndexedFeature>, options: PopulateParameters, canonical: CanonicalTileID) {
439
+ const layer = this.layers[0];
440
+ const layout = layer.layout;
441
+
442
+ const textFont = layout.get('text-font');
443
+ const textField = layout.get('text-field');
444
+ const iconImage = layout.get('icon-image');
445
+ const hasText =
446
+ (textField.value.kind !== 'constant' ||
447
+ (textField.value.value instanceof Formatted && !textField.value.value.isEmpty()) ||
448
+ textField.value.value.toString().length > 0) &&
449
+ (textFont.value.kind !== 'constant' || textFont.value.value.length > 0);
450
+ // we should always resolve the icon-image value if the property was defined in the style
451
+ // this allows us to fire the styleimagemissing event if image evaluation returns null
452
+ // the only way to distinguish between null returned from a coalesce statement with no valid images
453
+ // and null returned because icon-image wasn't defined is to check whether or not iconImage.parameters is an empty object
454
+ const hasIcon = iconImage.value.kind !== 'constant' || !!iconImage.value.value || Object.keys(iconImage.parameters).length > 0;
455
+ const symbolSortKey = layout.get('symbol-sort-key');
456
+
457
+ this.features = [];
458
+
459
+ if (!hasText && !hasIcon) {
460
+ return;
461
+ }
462
+
463
+ const icons = options.iconDependencies;
464
+ const stacks = options.glyphDependencies;
465
+ const availableImages = options.availableImages;
466
+ const globalProperties = new EvaluationParameters(this.zoom);
467
+
468
+ for (const {feature, id, index, sourceLayerIndex} of features) {
469
+
470
+ const needGeometry = layer._featureFilter.needGeometry;
471
+ const evaluationFeature = toEvaluationFeature(feature, needGeometry);
472
+ if (!layer._featureFilter.filter(globalProperties, evaluationFeature, canonical)) {
473
+ continue;
474
+ }
475
+
476
+ if (!needGeometry) evaluationFeature.geometry = loadGeometry(feature);
477
+
478
+ let text: Formatted | void;
479
+ if (hasText) {
480
+ // Expression evaluation will automatically coerce to Formatted
481
+ // but plain string token evaluation skips that pathway so do the
482
+ // conversion here.
483
+ const resolvedTokens = layer.getValueAndResolveTokens('text-field', evaluationFeature, canonical, availableImages);
484
+ const formattedText = Formatted.factory(resolvedTokens);
485
+
486
+ // on this instance: if hasRTLText is already true, all future calls to containsRTLText can be skipped.
487
+ const bucketHasRTLText = this.hasRTLText = (this.hasRTLText || containsRTLText(formattedText));
488
+ if (
489
+ !bucketHasRTLText || // non-rtl text so can proceed safely
490
+ rtlWorkerPlugin.getRTLTextPluginStatus() === 'unavailable' || // We don't intend to lazy-load the rtl text plugin, so proceed with incorrect shaping
491
+ bucketHasRTLText && rtlWorkerPlugin.isParsed() // Use the rtlText plugin to shape text
492
+ ) {
493
+ text = transformText(formattedText, layer, evaluationFeature);
494
+ }
495
+ }
496
+
497
+ let icon: ResolvedImage;
498
+ if (hasIcon) {
499
+ // Expression evaluation will automatically coerce to Image
500
+ // but plain string token evaluation skips that pathway so do the
501
+ // conversion here.
502
+ const resolvedTokens = layer.getValueAndResolveTokens('icon-image', evaluationFeature, canonical, availableImages);
503
+ if (resolvedTokens instanceof ResolvedImage) {
504
+ icon = resolvedTokens;
505
+ } else {
506
+ icon = ResolvedImage.fromString(resolvedTokens);
507
+ }
508
+ }
509
+
510
+ if (!text && !icon) {
511
+ continue;
512
+ }
513
+ const sortKey = this.sortFeaturesByKey ?
514
+ symbolSortKey.evaluate(evaluationFeature, {}, canonical) :
515
+ undefined;
516
+
517
+ const symbolFeature: SymbolFeature = {
518
+ id,
519
+ text,
520
+ icon,
521
+ index,
522
+ sourceLayerIndex,
523
+ geometry: evaluationFeature.geometry,
524
+ properties: feature.properties,
525
+ type: vectorTileFeatureTypes[feature.type],
526
+ sortKey
527
+ };
528
+ this.features.push(symbolFeature);
529
+
530
+ if (icon) {
531
+ icons[icon.name] = true;
532
+ }
533
+
534
+ if (text) {
535
+ const fontStack = textFont.evaluate(evaluationFeature, {}, canonical).join(',');
536
+ const textAlongLine = layout.get('text-rotation-alignment') !== 'viewport' && layout.get('symbol-placement') !== 'point';
537
+ this.allowVerticalPlacement = this.writingModes && this.writingModes.indexOf(WritingMode.vertical) >= 0;
538
+ for (const section of text.sections) {
539
+ if (!section.image) {
540
+ const doesAllowVerticalWritingMode = allowsVerticalWritingMode(text.toString());
541
+ const sectionFont = section.fontStack || fontStack;
542
+ const sectionStack = stacks[sectionFont] = stacks[sectionFont] || {};
543
+ this.calculateGlyphDependencies(section.text, sectionStack, textAlongLine, this.allowVerticalPlacement, doesAllowVerticalWritingMode);
544
+ } else {
545
+ // Add section image to the list of dependencies.
546
+ icons[section.image.name] = true;
547
+ }
548
+ }
549
+ }
550
+ }
551
+
552
+ if (layout.get('symbol-placement') === 'line') {
553
+ // Merge adjacent lines with the same text to improve labelling.
554
+ // It's better to place labels on one long line than on many short segments.
555
+ this.features = mergeLines(this.features);
556
+ }
557
+
558
+ if (this.sortFeaturesByKey) {
559
+ this.features.sort((a, b) => {
560
+ // a.sortKey is always a number when sortFeaturesByKey is true
561
+ return (a.sortKey as number) - (b.sortKey as number);
562
+ });
563
+ }
564
+ }
565
+
566
+ update(states: FeatureStates, vtLayer: VectorTileLayer, imagePositions: {[_: string]: ImagePosition}) {
567
+ if (!this.stateDependentLayers.length) return;
568
+ this.text.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, imagePositions);
569
+ this.icon.programConfigurations.updatePaintArrays(states, vtLayer, this.layers, imagePositions);
570
+ }
571
+
572
+ isEmpty() {
573
+ // When the bucket encounters only rtl-text but the plugin isn't loaded, no symbol instances will be created.
574
+ // In order for the bucket to be serialized, and not discarded as an empty bucket both checks are necessary.
575
+ return this.symbolInstances.length === 0 && !this.hasRTLText;
576
+ }
577
+
578
+ uploadPending() {
579
+ return !this.uploaded || this.text.programConfigurations.needsUpload || this.icon.programConfigurations.needsUpload;
580
+ }
581
+
582
+ upload(context: Context) {
583
+ if (!this.uploaded && this.hasDebugData()) {
584
+ this.textCollisionBox.upload(context);
585
+ this.iconCollisionBox.upload(context);
586
+ }
587
+ this.text.upload(context, this.sortFeaturesByY, !this.uploaded, this.text.programConfigurations.needsUpload);
588
+ this.icon.upload(context, this.sortFeaturesByY, !this.uploaded, this.icon.programConfigurations.needsUpload);
589
+ this.uploaded = true;
590
+ }
591
+
592
+ destroyDebugData() {
593
+ this.textCollisionBox.destroy();
594
+ this.iconCollisionBox.destroy();
595
+ }
596
+
597
+ destroy() {
598
+ this.text.destroy();
599
+ this.icon.destroy();
600
+
601
+ if (this.hasDebugData()) {
602
+ this.destroyDebugData();
603
+ }
604
+ }
605
+
606
+ addToLineVertexArray(anchor: Anchor, line: any) {
607
+ const lineStartIndex = this.lineVertexArray.length;
608
+ if (anchor.segment !== undefined) {
609
+ let sumForwardLength = anchor.dist(line[anchor.segment + 1]);
610
+ let sumBackwardLength = anchor.dist(line[anchor.segment]);
611
+ const vertices = {};
612
+ for (let i = anchor.segment + 1; i < line.length; i++) {
613
+ vertices[i] = {x: line[i].x, y: line[i].y, tileUnitDistanceFromAnchor: sumForwardLength};
614
+ if (i < line.length - 1) {
615
+ sumForwardLength += line[i + 1].dist(line[i]);
616
+ }
617
+ }
618
+ for (let i = anchor.segment || 0; i >= 0; i--) {
619
+ vertices[i] = {x: line[i].x, y: line[i].y, tileUnitDistanceFromAnchor: sumBackwardLength};
620
+ if (i > 0) {
621
+ sumBackwardLength += line[i - 1].dist(line[i]);
622
+ }
623
+ }
624
+ for (let i = 0; i < line.length; i++) {
625
+ const vertex = vertices[i];
626
+ this.lineVertexArray.emplaceBack(vertex.x, vertex.y, vertex.tileUnitDistanceFromAnchor);
627
+ }
628
+ }
629
+ return {
630
+ lineStartIndex,
631
+ lineLength: this.lineVertexArray.length - lineStartIndex
632
+ };
633
+ }
634
+
635
+ addSymbols(arrays: SymbolBuffers,
636
+ quads: Array<SymbolQuad>,
637
+ sizeVertex: any,
638
+ lineOffset: [number, number],
639
+ alongLine: boolean,
640
+ feature: SymbolFeature,
641
+ writingMode: WritingMode,
642
+ labelAnchor: Anchor,
643
+ lineStartIndex: number,
644
+ lineLength: number,
645
+ associatedIconIndex: number,
646
+ canonical: CanonicalTileID) {
647
+ const indexArray = arrays.indexArray;
648
+ const layoutVertexArray = arrays.layoutVertexArray;
649
+
650
+ const segment = arrays.segments.prepareSegment(4 * quads.length, layoutVertexArray, indexArray, this.canOverlap ? feature.sortKey as number : undefined);
651
+ const glyphOffsetArrayStart = this.glyphOffsetArray.length;
652
+ const vertexStartIndex = segment.vertexLength;
653
+
654
+ const angle = (this.allowVerticalPlacement && writingMode === WritingMode.vertical) ? Math.PI / 2 : 0;
655
+
656
+ const sections = feature.text && feature.text.sections;
657
+
658
+ for (let i = 0; i < quads.length; i++) {
659
+ const {tl, tr, bl, br, tex, pixelOffsetTL, pixelOffsetBR, minFontScaleX, minFontScaleY, glyphOffset, isSDF, sectionIndex} = quads[i];
660
+ const index = segment.vertexLength;
661
+
662
+ const y = glyphOffset[1];
663
+ addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, tl.x, y + tl.y, tex.x, tex.y, sizeVertex, isSDF, pixelOffsetTL.x, pixelOffsetTL.y, minFontScaleX, minFontScaleY);
664
+ addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, tr.x, y + tr.y, tex.x + tex.w, tex.y, sizeVertex, isSDF, pixelOffsetBR.x, pixelOffsetTL.y, minFontScaleX, minFontScaleY);
665
+ addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, bl.x, y + bl.y, tex.x, tex.y + tex.h, sizeVertex, isSDF, pixelOffsetTL.x, pixelOffsetBR.y, minFontScaleX, minFontScaleY);
666
+ addVertex(layoutVertexArray, labelAnchor.x, labelAnchor.y, br.x, y + br.y, tex.x + tex.w, tex.y + tex.h, sizeVertex, isSDF, pixelOffsetBR.x, pixelOffsetBR.y, minFontScaleX, minFontScaleY);
667
+
668
+ addDynamicAttributes(arrays.dynamicLayoutVertexArray, labelAnchor, angle);
669
+
670
+ indexArray.emplaceBack(index, index + 1, index + 2);
671
+ indexArray.emplaceBack(index + 1, index + 2, index + 3);
672
+
673
+ segment.vertexLength += 4;
674
+ segment.primitiveLength += 2;
675
+
676
+ this.glyphOffsetArray.emplaceBack(glyphOffset[0]);
677
+
678
+ if (i === quads.length - 1 || sectionIndex !== quads[i + 1].sectionIndex) {
679
+ arrays.programConfigurations.populatePaintArrays(layoutVertexArray.length, feature, feature.index, {}, canonical, sections && sections[sectionIndex]);
680
+ }
681
+ }
682
+
683
+ arrays.placedSymbolArray.emplaceBack(
684
+ labelAnchor.x, labelAnchor.y,
685
+ glyphOffsetArrayStart,
686
+ this.glyphOffsetArray.length - glyphOffsetArrayStart,
687
+ vertexStartIndex,
688
+ lineStartIndex,
689
+ lineLength,
690
+ labelAnchor.segment,
691
+ sizeVertex ? sizeVertex[0] : 0,
692
+ sizeVertex ? sizeVertex[1] : 0,
693
+ lineOffset[0], lineOffset[1],
694
+ writingMode,
695
+ // placedOrientation is null initially; will be updated to horizontal(1)/vertical(2) if placed
696
+ 0,
697
+ false as unknown as number,
698
+ // The crossTileID is only filled/used on the foreground for dynamic text anchors
699
+ 0,
700
+ associatedIconIndex
701
+ );
702
+ }
703
+
704
+ _addCollisionDebugVertex(layoutVertexArray: StructArray, collisionVertexArray: StructArray, point: Point, anchorX: number, anchorY: number, extrude: Point) {
705
+ collisionVertexArray.emplaceBack(0, 0);
706
+ return layoutVertexArray.emplaceBack(
707
+ // pos
708
+ point.x,
709
+ point.y,
710
+ // a_anchor_pos
711
+ anchorX,
712
+ anchorY,
713
+ // extrude
714
+ Math.round(extrude.x),
715
+ Math.round(extrude.y));
716
+ }
717
+
718
+ addCollisionDebugVertices(x1: number, y1: number, x2: number, y2: number, arrays: CollisionBuffers, boxAnchorPoint: Point, symbolInstance: SymbolInstance) {
719
+ const segment = arrays.segments.prepareSegment(4, arrays.layoutVertexArray, arrays.indexArray);
720
+ const index = segment.vertexLength;
721
+
722
+ const layoutVertexArray = arrays.layoutVertexArray;
723
+ const collisionVertexArray = arrays.collisionVertexArray;
724
+
725
+ const anchorX = symbolInstance.anchorX;
726
+ const anchorY = symbolInstance.anchorY;
727
+
728
+ this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new Point(x1, y1));
729
+ this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new Point(x2, y1));
730
+ this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new Point(x2, y2));
731
+ this._addCollisionDebugVertex(layoutVertexArray, collisionVertexArray, boxAnchorPoint, anchorX, anchorY, new Point(x1, y2));
732
+
733
+ segment.vertexLength += 4;
734
+
735
+ const indexArray = arrays.indexArray as LineIndexArray;
736
+ indexArray.emplaceBack(index, index + 1);
737
+ indexArray.emplaceBack(index + 1, index + 2);
738
+ indexArray.emplaceBack(index + 2, index + 3);
739
+ indexArray.emplaceBack(index + 3, index);
740
+
741
+ segment.primitiveLength += 4;
742
+ }
743
+
744
+ addDebugCollisionBoxes(startIndex: number, endIndex: number, symbolInstance: SymbolInstance, isText: boolean) {
745
+ for (let b = startIndex; b < endIndex; b++) {
746
+ const box: CollisionBox = this.collisionBoxArray.get(b);
747
+ const x1 = box.x1;
748
+ const y1 = box.y1;
749
+ const x2 = box.x2;
750
+ const y2 = box.y2;
751
+
752
+ this.addCollisionDebugVertices(x1, y1, x2, y2,
753
+ isText ? this.textCollisionBox : this.iconCollisionBox,
754
+ box.anchorPoint, symbolInstance);
755
+ }
756
+ }
757
+
758
+ generateCollisionDebugBuffers() {
759
+ if (this.hasDebugData()) {
760
+ this.destroyDebugData();
761
+ }
762
+
763
+ this.textCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
764
+ this.iconCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
765
+
766
+ for (let i = 0; i < this.symbolInstances.length; i++) {
767
+ const symbolInstance = this.symbolInstances.get(i);
768
+ this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance, true);
769
+ this.addDebugCollisionBoxes(symbolInstance.verticalTextBoxStartIndex, symbolInstance.verticalTextBoxEndIndex, symbolInstance, true);
770
+ this.addDebugCollisionBoxes(symbolInstance.iconBoxStartIndex, symbolInstance.iconBoxEndIndex, symbolInstance, false);
771
+ this.addDebugCollisionBoxes(symbolInstance.verticalIconBoxStartIndex, symbolInstance.verticalIconBoxEndIndex, symbolInstance, false);
772
+ }
773
+ }
774
+
775
+ // These flat arrays are meant to be quicker to iterate over than the source
776
+ // CollisionBoxArray
777
+ _deserializeCollisionBoxesForSymbol(
778
+ collisionBoxArray: CollisionBoxArray,
779
+ textStartIndex: number,
780
+ textEndIndex: number,
781
+ verticalTextStartIndex: number,
782
+ verticalTextEndIndex: number,
783
+ iconStartIndex: number,
784
+ iconEndIndex: number,
785
+ verticalIconStartIndex: number,
786
+ verticalIconEndIndex: number
787
+ ): CollisionArrays {
788
+
789
+ const collisionArrays = {} as CollisionArrays;
790
+ for (let k = textStartIndex; k < textEndIndex; k++) {
791
+ const box: CollisionBox = collisionBoxArray.get(k);
792
+ collisionArrays.textBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, anchorPointX: box.anchorPointX, anchorPointY: box.anchorPointY};
793
+ collisionArrays.textFeatureIndex = box.featureIndex;
794
+ break; // Only one box allowed per instance
795
+ }
796
+ for (let k = verticalTextStartIndex; k < verticalTextEndIndex; k++) {
797
+ const box: CollisionBox = collisionBoxArray.get(k);
798
+ collisionArrays.verticalTextBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, anchorPointX: box.anchorPointX, anchorPointY: box.anchorPointY};
799
+ collisionArrays.verticalTextFeatureIndex = box.featureIndex;
800
+ break; // Only one box allowed per instance
801
+ }
802
+ for (let k = iconStartIndex; k < iconEndIndex; k++) {
803
+ // An icon can only have one box now, so this indexing is a bit vestigial...
804
+ const box: CollisionBox = collisionBoxArray.get(k);
805
+ collisionArrays.iconBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, anchorPointX: box.anchorPointX, anchorPointY: box.anchorPointY};
806
+ collisionArrays.iconFeatureIndex = box.featureIndex;
807
+ break; // Only one box allowed per instance
808
+ }
809
+ for (let k = verticalIconStartIndex; k < verticalIconEndIndex; k++) {
810
+ // An icon can only have one box now, so this indexing is a bit vestigial...
811
+ const box: CollisionBox = collisionBoxArray.get(k);
812
+ collisionArrays.verticalIconBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, anchorPointX: box.anchorPointX, anchorPointY: box.anchorPointY};
813
+ collisionArrays.verticalIconFeatureIndex = box.featureIndex;
814
+ break; // Only one box allowed per instance
815
+ }
816
+ return collisionArrays;
817
+ }
818
+
819
+ deserializeCollisionBoxes(collisionBoxArray: CollisionBoxArray) {
820
+ this.collisionArrays = [];
821
+ for (let i = 0; i < this.symbolInstances.length; i++) {
822
+ const symbolInstance = this.symbolInstances.get(i);
823
+ this.collisionArrays.push(this._deserializeCollisionBoxesForSymbol(
824
+ collisionBoxArray,
825
+ symbolInstance.textBoxStartIndex,
826
+ symbolInstance.textBoxEndIndex,
827
+ symbolInstance.verticalTextBoxStartIndex,
828
+ symbolInstance.verticalTextBoxEndIndex,
829
+ symbolInstance.iconBoxStartIndex,
830
+ symbolInstance.iconBoxEndIndex,
831
+ symbolInstance.verticalIconBoxStartIndex,
832
+ symbolInstance.verticalIconBoxEndIndex
833
+ ));
834
+ }
835
+ }
836
+
837
+ hasTextData() {
838
+ return this.text.segments.get().length > 0;
839
+ }
840
+
841
+ hasIconData() {
842
+ return this.icon.segments.get().length > 0;
843
+ }
844
+
845
+ hasDebugData() {
846
+ return this.textCollisionBox && this.iconCollisionBox;
847
+ }
848
+
849
+ hasTextCollisionBoxData() {
850
+ return this.hasDebugData() && this.textCollisionBox.segments.get().length > 0;
851
+ }
852
+
853
+ hasIconCollisionBoxData() {
854
+ return this.hasDebugData() && this.iconCollisionBox.segments.get().length > 0;
855
+ }
856
+
857
+ addIndicesForPlacedSymbol(iconOrText: SymbolBuffers, placedSymbolIndex: number) {
858
+ const placedSymbol = iconOrText.placedSymbolArray.get(placedSymbolIndex);
859
+
860
+ const endIndex = placedSymbol.vertexStartIndex + placedSymbol.numGlyphs * 4;
861
+ for (let vertexIndex = placedSymbol.vertexStartIndex; vertexIndex < endIndex; vertexIndex += 4) {
862
+ iconOrText.indexArray.emplaceBack(vertexIndex, vertexIndex + 1, vertexIndex + 2);
863
+ iconOrText.indexArray.emplaceBack(vertexIndex + 1, vertexIndex + 2, vertexIndex + 3);
864
+ }
865
+ }
866
+
867
+ getSortedSymbolIndexes(angle: number) {
868
+ if (this.sortedAngle === angle && this.symbolInstanceIndexes !== undefined) {
869
+ return this.symbolInstanceIndexes;
870
+ }
871
+ const sin = Math.sin(angle);
872
+ const cos = Math.cos(angle);
873
+ const rotatedYs = [];
874
+ const featureIndexes = [];
875
+ const result = [];
876
+
877
+ for (let i = 0; i < this.symbolInstances.length; ++i) {
878
+ result.push(i);
879
+ const symbolInstance = this.symbolInstances.get(i);
880
+ rotatedYs.push(Math.round(sin * symbolInstance.anchorX + cos * symbolInstance.anchorY) | 0);
881
+ featureIndexes.push(symbolInstance.featureIndex);
882
+ }
883
+
884
+ result.sort((aIndex, bIndex) => {
885
+ return (rotatedYs[aIndex] - rotatedYs[bIndex]) ||
886
+ (featureIndexes[bIndex] - featureIndexes[aIndex]);
887
+ });
888
+
889
+ return result;
890
+ }
891
+
892
+ addToSortKeyRanges(symbolInstanceIndex: number, sortKey: number) {
893
+ const last = this.sortKeyRanges[this.sortKeyRanges.length - 1];
894
+ if (last && last.sortKey === sortKey) {
895
+ last.symbolInstanceEnd = symbolInstanceIndex + 1;
896
+ } else {
897
+ this.sortKeyRanges.push({
898
+ sortKey,
899
+ symbolInstanceStart: symbolInstanceIndex,
900
+ symbolInstanceEnd: symbolInstanceIndex + 1
901
+ });
902
+ }
903
+ }
904
+
905
+ sortFeatures(angle: number) {
906
+ if (!this.sortFeaturesByY) return;
907
+ if (this.sortedAngle === angle) return;
908
+
909
+ // The current approach to sorting doesn't sort across segments so don't try.
910
+ // Sorting within segments separately seemed not to be worth the complexity.
911
+ if (this.text.segments.get().length > 1 || this.icon.segments.get().length > 1) return;
912
+
913
+ // If the symbols are allowed to overlap sort them by their vertical screen position.
914
+ // The index array buffer is rewritten to reference the (unchanged) vertices in the
915
+ // sorted order.
916
+
917
+ // To avoid sorting the actual symbolInstance array we sort an array of indexes.
918
+ this.symbolInstanceIndexes = this.getSortedSymbolIndexes(angle);
919
+ this.sortedAngle = angle;
920
+
921
+ this.text.indexArray.clear();
922
+ this.icon.indexArray.clear();
923
+
924
+ this.featureSortOrder = [];
925
+
926
+ for (const i of this.symbolInstanceIndexes) {
927
+ const symbolInstance = this.symbolInstances.get(i);
928
+ this.featureSortOrder.push(symbolInstance.featureIndex);
929
+
930
+ [
931
+ symbolInstance.rightJustifiedTextSymbolIndex,
932
+ symbolInstance.centerJustifiedTextSymbolIndex,
933
+ symbolInstance.leftJustifiedTextSymbolIndex
934
+ ].forEach((index, i, array) => {
935
+ // Only add a given index the first time it shows up,
936
+ // to avoid duplicate opacity entries when multiple justifications
937
+ // share the same glyphs.
938
+ if (index >= 0 && array.indexOf(index) === i) {
939
+ this.addIndicesForPlacedSymbol(this.text, index);
940
+ }
941
+ });
942
+
943
+ if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) {
944
+ this.addIndicesForPlacedSymbol(this.text, symbolInstance.verticalPlacedTextSymbolIndex);
945
+ }
946
+
947
+ if (symbolInstance.placedIconSymbolIndex >= 0) {
948
+ this.addIndicesForPlacedSymbol(this.icon, symbolInstance.placedIconSymbolIndex);
949
+ }
950
+
951
+ if (symbolInstance.verticalPlacedIconSymbolIndex >= 0) {
952
+ this.addIndicesForPlacedSymbol(this.icon, symbolInstance.verticalPlacedIconSymbolIndex);
953
+ }
954
+ }
955
+
956
+ if (this.text.indexBuffer) this.text.indexBuffer.updateData(this.text.indexArray);
957
+ if (this.icon.indexBuffer) this.icon.indexBuffer.updateData(this.icon.indexArray);
958
+ }
959
+ }
960
+
961
+ register('SymbolBucket', SymbolBucket, {
962
+ omit: ['layers', 'collisionBoxArray', 'features', 'compareText']
963
+ });
964
+
965
+ // this constant is based on the size of StructArray indexes used in a symbol
966
+ // bucket--namely, glyphOffsetArrayStart
967
+ // eg the max valid UInt16 is 65,535
968
+ // See https://github.com/mapbox/mapbox-gl-js/issues/2907 for motivation
969
+ // lineStartIndex and textBoxStartIndex could potentially be concerns
970
+ // but we expect there to be many fewer boxes/lines than glyphs
971
+ SymbolBucket.MAX_GLYPHS = 65535;
972
+
973
+ SymbolBucket.addDynamicAttributes = addDynamicAttributes;
974
+
975
+ export {addDynamicAttributes};