@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
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const { parseCSSColor } = require('csscolorparser');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An RGBA color value. Create instances from color strings using the static
|
|
5
|
+
* method `Color.parse`. The constructor accepts RGB channel values in the range
|
|
6
|
+
* `[0, 1]`, premultiplied by A.
|
|
7
|
+
*
|
|
8
|
+
* @param {number} r The red channel.
|
|
9
|
+
* @param {number} g The green channel.
|
|
10
|
+
* @param {number} b The blue channel.
|
|
11
|
+
* @param {number} a The alpha channel.
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
class Color {
|
|
15
|
+
constructor(r, g, b, a = 1) {
|
|
16
|
+
this.r = r;
|
|
17
|
+
this.g = g;
|
|
18
|
+
this.b = b;
|
|
19
|
+
this.a = a;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Parses valid CSS color strings and returns a `Color` instance.
|
|
24
|
+
* @returns A `Color` instance, or `undefined` if the input is not a valid color string.
|
|
25
|
+
*/
|
|
26
|
+
static parse(input) {
|
|
27
|
+
if (!input) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (input instanceof Color) {
|
|
32
|
+
return input;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (typeof input !== 'string') {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const rgba = parseCSSColor(input);
|
|
40
|
+
if (!rgba) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return new Color((rgba[0] / 255) * rgba[3], (rgba[1] / 255) * rgba[3], (rgba[2] / 255) * rgba[3], rgba[3]);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns an RGBA string representing the color value.
|
|
49
|
+
*
|
|
50
|
+
* @returns An RGBA string.
|
|
51
|
+
* @example
|
|
52
|
+
* var purple = new Color.parse('purple');
|
|
53
|
+
* purple.toString; // = "rgba(128,0,128,1)"
|
|
54
|
+
* var translucentGreen = new Color.parse('rgba(26, 207, 26, .73)');
|
|
55
|
+
* translucentGreen.toString(); // = "rgba(26,207,26,0.73)"
|
|
56
|
+
*/
|
|
57
|
+
toString() {
|
|
58
|
+
const [r, g, b, a] = this.toArray();
|
|
59
|
+
return `rgba(${Math.round(r)},${Math.round(g)},${Math.round(b)},${a})`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
toArray() {
|
|
63
|
+
const { r, g, b, a } = this;
|
|
64
|
+
return a === 0 ? [0, 0, 0, 0] : [(r * 255) / a, (g * 255) / a, (b * 255) / a, a];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
Color.black = new Color(0, 0, 0, 1);
|
|
69
|
+
Color.white = new Color(1, 1, 1, 1);
|
|
70
|
+
Color.transparent = new Color(0, 0, 0, 0);
|
|
71
|
+
Color.red = new Color(1, 0, 0, 1);
|
|
72
|
+
|
|
73
|
+
module.exports = Color;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const Color = require('./color');
|
|
2
|
+
|
|
3
|
+
const { number: interpolateNumber } = require('./interpolate');
|
|
4
|
+
|
|
5
|
+
// Constants
|
|
6
|
+
const Xn = 0.95047; // D65 standard referent
|
|
7
|
+
const Yn = 1;
|
|
8
|
+
const Zn = 1.08883;
|
|
9
|
+
const t0 = 4 / 29;
|
|
10
|
+
const t1 = 6 / 29;
|
|
11
|
+
const t2 = 3 * t1 * t1;
|
|
12
|
+
const t3 = t1 * t1 * t1;
|
|
13
|
+
const deg2rad = Math.PI / 180;
|
|
14
|
+
const rad2deg = 180 / Math.PI;
|
|
15
|
+
|
|
16
|
+
// Utilities
|
|
17
|
+
function xyz2lab(t) {
|
|
18
|
+
return t > t3 ? t ** (1 / 3) : t / t2 + t0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function lab2xyz(t) {
|
|
22
|
+
return t > t1 ? t * t * t : t2 * (t - t0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function xyz2rgb(x) {
|
|
26
|
+
return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * x ** (1 / 2.4) - 0.055);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function rgb2xyz(x) {
|
|
30
|
+
x /= 255;
|
|
31
|
+
return x <= 0.04045 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// LAB
|
|
35
|
+
function rgbToLab(rgbColor) {
|
|
36
|
+
const b = rgb2xyz(rgbColor.r);
|
|
37
|
+
const a = rgb2xyz(rgbColor.g);
|
|
38
|
+
const l = rgb2xyz(rgbColor.b);
|
|
39
|
+
const x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn);
|
|
40
|
+
const y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.072175 * l) / Yn);
|
|
41
|
+
const z = xyz2lab((0.0193339 * b + 0.119192 * a + 0.9503041 * l) / Zn);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
l: 116 * y - 16,
|
|
45
|
+
a: 500 * (x - y),
|
|
46
|
+
b: 200 * (y - z),
|
|
47
|
+
alpha: rgbColor.a
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function labToRgb(labColor) {
|
|
52
|
+
let y = (labColor.l + 16) / 116;
|
|
53
|
+
let x = isNaN(labColor.a) ? y : y + labColor.a / 500;
|
|
54
|
+
let z = isNaN(labColor.b) ? y : y - labColor.b / 200;
|
|
55
|
+
y = Yn * lab2xyz(y);
|
|
56
|
+
x = Xn * lab2xyz(x);
|
|
57
|
+
z = Zn * lab2xyz(z);
|
|
58
|
+
return new Color(
|
|
59
|
+
xyz2rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
|
|
60
|
+
xyz2rgb(-0.969266 * x + 1.8760108 * y + 0.041556 * z),
|
|
61
|
+
xyz2rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
|
|
62
|
+
labColor.alpha
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function interpolateLab(from, to, t) {
|
|
67
|
+
return {
|
|
68
|
+
l: interpolateNumber(from.l, to.l, t),
|
|
69
|
+
a: interpolateNumber(from.a, to.a, t),
|
|
70
|
+
b: interpolateNumber(from.b, to.b, t),
|
|
71
|
+
alpha: interpolateNumber(from.alpha, to.alpha, t)
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// HCL
|
|
76
|
+
function rgbToHcl(rgbColor) {
|
|
77
|
+
const { l, a, b } = rgbToLab(rgbColor);
|
|
78
|
+
const h = Math.atan2(b, a) * rad2deg;
|
|
79
|
+
return {
|
|
80
|
+
h: h < 0 ? h + 360 : h,
|
|
81
|
+
c: Math.sqrt(a * a + b * b),
|
|
82
|
+
l: l,
|
|
83
|
+
alpha: rgbColor.a
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function hclToRgb(hclColor) {
|
|
88
|
+
const h = hclColor.h * deg2rad;
|
|
89
|
+
const c = hclColor.c;
|
|
90
|
+
const l = hclColor.l;
|
|
91
|
+
return labToRgb({
|
|
92
|
+
l: l,
|
|
93
|
+
a: Math.cos(h) * c,
|
|
94
|
+
b: Math.sin(h) * c,
|
|
95
|
+
alpha: hclColor.alpha
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function interpolateHue(a, b, t) {
|
|
100
|
+
const d = b - a;
|
|
101
|
+
return a + t * (d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function interpolateHcl(from, to, t) {
|
|
105
|
+
return {
|
|
106
|
+
h: interpolateHue(from.h, to.h, t),
|
|
107
|
+
c: interpolateNumber(from.c, to.c, t),
|
|
108
|
+
l: interpolateNumber(from.l, to.l, t),
|
|
109
|
+
alpha: interpolateNumber(from.alpha, to.alpha, t)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const lab = {
|
|
114
|
+
forward: rgbToLab,
|
|
115
|
+
reverse: labToRgb,
|
|
116
|
+
interpolate: interpolateLab
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const hcl = {
|
|
120
|
+
forward: rgbToHcl,
|
|
121
|
+
reverse: hclToRgb,
|
|
122
|
+
interpolate: interpolateHcl
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
module.exports = {
|
|
126
|
+
lab,
|
|
127
|
+
hcl
|
|
128
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module.exports = function getType(val) {
|
|
2
|
+
if (val instanceof Number) {
|
|
3
|
+
return 'number';
|
|
4
|
+
}
|
|
5
|
+
if (val instanceof String) {
|
|
6
|
+
return 'string';
|
|
7
|
+
}
|
|
8
|
+
if (val instanceof Boolean) {
|
|
9
|
+
return 'boolean';
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(val)) {
|
|
12
|
+
return 'array';
|
|
13
|
+
}
|
|
14
|
+
if (val === null) {
|
|
15
|
+
return 'null';
|
|
16
|
+
}
|
|
17
|
+
return typeof val;
|
|
18
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const Color = require('./color');
|
|
2
|
+
|
|
3
|
+
function number(a, b, t) {
|
|
4
|
+
return a * (1 - t) + b * t;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function color(from, to, t) {
|
|
8
|
+
return new Color(number(from.r, to.r, t), number(from.g, to.g, t), number(from.b, to.b, t), number(from.a, to.a, t));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function array(from, to, t) {
|
|
12
|
+
return from.map((d, i) => {
|
|
13
|
+
return number(d, to[i], t);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
number,
|
|
19
|
+
color,
|
|
20
|
+
array
|
|
21
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function supportsPropertyExpression({ ['property-type']: propertyType }) {
|
|
2
|
+
return propertyType === 'data-driven' || propertyType === 'cross-faded-data-driven';
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function supportsZoomExpression(spec) {
|
|
6
|
+
return !!spec.expression?.parameters.includes('zoom');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function supportsInterpolation(spec) {
|
|
10
|
+
return !!spec.expression?.interpolated;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
supportsPropertyExpression,
|
|
15
|
+
supportsZoomExpression,
|
|
16
|
+
supportsInterpolation
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A type used for returning and propagating errors. The first element of the union
|
|
3
|
+
* represents success and contains a value, and the second represents an error and
|
|
4
|
+
* contains an error value.
|
|
5
|
+
* @private
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
function success(value) {
|
|
9
|
+
return { result: 'success', value };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function error(value) {
|
|
13
|
+
return { result: 'error', value };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
success,
|
|
18
|
+
error
|
|
19
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const Point = require('@mapbox/point-geometry');
|
|
2
|
+
|
|
3
|
+
const { register } = require('../util/web_worker_transfer');
|
|
4
|
+
|
|
5
|
+
class Anchor extends Point {
|
|
6
|
+
constructor(x, y, angle, segment) {
|
|
7
|
+
super(x, y);
|
|
8
|
+
this.angle = angle;
|
|
9
|
+
if (segment !== undefined) {
|
|
10
|
+
this.segment = segment;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
clone() {
|
|
15
|
+
return new Anchor(this.x, this.y, this.angle, this.segment);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
register('Anchor', Anchor);
|
|
20
|
+
|
|
21
|
+
module.exports = Anchor;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module.exports = checkMaxAngle;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Labels placed around really sharp angles aren't readable. Check if any
|
|
5
|
+
* part of the potential label has a combined angle that is too big.
|
|
6
|
+
*
|
|
7
|
+
* @param line
|
|
8
|
+
* @param anchor The point on the line around which the label is anchored.
|
|
9
|
+
* @param labelLength The length of the label in geometry units.
|
|
10
|
+
* @param windowSize The check fails if the combined angles within a part of the line that is `windowSize` long is too big.
|
|
11
|
+
* @param maxAngle The maximum combined angle that any window along the label is allowed to have.
|
|
12
|
+
*
|
|
13
|
+
* @returns {boolean} whether the label should be placed
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
function checkMaxAngle(line, anchor, labelLength, windowSize, maxAngle) {
|
|
17
|
+
// horizontal labels always pass
|
|
18
|
+
if (anchor.segment === undefined) return true;
|
|
19
|
+
|
|
20
|
+
let p = anchor;
|
|
21
|
+
let index = anchor.segment + 1;
|
|
22
|
+
let anchorDistance = 0;
|
|
23
|
+
|
|
24
|
+
// move backwards along the line to the first segment the label appears on
|
|
25
|
+
while (anchorDistance > -labelLength / 2) {
|
|
26
|
+
index--;
|
|
27
|
+
|
|
28
|
+
// there isn't enough room for the label after the beginning of the line
|
|
29
|
+
if (index < 0) return false;
|
|
30
|
+
|
|
31
|
+
anchorDistance -= line[index].dist(p);
|
|
32
|
+
p = line[index];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
anchorDistance += line[index].dist(line[index + 1]);
|
|
36
|
+
index++;
|
|
37
|
+
|
|
38
|
+
// store recent corners and their total angle difference
|
|
39
|
+
const recentCorners = [];
|
|
40
|
+
let recentAngleDelta = 0;
|
|
41
|
+
|
|
42
|
+
// move forwards by the length of the label and check angles along the way
|
|
43
|
+
while (anchorDistance < labelLength / 2) {
|
|
44
|
+
const prev = line[index - 1];
|
|
45
|
+
const current = line[index];
|
|
46
|
+
const next = line[index + 1];
|
|
47
|
+
|
|
48
|
+
// there isn't enough room for the label before the end of the line
|
|
49
|
+
if (!next) return false;
|
|
50
|
+
|
|
51
|
+
let angleDelta = prev.angleTo(current) - current.angleTo(next);
|
|
52
|
+
// restrict angle to -pi..pi range
|
|
53
|
+
angleDelta = Math.abs(((angleDelta + 3 * Math.PI) % (Math.PI * 2)) - Math.PI);
|
|
54
|
+
|
|
55
|
+
recentCorners.push({
|
|
56
|
+
distance: anchorDistance,
|
|
57
|
+
angleDelta: angleDelta
|
|
58
|
+
});
|
|
59
|
+
recentAngleDelta += angleDelta;
|
|
60
|
+
|
|
61
|
+
// remove corners that are far enough away from the list of recent anchors
|
|
62
|
+
while (anchorDistance - recentCorners[0].distance > windowSize) {
|
|
63
|
+
recentAngleDelta -= recentCorners.shift().angleDelta;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// the sum of angles within the window area exceeds the maximum allowed value. check fails.
|
|
67
|
+
if (recentAngleDelta > maxAngle) return false;
|
|
68
|
+
|
|
69
|
+
index++;
|
|
70
|
+
anchorDistance += current.dist(next);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// no part of the line had an angle greater than the maximum allowed. check passes.
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const Point = require('@mapbox/point-geometry');
|
|
2
|
+
|
|
3
|
+
module.exports = clipLine;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the part of a multiline that intersects with the provided rectangular box.
|
|
7
|
+
*
|
|
8
|
+
* @param lines
|
|
9
|
+
* @param x1 the left edge of the box
|
|
10
|
+
* @param y1 the top edge of the box
|
|
11
|
+
* @param x2 the right edge of the box
|
|
12
|
+
* @param y2 the bottom edge of the box
|
|
13
|
+
* @returns lines
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
function clipLine(lines, x1, y1, x2, y2) {
|
|
17
|
+
const clippedLines = [];
|
|
18
|
+
|
|
19
|
+
for (let l = 0; l < lines.length; l++) {
|
|
20
|
+
const line = lines[l];
|
|
21
|
+
let clippedLine;
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < line.length - 1; i++) {
|
|
24
|
+
let p0 = line[i];
|
|
25
|
+
let p1 = line[i + 1];
|
|
26
|
+
|
|
27
|
+
if (p0.x < x1 && p1.x < x1) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (p0.x < x1) {
|
|
31
|
+
p0 = new Point(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round();
|
|
32
|
+
} else if (p1.x < x1) {
|
|
33
|
+
p1 = new Point(x1, p0.y + (p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x)))._round();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (p0.y < y1 && p1.y < y1) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (p0.y < y1) {
|
|
40
|
+
p0 = new Point(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round();
|
|
41
|
+
} else if (p1.y < y1) {
|
|
42
|
+
p1 = new Point(p0.x + (p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y)), y1)._round();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (p0.x >= x2 && p1.x >= x2) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (p0.x >= x2) {
|
|
49
|
+
p0 = new Point(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round();
|
|
50
|
+
} else if (p1.x >= x2) {
|
|
51
|
+
p1 = new Point(x2, p0.y + (p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x)))._round();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (p0.y >= y2 && p1.y >= y2) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (p0.y >= y2) {
|
|
58
|
+
p0 = new Point(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round();
|
|
59
|
+
} else if (p1.y >= y2) {
|
|
60
|
+
p1 = new Point(p0.x + (p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y)), y2)._round();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!clippedLine || !p0.equals(clippedLine[clippedLine.length - 1])) {
|
|
64
|
+
clippedLine = [p0];
|
|
65
|
+
clippedLines.push(clippedLine);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
clippedLine.push(p1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return clippedLines;
|
|
73
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
const Point = require('@mapbox/point-geometry');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A CollisionFeature represents the area of the tile covered by a single label.
|
|
5
|
+
* It is used with CollisionIndex to check if the label overlaps with any
|
|
6
|
+
* previous labels. A CollisionFeature is mostly just a set of CollisionBox
|
|
7
|
+
* objects.
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
class CollisionFeature {
|
|
12
|
+
/**
|
|
13
|
+
* Create a CollisionFeature, adding its collision box data to the given collisionBoxArray in the process.
|
|
14
|
+
*
|
|
15
|
+
* @param line The geometry the label is placed on.
|
|
16
|
+
* @param anchor The point along the line around which the label is anchored.
|
|
17
|
+
* @param shaped The text or icon shaping results.
|
|
18
|
+
* @param boxScale A magic number used to convert from glyph metrics units to geometry units.
|
|
19
|
+
* @param padding The amount of padding to add around the label edges.
|
|
20
|
+
* @param alignLine Whether the label is aligned with the line or the viewport.
|
|
21
|
+
*/
|
|
22
|
+
constructor(
|
|
23
|
+
collisionBoxArray,
|
|
24
|
+
line,
|
|
25
|
+
anchor,
|
|
26
|
+
featureIndex,
|
|
27
|
+
sourceLayerIndex,
|
|
28
|
+
bucketIndex,
|
|
29
|
+
shaped,
|
|
30
|
+
boxScale,
|
|
31
|
+
padding,
|
|
32
|
+
alignLine,
|
|
33
|
+
overscaling,
|
|
34
|
+
rotate
|
|
35
|
+
) {
|
|
36
|
+
let y1 = shaped.top * boxScale - padding;
|
|
37
|
+
let y2 = shaped.bottom * boxScale + padding;
|
|
38
|
+
let x1 = shaped.left * boxScale - padding;
|
|
39
|
+
let x2 = shaped.right * boxScale + padding;
|
|
40
|
+
|
|
41
|
+
this.boxStartIndex = collisionBoxArray.length;
|
|
42
|
+
|
|
43
|
+
if (alignLine) {
|
|
44
|
+
let height = y2 - y1;
|
|
45
|
+
const length = x2 - x1;
|
|
46
|
+
|
|
47
|
+
if (height > 0) {
|
|
48
|
+
// set minimum box height to avoid very many small labels
|
|
49
|
+
height = Math.max(10 * boxScale, height);
|
|
50
|
+
|
|
51
|
+
this._addLineCollisionCircles(
|
|
52
|
+
collisionBoxArray,
|
|
53
|
+
line,
|
|
54
|
+
anchor,
|
|
55
|
+
anchor.segment,
|
|
56
|
+
length,
|
|
57
|
+
height,
|
|
58
|
+
featureIndex,
|
|
59
|
+
sourceLayerIndex,
|
|
60
|
+
bucketIndex,
|
|
61
|
+
overscaling
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
if (rotate) {
|
|
66
|
+
// Account for *-rotate in point collision boxes
|
|
67
|
+
// See https://github.com/mapbox/mapbox-gl-js/issues/6075
|
|
68
|
+
// Doesn't account for icon-text-fit
|
|
69
|
+
|
|
70
|
+
const tl = new Point(x1, y1);
|
|
71
|
+
const tr = new Point(x2, y1);
|
|
72
|
+
const bl = new Point(x1, y2);
|
|
73
|
+
const br = new Point(x2, y2);
|
|
74
|
+
|
|
75
|
+
const rotateRadians = (rotate * Math.PI) / 180;
|
|
76
|
+
|
|
77
|
+
tl._rotate(rotateRadians);
|
|
78
|
+
tr._rotate(rotateRadians);
|
|
79
|
+
bl._rotate(rotateRadians);
|
|
80
|
+
br._rotate(rotateRadians);
|
|
81
|
+
|
|
82
|
+
// Collision features require an "on-axis" geometry,
|
|
83
|
+
// so take the envelope of the rotated geometry
|
|
84
|
+
// (may be quite large for wide labels rotated 45 degrees)
|
|
85
|
+
x1 = Math.min(tl.x, tr.x, bl.x, br.x);
|
|
86
|
+
x2 = Math.max(tl.x, tr.x, bl.x, br.x);
|
|
87
|
+
y1 = Math.min(tl.y, tr.y, bl.y, br.y);
|
|
88
|
+
y2 = Math.max(tl.y, tr.y, bl.y, br.y);
|
|
89
|
+
}
|
|
90
|
+
collisionBoxArray.emplaceBack(
|
|
91
|
+
anchor.x,
|
|
92
|
+
anchor.y,
|
|
93
|
+
x1,
|
|
94
|
+
y1,
|
|
95
|
+
x2,
|
|
96
|
+
y2,
|
|
97
|
+
featureIndex,
|
|
98
|
+
sourceLayerIndex,
|
|
99
|
+
bucketIndex,
|
|
100
|
+
0,
|
|
101
|
+
0
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
this.boxEndIndex = collisionBoxArray.length;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Create a set of CollisionBox objects for a line.
|
|
110
|
+
*
|
|
111
|
+
* @param labelLength The length of the label in geometry units.
|
|
112
|
+
* @param anchor The point along the line around which the label is anchored.
|
|
113
|
+
* @param boxSize The size of the collision boxes that will be created.
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
_addLineCollisionCircles(
|
|
117
|
+
collisionBoxArray,
|
|
118
|
+
line,
|
|
119
|
+
anchor,
|
|
120
|
+
segment,
|
|
121
|
+
labelLength,
|
|
122
|
+
boxSize,
|
|
123
|
+
featureIndex,
|
|
124
|
+
sourceLayerIndex,
|
|
125
|
+
bucketIndex,
|
|
126
|
+
overscaling
|
|
127
|
+
) {
|
|
128
|
+
const step = boxSize / 2;
|
|
129
|
+
const nBoxes = Math.floor(labelLength / step) || 1;
|
|
130
|
+
// We calculate line collision circles out to 300% of what would normally be our
|
|
131
|
+
// max size, to allow collision detection to work on labels that expand as
|
|
132
|
+
// they move into the distance
|
|
133
|
+
// Vertically oriented labels in the distant field can extend past this padding
|
|
134
|
+
// This is a noticeable problem in overscaled tiles where the pitch 0-based
|
|
135
|
+
// symbol spacing will put labels very close together in a pitched map.
|
|
136
|
+
// To reduce the cost of adding extra collision circles, we slowly increase
|
|
137
|
+
// them for overscaled tiles.
|
|
138
|
+
const overscalingPaddingFactor = 1 + (0.4 * Math.log(overscaling)) / Math.LN2;
|
|
139
|
+
const nPitchPaddingBoxes = Math.floor((nBoxes * overscalingPaddingFactor) / 2);
|
|
140
|
+
|
|
141
|
+
// offset the center of the first box by half a box so that the edge of the
|
|
142
|
+
// box is at the edge of the label.
|
|
143
|
+
const firstBoxOffset = -boxSize / 2;
|
|
144
|
+
|
|
145
|
+
let p = anchor;
|
|
146
|
+
let index = segment + 1;
|
|
147
|
+
let anchorDistance = firstBoxOffset;
|
|
148
|
+
const labelStartDistance = -labelLength / 2;
|
|
149
|
+
const paddingStartDistance = labelStartDistance - labelLength / 4;
|
|
150
|
+
// move backwards along the line to the first segment the label appears on
|
|
151
|
+
do {
|
|
152
|
+
index--;
|
|
153
|
+
|
|
154
|
+
if (index < 0) {
|
|
155
|
+
if (anchorDistance > labelStartDistance) {
|
|
156
|
+
// there isn't enough room for the label after the beginning of the line
|
|
157
|
+
// checkMaxAngle should have already caught this
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// The line doesn't extend far enough back for all of our padding,
|
|
161
|
+
// but we got far enough to show the label under most conditions.
|
|
162
|
+
index = 0;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
anchorDistance -= line[index].dist(p);
|
|
166
|
+
p = line[index];
|
|
167
|
+
} while (anchorDistance > paddingStartDistance);
|
|
168
|
+
|
|
169
|
+
let segmentLength = line[index].dist(line[index + 1]);
|
|
170
|
+
|
|
171
|
+
for (let i = -nPitchPaddingBoxes; i < nBoxes + nPitchPaddingBoxes; i++) {
|
|
172
|
+
// the distance the box will be from the anchor
|
|
173
|
+
const boxOffset = i * step;
|
|
174
|
+
let boxDistanceToAnchor = labelStartDistance + boxOffset;
|
|
175
|
+
|
|
176
|
+
// make the distance between pitch padding boxes bigger
|
|
177
|
+
if (boxOffset < 0) boxDistanceToAnchor += boxOffset;
|
|
178
|
+
if (boxOffset > labelLength) boxDistanceToAnchor += boxOffset - labelLength;
|
|
179
|
+
|
|
180
|
+
if (boxDistanceToAnchor < anchorDistance) {
|
|
181
|
+
// The line doesn't extend far enough back for this box, skip it
|
|
182
|
+
// (This could allow for line collisions on distant tiles)
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// the box is not on the current segment. Move to the next segment.
|
|
187
|
+
while (anchorDistance + segmentLength < boxDistanceToAnchor) {
|
|
188
|
+
anchorDistance += segmentLength;
|
|
189
|
+
index++;
|
|
190
|
+
|
|
191
|
+
// There isn't enough room before the end of the line.
|
|
192
|
+
if (index + 1 >= line.length) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
segmentLength = line[index].dist(line[index + 1]);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// the distance the box will be from the beginning of the segment
|
|
200
|
+
const segmentBoxDistance = boxDistanceToAnchor - anchorDistance;
|
|
201
|
+
|
|
202
|
+
const p0 = line[index];
|
|
203
|
+
const p1 = line[index + 1];
|
|
204
|
+
const boxAnchorPoint = p1.sub(p0)._unit()._mult(segmentBoxDistance)._add(p0)._round();
|
|
205
|
+
|
|
206
|
+
// If the box is within boxSize of the anchor, force the box to be used
|
|
207
|
+
// (so even 0-width labels use at least one box)
|
|
208
|
+
// Otherwise, the .8 multiplication gives us a little bit of conservative
|
|
209
|
+
// padding in choosing which boxes to use (see CollisionIndex#placedCollisionCircles)
|
|
210
|
+
const paddedAnchorDistance =
|
|
211
|
+
Math.abs(boxDistanceToAnchor - firstBoxOffset) < step ? 0 : (boxDistanceToAnchor - firstBoxOffset) * 0.8;
|
|
212
|
+
|
|
213
|
+
collisionBoxArray.emplaceBack(
|
|
214
|
+
boxAnchorPoint.x,
|
|
215
|
+
boxAnchorPoint.y,
|
|
216
|
+
-boxSize / 2,
|
|
217
|
+
-boxSize / 2,
|
|
218
|
+
boxSize / 2,
|
|
219
|
+
boxSize / 2,
|
|
220
|
+
featureIndex,
|
|
221
|
+
sourceLayerIndex,
|
|
222
|
+
bucketIndex,
|
|
223
|
+
boxSize / 2,
|
|
224
|
+
paddedAnchorDistance
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
module.exports = CollisionFeature;
|