@scoova/mgl 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +116 -0
- package/README.md +174 -0
- package/build/banner.ts +12 -0
- package/build/bump-version-changelog.js +26 -0
- package/build/check-bundle-size.js +77 -0
- package/build/generate-dist-package.js +26 -0
- package/build/generate-doc-images.ts +78 -0
- package/build/generate-docs.ts +190 -0
- package/build/generate-shaders.ts +68 -0
- package/build/generate-struct-arrays.ts +438 -0
- package/build/generate-style-code.ts +283 -0
- package/build/readme.md +56 -0
- package/build/release-notes.js +45 -0
- package/build/rollup/bundle_prelude.js +29 -0
- package/build/rollup/maplibregl.js +22 -0
- package/build/rollup_plugins.ts +58 -0
- package/dist/LICENSE.txt +116 -0
- package/dist/maplibre-gl.css +1 -0
- package/dist/maplibre-gl.d.ts +13304 -0
- package/dist/maplibre-gl.js +59 -0
- package/dist/maplibre-gl.js.map +1 -0
- package/dist/package.json +1 -0
- package/package.json +192 -0
- package/src/css/maplibre-gl.css +854 -0
- package/src/css/svg/maplibregl-ctrl-attrib.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-compass.svg +4 -0
- package/src/css/svg/maplibregl-ctrl-fullscreen.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-geolocate.svg +5 -0
- package/src/css/svg/maplibregl-ctrl-logo.svg +11 -0
- package/src/css/svg/maplibregl-ctrl-shrink.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-terrain.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-zoom-in.svg +3 -0
- package/src/css/svg/maplibregl-ctrl-zoom-out.svg +3 -0
- package/src/data/array_types.g.ts +1130 -0
- package/src/data/bucket/circle_attributes.ts +8 -0
- package/src/data/bucket/circle_bucket.ts +197 -0
- package/src/data/bucket/fill_attributes.ts +8 -0
- package/src/data/bucket/fill_bucket.test.ts +95 -0
- package/src/data/bucket/fill_bucket.ts +228 -0
- package/src/data/bucket/fill_extrusion_attributes.ts +13 -0
- package/src/data/bucket/fill_extrusion_bucket.ts +305 -0
- package/src/data/bucket/heatmap_bucket.ts +12 -0
- package/src/data/bucket/line_attributes.ts +8 -0
- package/src/data/bucket/line_attributes_ext.ts +8 -0
- package/src/data/bucket/line_bucket.test.ts +142 -0
- package/src/data/bucket/line_bucket.ts +592 -0
- package/src/data/bucket/pattern_attributes.ts +9 -0
- package/src/data/bucket/pattern_bucket_features.ts +57 -0
- package/src/data/bucket/symbol_attributes.ts +122 -0
- package/src/data/bucket/symbol_bucket.test.ts +243 -0
- package/src/data/bucket/symbol_bucket.ts +975 -0
- package/src/data/bucket.ts +123 -0
- package/src/data/dem_data.test.ts +237 -0
- package/src/data/dem_data.ts +171 -0
- package/src/data/evaluation_feature.ts +18 -0
- package/src/data/extent.ts +13 -0
- package/src/data/feature_index.ts +337 -0
- package/src/data/feature_position_map.test.ts +33 -0
- package/src/data/feature_position_map.ts +126 -0
- package/src/data/index_array_type.ts +9 -0
- package/src/data/load_geometry.test.ts +49 -0
- package/src/data/load_geometry.ts +44 -0
- package/src/data/pos3d_attributes.ts +5 -0
- package/src/data/pos_attributes.ts +5 -0
- package/src/data/program_configuration.ts +735 -0
- package/src/data/raster_bounds_attributes.ts +6 -0
- package/src/data/segment.ts +89 -0
- package/src/geo/edge_insets.test.ts +83 -0
- package/src/geo/edge_insets.ts +146 -0
- package/src/geo/lng_lat.test.ts +65 -0
- package/src/geo/lng_lat.ts +169 -0
- package/src/geo/lng_lat_bounds.test.ts +357 -0
- package/src/geo/lng_lat_bounds.ts +356 -0
- package/src/geo/mercator_coordinate.test.ts +34 -0
- package/src/geo/mercator_coordinate.ts +157 -0
- package/src/geo/projection/projection.ts +72 -0
- package/src/geo/transform.test.ts +509 -0
- package/src/geo/transform.ts +1072 -0
- package/src/gl/color_mode.ts +31 -0
- package/src/gl/context.ts +321 -0
- package/src/gl/cull_face_mode.ts +22 -0
- package/src/gl/depth_mode.ts +26 -0
- package/src/gl/framebuffer.ts +48 -0
- package/src/gl/index_buffer.ts +55 -0
- package/src/gl/render_pool.test.ts +69 -0
- package/src/gl/render_pool.ts +93 -0
- package/src/gl/state.test.ts +125 -0
- package/src/gl/stencil_mode.ts +27 -0
- package/src/gl/types.ts +59 -0
- package/src/gl/value.ts +534 -0
- package/src/gl/vertex_buffer.test.ts +57 -0
- package/src/gl/vertex_buffer.ts +111 -0
- package/src/gl/webgl2.ts +12 -0
- package/src/index.test.ts +121 -0
- package/src/index.ts +250 -0
- package/src/render/draw_background.ts +53 -0
- package/src/render/draw_circle.ts +113 -0
- package/src/render/draw_collision_debug.ts +168 -0
- package/src/render/draw_custom.test.ts +73 -0
- package/src/render/draw_custom.ts +45 -0
- package/src/render/draw_debug.test.ts +122 -0
- package/src/render/draw_debug.ts +148 -0
- package/src/render/draw_fill.test.ts +137 -0
- package/src/render/draw_fill.ts +128 -0
- package/src/render/draw_fill_extrusion.ts +97 -0
- package/src/render/draw_heatmap.ts +228 -0
- package/src/render/draw_hillshade.ts +119 -0
- package/src/render/draw_line.ts +125 -0
- package/src/render/draw_raster.ts +133 -0
- package/src/render/draw_sky.ts +44 -0
- package/src/render/draw_symbol.test.ts +223 -0
- package/src/render/draw_symbol.ts +499 -0
- package/src/render/draw_terrain.ts +99 -0
- package/src/render/glyph_atlas.ts +83 -0
- package/src/render/glyph_manager.test.ts +147 -0
- package/src/render/glyph_manager.ts +198 -0
- package/src/render/image_atlas.ts +159 -0
- package/src/render/image_manager.ts +337 -0
- package/src/render/line_atlas.test.ts +38 -0
- package/src/render/line_atlas.ts +214 -0
- package/src/render/mesh.ts +25 -0
- package/src/render/painter.test.ts +51 -0
- package/src/render/painter.ts +666 -0
- package/src/render/program/background_program.ts +100 -0
- package/src/render/program/circle_program.ts +61 -0
- package/src/render/program/clipping_mask_program.ts +19 -0
- package/src/render/program/collision_program.ts +47 -0
- package/src/render/program/debug_program.ts +29 -0
- package/src/render/program/fill_extrusion_program.ts +120 -0
- package/src/render/program/fill_program.ts +121 -0
- package/src/render/program/heatmap_program.ts +76 -0
- package/src/render/program/hillshade_program.ts +116 -0
- package/src/render/program/line_program.ts +207 -0
- package/src/render/program/pattern.ts +102 -0
- package/src/render/program/program_uniforms.ts +46 -0
- package/src/render/program/raster_program.ts +88 -0
- package/src/render/program/sky_program.ts +28 -0
- package/src/render/program/symbol_program.ts +266 -0
- package/src/render/program/terrain_program.ts +116 -0
- package/src/render/program.ts +233 -0
- package/src/render/render_to_texture.test.ts +151 -0
- package/src/render/render_to_texture.ts +197 -0
- package/src/render/terrain.test.ts +322 -0
- package/src/render/terrain.ts +464 -0
- package/src/render/texture.ts +114 -0
- package/src/render/uniform_binding.test.ts +122 -0
- package/src/render/uniform_binding.ts +157 -0
- package/src/render/update_pattern_positions_in_program.test.ts +74 -0
- package/src/render/update_pattern_positions_in_program.ts +50 -0
- package/src/render/vertex_array_object.ts +163 -0
- package/src/shaders/README.md +42 -0
- package/src/shaders/_prelude.fragment.glsl +19 -0
- package/src/shaders/_prelude.fragment.glsl.g.ts +2 -0
- package/src/shaders/_prelude.vertex.glsl +148 -0
- package/src/shaders/_prelude.vertex.glsl.g.ts +2 -0
- package/src/shaders/background.fragment.glsl +10 -0
- package/src/shaders/background.fragment.glsl.g.ts +2 -0
- package/src/shaders/background.vertex.glsl +7 -0
- package/src/shaders/background.vertex.glsl.g.ts +2 -0
- package/src/shaders/background_pattern.fragment.glsl +28 -0
- package/src/shaders/background_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/background_pattern.vertex.glsl +19 -0
- package/src/shaders/background_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/circle.fragment.glsl +34 -0
- package/src/shaders/circle.fragment.glsl.g.ts +2 -0
- package/src/shaders/circle.vertex.glsl +68 -0
- package/src/shaders/circle.vertex.glsl.g.ts +2 -0
- package/src/shaders/clipping_mask.fragment.glsl +3 -0
- package/src/shaders/clipping_mask.fragment.glsl.g.ts +2 -0
- package/src/shaders/clipping_mask.vertex.glsl +7 -0
- package/src/shaders/clipping_mask.vertex.glsl.g.ts +2 -0
- package/src/shaders/collision_box.fragment.glsl +20 -0
- package/src/shaders/collision_box.fragment.glsl.g.ts +2 -0
- package/src/shaders/collision_box.vertex.glsl +27 -0
- package/src/shaders/collision_box.vertex.glsl.g.ts +2 -0
- package/src/shaders/collision_circle.fragment.glsl +17 -0
- package/src/shaders/collision_circle.fragment.glsl.g.ts +2 -0
- package/src/shaders/collision_circle.vertex.glsl +59 -0
- package/src/shaders/collision_circle.vertex.glsl.g.ts +2 -0
- package/src/shaders/debug.fragment.glsl +9 -0
- package/src/shaders/debug.fragment.glsl.g.ts +2 -0
- package/src/shaders/debug.vertex.glsl +12 -0
- package/src/shaders/debug.vertex.glsl.g.ts +2 -0
- package/src/shaders/encode_attribute.test.ts +11 -0
- package/src/shaders/encode_attribute.ts +13 -0
- package/src/shaders/fill.fragment.glsl +13 -0
- package/src/shaders/fill.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill.vertex.glsl +13 -0
- package/src/shaders/fill.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion.fragment.glsl +9 -0
- package/src/shaders/fill_extrusion.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion.vertex.glsl +84 -0
- package/src/shaders/fill_extrusion.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion_pattern.fragment.glsl +47 -0
- package/src/shaders/fill_extrusion_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_extrusion_pattern.vertex.glsl +96 -0
- package/src/shaders/fill_extrusion_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_outline.fragment.glsl +17 -0
- package/src/shaders/fill_outline.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_outline.vertex.glsl +17 -0
- package/src/shaders/fill_outline.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
- package/src/shaders/fill_outline_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_outline_pattern.vertex.glsl +44 -0
- package/src/shaders/fill_outline_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/fill_pattern.fragment.glsl +39 -0
- package/src/shaders/fill_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/fill_pattern.vertex.glsl +39 -0
- package/src/shaders/fill_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/heatmap.fragment.glsl +22 -0
- package/src/shaders/heatmap.fragment.glsl.g.ts +2 -0
- package/src/shaders/heatmap.vertex.glsl +54 -0
- package/src/shaders/heatmap.vertex.glsl.g.ts +2 -0
- package/src/shaders/heatmap_texture.fragment.glsl +15 -0
- package/src/shaders/heatmap_texture.fragment.glsl.g.ts +2 -0
- package/src/shaders/heatmap_texture.vertex.glsl +11 -0
- package/src/shaders/heatmap_texture.vertex.glsl.g.ts +2 -0
- package/src/shaders/hillshade.fragment.glsl +52 -0
- package/src/shaders/hillshade.fragment.glsl.g.ts +2 -0
- package/src/shaders/hillshade.vertex.glsl +11 -0
- package/src/shaders/hillshade.vertex.glsl.g.ts +2 -0
- package/src/shaders/hillshade_prepare.fragment.glsl +77 -0
- package/src/shaders/hillshade_prepare.fragment.glsl.g.ts +2 -0
- package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
- package/src/shaders/hillshade_prepare.vertex.glsl.g.ts +2 -0
- package/src/shaders/line.fragment.glsl +30 -0
- package/src/shaders/line.fragment.glsl.g.ts +2 -0
- package/src/shaders/line.vertex.glsl +89 -0
- package/src/shaders/line.vertex.glsl.g.ts +2 -0
- package/src/shaders/line_gradient.fragment.glsl +34 -0
- package/src/shaders/line_gradient.fragment.glsl.g.ts +2 -0
- package/src/shaders/line_gradient.vertex.glsl +92 -0
- package/src/shaders/line_gradient.vertex.glsl.g.ts +2 -0
- package/src/shaders/line_pattern.fragment.glsl +77 -0
- package/src/shaders/line_pattern.fragment.glsl.g.ts +2 -0
- package/src/shaders/line_pattern.vertex.glsl +103 -0
- package/src/shaders/line_pattern.vertex.glsl.g.ts +2 -0
- package/src/shaders/line_sdf.fragment.glsl +45 -0
- package/src/shaders/line_sdf.fragment.glsl.g.ts +2 -0
- package/src/shaders/line_sdf.vertex.glsl +101 -0
- package/src/shaders/line_sdf.vertex.glsl.g.ts +2 -0
- package/src/shaders/raster.fragment.glsl +53 -0
- package/src/shaders/raster.fragment.glsl.g.ts +2 -0
- package/src/shaders/raster.vertex.glsl +21 -0
- package/src/shaders/raster.vertex.glsl.g.ts +2 -0
- package/src/shaders/shaders.ts +197 -0
- package/src/shaders/sky.fragment.glsl +17 -0
- package/src/shaders/sky.fragment.glsl.g.ts +2 -0
- package/src/shaders/sky.vertex.glsl +5 -0
- package/src/shaders/sky.vertex.glsl.g.ts +2 -0
- package/src/shaders/symbol_icon.fragment.glsl +17 -0
- package/src/shaders/symbol_icon.fragment.glsl.g.ts +2 -0
- package/src/shaders/symbol_icon.vertex.glsl +117 -0
- package/src/shaders/symbol_icon.vertex.glsl.g.ts +2 -0
- package/src/shaders/symbol_sdf.fragment.glsl +58 -0
- package/src/shaders/symbol_sdf.fragment.glsl.g.ts +2 -0
- package/src/shaders/symbol_sdf.vertex.glsl +142 -0
- package/src/shaders/symbol_sdf.vertex.glsl.g.ts +2 -0
- package/src/shaders/symbol_text_and_icon.fragment.glsl +68 -0
- package/src/shaders/symbol_text_and_icon.fragment.glsl.g.ts +2 -0
- package/src/shaders/symbol_text_and_icon.vertex.glsl +140 -0
- package/src/shaders/symbol_text_and_icon.vertex.glsl.g.ts +2 -0
- package/src/shaders/terrain.fragment.glsl +32 -0
- package/src/shaders/terrain.fragment.glsl.g.ts +2 -0
- package/src/shaders/terrain.vertex.glsl +17 -0
- package/src/shaders/terrain.vertex.glsl.g.ts +2 -0
- package/src/shaders/terrain_coords.fragment.glsl +11 -0
- package/src/shaders/terrain_coords.fragment.glsl.g.ts +2 -0
- package/src/shaders/terrain_coords.vertex.glsl +13 -0
- package/src/shaders/terrain_coords.vertex.glsl.g.ts +2 -0
- package/src/shaders/terrain_depth.fragment.glsl +15 -0
- package/src/shaders/terrain_depth.fragment.glsl.g.ts +2 -0
- package/src/shaders/terrain_depth.vertex.glsl +13 -0
- package/src/shaders/terrain_depth.vertex.glsl.g.ts +2 -0
- package/src/source/canvas_source.test.ts +210 -0
- package/src/source/canvas_source.ts +227 -0
- package/src/source/geojson_source.test.ts +492 -0
- package/src/source/geojson_source.ts +431 -0
- package/src/source/geojson_source_diff.test.ts +364 -0
- package/src/source/geojson_source_diff.ts +172 -0
- package/src/source/geojson_worker_source.test.ts +399 -0
- package/src/source/geojson_worker_source.ts +303 -0
- package/src/source/geojson_wrapper.test.ts +32 -0
- package/src/source/geojson_wrapper.ts +81 -0
- package/src/source/image_source.test.ts +235 -0
- package/src/source/image_source.ts +338 -0
- package/src/source/load_tilejson.ts +47 -0
- package/src/source/pixels_to_tile_units.ts +25 -0
- package/src/source/protocol_crud.ts +48 -0
- package/src/source/query_features.test.ts +31 -0
- package/src/source/query_features.ts +252 -0
- package/src/source/raster_dem_tile_source.test.ts +158 -0
- package/src/source/raster_dem_tile_source.ts +166 -0
- package/src/source/raster_dem_tile_worker_source.test.ts +36 -0
- package/src/source/raster_dem_tile_worker_source.ts +38 -0
- package/src/source/raster_tile_source.test.ts +206 -0
- package/src/source/raster_tile_source.ts +227 -0
- package/src/source/rtl_text_plugin_main_thread.test.ts +170 -0
- package/src/source/rtl_text_plugin_main_thread.ts +89 -0
- package/src/source/rtl_text_plugin_status.ts +33 -0
- package/src/source/rtl_text_plugin_worker.ts +49 -0
- package/src/source/source.test.ts +41 -0
- package/src/source/source.ts +186 -0
- package/src/source/source_cache.test.ts +2069 -0
- package/src/source/source_cache.ts +1102 -0
- package/src/source/source_state.ts +157 -0
- package/src/source/terrain_source_cache.test.ts +105 -0
- package/src/source/terrain_source_cache.ts +204 -0
- package/src/source/tile.test.ts +290 -0
- package/src/source/tile.ts +478 -0
- package/src/source/tile_bounds.ts +34 -0
- package/src/source/tile_cache.test.ts +130 -0
- package/src/source/tile_cache.ts +208 -0
- package/src/source/tile_id.test.ts +112 -0
- package/src/source/tile_id.ts +221 -0
- package/src/source/vector_tile_source.test.ts +401 -0
- package/src/source/vector_tile_source.ts +283 -0
- package/src/source/vector_tile_worker_source.test.ts +396 -0
- package/src/source/vector_tile_worker_source.ts +199 -0
- package/src/source/video_source.test.ts +124 -0
- package/src/source/video_source.ts +204 -0
- package/src/source/worker.test.ts +233 -0
- package/src/source/worker.ts +301 -0
- package/src/source/worker_source.ts +117 -0
- package/src/source/worker_tile.test.ts +226 -0
- package/src/source/worker_tile.ts +208 -0
- package/src/style/create_style_layer.ts +39 -0
- package/src/style/evaluation_parameters.ts +62 -0
- package/src/style/format_section_override.test.ts +62 -0
- package/src/style/format_section_override.ts +50 -0
- package/src/style/light.test.ts +86 -0
- package/src/style/light.ts +135 -0
- package/src/style/load_glyph_range.test.ts +40 -0
- package/src/style/load_glyph_range.ts +32 -0
- package/src/style/load_sprite.test.ts +227 -0
- package/src/style/load_sprite.ts +71 -0
- package/src/style/parse_glyph_pbf.ts +42 -0
- package/src/style/pauseable_placement.ts +138 -0
- package/src/style/properties.ts +726 -0
- package/src/style/query_utils.test.ts +107 -0
- package/src/style/query_utils.ts +70 -0
- package/src/style/sky.ts +127 -0
- package/src/style/style.test.ts +2654 -0
- package/src/style/style.ts +1814 -0
- package/src/style/style_glyph.ts +25 -0
- package/src/style/style_image.ts +188 -0
- package/src/style/style_layer/background_style_layer.ts +17 -0
- package/src/style/style_layer/background_style_layer_properties.g.ts +40 -0
- package/src/style/style_layer/circle_style_layer.ts +98 -0
- package/src/style/style_layer/circle_style_layer_properties.g.ts +76 -0
- package/src/style/style_layer/custom_style_layer.ts +233 -0
- package/src/style/style_layer/fill_extrusion_style_layer.ts +224 -0
- package/src/style/style_layer/fill_extrusion_style_layer_properties.g.ts +55 -0
- package/src/style/style_layer/fill_style_layer.test.ts +37 -0
- package/src/style/style_layer/fill_style_layer.ts +65 -0
- package/src/style/style_layer/fill_style_layer_properties.g.ts +64 -0
- package/src/style/style_layer/heatmap_style_layer.ts +74 -0
- package/src/style/style_layer/heatmap_style_layer_properties.g.ts +46 -0
- package/src/style/style_layer/hillshade_style_layer.ts +21 -0
- package/src/style/style_layer/hillshade_style_layer_properties.g.ts +49 -0
- package/src/style/style_layer/line_style_layer.test.ts +50 -0
- package/src/style/style_layer/line_style_layer.ts +131 -0
- package/src/style/style_layer/line_style_layer_properties.g.ts +88 -0
- package/src/style/style_layer/overlap_mode.test.ts +57 -0
- package/src/style/style_layer/overlap_mode.ts +25 -0
- package/src/style/style_layer/raster_style_layer.ts +17 -0
- package/src/style/style_layer/raster_style_layer_properties.g.ts +55 -0
- package/src/style/style_layer/symbol_style_layer.ts +195 -0
- package/src/style/style_layer/symbol_style_layer_properties.g.ts +218 -0
- package/src/style/style_layer/typed_style_layer.ts +9 -0
- package/src/style/style_layer/variable_text_anchor.test.ts +117 -0
- package/src/style/style_layer/variable_text_anchor.ts +163 -0
- package/src/style/style_layer.test.ts +372 -0
- package/src/style/style_layer.ts +287 -0
- package/src/style/style_layer_index.test.ts +99 -0
- package/src/style/style_layer_index.ts +78 -0
- package/src/style/validate_style.ts +53 -0
- package/src/style/zoom_history.ts +40 -0
- package/src/symbol/anchor.test.ts +14 -0
- package/src/symbol/anchor.ts +22 -0
- package/src/symbol/check_max_angle.test.ts +54 -0
- package/src/symbol/check_max_angle.ts +76 -0
- package/src/symbol/clip_line.test.ts +154 -0
- package/src/symbol/clip_line.ts +66 -0
- package/src/symbol/collision_feature.test.ts +98 -0
- package/src/symbol/collision_feature.ts +114 -0
- package/src/symbol/collision_index.test.ts +19 -0
- package/src/symbol/collision_index.ts +618 -0
- package/src/symbol/cross_tile_symbol_index.test.ts +260 -0
- package/src/symbol/cross_tile_symbol_index.ts +367 -0
- package/src/symbol/get_anchors.test.ts +113 -0
- package/src/symbol/get_anchors.ts +167 -0
- package/src/symbol/grid_index.test.ts +75 -0
- package/src/symbol/grid_index.ts +414 -0
- package/src/symbol/merge_lines.test.ts +30 -0
- package/src/symbol/merge_lines.ts +80 -0
- package/src/symbol/one_em.ts +3 -0
- package/src/symbol/opacity_state.ts +23 -0
- package/src/symbol/path_interpolator.test.ts +134 -0
- package/src/symbol/path_interpolator.ts +55 -0
- package/src/symbol/placement.ts +1371 -0
- package/src/symbol/projection.test.ts +171 -0
- package/src/symbol/projection.ts +833 -0
- package/src/symbol/quads.test.ts +157 -0
- package/src/symbol/quads.ts +349 -0
- package/src/symbol/shaping.test.ts +360 -0
- package/src/symbol/shaping.ts +911 -0
- package/src/symbol/symbol_layout.ts +739 -0
- package/src/symbol/symbol_size.ts +129 -0
- package/src/symbol/symbol_style_layer.test.ts +103 -0
- package/src/symbol/transform_text.ts +27 -0
- package/src/ui/anchor.ts +27 -0
- package/src/ui/camera.test.ts +2301 -0
- package/src/ui/camera.ts +1520 -0
- package/src/ui/control/attribution_control.test.ts +543 -0
- package/src/ui/control/attribution_control.ts +209 -0
- package/src/ui/control/control.ts +67 -0
- package/src/ui/control/fullscreen_control.test.ts +114 -0
- package/src/ui/control/fullscreen_control.ts +189 -0
- package/src/ui/control/geolocate_control.test.ts +619 -0
- package/src/ui/control/geolocate_control.ts +725 -0
- package/src/ui/control/logo_control.test.ts +88 -0
- package/src/ui/control/logo_control.ts +86 -0
- package/src/ui/control/navigation_control.test.ts +238 -0
- package/src/ui/control/navigation_control.ts +294 -0
- package/src/ui/control/scale_control.test.ts +52 -0
- package/src/ui/control/scale_control.ts +152 -0
- package/src/ui/control/terrain_control.test.ts +58 -0
- package/src/ui/control/terrain_control.ts +74 -0
- package/src/ui/default_locale.ts +25 -0
- package/src/ui/events.ts +758 -0
- package/src/ui/handler/box_zoom.test.ts +163 -0
- package/src/ui/handler/box_zoom.ts +171 -0
- package/src/ui/handler/click_zoom.ts +55 -0
- package/src/ui/handler/cooperative_gestures.test.ts +338 -0
- package/src/ui/handler/cooperative_gestures.ts +111 -0
- package/src/ui/handler/dblclick_zoom.test.ts +151 -0
- package/src/ui/handler/drag_handler.ts +174 -0
- package/src/ui/handler/drag_move_state_manager.ts +115 -0
- package/src/ui/handler/drag_pan.test.ts +487 -0
- package/src/ui/handler/drag_rotate.test.ts +859 -0
- package/src/ui/handler/handler_util.ts +10 -0
- package/src/ui/handler/keyboard.test.ts +235 -0
- package/src/ui/handler/keyboard.ts +212 -0
- package/src/ui/handler/map_event.test.ts +158 -0
- package/src/ui/handler/map_event.ts +161 -0
- package/src/ui/handler/mouse.ts +92 -0
- package/src/ui/handler/mouse_handler_interface.test.ts +111 -0
- package/src/ui/handler/mouse_rotate.test.ts +62 -0
- package/src/ui/handler/one_finger_touch_drag.ts +45 -0
- package/src/ui/handler/one_finger_touch_drag_handler_interface.test.ts +77 -0
- package/src/ui/handler/scroll_zoom.test.ts +382 -0
- package/src/ui/handler/scroll_zoom.ts +379 -0
- package/src/ui/handler/shim/dblclick_zoom.ts +64 -0
- package/src/ui/handler/shim/drag_pan.ts +104 -0
- package/src/ui/handler/shim/drag_rotate.ts +76 -0
- package/src/ui/handler/shim/two_fingers_touch.ts +112 -0
- package/src/ui/handler/tap_drag_zoom.test.ts +113 -0
- package/src/ui/handler/tap_drag_zoom.ts +112 -0
- package/src/ui/handler/tap_recognizer.ts +138 -0
- package/src/ui/handler/tap_zoom.ts +98 -0
- package/src/ui/handler/touch_pan.ts +115 -0
- package/src/ui/handler/transform-provider.ts +44 -0
- package/src/ui/handler/two_fingers_touch.test.ts +283 -0
- package/src/ui/handler/two_fingers_touch.ts +336 -0
- package/src/ui/handler_inertia.ts +157 -0
- package/src/ui/handler_manager.ts +637 -0
- package/src/ui/hash.test.ts +404 -0
- package/src/ui/hash.ts +153 -0
- package/src/ui/map.ts +3393 -0
- package/src/ui/map_tests/map_animation.test.ts +61 -0
- package/src/ui/map_tests/map_basic.test.ts +223 -0
- package/src/ui/map_tests/map_bounds.test.ts +123 -0
- package/src/ui/map_tests/map_calculate_camera_options.test.ts +113 -0
- package/src/ui/map_tests/map_canvas.test.ts +59 -0
- package/src/ui/map_tests/map_control.test.ts +61 -0
- package/src/ui/map_tests/map_disable_handlers.test.ts +38 -0
- package/src/ui/map_tests/map_events.test.ts +1001 -0
- package/src/ui/map_tests/map_feature_state.test.ts +421 -0
- package/src/ui/map_tests/map_images.test.ts +175 -0
- package/src/ui/map_tests/map_is_moving.test.ts +164 -0
- package/src/ui/map_tests/map_is_rotating.test.ts +62 -0
- package/src/ui/map_tests/map_is_zooming.test.ts +86 -0
- package/src/ui/map_tests/map_layer.test.ts +457 -0
- package/src/ui/map_tests/map_options.test.ts +64 -0
- package/src/ui/map_tests/map_pitch.test.ts +90 -0
- package/src/ui/map_tests/map_pixel_ratio.test.ts +75 -0
- package/src/ui/map_tests/map_query_rendered_features.test.ts +93 -0
- package/src/ui/map_tests/map_render.test.ts +90 -0
- package/src/ui/map_tests/map_request_render_frame.test.ts +51 -0
- package/src/ui/map_tests/map_resize.test.ts +120 -0
- package/src/ui/map_tests/map_style.test.ts +541 -0
- package/src/ui/map_tests/map_terrian.test.ts +104 -0
- package/src/ui/map_tests/map_webgl.test.ts +72 -0
- package/src/ui/map_tests/map_world_copies.test.ts +103 -0
- package/src/ui/map_tests/map_zoom.test.ts +95 -0
- package/src/ui/marker.test.ts +1149 -0
- package/src/ui/marker.ts +880 -0
- package/src/ui/popup.test.ts +827 -0
- package/src/ui/popup.ts +717 -0
- package/src/util/abort_error.ts +21 -0
- package/src/util/actor.test.ts +218 -0
- package/src/util/actor.ts +241 -0
- package/src/util/actor_messages.ts +149 -0
- package/src/util/ajax.test.ts +237 -0
- package/src/util/ajax.ts +297 -0
- package/src/util/browser.test.ts +23 -0
- package/src/util/browser.ts +63 -0
- package/src/util/color_ramp.test.ts +105 -0
- package/src/util/color_ramp.ts +56 -0
- package/src/util/config.ts +29 -0
- package/src/util/dictionary_coder.ts +23 -0
- package/src/util/dispatcher.test.ts +76 -0
- package/src/util/dispatcher.ts +78 -0
- package/src/util/dom.ts +135 -0
- package/src/util/evented.test.ts +231 -0
- package/src/util/evented.ts +178 -0
- package/src/util/find_pole_of_inaccessibility.test.ts +21 -0
- package/src/util/find_pole_of_inaccessibility.ts +130 -0
- package/src/util/geolocation_support.test.ts +43 -0
- package/src/util/geolocation_support.ts +23 -0
- package/src/util/global_worker_pool.ts +65 -0
- package/src/util/image.ts +150 -0
- package/src/util/image_request.test.ts +408 -0
- package/src/util/image_request.ts +246 -0
- package/src/util/intersection_tests.ts +206 -0
- package/src/util/is_char_in_unicode_block.test.ts +15 -0
- package/src/util/is_char_in_unicode_block.ts +345 -0
- package/src/util/offscreen_canvas_distorted.test.ts +13 -0
- package/src/util/offscreen_canvas_distorted.ts +39 -0
- package/src/util/offscreen_canvas_supported.ts +11 -0
- package/src/util/performance.ts +117 -0
- package/src/util/primitives.test.ts +140 -0
- package/src/util/primitives.ts +143 -0
- package/src/util/request_manager.ts +42 -0
- package/src/util/resolve_tokens.test.ts +45 -0
- package/src/util/resolve_tokens.ts +17 -0
- package/src/util/script_detection.test.ts +138 -0
- package/src/util/script_detection.ts +376 -0
- package/src/util/smart_wrap.test.ts +97 -0
- package/src/util/smart_wrap.ts +58 -0
- package/src/util/struct_array.test.ts +101 -0
- package/src/util/struct_array.ts +246 -0
- package/src/util/style.test.ts +34 -0
- package/src/util/style.ts +28 -0
- package/src/util/task_queue.test.ts +114 -0
- package/src/util/task_queue.ts +64 -0
- package/src/util/test/util.ts +185 -0
- package/src/util/throttle.test.ts +42 -0
- package/src/util/throttle.ts +28 -0
- package/src/util/throttled_invoker.ts +41 -0
- package/src/util/transferable_grid_index.test.ts +56 -0
- package/src/util/transferable_grid_index.ts +214 -0
- package/src/util/util.test.ts +414 -0
- package/src/util/util.ts +724 -0
- package/src/util/vectortile_to_geojson.ts +72 -0
- package/src/util/verticalize_punctuation.ts +110 -0
- package/src/util/web_worker.ts +16 -0
- package/src/util/web_worker_transfer.test.ts +153 -0
- package/src/util/web_worker_transfer.ts +254 -0
- package/src/util/webp_supported.ts +63 -0
- package/src/util/worker_pool.test.ts +43 -0
- package/src/util/worker_pool.ts +58 -0
- package/src/util/world_bounds.test.ts +59 -0
- package/src/util/world_bounds.ts +46 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import {CrossTileSymbolIndex, KDBUSH_THRESHHOLD} from './cross_tile_symbol_index';
|
|
2
|
+
import {OverscaledTileID} from '../source/tile_id';
|
|
3
|
+
import {StyleLayer} from '../style/style_layer';
|
|
4
|
+
|
|
5
|
+
const styleLayer = {
|
|
6
|
+
id: 'test'
|
|
7
|
+
} as StyleLayer;
|
|
8
|
+
|
|
9
|
+
const makeSymbolInstance = (x, y, key): any => {
|
|
10
|
+
return {
|
|
11
|
+
anchorX: x,
|
|
12
|
+
anchorY: y,
|
|
13
|
+
key
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const makeTile = (tileID, symbolInstances): any => {
|
|
18
|
+
const bucket = {
|
|
19
|
+
symbolInstances: {
|
|
20
|
+
get(i) { return symbolInstances[i]; },
|
|
21
|
+
length: symbolInstances.length
|
|
22
|
+
},
|
|
23
|
+
layerIds: ['test']
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
tileID,
|
|
27
|
+
getBucket: () => bucket,
|
|
28
|
+
latestFeatureIndex: {}
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
describe('CrossTileSymbolIndex.addLayer', () => {
|
|
33
|
+
|
|
34
|
+
test('matches ids', () => {
|
|
35
|
+
const index = new CrossTileSymbolIndex();
|
|
36
|
+
|
|
37
|
+
const mainID = new OverscaledTileID(6, 0, 6, 8, 8);
|
|
38
|
+
const mainInstances = [
|
|
39
|
+
makeSymbolInstance(1000, 1000, 'Detroit'),
|
|
40
|
+
makeSymbolInstance(2000, 2000, 'Toronto')
|
|
41
|
+
];
|
|
42
|
+
const mainTile = makeTile(mainID, mainInstances);
|
|
43
|
+
|
|
44
|
+
index.addLayer(styleLayer, [mainTile], 0);
|
|
45
|
+
// Assigned new IDs
|
|
46
|
+
expect(mainInstances[0].crossTileID).toBe(1);
|
|
47
|
+
expect(mainInstances[1].crossTileID).toBe(2);
|
|
48
|
+
|
|
49
|
+
const childID = new OverscaledTileID(7, 0, 7, 16, 16);
|
|
50
|
+
const childInstances = [
|
|
51
|
+
makeSymbolInstance(2000, 2000, 'Detroit'),
|
|
52
|
+
makeSymbolInstance(2000, 2000, 'Windsor'),
|
|
53
|
+
makeSymbolInstance(3000, 3000, 'Toronto'),
|
|
54
|
+
makeSymbolInstance(4001, 4001, 'Toronto')
|
|
55
|
+
];
|
|
56
|
+
const childTile = makeTile(childID, childInstances);
|
|
57
|
+
|
|
58
|
+
index.addLayer(styleLayer, [mainTile, childTile], 0);
|
|
59
|
+
// matched parent tile
|
|
60
|
+
expect(childInstances[0].crossTileID).toBe(1);
|
|
61
|
+
// does not match because of different key
|
|
62
|
+
expect(childInstances[1].crossTileID).toBe(3);
|
|
63
|
+
// does not match because of different location
|
|
64
|
+
expect(childInstances[2].crossTileID).toBe(4);
|
|
65
|
+
// matches with a slightly different location
|
|
66
|
+
expect(childInstances[3].crossTileID).toBe(2);
|
|
67
|
+
|
|
68
|
+
const parentID = new OverscaledTileID(5, 0, 5, 4, 4);
|
|
69
|
+
const parentInstances = [
|
|
70
|
+
makeSymbolInstance(500, 500, 'Detroit')
|
|
71
|
+
];
|
|
72
|
+
const parentTile = makeTile(parentID, parentInstances);
|
|
73
|
+
|
|
74
|
+
index.addLayer(styleLayer, [mainTile, childTile, parentTile], 0);
|
|
75
|
+
// matched child tile
|
|
76
|
+
expect(parentInstances[0].crossTileID).toBe(1);
|
|
77
|
+
|
|
78
|
+
const grandchildID = new OverscaledTileID(8, 0, 8, 32, 32);
|
|
79
|
+
const grandchildInstances = [
|
|
80
|
+
makeSymbolInstance(4000, 4000, 'Detroit'),
|
|
81
|
+
makeSymbolInstance(4000, 4000, 'Windsor')
|
|
82
|
+
];
|
|
83
|
+
const grandchildTile = makeTile(grandchildID, grandchildInstances);
|
|
84
|
+
|
|
85
|
+
index.addLayer(styleLayer, [mainTile], 0);
|
|
86
|
+
index.addLayer(styleLayer, [mainTile, grandchildTile], 0);
|
|
87
|
+
// Matches the symbol in `mainBucket`
|
|
88
|
+
expect(grandchildInstances[0].crossTileID).toBe(1);
|
|
89
|
+
// Does not match the previous value for Windsor because that tile was removed
|
|
90
|
+
expect(grandchildInstances[1].crossTileID).toBe(5);
|
|
91
|
+
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('overwrites ids when re-adding', () => {
|
|
95
|
+
const index = new CrossTileSymbolIndex();
|
|
96
|
+
|
|
97
|
+
const mainID = new OverscaledTileID(6, 0, 6, 8, 8);
|
|
98
|
+
const mainInstances = [makeSymbolInstance(1000, 1000, 'Detroit')];
|
|
99
|
+
const mainTile = makeTile(mainID, mainInstances);
|
|
100
|
+
|
|
101
|
+
const childID = new OverscaledTileID(7, 0, 7, 16, 16);
|
|
102
|
+
const childInstances = [makeSymbolInstance(2000, 2000, 'Detroit')];
|
|
103
|
+
const childTile = makeTile(childID, childInstances);
|
|
104
|
+
|
|
105
|
+
// assigns a new id
|
|
106
|
+
index.addLayer(styleLayer, [mainTile], 0);
|
|
107
|
+
expect(mainInstances[0].crossTileID).toBe(1);
|
|
108
|
+
|
|
109
|
+
// removes the tile
|
|
110
|
+
index.addLayer(styleLayer, [], 0);
|
|
111
|
+
|
|
112
|
+
// assigns a new id
|
|
113
|
+
index.addLayer(styleLayer, [childTile], 0);
|
|
114
|
+
expect(childInstances[0].crossTileID).toBe(2);
|
|
115
|
+
|
|
116
|
+
// overwrites the old id to match the already-added tile
|
|
117
|
+
index.addLayer(styleLayer, [mainTile, childTile], 0);
|
|
118
|
+
expect(mainInstances[0].crossTileID).toBe(2);
|
|
119
|
+
expect(childInstances[0].crossTileID).toBe(2);
|
|
120
|
+
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('does not duplicate ids within one zoom level', () => {
|
|
124
|
+
const index = new CrossTileSymbolIndex();
|
|
125
|
+
|
|
126
|
+
const mainID = new OverscaledTileID(6, 0, 6, 8, 8);
|
|
127
|
+
const mainInstances = [
|
|
128
|
+
makeSymbolInstance(1000, 1000, ''), // A
|
|
129
|
+
makeSymbolInstance(1000, 1000, '') // B
|
|
130
|
+
];
|
|
131
|
+
const mainTile = makeTile(mainID, mainInstances);
|
|
132
|
+
|
|
133
|
+
const childID = new OverscaledTileID(7, 0, 7, 16, 16);
|
|
134
|
+
const childInstances = [
|
|
135
|
+
makeSymbolInstance(2000, 2000, ''), // A'
|
|
136
|
+
makeSymbolInstance(2000, 2000, ''), // B'
|
|
137
|
+
makeSymbolInstance(2000, 2000, '') // C'
|
|
138
|
+
];
|
|
139
|
+
const childTile = makeTile(childID, childInstances);
|
|
140
|
+
|
|
141
|
+
// assigns new ids
|
|
142
|
+
index.addLayer(styleLayer, [mainTile], 0);
|
|
143
|
+
expect(mainInstances[0].crossTileID).toBe(1);
|
|
144
|
+
expect(mainInstances[1].crossTileID).toBe(2);
|
|
145
|
+
|
|
146
|
+
const layerIndex = index.layerIndexes[styleLayer.id];
|
|
147
|
+
expect(Object.keys(layerIndex.usedCrossTileIDs[6])).toEqual(['1', '2']);
|
|
148
|
+
|
|
149
|
+
// copies parent ids without duplicate ids in this tile
|
|
150
|
+
index.addLayer(styleLayer, [childTile], 0);
|
|
151
|
+
expect(childInstances[0].crossTileID).toBe(1); // A' copies from A
|
|
152
|
+
expect(childInstances[1].crossTileID).toBe(2); // B' copies from B
|
|
153
|
+
expect(childInstances[2].crossTileID).toBe(3); // C' gets new ID
|
|
154
|
+
|
|
155
|
+
// Updates per-zoom usedCrossTileIDs
|
|
156
|
+
expect(Object.keys(layerIndex.usedCrossTileIDs[6])).toEqual([]);
|
|
157
|
+
expect(Object.keys(layerIndex.usedCrossTileIDs[7])).toEqual(['1', '2', '3']);
|
|
158
|
+
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('does not regenerate ids for same zoom', () => {
|
|
162
|
+
const index = new CrossTileSymbolIndex();
|
|
163
|
+
|
|
164
|
+
const tileID = new OverscaledTileID(6, 0, 6, 8, 8);
|
|
165
|
+
const firstInstances = [
|
|
166
|
+
makeSymbolInstance(1000, 1000, ''), // A
|
|
167
|
+
makeSymbolInstance(1000, 1000, '') // B
|
|
168
|
+
];
|
|
169
|
+
const firstTile = makeTile(tileID, firstInstances);
|
|
170
|
+
|
|
171
|
+
const secondInstances = [
|
|
172
|
+
makeSymbolInstance(1000, 1000, ''), // A'
|
|
173
|
+
makeSymbolInstance(1000, 1000, ''), // B'
|
|
174
|
+
makeSymbolInstance(1000, 1000, ''), // C'
|
|
175
|
+
];
|
|
176
|
+
const secondTile = makeTile(tileID, secondInstances);
|
|
177
|
+
|
|
178
|
+
// assigns new ids
|
|
179
|
+
index.addLayer(styleLayer, [firstTile], 0);
|
|
180
|
+
expect(firstInstances[0].crossTileID).toBe(1);
|
|
181
|
+
expect(firstInstances[1].crossTileID).toBe(2);
|
|
182
|
+
|
|
183
|
+
const layerIndex = index.layerIndexes[styleLayer.id];
|
|
184
|
+
expect(Object.keys(layerIndex.usedCrossTileIDs[6])).toEqual(['1', '2']);
|
|
185
|
+
|
|
186
|
+
// uses same ids when tile gets updated
|
|
187
|
+
index.addLayer(styleLayer, [secondTile], 0);
|
|
188
|
+
expect(secondInstances[0].crossTileID).toBe(1); // A' copies from A
|
|
189
|
+
expect(secondInstances[1].crossTileID).toBe(2); // B' copies from B
|
|
190
|
+
expect(secondInstances[2].crossTileID).toBe(3); // C' gets new ID
|
|
191
|
+
|
|
192
|
+
expect(Object.keys(layerIndex.usedCrossTileIDs[6])).toEqual(['1', '2', '3']);
|
|
193
|
+
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test('reuses indexes when longitude is wrapped', () => {
|
|
197
|
+
const index = new CrossTileSymbolIndex();
|
|
198
|
+
const longitude = 370;
|
|
199
|
+
|
|
200
|
+
const tileID = new OverscaledTileID(6, 1, 6, 8, 8);
|
|
201
|
+
const firstInstances = [
|
|
202
|
+
makeSymbolInstance(1000, 1000, ''), // A
|
|
203
|
+
];
|
|
204
|
+
const tile = makeTile(tileID, firstInstances);
|
|
205
|
+
|
|
206
|
+
index.addLayer(styleLayer, [tile], longitude);
|
|
207
|
+
expect(firstInstances[0].crossTileID).toBe(1); // A
|
|
208
|
+
|
|
209
|
+
tile.tileID = tileID.wrapped();
|
|
210
|
+
|
|
211
|
+
index.addLayer(styleLayer, [tile], longitude % 360);
|
|
212
|
+
expect(firstInstances[0].crossTileID).toBe(1);
|
|
213
|
+
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test('indexes data for findMatches perf', () => {
|
|
217
|
+
const index = new CrossTileSymbolIndex();
|
|
218
|
+
|
|
219
|
+
const mainID = new OverscaledTileID(6, 0, 6, 8, 8);
|
|
220
|
+
const childID = new OverscaledTileID(7, 0, 7, 16, 16);
|
|
221
|
+
|
|
222
|
+
const mainInstances: any[] = [];
|
|
223
|
+
const childInstances: any[] = [];
|
|
224
|
+
|
|
225
|
+
for (let i = 0; i < KDBUSH_THRESHHOLD + 1; i++) {
|
|
226
|
+
mainInstances.push(makeSymbolInstance(0, 0, ''));
|
|
227
|
+
childInstances.push(makeSymbolInstance(0, 0, ''));
|
|
228
|
+
}
|
|
229
|
+
const mainTile = makeTile(mainID, mainInstances);
|
|
230
|
+
const childTile = makeTile(childID, childInstances);
|
|
231
|
+
index.addLayer(styleLayer, [mainTile], 0);
|
|
232
|
+
index.addLayer(styleLayer, [childTile], 0);
|
|
233
|
+
|
|
234
|
+
// check that we matched the parent tile
|
|
235
|
+
expect(childInstances[0].crossTileID).toBe(1);
|
|
236
|
+
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
describe('CrossTileSymbolIndex.pruneUnusedLayers', () => {
|
|
241
|
+
const index = new CrossTileSymbolIndex();
|
|
242
|
+
|
|
243
|
+
const tileID = new OverscaledTileID(6, 0, 6, 8, 8);
|
|
244
|
+
const instances = [
|
|
245
|
+
makeSymbolInstance(1000, 1000, ''), // A
|
|
246
|
+
makeSymbolInstance(1000, 1000, '') // B
|
|
247
|
+
];
|
|
248
|
+
const tile = makeTile(tileID, instances);
|
|
249
|
+
|
|
250
|
+
// assigns new ids
|
|
251
|
+
index.addLayer(styleLayer, [tile], 0);
|
|
252
|
+
expect(instances[0].crossTileID).toBe(1);
|
|
253
|
+
expect(instances[1].crossTileID).toBe(2);
|
|
254
|
+
expect(index.layerIndexes[styleLayer.id]).toBeTruthy();
|
|
255
|
+
|
|
256
|
+
// remove styleLayer
|
|
257
|
+
index.pruneUnusedLayers([]);
|
|
258
|
+
expect(index.layerIndexes[styleLayer.id]).toBeFalsy();
|
|
259
|
+
|
|
260
|
+
});
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import KDBush from 'kdbush';
|
|
2
|
+
import {EXTENT} from '../data/extent';
|
|
3
|
+
|
|
4
|
+
import {SymbolInstanceArray} from '../data/array_types.g';
|
|
5
|
+
|
|
6
|
+
import type {SymbolInstance} from '../data/array_types.g';
|
|
7
|
+
import type {OverscaledTileID} from '../source/tile_id';
|
|
8
|
+
import type {SymbolBucket} from '../data/bucket/symbol_bucket';
|
|
9
|
+
import type {StyleLayer} from '../style/style_layer';
|
|
10
|
+
import type {Tile} from '../source/tile';
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
The CrossTileSymbolIndex generally works on the assumption that
|
|
14
|
+
a conceptual "unique symbol" can be identified by the text of
|
|
15
|
+
the label combined with the anchor point. The goal is to assign
|
|
16
|
+
these conceptual "unique symbols" a shared crossTileID that can be
|
|
17
|
+
used by Placement to keep fading opacity states consistent and to
|
|
18
|
+
deduplicate labels.
|
|
19
|
+
|
|
20
|
+
The CrossTileSymbolIndex indexes all the current symbol instances and
|
|
21
|
+
their crossTileIDs. When a symbol bucket gets added or updated, the
|
|
22
|
+
index assigns a crossTileID to each of it's symbol instances by either
|
|
23
|
+
matching it with an existing id or assigning a new one.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
// Round anchor positions to roughly 4 pixel grid
|
|
27
|
+
const roundingFactor = 512 / EXTENT / 2;
|
|
28
|
+
|
|
29
|
+
export const KDBUSH_THRESHHOLD = 128;
|
|
30
|
+
|
|
31
|
+
interface SymbolsByKeyEntry {
|
|
32
|
+
index?: KDBush;
|
|
33
|
+
positions?: {x: number; y: number}[];
|
|
34
|
+
crossTileIDs: number[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class TileLayerIndex {
|
|
38
|
+
_symbolsByKey: Record<number, SymbolsByKeyEntry> = {};
|
|
39
|
+
|
|
40
|
+
constructor(public tileID: OverscaledTileID, symbolInstances: SymbolInstanceArray, public bucketInstanceId: number) {
|
|
41
|
+
// group the symbolInstances by key
|
|
42
|
+
const symbolInstancesByKey = new Map<number, SymbolInstance[]>();
|
|
43
|
+
for (let i = 0; i < symbolInstances.length; i++) {
|
|
44
|
+
const symbolInstance = symbolInstances.get(i);
|
|
45
|
+
const key = symbolInstance.key;
|
|
46
|
+
const instances = symbolInstancesByKey.get(key);
|
|
47
|
+
if (instances) {
|
|
48
|
+
// This tile may have multiple symbol instances with the same key
|
|
49
|
+
// Store each one along with its coordinates
|
|
50
|
+
instances.push(symbolInstance);
|
|
51
|
+
} else {
|
|
52
|
+
symbolInstancesByKey.set(key, [symbolInstance]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// index the SymbolInstances in this each bucket
|
|
57
|
+
for (const [key, symbols] of symbolInstancesByKey) {
|
|
58
|
+
const positions = symbols.map(symbolInstance => ({x: Math.floor(symbolInstance.anchorX * roundingFactor), y: Math.floor(symbolInstance.anchorY * roundingFactor)}));
|
|
59
|
+
const crossTileIDs = symbols.map(v => v.crossTileID);
|
|
60
|
+
const entry: SymbolsByKeyEntry = {positions, crossTileIDs};
|
|
61
|
+
|
|
62
|
+
// once we get too many symbols for a given key, it becomes much faster to index it before queries
|
|
63
|
+
if (entry.positions.length > KDBUSH_THRESHHOLD) {
|
|
64
|
+
|
|
65
|
+
const index = new KDBush(entry.positions.length, 16, Uint16Array);
|
|
66
|
+
for (const {x, y} of entry.positions) index.add(x, y);
|
|
67
|
+
index.finish();
|
|
68
|
+
|
|
69
|
+
// clear all references to the original positions data
|
|
70
|
+
delete entry.positions;
|
|
71
|
+
entry.index = index;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this._symbolsByKey[key] = entry;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Converts the coordinates of the input symbol instance into coordinates that be can compared
|
|
79
|
+
// against other symbols in this index. Coordinates are:
|
|
80
|
+
// (1) local-tile-based (so after correction we get x,y values relative to our local anchorX/Y)
|
|
81
|
+
// (2) converted to the z-scale of this TileLayerIndex
|
|
82
|
+
// (3) down-sampled by "roundingFactor" from tile coordinate precision in order to be
|
|
83
|
+
// more tolerant of small differences between tiles.
|
|
84
|
+
getScaledCoordinates(symbolInstance: SymbolInstance, childTileID: OverscaledTileID): {x: number; y: number} {
|
|
85
|
+
const {x: localX, y: localY, z: localZ} = this.tileID.canonical;
|
|
86
|
+
const {x, y, z} = childTileID.canonical;
|
|
87
|
+
|
|
88
|
+
const zDifference = z - localZ;
|
|
89
|
+
const scale = roundingFactor / Math.pow(2, zDifference);
|
|
90
|
+
const xWorld = (x * EXTENT + symbolInstance.anchorX) * scale;
|
|
91
|
+
const yWorld = (y * EXTENT + symbolInstance.anchorY) * scale;
|
|
92
|
+
const xOffset = localX * EXTENT * roundingFactor;
|
|
93
|
+
const yOffset = localY * EXTENT * roundingFactor;
|
|
94
|
+
const result = {
|
|
95
|
+
x: Math.floor(xWorld - xOffset),
|
|
96
|
+
y: Math.floor(yWorld - yOffset)
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
findMatches(symbolInstances: SymbolInstanceArray, newTileID: OverscaledTileID, zoomCrossTileIDs: {
|
|
103
|
+
[crossTileID: number]: boolean;
|
|
104
|
+
}) {
|
|
105
|
+
const tolerance = this.tileID.canonical.z < newTileID.canonical.z ? 1 : Math.pow(2, this.tileID.canonical.z - newTileID.canonical.z);
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < symbolInstances.length; i++) {
|
|
108
|
+
const symbolInstance = symbolInstances.get(i);
|
|
109
|
+
if (symbolInstance.crossTileID) {
|
|
110
|
+
// already has a match, skip
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const entry = this._symbolsByKey[symbolInstance.key];
|
|
115
|
+
if (!entry) {
|
|
116
|
+
// No symbol with this key in this bucket
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const scaledSymbolCoord = this.getScaledCoordinates(symbolInstance, newTileID);
|
|
121
|
+
|
|
122
|
+
if (entry.index) {
|
|
123
|
+
// Return any symbol with the same keys whose coordinates are within 1
|
|
124
|
+
// grid unit. (with a 4px grid, this covers a 12px by 12px area)
|
|
125
|
+
const indexes = entry.index.range(
|
|
126
|
+
scaledSymbolCoord.x - tolerance,
|
|
127
|
+
scaledSymbolCoord.y - tolerance,
|
|
128
|
+
scaledSymbolCoord.x + tolerance,
|
|
129
|
+
scaledSymbolCoord.y + tolerance).sort();
|
|
130
|
+
|
|
131
|
+
for (const i of indexes) {
|
|
132
|
+
const crossTileID = entry.crossTileIDs[i];
|
|
133
|
+
|
|
134
|
+
if (!zoomCrossTileIDs[crossTileID]) {
|
|
135
|
+
// Once we've marked ourselves duplicate against this parent symbol,
|
|
136
|
+
// don't let any other symbols at the same zoom level duplicate against
|
|
137
|
+
// the same parent (see issue #5993)
|
|
138
|
+
zoomCrossTileIDs[crossTileID] = true;
|
|
139
|
+
symbolInstance.crossTileID = crossTileID;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
} else if (entry.positions) {
|
|
144
|
+
for (let i = 0; i < entry.positions.length; i++) {
|
|
145
|
+
const thisTileSymbol = entry.positions[i];
|
|
146
|
+
const crossTileID = entry.crossTileIDs[i];
|
|
147
|
+
|
|
148
|
+
// Return any symbol with the same keys whose coordinates are within 1
|
|
149
|
+
// grid unit. (with a 4px grid, this covers a 12px by 12px area)
|
|
150
|
+
if (Math.abs(thisTileSymbol.x - scaledSymbolCoord.x) <= tolerance &&
|
|
151
|
+
Math.abs(thisTileSymbol.y - scaledSymbolCoord.y) <= tolerance &&
|
|
152
|
+
!zoomCrossTileIDs[crossTileID]) {
|
|
153
|
+
// Once we've marked ourselves duplicate against this parent symbol,
|
|
154
|
+
// don't let any other symbols at the same zoom level duplicate against
|
|
155
|
+
// the same parent (see issue #5993)
|
|
156
|
+
zoomCrossTileIDs[crossTileID] = true;
|
|
157
|
+
symbolInstance.crossTileID = crossTileID;
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
getCrossTileIDsLists() {
|
|
166
|
+
return Object.values(this._symbolsByKey).map(({crossTileIDs}) => crossTileIDs);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
class CrossTileIDs {
|
|
171
|
+
maxCrossTileID: number;
|
|
172
|
+
constructor() {
|
|
173
|
+
this.maxCrossTileID = 0;
|
|
174
|
+
}
|
|
175
|
+
generate() {
|
|
176
|
+
return ++this.maxCrossTileID;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
class CrossTileSymbolLayerIndex {
|
|
181
|
+
indexes: {
|
|
182
|
+
[zoom in string | number]: {
|
|
183
|
+
[tileId in string | number]: TileLayerIndex;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
usedCrossTileIDs: {
|
|
187
|
+
[zoom in string | number]: {
|
|
188
|
+
[crossTileID: number]: boolean;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
lng: number;
|
|
192
|
+
|
|
193
|
+
constructor() {
|
|
194
|
+
this.indexes = {};
|
|
195
|
+
this.usedCrossTileIDs = {};
|
|
196
|
+
this.lng = 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/*
|
|
200
|
+
* Sometimes when a user pans across the antimeridian the longitude value gets wrapped.
|
|
201
|
+
* To prevent labels from flashing out and in we adjust the tileID values in the indexes
|
|
202
|
+
* so that they match the new wrapped version of the map.
|
|
203
|
+
*/
|
|
204
|
+
handleWrapJump(lng: number) {
|
|
205
|
+
const wrapDelta = Math.round((lng - this.lng) / 360);
|
|
206
|
+
if (wrapDelta !== 0) {
|
|
207
|
+
for (const zoom in this.indexes) {
|
|
208
|
+
const zoomIndexes = this.indexes[zoom];
|
|
209
|
+
const newZoomIndex = {};
|
|
210
|
+
for (const key in zoomIndexes) {
|
|
211
|
+
// change the tileID's wrap and add it to a new index
|
|
212
|
+
const index = zoomIndexes[key];
|
|
213
|
+
index.tileID = index.tileID.unwrapTo(index.tileID.wrap + wrapDelta);
|
|
214
|
+
newZoomIndex[index.tileID.key] = index;
|
|
215
|
+
}
|
|
216
|
+
this.indexes[zoom] = newZoomIndex;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
this.lng = lng;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
addBucket(tileID: OverscaledTileID, bucket: SymbolBucket, crossTileIDs: CrossTileIDs) {
|
|
223
|
+
if (this.indexes[tileID.overscaledZ] &&
|
|
224
|
+
this.indexes[tileID.overscaledZ][tileID.key]) {
|
|
225
|
+
if (this.indexes[tileID.overscaledZ][tileID.key].bucketInstanceId ===
|
|
226
|
+
bucket.bucketInstanceId) {
|
|
227
|
+
return false;
|
|
228
|
+
} else {
|
|
229
|
+
// We're replacing this bucket with an updated version
|
|
230
|
+
// Remove the old bucket's "used crossTileIDs" now so that
|
|
231
|
+
// the new bucket can claim them.
|
|
232
|
+
// The old index entries themselves stick around until
|
|
233
|
+
// 'removeStaleBuckets' is called.
|
|
234
|
+
this.removeBucketCrossTileIDs(tileID.overscaledZ,
|
|
235
|
+
this.indexes[tileID.overscaledZ][tileID.key]);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
for (let i = 0; i < bucket.symbolInstances.length; i++) {
|
|
240
|
+
const symbolInstance = bucket.symbolInstances.get(i);
|
|
241
|
+
symbolInstance.crossTileID = 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (!this.usedCrossTileIDs[tileID.overscaledZ]) {
|
|
245
|
+
this.usedCrossTileIDs[tileID.overscaledZ] = {};
|
|
246
|
+
}
|
|
247
|
+
const zoomCrossTileIDs = this.usedCrossTileIDs[tileID.overscaledZ];
|
|
248
|
+
|
|
249
|
+
for (const zoom in this.indexes) {
|
|
250
|
+
const zoomIndexes = this.indexes[zoom];
|
|
251
|
+
if (Number(zoom) > tileID.overscaledZ) {
|
|
252
|
+
for (const id in zoomIndexes) {
|
|
253
|
+
const childIndex = zoomIndexes[id];
|
|
254
|
+
if (childIndex.tileID.isChildOf(tileID)) {
|
|
255
|
+
childIndex.findMatches(bucket.symbolInstances, tileID, zoomCrossTileIDs);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
} else {
|
|
259
|
+
const parentCoord = tileID.scaledTo(Number(zoom));
|
|
260
|
+
const parentIndex = zoomIndexes[parentCoord.key];
|
|
261
|
+
if (parentIndex) {
|
|
262
|
+
parentIndex.findMatches(bucket.symbolInstances, tileID, zoomCrossTileIDs);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
for (let i = 0; i < bucket.symbolInstances.length; i++) {
|
|
268
|
+
const symbolInstance = bucket.symbolInstances.get(i);
|
|
269
|
+
if (!symbolInstance.crossTileID) {
|
|
270
|
+
// symbol did not match any known symbol, assign a new id
|
|
271
|
+
symbolInstance.crossTileID = crossTileIDs.generate();
|
|
272
|
+
zoomCrossTileIDs[symbolInstance.crossTileID] = true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (this.indexes[tileID.overscaledZ] === undefined) {
|
|
277
|
+
this.indexes[tileID.overscaledZ] = {};
|
|
278
|
+
}
|
|
279
|
+
this.indexes[tileID.overscaledZ][tileID.key] = new TileLayerIndex(tileID, bucket.symbolInstances, bucket.bucketInstanceId);
|
|
280
|
+
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
removeBucketCrossTileIDs(zoom: string | number, removedBucket: TileLayerIndex) {
|
|
285
|
+
for (const crossTileIDs of removedBucket.getCrossTileIDsLists()) {
|
|
286
|
+
for (const crossTileID of crossTileIDs) {
|
|
287
|
+
delete this.usedCrossTileIDs[zoom][crossTileID];
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
removeStaleBuckets(currentIDs: {
|
|
293
|
+
[k in string | number]: boolean;
|
|
294
|
+
}) {
|
|
295
|
+
let tilesChanged = false;
|
|
296
|
+
for (const z in this.indexes) {
|
|
297
|
+
const zoomIndexes = this.indexes[z];
|
|
298
|
+
for (const tileKey in zoomIndexes) {
|
|
299
|
+
if (!currentIDs[zoomIndexes[tileKey].bucketInstanceId]) {
|
|
300
|
+
this.removeBucketCrossTileIDs(z, zoomIndexes[tileKey]);
|
|
301
|
+
delete zoomIndexes[tileKey];
|
|
302
|
+
tilesChanged = true;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return tilesChanged;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export class CrossTileSymbolIndex {
|
|
311
|
+
layerIndexes: {[layerId: string]: CrossTileSymbolLayerIndex};
|
|
312
|
+
crossTileIDs: CrossTileIDs;
|
|
313
|
+
maxBucketInstanceId: number;
|
|
314
|
+
bucketsInCurrentPlacement: {[_: number]: boolean};
|
|
315
|
+
|
|
316
|
+
constructor() {
|
|
317
|
+
this.layerIndexes = {};
|
|
318
|
+
this.crossTileIDs = new CrossTileIDs();
|
|
319
|
+
this.maxBucketInstanceId = 0;
|
|
320
|
+
this.bucketsInCurrentPlacement = {};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
addLayer(styleLayer: StyleLayer, tiles: Array<Tile>, lng: number) {
|
|
324
|
+
let layerIndex = this.layerIndexes[styleLayer.id];
|
|
325
|
+
if (layerIndex === undefined) {
|
|
326
|
+
layerIndex = this.layerIndexes[styleLayer.id] = new CrossTileSymbolLayerIndex();
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
let symbolBucketsChanged = false;
|
|
330
|
+
const currentBucketIDs = {};
|
|
331
|
+
|
|
332
|
+
layerIndex.handleWrapJump(lng);
|
|
333
|
+
|
|
334
|
+
for (const tile of tiles) {
|
|
335
|
+
const symbolBucket = (tile.getBucket(styleLayer) as any as SymbolBucket);
|
|
336
|
+
if (!symbolBucket || styleLayer.id !== symbolBucket.layerIds[0])
|
|
337
|
+
continue;
|
|
338
|
+
|
|
339
|
+
if (!symbolBucket.bucketInstanceId) {
|
|
340
|
+
symbolBucket.bucketInstanceId = ++this.maxBucketInstanceId;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (layerIndex.addBucket(tile.tileID, symbolBucket, this.crossTileIDs)) {
|
|
344
|
+
symbolBucketsChanged = true;
|
|
345
|
+
}
|
|
346
|
+
currentBucketIDs[symbolBucket.bucketInstanceId] = true;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (layerIndex.removeStaleBuckets(currentBucketIDs)) {
|
|
350
|
+
symbolBucketsChanged = true;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return symbolBucketsChanged;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
pruneUnusedLayers(usedLayers: Array<string>) {
|
|
357
|
+
const usedLayerMap = {};
|
|
358
|
+
usedLayers.forEach((usedLayer) => {
|
|
359
|
+
usedLayerMap[usedLayer] = true;
|
|
360
|
+
});
|
|
361
|
+
for (const layerId in this.layerIndexes) {
|
|
362
|
+
if (!usedLayerMap[layerId]) {
|
|
363
|
+
delete this.layerIndexes[layerId];
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|