@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,77 @@
|
|
|
1
|
+
const NullType = { kind: 'null' };
|
|
2
|
+
const NumberType = { kind: 'number' };
|
|
3
|
+
const StringType = { kind: 'string' };
|
|
4
|
+
const BooleanType = { kind: 'boolean' };
|
|
5
|
+
const ColorType = { kind: 'color' };
|
|
6
|
+
const ObjectType = { kind: 'object' };
|
|
7
|
+
const ValueType = { kind: 'value' };
|
|
8
|
+
const ErrorType = { kind: 'error' };
|
|
9
|
+
const CollatorType = { kind: 'collator' };
|
|
10
|
+
|
|
11
|
+
function array(itemType, N) {
|
|
12
|
+
return {
|
|
13
|
+
kind: 'array',
|
|
14
|
+
itemType,
|
|
15
|
+
N
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function toString(type) {
|
|
20
|
+
if (type.kind === 'array') {
|
|
21
|
+
const itemType = toString(type.itemType);
|
|
22
|
+
return typeof type.N === 'number'
|
|
23
|
+
? `array<${itemType}, ${type.N}>`
|
|
24
|
+
: type.itemType.kind === 'value'
|
|
25
|
+
? 'array'
|
|
26
|
+
: `array<${itemType}>`;
|
|
27
|
+
}
|
|
28
|
+
return type.kind;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const valueMemberTypes = [NullType, NumberType, StringType, BooleanType, ColorType, ObjectType, array(ValueType)];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns null if `t` is a subtype of `expected`; otherwise returns an
|
|
35
|
+
* error message.
|
|
36
|
+
* @private
|
|
37
|
+
*/
|
|
38
|
+
function checkSubtype(expected, t) {
|
|
39
|
+
if (t.kind === 'error') {
|
|
40
|
+
// Error is a subtype of every type
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
if (expected.kind === 'array') {
|
|
44
|
+
if (
|
|
45
|
+
t.kind === 'array' &&
|
|
46
|
+
!checkSubtype(expected.itemType, t.itemType) &&
|
|
47
|
+
(typeof expected.N !== 'number' || expected.N === t.N)
|
|
48
|
+
) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
} else if (expected.kind === t.kind) {
|
|
52
|
+
return null;
|
|
53
|
+
} else if (expected.kind === 'value') {
|
|
54
|
+
for (const memberType of valueMemberTypes) {
|
|
55
|
+
if (!checkSubtype(memberType, t)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return `Expected ${toString(expected)} but found ${toString(t)} instead.`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = {
|
|
65
|
+
NullType,
|
|
66
|
+
NumberType,
|
|
67
|
+
StringType,
|
|
68
|
+
BooleanType,
|
|
69
|
+
ColorType,
|
|
70
|
+
ObjectType,
|
|
71
|
+
ValueType,
|
|
72
|
+
ErrorType,
|
|
73
|
+
CollatorType,
|
|
74
|
+
array,
|
|
75
|
+
toString,
|
|
76
|
+
checkSubtype
|
|
77
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
|
|
3
|
+
const Color = require('../util/color');
|
|
4
|
+
const { Collator } = require('./definitions/collator');
|
|
5
|
+
const {
|
|
6
|
+
NullType,
|
|
7
|
+
NumberType,
|
|
8
|
+
StringType,
|
|
9
|
+
BooleanType,
|
|
10
|
+
ColorType,
|
|
11
|
+
ObjectType,
|
|
12
|
+
ValueType,
|
|
13
|
+
CollatorType,
|
|
14
|
+
array
|
|
15
|
+
} = require('./types');
|
|
16
|
+
|
|
17
|
+
function validateRGBA(r, g, b, a) {
|
|
18
|
+
if (
|
|
19
|
+
!(
|
|
20
|
+
typeof r === 'number' &&
|
|
21
|
+
r >= 0 &&
|
|
22
|
+
r <= 255 &&
|
|
23
|
+
typeof g === 'number' &&
|
|
24
|
+
g >= 0 &&
|
|
25
|
+
g <= 255 &&
|
|
26
|
+
typeof b === 'number' &&
|
|
27
|
+
b >= 0 &&
|
|
28
|
+
b <= 255
|
|
29
|
+
)
|
|
30
|
+
) {
|
|
31
|
+
const value = typeof a === 'number' ? [r, g, b, a] : [r, g, b];
|
|
32
|
+
return `Invalid rgba value [${value.join(', ')}]: 'r', 'g', and 'b' must be between 0 and 255.`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!(typeof a === 'undefined' || (typeof a === 'number' && a >= 0 && a <= 1))) {
|
|
36
|
+
return `Invalid rgba value [${[r, g, b, a].join(', ')}]: 'a' must be between 0 and 1.`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isValue(mixed) {
|
|
43
|
+
if (mixed === null) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (typeof mixed === 'string') {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
if (typeof mixed === 'boolean') {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (typeof mixed === 'number') {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (mixed instanceof Color) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
if (mixed instanceof Collator) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(mixed)) {
|
|
62
|
+
for (const item of mixed) {
|
|
63
|
+
if (!isValue(item)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
if (typeof mixed === 'object') {
|
|
70
|
+
for (const key in mixed) {
|
|
71
|
+
if (!isValue(mixed[key])) {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function typeOf(value) {
|
|
81
|
+
if (value === null) {
|
|
82
|
+
return NullType;
|
|
83
|
+
}
|
|
84
|
+
if (typeof value === 'string') {
|
|
85
|
+
return StringType;
|
|
86
|
+
}
|
|
87
|
+
if (typeof value === 'boolean') {
|
|
88
|
+
return BooleanType;
|
|
89
|
+
}
|
|
90
|
+
if (typeof value === 'number') {
|
|
91
|
+
return NumberType;
|
|
92
|
+
}
|
|
93
|
+
if (value instanceof Color) {
|
|
94
|
+
return ColorType;
|
|
95
|
+
}
|
|
96
|
+
if (value instanceof Collator) {
|
|
97
|
+
return CollatorType;
|
|
98
|
+
}
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
const length = value.length;
|
|
101
|
+
let itemType;
|
|
102
|
+
|
|
103
|
+
for (const item of value) {
|
|
104
|
+
const t = typeOf(item);
|
|
105
|
+
if (!itemType) {
|
|
106
|
+
itemType = t;
|
|
107
|
+
} else if (itemType === t) {
|
|
108
|
+
} else {
|
|
109
|
+
itemType = ValueType;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return array(itemType || ValueType, length);
|
|
115
|
+
}
|
|
116
|
+
assert(typeof value === 'object');
|
|
117
|
+
return ObjectType;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = {
|
|
121
|
+
Color,
|
|
122
|
+
Collator,
|
|
123
|
+
validateRGBA,
|
|
124
|
+
isValue,
|
|
125
|
+
typeOf
|
|
126
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
## Filter
|
|
2
|
+
|
|
3
|
+
Filter expressions are used to target specific data in a layer. This library implements the semantics specified by the [Mapbox GL JS spec](https://www.mapbox.com/mapbox-gl-style-spec/#filter).
|
|
4
|
+
|
|
5
|
+
### API
|
|
6
|
+
|
|
7
|
+
`featureFilter(filter)`
|
|
8
|
+
|
|
9
|
+
Given a filter expressed as nested arrays, return a new function
|
|
10
|
+
that evaluates whether a given feature (with a .properties or .tags property)
|
|
11
|
+
passes its test.
|
|
12
|
+
|
|
13
|
+
#### Parameters
|
|
14
|
+
|
|
15
|
+
| parameter | type | description |
|
|
16
|
+
| --------- | ----- | ---------------- |
|
|
17
|
+
| `filter` | Array | mapbox gl filter |
|
|
18
|
+
|
|
19
|
+
**Returns** `Function`, filter-evaluating function
|
|
20
|
+
|
|
21
|
+
### Usage
|
|
22
|
+
|
|
23
|
+
``` javascript
|
|
24
|
+
var ff = require('feature-filter');
|
|
25
|
+
|
|
26
|
+
// will match a feature with class of street_limited,
|
|
27
|
+
// AND an admin_level less than or equal to 3,
|
|
28
|
+
// that's NOT a polygon.
|
|
29
|
+
var filter = [
|
|
30
|
+
"all",
|
|
31
|
+
["==", "class", "street_limited"],
|
|
32
|
+
["<=", "admin_level", 3],
|
|
33
|
+
["!=", "$type", "Polygon"]
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
// will match a feature that has a class of
|
|
37
|
+
// wetland OR wetland_noveg.
|
|
38
|
+
// ["in", "class", "wetland", "wetland_noveg"]
|
|
39
|
+
|
|
40
|
+
// testFilter will be a function that returns a boolean
|
|
41
|
+
var testFilter = ff(filter);
|
|
42
|
+
|
|
43
|
+
// Layer feature that you're testing. Must have type
|
|
44
|
+
// and properties keys.
|
|
45
|
+
var feature = {
|
|
46
|
+
type: 2,
|
|
47
|
+
properties: {
|
|
48
|
+
class: "street_limited",
|
|
49
|
+
admin_level: 1
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// will return a boolean based on whether the feature matched the filter
|
|
54
|
+
return testFilter({zoom: 0}, feature);
|
|
55
|
+
```
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
const { createExpression } = require('../expression');
|
|
2
|
+
|
|
3
|
+
module.exports = createFilter;
|
|
4
|
+
|
|
5
|
+
createFilter.isExpressionFilter = isExpressionFilter;
|
|
6
|
+
|
|
7
|
+
function isExpressionFilter(filter) {
|
|
8
|
+
if (!Array.isArray(filter) || filter.length === 0) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
switch (filter[0]) {
|
|
12
|
+
case 'has':
|
|
13
|
+
return filter.length >= 2 && filter[1] !== '$id' && filter[1] !== '$type';
|
|
14
|
+
|
|
15
|
+
case 'in':
|
|
16
|
+
case '!in':
|
|
17
|
+
case '!has':
|
|
18
|
+
case 'none':
|
|
19
|
+
return false;
|
|
20
|
+
|
|
21
|
+
case '==':
|
|
22
|
+
case '!=':
|
|
23
|
+
case '>':
|
|
24
|
+
case '>=':
|
|
25
|
+
case '<':
|
|
26
|
+
case '<=':
|
|
27
|
+
return filter.length === 3 && (Array.isArray(filter[1]) || Array.isArray(filter[2]));
|
|
28
|
+
|
|
29
|
+
case 'any':
|
|
30
|
+
case 'all':
|
|
31
|
+
for (const f of filter.slice(1)) {
|
|
32
|
+
if (!isExpressionFilter(f) && typeof f !== 'boolean') {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
|
|
38
|
+
default:
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const filterSpec = {
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
default: false,
|
|
46
|
+
transition: false,
|
|
47
|
+
'property-type': 'data-driven',
|
|
48
|
+
expression: {
|
|
49
|
+
interpolated: false,
|
|
50
|
+
parameters: ['zoom', 'feature']
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Given a filter expressed as nested arrays, return a new function
|
|
56
|
+
* that evaluates whether a given feature (with a .properties or .tags property)
|
|
57
|
+
* passes its test.
|
|
58
|
+
*
|
|
59
|
+
* @private
|
|
60
|
+
* @param {Array} filter mapbox gl filter
|
|
61
|
+
* @returns {Function} filter-evaluating function
|
|
62
|
+
*/
|
|
63
|
+
function createFilter(filter) {
|
|
64
|
+
if (!filter) {
|
|
65
|
+
return () => true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!isExpressionFilter(filter)) {
|
|
69
|
+
filter = convertFilter(filter);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const compiled = createExpression(filter, filterSpec);
|
|
73
|
+
if (compiled.result === 'error') {
|
|
74
|
+
throw new Error(compiled.value.map(err => `${err.key}: ${err.message}`).join(', '));
|
|
75
|
+
}
|
|
76
|
+
return (globalProperties, feature) => compiled.value.evaluate(globalProperties, feature);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Comparison function to sort numbers and strings
|
|
80
|
+
function compare(a, b) {
|
|
81
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function convertFilter(filter) {
|
|
85
|
+
if (!filter) return true;
|
|
86
|
+
const op = filter[0];
|
|
87
|
+
if (filter.length <= 1) return op !== 'any';
|
|
88
|
+
const converted =
|
|
89
|
+
op === '=='
|
|
90
|
+
? convertComparisonOp(filter[1], filter[2], '==')
|
|
91
|
+
: op === '!='
|
|
92
|
+
? convertNegation(convertComparisonOp(filter[1], filter[2], '=='))
|
|
93
|
+
: op === '<' || op === '>' || op === '<=' || op === '>='
|
|
94
|
+
? convertComparisonOp(filter[1], filter[2], op)
|
|
95
|
+
: op === 'any'
|
|
96
|
+
? convertDisjunctionOp(filter.slice(1))
|
|
97
|
+
: op === 'all'
|
|
98
|
+
? ['all'].concat(filter.slice(1).map(convertFilter))
|
|
99
|
+
: op === 'none'
|
|
100
|
+
? ['all'].concat(filter.slice(1).map(convertFilter).map(convertNegation))
|
|
101
|
+
: op === 'in'
|
|
102
|
+
? convertInOp(filter[1], filter.slice(2))
|
|
103
|
+
: op === '!in'
|
|
104
|
+
? convertNegation(convertInOp(filter[1], filter.slice(2)))
|
|
105
|
+
: op === 'has'
|
|
106
|
+
? convertHasOp(filter[1])
|
|
107
|
+
: op === '!has'
|
|
108
|
+
? convertNegation(convertHasOp(filter[1]))
|
|
109
|
+
: true;
|
|
110
|
+
return converted;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function convertComparisonOp(property, value, op) {
|
|
114
|
+
switch (property) {
|
|
115
|
+
case '$type':
|
|
116
|
+
return [`filter-type-${op}`, value];
|
|
117
|
+
case '$id':
|
|
118
|
+
return [`filter-id-${op}`, value];
|
|
119
|
+
default:
|
|
120
|
+
return [`filter-${op}`, property, value];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function convertDisjunctionOp(filters) {
|
|
125
|
+
return ['any'].concat(filters.map(convertFilter));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function convertInOp(property, values) {
|
|
129
|
+
if (values.length === 0) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
switch (property) {
|
|
133
|
+
case '$type':
|
|
134
|
+
return ['filter-type-in', ['literal', values]];
|
|
135
|
+
case '$id':
|
|
136
|
+
return ['filter-id-in', ['literal', values]];
|
|
137
|
+
default:
|
|
138
|
+
if (values.length > 200 && !values.some(v => typeof v !== typeof values[0])) {
|
|
139
|
+
return ['filter-in-large', property, ['literal', values.sort(compare)]];
|
|
140
|
+
}
|
|
141
|
+
return ['filter-in-small', property, ['literal', values]];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function convertHasOp(property) {
|
|
146
|
+
switch (property) {
|
|
147
|
+
case '$type':
|
|
148
|
+
return true;
|
|
149
|
+
case '$id':
|
|
150
|
+
return ['filter-has-id'];
|
|
151
|
+
default:
|
|
152
|
+
return ['filter-has', property];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function convertNegation(filter) {
|
|
157
|
+
return ['!', filter];
|
|
158
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
|
|
3
|
+
module.exports = convertFunction;
|
|
4
|
+
|
|
5
|
+
function convertFunction(parameters, propertySpec) {
|
|
6
|
+
let expression;
|
|
7
|
+
|
|
8
|
+
parameters = { ...parameters };
|
|
9
|
+
let defaultExpression;
|
|
10
|
+
if (typeof parameters.default !== 'undefined') {
|
|
11
|
+
defaultExpression = convertValue(parameters.default, propertySpec);
|
|
12
|
+
} else {
|
|
13
|
+
defaultExpression = convertValue(propertySpec.default, propertySpec);
|
|
14
|
+
if (defaultExpression === null) {
|
|
15
|
+
defaultExpression = ['error', 'No default property value available.'];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (parameters.stops) {
|
|
20
|
+
const zoomAndFeatureDependent = parameters.stops && typeof parameters.stops[0][0] === 'object';
|
|
21
|
+
const featureDependent = zoomAndFeatureDependent || parameters.property !== undefined;
|
|
22
|
+
const zoomDependent = zoomAndFeatureDependent || !featureDependent;
|
|
23
|
+
|
|
24
|
+
const stops = parameters.stops.map(stop => {
|
|
25
|
+
if (!featureDependent && propertySpec.tokens && typeof stop[1] === 'string') {
|
|
26
|
+
return [stop[0], convertTokenString(stop[1])];
|
|
27
|
+
}
|
|
28
|
+
return [stop[0], convertValue(stop[1], propertySpec)];
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
if (parameters.colorSpace && parameters.colorSpace !== 'rgb') {
|
|
32
|
+
throw new Error('Unimplemented');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (zoomAndFeatureDependent) {
|
|
36
|
+
expression = convertZoomAndPropertyFunction(parameters, propertySpec, stops, defaultExpression);
|
|
37
|
+
} else if (zoomDependent) {
|
|
38
|
+
expression = convertZoomFunction(parameters, propertySpec, stops);
|
|
39
|
+
} else {
|
|
40
|
+
expression = convertPropertyFunction(parameters, propertySpec, stops, defaultExpression);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// identity function
|
|
44
|
+
expression = convertIdentityFunction(parameters, propertySpec, defaultExpression);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return expression;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function convertIdentityFunction(parameters, propertySpec, defaultExpression) {
|
|
51
|
+
const get = ['get', parameters.property];
|
|
52
|
+
|
|
53
|
+
if (propertySpec.type === 'color') {
|
|
54
|
+
return parameters.default === undefined ? get : ['to-color', get, parameters.default];
|
|
55
|
+
}
|
|
56
|
+
if (propertySpec.type === 'array' && typeof propertySpec.length === 'number') {
|
|
57
|
+
return ['array', propertySpec.value, propertySpec.length, get];
|
|
58
|
+
}
|
|
59
|
+
if (propertySpec.type === 'array') {
|
|
60
|
+
return ['array', propertySpec.value, get];
|
|
61
|
+
}
|
|
62
|
+
if (propertySpec.type === 'enum') {
|
|
63
|
+
return [
|
|
64
|
+
'let',
|
|
65
|
+
'property_value',
|
|
66
|
+
['string', get],
|
|
67
|
+
['match', ['var', 'property_value'], propertySpec.values, ['var', 'property_value'], defaultExpression]
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
return parameters.default === undefined ? get : [propertySpec.type, get, parameters.default];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function convertValue(value, spec) {
|
|
74
|
+
if (typeof value === 'undefined' || value === null) return null;
|
|
75
|
+
if (spec.type === 'color') {
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
if (spec.type === 'array') {
|
|
79
|
+
return ['literal', value];
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function convertZoomAndPropertyFunction(parameters, propertySpec, stops, defaultExpression) {
|
|
85
|
+
const featureFunctionParameters = {};
|
|
86
|
+
const featureFunctionStops = {};
|
|
87
|
+
const zoomStops = [];
|
|
88
|
+
for (let s = 0; s < stops.length; s++) {
|
|
89
|
+
const stop = stops[s];
|
|
90
|
+
const zoom = stop[0].zoom;
|
|
91
|
+
if (featureFunctionParameters[zoom] === undefined) {
|
|
92
|
+
featureFunctionParameters[zoom] = {
|
|
93
|
+
zoom: zoom,
|
|
94
|
+
type: parameters.type,
|
|
95
|
+
property: parameters.property,
|
|
96
|
+
default: parameters.default
|
|
97
|
+
};
|
|
98
|
+
featureFunctionStops[zoom] = [];
|
|
99
|
+
zoomStops.push(zoom);
|
|
100
|
+
}
|
|
101
|
+
featureFunctionStops[zoom].push([stop[0].value, stop[1]]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// the interpolation type for the zoom dimension of a zoom-and-property
|
|
105
|
+
// function is determined directly from the style property specification
|
|
106
|
+
// for which it's being used: linear for interpolatable properties, step
|
|
107
|
+
// otherwise.
|
|
108
|
+
const functionType = getFunctionType({}, propertySpec);
|
|
109
|
+
if (functionType === 'exponential') {
|
|
110
|
+
const expression = ['interpolate', ['linear'], ['zoom']];
|
|
111
|
+
|
|
112
|
+
for (const z of zoomStops) {
|
|
113
|
+
const output = convertPropertyFunction(
|
|
114
|
+
featureFunctionParameters[z],
|
|
115
|
+
propertySpec,
|
|
116
|
+
featureFunctionStops[z],
|
|
117
|
+
defaultExpression
|
|
118
|
+
);
|
|
119
|
+
appendStopPair(expression, z, output, false);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return expression;
|
|
123
|
+
}
|
|
124
|
+
const expression = ['step', ['zoom']];
|
|
125
|
+
|
|
126
|
+
for (const z of zoomStops) {
|
|
127
|
+
const output = convertPropertyFunction(
|
|
128
|
+
featureFunctionParameters[z],
|
|
129
|
+
propertySpec,
|
|
130
|
+
featureFunctionStops[z],
|
|
131
|
+
defaultExpression
|
|
132
|
+
);
|
|
133
|
+
appendStopPair(expression, z, output, true);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fixupDegenerateStepCurve(expression);
|
|
137
|
+
|
|
138
|
+
return expression;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function convertPropertyFunction(parameters, propertySpec, stops, defaultExpression) {
|
|
142
|
+
const type = getFunctionType(parameters, propertySpec);
|
|
143
|
+
|
|
144
|
+
let expression;
|
|
145
|
+
let isStep = false;
|
|
146
|
+
if (type === 'categorical' && typeof stops[0][0] === 'boolean') {
|
|
147
|
+
assert(parameters.stops.length > 0 && parameters.stops.length <= 2);
|
|
148
|
+
expression = ['case'];
|
|
149
|
+
for (const stop of stops) {
|
|
150
|
+
expression.push(['==', ['get', parameters.property], stop[0]], stop[1]);
|
|
151
|
+
}
|
|
152
|
+
expression.push(defaultExpression);
|
|
153
|
+
return expression;
|
|
154
|
+
}
|
|
155
|
+
if (type === 'categorical') {
|
|
156
|
+
expression = ['match', ['get', parameters.property]];
|
|
157
|
+
} else if (type === 'interval') {
|
|
158
|
+
expression = ['step', ['number', ['get', parameters.property]]];
|
|
159
|
+
isStep = true;
|
|
160
|
+
} else if (type === 'exponential') {
|
|
161
|
+
const base = parameters.base !== undefined ? parameters.base : 1;
|
|
162
|
+
expression = ['interpolate', ['exponential', base], ['number', ['get', parameters.property]]];
|
|
163
|
+
} else {
|
|
164
|
+
throw new Error(`Unknown property function type ${type}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
for (const stop of stops) {
|
|
168
|
+
appendStopPair(expression, stop[0], stop[1], isStep);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (expression[0] === 'match') {
|
|
172
|
+
expression.push(defaultExpression);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
fixupDegenerateStepCurve(expression);
|
|
176
|
+
|
|
177
|
+
return expression;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function convertZoomFunction(parameters, propertySpec, stops, input = ['zoom']) {
|
|
181
|
+
const type = getFunctionType(parameters, propertySpec);
|
|
182
|
+
let expression;
|
|
183
|
+
let isStep = false;
|
|
184
|
+
if (type === 'interval') {
|
|
185
|
+
expression = ['step', input];
|
|
186
|
+
isStep = true;
|
|
187
|
+
} else if (type === 'exponential') {
|
|
188
|
+
const base = parameters.base !== undefined ? parameters.base : 1;
|
|
189
|
+
expression = ['interpolate', ['exponential', base], input];
|
|
190
|
+
} else {
|
|
191
|
+
throw new Error(`Unknown zoom function type "${type}"`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for (const stop of stops) {
|
|
195
|
+
appendStopPair(expression, stop[0], stop[1], isStep);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
fixupDegenerateStepCurve(expression);
|
|
199
|
+
|
|
200
|
+
return expression;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function fixupDegenerateStepCurve(expression) {
|
|
204
|
+
// degenerate step curve (i.e. a constant function): add a noop stop
|
|
205
|
+
if (expression[0] === 'step' && expression.length === 3) {
|
|
206
|
+
expression.push(0);
|
|
207
|
+
expression.push(expression[3]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function appendStopPair(curve, input, output, isStep) {
|
|
212
|
+
// Skip duplicate stop values. They were not validated for functions, but they are for expressions.
|
|
213
|
+
// https://github.com/mapbox/mapbox-gl-js/issues/4107
|
|
214
|
+
if (curve.length > 3 && input === curve[curve.length - 2]) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
// step curves don't get the first input value, as it is redundant.
|
|
218
|
+
if (!(isStep && curve.length === 2)) {
|
|
219
|
+
curve.push(input);
|
|
220
|
+
}
|
|
221
|
+
curve.push(output);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function getFunctionType(parameters, propertySpec) {
|
|
225
|
+
if (parameters.type) {
|
|
226
|
+
return parameters.type;
|
|
227
|
+
}
|
|
228
|
+
assert(propertySpec.expression);
|
|
229
|
+
return propertySpec.expression.interpolated ? 'exponential' : 'interval';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// "String with {name} token" => ["concat", "String with ", ["get", "name"], " token"]
|
|
233
|
+
function convertTokenString(s) {
|
|
234
|
+
const result = ['concat'];
|
|
235
|
+
const re = /{([^{}]+)}/g;
|
|
236
|
+
let pos = 0;
|
|
237
|
+
let match;
|
|
238
|
+
while ((match = re.exec(s)) !== null) {
|
|
239
|
+
const literal = s.slice(pos, re.lastIndex - match[0].length);
|
|
240
|
+
pos = re.lastIndex;
|
|
241
|
+
if (literal.length > 0) result.push(literal);
|
|
242
|
+
result.push(['to-string', ['get', match[1]]]);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (result.length === 1) {
|
|
246
|
+
return s;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (pos < s.length) {
|
|
250
|
+
result.push(s.slice(pos));
|
|
251
|
+
} else if (result.length === 2) {
|
|
252
|
+
return result[1];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return result;
|
|
256
|
+
}
|