mapbox-gl 1.13.2

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 (460) hide show
  1. package/.flowconfig +61 -0
  2. package/CHANGELOG.md +2485 -0
  3. package/LICENSE.txt +84 -0
  4. package/README.md +34 -0
  5. package/build/banner.js +4 -0
  6. package/build/check-bundle-size.js +140 -0
  7. package/build/diff-tarball.js +18 -0
  8. package/build/generate-access-token-script.js +11 -0
  9. package/build/generate-flow-typed-style-spec.js +188 -0
  10. package/build/generate-release-list.js +21 -0
  11. package/build/generate-struct-arrays.js +243 -0
  12. package/build/generate-style-code.js +159 -0
  13. package/build/mapbox-gl.js.flow +3 -0
  14. package/build/print-release-url.js +6 -0
  15. package/build/rollup_plugin_minify_style_spec.js +24 -0
  16. package/build/rollup_plugins.js +80 -0
  17. package/build/run-node +3 -0
  18. package/build/run-tap +8 -0
  19. package/build/test/build-tape.js +19 -0
  20. package/dist/mapbox-gl-csp-worker.js +2 -0
  21. package/dist/mapbox-gl-csp-worker.js.map +1 -0
  22. package/dist/mapbox-gl-csp.js +2 -0
  23. package/dist/mapbox-gl-csp.js.map +1 -0
  24. package/dist/mapbox-gl-dev.js +65889 -0
  25. package/dist/mapbox-gl-dev.js.flow +3 -0
  26. package/dist/mapbox-gl-unminified.js +42889 -0
  27. package/dist/mapbox-gl-unminified.js.map +1 -0
  28. package/dist/mapbox-gl.css +1 -0
  29. package/dist/mapbox-gl.js +42 -0
  30. package/dist/mapbox-gl.js.flow +3 -0
  31. package/dist/mapbox-gl.js.map +1 -0
  32. package/dist/style-spec/index.es.js +15032 -0
  33. package/dist/style-spec/index.es.js.map +1 -0
  34. package/dist/style-spec/index.js +15058 -0
  35. package/dist/style-spec/index.js.map +1 -0
  36. package/flow-typed/gl.js +5 -0
  37. package/flow-typed/jsdom.js +18 -0
  38. package/flow-typed/mapbox-gl-supported.js +9 -0
  39. package/flow-typed/mapbox-unitbezier.js +14 -0
  40. package/flow-typed/offscreen-canvas.js +9 -0
  41. package/flow-typed/pbf.js +25 -0
  42. package/flow-typed/point-geometry.js +44 -0
  43. package/flow-typed/potpack.js +12 -0
  44. package/flow-typed/sinon.js +28 -0
  45. package/flow-typed/vector-tile.js +41 -0
  46. package/package.json +173 -0
  47. package/src/css/mapbox-gl.css +812 -0
  48. package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
  49. package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
  50. package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
  51. package/src/css/svg/mapboxgl-ctrl-geolocate.svg +5 -0
  52. package/src/css/svg/mapboxgl-ctrl-logo.svg +20 -0
  53. package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
  54. package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
  55. package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
  56. package/src/data/array_types.js +1135 -0
  57. package/src/data/bucket/circle_attributes.js +9 -0
  58. package/src/data/bucket/circle_bucket.js +201 -0
  59. package/src/data/bucket/fill_attributes.js +9 -0
  60. package/src/data/bucket/fill_bucket.js +229 -0
  61. package/src/data/bucket/fill_extrusion_attributes.js +10 -0
  62. package/src/data/bucket/fill_extrusion_bucket.js +283 -0
  63. package/src/data/bucket/heatmap_bucket.js +17 -0
  64. package/src/data/bucket/line_attributes.js +10 -0
  65. package/src/data/bucket/line_attributes_ext.js +10 -0
  66. package/src/data/bucket/line_bucket.js +594 -0
  67. package/src/data/bucket/pattern_attributes.js +12 -0
  68. package/src/data/bucket/pattern_bucket_features.js +60 -0
  69. package/src/data/bucket/symbol_attributes.js +117 -0
  70. package/src/data/bucket/symbol_bucket.js +937 -0
  71. package/src/data/bucket.js +123 -0
  72. package/src/data/dem_data.js +125 -0
  73. package/src/data/evaluation_feature.js +25 -0
  74. package/src/data/extent.js +18 -0
  75. package/src/data/feature_index.js +322 -0
  76. package/src/data/feature_position_map.js +131 -0
  77. package/src/data/index_array_type.js +16 -0
  78. package/src/data/load_geometry.js +46 -0
  79. package/src/data/pos_attributes.js +6 -0
  80. package/src/data/program_configuration.js +708 -0
  81. package/src/data/raster_bounds_attributes.js +7 -0
  82. package/src/data/segment.js +76 -0
  83. package/src/geo/edge_insets.js +102 -0
  84. package/src/geo/lng_lat.js +168 -0
  85. package/src/geo/lng_lat_bounds.js +276 -0
  86. package/src/geo/mercator_coordinate.js +150 -0
  87. package/src/geo/transform.js +834 -0
  88. package/src/gl/color_mode.js +34 -0
  89. package/src/gl/context.js +302 -0
  90. package/src/gl/cull_face_mode.js +26 -0
  91. package/src/gl/depth_mode.js +29 -0
  92. package/src/gl/framebuffer.js +44 -0
  93. package/src/gl/index_buffer.js +55 -0
  94. package/src/gl/stencil_mode.js +30 -0
  95. package/src/gl/types.js +84 -0
  96. package/src/gl/value.js +520 -0
  97. package/src/gl/vertex_buffer.js +119 -0
  98. package/src/index.js +230 -0
  99. package/src/render/draw_background.js +57 -0
  100. package/src/render/draw_circle.js +113 -0
  101. package/src/render/draw_collision_debug.js +172 -0
  102. package/src/render/draw_custom.js +49 -0
  103. package/src/render/draw_debug.js +127 -0
  104. package/src/render/draw_fill.js +124 -0
  105. package/src/render/draw_fill_extrusion.js +95 -0
  106. package/src/render/draw_heatmap.js +133 -0
  107. package/src/render/draw_hillshade.js +107 -0
  108. package/src/render/draw_line.js +125 -0
  109. package/src/render/draw_raster.js +125 -0
  110. package/src/render/draw_symbol.js +392 -0
  111. package/src/render/glyph_atlas.js +71 -0
  112. package/src/render/glyph_manager.js +182 -0
  113. package/src/render/image_atlas.js +149 -0
  114. package/src/render/image_manager.js +306 -0
  115. package/src/render/line_atlas.js +210 -0
  116. package/src/render/painter.js +654 -0
  117. package/src/render/program/background_program.js +103 -0
  118. package/src/render/program/circle_program.js +69 -0
  119. package/src/render/program/clipping_mask_program.js +20 -0
  120. package/src/render/program/collision_program.js +76 -0
  121. package/src/render/program/debug_program.js +35 -0
  122. package/src/render/program/fill_extrusion_program.js +122 -0
  123. package/src/render/program/fill_program.js +126 -0
  124. package/src/render/program/heatmap_program.js +83 -0
  125. package/src/render/program/hillshade_program.js +119 -0
  126. package/src/render/program/line_program.js +211 -0
  127. package/src/render/program/pattern.js +102 -0
  128. package/src/render/program/program_uniforms.js +42 -0
  129. package/src/render/program/raster_program.js +92 -0
  130. package/src/render/program/symbol_program.js +224 -0
  131. package/src/render/program.js +188 -0
  132. package/src/render/texture.js +122 -0
  133. package/src/render/uniform_binding.js +147 -0
  134. package/src/render/vertex_array_object.js +163 -0
  135. package/src/shaders/README.md +42 -0
  136. package/src/shaders/_prelude.fragment.glsl +17 -0
  137. package/src/shaders/_prelude.vertex.glsl +73 -0
  138. package/src/shaders/background.fragment.glsl +10 -0
  139. package/src/shaders/background.vertex.glsl +7 -0
  140. package/src/shaders/background_pattern.fragment.glsl +28 -0
  141. package/src/shaders/background_pattern.vertex.glsl +20 -0
  142. package/src/shaders/circle.fragment.glsl +39 -0
  143. package/src/shaders/circle.vertex.glsl +64 -0
  144. package/src/shaders/clipping_mask.fragment.glsl +3 -0
  145. package/src/shaders/clipping_mask.vertex.glsl +7 -0
  146. package/src/shaders/collision_box.fragment.glsl +21 -0
  147. package/src/shaders/collision_box.vertex.glsl +27 -0
  148. package/src/shaders/collision_circle.fragment.glsl +17 -0
  149. package/src/shaders/collision_circle.vertex.glsl +59 -0
  150. package/src/shaders/debug.fragment.glsl +9 -0
  151. package/src/shaders/debug.vertex.glsl +12 -0
  152. package/src/shaders/encode_attribute.js +17 -0
  153. package/src/shaders/fill.fragment.glsl +13 -0
  154. package/src/shaders/fill.vertex.glsl +13 -0
  155. package/src/shaders/fill_extrusion.fragment.glsl +9 -0
  156. package/src/shaders/fill_extrusion.vertex.glsl +66 -0
  157. package/src/shaders/fill_extrusion_pattern.fragment.glsl +45 -0
  158. package/src/shaders/fill_extrusion_pattern.vertex.glsl +79 -0
  159. package/src/shaders/fill_outline.fragment.glsl +17 -0
  160. package/src/shaders/fill_outline.vertex.glsl +17 -0
  161. package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
  162. package/src/shaders/fill_outline_pattern.vertex.glsl +44 -0
  163. package/src/shaders/fill_pattern.fragment.glsl +36 -0
  164. package/src/shaders/fill_pattern.vertex.glsl +39 -0
  165. package/src/shaders/heatmap.fragment.glsl +22 -0
  166. package/src/shaders/heatmap.vertex.glsl +54 -0
  167. package/src/shaders/heatmap_texture.fragment.glsl +14 -0
  168. package/src/shaders/heatmap_texture.vertex.glsl +11 -0
  169. package/src/shaders/hillshade.fragment.glsl +52 -0
  170. package/src/shaders/hillshade.vertex.glsl +11 -0
  171. package/src/shaders/hillshade_prepare.fragment.glsl +75 -0
  172. package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
  173. package/src/shaders/index.js +20 -0
  174. package/src/shaders/line.fragment.glsl +30 -0
  175. package/src/shaders/line.vertex.glsl +85 -0
  176. package/src/shaders/line_gradient.fragment.glsl +34 -0
  177. package/src/shaders/line_gradient.vertex.glsl +88 -0
  178. package/src/shaders/line_pattern.fragment.glsl +74 -0
  179. package/src/shaders/line_pattern.vertex.glsl +99 -0
  180. package/src/shaders/line_sdf.fragment.glsl +45 -0
  181. package/src/shaders/line_sdf.vertex.glsl +98 -0
  182. package/src/shaders/raster.fragment.glsl +52 -0
  183. package/src/shaders/raster.vertex.glsl +21 -0
  184. package/src/shaders/shaders.js +185 -0
  185. package/src/shaders/symbol_icon.fragment.glsl +17 -0
  186. package/src/shaders/symbol_icon.vertex.glsl +94 -0
  187. package/src/shaders/symbol_sdf.fragment.glsl +52 -0
  188. package/src/shaders/symbol_sdf.vertex.glsl +115 -0
  189. package/src/shaders/symbol_text_and_icon.fragment.glsl +68 -0
  190. package/src/shaders/symbol_text_and_icon.vertex.glsl +116 -0
  191. package/src/source/canvas_source.js +238 -0
  192. package/src/source/geojson_source.js +370 -0
  193. package/src/source/geojson_worker_source.js +366 -0
  194. package/src/source/geojson_wrapper.js +94 -0
  195. package/src/source/image_source.js +307 -0
  196. package/src/source/load_tilejson.js +39 -0
  197. package/src/source/pixels_to_tile_units.js +21 -0
  198. package/src/source/query_features.js +208 -0
  199. package/src/source/raster_dem_tile_source.js +138 -0
  200. package/src/source/raster_dem_tile_worker_source.js +62 -0
  201. package/src/source/raster_tile_source.js +169 -0
  202. package/src/source/rtl_text_plugin.js +143 -0
  203. package/src/source/source.js +137 -0
  204. package/src/source/source_cache.js +953 -0
  205. package/src/source/source_state.js +159 -0
  206. package/src/source/tile.js +458 -0
  207. package/src/source/tile_bounds.js +38 -0
  208. package/src/source/tile_cache.js +212 -0
  209. package/src/source/tile_id.js +199 -0
  210. package/src/source/vector_tile_source.js +259 -0
  211. package/src/source/vector_tile_worker_source.js +216 -0
  212. package/src/source/video_source.js +203 -0
  213. package/src/source/worker.js +240 -0
  214. package/src/source/worker_source.js +107 -0
  215. package/src/source/worker_tile.js +224 -0
  216. package/src/style/create_style_layer.js +36 -0
  217. package/src/style/evaluation_parameters.js +62 -0
  218. package/src/style/format_section_override.js +56 -0
  219. package/src/style/light.js +130 -0
  220. package/src/style/load_glyph_range.js +38 -0
  221. package/src/style/load_sprite.js +67 -0
  222. package/src/style/parse_glyph_pbf.js +44 -0
  223. package/src/style/pauseable_placement.js +132 -0
  224. package/src/style/properties.js +753 -0
  225. package/src/style/query_utils.js +43 -0
  226. package/src/style/style.js +1374 -0
  227. package/src/style/style_glyph.js +17 -0
  228. package/src/style/style_image.js +137 -0
  229. package/src/style/style_layer/background_style_layer.js +21 -0
  230. package/src/style/style_layer/background_style_layer_properties.js +40 -0
  231. package/src/style/style_layer/circle_style_layer.js +98 -0
  232. package/src/style/style_layer/circle_style_layer_properties.js +63 -0
  233. package/src/style/style_layer/custom_style_layer.js +223 -0
  234. package/src/style/style_layer/fill_extrusion_style_layer.js +224 -0
  235. package/src/style/style_layer/fill_extrusion_style_layer_properties.js +50 -0
  236. package/src/style/style_layer/fill_style_layer.js +67 -0
  237. package/src/style/style_layer/fill_style_layer_properties.js +55 -0
  238. package/src/style/style_layer/heatmap_style_layer.js +73 -0
  239. package/src/style/style_layer/heatmap_style_layer_properties.js +44 -0
  240. package/src/style/style_layer/hillshade_style_layer.js +25 -0
  241. package/src/style/style_layer/hillshade_style_layer_properties.js +46 -0
  242. package/src/style/style_layer/layer_properties.js.ejs +69 -0
  243. package/src/style/style_layer/line_style_layer.js +150 -0
  244. package/src/style/style_layer/line_style_layer_properties.js +71 -0
  245. package/src/style/style_layer/raster_style_layer.js +21 -0
  246. package/src/style/style_layer/raster_style_layer_properties.js +50 -0
  247. package/src/style/style_layer/symbol_style_layer.js +190 -0
  248. package/src/style/style_layer/symbol_style_layer_properties.js +153 -0
  249. package/src/style/style_layer/typed_style_layer.js +17 -0
  250. package/src/style/style_layer.js +283 -0
  251. package/src/style/style_layer_index.js +80 -0
  252. package/src/style/validate_style.js +42 -0
  253. package/src/style/zoom_history.js +44 -0
  254. package/src/style-spec/.eslintrc +5 -0
  255. package/src/style-spec/CHANGELOG.md +468 -0
  256. package/src/style-spec/README.md +59 -0
  257. package/src/style-spec/bin/gl-style-composite +9 -0
  258. package/src/style-spec/bin/gl-style-format +22 -0
  259. package/src/style-spec/bin/gl-style-migrate +9 -0
  260. package/src/style-spec/bin/gl-style-validate +50 -0
  261. package/src/style-spec/composite.js +50 -0
  262. package/src/style-spec/declass.js +42 -0
  263. package/src/style-spec/deref.js +52 -0
  264. package/src/style-spec/diff.js +393 -0
  265. package/src/style-spec/dist/.gitkeep +0 -0
  266. package/src/style-spec/dist/index.es.js +15032 -0
  267. package/src/style-spec/dist/index.es.js.map +1 -0
  268. package/src/style-spec/dist/index.js +15058 -0
  269. package/src/style-spec/dist/index.js.map +1 -0
  270. package/src/style-spec/empty.js +29 -0
  271. package/src/style-spec/error/parsing_error.js +16 -0
  272. package/src/style-spec/error/validation_error.js +18 -0
  273. package/src/style-spec/expression/compound_expression.js +162 -0
  274. package/src/style-spec/expression/definitions/assertion.js +130 -0
  275. package/src/style-spec/expression/definitions/at.js +70 -0
  276. package/src/style-spec/expression/definitions/case.js +85 -0
  277. package/src/style-spec/expression/definitions/coalesce.js +93 -0
  278. package/src/style-spec/expression/definitions/coercion.js +133 -0
  279. package/src/style-spec/expression/definitions/collator.js +78 -0
  280. package/src/style-spec/expression/definitions/comparison.js +184 -0
  281. package/src/style-spec/expression/definitions/format.js +144 -0
  282. package/src/style-spec/expression/definitions/image.js +52 -0
  283. package/src/style-spec/expression/definitions/in.js +72 -0
  284. package/src/style-spec/expression/definitions/index.js +565 -0
  285. package/src/style-spec/expression/definitions/index_of.js +89 -0
  286. package/src/style-spec/expression/definitions/interpolate.js +267 -0
  287. package/src/style-spec/expression/definitions/length.js +61 -0
  288. package/src/style-spec/expression/definitions/let.js +72 -0
  289. package/src/style-spec/expression/definitions/literal.js +77 -0
  290. package/src/style-spec/expression/definitions/match.js +158 -0
  291. package/src/style-spec/expression/definitions/number_format.js +142 -0
  292. package/src/style-spec/expression/definitions/slice.js +86 -0
  293. package/src/style-spec/expression/definitions/step.js +120 -0
  294. package/src/style-spec/expression/definitions/var.js +46 -0
  295. package/src/style-spec/expression/definitions/within.js +342 -0
  296. package/src/style-spec/expression/evaluation_context.js +59 -0
  297. package/src/style-spec/expression/expression.js +27 -0
  298. package/src/style-spec/expression/index.js +392 -0
  299. package/src/style-spec/expression/is_constant.js +59 -0
  300. package/src/style-spec/expression/parsing_context.js +233 -0
  301. package/src/style-spec/expression/parsing_error.js +13 -0
  302. package/src/style-spec/expression/runtime_error.js +17 -0
  303. package/src/style-spec/expression/scope.js +36 -0
  304. package/src/style-spec/expression/stops.js +39 -0
  305. package/src/style-spec/expression/types/collator.js +61 -0
  306. package/src/style-spec/expression/types/formatted.js +73 -0
  307. package/src/style-spec/expression/types/resolved_image.js +29 -0
  308. package/src/style-spec/expression/types.js +126 -0
  309. package/src/style-spec/expression/values.js +123 -0
  310. package/src/style-spec/feature_filter/README.md +55 -0
  311. package/src/style-spec/feature_filter/convert.js +208 -0
  312. package/src/style-spec/feature_filter/index.js +175 -0
  313. package/src/style-spec/format.js +51 -0
  314. package/src/style-spec/function/convert.js +270 -0
  315. package/src/style-spec/function/index.js +262 -0
  316. package/src/style-spec/group_by_layout.js +75 -0
  317. package/src/style-spec/migrate/expressions.js +39 -0
  318. package/src/style-spec/migrate/v8.js +203 -0
  319. package/src/style-spec/migrate/v9.js +26 -0
  320. package/src/style-spec/migrate.js +36 -0
  321. package/src/style-spec/package.json +41 -0
  322. package/src/style-spec/read_style.js +14 -0
  323. package/src/style-spec/reference/latest.js +3 -0
  324. package/src/style-spec/reference/v8.json +5914 -0
  325. package/src/style-spec/rollup.config.js +65 -0
  326. package/src/style-spec/style-spec.js +124 -0
  327. package/src/style-spec/types.js +432 -0
  328. package/src/style-spec/util/color.js +95 -0
  329. package/src/style-spec/util/color_spaces.js +139 -0
  330. package/src/style-spec/util/deep_equal.js +28 -0
  331. package/src/style-spec/util/extend.js +10 -0
  332. package/src/style-spec/util/get_type.js +17 -0
  333. package/src/style-spec/util/interpolate.js +22 -0
  334. package/src/style-spec/util/properties.js +15 -0
  335. package/src/style-spec/util/ref_properties.js +2 -0
  336. package/src/style-spec/util/result.js +19 -0
  337. package/src/style-spec/util/unbundle_jsonlint.js +24 -0
  338. package/src/style-spec/validate/latest.js +11 -0
  339. package/src/style-spec/validate/validate.js +75 -0
  340. package/src/style-spec/validate/validate_array.js +52 -0
  341. package/src/style-spec/validate/validate_boolean.js +15 -0
  342. package/src/style-spec/validate/validate_color.js +20 -0
  343. package/src/style-spec/validate/validate_constants.js +13 -0
  344. package/src/style-spec/validate/validate_enum.js +21 -0
  345. package/src/style-spec/validate/validate_expression.js +43 -0
  346. package/src/style-spec/validate/validate_filter.js +117 -0
  347. package/src/style-spec/validate/validate_formatted.js +11 -0
  348. package/src/style-spec/validate/validate_function.js +207 -0
  349. package/src/style-spec/validate/validate_glyphs_url.js +21 -0
  350. package/src/style-spec/validate/validate_image.js +11 -0
  351. package/src/style-spec/validate/validate_layer.js +134 -0
  352. package/src/style-spec/validate/validate_layout_property.js +6 -0
  353. package/src/style-spec/validate/validate_light.js +47 -0
  354. package/src/style-spec/validate/validate_number.js +29 -0
  355. package/src/style-spec/validate/validate_object.js +61 -0
  356. package/src/style-spec/validate/validate_paint_property.js +6 -0
  357. package/src/style-spec/validate/validate_property.js +64 -0
  358. package/src/style-spec/validate/validate_source.js +111 -0
  359. package/src/style-spec/validate/validate_string.js +15 -0
  360. package/src/style-spec/validate_mapbox_api_supported.js +171 -0
  361. package/src/style-spec/validate_style.js +39 -0
  362. package/src/style-spec/validate_style.min.js +78 -0
  363. package/src/style-spec/visit.js +77 -0
  364. package/src/symbol/anchor.js +26 -0
  365. package/src/symbol/check_max_angle.js +81 -0
  366. package/src/symbol/clip_line.js +71 -0
  367. package/src/symbol/collision_feature.js +109 -0
  368. package/src/symbol/collision_index.js +373 -0
  369. package/src/symbol/cross_tile_symbol_index.js +301 -0
  370. package/src/symbol/get_anchors.js +167 -0
  371. package/src/symbol/grid_index.js +335 -0
  372. package/src/symbol/mergelines.js +82 -0
  373. package/src/symbol/one_em.js +4 -0
  374. package/src/symbol/opacity_state.js +27 -0
  375. package/src/symbol/path_interpolator.js +61 -0
  376. package/src/symbol/placement.js +1124 -0
  377. package/src/symbol/projection.js +451 -0
  378. package/src/symbol/quads.js +334 -0
  379. package/src/symbol/shaping.js +816 -0
  380. package/src/symbol/symbol_layout.js +796 -0
  381. package/src/symbol/symbol_size.js +113 -0
  382. package/src/symbol/transform_text.js +29 -0
  383. package/src/types/callback.js +17 -0
  384. package/src/types/cancelable.js +3 -0
  385. package/src/types/tilejson.js +17 -0
  386. package/src/types/transferable.js +3 -0
  387. package/src/types/window.js +172 -0
  388. package/src/ui/anchor.js +32 -0
  389. package/src/ui/camera.js +1277 -0
  390. package/src/ui/control/attribution_control.js +212 -0
  391. package/src/ui/control/fullscreen_control.js +147 -0
  392. package/src/ui/control/geolocate_control.js +707 -0
  393. package/src/ui/control/logo_control.js +92 -0
  394. package/src/ui/control/navigation_control.js +257 -0
  395. package/src/ui/control/scale_control.js +142 -0
  396. package/src/ui/default_locale.js +22 -0
  397. package/src/ui/events.js +1301 -0
  398. package/src/ui/handler/box_zoom.js +170 -0
  399. package/src/ui/handler/click_zoom.js +52 -0
  400. package/src/ui/handler/handler_util.js +12 -0
  401. package/src/ui/handler/keyboard.js +208 -0
  402. package/src/ui/handler/map_event.js +156 -0
  403. package/src/ui/handler/mouse.js +171 -0
  404. package/src/ui/handler/scroll_zoom.js +350 -0
  405. package/src/ui/handler/shim/dblclick_zoom.js +62 -0
  406. package/src/ui/handler/shim/drag_pan.js +88 -0
  407. package/src/ui/handler/shim/drag_rotate.js +67 -0
  408. package/src/ui/handler/shim/touch_zoom_rotate.js +108 -0
  409. package/src/ui/handler/tap_drag_zoom.js +103 -0
  410. package/src/ui/handler/tap_recognizer.js +133 -0
  411. package/src/ui/handler/tap_zoom.js +93 -0
  412. package/src/ui/handler/touch_pan.js +101 -0
  413. package/src/ui/handler/touch_zoom_rotate.js +305 -0
  414. package/src/ui/handler_inertia.js +158 -0
  415. package/src/ui/handler_manager.js +531 -0
  416. package/src/ui/hash.js +148 -0
  417. package/src/ui/map.js +2874 -0
  418. package/src/ui/marker.js +672 -0
  419. package/src/ui/popup.js +640 -0
  420. package/src/util/actor.js +212 -0
  421. package/src/util/ajax.js +388 -0
  422. package/src/util/browser/web_worker.js +10 -0
  423. package/src/util/browser/window.js +6 -0
  424. package/src/util/browser.js +70 -0
  425. package/src/util/classify_rings.js +52 -0
  426. package/src/util/color_ramp.js +61 -0
  427. package/src/util/config.js +30 -0
  428. package/src/util/debug.js +28 -0
  429. package/src/util/dictionary_coder.js +30 -0
  430. package/src/util/dispatcher.js +70 -0
  431. package/src/util/dom.js +142 -0
  432. package/src/util/evented.js +174 -0
  433. package/src/util/find_pole_of_inaccessibility.js +129 -0
  434. package/src/util/global_worker_pool.js +35 -0
  435. package/src/util/image.js +142 -0
  436. package/src/util/intersection_tests.js +208 -0
  437. package/src/util/is_char_in_unicode_block.js +311 -0
  438. package/src/util/mapbox.js +491 -0
  439. package/src/util/offscreen_canvas_supported.js +14 -0
  440. package/src/util/performance.js +112 -0
  441. package/src/util/primitives.js +145 -0
  442. package/src/util/resolve_tokens.js +16 -0
  443. package/src/util/script_detection.js +328 -0
  444. package/src/util/sku_token.js +42 -0
  445. package/src/util/smart_wrap.js +55 -0
  446. package/src/util/struct_array.js +243 -0
  447. package/src/util/struct_array.js.ejs +112 -0
  448. package/src/util/struct_array_layout.js.ejs +98 -0
  449. package/src/util/task_queue.js +68 -0
  450. package/src/util/throttle.js +27 -0
  451. package/src/util/throttled_invoker.js +46 -0
  452. package/src/util/tile_request_cache.js +172 -0
  453. package/src/util/util.js +524 -0
  454. package/src/util/vectortile_to_geojson.js +50 -0
  455. package/src/util/verticalize_punctuation.js +114 -0
  456. package/src/util/web_worker.js +91 -0
  457. package/src/util/web_worker_transfer.js +266 -0
  458. package/src/util/webp_supported.js +69 -0
  459. package/src/util/window.js +102 -0
  460. package/src/util/worker_pool.js +57 -0
@@ -0,0 +1,1374 @@
1
+ // @flow
2
+
3
+ import assert from 'assert';
4
+
5
+ import {Event, ErrorEvent, Evented} from '../util/evented';
6
+ import StyleLayer from './style_layer';
7
+ import createStyleLayer from './create_style_layer';
8
+ import loadSprite from './load_sprite';
9
+ import ImageManager from '../render/image_manager';
10
+ import GlyphManager from '../render/glyph_manager';
11
+ import Light from './light';
12
+ import LineAtlas from '../render/line_atlas';
13
+ import {pick, clone, extend, deepEqual, filterObject, mapObject} from '../util/util';
14
+ import {getJSON, getReferrer, makeRequest, ResourceType} from '../util/ajax';
15
+ import {isMapboxURL} from '../util/mapbox';
16
+ import browser from '../util/browser';
17
+ import Dispatcher from '../util/dispatcher';
18
+ import {validateStyle, emitValidationErrors as _emitValidationErrors} from './validate_style';
19
+ import {
20
+ getType as getSourceType,
21
+ setType as setSourceType,
22
+ type SourceClass
23
+ } from '../source/source';
24
+ import {queryRenderedFeatures, queryRenderedSymbols, querySourceFeatures} from '../source/query_features';
25
+ import SourceCache from '../source/source_cache';
26
+ import GeoJSONSource from '../source/geojson_source';
27
+ import styleSpec from '../style-spec/reference/latest';
28
+ import getWorkerPool from '../util/global_worker_pool';
29
+ import deref from '../style-spec/deref';
30
+ import emptyStyle from '../style-spec/empty';
31
+ import diffStyles, {operations as diffOperations} from '../style-spec/diff';
32
+ import {
33
+ registerForPluginStateChange,
34
+ evented as rtlTextPluginEvented,
35
+ triggerPluginCompletionEvent
36
+ } from '../source/rtl_text_plugin';
37
+ import PauseablePlacement from './pauseable_placement';
38
+ import ZoomHistory from './zoom_history';
39
+ import CrossTileSymbolIndex from '../symbol/cross_tile_symbol_index';
40
+ import {validateCustomStyleLayer} from './style_layer/custom_style_layer';
41
+
42
+ // We're skipping validation errors with the `source.canvas` identifier in order
43
+ // to continue to allow canvas sources to be added at runtime/updated in
44
+ // smart setStyle (see https://github.com/mapbox/mapbox-gl-js/pull/6424):
45
+ const emitValidationErrors = (evented: Evented, errors: ?$ReadOnlyArray<{message: string, identifier?: string}>) =>
46
+ _emitValidationErrors(evented, errors && errors.filter(error => error.identifier !== 'source.canvas'));
47
+
48
+ import type Map from '../ui/map';
49
+ import type Transform from '../geo/transform';
50
+ import type {StyleImage} from './style_image';
51
+ import type {StyleGlyph} from './style_glyph';
52
+ import type {Callback} from '../types/callback';
53
+ import type EvaluationParameters from './evaluation_parameters';
54
+ import type {Placement} from '../symbol/placement';
55
+ import type {Cancelable} from '../types/cancelable';
56
+ import type {RequestParameters, ResponseCallback} from '../util/ajax';
57
+ import type {GeoJSON} from '@mapbox/geojson-types';
58
+ import type {
59
+ LayerSpecification,
60
+ FilterSpecification,
61
+ StyleSpecification,
62
+ LightSpecification,
63
+ SourceSpecification
64
+ } from '../style-spec/types';
65
+ import type {CustomLayerInterface} from './style_layer/custom_style_layer';
66
+ import type {Validator} from './validate_style';
67
+ import type {OverscaledTileID} from '../source/tile_id';
68
+
69
+ const supportedDiffOperations = pick(diffOperations, [
70
+ 'addLayer',
71
+ 'removeLayer',
72
+ 'setPaintProperty',
73
+ 'setLayoutProperty',
74
+ 'setFilter',
75
+ 'addSource',
76
+ 'removeSource',
77
+ 'setLayerZoomRange',
78
+ 'setLight',
79
+ 'setTransition',
80
+ 'setGeoJSONSourceData'
81
+ // 'setGlyphs',
82
+ // 'setSprite',
83
+ ]);
84
+
85
+ const ignoredDiffOperations = pick(diffOperations, [
86
+ 'setCenter',
87
+ 'setZoom',
88
+ 'setBearing',
89
+ 'setPitch'
90
+ ]);
91
+
92
+ const empty = emptyStyle();
93
+
94
+ export type StyleOptions = {
95
+ validate?: boolean,
96
+ localIdeographFontFamily?: string
97
+ };
98
+
99
+ export type StyleSetterOptions = {
100
+ validate?: boolean
101
+ };
102
+ /**
103
+ * @private
104
+ */
105
+ class Style extends Evented {
106
+ map: Map;
107
+ stylesheet: StyleSpecification;
108
+ dispatcher: Dispatcher;
109
+ imageManager: ImageManager;
110
+ glyphManager: GlyphManager;
111
+ lineAtlas: LineAtlas;
112
+ light: Light;
113
+
114
+ _request: ?Cancelable;
115
+ _spriteRequest: ?Cancelable;
116
+ _layers: {[_: string]: StyleLayer};
117
+ _serializedLayers: {[_: string]: Object};
118
+ _order: Array<string>;
119
+ sourceCaches: {[_: string]: SourceCache};
120
+ zoomHistory: ZoomHistory;
121
+ _loaded: boolean;
122
+ _rtlTextPluginCallback: Function;
123
+ _changed: boolean;
124
+ _updatedSources: {[_: string]: 'clear' | 'reload'};
125
+ _updatedLayers: {[_: string]: true};
126
+ _removedLayers: {[_: string]: StyleLayer};
127
+ _changedImages: {[_: string]: true};
128
+ _updatedPaintProps: {[layer: string]: true};
129
+ _layerOrderChanged: boolean;
130
+ _availableImages: Array<string>;
131
+
132
+ crossTileSymbolIndex: CrossTileSymbolIndex;
133
+ pauseablePlacement: PauseablePlacement;
134
+ placement: Placement;
135
+ z: number;
136
+
137
+ // exposed to allow stubbing by unit tests
138
+ static getSourceType: typeof getSourceType;
139
+ static setSourceType: typeof setSourceType;
140
+ static registerForPluginStateChange: typeof registerForPluginStateChange;
141
+
142
+ constructor(map: Map, options: StyleOptions = {}) {
143
+ super();
144
+
145
+ this.map = map;
146
+ this.dispatcher = new Dispatcher(getWorkerPool(), this);
147
+ this.imageManager = new ImageManager();
148
+ this.imageManager.setEventedParent(this);
149
+ this.glyphManager = new GlyphManager(map._requestManager, options.localIdeographFontFamily);
150
+ this.lineAtlas = new LineAtlas(256, 512);
151
+ this.crossTileSymbolIndex = new CrossTileSymbolIndex();
152
+
153
+ this._layers = {};
154
+ this._serializedLayers = {};
155
+ this._order = [];
156
+ this.sourceCaches = {};
157
+ this.zoomHistory = new ZoomHistory();
158
+ this._loaded = false;
159
+ this._availableImages = [];
160
+
161
+ this._resetUpdates();
162
+
163
+ this.dispatcher.broadcast('setReferrer', getReferrer());
164
+
165
+ const self = this;
166
+ this._rtlTextPluginCallback = Style.registerForPluginStateChange((event) => {
167
+ const state = {
168
+ pluginStatus: event.pluginStatus,
169
+ pluginURL: event.pluginURL
170
+ };
171
+ self.dispatcher.broadcast('syncRTLPluginState', state, (err, results) => {
172
+ triggerPluginCompletionEvent(err);
173
+ if (results) {
174
+ const allComplete = results.every((elem) => elem);
175
+ if (allComplete) {
176
+ for (const id in self.sourceCaches) {
177
+ self.sourceCaches[id].reload(); // Should be a no-op if the plugin loads before any tiles load
178
+ }
179
+ }
180
+ }
181
+
182
+ });
183
+ });
184
+
185
+ this.on('data', (event) => {
186
+ if (event.dataType !== 'source' || event.sourceDataType !== 'metadata') {
187
+ return;
188
+ }
189
+
190
+ const sourceCache = this.sourceCaches[event.sourceId];
191
+ if (!sourceCache) {
192
+ return;
193
+ }
194
+
195
+ const source = sourceCache.getSource();
196
+ if (!source || !source.vectorLayerIds) {
197
+ return;
198
+ }
199
+
200
+ for (const layerId in this._layers) {
201
+ const layer = this._layers[layerId];
202
+ if (layer.source === source.id) {
203
+ this._validateLayer(layer);
204
+ }
205
+ }
206
+ });
207
+ }
208
+
209
+ loadURL(url: string, options: {
210
+ validate?: boolean,
211
+ accessToken?: string
212
+ } = {}) {
213
+ this.fire(new Event('dataloading', {dataType: 'style'}));
214
+
215
+ const validate = typeof options.validate === 'boolean' ?
216
+ options.validate : !isMapboxURL(url);
217
+
218
+ url = this.map._requestManager.normalizeStyleURL(url, options.accessToken);
219
+ const request = this.map._requestManager.transformRequest(url, ResourceType.Style);
220
+ this._request = getJSON(request, (error: ?Error, json: ?Object) => {
221
+ this._request = null;
222
+ if (error) {
223
+ this.fire(new ErrorEvent(error));
224
+ } else if (json) {
225
+ this._load(json, validate);
226
+ }
227
+ });
228
+ }
229
+
230
+ loadJSON(json: StyleSpecification, options: StyleSetterOptions = {}) {
231
+ this.fire(new Event('dataloading', {dataType: 'style'}));
232
+
233
+ this._request = browser.frame(() => {
234
+ this._request = null;
235
+ this._load(json, options.validate !== false);
236
+ });
237
+ }
238
+
239
+ loadEmpty() {
240
+ this.fire(new Event('dataloading', {dataType: 'style'}));
241
+ this._load(empty, false);
242
+ }
243
+
244
+ _load(json: StyleSpecification, validate: boolean) {
245
+ if (validate && emitValidationErrors(this, validateStyle(json))) {
246
+ return;
247
+ }
248
+
249
+ this._loaded = true;
250
+ this.stylesheet = json;
251
+
252
+ for (const id in json.sources) {
253
+ this.addSource(id, json.sources[id], {validate: false});
254
+ }
255
+
256
+ if (json.sprite) {
257
+ this._loadSprite(json.sprite);
258
+ } else {
259
+ this.imageManager.setLoaded(true);
260
+ }
261
+
262
+ this.glyphManager.setURL(json.glyphs);
263
+
264
+ const layers = deref(this.stylesheet.layers);
265
+
266
+ this._order = layers.map((layer) => layer.id);
267
+
268
+ this._layers = {};
269
+ this._serializedLayers = {};
270
+ for (let layer of layers) {
271
+ layer = createStyleLayer(layer);
272
+ layer.setEventedParent(this, {layer: {id: layer.id}});
273
+ this._layers[layer.id] = layer;
274
+ this._serializedLayers[layer.id] = layer.serialize();
275
+ }
276
+ this.dispatcher.broadcast('setLayers', this._serializeLayers(this._order));
277
+
278
+ this.light = new Light(this.stylesheet.light);
279
+
280
+ this.fire(new Event('data', {dataType: 'style'}));
281
+ this.fire(new Event('style.load'));
282
+ }
283
+
284
+ _loadSprite(url: string) {
285
+ this._spriteRequest = loadSprite(url, this.map._requestManager, (err, images) => {
286
+ this._spriteRequest = null;
287
+ if (err) {
288
+ this.fire(new ErrorEvent(err));
289
+ } else if (images) {
290
+ for (const id in images) {
291
+ this.imageManager.addImage(id, images[id]);
292
+ }
293
+ }
294
+
295
+ this.imageManager.setLoaded(true);
296
+ this._availableImages = this.imageManager.listImages();
297
+ this.dispatcher.broadcast('setImages', this._availableImages);
298
+ this.fire(new Event('data', {dataType: 'style'}));
299
+ });
300
+ }
301
+
302
+ _validateLayer(layer: StyleLayer) {
303
+ const sourceCache = this.sourceCaches[layer.source];
304
+ if (!sourceCache) {
305
+ return;
306
+ }
307
+
308
+ const sourceLayer = layer.sourceLayer;
309
+ if (!sourceLayer) {
310
+ return;
311
+ }
312
+
313
+ const source = sourceCache.getSource();
314
+ if (source.type === 'geojson' || (source.vectorLayerIds && source.vectorLayerIds.indexOf(sourceLayer) === -1)) {
315
+ this.fire(new ErrorEvent(new Error(
316
+ `Source layer "${sourceLayer}" ` +
317
+ `does not exist on source "${source.id}" ` +
318
+ `as specified by style layer "${layer.id}"`
319
+ )));
320
+ }
321
+ }
322
+
323
+ loaded() {
324
+ if (!this._loaded)
325
+ return false;
326
+
327
+ if (Object.keys(this._updatedSources).length)
328
+ return false;
329
+
330
+ for (const id in this.sourceCaches)
331
+ if (!this.sourceCaches[id].loaded())
332
+ return false;
333
+
334
+ if (!this.imageManager.isLoaded())
335
+ return false;
336
+
337
+ return true;
338
+ }
339
+
340
+ _serializeLayers(ids: Array<string>): Array<Object> {
341
+ const serializedLayers = [];
342
+ for (const id of ids) {
343
+ const layer = this._layers[id];
344
+ if (layer.type !== 'custom') {
345
+ serializedLayers.push(layer.serialize());
346
+ }
347
+ }
348
+ return serializedLayers;
349
+ }
350
+
351
+ hasTransitions() {
352
+ if (this.light && this.light.hasTransition()) {
353
+ return true;
354
+ }
355
+
356
+ for (const id in this.sourceCaches) {
357
+ if (this.sourceCaches[id].hasTransition()) {
358
+ return true;
359
+ }
360
+ }
361
+
362
+ for (const id in this._layers) {
363
+ if (this._layers[id].hasTransition()) {
364
+ return true;
365
+ }
366
+ }
367
+
368
+ return false;
369
+ }
370
+
371
+ _checkLoaded() {
372
+ if (!this._loaded) {
373
+ throw new Error('Style is not done loading');
374
+ }
375
+ }
376
+
377
+ /**
378
+ * Apply queued style updates in a batch and recalculate zoom-dependent paint properties.
379
+ * @private
380
+ */
381
+ update(parameters: EvaluationParameters) {
382
+ if (!this._loaded) {
383
+ return;
384
+ }
385
+
386
+ const changed = this._changed;
387
+ if (this._changed) {
388
+ const updatedIds = Object.keys(this._updatedLayers);
389
+ const removedIds = Object.keys(this._removedLayers);
390
+
391
+ if (updatedIds.length || removedIds.length) {
392
+ this._updateWorkerLayers(updatedIds, removedIds);
393
+ }
394
+ for (const id in this._updatedSources) {
395
+ const action = this._updatedSources[id];
396
+ assert(action === 'reload' || action === 'clear');
397
+ if (action === 'reload') {
398
+ this._reloadSource(id);
399
+ } else if (action === 'clear') {
400
+ this._clearSource(id);
401
+ }
402
+ }
403
+
404
+ this._updateTilesForChangedImages();
405
+
406
+ for (const id in this._updatedPaintProps) {
407
+ this._layers[id].updateTransitions(parameters);
408
+ }
409
+
410
+ this.light.updateTransitions(parameters);
411
+
412
+ this._resetUpdates();
413
+ }
414
+
415
+ const sourcesUsedBefore = {};
416
+
417
+ for (const sourceId in this.sourceCaches) {
418
+ const sourceCache = this.sourceCaches[sourceId];
419
+ sourcesUsedBefore[sourceId] = sourceCache.used;
420
+ sourceCache.used = false;
421
+ }
422
+
423
+ for (const layerId of this._order) {
424
+ const layer = this._layers[layerId];
425
+
426
+ layer.recalculate(parameters, this._availableImages);
427
+ if (!layer.isHidden(parameters.zoom) && layer.source) {
428
+ this.sourceCaches[layer.source].used = true;
429
+ }
430
+ }
431
+
432
+ for (const sourceId in sourcesUsedBefore) {
433
+ const sourceCache = this.sourceCaches[sourceId];
434
+ if (sourcesUsedBefore[sourceId] !== sourceCache.used) {
435
+ sourceCache.fire(new Event('data', {sourceDataType: 'visibility', dataType:'source', sourceId}));
436
+ }
437
+ }
438
+
439
+ this.light.recalculate(parameters);
440
+ this.z = parameters.zoom;
441
+
442
+ if (changed) {
443
+ this.fire(new Event('data', {dataType: 'style'}));
444
+ }
445
+
446
+ }
447
+
448
+ /*
449
+ * Apply any queued image changes.
450
+ */
451
+ _updateTilesForChangedImages() {
452
+ const changedImages = Object.keys(this._changedImages);
453
+ if (changedImages.length) {
454
+ for (const name in this.sourceCaches) {
455
+ this.sourceCaches[name].reloadTilesForDependencies(['icons', 'patterns'], changedImages);
456
+ }
457
+ this._changedImages = {};
458
+ }
459
+ }
460
+
461
+ _updateWorkerLayers(updatedIds: Array<string>, removedIds: Array<string>) {
462
+ this.dispatcher.broadcast('updateLayers', {
463
+ layers: this._serializeLayers(updatedIds),
464
+ removedIds
465
+ });
466
+ }
467
+
468
+ _resetUpdates() {
469
+ this._changed = false;
470
+
471
+ this._updatedLayers = {};
472
+ this._removedLayers = {};
473
+
474
+ this._updatedSources = {};
475
+ this._updatedPaintProps = {};
476
+
477
+ this._changedImages = {};
478
+ }
479
+
480
+ /**
481
+ * Update this style's state to match the given style JSON, performing only
482
+ * the necessary mutations.
483
+ *
484
+ * May throw an Error ('Unimplemented: METHOD') if the mapbox-gl-style-spec
485
+ * diff algorithm produces an operation that is not supported.
486
+ *
487
+ * @returns {boolean} true if any changes were made; false otherwise
488
+ * @private
489
+ */
490
+ setState(nextState: StyleSpecification) {
491
+ this._checkLoaded();
492
+
493
+ if (emitValidationErrors(this, validateStyle(nextState))) return false;
494
+
495
+ nextState = clone(nextState);
496
+ nextState.layers = deref(nextState.layers);
497
+
498
+ const changes = diffStyles(this.serialize(), nextState)
499
+ .filter(op => !(op.command in ignoredDiffOperations));
500
+
501
+ if (changes.length === 0) {
502
+ return false;
503
+ }
504
+
505
+ const unimplementedOps = changes.filter(op => !(op.command in supportedDiffOperations));
506
+ if (unimplementedOps.length > 0) {
507
+ throw new Error(`Unimplemented: ${unimplementedOps.map(op => op.command).join(', ')}.`);
508
+ }
509
+
510
+ changes.forEach((op) => {
511
+ if (op.command === 'setTransition') {
512
+ // `transition` is always read directly off of
513
+ // `this.stylesheet`, which we update below
514
+ return;
515
+ }
516
+ (this: any)[op.command].apply(this, op.args);
517
+ });
518
+
519
+ this.stylesheet = nextState;
520
+
521
+ return true;
522
+ }
523
+
524
+ addImage(id: string, image: StyleImage) {
525
+ if (this.getImage(id)) {
526
+ return this.fire(new ErrorEvent(new Error('An image with this name already exists.')));
527
+ }
528
+ this.imageManager.addImage(id, image);
529
+ this._afterImageUpdated(id);
530
+ }
531
+
532
+ updateImage(id: string, image: StyleImage) {
533
+ this.imageManager.updateImage(id, image);
534
+ }
535
+
536
+ getImage(id: string): ?StyleImage {
537
+ return this.imageManager.getImage(id);
538
+ }
539
+
540
+ removeImage(id: string) {
541
+ if (!this.getImage(id)) {
542
+ return this.fire(new ErrorEvent(new Error('No image with this name exists.')));
543
+ }
544
+ this.imageManager.removeImage(id);
545
+ this._afterImageUpdated(id);
546
+ }
547
+
548
+ _afterImageUpdated(id: string) {
549
+ this._availableImages = this.imageManager.listImages();
550
+ this._changedImages[id] = true;
551
+ this._changed = true;
552
+ this.dispatcher.broadcast('setImages', this._availableImages);
553
+ this.fire(new Event('data', {dataType: 'style'}));
554
+ }
555
+
556
+ listImages() {
557
+ this._checkLoaded();
558
+
559
+ return this.imageManager.listImages();
560
+ }
561
+
562
+ addSource(id: string, source: SourceSpecification, options: StyleSetterOptions = {}) {
563
+ this._checkLoaded();
564
+
565
+ if (this.sourceCaches[id] !== undefined) {
566
+ throw new Error('There is already a source with this ID');
567
+ }
568
+
569
+ if (!source.type) {
570
+ throw new Error(`The type property must be defined, but only the following properties were given: ${Object.keys(source).join(', ')}.`);
571
+ }
572
+
573
+ const builtIns = ['vector', 'raster', 'geojson', 'video', 'image'];
574
+ const shouldValidate = builtIns.indexOf(source.type) >= 0;
575
+ if (shouldValidate && this._validate(validateStyle.source, `sources.${id}`, source, null, options)) return;
576
+
577
+ if (this.map && this.map._collectResourceTiming) (source: any).collectResourceTiming = true;
578
+ const sourceCache = this.sourceCaches[id] = new SourceCache(id, source, this.dispatcher);
579
+ sourceCache.style = this;
580
+ sourceCache.setEventedParent(this, () => ({
581
+ isSourceLoaded: this.loaded(),
582
+ source: sourceCache.serialize(),
583
+ sourceId: id
584
+ }));
585
+
586
+ sourceCache.onAdd(this.map);
587
+ this._changed = true;
588
+ }
589
+
590
+ /**
591
+ * Remove a source from this stylesheet, given its id.
592
+ * @param {string} id id of the source to remove
593
+ * @throws {Error} if no source is found with the given ID
594
+ * @returns {Map} The {@link Map} object.
595
+ */
596
+ removeSource(id: string) {
597
+ this._checkLoaded();
598
+
599
+ if (this.sourceCaches[id] === undefined) {
600
+ throw new Error('There is no source with this ID');
601
+ }
602
+ for (const layerId in this._layers) {
603
+ if (this._layers[layerId].source === id) {
604
+ return this.fire(new ErrorEvent(new Error(`Source "${id}" cannot be removed while layer "${layerId}" is using it.`)));
605
+ }
606
+ }
607
+
608
+ const sourceCache = this.sourceCaches[id];
609
+ delete this.sourceCaches[id];
610
+ delete this._updatedSources[id];
611
+ sourceCache.fire(new Event('data', {sourceDataType: 'metadata', dataType:'source', sourceId: id}));
612
+ sourceCache.setEventedParent(null);
613
+ sourceCache.clearTiles();
614
+
615
+ if (sourceCache.onRemove) sourceCache.onRemove(this.map);
616
+ this._changed = true;
617
+ }
618
+
619
+ /**
620
+ * Set the data of a GeoJSON source, given its id.
621
+ * @param {string} id id of the source
622
+ * @param {GeoJSON|string} data GeoJSON source
623
+ */
624
+ setGeoJSONSourceData(id: string, data: GeoJSON | string) {
625
+ this._checkLoaded();
626
+
627
+ assert(this.sourceCaches[id] !== undefined, 'There is no source with this ID');
628
+ const geojsonSource: GeoJSONSource = (this.sourceCaches[id].getSource(): any);
629
+ assert(geojsonSource.type === 'geojson');
630
+
631
+ geojsonSource.setData(data);
632
+ this._changed = true;
633
+ }
634
+
635
+ /**
636
+ * Get a source by id.
637
+ * @param {string} id id of the desired source
638
+ * @returns {Object} source
639
+ */
640
+ getSource(id: string): Object {
641
+ return this.sourceCaches[id] && this.sourceCaches[id].getSource();
642
+ }
643
+
644
+ /**
645
+ * Add a layer to the map style. The layer will be inserted before the layer with
646
+ * ID `before`, or appended if `before` is omitted.
647
+ * @param {Object | CustomLayerInterface} layerObject The style layer to add.
648
+ * @param {string} [before] ID of an existing layer to insert before
649
+ * @param {Object} options Style setter options.
650
+ * @returns {Map} The {@link Map} object.
651
+ */
652
+ addLayer(layerObject: LayerSpecification | CustomLayerInterface, before?: string, options: StyleSetterOptions = {}) {
653
+ this._checkLoaded();
654
+
655
+ const id = layerObject.id;
656
+
657
+ if (this.getLayer(id)) {
658
+ this.fire(new ErrorEvent(new Error(`Layer with id "${id}" already exists on this map`)));
659
+ return;
660
+ }
661
+
662
+ let layer;
663
+ if (layerObject.type === 'custom') {
664
+
665
+ if (emitValidationErrors(this, validateCustomStyleLayer(layerObject))) return;
666
+
667
+ layer = createStyleLayer(layerObject);
668
+
669
+ } else {
670
+ if (typeof layerObject.source === 'object') {
671
+ this.addSource(id, layerObject.source);
672
+ layerObject = clone(layerObject);
673
+ layerObject = (extend(layerObject, {source: id}): any);
674
+ }
675
+
676
+ // this layer is not in the style.layers array, so we pass an impossible array index
677
+ if (this._validate(validateStyle.layer,
678
+ `layers.${id}`, layerObject, {arrayIndex: -1}, options)) return;
679
+
680
+ layer = createStyleLayer(layerObject);
681
+ this._validateLayer(layer);
682
+
683
+ layer.setEventedParent(this, {layer: {id}});
684
+ this._serializedLayers[layer.id] = layer.serialize();
685
+ }
686
+
687
+ const index = before ? this._order.indexOf(before) : this._order.length;
688
+ if (before && index === -1) {
689
+ this.fire(new ErrorEvent(new Error(`Layer with id "${before}" does not exist on this map.`)));
690
+ return;
691
+ }
692
+
693
+ this._order.splice(index, 0, id);
694
+ this._layerOrderChanged = true;
695
+
696
+ this._layers[id] = layer;
697
+
698
+ if (this._removedLayers[id] && layer.source && layer.type !== 'custom') {
699
+ // If, in the current batch, we have already removed this layer
700
+ // and we are now re-adding it with a different `type`, then we
701
+ // need to clear (rather than just reload) the underyling source's
702
+ // tiles. Otherwise, tiles marked 'reloading' will have buckets /
703
+ // buffers that are set up for the _previous_ version of this
704
+ // layer, causing, e.g.:
705
+ // https://github.com/mapbox/mapbox-gl-js/issues/3633
706
+ const removed = this._removedLayers[id];
707
+ delete this._removedLayers[id];
708
+ if (removed.type !== layer.type) {
709
+ this._updatedSources[layer.source] = 'clear';
710
+ } else {
711
+ this._updatedSources[layer.source] = 'reload';
712
+ this.sourceCaches[layer.source].pause();
713
+ }
714
+ }
715
+ this._updateLayer(layer);
716
+
717
+ if (layer.onAdd) {
718
+ layer.onAdd(this.map);
719
+ }
720
+ }
721
+
722
+ /**
723
+ * Moves a layer to a different z-position. The layer will be inserted before the layer with
724
+ * ID `before`, or appended if `before` is omitted.
725
+ * @param {string} id ID of the layer to move
726
+ * @param {string} [before] ID of an existing layer to insert before
727
+ */
728
+ moveLayer(id: string, before?: string) {
729
+ this._checkLoaded();
730
+ this._changed = true;
731
+
732
+ const layer = this._layers[id];
733
+ if (!layer) {
734
+ this.fire(new ErrorEvent(new Error(`The layer '${id}' does not exist in the map's style and cannot be moved.`)));
735
+ return;
736
+ }
737
+
738
+ if (id === before) {
739
+ return;
740
+ }
741
+
742
+ const index = this._order.indexOf(id);
743
+ this._order.splice(index, 1);
744
+
745
+ const newIndex = before ? this._order.indexOf(before) : this._order.length;
746
+ if (before && newIndex === -1) {
747
+ this.fire(new ErrorEvent(new Error(`Layer with id "${before}" does not exist on this map.`)));
748
+ return;
749
+ }
750
+ this._order.splice(newIndex, 0, id);
751
+
752
+ this._layerOrderChanged = true;
753
+ }
754
+
755
+ /**
756
+ * Remove the layer with the given id from the style.
757
+ *
758
+ * If no such layer exists, an `error` event is fired.
759
+ *
760
+ * @param {string} id id of the layer to remove
761
+ * @fires error
762
+ */
763
+ removeLayer(id: string) {
764
+ this._checkLoaded();
765
+
766
+ const layer = this._layers[id];
767
+ if (!layer) {
768
+ this.fire(new ErrorEvent(new Error(`The layer '${id}' does not exist in the map's style and cannot be removed.`)));
769
+ return;
770
+ }
771
+
772
+ layer.setEventedParent(null);
773
+
774
+ const index = this._order.indexOf(id);
775
+ this._order.splice(index, 1);
776
+
777
+ this._layerOrderChanged = true;
778
+ this._changed = true;
779
+ this._removedLayers[id] = layer;
780
+ delete this._layers[id];
781
+ delete this._serializedLayers[id];
782
+ delete this._updatedLayers[id];
783
+ delete this._updatedPaintProps[id];
784
+
785
+ if (layer.onRemove) {
786
+ layer.onRemove(this.map);
787
+ }
788
+ }
789
+
790
+ /**
791
+ * Return the style layer object with the given `id`.
792
+ *
793
+ * @param {string} id - id of the desired layer
794
+ * @returns {?Object} a layer, if one with the given `id` exists
795
+ */
796
+ getLayer(id: string): Object {
797
+ return this._layers[id];
798
+ }
799
+
800
+ /**
801
+ * checks if a specific layer is present within the style.
802
+ *
803
+ * @param {string} id - id of the desired layer
804
+ * @returns {boolean} a boolean specifying if the given layer is present
805
+ */
806
+ hasLayer(id: string): boolean {
807
+ return id in this._layers;
808
+ }
809
+
810
+ setLayerZoomRange(layerId: string, minzoom: ?number, maxzoom: ?number) {
811
+ this._checkLoaded();
812
+
813
+ const layer = this.getLayer(layerId);
814
+ if (!layer) {
815
+ this.fire(new ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot have zoom extent.`)));
816
+ return;
817
+ }
818
+
819
+ if (layer.minzoom === minzoom && layer.maxzoom === maxzoom) return;
820
+
821
+ if (minzoom != null) {
822
+ layer.minzoom = minzoom;
823
+ }
824
+ if (maxzoom != null) {
825
+ layer.maxzoom = maxzoom;
826
+ }
827
+ this._updateLayer(layer);
828
+ }
829
+
830
+ setFilter(layerId: string, filter: ?FilterSpecification, options: StyleSetterOptions = {}) {
831
+ this._checkLoaded();
832
+
833
+ const layer = this.getLayer(layerId);
834
+ if (!layer) {
835
+ this.fire(new ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be filtered.`)));
836
+ return;
837
+ }
838
+
839
+ if (deepEqual(layer.filter, filter)) {
840
+ return;
841
+ }
842
+
843
+ if (filter === null || filter === undefined) {
844
+ layer.filter = undefined;
845
+ this._updateLayer(layer);
846
+ return;
847
+ }
848
+
849
+ if (this._validate(validateStyle.filter, `layers.${layer.id}.filter`, filter, null, options)) {
850
+ return;
851
+ }
852
+
853
+ layer.filter = clone(filter);
854
+ this._updateLayer(layer);
855
+ }
856
+
857
+ /**
858
+ * Get a layer's filter object
859
+ * @param {string} layer the layer to inspect
860
+ * @returns {*} the layer's filter, if any
861
+ */
862
+ getFilter(layer: string) {
863
+ return clone(this.getLayer(layer).filter);
864
+ }
865
+
866
+ setLayoutProperty(layerId: string, name: string, value: any, options: StyleSetterOptions = {}) {
867
+ this._checkLoaded();
868
+
869
+ const layer = this.getLayer(layerId);
870
+ if (!layer) {
871
+ this.fire(new ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be styled.`)));
872
+ return;
873
+ }
874
+
875
+ if (deepEqual(layer.getLayoutProperty(name), value)) return;
876
+
877
+ layer.setLayoutProperty(name, value, options);
878
+ this._updateLayer(layer);
879
+ }
880
+
881
+ /**
882
+ * Get a layout property's value from a given layer
883
+ * @param {string} layerId the layer to inspect
884
+ * @param {string} name the name of the layout property
885
+ * @returns {*} the property value
886
+ */
887
+ getLayoutProperty(layerId: string, name: string) {
888
+ const layer = this.getLayer(layerId);
889
+ if (!layer) {
890
+ this.fire(new ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style.`)));
891
+ return;
892
+ }
893
+
894
+ return layer.getLayoutProperty(name);
895
+ }
896
+
897
+ setPaintProperty(layerId: string, name: string, value: any, options: StyleSetterOptions = {}) {
898
+ this._checkLoaded();
899
+
900
+ const layer = this.getLayer(layerId);
901
+ if (!layer) {
902
+ this.fire(new ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be styled.`)));
903
+ return;
904
+ }
905
+
906
+ if (deepEqual(layer.getPaintProperty(name), value)) return;
907
+
908
+ const requiresRelayout = layer.setPaintProperty(name, value, options);
909
+ if (requiresRelayout) {
910
+ this._updateLayer(layer);
911
+ }
912
+
913
+ this._changed = true;
914
+ this._updatedPaintProps[layerId] = true;
915
+ }
916
+
917
+ getPaintProperty(layer: string, name: string) {
918
+ return this.getLayer(layer).getPaintProperty(name);
919
+ }
920
+
921
+ setFeatureState(target: { source: string; sourceLayer?: string; id: string | number; }, state: Object) {
922
+ this._checkLoaded();
923
+ const sourceId = target.source;
924
+ const sourceLayer = target.sourceLayer;
925
+ const sourceCache = this.sourceCaches[sourceId];
926
+
927
+ if (sourceCache === undefined) {
928
+ this.fire(new ErrorEvent(new Error(`The source '${sourceId}' does not exist in the map's style.`)));
929
+ return;
930
+ }
931
+ const sourceType = sourceCache.getSource().type;
932
+ if (sourceType === 'geojson' && sourceLayer) {
933
+ this.fire(new ErrorEvent(new Error(`GeoJSON sources cannot have a sourceLayer parameter.`)));
934
+ return;
935
+ }
936
+ if (sourceType === 'vector' && !sourceLayer) {
937
+ this.fire(new ErrorEvent(new Error(`The sourceLayer parameter must be provided for vector source types.`)));
938
+ return;
939
+ }
940
+ if (target.id === undefined) {
941
+ this.fire(new ErrorEvent(new Error(`The feature id parameter must be provided.`)));
942
+ }
943
+
944
+ sourceCache.setFeatureState(sourceLayer, target.id, state);
945
+ }
946
+
947
+ removeFeatureState(target: { source: string; sourceLayer?: string; id?: string | number; }, key?: string) {
948
+ this._checkLoaded();
949
+ const sourceId = target.source;
950
+ const sourceCache = this.sourceCaches[sourceId];
951
+
952
+ if (sourceCache === undefined) {
953
+ this.fire(new ErrorEvent(new Error(`The source '${sourceId}' does not exist in the map's style.`)));
954
+ return;
955
+ }
956
+
957
+ const sourceType = sourceCache.getSource().type;
958
+ const sourceLayer = sourceType === 'vector' ? target.sourceLayer : undefined;
959
+
960
+ if (sourceType === 'vector' && !sourceLayer) {
961
+ this.fire(new ErrorEvent(new Error(`The sourceLayer parameter must be provided for vector source types.`)));
962
+ return;
963
+ }
964
+
965
+ if (key && (typeof target.id !== 'string' && typeof target.id !== 'number')) {
966
+ this.fire(new ErrorEvent(new Error(`A feature id is required to remove its specific state property.`)));
967
+ return;
968
+ }
969
+
970
+ sourceCache.removeFeatureState(sourceLayer, target.id, key);
971
+ }
972
+
973
+ getFeatureState(target: { source: string; sourceLayer?: string; id: string | number; }) {
974
+ this._checkLoaded();
975
+ const sourceId = target.source;
976
+ const sourceLayer = target.sourceLayer;
977
+ const sourceCache = this.sourceCaches[sourceId];
978
+
979
+ if (sourceCache === undefined) {
980
+ this.fire(new ErrorEvent(new Error(`The source '${sourceId}' does not exist in the map's style.`)));
981
+ return;
982
+ }
983
+ const sourceType = sourceCache.getSource().type;
984
+ if (sourceType === 'vector' && !sourceLayer) {
985
+ this.fire(new ErrorEvent(new Error(`The sourceLayer parameter must be provided for vector source types.`)));
986
+ return;
987
+ }
988
+ if (target.id === undefined) {
989
+ this.fire(new ErrorEvent(new Error(`The feature id parameter must be provided.`)));
990
+ }
991
+
992
+ return sourceCache.getFeatureState(sourceLayer, target.id);
993
+ }
994
+
995
+ getTransition() {
996
+ return extend({duration: 300, delay: 0}, this.stylesheet && this.stylesheet.transition);
997
+ }
998
+
999
+ serialize() {
1000
+ return filterObject({
1001
+ version: this.stylesheet.version,
1002
+ name: this.stylesheet.name,
1003
+ metadata: this.stylesheet.metadata,
1004
+ light: this.stylesheet.light,
1005
+ center: this.stylesheet.center,
1006
+ zoom: this.stylesheet.zoom,
1007
+ bearing: this.stylesheet.bearing,
1008
+ pitch: this.stylesheet.pitch,
1009
+ sprite: this.stylesheet.sprite,
1010
+ glyphs: this.stylesheet.glyphs,
1011
+ transition: this.stylesheet.transition,
1012
+ sources: mapObject(this.sourceCaches, (source) => source.serialize()),
1013
+ layers: this._serializeLayers(this._order)
1014
+ }, (value) => { return value !== undefined; });
1015
+ }
1016
+
1017
+ _updateLayer(layer: StyleLayer) {
1018
+ this._updatedLayers[layer.id] = true;
1019
+ if (layer.source && !this._updatedSources[layer.source] &&
1020
+ //Skip for raster layers (https://github.com/mapbox/mapbox-gl-js/issues/7865)
1021
+ this.sourceCaches[layer.source].getSource().type !== 'raster') {
1022
+ this._updatedSources[layer.source] = 'reload';
1023
+ this.sourceCaches[layer.source].pause();
1024
+ }
1025
+ this._changed = true;
1026
+ }
1027
+
1028
+ _flattenAndSortRenderedFeatures(sourceResults: Array<any>) {
1029
+ // Feature order is complicated.
1030
+ // The order between features in two 2D layers is always determined by layer order.
1031
+ // The order between features in two 3D layers is always determined by depth.
1032
+ // The order between a feature in a 2D layer and a 3D layer is tricky:
1033
+ // Most often layer order determines the feature order in this case. If
1034
+ // a line layer is above a extrusion layer the line feature will be rendered
1035
+ // above the extrusion. If the line layer is below the extrusion layer,
1036
+ // it will be rendered below it.
1037
+ //
1038
+ // There is a weird case though.
1039
+ // You have layers in this order: extrusion_layer_a, line_layer, extrusion_layer_b
1040
+ // Each layer has a feature that overlaps the other features.
1041
+ // The feature in extrusion_layer_a is closer than the feature in extrusion_layer_b so it is rendered above.
1042
+ // The feature in line_layer is rendered above extrusion_layer_a.
1043
+ // This means that that the line_layer feature is above the extrusion_layer_b feature despite
1044
+ // it being in an earlier layer.
1045
+
1046
+ const isLayer3D = layerId => this._layers[layerId].type === 'fill-extrusion';
1047
+
1048
+ const layerIndex = {};
1049
+ const features3D = [];
1050
+ for (let l = this._order.length - 1; l >= 0; l--) {
1051
+ const layerId = this._order[l];
1052
+ if (isLayer3D(layerId)) {
1053
+ layerIndex[layerId] = l;
1054
+ for (const sourceResult of sourceResults) {
1055
+ const layerFeatures = sourceResult[layerId];
1056
+ if (layerFeatures) {
1057
+ for (const featureWrapper of layerFeatures) {
1058
+ features3D.push(featureWrapper);
1059
+ }
1060
+ }
1061
+ }
1062
+ }
1063
+ }
1064
+
1065
+ features3D.sort((a, b) => {
1066
+ return b.intersectionZ - a.intersectionZ;
1067
+ });
1068
+
1069
+ const features = [];
1070
+ for (let l = this._order.length - 1; l >= 0; l--) {
1071
+ const layerId = this._order[l];
1072
+
1073
+ if (isLayer3D(layerId)) {
1074
+ // add all 3D features that are in or above the current layer
1075
+ for (let i = features3D.length - 1; i >= 0; i--) {
1076
+ const topmost3D = features3D[i].feature;
1077
+ if (layerIndex[topmost3D.layer.id] < l) break;
1078
+ features.push(topmost3D);
1079
+ features3D.pop();
1080
+ }
1081
+ } else {
1082
+ for (const sourceResult of sourceResults) {
1083
+ const layerFeatures = sourceResult[layerId];
1084
+ if (layerFeatures) {
1085
+ for (const featureWrapper of layerFeatures) {
1086
+ features.push(featureWrapper.feature);
1087
+ }
1088
+ }
1089
+ }
1090
+ }
1091
+ }
1092
+
1093
+ return features;
1094
+ }
1095
+
1096
+ queryRenderedFeatures(queryGeometry: any, params: any, transform: Transform) {
1097
+ if (params && params.filter) {
1098
+ this._validate(validateStyle.filter, 'queryRenderedFeatures.filter', params.filter, null, params);
1099
+ }
1100
+
1101
+ const includedSources = {};
1102
+ if (params && params.layers) {
1103
+ if (!Array.isArray(params.layers)) {
1104
+ this.fire(new ErrorEvent(new Error('parameters.layers must be an Array.')));
1105
+ return [];
1106
+ }
1107
+ for (const layerId of params.layers) {
1108
+ const layer = this._layers[layerId];
1109
+ if (!layer) {
1110
+ // this layer is not in the style.layers array
1111
+ this.fire(new ErrorEvent(new Error(`The layer '${layerId}' does not exist in the map's style and cannot be queried for features.`)));
1112
+ return [];
1113
+ }
1114
+ includedSources[layer.source] = true;
1115
+ }
1116
+ }
1117
+
1118
+ const sourceResults = [];
1119
+
1120
+ params.availableImages = this._availableImages;
1121
+
1122
+ for (const id in this.sourceCaches) {
1123
+ if (params.layers && !includedSources[id]) continue;
1124
+ sourceResults.push(
1125
+ queryRenderedFeatures(
1126
+ this.sourceCaches[id],
1127
+ this._layers,
1128
+ this._serializedLayers,
1129
+ queryGeometry,
1130
+ params,
1131
+ transform)
1132
+ );
1133
+ }
1134
+
1135
+ if (this.placement) {
1136
+ // If a placement has run, query against its CollisionIndex
1137
+ // for symbol results, and treat it as an extra source to merge
1138
+ sourceResults.push(
1139
+ queryRenderedSymbols(
1140
+ this._layers,
1141
+ this._serializedLayers,
1142
+ this.sourceCaches,
1143
+ queryGeometry,
1144
+ params,
1145
+ this.placement.collisionIndex,
1146
+ this.placement.retainedQueryData)
1147
+ );
1148
+ }
1149
+
1150
+ return this._flattenAndSortRenderedFeatures(sourceResults);
1151
+ }
1152
+
1153
+ querySourceFeatures(sourceID: string, params: ?{sourceLayer: ?string, filter: ?Array<any>, validate?: boolean}) {
1154
+ if (params && params.filter) {
1155
+ this._validate(validateStyle.filter, 'querySourceFeatures.filter', params.filter, null, params);
1156
+ }
1157
+ const sourceCache = this.sourceCaches[sourceID];
1158
+ return sourceCache ? querySourceFeatures(sourceCache, params) : [];
1159
+ }
1160
+
1161
+ addSourceType(name: string, SourceType: SourceClass, callback: Callback<void>) {
1162
+ if (Style.getSourceType(name)) {
1163
+ return callback(new Error(`A source type called "${name}" already exists.`));
1164
+ }
1165
+
1166
+ Style.setSourceType(name, SourceType);
1167
+
1168
+ if (!SourceType.workerSourceURL) {
1169
+ return callback(null, null);
1170
+ }
1171
+
1172
+ this.dispatcher.broadcast('loadWorkerSource', {
1173
+ name,
1174
+ url: SourceType.workerSourceURL
1175
+ }, callback);
1176
+ }
1177
+
1178
+ getLight() {
1179
+ return this.light.getLight();
1180
+ }
1181
+
1182
+ setLight(lightOptions: LightSpecification, options: StyleSetterOptions = {}) {
1183
+ this._checkLoaded();
1184
+
1185
+ const light = this.light.getLight();
1186
+ let _update = false;
1187
+ for (const key in lightOptions) {
1188
+ if (!deepEqual(lightOptions[key], light[key])) {
1189
+ _update = true;
1190
+ break;
1191
+ }
1192
+ }
1193
+ if (!_update) return;
1194
+
1195
+ const parameters = {
1196
+ now: browser.now(),
1197
+ transition: extend({
1198
+ duration: 300,
1199
+ delay: 0
1200
+ }, this.stylesheet.transition)
1201
+ };
1202
+
1203
+ this.light.setLight(lightOptions, options);
1204
+ this.light.updateTransitions(parameters);
1205
+ }
1206
+
1207
+ _validate(validate: Validator, key: string, value: any, props: any, options: { validate?: boolean } = {}) {
1208
+ if (options && options.validate === false) {
1209
+ return false;
1210
+ }
1211
+ return emitValidationErrors(this, validate.call(validateStyle, extend({
1212
+ key,
1213
+ style: this.serialize(),
1214
+ value,
1215
+ styleSpec
1216
+ }, props)));
1217
+ }
1218
+
1219
+ _remove() {
1220
+ if (this._request) {
1221
+ this._request.cancel();
1222
+ this._request = null;
1223
+ }
1224
+ if (this._spriteRequest) {
1225
+ this._spriteRequest.cancel();
1226
+ this._spriteRequest = null;
1227
+ }
1228
+ rtlTextPluginEvented.off('pluginStateChange', this._rtlTextPluginCallback);
1229
+ for (const layerId in this._layers) {
1230
+ const layer: StyleLayer = this._layers[layerId];
1231
+ layer.setEventedParent(null);
1232
+ }
1233
+ for (const id in this.sourceCaches) {
1234
+ this.sourceCaches[id].clearTiles();
1235
+ this.sourceCaches[id].setEventedParent(null);
1236
+ }
1237
+ this.imageManager.setEventedParent(null);
1238
+ this.setEventedParent(null);
1239
+ this.dispatcher.remove();
1240
+ }
1241
+
1242
+ _clearSource(id: string) {
1243
+ this.sourceCaches[id].clearTiles();
1244
+ }
1245
+
1246
+ _reloadSource(id: string) {
1247
+ this.sourceCaches[id].resume();
1248
+ this.sourceCaches[id].reload();
1249
+ }
1250
+
1251
+ _updateSources(transform: Transform) {
1252
+ for (const id in this.sourceCaches) {
1253
+ this.sourceCaches[id].update(transform);
1254
+ }
1255
+ }
1256
+
1257
+ _generateCollisionBoxes() {
1258
+ for (const id in this.sourceCaches) {
1259
+ this._reloadSource(id);
1260
+ }
1261
+ }
1262
+
1263
+ _updatePlacement(transform: Transform, showCollisionBoxes: boolean, fadeDuration: number, crossSourceCollisions: boolean, forceFullPlacement: boolean = false) {
1264
+ let symbolBucketsChanged = false;
1265
+ let placementCommitted = false;
1266
+
1267
+ const layerTiles = {};
1268
+
1269
+ for (const layerID of this._order) {
1270
+ const styleLayer = this._layers[layerID];
1271
+ if (styleLayer.type !== 'symbol') continue;
1272
+
1273
+ if (!layerTiles[styleLayer.source]) {
1274
+ const sourceCache = this.sourceCaches[styleLayer.source];
1275
+ layerTiles[styleLayer.source] = sourceCache.getRenderableIds(true)
1276
+ .map((id) => sourceCache.getTileByID(id))
1277
+ .sort((a, b) => (b.tileID.overscaledZ - a.tileID.overscaledZ) || (a.tileID.isLessThan(b.tileID) ? -1 : 1));
1278
+ }
1279
+
1280
+ const layerBucketsChanged = this.crossTileSymbolIndex.addLayer(styleLayer, layerTiles[styleLayer.source], transform.center.lng);
1281
+ symbolBucketsChanged = symbolBucketsChanged || layerBucketsChanged;
1282
+ }
1283
+ this.crossTileSymbolIndex.pruneUnusedLayers(this._order);
1284
+
1285
+ // Anything that changes our "in progress" layer and tile indices requires us
1286
+ // to start over. When we start over, we do a full placement instead of incremental
1287
+ // to prevent starvation.
1288
+ // We need to restart placement to keep layer indices in sync.
1289
+ // Also force full placement when fadeDuration === 0 to ensure that newly loaded
1290
+ // tiles will fully display symbols in their first frame
1291
+ forceFullPlacement = forceFullPlacement || this._layerOrderChanged || fadeDuration === 0;
1292
+
1293
+ if (forceFullPlacement || !this.pauseablePlacement || (this.pauseablePlacement.isDone() && !this.placement.stillRecent(browser.now(), transform.zoom))) {
1294
+ this.pauseablePlacement = new PauseablePlacement(transform, this._order, forceFullPlacement, showCollisionBoxes, fadeDuration, crossSourceCollisions, this.placement);
1295
+ this._layerOrderChanged = false;
1296
+ }
1297
+
1298
+ if (this.pauseablePlacement.isDone()) {
1299
+ // the last placement finished running, but the next one hasn’t
1300
+ // started yet because of the `stillRecent` check immediately
1301
+ // above, so mark it stale to ensure that we request another
1302
+ // render frame
1303
+ this.placement.setStale();
1304
+ } else {
1305
+ this.pauseablePlacement.continuePlacement(this._order, this._layers, layerTiles);
1306
+
1307
+ if (this.pauseablePlacement.isDone()) {
1308
+ this.placement = this.pauseablePlacement.commit(browser.now());
1309
+ placementCommitted = true;
1310
+ }
1311
+
1312
+ if (symbolBucketsChanged) {
1313
+ // since the placement gets split over multiple frames it is possible
1314
+ // these buckets were processed before they were changed and so the
1315
+ // placement is already stale while it is in progress
1316
+ this.pauseablePlacement.placement.setStale();
1317
+ }
1318
+ }
1319
+
1320
+ if (placementCommitted || symbolBucketsChanged) {
1321
+ for (const layerID of this._order) {
1322
+ const styleLayer = this._layers[layerID];
1323
+ if (styleLayer.type !== 'symbol') continue;
1324
+ this.placement.updateLayerOpacities(styleLayer, layerTiles[styleLayer.source]);
1325
+ }
1326
+ }
1327
+
1328
+ // needsRender is false when we have just finished a placement that didn't change the visibility of any symbols
1329
+ const needsRerender = !this.pauseablePlacement.isDone() || this.placement.hasTransitions(browser.now());
1330
+ return needsRerender;
1331
+ }
1332
+
1333
+ _releaseSymbolFadeTiles() {
1334
+ for (const id in this.sourceCaches) {
1335
+ this.sourceCaches[id].releaseSymbolFadeTiles();
1336
+ }
1337
+ }
1338
+
1339
+ // Callbacks from web workers
1340
+
1341
+ getImages(mapId: string, params: {icons: Array<string>, source: string, tileID: OverscaledTileID, type: string}, callback: Callback<{[_: string]: StyleImage}>) {
1342
+
1343
+ this.imageManager.getImages(params.icons, callback);
1344
+
1345
+ // Apply queued image changes before setting the tile's dependencies so that the tile
1346
+ // is not reloaded unecessarily. Without this forced update the reload could happen in cases
1347
+ // like this one:
1348
+ // - icons contains "my-image"
1349
+ // - imageManager.getImages(...) triggers `onstyleimagemissing`
1350
+ // - the user adds "my-image" within the callback
1351
+ // - addImage adds "my-image" to this._changedImages
1352
+ // - the next frame triggers a reload of this tile even though it already has the latest version
1353
+ this._updateTilesForChangedImages();
1354
+
1355
+ const sourceCache = this.sourceCaches[params.source];
1356
+ if (sourceCache) {
1357
+ sourceCache.setDependencies(params.tileID.key, params.type, params.icons);
1358
+ }
1359
+ }
1360
+
1361
+ getGlyphs(mapId: string, params: {stacks: {[_: string]: Array<number>}}, callback: Callback<{[_: string]: {[_: number]: ?StyleGlyph}}>) {
1362
+ this.glyphManager.getGlyphs(params.stacks, callback);
1363
+ }
1364
+
1365
+ getResource(mapId: string, params: RequestParameters, callback: ResponseCallback<any>): Cancelable {
1366
+ return makeRequest(params, callback);
1367
+ }
1368
+ }
1369
+
1370
+ Style.getSourceType = getSourceType;
1371
+ Style.setSourceType = setSourceType;
1372
+ Style.registerForPluginStateChange = registerForPluginStateChange;
1373
+
1374
+ export default Style;