@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,1102 @@
1
+ import {create as createSource} from './source';
2
+
3
+ import {Tile} from './tile';
4
+ import {Event, ErrorEvent, Evented} from '../util/evented';
5
+ import {TileCache} from './tile_cache';
6
+ import {MercatorCoordinate} from '../geo/mercator_coordinate';
7
+ import {keysDifference} from '../util/util';
8
+ import {EXTENT} from '../data/extent';
9
+ import {Context} from '../gl/context';
10
+ import Point from '@mapbox/point-geometry';
11
+ import {browser} from '../util/browser';
12
+ import {OverscaledTileID} from './tile_id';
13
+ import {SourceFeatureState} from './source_state';
14
+ import {config} from '../util/config';
15
+
16
+ import type {Source} from './source';
17
+ import type {Map} from '../ui/map';
18
+ import type {Style} from '../style/style';
19
+ import type {Dispatcher} from '../util/dispatcher';
20
+ import type {Transform} from '../geo/transform';
21
+ import type {TileState} from './tile';
22
+ import type {SourceSpecification} from '@maplibre/maplibre-gl-style-spec';
23
+ import type {MapSourceDataEvent} from '../ui/events';
24
+ import type {Terrain} from '../render/terrain';
25
+ import type {CanvasSourceSpecification} from './canvas_source';
26
+
27
+ /**
28
+ * @internal
29
+ * `SourceCache` is responsible for
30
+ *
31
+ * - creating an instance of `Source`
32
+ * - forwarding events from `Source`
33
+ * - caching tiles loaded from an instance of `Source`
34
+ * - loading the tiles needed to render a given viewport
35
+ * - unloading the cached tiles not needed to render a given viewport
36
+ */
37
+ export class SourceCache extends Evented {
38
+ id: string;
39
+ dispatcher: Dispatcher;
40
+ map: Map;
41
+ style: Style;
42
+
43
+ _source: Source;
44
+
45
+ /**
46
+ * @internal
47
+ * signifies that the TileJSON is loaded if applicable.
48
+ * if the source type does not come with a TileJSON, the flag signifies the
49
+ * source data has loaded (i.e geojson has been tiled on the worker and is ready)
50
+ */
51
+ _sourceLoaded: boolean;
52
+
53
+ _sourceErrored: boolean;
54
+ _tiles: {[_: string]: Tile};
55
+ _prevLng: number;
56
+ _cache: TileCache;
57
+ _timers: {
58
+ [_ in any]: ReturnType<typeof setTimeout>;
59
+ };
60
+ _cacheTimers: {
61
+ [_ in any]: ReturnType<typeof setTimeout>;
62
+ };
63
+ _maxTileCacheSize: number;
64
+ _maxTileCacheZoomLevels: number;
65
+ _paused: boolean;
66
+ _shouldReloadOnResume: boolean;
67
+ _coveredTiles: {[_: string]: boolean};
68
+ transform: Transform;
69
+ terrain: Terrain;
70
+ used: boolean;
71
+ usedForTerrain: boolean;
72
+ tileSize: number;
73
+ _state: SourceFeatureState;
74
+ _loadedParentTiles: {[_: string]: Tile};
75
+ _loadedSiblingTiles: {[_: string]: Tile};
76
+ _didEmitContent: boolean;
77
+ _updated: boolean;
78
+
79
+ static maxUnderzooming: number;
80
+ static maxOverzooming: number;
81
+
82
+ constructor(id: string, options: SourceSpecification | CanvasSourceSpecification, dispatcher: Dispatcher) {
83
+ super();
84
+ this.id = id;
85
+ this.dispatcher = dispatcher;
86
+
87
+ this.on('data', (e: MapSourceDataEvent) => this._dataHandler(e));
88
+
89
+ this.on('dataloading', () => {
90
+ this._sourceErrored = false;
91
+ });
92
+
93
+ this.on('error', () => {
94
+ // Only set _sourceErrored if the source does not have pending loads.
95
+ this._sourceErrored = this._source.loaded();
96
+ });
97
+
98
+ this._source = createSource(id, options, dispatcher, this);
99
+
100
+ this._tiles = {};
101
+ this._cache = new TileCache(0, (tile) => this._unloadTile(tile));
102
+ this._timers = {};
103
+ this._cacheTimers = {};
104
+ this._maxTileCacheSize = null;
105
+ this._maxTileCacheZoomLevels = null;
106
+ this._loadedParentTiles = {};
107
+
108
+ this._coveredTiles = {};
109
+ this._state = new SourceFeatureState();
110
+ this._didEmitContent = false;
111
+ this._updated = false;
112
+ }
113
+
114
+ onAdd(map: Map) {
115
+ this.map = map;
116
+ this._maxTileCacheSize = map ? map._maxTileCacheSize : null;
117
+ this._maxTileCacheZoomLevels = map ? map._maxTileCacheZoomLevels : null;
118
+ if (this._source && this._source.onAdd) {
119
+ this._source.onAdd(map);
120
+ }
121
+ }
122
+
123
+ onRemove(map: Map) {
124
+ this.clearTiles();
125
+ if (this._source && this._source.onRemove) {
126
+ this._source.onRemove(map);
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Return true if no tile data is pending, tiles will not change unless
132
+ * an additional API call is received.
133
+ */
134
+ loaded(): boolean {
135
+ if (this._sourceErrored) { return true; }
136
+ if (!this._sourceLoaded) { return false; }
137
+ if (!this._source.loaded()) { return false; }
138
+ if ((this.used !== undefined || this.usedForTerrain !== undefined) && !this.used && !this.usedForTerrain) { return true; }
139
+ // do not consider as loaded if the update hasn't been called yet (we do not know if we will have any tiles to fetch)
140
+ if (!this._updated) { return false; }
141
+
142
+ for (const t in this._tiles) {
143
+ const tile = this._tiles[t];
144
+ if (tile.state !== 'loaded' && tile.state !== 'errored')
145
+ return false;
146
+ }
147
+ return true;
148
+ }
149
+
150
+ getSource(): Source {
151
+ return this._source;
152
+ }
153
+
154
+ pause() {
155
+ this._paused = true;
156
+ }
157
+
158
+ resume() {
159
+ if (!this._paused) return;
160
+ const shouldReload = this._shouldReloadOnResume;
161
+ this._paused = false;
162
+ this._shouldReloadOnResume = false;
163
+ if (shouldReload) this.reload();
164
+ if (this.transform) this.update(this.transform, this.terrain);
165
+ }
166
+
167
+ async _loadTile(tile: Tile, id: string, state: TileState): Promise<void> {
168
+ try {
169
+ await this._source.loadTile(tile);
170
+ this._tileLoaded(tile, id, state);
171
+ } catch (err) {
172
+ tile.state = 'errored';
173
+ if ((err as any).status !== 404) {
174
+ this._source.fire(new ErrorEvent(err, {tile}));
175
+ } else {
176
+ // continue to try loading parent/children tiles if a tile doesn't exist (404)
177
+ this.update(this.transform, this.terrain);
178
+ }
179
+ }
180
+ }
181
+
182
+ _unloadTile(tile: Tile) {
183
+ if (this._source.unloadTile)
184
+ this._source.unloadTile(tile);
185
+ }
186
+
187
+ _abortTile(tile: Tile) {
188
+ if (this._source.abortTile)
189
+ this._source.abortTile(tile);
190
+
191
+ this._source.fire(new Event('dataabort', {tile, coord: tile.tileID, dataType: 'source'}));
192
+ }
193
+
194
+ serialize() {
195
+ return this._source.serialize();
196
+ }
197
+
198
+ prepare(context: Context) {
199
+ if (this._source.prepare) {
200
+ this._source.prepare();
201
+ }
202
+
203
+ this._state.coalesceChanges(this._tiles, this.map ? this.map.painter : null);
204
+ for (const i in this._tiles) {
205
+ const tile = this._tiles[i];
206
+ tile.upload(context);
207
+ tile.prepare(this.map.style.imageManager);
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Return all tile ids ordered with z-order, and cast to numbers
213
+ */
214
+ getIds(): Array<string> {
215
+ return (Object.values(this._tiles) as any).map((tile: Tile) => tile.tileID).sort(compareTileId).map(id => id.key);
216
+ }
217
+
218
+ getRenderableIds(symbolLayer?: boolean): Array<string> {
219
+ const renderables: Array<Tile> = [];
220
+ for (const id in this._tiles) {
221
+ if (this._isIdRenderable(id, symbolLayer)) renderables.push(this._tiles[id]);
222
+ }
223
+ if (symbolLayer) {
224
+ return renderables.sort((a_: Tile, b_: Tile) => {
225
+ const a = a_.tileID;
226
+ const b = b_.tileID;
227
+ const rotatedA = (new Point(a.canonical.x, a.canonical.y))._rotate(this.transform.angle);
228
+ const rotatedB = (new Point(b.canonical.x, b.canonical.y))._rotate(this.transform.angle);
229
+ return a.overscaledZ - b.overscaledZ || rotatedB.y - rotatedA.y || rotatedB.x - rotatedA.x;
230
+ }).map(tile => tile.tileID.key);
231
+ }
232
+ return renderables.map(tile => tile.tileID).sort(compareTileId).map(id => id.key);
233
+ }
234
+
235
+ hasRenderableParent(tileID: OverscaledTileID) {
236
+ const parentTile = this.findLoadedParent(tileID, 0);
237
+ if (parentTile) {
238
+ return this._isIdRenderable(parentTile.tileID.key);
239
+ }
240
+ return false;
241
+ }
242
+
243
+ _isIdRenderable(id: string, symbolLayer?: boolean) {
244
+ return this._tiles[id] && this._tiles[id].hasData() &&
245
+ !this._coveredTiles[id] && (symbolLayer || !this._tiles[id].holdingForFade());
246
+ }
247
+
248
+ reload() {
249
+ if (this._paused) {
250
+ this._shouldReloadOnResume = true;
251
+ return;
252
+ }
253
+
254
+ this._cache.reset();
255
+
256
+ for (const i in this._tiles) {
257
+ if (this._tiles[i].state !== 'errored') this._reloadTile(i, 'reloading');
258
+ }
259
+ }
260
+
261
+ async _reloadTile(id: string, state: TileState) {
262
+ const tile = this._tiles[id];
263
+
264
+ // this potentially does not address all underlying
265
+ // issues https://github.com/mapbox/mapbox-gl-js/issues/4252
266
+ // - hard to tell without repro steps
267
+ if (!tile) return;
268
+
269
+ // The difference between "loading" tiles and "reloading" or "expired"
270
+ // tiles is that "reloading"/"expired" tiles are "renderable".
271
+ // Therefore, a "loading" tile cannot become a "reloading" tile without
272
+ // first becoming a "loaded" tile.
273
+ if (tile.state !== 'loading') {
274
+ tile.state = state;
275
+ }
276
+ await this._loadTile(tile, id, state);
277
+ }
278
+
279
+ _tileLoaded(tile: Tile, id: string, previousState: TileState) {
280
+ tile.timeAdded = browser.now();
281
+ if (previousState === 'expired') tile.refreshedUponExpiration = true;
282
+ this._setTileReloadTimer(id, tile);
283
+ if (this.getSource().type === 'raster-dem' && tile.dem) this._backfillDEM(tile);
284
+ this._state.initializeTileState(tile, this.map ? this.map.painter : null);
285
+
286
+ if (!tile.aborted) {
287
+ this._source.fire(new Event('data', {dataType: 'source', tile, coord: tile.tileID}));
288
+ }
289
+ }
290
+
291
+ /**
292
+ * For raster terrain source, backfill DEM to eliminate visible tile boundaries
293
+ */
294
+ _backfillDEM(tile: Tile) {
295
+ const renderables = this.getRenderableIds();
296
+ for (let i = 0; i < renderables.length; i++) {
297
+ const borderId = renderables[i];
298
+ if (tile.neighboringTiles && tile.neighboringTiles[borderId]) {
299
+ const borderTile = this.getTileByID(borderId);
300
+ fillBorder(tile, borderTile);
301
+ fillBorder(borderTile, tile);
302
+ }
303
+ }
304
+
305
+ function fillBorder(tile, borderTile) {
306
+ tile.needsHillshadePrepare = true;
307
+ tile.needsTerrainPrepare = true;
308
+ let dx = borderTile.tileID.canonical.x - tile.tileID.canonical.x;
309
+ const dy = borderTile.tileID.canonical.y - tile.tileID.canonical.y;
310
+ const dim = Math.pow(2, tile.tileID.canonical.z);
311
+ const borderId = borderTile.tileID.key;
312
+ if (dx === 0 && dy === 0) return;
313
+
314
+ if (Math.abs(dy) > 1) {
315
+ return;
316
+ }
317
+ if (Math.abs(dx) > 1) {
318
+ // Adjust the delta coordinate for world wraparound.
319
+ if (Math.abs(dx + dim) === 1) {
320
+ dx += dim;
321
+ } else if (Math.abs(dx - dim) === 1) {
322
+ dx -= dim;
323
+ }
324
+ }
325
+ if (!borderTile.dem || !tile.dem) return;
326
+ tile.dem.backfillBorder(borderTile.dem, dx, dy);
327
+ if (tile.neighboringTiles && tile.neighboringTiles[borderId])
328
+ tile.neighboringTiles[borderId].backfilled = true;
329
+ }
330
+ }
331
+ /**
332
+ * Get a specific tile by TileID
333
+ */
334
+ getTile(tileID: OverscaledTileID): Tile {
335
+ return this.getTileByID(tileID.key);
336
+ }
337
+
338
+ /**
339
+ * Get a specific tile by id
340
+ */
341
+ getTileByID(id: string): Tile {
342
+ return this._tiles[id];
343
+ }
344
+
345
+ /**
346
+ * For a given set of tiles, retain children that are loaded and have a zoom
347
+ * between `zoom` (exclusive) and `maxCoveringZoom` (inclusive)
348
+ */
349
+ _retainLoadedChildren(
350
+ idealTiles: {
351
+ [_ in any]: OverscaledTileID;
352
+ },
353
+ zoom: number,
354
+ maxCoveringZoom: number,
355
+ retain: {
356
+ [_ in any]: OverscaledTileID;
357
+ }
358
+ ) {
359
+ for (const id in this._tiles) {
360
+ let tile = this._tiles[id];
361
+
362
+ // only consider renderable tiles up to maxCoveringZoom
363
+ if (retain[id] ||
364
+ !tile.hasData() ||
365
+ tile.tileID.overscaledZ <= zoom ||
366
+ tile.tileID.overscaledZ > maxCoveringZoom
367
+ ) continue;
368
+
369
+ // loop through parents and retain the topmost loaded one if found
370
+ let topmostLoadedID = tile.tileID;
371
+ while (tile && tile.tileID.overscaledZ > zoom + 1) {
372
+ const parentID = tile.tileID.scaledTo(tile.tileID.overscaledZ - 1);
373
+
374
+ tile = this._tiles[parentID.key];
375
+
376
+ if (tile && tile.hasData()) {
377
+ topmostLoadedID = parentID;
378
+ }
379
+ }
380
+
381
+ // loop through ancestors of the topmost loaded child to see if there's one that needed it
382
+ let tileID = topmostLoadedID;
383
+ while (tileID.overscaledZ > zoom) {
384
+ tileID = tileID.scaledTo(tileID.overscaledZ - 1);
385
+
386
+ if (idealTiles[tileID.key]) {
387
+ // found a parent that needed a loaded child; retain that child
388
+ retain[topmostLoadedID.key] = topmostLoadedID;
389
+ break;
390
+ }
391
+ }
392
+ }
393
+ }
394
+
395
+ /**
396
+ * Find a loaded parent of the given tile (up to minCoveringZoom)
397
+ */
398
+ findLoadedParent(tileID: OverscaledTileID, minCoveringZoom: number): Tile {
399
+ if (tileID.key in this._loadedParentTiles) {
400
+ const parent = this._loadedParentTiles[tileID.key];
401
+ if (parent && parent.tileID.overscaledZ >= minCoveringZoom) {
402
+ return parent;
403
+ } else {
404
+ return null;
405
+ }
406
+ }
407
+ for (let z = tileID.overscaledZ - 1; z >= minCoveringZoom; z--) {
408
+ const parentTileID = tileID.scaledTo(z);
409
+ const tile = this._getLoadedTile(parentTileID);
410
+ if (tile) {
411
+ return tile;
412
+ }
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Find a loaded sibling of the given tile
418
+ */
419
+ findLoadedSibling(tileID: OverscaledTileID): Tile {
420
+ // If a tile with this ID already exists, return it
421
+ return this._getLoadedTile(tileID);
422
+ }
423
+
424
+ _getLoadedTile(tileID: OverscaledTileID): Tile {
425
+ const tile = this._tiles[tileID.key];
426
+ if (tile && tile.hasData()) {
427
+ return tile;
428
+ }
429
+ // TileCache ignores wrap in lookup.
430
+ const cachedTile = this._cache.getByKey(tileID.wrapped().key);
431
+ return cachedTile;
432
+ }
433
+
434
+ /**
435
+ * Resizes the tile cache based on the current viewport's size
436
+ * or the maxTileCacheSize option passed during map creation
437
+ *
438
+ * Larger viewports use more tiles and need larger caches. Larger viewports
439
+ * are more likely to be found on devices with more memory and on pages where
440
+ * the map is more important.
441
+ */
442
+ updateCacheSize(transform: Transform) {
443
+ const widthInTiles = Math.ceil(transform.width / this._source.tileSize) + 1;
444
+ const heightInTiles = Math.ceil(transform.height / this._source.tileSize) + 1;
445
+ const approxTilesInView = widthInTiles * heightInTiles;
446
+ const commonZoomRange = this._maxTileCacheZoomLevels === null ?
447
+ config.MAX_TILE_CACHE_ZOOM_LEVELS : this._maxTileCacheZoomLevels;
448
+ const viewDependentMaxSize = Math.floor(approxTilesInView * commonZoomRange);
449
+ const maxSize = typeof this._maxTileCacheSize === 'number' ?
450
+ Math.min(this._maxTileCacheSize, viewDependentMaxSize) : viewDependentMaxSize;
451
+
452
+ this._cache.setMaxSize(maxSize);
453
+ }
454
+
455
+ handleWrapJump(lng: number) {
456
+ // On top of the regular z/x/y values, TileIDs have a `wrap` value that specify
457
+ // which copy of the world the tile belongs to. For example, at `lng: 10` you
458
+ // might render z/x/y/0 while at `lng: 370` you would render z/x/y/1.
459
+ //
460
+ // When lng values get wrapped (going from `lng: 370` to `long: 10`) you expect
461
+ // to see the same thing on the screen (370 degrees and 10 degrees is the same
462
+ // place in the world) but all the TileIDs will have different wrap values.
463
+ //
464
+ // In order to make this transition seamless, we calculate the rounded difference of
465
+ // "worlds" between the last frame and the current frame. If the map panned by
466
+ // a world, then we can assign all the tiles new TileIDs with updated wrap values.
467
+ // For example, assign z/x/y/1 a new id: z/x/y/0. It is the same tile, just rendered
468
+ // in a different position.
469
+ //
470
+ // This enables us to reuse the tiles at more ideal locations and prevent flickering.
471
+ const prevLng = this._prevLng === undefined ? lng : this._prevLng;
472
+ const lngDifference = lng - prevLng;
473
+ const worldDifference = lngDifference / 360;
474
+ const wrapDelta = Math.round(worldDifference);
475
+ this._prevLng = lng;
476
+
477
+ if (wrapDelta) {
478
+ const tiles: {[_: string]: Tile} = {};
479
+ for (const key in this._tiles) {
480
+ const tile = this._tiles[key];
481
+ tile.tileID = tile.tileID.unwrapTo(tile.tileID.wrap + wrapDelta);
482
+ tiles[tile.tileID.key] = tile;
483
+ }
484
+ this._tiles = tiles;
485
+
486
+ // Reset tile reload timers
487
+ for (const id in this._timers) {
488
+ clearTimeout(this._timers[id]);
489
+ delete this._timers[id];
490
+ }
491
+ for (const id in this._tiles) {
492
+ const tile = this._tiles[id];
493
+ this._setTileReloadTimer(id, tile);
494
+ }
495
+ }
496
+ }
497
+
498
+ _updateCoveredAndRetainedTiles(
499
+ retain: { [_: string]: OverscaledTileID },
500
+ minCoveringZoom: number,
501
+ maxCoveringZoom: number,
502
+ zoom: number,
503
+ idealTileIDs: OverscaledTileID[],
504
+ terrain?: Terrain
505
+ ) {
506
+ const tilesForFading: { [_: string]: OverscaledTileID } = {};
507
+ const fadingTiles = {};
508
+ const ids = Object.keys(retain);
509
+ const now = browser.now();
510
+ for (const id of ids) {
511
+ const tileID = retain[id];
512
+
513
+ const tile = this._tiles[id];
514
+
515
+ // when fadeEndTime is 0, the tile is created but registerFadeDuration
516
+ // has not been called, therefore must be kept in fadingTiles dictionary
517
+ // for next round of rendering
518
+ if (!tile || (tile.fadeEndTime !== 0 && tile.fadeEndTime <= now)) {
519
+ continue;
520
+ }
521
+
522
+ // if the tile is loaded but still fading in, find parents to cross-fade with it
523
+ const parentTile = this.findLoadedParent(tileID, minCoveringZoom);
524
+ const siblingTile = this.findLoadedSibling(tileID);
525
+ const fadeTileRef = parentTile || siblingTile || null;
526
+ if (fadeTileRef) {
527
+ this._addTile(fadeTileRef.tileID);
528
+ tilesForFading[fadeTileRef.tileID.key] = fadeTileRef.tileID;
529
+ }
530
+
531
+ fadingTiles[id] = tileID;
532
+ }
533
+
534
+ // for tiles that are still fading in, also find children to cross-fade with
535
+ this._retainLoadedChildren(fadingTiles, zoom, maxCoveringZoom, retain);
536
+
537
+ for (const id in tilesForFading) {
538
+ if (!retain[id]) {
539
+ // If a tile is only needed for fading, mark it as covered so that it isn't rendered on it's own.
540
+ this._coveredTiles[id] = true;
541
+ retain[id] = tilesForFading[id];
542
+ }
543
+ }
544
+
545
+ // disable fading logic in terrain3D mode to avoid rendering two tiles on the same place
546
+ if (terrain) {
547
+ const idealRasterTileIDs: { [_: string]: OverscaledTileID } = {};
548
+ const missingTileIDs: { [_: string]: OverscaledTileID } = {};
549
+ for (const tileID of idealTileIDs) {
550
+ if (this._tiles[tileID.key].hasData())
551
+ idealRasterTileIDs[tileID.key] = tileID;
552
+ else
553
+ missingTileIDs[tileID.key] = tileID;
554
+ }
555
+ // search for a complete set of children for each missing tile
556
+ for (const key in missingTileIDs) {
557
+ const children = missingTileIDs[key].children(this._source.maxzoom);
558
+ if (this._tiles[children[0].key] && this._tiles[children[1].key] && this._tiles[children[2].key] && this._tiles[children[3].key]) {
559
+ idealRasterTileIDs[children[0].key] = retain[children[0].key] = children[0];
560
+ idealRasterTileIDs[children[1].key] = retain[children[1].key] = children[1];
561
+ idealRasterTileIDs[children[2].key] = retain[children[2].key] = children[2];
562
+ idealRasterTileIDs[children[3].key] = retain[children[3].key] = children[3];
563
+ delete missingTileIDs[key];
564
+ }
565
+ }
566
+ // search for parent or sibling for each missing tile
567
+ for (const key in missingTileIDs) {
568
+ const tileID = missingTileIDs[key];
569
+ const parentTile = this.findLoadedParent(tileID, this._source.minzoom);
570
+ const siblingTile = this.findLoadedSibling(tileID);
571
+ const fadeTileRef = parentTile || siblingTile || null;
572
+ if (fadeTileRef) {
573
+ idealRasterTileIDs[fadeTileRef.tileID.key] = retain[fadeTileRef.tileID.key] = fadeTileRef.tileID;
574
+ // remove idealTiles which would be rendered twice
575
+ for (const key in idealRasterTileIDs) {
576
+ if (idealRasterTileIDs[key].isChildOf(fadeTileRef.tileID)) delete idealRasterTileIDs[key];
577
+ }
578
+ }
579
+ }
580
+ // cover all tiles which are not needed
581
+ for (const key in this._tiles) {
582
+ if (!idealRasterTileIDs[key]) this._coveredTiles[key] = true;
583
+ }
584
+ }
585
+ }
586
+
587
+ /**
588
+ * Removes tiles that are outside the viewport and adds new tiles that
589
+ * are inside the viewport.
590
+ */
591
+ update(transform: Transform, terrain?: Terrain) {
592
+ if (!this._sourceLoaded || this._paused) {
593
+ return;
594
+ }
595
+ this.transform = transform;
596
+ this.terrain = terrain;
597
+
598
+ this.updateCacheSize(transform);
599
+ this.handleWrapJump(this.transform.center.lng);
600
+
601
+ // Covered is a list of retained tiles who's areas are fully covered by other,
602
+ // better, retained tiles. They are not drawn separately.
603
+ this._coveredTiles = {};
604
+
605
+ let idealTileIDs: OverscaledTileID[];
606
+
607
+ if (!this.used && !this.usedForTerrain) {
608
+ idealTileIDs = [];
609
+ } else if (this._source.tileID) {
610
+ idealTileIDs = transform.getVisibleUnwrappedCoordinates(this._source.tileID)
611
+ .map((unwrapped) => new OverscaledTileID(unwrapped.canonical.z, unwrapped.wrap, unwrapped.canonical.z, unwrapped.canonical.x, unwrapped.canonical.y));
612
+ } else {
613
+ idealTileIDs = transform.coveringTiles({
614
+ tileSize: this.usedForTerrain ? this.tileSize : this._source.tileSize,
615
+ minzoom: this._source.minzoom,
616
+ maxzoom: this._source.maxzoom,
617
+ roundZoom: this.usedForTerrain ? false : this._source.roundZoom,
618
+ reparseOverscaled: this._source.reparseOverscaled,
619
+ terrain
620
+ });
621
+
622
+ if (this._source.hasTile) {
623
+ idealTileIDs = idealTileIDs.filter((coord) => (this._source.hasTile as any)(coord));
624
+ }
625
+ }
626
+
627
+ // Determine the overzooming/underzooming amounts.
628
+ const zoom = transform.coveringZoomLevel(this._source);
629
+ const minCoveringZoom = Math.max(zoom - SourceCache.maxOverzooming, this._source.minzoom);
630
+ const maxCoveringZoom = Math.max(zoom + SourceCache.maxUnderzooming, this._source.minzoom);
631
+
632
+ // When sourcecache is used for terrain also load parent tiles to avoid flickering when zooming out
633
+ if (this.usedForTerrain) {
634
+ const parents = {};
635
+ for (const tileID of idealTileIDs) {
636
+ if (tileID.canonical.z > this._source.minzoom) {
637
+ const parent = tileID.scaledTo(tileID.canonical.z - 1);
638
+ parents[parent.key] = parent;
639
+ // load very low zoom to calculate tile visibility in transform.coveringTiles and high zoomlevels correct
640
+ const parent2 = tileID.scaledTo(Math.max(this._source.minzoom, Math.min(tileID.canonical.z, 5)));
641
+ parents[parent2.key] = parent2;
642
+ }
643
+ }
644
+ idealTileIDs = idealTileIDs.concat(Object.values(parents));
645
+ }
646
+
647
+ const noPendingDataEmissions = idealTileIDs.length === 0 && !this._updated && this._didEmitContent;
648
+ this._updated = true;
649
+ // if we won't have any tiles to fetch and content is already emitted
650
+ // there will be no more data emissions, so we need to emit the event with isSourceLoaded = true
651
+ if (noPendingDataEmissions) {
652
+ this.fire(new Event('data', {sourceDataType: 'idle', dataType: 'source', sourceId: this.id}));
653
+ }
654
+
655
+ // Retain is a list of tiles that we shouldn't delete, even if they are not
656
+ // the most ideal tile for the current viewport. This may include tiles like
657
+ // parent or child tiles that are *already* loaded.
658
+ const retain = this._updateRetainedTiles(idealTileIDs, zoom);
659
+
660
+ if (isRasterType(this._source.type)) {
661
+ this._updateCoveredAndRetainedTiles(retain, minCoveringZoom, maxCoveringZoom, zoom, idealTileIDs, terrain);
662
+ }
663
+
664
+ for (const retainedId in retain) {
665
+ // Make sure retained tiles always clear any existing fade holds
666
+ // so that if they're removed again their fade timer starts fresh.
667
+ this._tiles[retainedId].clearFadeHold();
668
+ }
669
+
670
+ // Remove the tiles we don't need anymore.
671
+ const remove = keysDifference(this._tiles, retain);
672
+ for (const tileID of remove) {
673
+ const tile = this._tiles[tileID];
674
+ if (tile.hasSymbolBuckets && !tile.holdingForFade()) {
675
+ tile.setHoldDuration(this.map._fadeDuration);
676
+ } else if (!tile.hasSymbolBuckets || tile.symbolFadeFinished()) {
677
+ this._removeTile(tileID);
678
+ }
679
+ }
680
+
681
+ // Construct caches of loaded parents & siblings
682
+ this._updateLoadedParentTileCache();
683
+ this._updateLoadedSiblingTileCache();
684
+ }
685
+
686
+ releaseSymbolFadeTiles() {
687
+ for (const id in this._tiles) {
688
+ if (this._tiles[id].holdingForFade()) {
689
+ this._removeTile(id);
690
+ }
691
+ }
692
+ }
693
+
694
+ _updateRetainedTiles(idealTileIDs: Array<OverscaledTileID>, zoom: number): {[_: string]: OverscaledTileID} {
695
+ const retain: {[_: string]: OverscaledTileID} = {};
696
+ const checked: {[_: string]: boolean} = {};
697
+ const minCoveringZoom = Math.max(zoom - SourceCache.maxOverzooming, this._source.minzoom);
698
+ const maxCoveringZoom = Math.max(zoom + SourceCache.maxUnderzooming, this._source.minzoom);
699
+
700
+ const missingTiles = {};
701
+ for (const tileID of idealTileIDs) {
702
+ const tile = this._addTile(tileID);
703
+
704
+ // retain the tile even if it's not loaded because it's an ideal tile.
705
+ retain[tileID.key] = tileID;
706
+
707
+ if (tile.hasData()) continue;
708
+
709
+ if (zoom < this._source.maxzoom) {
710
+ // save missing tiles that potentially have loaded children
711
+ missingTiles[tileID.key] = tileID;
712
+ }
713
+ }
714
+
715
+ // retain any loaded children of ideal tiles up to maxCoveringZoom
716
+ this._retainLoadedChildren(missingTiles, zoom, maxCoveringZoom, retain);
717
+
718
+ for (const tileID of idealTileIDs) {
719
+ let tile = this._tiles[tileID.key];
720
+
721
+ if (tile.hasData()) continue;
722
+
723
+ // The tile we require is not yet loaded or does not exist;
724
+ // Attempt to find children that fully cover it.
725
+
726
+ if (zoom + 1 > this._source.maxzoom) {
727
+ // We're looking for an overzoomed child tile.
728
+ const childCoord = tileID.children(this._source.maxzoom)[0];
729
+ const childTile = this.getTile(childCoord);
730
+ if (!!childTile && childTile.hasData()) {
731
+ retain[childCoord.key] = childCoord;
732
+ continue; // tile is covered by overzoomed child
733
+ }
734
+ } else {
735
+ // check if all 4 immediate children are loaded (i.e. the missing ideal tile is covered)
736
+ const children = tileID.children(this._source.maxzoom);
737
+
738
+ if (retain[children[0].key] &&
739
+ retain[children[1].key] &&
740
+ retain[children[2].key] &&
741
+ retain[children[3].key]) continue; // tile is covered by children
742
+ }
743
+
744
+ // We couldn't find child tiles that entirely cover the ideal tile; look for parents now.
745
+
746
+ // As we ascend up the tile pyramid of the ideal tile, we check whether the parent
747
+ // tile has been previously requested (and errored because we only loop over tiles with no data)
748
+ // in order to determine if we need to request its parent.
749
+ let parentWasRequested = tile.wasRequested();
750
+
751
+ for (let overscaledZ = tileID.overscaledZ - 1; overscaledZ >= minCoveringZoom; --overscaledZ) {
752
+ const parentId = tileID.scaledTo(overscaledZ);
753
+
754
+ // Break parent tile ascent if this route has been previously checked by another child.
755
+ if (checked[parentId.key]) break;
756
+ checked[parentId.key] = true;
757
+
758
+ tile = this.getTile(parentId);
759
+ if (!tile && parentWasRequested) {
760
+ tile = this._addTile(parentId);
761
+ }
762
+ if (tile) {
763
+ const hasData = tile.hasData();
764
+ if (hasData || !this.map?.cancelPendingTileRequestsWhileZooming || parentWasRequested) {
765
+ retain[parentId.key] = parentId;
766
+ }
767
+ // Save the current values, since they're the parent of the next iteration
768
+ // of the parent tile ascent loop.
769
+ parentWasRequested = tile.wasRequested();
770
+ if (hasData) break;
771
+ }
772
+ }
773
+ }
774
+
775
+ return retain;
776
+ }
777
+
778
+ _updateLoadedParentTileCache() {
779
+ this._loadedParentTiles = {};
780
+
781
+ for (const tileKey in this._tiles) {
782
+ const path = [];
783
+ let parentTile: Tile;
784
+ let currentId = this._tiles[tileKey].tileID;
785
+
786
+ // Find the closest loaded ancestor by traversing the tile tree towards the root and
787
+ // caching results along the way
788
+ while (currentId.overscaledZ > 0) {
789
+
790
+ // Do we have a cached result from previous traversals?
791
+ if (currentId.key in this._loadedParentTiles) {
792
+ parentTile = this._loadedParentTiles[currentId.key];
793
+ break;
794
+ }
795
+
796
+ path.push(currentId.key);
797
+
798
+ // Is the parent loaded?
799
+ const parentId = currentId.scaledTo(currentId.overscaledZ - 1);
800
+ parentTile = this._getLoadedTile(parentId);
801
+ if (parentTile) {
802
+ break;
803
+ }
804
+
805
+ currentId = parentId;
806
+ }
807
+
808
+ // Cache the result of this traversal to all newly visited tiles
809
+ for (const key of path) {
810
+ this._loadedParentTiles[key] = parentTile;
811
+ }
812
+ }
813
+ }
814
+
815
+ /**
816
+ * Update the cache of loaded sibling tiles
817
+ *
818
+ * Sibling tiles are tiles that share the same zoom level and
819
+ * x/y position but have different wrap values
820
+ * Maintaining sibling tile cache allows fading from old to new tiles
821
+ * of the same position and zoom level
822
+ */
823
+ _updateLoadedSiblingTileCache() {
824
+ this._loadedSiblingTiles = {};
825
+
826
+ for (const tileKey in this._tiles) {
827
+ const currentId = this._tiles[tileKey].tileID;
828
+ const siblingTile: Tile = this._getLoadedTile(currentId);
829
+ this._loadedSiblingTiles[currentId.key] = siblingTile;
830
+ }
831
+ }
832
+
833
+ /**
834
+ * Add a tile, given its coordinate, to the pyramid.
835
+ */
836
+ _addTile(tileID: OverscaledTileID): Tile {
837
+ let tile = this._tiles[tileID.key];
838
+ if (tile)
839
+ return tile;
840
+
841
+ tile = this._cache.getAndRemove(tileID);
842
+ if (tile) {
843
+ this._setTileReloadTimer(tileID.key, tile);
844
+ // set the tileID because the cached tile could have had a different wrap value
845
+ tile.tileID = tileID;
846
+ this._state.initializeTileState(tile, this.map ? this.map.painter : null);
847
+ if (this._cacheTimers[tileID.key]) {
848
+ clearTimeout(this._cacheTimers[tileID.key]);
849
+ delete this._cacheTimers[tileID.key];
850
+ this._setTileReloadTimer(tileID.key, tile);
851
+ }
852
+ }
853
+
854
+ const cached = tile;
855
+
856
+ if (!tile) {
857
+ tile = new Tile(tileID, this._source.tileSize * tileID.overscaleFactor());
858
+ this._loadTile(tile, tileID.key, tile.state);
859
+ }
860
+
861
+ tile.uses++;
862
+ this._tiles[tileID.key] = tile;
863
+ if (!cached) {
864
+ this._source.fire(new Event('dataloading', {tile, coord: tile.tileID, dataType: 'source'}));
865
+ }
866
+
867
+ return tile;
868
+ }
869
+
870
+ _setTileReloadTimer(id: string, tile: Tile) {
871
+ if (id in this._timers) {
872
+ clearTimeout(this._timers[id]);
873
+ delete this._timers[id];
874
+ }
875
+
876
+ const expiryTimeout = tile.getExpiryTimeout();
877
+ if (expiryTimeout) {
878
+ this._timers[id] = setTimeout(() => {
879
+ this._reloadTile(id, 'expired');
880
+ delete this._timers[id];
881
+ }, expiryTimeout);
882
+ }
883
+ }
884
+
885
+ /**
886
+ * Remove a tile, given its id, from the pyramid
887
+ */
888
+ _removeTile(id: string) {
889
+ const tile = this._tiles[id];
890
+ if (!tile)
891
+ return;
892
+
893
+ tile.uses--;
894
+ delete this._tiles[id];
895
+ if (this._timers[id]) {
896
+ clearTimeout(this._timers[id]);
897
+ delete this._timers[id];
898
+ }
899
+
900
+ if (tile.uses > 0)
901
+ return;
902
+
903
+ if (tile.hasData() && tile.state !== 'reloading') {
904
+ this._cache.add(tile.tileID, tile, tile.getExpiryTimeout());
905
+ } else {
906
+ tile.aborted = true;
907
+ this._abortTile(tile);
908
+ this._unloadTile(tile);
909
+ }
910
+ }
911
+
912
+ /** @internal */
913
+ private _dataHandler(e: MapSourceDataEvent) {
914
+
915
+ const eventSourceDataType = e.sourceDataType;
916
+ if (e.dataType === 'source' && eventSourceDataType === 'metadata') {
917
+ this._sourceLoaded = true;
918
+ }
919
+
920
+ // for sources with mutable data, this event fires when the underlying data
921
+ // to a source is changed. (i.e. GeoJSONSource#setData and ImageSource#serCoordinates)
922
+ if (this._sourceLoaded && !this._paused && e.dataType === 'source' && eventSourceDataType === 'content') {
923
+ this.reload();
924
+ if (this.transform) {
925
+ this.update(this.transform, this.terrain);
926
+ }
927
+
928
+ this._didEmitContent = true;
929
+ }
930
+ }
931
+
932
+ /**
933
+ * Remove all tiles from this pyramid
934
+ */
935
+ clearTiles() {
936
+ this._shouldReloadOnResume = false;
937
+ this._paused = false;
938
+
939
+ for (const id in this._tiles)
940
+ this._removeTile(id);
941
+
942
+ this._cache.reset();
943
+ }
944
+
945
+ /**
946
+ * Search through our current tiles and attempt to find the tiles that
947
+ * cover the given bounds.
948
+ * @param pointQueryGeometry - coordinates of the corners of bounding rectangle
949
+ * @returns result items have `{tile, minX, maxX, minY, maxY}`, where min/max bounding values are the given bounds transformed in into the coordinate space of this tile.
950
+ */
951
+ tilesIn(pointQueryGeometry: Array<Point>, maxPitchScaleFactor: number, has3DLayer: boolean): any[] {
952
+
953
+ const tileResults = [];
954
+
955
+ const transform = this.transform;
956
+ if (!transform) return tileResults;
957
+
958
+ const cameraPointQueryGeometry = has3DLayer ?
959
+ transform.getCameraQueryGeometry(pointQueryGeometry) :
960
+ pointQueryGeometry;
961
+
962
+ const queryGeometry = pointQueryGeometry.map((p: Point) => transform.pointCoordinate(p, this.terrain));
963
+ const cameraQueryGeometry = cameraPointQueryGeometry.map((p: Point) => transform.pointCoordinate(p, this.terrain));
964
+
965
+ const ids = this.getIds();
966
+
967
+ let minX = Infinity;
968
+ let minY = Infinity;
969
+ let maxX = -Infinity;
970
+ let maxY = -Infinity;
971
+
972
+ for (const p of cameraQueryGeometry) {
973
+ minX = Math.min(minX, p.x);
974
+ minY = Math.min(minY, p.y);
975
+ maxX = Math.max(maxX, p.x);
976
+ maxY = Math.max(maxY, p.y);
977
+ }
978
+
979
+ for (let i = 0; i < ids.length; i++) {
980
+ const tile = this._tiles[ids[i]];
981
+ if (tile.holdingForFade()) {
982
+ // Tiles held for fading are covered by tiles that are closer to ideal
983
+ continue;
984
+ }
985
+ const tileID = tile.tileID;
986
+ const scale = Math.pow(2, transform.zoom - tile.tileID.overscaledZ);
987
+ const queryPadding = maxPitchScaleFactor * tile.queryPadding * EXTENT / tile.tileSize / scale;
988
+
989
+ const tileSpaceBounds = [
990
+ tileID.getTilePoint(new MercatorCoordinate(minX, minY)),
991
+ tileID.getTilePoint(new MercatorCoordinate(maxX, maxY))
992
+ ];
993
+
994
+ if (tileSpaceBounds[0].x - queryPadding < EXTENT && tileSpaceBounds[0].y - queryPadding < EXTENT &&
995
+ tileSpaceBounds[1].x + queryPadding >= 0 && tileSpaceBounds[1].y + queryPadding >= 0) {
996
+
997
+ const tileSpaceQueryGeometry: Array<Point> = queryGeometry.map((c) => tileID.getTilePoint(c));
998
+ const tileSpaceCameraQueryGeometry = cameraQueryGeometry.map((c) => tileID.getTilePoint(c));
999
+
1000
+ tileResults.push({
1001
+ tile,
1002
+ tileID,
1003
+ queryGeometry: tileSpaceQueryGeometry,
1004
+ cameraQueryGeometry: tileSpaceCameraQueryGeometry,
1005
+ scale
1006
+ });
1007
+ }
1008
+ }
1009
+
1010
+ return tileResults;
1011
+ }
1012
+
1013
+ getVisibleCoordinates(symbolLayer?: boolean): Array<OverscaledTileID> {
1014
+ const coords = this.getRenderableIds(symbolLayer).map((id) => this._tiles[id].tileID);
1015
+ for (const coord of coords) {
1016
+ coord.posMatrix = this.transform.calculatePosMatrix(coord.toUnwrapped());
1017
+ }
1018
+ return coords;
1019
+ }
1020
+
1021
+ hasTransition() {
1022
+ if (this._source.hasTransition()) {
1023
+ return true;
1024
+ }
1025
+
1026
+ if (isRasterType(this._source.type)) {
1027
+ const now = browser.now();
1028
+ for (const id in this._tiles) {
1029
+ const tile = this._tiles[id];
1030
+ if (tile.fadeEndTime >= now) {
1031
+ return true;
1032
+ }
1033
+ }
1034
+ }
1035
+
1036
+ return false;
1037
+ }
1038
+
1039
+ /**
1040
+ * Set the value of a particular state for a feature
1041
+ */
1042
+ setFeatureState(sourceLayer: string, featureId: number | string, state: any) {
1043
+ sourceLayer = sourceLayer || '_geojsonTileLayer';
1044
+ this._state.updateState(sourceLayer, featureId, state);
1045
+ }
1046
+
1047
+ /**
1048
+ * Resets the value of a particular state key for a feature
1049
+ */
1050
+ removeFeatureState(sourceLayer?: string, featureId?: number | string, key?: string) {
1051
+ sourceLayer = sourceLayer || '_geojsonTileLayer';
1052
+ this._state.removeFeatureState(sourceLayer, featureId, key);
1053
+ }
1054
+
1055
+ /**
1056
+ * Get the entire state object for a feature
1057
+ */
1058
+ getFeatureState(sourceLayer: string, featureId: number | string) {
1059
+ sourceLayer = sourceLayer || '_geojsonTileLayer';
1060
+ return this._state.getState(sourceLayer, featureId);
1061
+ }
1062
+
1063
+ /**
1064
+ * Sets the set of keys that the tile depends on. This allows tiles to
1065
+ * be reloaded when their dependencies change.
1066
+ */
1067
+ setDependencies(tileKey: string, namespace: string, dependencies: Array<string>) {
1068
+ const tile = this._tiles[tileKey];
1069
+ if (tile) {
1070
+ tile.setDependencies(namespace, dependencies);
1071
+ }
1072
+ }
1073
+
1074
+ /**
1075
+ * Reloads all tiles that depend on the given keys.
1076
+ */
1077
+ reloadTilesForDependencies(namespaces: Array<string>, keys: Array<string>) {
1078
+ for (const id in this._tiles) {
1079
+ const tile = this._tiles[id];
1080
+ if (tile.hasDependency(namespaces, keys)) {
1081
+ this._reloadTile(id, 'reloading');
1082
+ }
1083
+ }
1084
+ this._cache.filter(tile => !tile.hasDependency(namespaces, keys));
1085
+ }
1086
+ }
1087
+
1088
+ SourceCache.maxOverzooming = 10;
1089
+ SourceCache.maxUnderzooming = 3;
1090
+
1091
+ function compareTileId(a: OverscaledTileID, b: OverscaledTileID): number {
1092
+ // Different copies of the world are sorted based on their distance to the center.
1093
+ // Wrap values are converted to unsigned distances by reserving odd number for copies
1094
+ // with negative wrap and even numbers for copies with positive wrap.
1095
+ const aWrap = Math.abs(a.wrap * 2) - +(a.wrap < 0);
1096
+ const bWrap = Math.abs(b.wrap * 2) - +(b.wrap < 0);
1097
+ return a.overscaledZ - b.overscaledZ || bWrap - aWrap || b.canonical.y - a.canonical.y || b.canonical.x - a.canonical.x;
1098
+ }
1099
+
1100
+ function isRasterType(type) {
1101
+ return type === 'raster' || type === 'image' || type === 'video';
1102
+ }