@mapwhit/tilerenderer 0.47.1
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.
- package/LICENSE.txt +87 -0
- package/README.md +25 -0
- package/build/min/.dir +0 -0
- package/build/min/package.json +3 -0
- package/build/min/src/shaders/_prelude.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/_prelude.vertex.glsl.txt +14 -0
- package/build/min/src/shaders/background.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/background.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/background_pattern.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/background_pattern.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/circle.fragment.glsl.txt +20 -0
- package/build/min/src/shaders/circle.vertex.glsl.txt +17 -0
- package/build/min/src/shaders/clipping_mask.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/clipping_mask.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/collision_box.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/collision_box.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/collision_circle.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/collision_circle.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/debug.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/debug.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/fill.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/fill.vertex.glsl.txt +7 -0
- package/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.txt +15 -0
- package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.txt +11 -0
- package/build/min/src/shaders/fill_outline.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/fill_outline.vertex.glsl.txt +7 -0
- package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/fill_pattern.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_pattern.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/heatmap.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/heatmap.vertex.glsl.txt +8 -0
- package/build/min/src/shaders/heatmap_texture.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/heatmap_texture.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/hillshade.fragment.glsl.txt +7 -0
- package/build/min/src/shaders/hillshade.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/hillshade_prepare.fragment.glsl.txt +8 -0
- package/build/min/src/shaders/hillshade_prepare.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/line.fragment.glsl.txt +12 -0
- package/build/min/src/shaders/line.vertex.glsl.txt +17 -0
- package/build/min/src/shaders/line_gradient.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/line_gradient.vertex.glsl.txt +16 -0
- package/build/min/src/shaders/line_pattern.fragment.glsl.txt +15 -0
- package/build/min/src/shaders/line_pattern.vertex.glsl.txt +20 -0
- package/build/min/src/shaders/line_sdf.fragment.glsl.txt +17 -0
- package/build/min/src/shaders/line_sdf.vertex.glsl.txt +20 -0
- package/build/min/src/shaders/raster.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/raster.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/symbol_icon.fragment.glsl.txt +9 -0
- package/build/min/src/shaders/symbol_icon.vertex.glsl.txt +5 -0
- package/build/min/src/shaders/symbol_sdf.fragment.glsl.txt +19 -0
- package/build/min/src/shaders/symbol_sdf.vertex.glsl.txt +13 -0
- package/package.json +44 -0
- package/src/css/mapbox-gl.css +506 -0
- package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
- package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-geolocate-background.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-geolocate.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-logo-compact.svg +2 -0
- package/src/css/svg/mapboxgl-ctrl-logo.svg +1 -0
- package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
- package/src/data/array_types.js +1138 -0
- package/src/data/bucket/circle_attributes.js +5 -0
- package/src/data/bucket/circle_bucket.js +118 -0
- package/src/data/bucket/fill_attributes.js +5 -0
- package/src/data/bucket/fill_bucket.js +166 -0
- package/src/data/bucket/fill_extrusion_attributes.js +11 -0
- package/src/data/bucket/fill_extrusion_bucket.js +247 -0
- package/src/data/bucket/heatmap_bucket.js +12 -0
- package/src/data/bucket/line_attributes.js +11 -0
- package/src/data/bucket/line_bucket.js +625 -0
- package/src/data/bucket/pattern_attributes.js +9 -0
- package/src/data/bucket/pattern_bucket_features.js +44 -0
- package/src/data/bucket/symbol_attributes.js +95 -0
- package/src/data/bucket/symbol_bucket.js +697 -0
- package/src/data/bucket.js +53 -0
- package/src/data/dem_data.js +126 -0
- package/src/data/extent.js +17 -0
- package/src/data/feature_index.js +254 -0
- package/src/data/index_array_type.js +14 -0
- package/src/data/load_geometry.js +42 -0
- package/src/data/pos_attributes.js +3 -0
- package/src/data/program_configuration.js +782 -0
- package/src/data/raster_bounds_attributes.js +6 -0
- package/src/data/segment.js +63 -0
- package/src/geo/coordinate.js +78 -0
- package/src/geo/lng_lat.js +129 -0
- package/src/geo/lng_lat_bounds.js +253 -0
- package/src/geo/transform.js +605 -0
- package/src/gl/color_mode.js +21 -0
- package/src/gl/context.js +193 -0
- package/src/gl/cull_face_mode.js +22 -0
- package/src/gl/depth_mode.js +18 -0
- package/src/gl/framebuffer.js +28 -0
- package/src/gl/index_buffer.js +52 -0
- package/src/gl/stencil_mode.js +17 -0
- package/src/gl/types.js +0 -0
- package/src/gl/value.js +676 -0
- package/src/gl/vertex_buffer.js +101 -0
- package/src/index.js +50 -0
- package/src/render/draw_background.js +60 -0
- package/src/render/draw_circle.js +55 -0
- package/src/render/draw_collision_debug.js +45 -0
- package/src/render/draw_debug.js +429 -0
- package/src/render/draw_fill.js +143 -0
- package/src/render/draw_fill_extrusion.js +101 -0
- package/src/render/draw_heatmap.js +159 -0
- package/src/render/draw_hillshade.js +144 -0
- package/src/render/draw_line.js +99 -0
- package/src/render/draw_raster.js +151 -0
- package/src/render/draw_symbol.js +231 -0
- package/src/render/glyph_atlas.js +55 -0
- package/src/render/glyph_manager.js +145 -0
- package/src/render/image_atlas.js +97 -0
- package/src/render/image_manager.js +183 -0
- package/src/render/line_atlas.js +139 -0
- package/src/render/painter.js +483 -0
- package/src/render/program/background_program.js +46 -0
- package/src/render/program/circle_program.js +40 -0
- package/src/render/program/clipping_mask_program.js +11 -0
- package/src/render/program/collision_program.js +28 -0
- package/src/render/program/debug_program.js +13 -0
- package/src/render/program/fill_extrusion_program.js +76 -0
- package/src/render/program/fill_program.js +60 -0
- package/src/render/program/heatmap_program.js +46 -0
- package/src/render/program/hillshade_program.js +77 -0
- package/src/render/program/line_program.js +119 -0
- package/src/render/program/pattern.js +57 -0
- package/src/render/program/program_uniforms.js +46 -0
- package/src/render/program/raster_program.js +50 -0
- package/src/render/program/symbol_program.js +112 -0
- package/src/render/program.js +133 -0
- package/src/render/texture.js +88 -0
- package/src/render/tile_mask.js +108 -0
- package/src/render/uniform_binding.js +129 -0
- package/src/render/vertex_array_object.js +155 -0
- package/src/shaders/README.md +42 -0
- package/src/shaders/_prelude.fragment.glsl +17 -0
- package/src/shaders/_prelude.vertex.glsl +73 -0
- package/src/shaders/background.fragment.glsl +10 -0
- package/src/shaders/background.vertex.glsl +7 -0
- package/src/shaders/background_pattern.fragment.glsl +28 -0
- package/src/shaders/background_pattern.vertex.glsl +20 -0
- package/src/shaders/circle.fragment.glsl +39 -0
- package/src/shaders/circle.vertex.glsl +63 -0
- package/src/shaders/clipping_mask.fragment.glsl +3 -0
- package/src/shaders/clipping_mask.vertex.glsl +7 -0
- package/src/shaders/collision_box.fragment.glsl +21 -0
- package/src/shaders/collision_box.vertex.glsl +26 -0
- package/src/shaders/collision_circle.fragment.glsl +34 -0
- package/src/shaders/collision_circle.vertex.glsl +36 -0
- package/src/shaders/debug.fragment.glsl +5 -0
- package/src/shaders/debug.vertex.glsl +7 -0
- package/src/shaders/encode_attribute.js +19 -0
- package/src/shaders/fill.fragment.glsl +13 -0
- package/src/shaders/fill.vertex.glsl +13 -0
- package/src/shaders/fill_extrusion.fragment.glsl +16 -0
- package/src/shaders/fill_extrusion.vertex.glsl +66 -0
- package/src/shaders/fill_extrusion_pattern.fragment.glsl +41 -0
- package/src/shaders/fill_extrusion_pattern.vertex.glsl +76 -0
- package/src/shaders/fill_outline.fragment.glsl +17 -0
- package/src/shaders/fill_outline.vertex.glsl +17 -0
- package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
- package/src/shaders/fill_outline_pattern.vertex.glsl +41 -0
- package/src/shaders/fill_pattern.fragment.glsl +36 -0
- package/src/shaders/fill_pattern.vertex.glsl +36 -0
- package/src/shaders/heatmap.fragment.glsl +21 -0
- package/src/shaders/heatmap.vertex.glsl +53 -0
- package/src/shaders/heatmap_texture.fragment.glsl +14 -0
- package/src/shaders/heatmap_texture.vertex.glsl +11 -0
- package/src/shaders/hillshade.fragment.glsl +52 -0
- package/src/shaders/hillshade.vertex.glsl +11 -0
- package/src/shaders/hillshade_prepare.fragment.glsl +72 -0
- package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
- package/src/shaders/index.js +194 -0
- package/src/shaders/line.fragment.glsl +28 -0
- package/src/shaders/line.vertex.glsl +84 -0
- package/src/shaders/line_gradient.fragment.glsl +34 -0
- package/src/shaders/line_gradient.vertex.glsl +84 -0
- package/src/shaders/line_pattern.fragment.glsl +69 -0
- package/src/shaders/line_pattern.vertex.glsl +88 -0
- package/src/shaders/line_sdf.fragment.glsl +44 -0
- package/src/shaders/line_sdf.vertex.glsl +95 -0
- package/src/shaders/raster.fragment.glsl +52 -0
- package/src/shaders/raster.vertex.glsl +21 -0
- package/src/shaders/symbol_icon.fragment.glsl +17 -0
- package/src/shaders/symbol_icon.vertex.glsl +91 -0
- package/src/shaders/symbol_sdf.fragment.glsl +50 -0
- package/src/shaders/symbol_sdf.vertex.glsl +117 -0
- package/src/source/geojson_source.js +267 -0
- package/src/source/geojson_worker_source.js +210 -0
- package/src/source/geojson_wrapper.js +67 -0
- package/src/source/image_source.js +213 -0
- package/src/source/load_tilejson.js +40 -0
- package/src/source/pixels_to_tile_units.js +17 -0
- package/src/source/query_features.js +198 -0
- package/src/source/raster_dem_tile_source.js +140 -0
- package/src/source/raster_dem_tile_worker_source.js +26 -0
- package/src/source/raster_tile_source.js +126 -0
- package/src/source/rtl_text_plugin.js +63 -0
- package/src/source/source.js +75 -0
- package/src/source/source_cache.js +794 -0
- package/src/source/source_state.js +55 -0
- package/src/source/tile.js +332 -0
- package/src/source/tile_bounds.js +40 -0
- package/src/source/tile_cache.js +122 -0
- package/src/source/tile_id.js +150 -0
- package/src/source/vector_tile_source.js +144 -0
- package/src/source/vector_tile_worker_source.js +126 -0
- package/src/source/worker.js +175 -0
- package/src/source/worker_source.js +14 -0
- package/src/source/worker_tile.js +199 -0
- package/src/style/create_style_layer.js +25 -0
- package/src/style/evaluation_parameters.js +45 -0
- package/src/style/light.js +112 -0
- package/src/style/load_glyph_range.js +17 -0
- package/src/style/load_sprite.js +26 -0
- package/src/style/parse_glyph_pbf.js +45 -0
- package/src/style/pauseable_placement.js +88 -0
- package/src/style/properties.js +691 -0
- package/src/style/query_utils.js +39 -0
- package/src/style/style.js +955 -0
- package/src/style/style_layer/background_style_layer.js +11 -0
- package/src/style/style_layer/background_style_layer_properties.js +25 -0
- package/src/style/style_layer/circle_style_layer.js +93 -0
- package/src/style/style_layer/circle_style_layer_properties.js +76 -0
- package/src/style/style_layer/fill_extrusion_style_layer.js +194 -0
- package/src/style/style_layer/fill_extrusion_style_layer_properties.js +56 -0
- package/src/style/style_layer/fill_style_layer.js +46 -0
- package/src/style/style_layer/fill_style_layer_properties.js +45 -0
- package/src/style/style_layer/heatmap_style_layer.js +51 -0
- package/src/style/style_layer/heatmap_style_layer_properties.js +52 -0
- package/src/style/style_layer/hillshade_style_layer.js +15 -0
- package/src/style/style_layer/hillshade_style_layer_properties.js +43 -0
- package/src/style/style_layer/line_style_layer.js +129 -0
- package/src/style/style_layer/line_style_layer_properties.js +104 -0
- package/src/style/style_layer/raster_style_layer.js +11 -0
- package/src/style/style_layer/raster_style_layer_properties.js +55 -0
- package/src/style/style_layer/symbol_style_layer.js +66 -0
- package/src/style/style_layer/symbol_style_layer_properties.js +288 -0
- package/src/style/style_layer.js +183 -0
- package/src/style/style_layer_index.js +61 -0
- package/src/style/zoom_history.js +36 -0
- package/src/style-spec/deref.js +51 -0
- package/src/style-spec/error/parsing_error.js +8 -0
- package/src/style-spec/error/validation_error.js +10 -0
- package/src/style-spec/expression/compound_expression.js +118 -0
- package/src/style-spec/expression/definitions/array.js +82 -0
- package/src/style-spec/expression/definitions/assertion.js +69 -0
- package/src/style-spec/expression/definitions/at.js +57 -0
- package/src/style-spec/expression/definitions/case.js +73 -0
- package/src/style-spec/expression/definitions/coalesce.js +68 -0
- package/src/style-spec/expression/definitions/coercion.js +96 -0
- package/src/style-spec/expression/definitions/collator.js +102 -0
- package/src/style-spec/expression/definitions/equals.js +93 -0
- package/src/style-spec/expression/definitions/index.js +407 -0
- package/src/style-spec/expression/definitions/interpolate.js +235 -0
- package/src/style-spec/expression/definitions/length.js +54 -0
- package/src/style-spec/expression/definitions/let.js +60 -0
- package/src/style-spec/expression/definitions/literal.js +64 -0
- package/src/style-spec/expression/definitions/match.js +142 -0
- package/src/style-spec/expression/definitions/step.js +116 -0
- package/src/style-spec/expression/definitions/var.js +38 -0
- package/src/style-spec/expression/evaluation_context.js +35 -0
- package/src/style-spec/expression/index.js +329 -0
- package/src/style-spec/expression/is_constant.js +63 -0
- package/src/style-spec/expression/parsing_context.js +213 -0
- package/src/style-spec/expression/parsing_error.js +9 -0
- package/src/style-spec/expression/runtime_error.js +12 -0
- package/src/style-spec/expression/scope.js +34 -0
- package/src/style-spec/expression/stops.js +37 -0
- package/src/style-spec/expression/types.js +77 -0
- package/src/style-spec/expression/values.js +126 -0
- package/src/style-spec/feature_filter/README.md +55 -0
- package/src/style-spec/feature_filter/index.js +158 -0
- package/src/style-spec/function/convert.js +256 -0
- package/src/style-spec/function/index.js +299 -0
- package/src/style-spec/group_by_layout.js +68 -0
- package/src/style-spec/reference/v8.json +5356 -0
- package/src/style-spec/util/color.js +73 -0
- package/src/style-spec/util/color_spaces.js +128 -0
- package/src/style-spec/util/eval_support.js +8 -0
- package/src/style-spec/util/get_type.js +18 -0
- package/src/style-spec/util/interpolate.js +21 -0
- package/src/style-spec/util/properties.js +17 -0
- package/src/style-spec/util/ref_properties.js +1 -0
- package/src/style-spec/util/result.js +19 -0
- package/src/symbol/anchor.js +21 -0
- package/src/symbol/check_max_angle.js +75 -0
- package/src/symbol/clip_line.js +73 -0
- package/src/symbol/collision_feature.js +230 -0
- package/src/symbol/collision_index.js +379 -0
- package/src/symbol/cross_tile_symbol_index.js +270 -0
- package/src/symbol/get_anchors.js +177 -0
- package/src/symbol/grid_index.js +318 -0
- package/src/symbol/mergelines.js +75 -0
- package/src/symbol/opacity_state.js +21 -0
- package/src/symbol/placement.js +563 -0
- package/src/symbol/projection.js +601 -0
- package/src/symbol/quads.js +173 -0
- package/src/symbol/shaping.js +347 -0
- package/src/symbol/symbol_layout.js +519 -0
- package/src/symbol/symbol_size.js +110 -0
- package/src/symbol/transform_text.js +16 -0
- package/src/ui/anchor.js +24 -0
- package/src/ui/bind_handlers.js +199 -0
- package/src/ui/camera.js +954 -0
- package/src/ui/events.js +210 -0
- package/src/ui/handler/box_zoom.js +151 -0
- package/src/ui/handler/dblclick_zoom.js +91 -0
- package/src/ui/handler/drag_pan.js +285 -0
- package/src/ui/handler/drag_rotate.js +290 -0
- package/src/ui/handler/frame.js +28 -0
- package/src/ui/handler/inertia.js +45 -0
- package/src/ui/handler/keyboard.js +148 -0
- package/src/ui/handler/scroll_zoom.js +284 -0
- package/src/ui/handler/touch_zoom_rotate.js +263 -0
- package/src/ui/map.js +1645 -0
- package/src/util/actor.js +104 -0
- package/src/util/async.js +23 -0
- package/src/util/browser.js +61 -0
- package/src/util/callback.js +26 -0
- package/src/util/classify_rings.js +43 -0
- package/src/util/color_ramp.js +24 -0
- package/src/util/config.js +24 -0
- package/src/util/dictionary_coder.js +25 -0
- package/src/util/dispatcher.js +68 -0
- package/src/util/dom.js +102 -0
- package/src/util/evented.js +182 -0
- package/src/util/find_pole_of_inaccessibility.js +129 -0
- package/src/util/global_worker_pool.js +15 -0
- package/src/util/image.js +124 -0
- package/src/util/interpolate.js +5 -0
- package/src/util/intersection_tests.js +207 -0
- package/src/util/is_char_in_unicode_block.js +287 -0
- package/src/util/loader/image.js +32 -0
- package/src/util/object.js +178 -0
- package/src/util/script_detection.js +337 -0
- package/src/util/struct_array.js +197 -0
- package/src/util/task_queue.js +57 -0
- package/src/util/throttle.js +26 -0
- package/src/util/tile_cover.js +114 -0
- package/src/util/token.js +13 -0
- package/src/util/unique_id.js +12 -0
- package/src/util/util.js +192 -0
- package/src/util/vectortile_to_geojson.js +44 -0
- package/src/util/verticalize_punctuation.js +112 -0
- package/src/util/warn.js +21 -0
- package/src/util/web_worker.js +5 -0
- package/src/util/web_worker_transfer.js +228 -0
- package/src/util/worker_pool.js +41 -0
package/src/ui/map.js
ADDED
|
@@ -0,0 +1,1645 @@
|
|
|
1
|
+
const { bindAll } = require('../util/object');
|
|
2
|
+
const warn = require('../util/warn');
|
|
3
|
+
|
|
4
|
+
const browser = require('../util/browser');
|
|
5
|
+
const DOM = require('../util/dom');
|
|
6
|
+
const loadImage = require('../util/loader/image');
|
|
7
|
+
|
|
8
|
+
const Style = require('../style/style');
|
|
9
|
+
const EvaluationParameters = require('../style/evaluation_parameters');
|
|
10
|
+
const Painter = require('../render/painter');
|
|
11
|
+
const Transform = require('../geo/transform');
|
|
12
|
+
const bindHandlers = require('./bind_handlers');
|
|
13
|
+
const Camera = require('./camera');
|
|
14
|
+
const LngLat = require('../geo/lng_lat');
|
|
15
|
+
const LngLatBounds = require('../geo/lng_lat_bounds');
|
|
16
|
+
const Point = require('@mapbox/point-geometry');
|
|
17
|
+
const { RGBAImage } = require('../util/image');
|
|
18
|
+
const { Event, ErrorEvent } = require('../util/evented');
|
|
19
|
+
const TaskQueue = require('../util/task_queue');
|
|
20
|
+
|
|
21
|
+
const defaultMinZoom = 0;
|
|
22
|
+
const defaultMaxZoom = 22;
|
|
23
|
+
const defaultOptions = {
|
|
24
|
+
center: [0, 0],
|
|
25
|
+
zoom: 0,
|
|
26
|
+
bearing: 0,
|
|
27
|
+
pitch: 0,
|
|
28
|
+
|
|
29
|
+
minZoom: defaultMinZoom,
|
|
30
|
+
maxZoom: defaultMaxZoom,
|
|
31
|
+
|
|
32
|
+
interactive: true,
|
|
33
|
+
|
|
34
|
+
scrollZoom: true,
|
|
35
|
+
boxZoom: true,
|
|
36
|
+
dragRotate: true,
|
|
37
|
+
dragPan: true,
|
|
38
|
+
keyboard: true,
|
|
39
|
+
doubleClickZoom: true,
|
|
40
|
+
touchZoomRotate: true,
|
|
41
|
+
|
|
42
|
+
bearingSnap: 7,
|
|
43
|
+
|
|
44
|
+
clickTolerance: 3,
|
|
45
|
+
|
|
46
|
+
attributionControl: true,
|
|
47
|
+
|
|
48
|
+
failIfMajorPerformanceCaveat: false,
|
|
49
|
+
preserveDrawingBuffer: false,
|
|
50
|
+
|
|
51
|
+
trackResize: true,
|
|
52
|
+
|
|
53
|
+
renderWorldCopies: true,
|
|
54
|
+
|
|
55
|
+
refreshExpiredTiles: true,
|
|
56
|
+
|
|
57
|
+
maxTileCacheSize: null,
|
|
58
|
+
|
|
59
|
+
transformRequest: null,
|
|
60
|
+
fadeDuration: 300,
|
|
61
|
+
crossSourceCollisions: true
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The `Map` object represents the map on your page. It exposes methods
|
|
66
|
+
* and properties that enable you to programmatically change the map,
|
|
67
|
+
* and fires events as users interact with it.
|
|
68
|
+
*
|
|
69
|
+
* You create a `Map` by specifying a `container` and other options.
|
|
70
|
+
* Then Mapbox GL JS initializes the map on the page and returns your `Map`
|
|
71
|
+
* object.
|
|
72
|
+
*
|
|
73
|
+
* @extends Evented
|
|
74
|
+
* @param {Object} options
|
|
75
|
+
* @param {HTMLElement|string} options.container The HTML element in which Mapbox GL JS will render the map, or the element's string `id`. The specified element must have no children.
|
|
76
|
+
* @param {number} [options.minZoom=0] The minimum zoom level of the map (0-24).
|
|
77
|
+
* @param {number} [options.maxZoom=22] The maximum zoom level of the map (0-24).
|
|
78
|
+
* @param {Object|string} [options.style] The map's Mapbox style. This must be an a JSON object conforming to
|
|
79
|
+
* the schema described in the [Mapbox Style Specification](https://mapbox.com/mapbox-gl-style-spec/), or a URL to
|
|
80
|
+
* such JSON.
|
|
81
|
+
*
|
|
82
|
+
* To load a style from the Mapbox API, you can use a URL of the form `mapbox://styles/:owner/:style`,
|
|
83
|
+
* where `:owner` is your Mapbox account name and `:style` is the style ID. Or you can use one of the following
|
|
84
|
+
* [the predefined Mapbox styles](https://www.mapbox.com/maps/):
|
|
85
|
+
*
|
|
86
|
+
* * `mapbox://styles/mapbox/streets-v9`
|
|
87
|
+
* * `mapbox://styles/mapbox/outdoors-v9`
|
|
88
|
+
* * `mapbox://styles/mapbox/light-v9`
|
|
89
|
+
* * `mapbox://styles/mapbox/dark-v9`
|
|
90
|
+
* * `mapbox://styles/mapbox/satellite-v9`
|
|
91
|
+
* * `mapbox://styles/mapbox/satellite-streets-v9`
|
|
92
|
+
*
|
|
93
|
+
* Tilesets hosted with Mapbox can be style-optimized if you append `?optimize=true` to the end of your style URL, like `mapbox://styles/mapbox/streets-v9?optimize=true`.
|
|
94
|
+
* Learn more about style-optimized vector tiles in our [API documentation](https://www.mapbox.com/api-documentation/#retrieve-tiles).
|
|
95
|
+
*
|
|
96
|
+
* @param {boolean} [options.interactive=true] If `false`, no mouse, touch, or keyboard listeners will be attached to the map, so it will not respond to interaction.
|
|
97
|
+
* @param {number} [options.bearingSnap=7] The threshold, measured in degrees, that determines when the map's
|
|
98
|
+
* bearing will snap to north. For example, with a `bearingSnap` of 7, if the user rotates
|
|
99
|
+
* the map within 7 degrees of north, the map will automatically snap to exact north.
|
|
100
|
+
* @param {boolean} [options.pitchWithRotate=true] If `false`, the map's pitch (tilt) control with "drag to rotate" interaction will be disabled.
|
|
101
|
+
* @param {number} [options.clickTolerance=3] The max number of pixels a user can shift the mouse pointer during a click for it to be considered a valid click (as opposed to a mouse drag).
|
|
102
|
+
* @param {string} [options.logoPosition='bottom-left'] A string representing the position of the Mapbox wordmark on the map. Valid options are `top-left`,`top-right`, `bottom-left`, `bottom-right`.
|
|
103
|
+
* @param {boolean} [options.failIfMajorPerformanceCaveat=false] If `true`, map creation will fail if the performance of Mapbox
|
|
104
|
+
* GL JS would be dramatically worse than expected (i.e. a software renderer would be used).
|
|
105
|
+
* @param {boolean} [options.preserveDrawingBuffer=false] If `true`, the map's canvas can be exported to a PNG using `map.getCanvas().toDataURL()`. This is `false` by default as a performance optimization.
|
|
106
|
+
* @param {LngLatBoundsLike} [options.maxBounds] If set, the map will be constrained to the given bounds.
|
|
107
|
+
* @param {boolean|Object} [options.scrollZoom=true] If `true`, the "scroll to zoom" interaction is enabled. An `Object` value is passed as options to {@link ScrollZoomHandler#enable}.
|
|
108
|
+
* @param {boolean} [options.boxZoom=true] If `true`, the "box zoom" interaction is enabled (see {@link BoxZoomHandler}).
|
|
109
|
+
* @param {boolean} [options.dragRotate=true] If `true`, the "drag to rotate" interaction is enabled (see {@link DragRotateHandler}).
|
|
110
|
+
* @param {boolean} [options.dragPan=true] If `true`, the "drag to pan" interaction is enabled (see {@link DragPanHandler}).
|
|
111
|
+
* @param {boolean} [options.keyboard=true] If `true`, keyboard shortcuts are enabled (see {@link KeyboardHandler}).
|
|
112
|
+
* @param {boolean} [options.doubleClickZoom=true] If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}).
|
|
113
|
+
* @param {boolean|Object} [options.touchZoomRotate=true] If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}.
|
|
114
|
+
* @param {boolean} [options.trackResize=true] If `true`, the map will automatically resize when the browser window resizes.
|
|
115
|
+
* @param {LngLatLike} [options.center=[0, 0]] The inital geographical centerpoint of the map. If `center` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON.
|
|
116
|
+
* @param {number} [options.zoom=0] The initial zoom level of the map. If `zoom` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.
|
|
117
|
+
* @param {number} [options.bearing=0] The initial bearing (rotation) of the map, measured in degrees counter-clockwise from north. If `bearing` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.
|
|
118
|
+
* @param {number} [options.pitch=0] The initial pitch (tilt) of the map, measured in degrees away from the plane of the screen (0-60). If `pitch` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`.
|
|
119
|
+
* @param {boolean} [options.renderWorldCopies=true] If `true`, multiple copies of the world will be rendered, when zoomed out.
|
|
120
|
+
* @param {number} [options.maxTileCacheSize=null] The maximum number of tiles stored in the tile cache for a given source. If omitted, the cache will be dynamically sized based on the current viewport.
|
|
121
|
+
* @param {string} [options.localIdeographFontFamily=null] If specified, defines a CSS font-family
|
|
122
|
+
* for locally overriding generation of glyphs in the 'CJK Unified Ideographs' and 'Hangul Syllables' ranges.
|
|
123
|
+
* In these ranges, font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold).
|
|
124
|
+
* The purpose of this option is to avoid bandwidth-intensive glyph server requests. (see [Use locally generated ideographs](https://www.mapbox.com/mapbox-gl-js/example/local-ideographs))
|
|
125
|
+
* @param {number} [options.fadeDuration=300] Controls the duration of the fade-in/fade-out animation for label collisions, in milliseconds. This setting affects all symbol layers. This setting does not affect the duration of runtime styling transitions or raster tile cross-fading.
|
|
126
|
+
* @param {boolean} [options.crossSourceCollisions=true] If `true`, symbols from multiple sources can collide with each other during collision detection. If `false`, collision detection is run separately for the symbols in each source.
|
|
127
|
+
* @example
|
|
128
|
+
* var map = new mapboxgl.Map({
|
|
129
|
+
* container: 'map',
|
|
130
|
+
* center: [-122.420679, 37.772537],
|
|
131
|
+
* zoom: 13,
|
|
132
|
+
* style: style_object
|
|
133
|
+
* });
|
|
134
|
+
* @see [Display a map](https://www.mapbox.com/mapbox-gl-js/examples/)
|
|
135
|
+
*/
|
|
136
|
+
class Map extends Camera {
|
|
137
|
+
/**
|
|
138
|
+
* The map's {@link ScrollZoomHandler}, which implements zooming in and out with a scroll wheel or trackpad.
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The map's {@link BoxZoomHandler}, which implements zooming using a drag gesture with the Shift key pressed.
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The map's {@link DragRotateHandler}, which implements rotating the map while dragging with the right
|
|
147
|
+
* mouse button or with the Control key pressed.
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The map's {@link DragPanHandler}, which implements dragging the map with a mouse or touch gesture.
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The map's {@link KeyboardHandler}, which allows the user to zoom, rotate, and pan the map using keyboard
|
|
156
|
+
* shortcuts.
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The map's {@link DoubleClickZoomHandler}, which allows the user to zoom by double clicking.
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* The map's {@link TouchZoomRotateHandler}, which allows the user to zoom or rotate the map with touch gestures.
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
constructor(options) {
|
|
168
|
+
options = Object.assign({}, defaultOptions, options);
|
|
169
|
+
|
|
170
|
+
if (options.minZoom != null && options.maxZoom != null && options.minZoom > options.maxZoom) {
|
|
171
|
+
throw new Error('maxZoom must be greater than minZoom');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const transform = new Transform(options.minZoom, options.maxZoom, options.renderWorldCopies);
|
|
175
|
+
super(transform, options);
|
|
176
|
+
|
|
177
|
+
// use global loadImage implementation
|
|
178
|
+
this.loadImage = loadImage;
|
|
179
|
+
|
|
180
|
+
this._interactive = options.interactive;
|
|
181
|
+
this._maxTileCacheSize = options.maxTileCacheSize;
|
|
182
|
+
this._failIfMajorPerformanceCaveat = options.failIfMajorPerformanceCaveat;
|
|
183
|
+
this._preserveDrawingBuffer = options.preserveDrawingBuffer;
|
|
184
|
+
this._trackResize = options.trackResize;
|
|
185
|
+
this._bearingSnap = options.bearingSnap;
|
|
186
|
+
this._fadeDuration = options.fadeDuration;
|
|
187
|
+
this._crossSourceCollisions = options.crossSourceCollisions;
|
|
188
|
+
this._crossFadingFactor = 1;
|
|
189
|
+
this._renderTaskQueue = new TaskQueue();
|
|
190
|
+
|
|
191
|
+
if (typeof options.container === 'string') {
|
|
192
|
+
const container = window.document.getElementById(options.container);
|
|
193
|
+
if (!container) {
|
|
194
|
+
throw new Error(`Container '${options.container}' not found.`);
|
|
195
|
+
}
|
|
196
|
+
this._container = container;
|
|
197
|
+
} else if (options.container instanceof window.HTMLElement) {
|
|
198
|
+
this._container = options.container;
|
|
199
|
+
} else {
|
|
200
|
+
throw new Error(`Invalid type: 'container' must be a String or HTMLElement.`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (options.maxBounds) {
|
|
204
|
+
this.setMaxBounds(options.maxBounds);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
bindAll(
|
|
208
|
+
[
|
|
209
|
+
'_onWindowOnline',
|
|
210
|
+
'_onWindowResize',
|
|
211
|
+
'_contextLost',
|
|
212
|
+
'_contextRestored',
|
|
213
|
+
'_update',
|
|
214
|
+
'_render',
|
|
215
|
+
'_onData',
|
|
216
|
+
'_onDataLoading'
|
|
217
|
+
],
|
|
218
|
+
this
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
this._setupContainer();
|
|
222
|
+
this._setupPainter();
|
|
223
|
+
|
|
224
|
+
this.on('move', this._update.bind(this, false));
|
|
225
|
+
this.on('moveend', this._update.bind(this, false));
|
|
226
|
+
this.on('zoom', this._update.bind(this, true));
|
|
227
|
+
|
|
228
|
+
if (typeof window !== 'undefined') {
|
|
229
|
+
window.addEventListener('online', this._onWindowOnline, false);
|
|
230
|
+
window.addEventListener('resize', this._onWindowResize, false);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
bindHandlers(this, options);
|
|
234
|
+
|
|
235
|
+
this.jumpTo({
|
|
236
|
+
center: options.center,
|
|
237
|
+
zoom: options.zoom,
|
|
238
|
+
bearing: options.bearing,
|
|
239
|
+
pitch: options.pitch
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
this.resize();
|
|
243
|
+
|
|
244
|
+
if (options.style) this.setStyle(options.style, { localIdeographFontFamily: options.localIdeographFontFamily });
|
|
245
|
+
|
|
246
|
+
this.on('style.load', function () {
|
|
247
|
+
if (this.transform.unmodified) {
|
|
248
|
+
this.jumpTo(this.style.stylesheet);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
this.on('data', this._onData);
|
|
253
|
+
this.on('dataloading', this._onDataLoading);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Adds a {@link IControl} to the map, calling `control.onAdd(this)`.
|
|
258
|
+
*
|
|
259
|
+
* @param {IControl} control The {@link IControl} to add.
|
|
260
|
+
* @param {string} [position] position on the map to which the control will be added.
|
|
261
|
+
* Valid values are `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. Defaults to `'top-right'`.
|
|
262
|
+
* @returns {Map} `this`
|
|
263
|
+
* @see [Display map navigation controls](https://www.mapbox.com/mapbox-gl-js/example/navigation/)
|
|
264
|
+
*/
|
|
265
|
+
addControl(control, position) {
|
|
266
|
+
if (position === undefined && control.getDefaultPosition) {
|
|
267
|
+
position = control.getDefaultPosition();
|
|
268
|
+
}
|
|
269
|
+
if (position === undefined) {
|
|
270
|
+
position = 'top-right';
|
|
271
|
+
}
|
|
272
|
+
const controlElement = control.onAdd(this);
|
|
273
|
+
const positionContainer = this._controlPositions[position];
|
|
274
|
+
if (position.indexOf('bottom') !== -1) {
|
|
275
|
+
positionContainer.insertBefore(controlElement, positionContainer.firstChild);
|
|
276
|
+
} else {
|
|
277
|
+
positionContainer.appendChild(controlElement);
|
|
278
|
+
}
|
|
279
|
+
return this;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Removes the control from the map.
|
|
284
|
+
*
|
|
285
|
+
* @param {IControl} control The {@link IControl} to remove.
|
|
286
|
+
* @returns {Map} `this`
|
|
287
|
+
*/
|
|
288
|
+
removeControl(control) {
|
|
289
|
+
control.onRemove(this);
|
|
290
|
+
return this;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Resizes the map according to the dimensions of its
|
|
295
|
+
* `container` element.
|
|
296
|
+
*
|
|
297
|
+
* This method must be called after the map's `container` is resized by another script,
|
|
298
|
+
* or when the map is shown after being initially hidden with CSS.
|
|
299
|
+
*
|
|
300
|
+
* @param eventData Additional properties to be added to event objects of events triggered by this method.
|
|
301
|
+
* @returns {Map} `this`
|
|
302
|
+
*/
|
|
303
|
+
resize(eventData) {
|
|
304
|
+
const dimensions = this._containerDimensions();
|
|
305
|
+
const width = dimensions[0];
|
|
306
|
+
const height = dimensions[1];
|
|
307
|
+
|
|
308
|
+
this._resizeCanvas(width, height);
|
|
309
|
+
this.transform.resize(width, height);
|
|
310
|
+
this.painter.resize(width, height);
|
|
311
|
+
|
|
312
|
+
return this.fire(new Event('movestart', eventData))
|
|
313
|
+
.fire(new Event('move', eventData))
|
|
314
|
+
.fire(new Event('resize', eventData))
|
|
315
|
+
.fire(new Event('moveend', eventData));
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Returns the map's geographical bounds.
|
|
320
|
+
*
|
|
321
|
+
* @returns {LngLatBounds} The map's geographical bounds.
|
|
322
|
+
*/
|
|
323
|
+
getBounds() {
|
|
324
|
+
const bounds = new LngLatBounds(
|
|
325
|
+
this.transform.pointLocation(new Point(0, this.transform.height)),
|
|
326
|
+
this.transform.pointLocation(new Point(this.transform.width, 0))
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
if (this.transform.angle || this.transform.pitch) {
|
|
330
|
+
bounds.extend(this.transform.pointLocation(new Point(this.transform.size.x, 0)));
|
|
331
|
+
bounds.extend(this.transform.pointLocation(new Point(0, this.transform.size.y)));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return bounds;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Gets the map's geographical bounds.
|
|
339
|
+
*
|
|
340
|
+
* Returns the LngLatBounds by which pan and zoom operations on the map are constrained.
|
|
341
|
+
*
|
|
342
|
+
* @returns {LngLatBounds | null} The maximum bounds the map is constrained to, or `null` if none set.
|
|
343
|
+
*/
|
|
344
|
+
getMaxBounds() {
|
|
345
|
+
if (
|
|
346
|
+
this.transform.latRange &&
|
|
347
|
+
this.transform.latRange.length === 2 &&
|
|
348
|
+
this.transform.lngRange &&
|
|
349
|
+
this.transform.lngRange.length === 2
|
|
350
|
+
) {
|
|
351
|
+
return new LngLatBounds(
|
|
352
|
+
[this.transform.lngRange[0], this.transform.latRange[0]],
|
|
353
|
+
[this.transform.lngRange[1], this.transform.latRange[1]]
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Sets or clears the map's geographical bounds.
|
|
361
|
+
*
|
|
362
|
+
* Pan and zoom operations are constrained within these bounds.
|
|
363
|
+
* If a pan or zoom is performed that would
|
|
364
|
+
* display regions outside these bounds, the map will
|
|
365
|
+
* instead display a position and zoom level
|
|
366
|
+
* as close as possible to the operation's request while still
|
|
367
|
+
* remaining within the bounds.
|
|
368
|
+
*
|
|
369
|
+
* @param {LngLatBoundsLike | null | undefined} lnglatbounds The maximum bounds to set. If `null` or `undefined` is provided, the function removes the map's maximum bounds.
|
|
370
|
+
* @returns {Map} `this`
|
|
371
|
+
*/
|
|
372
|
+
setMaxBounds(lnglatbounds) {
|
|
373
|
+
if (lnglatbounds) {
|
|
374
|
+
const b = LngLatBounds.convert(lnglatbounds);
|
|
375
|
+
this.transform.lngRange = [b.getWest(), b.getEast()];
|
|
376
|
+
this.transform.latRange = [b.getSouth(), b.getNorth()];
|
|
377
|
+
this.transform._constrain();
|
|
378
|
+
this._update();
|
|
379
|
+
} else if (lnglatbounds === null || lnglatbounds === undefined) {
|
|
380
|
+
this.transform.lngRange = null;
|
|
381
|
+
this.transform.latRange = null;
|
|
382
|
+
this._update();
|
|
383
|
+
}
|
|
384
|
+
return this;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Sets or clears the map's minimum zoom level.
|
|
389
|
+
* If the map's current zoom level is lower than the new minimum,
|
|
390
|
+
* the map will zoom to the new minimum.
|
|
391
|
+
*
|
|
392
|
+
* @param {number | null | undefined} minZoom The minimum zoom level to set (0-24).
|
|
393
|
+
* If `null` or `undefined` is provided, the function removes the current minimum zoom (i.e. sets it to 0).
|
|
394
|
+
* @returns {Map} `this`
|
|
395
|
+
*/
|
|
396
|
+
setMinZoom(minZoom) {
|
|
397
|
+
minZoom = minZoom === null || minZoom === undefined ? defaultMinZoom : minZoom;
|
|
398
|
+
|
|
399
|
+
if (minZoom >= defaultMinZoom && minZoom <= this.transform.maxZoom) {
|
|
400
|
+
this.transform.minZoom = minZoom;
|
|
401
|
+
this._update();
|
|
402
|
+
|
|
403
|
+
if (this.getZoom() < minZoom) this.setZoom(minZoom);
|
|
404
|
+
|
|
405
|
+
return this;
|
|
406
|
+
}
|
|
407
|
+
throw new Error(`minZoom must be between ${defaultMinZoom} and the current maxZoom, inclusive`);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Returns the map's minimum allowable zoom level.
|
|
412
|
+
*
|
|
413
|
+
* @returns {number} minZoom
|
|
414
|
+
*/
|
|
415
|
+
getMinZoom() {
|
|
416
|
+
return this.transform.minZoom;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Sets or clears the map's maximum zoom level.
|
|
421
|
+
* If the map's current zoom level is higher than the new maximum,
|
|
422
|
+
* the map will zoom to the new maximum.
|
|
423
|
+
*
|
|
424
|
+
* @param {number | null | undefined} maxZoom The maximum zoom level to set.
|
|
425
|
+
* If `null` or `undefined` is provided, the function removes the current maximum zoom (sets it to 22).
|
|
426
|
+
* @returns {Map} `this`
|
|
427
|
+
*/
|
|
428
|
+
setMaxZoom(maxZoom) {
|
|
429
|
+
maxZoom = maxZoom === null || maxZoom === undefined ? defaultMaxZoom : maxZoom;
|
|
430
|
+
|
|
431
|
+
if (maxZoom >= this.transform.minZoom) {
|
|
432
|
+
this.transform.maxZoom = maxZoom;
|
|
433
|
+
this._update();
|
|
434
|
+
|
|
435
|
+
if (this.getZoom() > maxZoom) this.setZoom(maxZoom);
|
|
436
|
+
|
|
437
|
+
return this;
|
|
438
|
+
}
|
|
439
|
+
throw new Error('maxZoom must be greater than the current minZoom');
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Returns the state of renderWorldCopies.
|
|
444
|
+
*
|
|
445
|
+
* @returns {boolean} renderWorldCopies
|
|
446
|
+
*/
|
|
447
|
+
getRenderWorldCopies() {
|
|
448
|
+
return this.transform.renderWorldCopies;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Sets the state of renderWorldCopies.
|
|
453
|
+
*
|
|
454
|
+
* @param {boolean} renderWorldCopies If `true`, multiple copies of the world will be rendered, when zoomed out. `undefined` is treated as `true`, `null` is treated as `false`.
|
|
455
|
+
* @returns {Map} `this`
|
|
456
|
+
*/
|
|
457
|
+
setRenderWorldCopies(renderWorldCopies) {
|
|
458
|
+
this.transform.renderWorldCopies = renderWorldCopies;
|
|
459
|
+
this._update();
|
|
460
|
+
|
|
461
|
+
return this;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Returns the map's maximum allowable zoom level.
|
|
466
|
+
*
|
|
467
|
+
* @returns {number} maxZoom
|
|
468
|
+
*/
|
|
469
|
+
getMaxZoom() {
|
|
470
|
+
return this.transform.maxZoom;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Returns a {@link Point} representing pixel coordinates, relative to the map's `container`,
|
|
475
|
+
* that correspond to the specified geographical location.
|
|
476
|
+
*
|
|
477
|
+
* @param {LngLatLike} lnglat The geographical location to project.
|
|
478
|
+
* @returns {Point} The {@link Point} corresponding to `lnglat`, relative to the map's `container`.
|
|
479
|
+
*/
|
|
480
|
+
project(lnglat) {
|
|
481
|
+
return this.transform.locationPoint(LngLat.convert(lnglat));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Returns a {@link LngLat} representing geographical coordinates that correspond
|
|
486
|
+
* to the specified pixel coordinates.
|
|
487
|
+
*
|
|
488
|
+
* @param {PointLike} point The pixel coordinates to unproject.
|
|
489
|
+
* @returns {LngLat} The {@link LngLat} corresponding to `point`.
|
|
490
|
+
* @see [Show polygon information on click](https://www.mapbox.com/mapbox-gl-js/example/polygon-popup-on-click/)
|
|
491
|
+
*/
|
|
492
|
+
unproject(point) {
|
|
493
|
+
return this.transform.pointLocation(Point.convert(point));
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Returns true if the map is panning, zooming, rotating, or pitching due to a camera animation or user gesture.
|
|
498
|
+
*/
|
|
499
|
+
isMoving() {
|
|
500
|
+
return (
|
|
501
|
+
this._moving ||
|
|
502
|
+
this.dragPan.isActive() ||
|
|
503
|
+
this.dragRotate.isActive() ||
|
|
504
|
+
this.touchZoomRotate.isActive() ||
|
|
505
|
+
this.scrollZoom.isActive()
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Returns true if the map is zooming due to a camera animation or user gesture.
|
|
511
|
+
*/
|
|
512
|
+
isZooming() {
|
|
513
|
+
return this._zooming || this.touchZoomRotate.isActive() || this.scrollZoom.isZooming();
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Returns true if the map is rotating due to a camera animation or user gesture.
|
|
518
|
+
*/
|
|
519
|
+
isRotating() {
|
|
520
|
+
return this._rotating || this.touchZoomRotate.isActive() || this.dragRotate.isActive();
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Returns an array of [GeoJSON](http://geojson.org/)
|
|
525
|
+
* [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2)
|
|
526
|
+
* representing visible features that satisfy the query parameters.
|
|
527
|
+
*
|
|
528
|
+
* @param {PointLike|Array<PointLike>} [geometry] - The geometry of the query region:
|
|
529
|
+
* either a single point or southwest and northeast points describing a bounding box.
|
|
530
|
+
* Omitting this parameter (i.e. calling {@link Map#queryRenderedFeatures} with zero arguments,
|
|
531
|
+
* or with only a `options` argument) is equivalent to passing a bounding box encompassing the entire
|
|
532
|
+
* map viewport.
|
|
533
|
+
* @param {Object} [options]
|
|
534
|
+
* @param {Array<string>} [options.layers] An array of style layer IDs for the query to inspect.
|
|
535
|
+
* Only features within these layers will be returned. If this parameter is undefined, all layers will be checked.
|
|
536
|
+
* @param {Array} [options.filter] A [filter](https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter)
|
|
537
|
+
* to limit query results.
|
|
538
|
+
*
|
|
539
|
+
* @returns {Array<Object>} An array of [GeoJSON](http://geojson.org/)
|
|
540
|
+
* [feature objects](https://tools.ietf.org/html/rfc7946#section-3.2).
|
|
541
|
+
*
|
|
542
|
+
* The `properties` value of each returned feature object contains the properties of its source feature. For GeoJSON sources, only
|
|
543
|
+
* string and numeric property values are supported (i.e. `null`, `Array`, and `Object` values are not supported).
|
|
544
|
+
*
|
|
545
|
+
* Each feature includes top-level `layer`, `source`, and `sourceLayer` properties. The `layer` property is an object
|
|
546
|
+
* representing the style layer to which the feature belongs. Layout and paint properties in this object contain values
|
|
547
|
+
* which are fully evaluated for the given zoom level and feature.
|
|
548
|
+
*
|
|
549
|
+
* Features from layers whose `visibility` property is `"none"`, or from layers whose zoom range excludes the
|
|
550
|
+
* current zoom level are not included. Symbol features that have been hidden due to text or icon collision are
|
|
551
|
+
* not included. Features from all other layers are included, including features that may have no visible
|
|
552
|
+
* contribution to the rendered result; for example, because the layer's opacity or color alpha component is set to
|
|
553
|
+
* 0.
|
|
554
|
+
*
|
|
555
|
+
* The topmost rendered feature appears first in the returned array, and subsequent features are sorted by
|
|
556
|
+
* descending z-order. Features that are rendered multiple times (due to wrapping across the antimeridian at low
|
|
557
|
+
* zoom levels) are returned only once (though subject to the following caveat).
|
|
558
|
+
*
|
|
559
|
+
* Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature
|
|
560
|
+
* geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple
|
|
561
|
+
* times in query results. For example, suppose there is a highway running through the bounding rectangle of a query.
|
|
562
|
+
* The results of the query will be those parts of the highway that lie within the map tiles covering the bounding
|
|
563
|
+
* rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile
|
|
564
|
+
* will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple
|
|
565
|
+
* tiles due to tile buffering.
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* // Find all features at a point
|
|
569
|
+
* var features = map.queryRenderedFeatures(
|
|
570
|
+
* [20, 35],
|
|
571
|
+
* { layers: ['my-layer-name'] }
|
|
572
|
+
* );
|
|
573
|
+
*
|
|
574
|
+
* @example
|
|
575
|
+
* // Find all features within a static bounding box
|
|
576
|
+
* var features = map.queryRenderedFeatures(
|
|
577
|
+
* [[10, 20], [30, 50]],
|
|
578
|
+
* { layers: ['my-layer-name'] }
|
|
579
|
+
* );
|
|
580
|
+
*
|
|
581
|
+
* @example
|
|
582
|
+
* // Find all features within a bounding box around a point
|
|
583
|
+
* var width = 10;
|
|
584
|
+
* var height = 20;
|
|
585
|
+
* var features = map.queryRenderedFeatures([
|
|
586
|
+
* [point.x - width / 2, point.y - height / 2],
|
|
587
|
+
* [point.x + width / 2, point.y + height / 2]
|
|
588
|
+
* ], { layers: ['my-layer-name'] });
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* // Query all rendered features from a single layer
|
|
592
|
+
* var features = map.queryRenderedFeatures({ layers: ['my-layer-name'] });
|
|
593
|
+
* @see [Get features under the mouse pointer](https://www.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures/)
|
|
594
|
+
* @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
|
|
595
|
+
* @see [Center the map on a clicked symbol](https://www.mapbox.com/mapbox-gl-js/example/center-on-symbol/)
|
|
596
|
+
*/
|
|
597
|
+
queryRenderedFeatures(geometry, options) {
|
|
598
|
+
// The first parameter can be omitted entirely, making this effectively an overloaded method
|
|
599
|
+
// with two signatures:
|
|
600
|
+
//
|
|
601
|
+
// queryRenderedFeatures(geometry: PointLike | [PointLike, PointLike], options?: Object)
|
|
602
|
+
// queryRenderedFeatures(options?: Object)
|
|
603
|
+
//
|
|
604
|
+
// There no way to express that in a way that's compatible with both flow and documentation.js.
|
|
605
|
+
// Related: https://github.com/facebook/flow/issues/1556
|
|
606
|
+
if (arguments.length === 2) {
|
|
607
|
+
geometry = arguments[0];
|
|
608
|
+
options = arguments[1];
|
|
609
|
+
} else if (arguments.length === 1 && isPointLike(arguments[0])) {
|
|
610
|
+
geometry = arguments[0];
|
|
611
|
+
options = {};
|
|
612
|
+
} else if (arguments.length === 1) {
|
|
613
|
+
geometry = undefined;
|
|
614
|
+
options = arguments[0];
|
|
615
|
+
} else {
|
|
616
|
+
geometry = undefined;
|
|
617
|
+
options = {};
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
if (!this.style) {
|
|
621
|
+
return [];
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return this.style.queryRenderedFeatures(this._makeQueryGeometry(geometry), options, this.transform) || [];
|
|
625
|
+
|
|
626
|
+
function isPointLike(input) {
|
|
627
|
+
return input instanceof Point || Array.isArray(input);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
_makeQueryGeometry(pointOrBox) {
|
|
632
|
+
if (pointOrBox === undefined) {
|
|
633
|
+
// bounds was omitted: use full viewport
|
|
634
|
+
pointOrBox = [Point.convert([0, 0]), Point.convert([this.transform.width, this.transform.height])];
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
let queryGeometry;
|
|
638
|
+
|
|
639
|
+
if (pointOrBox instanceof Point || typeof pointOrBox[0] === 'number') {
|
|
640
|
+
const point = Point.convert(pointOrBox);
|
|
641
|
+
queryGeometry = [point];
|
|
642
|
+
} else {
|
|
643
|
+
const box = [Point.convert(pointOrBox[0]), Point.convert(pointOrBox[1])];
|
|
644
|
+
queryGeometry = [box[0], new Point(box[1].x, box[0].y), box[1], new Point(box[0].x, box[1].y), box[0]];
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
return {
|
|
648
|
+
viewport: queryGeometry,
|
|
649
|
+
worldCoordinate: queryGeometry.map(p => {
|
|
650
|
+
return this.transform.pointCoordinate(p);
|
|
651
|
+
})
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Returns an array of [GeoJSON](http://geojson.org/)
|
|
657
|
+
* [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2)
|
|
658
|
+
* representing features within the specified vector tile or GeoJSON source that satisfy the query parameters.
|
|
659
|
+
*
|
|
660
|
+
* @param {string} sourceID The ID of the vector tile or GeoJSON source to query.
|
|
661
|
+
* @param {Object} [parameters]
|
|
662
|
+
* @param {string} [parameters.sourceLayer] The name of the vector tile layer to query. *For vector tile
|
|
663
|
+
* sources, this parameter is required.* For GeoJSON sources, it is ignored.
|
|
664
|
+
* @param {Array} [parameters.filter] A [filter](https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter)
|
|
665
|
+
* to limit query results.
|
|
666
|
+
*
|
|
667
|
+
* @returns {Array<Object>} An array of [GeoJSON](http://geojson.org/)
|
|
668
|
+
* [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2).
|
|
669
|
+
*
|
|
670
|
+
* In contrast to {@link Map#queryRenderedFeatures}, this function
|
|
671
|
+
* returns all features matching the query parameters,
|
|
672
|
+
* whether or not they are rendered by the current style (i.e. visible). The domain of the query includes all currently-loaded
|
|
673
|
+
* vector tiles and GeoJSON source tiles: this function does not check tiles outside the currently
|
|
674
|
+
* visible viewport.
|
|
675
|
+
*
|
|
676
|
+
* Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature
|
|
677
|
+
* geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple
|
|
678
|
+
* times in query results. For example, suppose there is a highway running through the bounding rectangle of a query.
|
|
679
|
+
* The results of the query will be those parts of the highway that lie within the map tiles covering the bounding
|
|
680
|
+
* rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile
|
|
681
|
+
* will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple
|
|
682
|
+
* tiles due to tile buffering.
|
|
683
|
+
* @see [Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/)
|
|
684
|
+
* @see [Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/)
|
|
685
|
+
*/
|
|
686
|
+
querySourceFeatures(sourceID, parameters) {
|
|
687
|
+
return this.style.querySourceFeatures(sourceID, parameters);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Updates the map's Mapbox style object with a new value. If the given
|
|
692
|
+
* value is style JSON object, compares it against the the map's current
|
|
693
|
+
* state and perform only the changes necessary to make the map style match
|
|
694
|
+
* the desired state.
|
|
695
|
+
*
|
|
696
|
+
* @param style A JSON object conforming to the schema described in the
|
|
697
|
+
* [Mapbox Style Specification](https://mapbox.com/mapbox-gl-style-spec/), or a URL to such JSON.
|
|
698
|
+
* @param {Object} [options]
|
|
699
|
+
* @param {boolean} [options.diff=true] If false, force a 'full' update, removing the current style
|
|
700
|
+
* and adding building the given one instead of attempting a diff-based update.
|
|
701
|
+
* @param {string} [options.localIdeographFontFamily=null] If non-null, defines a css font-family
|
|
702
|
+
* for locally overriding generation of glyphs in the 'CJK Unified Ideographs' and 'Hangul Syllables'
|
|
703
|
+
* ranges. Forces a full update.
|
|
704
|
+
* @returns {Map} `this`
|
|
705
|
+
* @see [Change a map's style](https://www.mapbox.com/mapbox-gl-js/example/setstyle/)
|
|
706
|
+
*/
|
|
707
|
+
setStyle(style, options) {
|
|
708
|
+
if (this.style) {
|
|
709
|
+
this.style.setEventedParent(null);
|
|
710
|
+
this.style._remove();
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
if (!style) {
|
|
714
|
+
delete this.style;
|
|
715
|
+
return this;
|
|
716
|
+
}
|
|
717
|
+
this.style = new Style(this, options || {});
|
|
718
|
+
|
|
719
|
+
this.style.setEventedParent(this, { style: this.style });
|
|
720
|
+
|
|
721
|
+
// style is expected to be an object
|
|
722
|
+
this.style.loadJSON(style);
|
|
723
|
+
|
|
724
|
+
return this;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Returns the map's Mapbox style object, which can be used to recreate the map's style.
|
|
729
|
+
*
|
|
730
|
+
* @returns {Object} The map's style object.
|
|
731
|
+
*/
|
|
732
|
+
getStyle() {
|
|
733
|
+
if (this.style) {
|
|
734
|
+
return this.style.serialize();
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Returns a Boolean indicating whether the map's style is fully loaded.
|
|
740
|
+
*
|
|
741
|
+
* @returns {boolean} A Boolean indicating whether the style is fully loaded.
|
|
742
|
+
*/
|
|
743
|
+
isStyleLoaded() {
|
|
744
|
+
if (!this.style) return warn.once('There is no style added to the map.');
|
|
745
|
+
return this.style.loaded();
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Adds a source to the map's style.
|
|
750
|
+
*
|
|
751
|
+
* @param {string} id The ID of the source to add. Must not conflict with existing sources.
|
|
752
|
+
* @param {Object} source The source object, conforming to the
|
|
753
|
+
* Mapbox Style Specification's [source definition](https://www.mapbox.com/mapbox-gl-style-spec/#sources) or
|
|
754
|
+
* {@link CanvasSourceOptions}.
|
|
755
|
+
* @fires source.add
|
|
756
|
+
* @returns {Map} `this`
|
|
757
|
+
* @see [Draw GeoJSON points](https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/)
|
|
758
|
+
* @see [Style circles using data-driven styling](https://www.mapbox.com/mapbox-gl-js/example/data-driven-circle-colors/)
|
|
759
|
+
* @see [Set a point after Geocoder result](https://www.mapbox.com/mapbox-gl-js/example/point-from-geocoder-result/)
|
|
760
|
+
*/
|
|
761
|
+
addSource(id, source) {
|
|
762
|
+
this.style.addSource(id, source);
|
|
763
|
+
this._update(true);
|
|
764
|
+
return this;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Returns a Boolean indicating whether the source is loaded.
|
|
769
|
+
*
|
|
770
|
+
* @param {string} id The ID of the source to be checked.
|
|
771
|
+
* @returns {boolean} A Boolean indicating whether the source is loaded.
|
|
772
|
+
*/
|
|
773
|
+
isSourceLoaded(id) {
|
|
774
|
+
const source = this.style?.sourceCaches[id];
|
|
775
|
+
if (source === undefined) {
|
|
776
|
+
this.fire(new ErrorEvent(new Error(`There is no source with ID '${id}'`)));
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
return source.loaded();
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Returns a Boolean indicating whether all tiles in the viewport from all sources on
|
|
784
|
+
* the style are loaded.
|
|
785
|
+
*
|
|
786
|
+
* @returns {boolean} A Boolean indicating whether all tiles are loaded.
|
|
787
|
+
*/
|
|
788
|
+
|
|
789
|
+
areTilesLoaded() {
|
|
790
|
+
const sources = this.style?.sourceCaches;
|
|
791
|
+
for (const id in sources) {
|
|
792
|
+
const source = sources[id];
|
|
793
|
+
const tiles = source._tiles;
|
|
794
|
+
for (const t in tiles) {
|
|
795
|
+
const tile = tiles[t];
|
|
796
|
+
if (!(tile.state === 'loaded' || tile.state === 'errored')) return false;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
return true;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* Adds a [custom source type](#Custom Sources), making it available for use with
|
|
804
|
+
* {@link Map#addSource}.
|
|
805
|
+
* @private
|
|
806
|
+
* @param {string} name The name of the source type; source definition objects use this name in the `{type: ...}` field.
|
|
807
|
+
* @param {Function} SourceType A {@link Source} constructor.
|
|
808
|
+
* @param {Function} callback Called when the source type is ready or with an error argument if there is an error.
|
|
809
|
+
*/
|
|
810
|
+
addSourceType(name, SourceType, callback) {
|
|
811
|
+
return this.style.addSourceType(name, SourceType, callback);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Removes a source from the map's style.
|
|
816
|
+
*
|
|
817
|
+
* @param {string} id The ID of the source to remove.
|
|
818
|
+
* @returns {Map} `this`
|
|
819
|
+
*/
|
|
820
|
+
removeSource(id) {
|
|
821
|
+
this.style.removeSource(id);
|
|
822
|
+
this._update(true);
|
|
823
|
+
return this;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Returns the source with the specified ID in the map's style.
|
|
828
|
+
*
|
|
829
|
+
* @param {string} id The ID of the source to get.
|
|
830
|
+
* @returns {?Object} The style source with the specified ID, or `undefined`
|
|
831
|
+
* if the ID corresponds to no existing sources.
|
|
832
|
+
* @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/)
|
|
833
|
+
* @see [Animate a point](https://www.mapbox.com/mapbox-gl-js/example/animate-point-along-line/)
|
|
834
|
+
* @see [Add live realtime data](https://www.mapbox.com/mapbox-gl-js/example/live-geojson/)
|
|
835
|
+
*/
|
|
836
|
+
getSource(id) {
|
|
837
|
+
return this.style.getSource(id);
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Add an image to the style. This image can be used in `icon-image`,
|
|
842
|
+
* `background-pattern`, `fill-pattern`, and `line-pattern`. An
|
|
843
|
+
* {@link Map#error} event will be fired if there is not enough space in the
|
|
844
|
+
* sprite to add this image.
|
|
845
|
+
*
|
|
846
|
+
* @see [Add an icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image/)
|
|
847
|
+
* @see [Add a generated icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image-generated/)
|
|
848
|
+
* @param id The ID of the image.
|
|
849
|
+
* @param image The image as an `HTMLImageElement`, `ImageData`, or object with `width`, `height`, and `data`
|
|
850
|
+
* properties with the same format as `ImageData`.
|
|
851
|
+
* @param options
|
|
852
|
+
* @param options.pixelRatio The ratio of pixels in the image to physical pixels on the screen
|
|
853
|
+
* @param options.sdf Whether the image should be interpreted as an SDF image
|
|
854
|
+
*/
|
|
855
|
+
addImage(id, image, { pixelRatio = 1, sdf = false } = {}) {
|
|
856
|
+
if (image instanceof HTMLImageElement) {
|
|
857
|
+
const { width, height, data } = browser.getImageData(image);
|
|
858
|
+
this.style.addImage(id, { data: new RGBAImage({ width, height }, data), pixelRatio, sdf });
|
|
859
|
+
} else if (image.width === undefined || image.height === undefined) {
|
|
860
|
+
return this.fire(
|
|
861
|
+
new ErrorEvent(
|
|
862
|
+
new Error(
|
|
863
|
+
'Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, ' +
|
|
864
|
+
'or object with `width`, `height`, and `data` properties with the same format as `ImageData`'
|
|
865
|
+
)
|
|
866
|
+
)
|
|
867
|
+
);
|
|
868
|
+
} else {
|
|
869
|
+
const { width, height, data } = image;
|
|
870
|
+
this.style.addImage(id, { data: new RGBAImage({ width, height }, new Uint8Array(data)), pixelRatio, sdf });
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Define wether the image has been added or not
|
|
876
|
+
*
|
|
877
|
+
* @param id The ID of the image.
|
|
878
|
+
*/
|
|
879
|
+
hasImage(id) {
|
|
880
|
+
if (!id) {
|
|
881
|
+
this.fire(new ErrorEvent(new Error('Missing required image id')));
|
|
882
|
+
return false;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
return !!this.style.getImage(id);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/**
|
|
889
|
+
* Remove an image from the style (such as one used by `icon-image` or `background-pattern`).
|
|
890
|
+
*
|
|
891
|
+
* @param id The ID of the image.
|
|
892
|
+
*/
|
|
893
|
+
removeImage(id) {
|
|
894
|
+
this.style.removeImage(id);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Returns an Array of strings containing the names of all sprites/images currently available in the map
|
|
899
|
+
*
|
|
900
|
+
* @returns {Array<string>} An Array of strings containing the names of all sprites/images currently available in the map
|
|
901
|
+
*
|
|
902
|
+
*/
|
|
903
|
+
listImages() {
|
|
904
|
+
return this.style.listImages();
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Adds a [Mapbox style layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers)
|
|
909
|
+
* to the map's style.
|
|
910
|
+
*
|
|
911
|
+
* A layer defines styling for data from a specified source.
|
|
912
|
+
*
|
|
913
|
+
* @param {Object} layer The style layer to add, conforming to the Mapbox Style Specification's
|
|
914
|
+
* [layer definition](https://www.mapbox.com/mapbox-gl-style-spec/#layers).
|
|
915
|
+
* @param {string} [before] The ID of an existing layer to insert the new layer before.
|
|
916
|
+
* If this argument is omitted, the layer will be appended to the end of the layers array.
|
|
917
|
+
* @returns {Map} `this`
|
|
918
|
+
* @see [Create and style clusters](https://www.mapbox.com/mapbox-gl-js/example/cluster/)
|
|
919
|
+
* @see [Add a vector tile source](https://www.mapbox.com/mapbox-gl-js/example/vector-source/)
|
|
920
|
+
* @see [Add a WMS source](https://www.mapbox.com/mapbox-gl-js/example/wms/)
|
|
921
|
+
*/
|
|
922
|
+
addLayer(layer, before) {
|
|
923
|
+
this.style.addLayer(layer, before);
|
|
924
|
+
this._update(true);
|
|
925
|
+
return this;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* Moves a layer to a different z-position.
|
|
930
|
+
*
|
|
931
|
+
* @param {string} id The ID of the layer to move.
|
|
932
|
+
* @param {string} [beforeId] The ID of an existing layer to insert the new layer before.
|
|
933
|
+
* If this argument is omitted, the layer will be appended to the end of the layers array.
|
|
934
|
+
* @returns {Map} `this`
|
|
935
|
+
*/
|
|
936
|
+
moveLayer(id, beforeId) {
|
|
937
|
+
this.style.moveLayer(id, beforeId);
|
|
938
|
+
this._update(true);
|
|
939
|
+
return this;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* Removes the layer with the given id from the map's style.
|
|
944
|
+
*
|
|
945
|
+
* If no such layer exists, an `error` event is fired.
|
|
946
|
+
*
|
|
947
|
+
* @param {string} id id of the layer to remove
|
|
948
|
+
* @fires error
|
|
949
|
+
*/
|
|
950
|
+
removeLayer(id) {
|
|
951
|
+
this.style.removeLayer(id);
|
|
952
|
+
this._update(true);
|
|
953
|
+
return this;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Returns the layer with the specified ID in the map's style.
|
|
958
|
+
*
|
|
959
|
+
* @param {string} id The ID of the layer to get.
|
|
960
|
+
* @returns {?Object} The layer with the specified ID, or `undefined`
|
|
961
|
+
* if the ID corresponds to no existing layers.
|
|
962
|
+
* @see [Filter symbols by toggling a list](https://www.mapbox.com/mapbox-gl-js/example/filter-markers/)
|
|
963
|
+
* @see [Filter symbols by text input](https://www.mapbox.com/mapbox-gl-js/example/filter-markers-by-input/)
|
|
964
|
+
*/
|
|
965
|
+
getLayer(id) {
|
|
966
|
+
return this.style.getLayer(id);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* Sets the filter for the specified style layer.
|
|
971
|
+
*
|
|
972
|
+
* @param {string} layer The ID of the layer to which the filter will be applied.
|
|
973
|
+
* @param {Array | null | undefined} filter The filter, conforming to the Mapbox Style Specification's
|
|
974
|
+
* [filter definition](https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter). If `null` or `undefined` is provided, the function removes any existing filter from the layer.
|
|
975
|
+
* @returns {Map} `this`
|
|
976
|
+
* @example
|
|
977
|
+
* map.setFilter('my-layer', ['==', 'name', 'USA']);
|
|
978
|
+
* @see [Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/)
|
|
979
|
+
* @see [Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/)
|
|
980
|
+
* @see [Create a timeline animation](https://www.mapbox.com/mapbox-gl-js/example/timeline-animation/)
|
|
981
|
+
*/
|
|
982
|
+
setFilter(layer, filter) {
|
|
983
|
+
this.style.setFilter(layer, filter);
|
|
984
|
+
this._update(true);
|
|
985
|
+
return this;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
/**
|
|
989
|
+
* Sets the zoom extent for the specified style layer.
|
|
990
|
+
*
|
|
991
|
+
* @param {string} layerId The ID of the layer to which the zoom extent will be applied.
|
|
992
|
+
* @param {number} minzoom The minimum zoom to set (0-24).
|
|
993
|
+
* @param {number} maxzoom The maximum zoom to set (0-24).
|
|
994
|
+
* @returns {Map} `this`
|
|
995
|
+
* @example
|
|
996
|
+
* map.setLayerZoomRange('my-layer', 2, 5);
|
|
997
|
+
*/
|
|
998
|
+
setLayerZoomRange(layerId, minzoom, maxzoom) {
|
|
999
|
+
this.style.setLayerZoomRange(layerId, minzoom, maxzoom);
|
|
1000
|
+
this._update(true);
|
|
1001
|
+
return this;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Returns the filter applied to the specified style layer.
|
|
1006
|
+
*
|
|
1007
|
+
* @param {string} layer The ID of the style layer whose filter to get.
|
|
1008
|
+
* @returns {Array} The layer's filter.
|
|
1009
|
+
*/
|
|
1010
|
+
getFilter(layer) {
|
|
1011
|
+
return this.style.getFilter(layer);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Sets the value of a paint property in the specified style layer.
|
|
1016
|
+
*
|
|
1017
|
+
* @param {string} layer The ID of the layer to set the paint property in.
|
|
1018
|
+
* @param {string} name The name of the paint property to set.
|
|
1019
|
+
* @param {*} value The value of the paint propery to set.
|
|
1020
|
+
* Must be of a type appropriate for the property, as defined in the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/).
|
|
1021
|
+
* @returns {Map} `this`
|
|
1022
|
+
* @example
|
|
1023
|
+
* map.setPaintProperty('my-layer', 'fill-color', '#faafee');
|
|
1024
|
+
* @see [Change a layer's color with buttons](https://www.mapbox.com/mapbox-gl-js/example/color-switcher/)
|
|
1025
|
+
* @see [Adjust a layer's opacity](https://www.mapbox.com/mapbox-gl-js/example/adjust-layer-opacity/)
|
|
1026
|
+
* @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/)
|
|
1027
|
+
*/
|
|
1028
|
+
setPaintProperty(layer, name, value) {
|
|
1029
|
+
this.style.setPaintProperty(layer, name, value);
|
|
1030
|
+
this._update(true);
|
|
1031
|
+
return this;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* Returns the value of a paint property in the specified style layer.
|
|
1036
|
+
*
|
|
1037
|
+
* @param {string} layer The ID of the layer to get the paint property from.
|
|
1038
|
+
* @param {string} name The name of a paint property to get.
|
|
1039
|
+
* @returns {*} The value of the specified paint property.
|
|
1040
|
+
*/
|
|
1041
|
+
getPaintProperty(layer, name) {
|
|
1042
|
+
return this.style.getPaintProperty(layer, name);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* Sets the value of a layout property in the specified style layer.
|
|
1047
|
+
*
|
|
1048
|
+
* @param {string} layer The ID of the layer to set the layout property in.
|
|
1049
|
+
* @param {string} name The name of the layout property to set.
|
|
1050
|
+
* @param {*} value The value of the layout propery. Must be of a type appropriate for the property, as defined in the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/).
|
|
1051
|
+
* @returns {Map} `this`
|
|
1052
|
+
* @example
|
|
1053
|
+
* map.setLayoutProperty('my-layer', 'visibility', 'none');
|
|
1054
|
+
*/
|
|
1055
|
+
setLayoutProperty(layer, name, value) {
|
|
1056
|
+
this.style.setLayoutProperty(layer, name, value);
|
|
1057
|
+
this._update(true);
|
|
1058
|
+
return this;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* Returns the value of a layout property in the specified style layer.
|
|
1063
|
+
*
|
|
1064
|
+
* @param {string} layer The ID of the layer to get the layout property from.
|
|
1065
|
+
* @param {string} name The name of the layout property to get.
|
|
1066
|
+
* @returns {*} The value of the specified layout property.
|
|
1067
|
+
*/
|
|
1068
|
+
getLayoutProperty(layer, name) {
|
|
1069
|
+
return this.style.getLayoutProperty(layer, name);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/**
|
|
1073
|
+
* Sets the any combination of light values.
|
|
1074
|
+
*
|
|
1075
|
+
* @param light Light properties to set. Must conform to the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/).
|
|
1076
|
+
* @returns {Map} `this`
|
|
1077
|
+
*/
|
|
1078
|
+
setLight(light) {
|
|
1079
|
+
this.style.setLight(light);
|
|
1080
|
+
this._update(true);
|
|
1081
|
+
return this;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
/**
|
|
1085
|
+
* Returns the value of the light object.
|
|
1086
|
+
*
|
|
1087
|
+
* @returns {Object} light Light properties of the style.
|
|
1088
|
+
*/
|
|
1089
|
+
getLight() {
|
|
1090
|
+
return this.style.getLight();
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* Sets the state of a feature. The `state` object is merged in with the existing state of the feature.
|
|
1095
|
+
*
|
|
1096
|
+
* @param {Object} [feature] Feature identifier. Feature objects returned from
|
|
1097
|
+
* {@link Map#queryRenderedFeatures} or event handlers can be used as feature identifiers.
|
|
1098
|
+
* @param {string} [feature.source] The Id of the vector source or GeoJSON source for the feature.
|
|
1099
|
+
* @param {string} [feature.sourceLayer] (optional) *For vector tile sources, the sourceLayer is
|
|
1100
|
+
* required.*
|
|
1101
|
+
* @param {string} [feature.id] Unique id of the feature.
|
|
1102
|
+
* @param {Object} state A set of key-value pairs. The values should be valid JSON types.
|
|
1103
|
+
*/
|
|
1104
|
+
setFeatureState(feature, state) {
|
|
1105
|
+
this.style.setFeatureState(feature, state);
|
|
1106
|
+
this._update();
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* Gets the state of a feature.
|
|
1111
|
+
*
|
|
1112
|
+
* @param {Object} [feature] Feature identifier. Feature objects returned from
|
|
1113
|
+
* {@link Map#queryRenderedFeatures} or event handlers can be used as feature identifiers.
|
|
1114
|
+
* @param {string} [feature.source] The Id of the vector source or GeoJSON source for the feature.
|
|
1115
|
+
* @param {string} [feature.sourceLayer] (optional) *For vector tile sources, the sourceLayer is
|
|
1116
|
+
* required.*
|
|
1117
|
+
* @param {string} [feature.id] Unique id of the feature.
|
|
1118
|
+
*
|
|
1119
|
+
* @returns {Object} The state of the feature.
|
|
1120
|
+
*/
|
|
1121
|
+
getFeatureState(feature) {
|
|
1122
|
+
return this.style.getFeatureState(feature);
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Returns the map's containing HTML element.
|
|
1127
|
+
*
|
|
1128
|
+
* @returns {HTMLElement} The map's container.
|
|
1129
|
+
*/
|
|
1130
|
+
getContainer() {
|
|
1131
|
+
return this._container;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
/**
|
|
1135
|
+
* Returns the HTML element containing the map's `<canvas>` element.
|
|
1136
|
+
*
|
|
1137
|
+
* If you want to add non-GL overlays to the map, you should append them to this element.
|
|
1138
|
+
*
|
|
1139
|
+
* This is the element to which event bindings for map interactivity (such as panning and zooming) are
|
|
1140
|
+
* attached. It will receive bubbled events from child elements such as the `<canvas>`, but not from
|
|
1141
|
+
* map controls.
|
|
1142
|
+
*
|
|
1143
|
+
* @returns {HTMLElement} The container of the map's `<canvas>`.
|
|
1144
|
+
* @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/)
|
|
1145
|
+
* @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/)
|
|
1146
|
+
*/
|
|
1147
|
+
getCanvasContainer() {
|
|
1148
|
+
return this._canvasContainer;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* Returns the map's `<canvas>` element.
|
|
1153
|
+
*
|
|
1154
|
+
* @returns {HTMLCanvasElement} The map's `<canvas>` element.
|
|
1155
|
+
* @see [Measure distances](https://www.mapbox.com/mapbox-gl-js/example/measure/)
|
|
1156
|
+
* @see [Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/)
|
|
1157
|
+
* @see [Center the map on a clicked symbol](https://www.mapbox.com/mapbox-gl-js/example/center-on-symbol/)
|
|
1158
|
+
*/
|
|
1159
|
+
getCanvas() {
|
|
1160
|
+
return this._canvas;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
_containerDimensions() {
|
|
1164
|
+
let width = 0;
|
|
1165
|
+
let height = 0;
|
|
1166
|
+
|
|
1167
|
+
if (this._container) {
|
|
1168
|
+
width = this._container.offsetWidth || 400;
|
|
1169
|
+
height = this._container.offsetHeight || 300;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
return [width, height];
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
_setupContainer() {
|
|
1176
|
+
const container = this._container;
|
|
1177
|
+
container.classList.add('mapboxgl-map');
|
|
1178
|
+
|
|
1179
|
+
const canvasContainer = (this._canvasContainer = DOM.create('div', 'mapboxgl-canvas-container', container));
|
|
1180
|
+
if (this._interactive) {
|
|
1181
|
+
canvasContainer.classList.add('mapboxgl-interactive');
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
this._canvas = DOM.create('canvas', 'mapboxgl-canvas', canvasContainer);
|
|
1185
|
+
this._canvas.style.position = 'absolute';
|
|
1186
|
+
this._canvas.addEventListener('webglcontextlost', this._contextLost, false);
|
|
1187
|
+
this._canvas.addEventListener('webglcontextrestored', this._contextRestored, false);
|
|
1188
|
+
this._canvas.setAttribute('tabindex', '0');
|
|
1189
|
+
this._canvas.setAttribute('aria-label', 'Map');
|
|
1190
|
+
|
|
1191
|
+
const dimensions = this._containerDimensions();
|
|
1192
|
+
this._resizeCanvas(dimensions[0], dimensions[1]);
|
|
1193
|
+
|
|
1194
|
+
const controlContainer = (this._controlContainer = DOM.create('div', 'mapboxgl-control-container', container));
|
|
1195
|
+
const positions = (this._controlPositions = {});
|
|
1196
|
+
['top-left', 'top-right', 'bottom-left', 'bottom-right'].forEach(positionName => {
|
|
1197
|
+
positions[positionName] = DOM.create('div', `mapboxgl-ctrl-${positionName}`, controlContainer);
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
_resizeCanvas(width, height) {
|
|
1202
|
+
const pixelRatio = window.devicePixelRatio || 1;
|
|
1203
|
+
|
|
1204
|
+
// Request the required canvas size taking the pixelratio into account.
|
|
1205
|
+
this._canvas.width = pixelRatio * width;
|
|
1206
|
+
this._canvas.height = pixelRatio * height;
|
|
1207
|
+
|
|
1208
|
+
// Maintain the same canvas size, potentially downscaling it for HiDPI displays
|
|
1209
|
+
this._canvas.style.width = `${width}px`;
|
|
1210
|
+
this._canvas.style.height = `${height}px`;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
_setupPainter() {
|
|
1214
|
+
const attributes = {
|
|
1215
|
+
antialias: false,
|
|
1216
|
+
alpha: true,
|
|
1217
|
+
stencil: true,
|
|
1218
|
+
depth: true,
|
|
1219
|
+
failIfMajorPerformanceCaveat: this._failIfMajorPerformanceCaveat,
|
|
1220
|
+
preserveDrawingBuffer: this._preserveDrawingBuffer
|
|
1221
|
+
};
|
|
1222
|
+
|
|
1223
|
+
const gl =
|
|
1224
|
+
this._canvas.getContext('webgl', attributes) || this._canvas.getContext('experimental-webgl', attributes);
|
|
1225
|
+
|
|
1226
|
+
if (!gl) {
|
|
1227
|
+
throw new Error('Failed to initialize WebGL');
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
this.painter = new Painter(gl, this.transform);
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
_contextLost(event) {
|
|
1234
|
+
event.preventDefault();
|
|
1235
|
+
if (this._frameId) {
|
|
1236
|
+
browser.cancelFrame(this._frameId);
|
|
1237
|
+
this._frameId = null;
|
|
1238
|
+
}
|
|
1239
|
+
this.fire(new Event('webglcontextlost', { originalEvent: event }));
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
_contextRestored(event) {
|
|
1243
|
+
this._setupPainter();
|
|
1244
|
+
this.resize();
|
|
1245
|
+
this._update();
|
|
1246
|
+
this.fire(new Event('webglcontextrestored', { originalEvent: event }));
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* Returns a Boolean indicating whether the map is fully loaded.
|
|
1251
|
+
*
|
|
1252
|
+
* Returns `false` if the style is not yet fully loaded,
|
|
1253
|
+
* or if there has been a change to the sources or style that
|
|
1254
|
+
* has not yet fully loaded.
|
|
1255
|
+
*
|
|
1256
|
+
* @returns {boolean} A Boolean indicating whether the map is fully loaded.
|
|
1257
|
+
*/
|
|
1258
|
+
loaded() {
|
|
1259
|
+
if (this._styleDirty || this._sourcesDirty) return false;
|
|
1260
|
+
if (!this.style || !this.style.loaded()) return false;
|
|
1261
|
+
return true;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
/**
|
|
1265
|
+
* Update this map's style and sources, and re-render the map.
|
|
1266
|
+
*
|
|
1267
|
+
* @param {boolean} updateStyle mark the map's style for reprocessing as
|
|
1268
|
+
* well as its sources
|
|
1269
|
+
* @returns {Map} this
|
|
1270
|
+
* @private
|
|
1271
|
+
*/
|
|
1272
|
+
_update(updateStyle) {
|
|
1273
|
+
if (!this.style) return;
|
|
1274
|
+
|
|
1275
|
+
this._styleDirty = this._styleDirty || updateStyle;
|
|
1276
|
+
this._sourcesDirty = true;
|
|
1277
|
+
|
|
1278
|
+
this._rerender();
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
/**
|
|
1282
|
+
* Request that the given callback be executed during the next render
|
|
1283
|
+
* frame. Schedule a render frame if one is not already scheduled.
|
|
1284
|
+
* @returns An id that can be used to cancel the callback
|
|
1285
|
+
* @private
|
|
1286
|
+
*/
|
|
1287
|
+
_requestRenderFrame(callback) {
|
|
1288
|
+
this._update();
|
|
1289
|
+
return this._renderTaskQueue.add(callback);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
_cancelRenderFrame(id) {
|
|
1293
|
+
this._renderTaskQueue.remove(id);
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
/**
|
|
1297
|
+
* Call when a (re-)render of the map is required:
|
|
1298
|
+
* - The style has changed (`setPaintProperty()`, etc.)
|
|
1299
|
+
* - Source data has changed (e.g. tiles have finished loading)
|
|
1300
|
+
* - The map has is moving (or just finished moving)
|
|
1301
|
+
* - A transition is in progress
|
|
1302
|
+
*
|
|
1303
|
+
* @returns {Map} this
|
|
1304
|
+
* @private
|
|
1305
|
+
*/
|
|
1306
|
+
_render() {
|
|
1307
|
+
this._renderTaskQueue.run();
|
|
1308
|
+
|
|
1309
|
+
let crossFading = false;
|
|
1310
|
+
|
|
1311
|
+
// If the style has changed, the map is being zoomed, or a transition or fade is in progress:
|
|
1312
|
+
// - Apply style changes (in a batch)
|
|
1313
|
+
// - Recalculate paint properties.
|
|
1314
|
+
if (this.style && this._styleDirty) {
|
|
1315
|
+
this._styleDirty = false;
|
|
1316
|
+
|
|
1317
|
+
const zoom = this.transform.zoom;
|
|
1318
|
+
const now = browser.now();
|
|
1319
|
+
this.style.zoomHistory.update(zoom, now);
|
|
1320
|
+
|
|
1321
|
+
const parameters = new EvaluationParameters(zoom, {
|
|
1322
|
+
now,
|
|
1323
|
+
fadeDuration: this._fadeDuration,
|
|
1324
|
+
zoomHistory: this.style.zoomHistory,
|
|
1325
|
+
transition: this.style.getTransition()
|
|
1326
|
+
});
|
|
1327
|
+
|
|
1328
|
+
const factor = parameters.crossFadingFactor();
|
|
1329
|
+
if (factor !== 1 || factor !== this._crossFadingFactor) {
|
|
1330
|
+
crossFading = true;
|
|
1331
|
+
this._crossFadingFactor = factor;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
this.style.update(parameters);
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
// If we are in _render for any reason other than an in-progress paint
|
|
1338
|
+
// transition, update source caches to check for and load any tiles we
|
|
1339
|
+
// need for the current transform
|
|
1340
|
+
if (this.style && this._sourcesDirty) {
|
|
1341
|
+
this._sourcesDirty = false;
|
|
1342
|
+
this.style._updateSources(this.transform);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
this._placementDirty = this.style?._updatePlacement(
|
|
1346
|
+
this.painter.transform,
|
|
1347
|
+
this.showCollisionBoxes,
|
|
1348
|
+
this._fadeDuration,
|
|
1349
|
+
this._crossSourceCollisions
|
|
1350
|
+
);
|
|
1351
|
+
|
|
1352
|
+
// Actually draw
|
|
1353
|
+
this.painter.render(this.style, {
|
|
1354
|
+
showTileBoundaries: this.showTileBoundaries,
|
|
1355
|
+
showOverdrawInspector: this._showOverdrawInspector,
|
|
1356
|
+
rotating: this.isRotating(),
|
|
1357
|
+
zooming: this.isZooming(),
|
|
1358
|
+
moving: this.isMoving(),
|
|
1359
|
+
fadeDuration: this._fadeDuration
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1362
|
+
this.fire(new Event('render'));
|
|
1363
|
+
|
|
1364
|
+
if (this.loaded() && !this._loaded) {
|
|
1365
|
+
this._loaded = true;
|
|
1366
|
+
this.fire(new Event('load'));
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
if (this.style && (this.style.hasTransitions() || crossFading)) {
|
|
1370
|
+
this._styleDirty = true;
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
if (this.style && !this._placementDirty) {
|
|
1374
|
+
// Since no fade operations are in progress, we can release
|
|
1375
|
+
// all tiles held for fading. If we didn't do this, the tiles
|
|
1376
|
+
// would just sit in the SourceCaches until the next render
|
|
1377
|
+
this.style._releaseSymbolFadeTiles();
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// Schedule another render frame if it's needed.
|
|
1381
|
+
//
|
|
1382
|
+
// Even though `_styleDirty` and `_sourcesDirty` are reset in this
|
|
1383
|
+
// method, synchronous events fired during Style#update or
|
|
1384
|
+
// Style#_updateSources could have caused them to be set again.
|
|
1385
|
+
if (this._sourcesDirty || this._repaint || this._styleDirty || this._placementDirty) {
|
|
1386
|
+
this._rerender();
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
return this;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
/**
|
|
1393
|
+
* Clean up and release all internal resources associated with this map.
|
|
1394
|
+
*
|
|
1395
|
+
* This includes DOM elements, event bindings, web workers, and WebGL resources.
|
|
1396
|
+
*
|
|
1397
|
+
* Use this method when you are done using the map and wish to ensure that it no
|
|
1398
|
+
* longer consumes browser resources. Afterwards, you must not call any other
|
|
1399
|
+
* methods on the map.
|
|
1400
|
+
*/
|
|
1401
|
+
remove() {
|
|
1402
|
+
browser.cancelFrame(this._frameId);
|
|
1403
|
+
this._renderTaskQueue.clear();
|
|
1404
|
+
this._frameId = null;
|
|
1405
|
+
this.setStyle(null);
|
|
1406
|
+
if (typeof window !== 'undefined') {
|
|
1407
|
+
window.removeEventListener('resize', this._onWindowResize, false);
|
|
1408
|
+
window.removeEventListener('online', this._onWindowOnline, false);
|
|
1409
|
+
}
|
|
1410
|
+
const extension = this.painter.context.gl.getExtension('WEBGL_lose_context');
|
|
1411
|
+
if (extension) extension.loseContext();
|
|
1412
|
+
removeNode(this._canvasContainer);
|
|
1413
|
+
removeNode(this._controlContainer);
|
|
1414
|
+
this._container.classList.remove('mapboxgl-map');
|
|
1415
|
+
this.fire(new Event('remove'));
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
_rerender() {
|
|
1419
|
+
if (this.style && !this._frameId) {
|
|
1420
|
+
this._frameId = browser.frame(() => {
|
|
1421
|
+
this._frameId = null;
|
|
1422
|
+
this._render();
|
|
1423
|
+
});
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
_onWindowOnline() {
|
|
1428
|
+
this._update();
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
_onWindowResize() {
|
|
1432
|
+
if (this._trackResize) {
|
|
1433
|
+
this.stop().resize()._update();
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
/**
|
|
1438
|
+
* Gets and sets a Boolean indicating whether the map will render an outline
|
|
1439
|
+
* around each tile. These tile boundaries are useful for debugging.
|
|
1440
|
+
*
|
|
1441
|
+
* @name showTileBoundaries
|
|
1442
|
+
* @type {boolean}
|
|
1443
|
+
* @instance
|
|
1444
|
+
* @memberof Map
|
|
1445
|
+
*/
|
|
1446
|
+
get showTileBoundaries() {
|
|
1447
|
+
return !!this._showTileBoundaries;
|
|
1448
|
+
}
|
|
1449
|
+
set showTileBoundaries(value) {
|
|
1450
|
+
if (this._showTileBoundaries === value) return;
|
|
1451
|
+
this._showTileBoundaries = value;
|
|
1452
|
+
this._update();
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
/**
|
|
1456
|
+
* Gets and sets a Boolean indicating whether the map will render boxes
|
|
1457
|
+
* around all symbols in the data source, revealing which symbols
|
|
1458
|
+
* were rendered or which were hidden due to collisions.
|
|
1459
|
+
* This information is useful for debugging.
|
|
1460
|
+
*
|
|
1461
|
+
* @name showCollisionBoxes
|
|
1462
|
+
* @type {boolean}
|
|
1463
|
+
* @instance
|
|
1464
|
+
* @memberof Map
|
|
1465
|
+
*/
|
|
1466
|
+
get showCollisionBoxes() {
|
|
1467
|
+
return !!this._showCollisionBoxes;
|
|
1468
|
+
}
|
|
1469
|
+
set showCollisionBoxes(value) {
|
|
1470
|
+
if (this._showCollisionBoxes === value) return;
|
|
1471
|
+
this._showCollisionBoxes = value;
|
|
1472
|
+
if (value) {
|
|
1473
|
+
// When we turn collision boxes on we have to generate them for existing tiles
|
|
1474
|
+
// When we turn them off, there's no cost to leaving existing boxes in place
|
|
1475
|
+
this.style._generateCollisionBoxes();
|
|
1476
|
+
} else {
|
|
1477
|
+
// Otherwise, call an update to remove collision boxes
|
|
1478
|
+
this._update();
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
/*
|
|
1483
|
+
* Gets and sets a Boolean indicating whether the map should color-code
|
|
1484
|
+
* each fragment to show how many times it has been shaded.
|
|
1485
|
+
* White fragments have been shaded 8 or more times.
|
|
1486
|
+
* Black fragments have been shaded 0 times.
|
|
1487
|
+
* This information is useful for debugging.
|
|
1488
|
+
*
|
|
1489
|
+
* @name showOverdraw
|
|
1490
|
+
* @type {boolean}
|
|
1491
|
+
* @instance
|
|
1492
|
+
* @memberof Map
|
|
1493
|
+
*/
|
|
1494
|
+
get showOverdrawInspector() {
|
|
1495
|
+
return !!this._showOverdrawInspector;
|
|
1496
|
+
}
|
|
1497
|
+
set showOverdrawInspector(value) {
|
|
1498
|
+
if (this._showOverdrawInspector === value) return;
|
|
1499
|
+
this._showOverdrawInspector = value;
|
|
1500
|
+
this._update();
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
/**
|
|
1504
|
+
* Gets and sets a Boolean indicating whether the map will
|
|
1505
|
+
* continuously repaint. This information is useful for analyzing performance.
|
|
1506
|
+
*
|
|
1507
|
+
* @name repaint
|
|
1508
|
+
* @type {boolean}
|
|
1509
|
+
* @instance
|
|
1510
|
+
* @memberof Map
|
|
1511
|
+
*/
|
|
1512
|
+
get repaint() {
|
|
1513
|
+
return !!this._repaint;
|
|
1514
|
+
}
|
|
1515
|
+
set repaint(value) {
|
|
1516
|
+
this._repaint = value;
|
|
1517
|
+
this._update();
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
// show vertices
|
|
1521
|
+
get vertices() {
|
|
1522
|
+
return !!this._vertices;
|
|
1523
|
+
}
|
|
1524
|
+
set vertices(value) {
|
|
1525
|
+
this._vertices = value;
|
|
1526
|
+
this._update();
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
_onData(event) {
|
|
1530
|
+
this._update(event.dataType === 'style');
|
|
1531
|
+
this.fire(new Event(`${event.dataType}data`, event));
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
_onDataLoading(event) {
|
|
1535
|
+
this.fire(new Event(`${event.dataType}dataloading`, event));
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
module.exports = Map;
|
|
1540
|
+
|
|
1541
|
+
function removeNode(node) {
|
|
1542
|
+
if (node.parentNode) {
|
|
1543
|
+
node.parentNode.removeChild(node);
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
/**
|
|
1548
|
+
* Interface for interactive controls added to the map. This is an
|
|
1549
|
+
* specification for implementers to model: it is not
|
|
1550
|
+
* an exported method or class.
|
|
1551
|
+
*
|
|
1552
|
+
* Controls must implement `onAdd` and `onRemove`, and must own an
|
|
1553
|
+
* element, which is often a `div` element. To use Mapbox GL JS's
|
|
1554
|
+
* default control styling, add the `mapboxgl-ctrl` class to your control's
|
|
1555
|
+
* node.
|
|
1556
|
+
*
|
|
1557
|
+
* @interface IControl
|
|
1558
|
+
* @example
|
|
1559
|
+
* // Control implemented as ES6 class
|
|
1560
|
+
* class HelloWorldControl {
|
|
1561
|
+
* onAdd(map) {
|
|
1562
|
+
* this._map = map;
|
|
1563
|
+
* this._container = document.createElement('div');
|
|
1564
|
+
* this._container.className = 'mapboxgl-ctrl';
|
|
1565
|
+
* this._container.textContent = 'Hello, world';
|
|
1566
|
+
* return this._container;
|
|
1567
|
+
* }
|
|
1568
|
+
*
|
|
1569
|
+
* onRemove() {
|
|
1570
|
+
* this._container.parentNode.removeChild(this._container);
|
|
1571
|
+
* this._map = undefined;
|
|
1572
|
+
* }
|
|
1573
|
+
* }
|
|
1574
|
+
*
|
|
1575
|
+
* // Control implemented as ES5 prototypical class
|
|
1576
|
+
* function HelloWorldControl() { }
|
|
1577
|
+
*
|
|
1578
|
+
* HelloWorldControl.prototype.onAdd = function(map) {
|
|
1579
|
+
* this._map = map;
|
|
1580
|
+
* this._container = document.createElement('div');
|
|
1581
|
+
* this._container.className = 'mapboxgl-ctrl';
|
|
1582
|
+
* this._container.textContent = 'Hello, world';
|
|
1583
|
+
* return this._container;
|
|
1584
|
+
* };
|
|
1585
|
+
*
|
|
1586
|
+
* HelloWorldControl.prototype.onRemove = function () {
|
|
1587
|
+
* this._container.parentNode.removeChild(this._container);
|
|
1588
|
+
* this._map = undefined;
|
|
1589
|
+
* };
|
|
1590
|
+
*/
|
|
1591
|
+
|
|
1592
|
+
/**
|
|
1593
|
+
* Register a control on the map and give it a chance to register event listeners
|
|
1594
|
+
* and resources. This method is called by {@link Map#addControl}
|
|
1595
|
+
* internally.
|
|
1596
|
+
*
|
|
1597
|
+
* @function
|
|
1598
|
+
* @memberof IControl
|
|
1599
|
+
* @instance
|
|
1600
|
+
* @name onAdd
|
|
1601
|
+
* @param {Map} map the Map this control will be added to
|
|
1602
|
+
* @returns {HTMLElement} The control's container element. This should
|
|
1603
|
+
* be created by the control and returned by onAdd without being attached
|
|
1604
|
+
* to the DOM: the map will insert the control's element into the DOM
|
|
1605
|
+
* as necessary.
|
|
1606
|
+
*/
|
|
1607
|
+
|
|
1608
|
+
/**
|
|
1609
|
+
* Unregister a control on the map and give it a chance to detach event listeners
|
|
1610
|
+
* and resources. This method is called by {@link Map#removeControl}
|
|
1611
|
+
* internally.
|
|
1612
|
+
*
|
|
1613
|
+
* @function
|
|
1614
|
+
* @memberof IControl
|
|
1615
|
+
* @instance
|
|
1616
|
+
* @name onRemove
|
|
1617
|
+
* @param {Map} map the Map this control will be removed from
|
|
1618
|
+
* @returns {undefined} there is no required return value for this method
|
|
1619
|
+
*/
|
|
1620
|
+
|
|
1621
|
+
/**
|
|
1622
|
+
* Optionally provide a default position for this control. If this method
|
|
1623
|
+
* is implemented and {@link Map#addControl} is called without the `position`
|
|
1624
|
+
* parameter, the value returned by getDefaultPosition will be used as the
|
|
1625
|
+
* control's position.
|
|
1626
|
+
*
|
|
1627
|
+
* @function
|
|
1628
|
+
* @memberof IControl
|
|
1629
|
+
* @instance
|
|
1630
|
+
* @name getDefaultPosition
|
|
1631
|
+
* @returns {string} a control position, one of the values valid in addControl.
|
|
1632
|
+
*/
|
|
1633
|
+
|
|
1634
|
+
/**
|
|
1635
|
+
* A [`Point` geometry](https://github.com/mapbox/point-geometry) object, which has
|
|
1636
|
+
* `x` and `y` properties representing screen coordinates in pixels.
|
|
1637
|
+
*
|
|
1638
|
+
* @typedef {Object} Point
|
|
1639
|
+
*/
|
|
1640
|
+
|
|
1641
|
+
/**
|
|
1642
|
+
* A {@link Point} or an array of two numbers representing `x` and `y` screen coordinates in pixels.
|
|
1643
|
+
*
|
|
1644
|
+
* @typedef {(Point | Array<number>)} PointLike
|
|
1645
|
+
*/
|