@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,618 @@
1
+ import Point from '@mapbox/point-geometry';
2
+ import {clipLine} from './clip_line';
3
+ import {PathInterpolator} from './path_interpolator';
4
+
5
+ import * as intersectionTests from '../util/intersection_tests';
6
+ import {GridIndex} from './grid_index';
7
+ import {mat4, vec4} from 'gl-matrix';
8
+ import ONE_EM from '../symbol/one_em';
9
+
10
+ import * as projection from '../symbol/projection';
11
+
12
+ import type {Transform} from '../geo/transform';
13
+ import type {SingleCollisionBox} from '../data/bucket/symbol_bucket';
14
+ import type {
15
+ GlyphOffsetArray,
16
+ SymbolLineVertexArray
17
+ } from '../data/array_types.g';
18
+ import type {OverlapMode} from '../style/style_layer/overlap_mode';
19
+ import {UnwrappedTileID} from '../source/tile_id';
20
+ import {SymbolProjectionContext} from '../symbol/projection';
21
+ import {Projection} from '../geo/projection/projection';
22
+ import {clamp, getAABB} from '../util/util';
23
+
24
+ // When a symbol crosses the edge that causes it to be included in
25
+ // collision detection, it will cause changes in the symbols around
26
+ // it. This constant specifies how many pixels to pad the edge of
27
+ // the viewport for collision detection so that the bulk of the changes
28
+ // occur offscreen. Making this constant greater increases label
29
+ // stability, but it's expensive.
30
+ export const viewportPadding = 100;
31
+
32
+ export type PlacedCircles = {
33
+ circles: Array<number>;
34
+ offscreen: boolean;
35
+ collisionDetected: boolean;
36
+ };
37
+
38
+ export type PlacedBox = {
39
+ box: Array<number>;
40
+ placeable: boolean;
41
+ offscreen: boolean;
42
+ };
43
+
44
+ export type FeatureKey = {
45
+ bucketInstanceId: number;
46
+ featureIndex: number;
47
+ collisionGroupID: number;
48
+ overlapMode: OverlapMode;
49
+ };
50
+
51
+ type ProjectedBox = {
52
+ /**
53
+ * The AABB in the format [minX, minY, maxX, maxY].
54
+ */
55
+ box: [number, number, number, number];
56
+ allPointsOccluded: boolean;
57
+ };
58
+
59
+ /**
60
+ * @internal
61
+ * A collision index used to prevent symbols from overlapping. It keep tracks of
62
+ * where previous symbols have been placed and is used to check if a new
63
+ * symbol overlaps with any previously added symbols.
64
+ *
65
+ * There are two steps to insertion: first placeCollisionBox/Circles checks if
66
+ * there's room for a symbol, then insertCollisionBox/Circles actually puts the
67
+ * symbol in the index. The two step process allows paired symbols to be inserted
68
+ * together even if they overlap.
69
+ */
70
+ export class CollisionIndex {
71
+ grid: GridIndex<FeatureKey>;
72
+ ignoredGrid: GridIndex<FeatureKey>;
73
+ transform: Transform;
74
+ pitchFactor: number;
75
+ screenRightBoundary: number;
76
+ screenBottomBoundary: number;
77
+ gridRightBoundary: number;
78
+ gridBottomBoundary: number;
79
+ mapProjection: Projection;
80
+
81
+ // With perspectiveRatio the fontsize is calculated for tilted maps (near = bigger, far = smaller).
82
+ // The cutoff defines a threshold to no longer render labels near the horizon.
83
+ perspectiveRatioCutoff: number;
84
+
85
+ constructor(
86
+ transform: Transform,
87
+ projection: Projection,
88
+ grid = new GridIndex<FeatureKey>(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25),
89
+ ignoredGrid = new GridIndex<FeatureKey>(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25)
90
+ ) {
91
+ this.transform = transform;
92
+ this.mapProjection = projection;
93
+
94
+ this.grid = grid;
95
+ this.ignoredGrid = ignoredGrid;
96
+ this.pitchFactor = Math.cos(transform._pitch) * transform.cameraToCenterDistance;
97
+
98
+ this.screenRightBoundary = transform.width + viewportPadding;
99
+ this.screenBottomBoundary = transform.height + viewportPadding;
100
+ this.gridRightBoundary = transform.width + 2 * viewportPadding;
101
+ this.gridBottomBoundary = transform.height + 2 * viewportPadding;
102
+
103
+ this.perspectiveRatioCutoff = 0.6;
104
+ }
105
+
106
+ placeCollisionBox(
107
+ collisionBox: SingleCollisionBox,
108
+ overlapMode: OverlapMode,
109
+ textPixelRatio: number,
110
+ posMatrix: mat4,
111
+ unwrappedTileID: UnwrappedTileID,
112
+ pitchWithMap: boolean,
113
+ rotateWithMap: boolean,
114
+ translation: [number, number],
115
+ collisionGroupPredicate?: (key: FeatureKey) => boolean,
116
+ getElevation?: (x: number, y: number) => number,
117
+ shift?: Point
118
+ ): PlacedBox {
119
+ const x = collisionBox.anchorPointX + translation[0];
120
+ const y = collisionBox.anchorPointY + translation[1];
121
+ const projectedPoint = this.projectAndGetPerspectiveRatio(
122
+ posMatrix,
123
+ x,
124
+ y,
125
+ unwrappedTileID,
126
+ getElevation
127
+ );
128
+
129
+ const tileToViewport = textPixelRatio * projectedPoint.perspectiveRatio;
130
+
131
+ let projectedBox: ProjectedBox;
132
+
133
+ if (!pitchWithMap && !rotateWithMap) {
134
+ // Fast path for common symbols
135
+ const pointX = projectedPoint.point.x + (shift ? shift.x * tileToViewport : 0);
136
+ const pointY = projectedPoint.point.y + (shift ? shift.y * tileToViewport : 0);
137
+ projectedBox = {
138
+ allPointsOccluded: false,
139
+ box: [
140
+ pointX + collisionBox.x1 * tileToViewport,
141
+ pointY + collisionBox.y1 * tileToViewport,
142
+ pointX + collisionBox.x2 * tileToViewport,
143
+ pointY + collisionBox.y2 * tileToViewport,
144
+ ]
145
+ };
146
+ } else {
147
+ projectedBox = this._projectCollisionBox(
148
+ collisionBox,
149
+ tileToViewport,
150
+ posMatrix,
151
+ unwrappedTileID,
152
+ pitchWithMap,
153
+ rotateWithMap,
154
+ translation,
155
+ projectedPoint,
156
+ getElevation,
157
+ shift
158
+ );
159
+ }
160
+
161
+ const [tlX, tlY, brX, brY] = projectedBox.box;
162
+
163
+ const projectionOccluded = this.mapProjection.useSpecialProjectionForSymbols ? (pitchWithMap ? projectedBox.allPointsOccluded : this.mapProjection.isOccluded(x, y, unwrappedTileID)) : false;
164
+
165
+ if (projectionOccluded || projectedPoint.perspectiveRatio < this.perspectiveRatioCutoff || !this.isInsideGrid(tlX, tlY, brX, brY) ||
166
+ (overlapMode !== 'always' && this.grid.hitTest(tlX, tlY, brX, brY, overlapMode, collisionGroupPredicate))) {
167
+ return {
168
+ box: [tlX, tlY, brX, brY],
169
+ placeable: false,
170
+ offscreen: false
171
+ };
172
+ }
173
+
174
+ return {
175
+ box: [tlX, tlY, brX, brY],
176
+ placeable: true,
177
+ offscreen: this.isOffscreen(tlX, tlY, brX, brY)
178
+ };
179
+ }
180
+
181
+ placeCollisionCircles(
182
+ overlapMode: OverlapMode,
183
+ symbol: any,
184
+ lineVertexArray: SymbolLineVertexArray,
185
+ glyphOffsetArray: GlyphOffsetArray,
186
+ fontSize: number,
187
+ posMatrix: mat4,
188
+ unwrappedTileID: UnwrappedTileID,
189
+ labelPlaneMatrix: mat4,
190
+ labelToScreenMatrix: mat4,
191
+ showCollisionCircles: boolean,
192
+ pitchWithMap: boolean,
193
+ collisionGroupPredicate: (key: FeatureKey) => boolean,
194
+ circlePixelDiameter: number,
195
+ textPixelPadding: number,
196
+ translation: [number, number],
197
+ getElevation: (x: number, y: number) => number
198
+ ): PlacedCircles {
199
+ const placedCollisionCircles = [];
200
+
201
+ const tileUnitAnchorPoint = new Point(symbol.anchorX, symbol.anchorY);
202
+ const perspectiveRatio = this.getPerspectiveRatio(posMatrix, tileUnitAnchorPoint.x, tileUnitAnchorPoint.y, unwrappedTileID, getElevation);
203
+ const labelPlaneFontSize = pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio;
204
+ const labelPlaneFontScale = labelPlaneFontSize / ONE_EM;
205
+
206
+ const projectionCache = {projections: {}, offsets: {}, cachedAnchorPoint: undefined, anyProjectionOccluded: false};
207
+ const lineOffsetX = symbol.lineOffsetX * labelPlaneFontScale;
208
+ const lineOffsetY = symbol.lineOffsetY * labelPlaneFontScale;
209
+
210
+ const projectionContext: SymbolProjectionContext = {
211
+ getElevation,
212
+ labelPlaneMatrix,
213
+ lineVertexArray,
214
+ pitchWithMap,
215
+ projectionCache,
216
+ projection: this.mapProjection,
217
+ tileAnchorPoint: tileUnitAnchorPoint,
218
+ unwrappedTileID,
219
+ width: this.transform.width,
220
+ height: this.transform.height,
221
+ translation
222
+ };
223
+
224
+ const firstAndLastGlyph = projection.placeFirstAndLastGlyph(
225
+ labelPlaneFontScale,
226
+ glyphOffsetArray,
227
+ lineOffsetX,
228
+ lineOffsetY,
229
+ /*flip*/ false,
230
+ symbol,
231
+ false,
232
+ projectionContext);
233
+
234
+ let collisionDetected = false;
235
+ let inGrid = false;
236
+ let entirelyOffscreen = true;
237
+
238
+ if (firstAndLastGlyph) {
239
+ const radius = circlePixelDiameter * 0.5 * perspectiveRatio + textPixelPadding;
240
+ const screenPlaneMin = new Point(-viewportPadding, -viewportPadding);
241
+ const screenPlaneMax = new Point(this.screenRightBoundary, this.screenBottomBoundary);
242
+ const interpolator = new PathInterpolator();
243
+
244
+ // Construct a projected path from projected line vertices. Anchor points are ignored and removed
245
+ const first = firstAndLastGlyph.first;
246
+ const last = firstAndLastGlyph.last;
247
+
248
+ let projectedPath: Array<Point> = [];
249
+ for (let i = first.path.length - 1; i >= 1; i--) {
250
+ projectedPath.push(first.path[i]);
251
+ }
252
+ for (let i = 1; i < last.path.length; i++) {
253
+ projectedPath.push(last.path[i]);
254
+ }
255
+
256
+ // Tolerate a slightly longer distance than one diameter between two adjacent circles
257
+ const circleDist = radius * 2.5;
258
+
259
+ // The path might need to be converted into screen space if a pitched map is used as the label space
260
+ if (labelToScreenMatrix) {
261
+ const screenSpacePath = this.projectPathToScreenSpace(projectedPath, projectionContext, labelToScreenMatrix);
262
+ // Do not try to place collision circles if even one of the points is behind the camera.
263
+ // This is a plausible scenario with big camera pitch angles
264
+ if (screenSpacePath.some(point => point.signedDistanceFromCamera <= 0)) {
265
+ projectedPath = [];
266
+ } else {
267
+ projectedPath = screenSpacePath.map(p => p.point);
268
+ }
269
+ }
270
+
271
+ let segments = [];
272
+
273
+ if (projectedPath.length > 0) {
274
+ // Quickly check if the path is fully inside or outside of the padded collision region.
275
+ // For overlapping paths we'll only create collision circles for the visible segments
276
+ const minPoint = projectedPath[0].clone();
277
+ const maxPoint = projectedPath[0].clone();
278
+
279
+ for (let i = 1; i < projectedPath.length; i++) {
280
+ minPoint.x = Math.min(minPoint.x, projectedPath[i].x);
281
+ minPoint.y = Math.min(minPoint.y, projectedPath[i].y);
282
+ maxPoint.x = Math.max(maxPoint.x, projectedPath[i].x);
283
+ maxPoint.y = Math.max(maxPoint.y, projectedPath[i].y);
284
+ }
285
+
286
+ if (minPoint.x >= screenPlaneMin.x && maxPoint.x <= screenPlaneMax.x &&
287
+ minPoint.y >= screenPlaneMin.y && maxPoint.y <= screenPlaneMax.y) {
288
+ // Quad fully visible
289
+ segments = [projectedPath];
290
+ } else if (maxPoint.x < screenPlaneMin.x || minPoint.x > screenPlaneMax.x ||
291
+ maxPoint.y < screenPlaneMin.y || minPoint.y > screenPlaneMax.y) {
292
+ // Not visible
293
+ segments = [];
294
+ } else {
295
+ segments = clipLine([projectedPath], screenPlaneMin.x, screenPlaneMin.y, screenPlaneMax.x, screenPlaneMax.y);
296
+ }
297
+ }
298
+
299
+ for (const seg of segments) {
300
+ // interpolate positions for collision circles. Add a small padding to both ends of the segment
301
+ interpolator.reset(seg, radius * 0.25);
302
+
303
+ let numCircles = 0;
304
+
305
+ if (interpolator.length <= 0.5 * radius) {
306
+ numCircles = 1;
307
+ } else {
308
+ numCircles = Math.ceil(interpolator.paddedLength / circleDist) + 1;
309
+ }
310
+
311
+ for (let i = 0; i < numCircles; i++) {
312
+ const t = i / Math.max(numCircles - 1, 1);
313
+ const circlePosition = interpolator.lerp(t);
314
+
315
+ // add viewport padding to the position and perform initial collision check
316
+ const centerX = circlePosition.x + viewportPadding;
317
+ const centerY = circlePosition.y + viewportPadding;
318
+
319
+ placedCollisionCircles.push(centerX, centerY, radius, 0);
320
+
321
+ const x1 = centerX - radius;
322
+ const y1 = centerY - radius;
323
+ const x2 = centerX + radius;
324
+ const y2 = centerY + radius;
325
+
326
+ entirelyOffscreen = entirelyOffscreen && this.isOffscreen(x1, y1, x2, y2);
327
+ inGrid = inGrid || this.isInsideGrid(x1, y1, x2, y2);
328
+
329
+ if (overlapMode !== 'always' && this.grid.hitTestCircle(centerX, centerY, radius, overlapMode, collisionGroupPredicate)) {
330
+ // Don't early exit if we're showing the debug circles because we still want to calculate
331
+ // which circles are in use
332
+ collisionDetected = true;
333
+ if (!showCollisionCircles) {
334
+ return {
335
+ circles: [],
336
+ offscreen: false,
337
+ collisionDetected
338
+ };
339
+ }
340
+ }
341
+ }
342
+ }
343
+ }
344
+
345
+ return {
346
+ circles: ((!showCollisionCircles && collisionDetected) || !inGrid || perspectiveRatio < this.perspectiveRatioCutoff) ? [] : placedCollisionCircles,
347
+ offscreen: entirelyOffscreen,
348
+ collisionDetected
349
+ };
350
+ }
351
+
352
+ projectPathToScreenSpace(projectedPath: Array<Point>, projectionContext: SymbolProjectionContext, labelToScreenMatrix: mat4) {
353
+ return projectedPath.map(p => projection.project(p.x, p.y, labelToScreenMatrix, projectionContext.getElevation));
354
+ }
355
+
356
+ /**
357
+ * Because the geometries in the CollisionIndex are an approximation of the shape of
358
+ * symbols on the map, we use the CollisionIndex to look up the symbol part of
359
+ * `queryRenderedFeatures`.
360
+ */
361
+ queryRenderedSymbols(viewportQueryGeometry: Array<Point>) {
362
+ if (viewportQueryGeometry.length === 0 || (this.grid.keysLength() === 0 && this.ignoredGrid.keysLength() === 0)) {
363
+ return {};
364
+ }
365
+
366
+ const query = [];
367
+ let minX = Infinity;
368
+ let minY = Infinity;
369
+ let maxX = -Infinity;
370
+ let maxY = -Infinity;
371
+ for (const point of viewportQueryGeometry) {
372
+ const gridPoint = new Point(point.x + viewportPadding, point.y + viewportPadding);
373
+ minX = Math.min(minX, gridPoint.x);
374
+ minY = Math.min(minY, gridPoint.y);
375
+ maxX = Math.max(maxX, gridPoint.x);
376
+ maxY = Math.max(maxY, gridPoint.y);
377
+ query.push(gridPoint);
378
+ }
379
+
380
+ const features = this.grid.query(minX, minY, maxX, maxY)
381
+ .concat(this.ignoredGrid.query(minX, minY, maxX, maxY));
382
+
383
+ const seenFeatures = {};
384
+ const result = {};
385
+
386
+ for (const feature of features) {
387
+ const featureKey = feature.key;
388
+ // Skip already seen features.
389
+ if (seenFeatures[featureKey.bucketInstanceId] === undefined) {
390
+ seenFeatures[featureKey.bucketInstanceId] = {};
391
+ }
392
+ if (seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex]) {
393
+ continue;
394
+ }
395
+
396
+ // Check if query intersects with the feature box
397
+ // "Collision Circles" for line labels are treated as boxes here
398
+ // Since there's no actual collision taking place, the circle vs. square
399
+ // distinction doesn't matter as much, and box geometry is easier
400
+ // to work with.
401
+ const bbox = [
402
+ new Point(feature.x1, feature.y1),
403
+ new Point(feature.x2, feature.y1),
404
+ new Point(feature.x2, feature.y2),
405
+ new Point(feature.x1, feature.y2)
406
+ ];
407
+ if (!intersectionTests.polygonIntersectsPolygon(query, bbox)) {
408
+ continue;
409
+ }
410
+
411
+ seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex] = true;
412
+ if (result[featureKey.bucketInstanceId] === undefined) {
413
+ result[featureKey.bucketInstanceId] = [];
414
+ }
415
+ result[featureKey.bucketInstanceId].push(featureKey.featureIndex);
416
+ }
417
+
418
+ return result;
419
+ }
420
+
421
+ insertCollisionBox(collisionBox: Array<number>, overlapMode: OverlapMode, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number) {
422
+ const grid = ignorePlacement ? this.ignoredGrid : this.grid;
423
+
424
+ const key = {bucketInstanceId, featureIndex, collisionGroupID, overlapMode};
425
+ grid.insert(key, collisionBox[0], collisionBox[1], collisionBox[2], collisionBox[3]);
426
+ }
427
+
428
+ insertCollisionCircles(collisionCircles: Array<number>, overlapMode: OverlapMode, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number) {
429
+ const grid = ignorePlacement ? this.ignoredGrid : this.grid;
430
+
431
+ const key = {bucketInstanceId, featureIndex, collisionGroupID, overlapMode};
432
+ for (let k = 0; k < collisionCircles.length; k += 4) {
433
+ grid.insertCircle(key, collisionCircles[k], collisionCircles[k + 1], collisionCircles[k + 2]);
434
+ }
435
+ }
436
+
437
+ projectAndGetPerspectiveRatio(posMatrix: mat4, x: number, y: number, _unwrappedTileID: UnwrappedTileID, getElevation?: (x: number, y: number) => number) {
438
+ // The code here is duplicated from "projection.ts" for performance.
439
+ // Code here is subject to change once globe is merged.
440
+ let pos;
441
+ if (getElevation) { // slow because of handle z-index
442
+ pos = [x, y, getElevation(x, y), 1] as vec4;
443
+ vec4.transformMat4(pos, pos, posMatrix);
444
+ } else { // fast because of ignore z-index
445
+ pos = [x, y, 0, 1] as vec4;
446
+ projection.xyTransformMat4(pos, pos, posMatrix);
447
+ }
448
+ const w = pos[3];
449
+ return {
450
+ point: new Point(
451
+ (((pos[0] / w + 1) / 2) * this.transform.width) + viewportPadding,
452
+ (((-pos[1] / w + 1) / 2) * this.transform.height) + viewportPadding
453
+ ),
454
+ // See perspective ratio comment in symbol_sdf.vertex
455
+ // We're doing collision detection in viewport space so we need
456
+ // to scale down boxes in the distance
457
+ perspectiveRatio: 0.5 + 0.5 * (this.transform.cameraToCenterDistance / w),
458
+ isOccluded: false,
459
+ signedDistanceFromCamera: w
460
+ };
461
+ }
462
+
463
+ getPerspectiveRatio(posMatrix: mat4, x: number, y: number, unwrappedTileID: UnwrappedTileID, getElevation?: (x: number, y: number) => number): number {
464
+ // We don't care about the actual projected point, just its W component.
465
+ const projected = this.mapProjection.useSpecialProjectionForSymbols ?
466
+ this.mapProjection.projectTileCoordinates(x, y, unwrappedTileID, getElevation) :
467
+ projection.project(x, y, posMatrix, getElevation);
468
+ return 0.5 + 0.5 * (this.transform.cameraToCenterDistance / projected.signedDistanceFromCamera);
469
+ }
470
+
471
+ isOffscreen(x1: number, y1: number, x2: number, y2: number) {
472
+ return x2 < viewportPadding || x1 >= this.screenRightBoundary || y2 < viewportPadding || y1 > this.screenBottomBoundary;
473
+ }
474
+
475
+ isInsideGrid(x1: number, y1: number, x2: number, y2: number) {
476
+ return x2 >= 0 && x1 < this.gridRightBoundary && y2 >= 0 && y1 < this.gridBottomBoundary;
477
+ }
478
+
479
+ /*
480
+ * Returns a matrix for transforming collision shapes to viewport coordinate space.
481
+ * Use this function to render e.g. collision circles on the screen.
482
+ * example transformation: clipPos = glCoordMatrix * viewportMatrix * circle_pos
483
+ */
484
+ getViewportMatrix() {
485
+ const m = mat4.identity([] as any);
486
+ mat4.translate(m, m, [-viewportPadding, -viewportPadding, 0.0]);
487
+ return m;
488
+ }
489
+
490
+ /**
491
+ * Applies all layout+paint properties of the given box in order to find as good approximation of its screen-space bounding box as possible.
492
+ */
493
+ private _projectCollisionBox(
494
+ collisionBox: SingleCollisionBox,
495
+ tileToViewport: number,
496
+ posMatrix: mat4,
497
+ unwrappedTileID: UnwrappedTileID,
498
+ pitchWithMap: boolean,
499
+ rotateWithMap: boolean,
500
+ translation: [number, number],
501
+ projectedPoint: {point: Point; perspectiveRatio: number; signedDistanceFromCamera: number},
502
+ getElevation?: (x: number, y: number) => number,
503
+ shift?: Point
504
+ ): ProjectedBox {
505
+
506
+ // These vectors are valid both for screen space viewport-rotation-aligned texts and for pitch-align: map texts that are map-rotation-aligned.
507
+ let vecEast = new Point(1, 0);
508
+ let vecSouth = new Point(0, 1);
509
+
510
+ const translatedAnchor = new Point(collisionBox.anchorPointX + translation[0], collisionBox.anchorPointY + translation[1]);
511
+
512
+ if (rotateWithMap && !pitchWithMap) {
513
+ // Handles screen space texts that are always aligned east-west.
514
+ const projectedEast = this.projectAndGetPerspectiveRatio(
515
+ posMatrix,
516
+ translatedAnchor.x + 1,
517
+ translatedAnchor.y,
518
+ unwrappedTileID,
519
+ getElevation
520
+ ).point;
521
+ const toEast = projectedEast.sub(projectedPoint.point).unit();
522
+ const angle = Math.atan(toEast.y / toEast.x) + (toEast.x < 0 ? Math.PI : 0);
523
+ const sin = Math.sin(angle);
524
+ const cos = Math.cos(angle);
525
+ vecEast = new Point(cos, sin);
526
+ vecSouth = new Point(-sin, cos);
527
+ } else if (!rotateWithMap && pitchWithMap) {
528
+ // Handles pitch-align: map texts that are always aligned with the viewport's X axis.
529
+ const angle = -this.transform.angle;
530
+ const sin = Math.sin(angle);
531
+ const cos = Math.cos(angle);
532
+ vecEast = new Point(cos, sin);
533
+ vecSouth = new Point(-sin, cos);
534
+ }
535
+
536
+ // Configuration for screen space offsets
537
+ let basePoint = projectedPoint.point;
538
+ let distanceMultiplier = tileToViewport;
539
+
540
+ if (pitchWithMap) {
541
+ // Configuration for tile space (map-pitch-aligned) offsets
542
+ basePoint = translatedAnchor;
543
+
544
+ const zoomFraction = this.transform.zoom - Math.floor(this.transform.zoom);
545
+ distanceMultiplier = Math.pow(2, -zoomFraction);
546
+ distanceMultiplier *= this.mapProjection.getPitchedTextCorrection(this.transform, translatedAnchor, unwrappedTileID);
547
+
548
+ // This next correction can't be applied when variable anchors are in use.
549
+ if (!shift) {
550
+ // Shader applies a perspective size correction, we need to apply the same correction.
551
+ // For non-pitchWithMap texts, this is handled above by multiplying `textPixelRatio` with `projectedPoint.perspectiveRatio`,
552
+ // which is equivalent to the non-pitchWithMap branch of the GLSL code.
553
+ // Here, we compute and apply the pitchWithMap branch.
554
+ // See the computation of `perspective_ratio` in the symbol vertex shaders for the GLSL code.
555
+ const distanceRatio = projectedPoint.signedDistanceFromCamera / this.transform.cameraToCenterDistance;
556
+ const perspectiveRatio = clamp(0.5 + 0.5 * distanceRatio, 0.0, 4.0); // Same clamp as what is used in the shader.
557
+ distanceMultiplier *= perspectiveRatio;
558
+ }
559
+ }
560
+
561
+ if (shift) {
562
+ // Variable anchors are in use
563
+ basePoint = basePoint.add(vecEast.mult(shift.x * distanceMultiplier)).add(vecSouth.mult(shift.y * distanceMultiplier));
564
+ }
565
+
566
+ const offsetXmin = collisionBox.x1 * distanceMultiplier;
567
+ const offsetXmax = collisionBox.x2 * distanceMultiplier;
568
+ const offsetXhalf = (offsetXmin + offsetXmax) / 2;
569
+ const offsetYmin = collisionBox.y1 * distanceMultiplier;
570
+ const offsetYmax = collisionBox.y2 * distanceMultiplier;
571
+ const offsetYhalf = (offsetYmin + offsetYmax) / 2;
572
+
573
+ // 0--1--2
574
+ // | |
575
+ // 7 3
576
+ // | |
577
+ // 6--5--4
578
+ const offsetsArray: Array<{offsetX: number; offsetY: number}> = [
579
+ {offsetX: offsetXmin, offsetY: offsetYmin},
580
+ {offsetX: offsetXhalf, offsetY: offsetYmin},
581
+ {offsetX: offsetXmax, offsetY: offsetYmin},
582
+ {offsetX: offsetXmax, offsetY: offsetYhalf},
583
+ {offsetX: offsetXmax, offsetY: offsetYmax},
584
+ {offsetX: offsetXhalf, offsetY: offsetYmax},
585
+ {offsetX: offsetXmin, offsetY: offsetYmax},
586
+ {offsetX: offsetXmin, offsetY: offsetYhalf}
587
+ ];
588
+
589
+ let points: Array<Point> = [];
590
+
591
+ for (const {offsetX, offsetY} of offsetsArray) {
592
+ points.push(new Point(
593
+ basePoint.x + vecEast.x * offsetX + vecSouth.x * offsetY,
594
+ basePoint.y + vecEast.y * offsetX + vecSouth.y * offsetY
595
+ ));
596
+ }
597
+
598
+ // Is any point of the collision shape visible on the globe (on beyond horizon)?
599
+ let anyPointVisible = false;
600
+
601
+ if (pitchWithMap) {
602
+ const projected = points.map(p => this.projectAndGetPerspectiveRatio(posMatrix, p.x, p.y, unwrappedTileID, getElevation));
603
+
604
+ // Is at least one of the projected points NOT behind the horizon?
605
+ anyPointVisible = projected.some(p => !p.isOccluded);
606
+
607
+ points = projected.map(p => p.point);
608
+ } else {
609
+ // Labels that are not pitchWithMap cannot ever hide behind the horizon.
610
+ anyPointVisible = true;
611
+ }
612
+
613
+ return {
614
+ box: getAABB(points),
615
+ allPointsOccluded: !anyPointVisible
616
+ };
617
+ }
618
+ }