@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,618 @@
|
|
|
1
|
+
import Point from '@mapbox/point-geometry';
|
|
2
|
+
import {clipLine} from './clip_line';
|
|
3
|
+
import {PathInterpolator} from './path_interpolator';
|
|
4
|
+
|
|
5
|
+
import * as intersectionTests from '../util/intersection_tests';
|
|
6
|
+
import {GridIndex} from './grid_index';
|
|
7
|
+
import {mat4, vec4} from 'gl-matrix';
|
|
8
|
+
import ONE_EM from '../symbol/one_em';
|
|
9
|
+
|
|
10
|
+
import * as projection from '../symbol/projection';
|
|
11
|
+
|
|
12
|
+
import type {Transform} from '../geo/transform';
|
|
13
|
+
import type {SingleCollisionBox} from '../data/bucket/symbol_bucket';
|
|
14
|
+
import type {
|
|
15
|
+
GlyphOffsetArray,
|
|
16
|
+
SymbolLineVertexArray
|
|
17
|
+
} from '../data/array_types.g';
|
|
18
|
+
import type {OverlapMode} from '../style/style_layer/overlap_mode';
|
|
19
|
+
import {UnwrappedTileID} from '../source/tile_id';
|
|
20
|
+
import {SymbolProjectionContext} from '../symbol/projection';
|
|
21
|
+
import {Projection} from '../geo/projection/projection';
|
|
22
|
+
import {clamp, getAABB} from '../util/util';
|
|
23
|
+
|
|
24
|
+
// When a symbol crosses the edge that causes it to be included in
|
|
25
|
+
// collision detection, it will cause changes in the symbols around
|
|
26
|
+
// it. This constant specifies how many pixels to pad the edge of
|
|
27
|
+
// the viewport for collision detection so that the bulk of the changes
|
|
28
|
+
// occur offscreen. Making this constant greater increases label
|
|
29
|
+
// stability, but it's expensive.
|
|
30
|
+
export const viewportPadding = 100;
|
|
31
|
+
|
|
32
|
+
export type PlacedCircles = {
|
|
33
|
+
circles: Array<number>;
|
|
34
|
+
offscreen: boolean;
|
|
35
|
+
collisionDetected: boolean;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type PlacedBox = {
|
|
39
|
+
box: Array<number>;
|
|
40
|
+
placeable: boolean;
|
|
41
|
+
offscreen: boolean;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type FeatureKey = {
|
|
45
|
+
bucketInstanceId: number;
|
|
46
|
+
featureIndex: number;
|
|
47
|
+
collisionGroupID: number;
|
|
48
|
+
overlapMode: OverlapMode;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type ProjectedBox = {
|
|
52
|
+
/**
|
|
53
|
+
* The AABB in the format [minX, minY, maxX, maxY].
|
|
54
|
+
*/
|
|
55
|
+
box: [number, number, number, number];
|
|
56
|
+
allPointsOccluded: boolean;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @internal
|
|
61
|
+
* A collision index used to prevent symbols from overlapping. It keep tracks of
|
|
62
|
+
* where previous symbols have been placed and is used to check if a new
|
|
63
|
+
* symbol overlaps with any previously added symbols.
|
|
64
|
+
*
|
|
65
|
+
* There are two steps to insertion: first placeCollisionBox/Circles checks if
|
|
66
|
+
* there's room for a symbol, then insertCollisionBox/Circles actually puts the
|
|
67
|
+
* symbol in the index. The two step process allows paired symbols to be inserted
|
|
68
|
+
* together even if they overlap.
|
|
69
|
+
*/
|
|
70
|
+
export class CollisionIndex {
|
|
71
|
+
grid: GridIndex<FeatureKey>;
|
|
72
|
+
ignoredGrid: GridIndex<FeatureKey>;
|
|
73
|
+
transform: Transform;
|
|
74
|
+
pitchFactor: number;
|
|
75
|
+
screenRightBoundary: number;
|
|
76
|
+
screenBottomBoundary: number;
|
|
77
|
+
gridRightBoundary: number;
|
|
78
|
+
gridBottomBoundary: number;
|
|
79
|
+
mapProjection: Projection;
|
|
80
|
+
|
|
81
|
+
// With perspectiveRatio the fontsize is calculated for tilted maps (near = bigger, far = smaller).
|
|
82
|
+
// The cutoff defines a threshold to no longer render labels near the horizon.
|
|
83
|
+
perspectiveRatioCutoff: number;
|
|
84
|
+
|
|
85
|
+
constructor(
|
|
86
|
+
transform: Transform,
|
|
87
|
+
projection: Projection,
|
|
88
|
+
grid = new GridIndex<FeatureKey>(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25),
|
|
89
|
+
ignoredGrid = new GridIndex<FeatureKey>(transform.width + 2 * viewportPadding, transform.height + 2 * viewportPadding, 25)
|
|
90
|
+
) {
|
|
91
|
+
this.transform = transform;
|
|
92
|
+
this.mapProjection = projection;
|
|
93
|
+
|
|
94
|
+
this.grid = grid;
|
|
95
|
+
this.ignoredGrid = ignoredGrid;
|
|
96
|
+
this.pitchFactor = Math.cos(transform._pitch) * transform.cameraToCenterDistance;
|
|
97
|
+
|
|
98
|
+
this.screenRightBoundary = transform.width + viewportPadding;
|
|
99
|
+
this.screenBottomBoundary = transform.height + viewportPadding;
|
|
100
|
+
this.gridRightBoundary = transform.width + 2 * viewportPadding;
|
|
101
|
+
this.gridBottomBoundary = transform.height + 2 * viewportPadding;
|
|
102
|
+
|
|
103
|
+
this.perspectiveRatioCutoff = 0.6;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
placeCollisionBox(
|
|
107
|
+
collisionBox: SingleCollisionBox,
|
|
108
|
+
overlapMode: OverlapMode,
|
|
109
|
+
textPixelRatio: number,
|
|
110
|
+
posMatrix: mat4,
|
|
111
|
+
unwrappedTileID: UnwrappedTileID,
|
|
112
|
+
pitchWithMap: boolean,
|
|
113
|
+
rotateWithMap: boolean,
|
|
114
|
+
translation: [number, number],
|
|
115
|
+
collisionGroupPredicate?: (key: FeatureKey) => boolean,
|
|
116
|
+
getElevation?: (x: number, y: number) => number,
|
|
117
|
+
shift?: Point
|
|
118
|
+
): PlacedBox {
|
|
119
|
+
const x = collisionBox.anchorPointX + translation[0];
|
|
120
|
+
const y = collisionBox.anchorPointY + translation[1];
|
|
121
|
+
const projectedPoint = this.projectAndGetPerspectiveRatio(
|
|
122
|
+
posMatrix,
|
|
123
|
+
x,
|
|
124
|
+
y,
|
|
125
|
+
unwrappedTileID,
|
|
126
|
+
getElevation
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const tileToViewport = textPixelRatio * projectedPoint.perspectiveRatio;
|
|
130
|
+
|
|
131
|
+
let projectedBox: ProjectedBox;
|
|
132
|
+
|
|
133
|
+
if (!pitchWithMap && !rotateWithMap) {
|
|
134
|
+
// Fast path for common symbols
|
|
135
|
+
const pointX = projectedPoint.point.x + (shift ? shift.x * tileToViewport : 0);
|
|
136
|
+
const pointY = projectedPoint.point.y + (shift ? shift.y * tileToViewport : 0);
|
|
137
|
+
projectedBox = {
|
|
138
|
+
allPointsOccluded: false,
|
|
139
|
+
box: [
|
|
140
|
+
pointX + collisionBox.x1 * tileToViewport,
|
|
141
|
+
pointY + collisionBox.y1 * tileToViewport,
|
|
142
|
+
pointX + collisionBox.x2 * tileToViewport,
|
|
143
|
+
pointY + collisionBox.y2 * tileToViewport,
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
} else {
|
|
147
|
+
projectedBox = this._projectCollisionBox(
|
|
148
|
+
collisionBox,
|
|
149
|
+
tileToViewport,
|
|
150
|
+
posMatrix,
|
|
151
|
+
unwrappedTileID,
|
|
152
|
+
pitchWithMap,
|
|
153
|
+
rotateWithMap,
|
|
154
|
+
translation,
|
|
155
|
+
projectedPoint,
|
|
156
|
+
getElevation,
|
|
157
|
+
shift
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const [tlX, tlY, brX, brY] = projectedBox.box;
|
|
162
|
+
|
|
163
|
+
const projectionOccluded = this.mapProjection.useSpecialProjectionForSymbols ? (pitchWithMap ? projectedBox.allPointsOccluded : this.mapProjection.isOccluded(x, y, unwrappedTileID)) : false;
|
|
164
|
+
|
|
165
|
+
if (projectionOccluded || projectedPoint.perspectiveRatio < this.perspectiveRatioCutoff || !this.isInsideGrid(tlX, tlY, brX, brY) ||
|
|
166
|
+
(overlapMode !== 'always' && this.grid.hitTest(tlX, tlY, brX, brY, overlapMode, collisionGroupPredicate))) {
|
|
167
|
+
return {
|
|
168
|
+
box: [tlX, tlY, brX, brY],
|
|
169
|
+
placeable: false,
|
|
170
|
+
offscreen: false
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
box: [tlX, tlY, brX, brY],
|
|
176
|
+
placeable: true,
|
|
177
|
+
offscreen: this.isOffscreen(tlX, tlY, brX, brY)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
placeCollisionCircles(
|
|
182
|
+
overlapMode: OverlapMode,
|
|
183
|
+
symbol: any,
|
|
184
|
+
lineVertexArray: SymbolLineVertexArray,
|
|
185
|
+
glyphOffsetArray: GlyphOffsetArray,
|
|
186
|
+
fontSize: number,
|
|
187
|
+
posMatrix: mat4,
|
|
188
|
+
unwrappedTileID: UnwrappedTileID,
|
|
189
|
+
labelPlaneMatrix: mat4,
|
|
190
|
+
labelToScreenMatrix: mat4,
|
|
191
|
+
showCollisionCircles: boolean,
|
|
192
|
+
pitchWithMap: boolean,
|
|
193
|
+
collisionGroupPredicate: (key: FeatureKey) => boolean,
|
|
194
|
+
circlePixelDiameter: number,
|
|
195
|
+
textPixelPadding: number,
|
|
196
|
+
translation: [number, number],
|
|
197
|
+
getElevation: (x: number, y: number) => number
|
|
198
|
+
): PlacedCircles {
|
|
199
|
+
const placedCollisionCircles = [];
|
|
200
|
+
|
|
201
|
+
const tileUnitAnchorPoint = new Point(symbol.anchorX, symbol.anchorY);
|
|
202
|
+
const perspectiveRatio = this.getPerspectiveRatio(posMatrix, tileUnitAnchorPoint.x, tileUnitAnchorPoint.y, unwrappedTileID, getElevation);
|
|
203
|
+
const labelPlaneFontSize = pitchWithMap ? fontSize / perspectiveRatio : fontSize * perspectiveRatio;
|
|
204
|
+
const labelPlaneFontScale = labelPlaneFontSize / ONE_EM;
|
|
205
|
+
|
|
206
|
+
const projectionCache = {projections: {}, offsets: {}, cachedAnchorPoint: undefined, anyProjectionOccluded: false};
|
|
207
|
+
const lineOffsetX = symbol.lineOffsetX * labelPlaneFontScale;
|
|
208
|
+
const lineOffsetY = symbol.lineOffsetY * labelPlaneFontScale;
|
|
209
|
+
|
|
210
|
+
const projectionContext: SymbolProjectionContext = {
|
|
211
|
+
getElevation,
|
|
212
|
+
labelPlaneMatrix,
|
|
213
|
+
lineVertexArray,
|
|
214
|
+
pitchWithMap,
|
|
215
|
+
projectionCache,
|
|
216
|
+
projection: this.mapProjection,
|
|
217
|
+
tileAnchorPoint: tileUnitAnchorPoint,
|
|
218
|
+
unwrappedTileID,
|
|
219
|
+
width: this.transform.width,
|
|
220
|
+
height: this.transform.height,
|
|
221
|
+
translation
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const firstAndLastGlyph = projection.placeFirstAndLastGlyph(
|
|
225
|
+
labelPlaneFontScale,
|
|
226
|
+
glyphOffsetArray,
|
|
227
|
+
lineOffsetX,
|
|
228
|
+
lineOffsetY,
|
|
229
|
+
/*flip*/ false,
|
|
230
|
+
symbol,
|
|
231
|
+
false,
|
|
232
|
+
projectionContext);
|
|
233
|
+
|
|
234
|
+
let collisionDetected = false;
|
|
235
|
+
let inGrid = false;
|
|
236
|
+
let entirelyOffscreen = true;
|
|
237
|
+
|
|
238
|
+
if (firstAndLastGlyph) {
|
|
239
|
+
const radius = circlePixelDiameter * 0.5 * perspectiveRatio + textPixelPadding;
|
|
240
|
+
const screenPlaneMin = new Point(-viewportPadding, -viewportPadding);
|
|
241
|
+
const screenPlaneMax = new Point(this.screenRightBoundary, this.screenBottomBoundary);
|
|
242
|
+
const interpolator = new PathInterpolator();
|
|
243
|
+
|
|
244
|
+
// Construct a projected path from projected line vertices. Anchor points are ignored and removed
|
|
245
|
+
const first = firstAndLastGlyph.first;
|
|
246
|
+
const last = firstAndLastGlyph.last;
|
|
247
|
+
|
|
248
|
+
let projectedPath: Array<Point> = [];
|
|
249
|
+
for (let i = first.path.length - 1; i >= 1; i--) {
|
|
250
|
+
projectedPath.push(first.path[i]);
|
|
251
|
+
}
|
|
252
|
+
for (let i = 1; i < last.path.length; i++) {
|
|
253
|
+
projectedPath.push(last.path[i]);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Tolerate a slightly longer distance than one diameter between two adjacent circles
|
|
257
|
+
const circleDist = radius * 2.5;
|
|
258
|
+
|
|
259
|
+
// The path might need to be converted into screen space if a pitched map is used as the label space
|
|
260
|
+
if (labelToScreenMatrix) {
|
|
261
|
+
const screenSpacePath = this.projectPathToScreenSpace(projectedPath, projectionContext, labelToScreenMatrix);
|
|
262
|
+
// Do not try to place collision circles if even one of the points is behind the camera.
|
|
263
|
+
// This is a plausible scenario with big camera pitch angles
|
|
264
|
+
if (screenSpacePath.some(point => point.signedDistanceFromCamera <= 0)) {
|
|
265
|
+
projectedPath = [];
|
|
266
|
+
} else {
|
|
267
|
+
projectedPath = screenSpacePath.map(p => p.point);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
let segments = [];
|
|
272
|
+
|
|
273
|
+
if (projectedPath.length > 0) {
|
|
274
|
+
// Quickly check if the path is fully inside or outside of the padded collision region.
|
|
275
|
+
// For overlapping paths we'll only create collision circles for the visible segments
|
|
276
|
+
const minPoint = projectedPath[0].clone();
|
|
277
|
+
const maxPoint = projectedPath[0].clone();
|
|
278
|
+
|
|
279
|
+
for (let i = 1; i < projectedPath.length; i++) {
|
|
280
|
+
minPoint.x = Math.min(minPoint.x, projectedPath[i].x);
|
|
281
|
+
minPoint.y = Math.min(minPoint.y, projectedPath[i].y);
|
|
282
|
+
maxPoint.x = Math.max(maxPoint.x, projectedPath[i].x);
|
|
283
|
+
maxPoint.y = Math.max(maxPoint.y, projectedPath[i].y);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (minPoint.x >= screenPlaneMin.x && maxPoint.x <= screenPlaneMax.x &&
|
|
287
|
+
minPoint.y >= screenPlaneMin.y && maxPoint.y <= screenPlaneMax.y) {
|
|
288
|
+
// Quad fully visible
|
|
289
|
+
segments = [projectedPath];
|
|
290
|
+
} else if (maxPoint.x < screenPlaneMin.x || minPoint.x > screenPlaneMax.x ||
|
|
291
|
+
maxPoint.y < screenPlaneMin.y || minPoint.y > screenPlaneMax.y) {
|
|
292
|
+
// Not visible
|
|
293
|
+
segments = [];
|
|
294
|
+
} else {
|
|
295
|
+
segments = clipLine([projectedPath], screenPlaneMin.x, screenPlaneMin.y, screenPlaneMax.x, screenPlaneMax.y);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
for (const seg of segments) {
|
|
300
|
+
// interpolate positions for collision circles. Add a small padding to both ends of the segment
|
|
301
|
+
interpolator.reset(seg, radius * 0.25);
|
|
302
|
+
|
|
303
|
+
let numCircles = 0;
|
|
304
|
+
|
|
305
|
+
if (interpolator.length <= 0.5 * radius) {
|
|
306
|
+
numCircles = 1;
|
|
307
|
+
} else {
|
|
308
|
+
numCircles = Math.ceil(interpolator.paddedLength / circleDist) + 1;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
for (let i = 0; i < numCircles; i++) {
|
|
312
|
+
const t = i / Math.max(numCircles - 1, 1);
|
|
313
|
+
const circlePosition = interpolator.lerp(t);
|
|
314
|
+
|
|
315
|
+
// add viewport padding to the position and perform initial collision check
|
|
316
|
+
const centerX = circlePosition.x + viewportPadding;
|
|
317
|
+
const centerY = circlePosition.y + viewportPadding;
|
|
318
|
+
|
|
319
|
+
placedCollisionCircles.push(centerX, centerY, radius, 0);
|
|
320
|
+
|
|
321
|
+
const x1 = centerX - radius;
|
|
322
|
+
const y1 = centerY - radius;
|
|
323
|
+
const x2 = centerX + radius;
|
|
324
|
+
const y2 = centerY + radius;
|
|
325
|
+
|
|
326
|
+
entirelyOffscreen = entirelyOffscreen && this.isOffscreen(x1, y1, x2, y2);
|
|
327
|
+
inGrid = inGrid || this.isInsideGrid(x1, y1, x2, y2);
|
|
328
|
+
|
|
329
|
+
if (overlapMode !== 'always' && this.grid.hitTestCircle(centerX, centerY, radius, overlapMode, collisionGroupPredicate)) {
|
|
330
|
+
// Don't early exit if we're showing the debug circles because we still want to calculate
|
|
331
|
+
// which circles are in use
|
|
332
|
+
collisionDetected = true;
|
|
333
|
+
if (!showCollisionCircles) {
|
|
334
|
+
return {
|
|
335
|
+
circles: [],
|
|
336
|
+
offscreen: false,
|
|
337
|
+
collisionDetected
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
circles: ((!showCollisionCircles && collisionDetected) || !inGrid || perspectiveRatio < this.perspectiveRatioCutoff) ? [] : placedCollisionCircles,
|
|
347
|
+
offscreen: entirelyOffscreen,
|
|
348
|
+
collisionDetected
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
projectPathToScreenSpace(projectedPath: Array<Point>, projectionContext: SymbolProjectionContext, labelToScreenMatrix: mat4) {
|
|
353
|
+
return projectedPath.map(p => projection.project(p.x, p.y, labelToScreenMatrix, projectionContext.getElevation));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Because the geometries in the CollisionIndex are an approximation of the shape of
|
|
358
|
+
* symbols on the map, we use the CollisionIndex to look up the symbol part of
|
|
359
|
+
* `queryRenderedFeatures`.
|
|
360
|
+
*/
|
|
361
|
+
queryRenderedSymbols(viewportQueryGeometry: Array<Point>) {
|
|
362
|
+
if (viewportQueryGeometry.length === 0 || (this.grid.keysLength() === 0 && this.ignoredGrid.keysLength() === 0)) {
|
|
363
|
+
return {};
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const query = [];
|
|
367
|
+
let minX = Infinity;
|
|
368
|
+
let minY = Infinity;
|
|
369
|
+
let maxX = -Infinity;
|
|
370
|
+
let maxY = -Infinity;
|
|
371
|
+
for (const point of viewportQueryGeometry) {
|
|
372
|
+
const gridPoint = new Point(point.x + viewportPadding, point.y + viewportPadding);
|
|
373
|
+
minX = Math.min(minX, gridPoint.x);
|
|
374
|
+
minY = Math.min(minY, gridPoint.y);
|
|
375
|
+
maxX = Math.max(maxX, gridPoint.x);
|
|
376
|
+
maxY = Math.max(maxY, gridPoint.y);
|
|
377
|
+
query.push(gridPoint);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const features = this.grid.query(minX, minY, maxX, maxY)
|
|
381
|
+
.concat(this.ignoredGrid.query(minX, minY, maxX, maxY));
|
|
382
|
+
|
|
383
|
+
const seenFeatures = {};
|
|
384
|
+
const result = {};
|
|
385
|
+
|
|
386
|
+
for (const feature of features) {
|
|
387
|
+
const featureKey = feature.key;
|
|
388
|
+
// Skip already seen features.
|
|
389
|
+
if (seenFeatures[featureKey.bucketInstanceId] === undefined) {
|
|
390
|
+
seenFeatures[featureKey.bucketInstanceId] = {};
|
|
391
|
+
}
|
|
392
|
+
if (seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex]) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Check if query intersects with the feature box
|
|
397
|
+
// "Collision Circles" for line labels are treated as boxes here
|
|
398
|
+
// Since there's no actual collision taking place, the circle vs. square
|
|
399
|
+
// distinction doesn't matter as much, and box geometry is easier
|
|
400
|
+
// to work with.
|
|
401
|
+
const bbox = [
|
|
402
|
+
new Point(feature.x1, feature.y1),
|
|
403
|
+
new Point(feature.x2, feature.y1),
|
|
404
|
+
new Point(feature.x2, feature.y2),
|
|
405
|
+
new Point(feature.x1, feature.y2)
|
|
406
|
+
];
|
|
407
|
+
if (!intersectionTests.polygonIntersectsPolygon(query, bbox)) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
seenFeatures[featureKey.bucketInstanceId][featureKey.featureIndex] = true;
|
|
412
|
+
if (result[featureKey.bucketInstanceId] === undefined) {
|
|
413
|
+
result[featureKey.bucketInstanceId] = [];
|
|
414
|
+
}
|
|
415
|
+
result[featureKey.bucketInstanceId].push(featureKey.featureIndex);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return result;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
insertCollisionBox(collisionBox: Array<number>, overlapMode: OverlapMode, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number) {
|
|
422
|
+
const grid = ignorePlacement ? this.ignoredGrid : this.grid;
|
|
423
|
+
|
|
424
|
+
const key = {bucketInstanceId, featureIndex, collisionGroupID, overlapMode};
|
|
425
|
+
grid.insert(key, collisionBox[0], collisionBox[1], collisionBox[2], collisionBox[3]);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
insertCollisionCircles(collisionCircles: Array<number>, overlapMode: OverlapMode, ignorePlacement: boolean, bucketInstanceId: number, featureIndex: number, collisionGroupID: number) {
|
|
429
|
+
const grid = ignorePlacement ? this.ignoredGrid : this.grid;
|
|
430
|
+
|
|
431
|
+
const key = {bucketInstanceId, featureIndex, collisionGroupID, overlapMode};
|
|
432
|
+
for (let k = 0; k < collisionCircles.length; k += 4) {
|
|
433
|
+
grid.insertCircle(key, collisionCircles[k], collisionCircles[k + 1], collisionCircles[k + 2]);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
projectAndGetPerspectiveRatio(posMatrix: mat4, x: number, y: number, _unwrappedTileID: UnwrappedTileID, getElevation?: (x: number, y: number) => number) {
|
|
438
|
+
// The code here is duplicated from "projection.ts" for performance.
|
|
439
|
+
// Code here is subject to change once globe is merged.
|
|
440
|
+
let pos;
|
|
441
|
+
if (getElevation) { // slow because of handle z-index
|
|
442
|
+
pos = [x, y, getElevation(x, y), 1] as vec4;
|
|
443
|
+
vec4.transformMat4(pos, pos, posMatrix);
|
|
444
|
+
} else { // fast because of ignore z-index
|
|
445
|
+
pos = [x, y, 0, 1] as vec4;
|
|
446
|
+
projection.xyTransformMat4(pos, pos, posMatrix);
|
|
447
|
+
}
|
|
448
|
+
const w = pos[3];
|
|
449
|
+
return {
|
|
450
|
+
point: new Point(
|
|
451
|
+
(((pos[0] / w + 1) / 2) * this.transform.width) + viewportPadding,
|
|
452
|
+
(((-pos[1] / w + 1) / 2) * this.transform.height) + viewportPadding
|
|
453
|
+
),
|
|
454
|
+
// See perspective ratio comment in symbol_sdf.vertex
|
|
455
|
+
// We're doing collision detection in viewport space so we need
|
|
456
|
+
// to scale down boxes in the distance
|
|
457
|
+
perspectiveRatio: 0.5 + 0.5 * (this.transform.cameraToCenterDistance / w),
|
|
458
|
+
isOccluded: false,
|
|
459
|
+
signedDistanceFromCamera: w
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
getPerspectiveRatio(posMatrix: mat4, x: number, y: number, unwrappedTileID: UnwrappedTileID, getElevation?: (x: number, y: number) => number): number {
|
|
464
|
+
// We don't care about the actual projected point, just its W component.
|
|
465
|
+
const projected = this.mapProjection.useSpecialProjectionForSymbols ?
|
|
466
|
+
this.mapProjection.projectTileCoordinates(x, y, unwrappedTileID, getElevation) :
|
|
467
|
+
projection.project(x, y, posMatrix, getElevation);
|
|
468
|
+
return 0.5 + 0.5 * (this.transform.cameraToCenterDistance / projected.signedDistanceFromCamera);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
isOffscreen(x1: number, y1: number, x2: number, y2: number) {
|
|
472
|
+
return x2 < viewportPadding || x1 >= this.screenRightBoundary || y2 < viewportPadding || y1 > this.screenBottomBoundary;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
isInsideGrid(x1: number, y1: number, x2: number, y2: number) {
|
|
476
|
+
return x2 >= 0 && x1 < this.gridRightBoundary && y2 >= 0 && y1 < this.gridBottomBoundary;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/*
|
|
480
|
+
* Returns a matrix for transforming collision shapes to viewport coordinate space.
|
|
481
|
+
* Use this function to render e.g. collision circles on the screen.
|
|
482
|
+
* example transformation: clipPos = glCoordMatrix * viewportMatrix * circle_pos
|
|
483
|
+
*/
|
|
484
|
+
getViewportMatrix() {
|
|
485
|
+
const m = mat4.identity([] as any);
|
|
486
|
+
mat4.translate(m, m, [-viewportPadding, -viewportPadding, 0.0]);
|
|
487
|
+
return m;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Applies all layout+paint properties of the given box in order to find as good approximation of its screen-space bounding box as possible.
|
|
492
|
+
*/
|
|
493
|
+
private _projectCollisionBox(
|
|
494
|
+
collisionBox: SingleCollisionBox,
|
|
495
|
+
tileToViewport: number,
|
|
496
|
+
posMatrix: mat4,
|
|
497
|
+
unwrappedTileID: UnwrappedTileID,
|
|
498
|
+
pitchWithMap: boolean,
|
|
499
|
+
rotateWithMap: boolean,
|
|
500
|
+
translation: [number, number],
|
|
501
|
+
projectedPoint: {point: Point; perspectiveRatio: number; signedDistanceFromCamera: number},
|
|
502
|
+
getElevation?: (x: number, y: number) => number,
|
|
503
|
+
shift?: Point
|
|
504
|
+
): ProjectedBox {
|
|
505
|
+
|
|
506
|
+
// These vectors are valid both for screen space viewport-rotation-aligned texts and for pitch-align: map texts that are map-rotation-aligned.
|
|
507
|
+
let vecEast = new Point(1, 0);
|
|
508
|
+
let vecSouth = new Point(0, 1);
|
|
509
|
+
|
|
510
|
+
const translatedAnchor = new Point(collisionBox.anchorPointX + translation[0], collisionBox.anchorPointY + translation[1]);
|
|
511
|
+
|
|
512
|
+
if (rotateWithMap && !pitchWithMap) {
|
|
513
|
+
// Handles screen space texts that are always aligned east-west.
|
|
514
|
+
const projectedEast = this.projectAndGetPerspectiveRatio(
|
|
515
|
+
posMatrix,
|
|
516
|
+
translatedAnchor.x + 1,
|
|
517
|
+
translatedAnchor.y,
|
|
518
|
+
unwrappedTileID,
|
|
519
|
+
getElevation
|
|
520
|
+
).point;
|
|
521
|
+
const toEast = projectedEast.sub(projectedPoint.point).unit();
|
|
522
|
+
const angle = Math.atan(toEast.y / toEast.x) + (toEast.x < 0 ? Math.PI : 0);
|
|
523
|
+
const sin = Math.sin(angle);
|
|
524
|
+
const cos = Math.cos(angle);
|
|
525
|
+
vecEast = new Point(cos, sin);
|
|
526
|
+
vecSouth = new Point(-sin, cos);
|
|
527
|
+
} else if (!rotateWithMap && pitchWithMap) {
|
|
528
|
+
// Handles pitch-align: map texts that are always aligned with the viewport's X axis.
|
|
529
|
+
const angle = -this.transform.angle;
|
|
530
|
+
const sin = Math.sin(angle);
|
|
531
|
+
const cos = Math.cos(angle);
|
|
532
|
+
vecEast = new Point(cos, sin);
|
|
533
|
+
vecSouth = new Point(-sin, cos);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// Configuration for screen space offsets
|
|
537
|
+
let basePoint = projectedPoint.point;
|
|
538
|
+
let distanceMultiplier = tileToViewport;
|
|
539
|
+
|
|
540
|
+
if (pitchWithMap) {
|
|
541
|
+
// Configuration for tile space (map-pitch-aligned) offsets
|
|
542
|
+
basePoint = translatedAnchor;
|
|
543
|
+
|
|
544
|
+
const zoomFraction = this.transform.zoom - Math.floor(this.transform.zoom);
|
|
545
|
+
distanceMultiplier = Math.pow(2, -zoomFraction);
|
|
546
|
+
distanceMultiplier *= this.mapProjection.getPitchedTextCorrection(this.transform, translatedAnchor, unwrappedTileID);
|
|
547
|
+
|
|
548
|
+
// This next correction can't be applied when variable anchors are in use.
|
|
549
|
+
if (!shift) {
|
|
550
|
+
// Shader applies a perspective size correction, we need to apply the same correction.
|
|
551
|
+
// For non-pitchWithMap texts, this is handled above by multiplying `textPixelRatio` with `projectedPoint.perspectiveRatio`,
|
|
552
|
+
// which is equivalent to the non-pitchWithMap branch of the GLSL code.
|
|
553
|
+
// Here, we compute and apply the pitchWithMap branch.
|
|
554
|
+
// See the computation of `perspective_ratio` in the symbol vertex shaders for the GLSL code.
|
|
555
|
+
const distanceRatio = projectedPoint.signedDistanceFromCamera / this.transform.cameraToCenterDistance;
|
|
556
|
+
const perspectiveRatio = clamp(0.5 + 0.5 * distanceRatio, 0.0, 4.0); // Same clamp as what is used in the shader.
|
|
557
|
+
distanceMultiplier *= perspectiveRatio;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (shift) {
|
|
562
|
+
// Variable anchors are in use
|
|
563
|
+
basePoint = basePoint.add(vecEast.mult(shift.x * distanceMultiplier)).add(vecSouth.mult(shift.y * distanceMultiplier));
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
const offsetXmin = collisionBox.x1 * distanceMultiplier;
|
|
567
|
+
const offsetXmax = collisionBox.x2 * distanceMultiplier;
|
|
568
|
+
const offsetXhalf = (offsetXmin + offsetXmax) / 2;
|
|
569
|
+
const offsetYmin = collisionBox.y1 * distanceMultiplier;
|
|
570
|
+
const offsetYmax = collisionBox.y2 * distanceMultiplier;
|
|
571
|
+
const offsetYhalf = (offsetYmin + offsetYmax) / 2;
|
|
572
|
+
|
|
573
|
+
// 0--1--2
|
|
574
|
+
// | |
|
|
575
|
+
// 7 3
|
|
576
|
+
// | |
|
|
577
|
+
// 6--5--4
|
|
578
|
+
const offsetsArray: Array<{offsetX: number; offsetY: number}> = [
|
|
579
|
+
{offsetX: offsetXmin, offsetY: offsetYmin},
|
|
580
|
+
{offsetX: offsetXhalf, offsetY: offsetYmin},
|
|
581
|
+
{offsetX: offsetXmax, offsetY: offsetYmin},
|
|
582
|
+
{offsetX: offsetXmax, offsetY: offsetYhalf},
|
|
583
|
+
{offsetX: offsetXmax, offsetY: offsetYmax},
|
|
584
|
+
{offsetX: offsetXhalf, offsetY: offsetYmax},
|
|
585
|
+
{offsetX: offsetXmin, offsetY: offsetYmax},
|
|
586
|
+
{offsetX: offsetXmin, offsetY: offsetYhalf}
|
|
587
|
+
];
|
|
588
|
+
|
|
589
|
+
let points: Array<Point> = [];
|
|
590
|
+
|
|
591
|
+
for (const {offsetX, offsetY} of offsetsArray) {
|
|
592
|
+
points.push(new Point(
|
|
593
|
+
basePoint.x + vecEast.x * offsetX + vecSouth.x * offsetY,
|
|
594
|
+
basePoint.y + vecEast.y * offsetX + vecSouth.y * offsetY
|
|
595
|
+
));
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Is any point of the collision shape visible on the globe (on beyond horizon)?
|
|
599
|
+
let anyPointVisible = false;
|
|
600
|
+
|
|
601
|
+
if (pitchWithMap) {
|
|
602
|
+
const projected = points.map(p => this.projectAndGetPerspectiveRatio(posMatrix, p.x, p.y, unwrappedTileID, getElevation));
|
|
603
|
+
|
|
604
|
+
// Is at least one of the projected points NOT behind the horizon?
|
|
605
|
+
anyPointVisible = projected.some(p => !p.isOccluded);
|
|
606
|
+
|
|
607
|
+
points = projected.map(p => p.point);
|
|
608
|
+
} else {
|
|
609
|
+
// Labels that are not pitchWithMap cannot ever hide behind the horizon.
|
|
610
|
+
anyPointVisible = true;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
return {
|
|
614
|
+
box: getAABB(points),
|
|
615
|
+
allPointsOccluded: !anyPointVisible
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
}
|