@mapwhit/tilerenderer 0.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +87 -0
- package/README.md +25 -0
- package/build/min/.dir +0 -0
- package/build/min/package.json +3 -0
- package/build/min/src/shaders/_prelude.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/_prelude.vertex.glsl.txt +14 -0
- package/build/min/src/shaders/background.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/background.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/background_pattern.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/background_pattern.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/circle.fragment.glsl.txt +20 -0
- package/build/min/src/shaders/circle.vertex.glsl.txt +17 -0
- package/build/min/src/shaders/clipping_mask.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/clipping_mask.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/collision_box.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/collision_box.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/collision_circle.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/collision_circle.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/debug.fragment.glsl.txt +1 -0
- package/build/min/src/shaders/debug.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/fill.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/fill.vertex.glsl.txt +7 -0
- package/build/min/src/shaders/fill_extrusion.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_extrusion.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/fill_extrusion_pattern.fragment.glsl.txt +15 -0
- package/build/min/src/shaders/fill_extrusion_pattern.vertex.glsl.txt +11 -0
- package/build/min/src/shaders/fill_outline.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/fill_outline.vertex.glsl.txt +7 -0
- package/build/min/src/shaders/fill_outline_pattern.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_outline_pattern.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/fill_pattern.fragment.glsl.txt +13 -0
- package/build/min/src/shaders/fill_pattern.vertex.glsl.txt +9 -0
- package/build/min/src/shaders/heatmap.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/heatmap.vertex.glsl.txt +8 -0
- package/build/min/src/shaders/heatmap_texture.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/heatmap_texture.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/hillshade.fragment.glsl.txt +7 -0
- package/build/min/src/shaders/hillshade.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/hillshade_prepare.fragment.glsl.txt +8 -0
- package/build/min/src/shaders/hillshade_prepare.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/line.fragment.glsl.txt +12 -0
- package/build/min/src/shaders/line.vertex.glsl.txt +17 -0
- package/build/min/src/shaders/line_gradient.fragment.glsl.txt +10 -0
- package/build/min/src/shaders/line_gradient.vertex.glsl.txt +16 -0
- package/build/min/src/shaders/line_pattern.fragment.glsl.txt +15 -0
- package/build/min/src/shaders/line_pattern.vertex.glsl.txt +20 -0
- package/build/min/src/shaders/line_sdf.fragment.glsl.txt +17 -0
- package/build/min/src/shaders/line_sdf.vertex.glsl.txt +20 -0
- package/build/min/src/shaders/raster.fragment.glsl.txt +5 -0
- package/build/min/src/shaders/raster.vertex.glsl.txt +1 -0
- package/build/min/src/shaders/symbol_icon.fragment.glsl.txt +9 -0
- package/build/min/src/shaders/symbol_icon.vertex.glsl.txt +5 -0
- package/build/min/src/shaders/symbol_sdf.fragment.glsl.txt +19 -0
- package/build/min/src/shaders/symbol_sdf.vertex.glsl.txt +13 -0
- package/package.json +44 -0
- package/src/css/mapbox-gl.css +506 -0
- package/src/css/svg/mapboxgl-ctrl-attrib.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-compass.svg +4 -0
- package/src/css/svg/mapboxgl-ctrl-fullscreen.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-geolocate-background.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-geolocate.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-logo-compact.svg +2 -0
- package/src/css/svg/mapboxgl-ctrl-logo.svg +1 -0
- package/src/css/svg/mapboxgl-ctrl-shrink.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-zoom-in.svg +3 -0
- package/src/css/svg/mapboxgl-ctrl-zoom-out.svg +3 -0
- package/src/data/array_types.js +1138 -0
- package/src/data/bucket/circle_attributes.js +5 -0
- package/src/data/bucket/circle_bucket.js +118 -0
- package/src/data/bucket/fill_attributes.js +5 -0
- package/src/data/bucket/fill_bucket.js +166 -0
- package/src/data/bucket/fill_extrusion_attributes.js +11 -0
- package/src/data/bucket/fill_extrusion_bucket.js +247 -0
- package/src/data/bucket/heatmap_bucket.js +12 -0
- package/src/data/bucket/line_attributes.js +11 -0
- package/src/data/bucket/line_bucket.js +625 -0
- package/src/data/bucket/pattern_attributes.js +9 -0
- package/src/data/bucket/pattern_bucket_features.js +44 -0
- package/src/data/bucket/symbol_attributes.js +95 -0
- package/src/data/bucket/symbol_bucket.js +697 -0
- package/src/data/bucket.js +53 -0
- package/src/data/dem_data.js +126 -0
- package/src/data/extent.js +17 -0
- package/src/data/feature_index.js +254 -0
- package/src/data/index_array_type.js +14 -0
- package/src/data/load_geometry.js +42 -0
- package/src/data/pos_attributes.js +3 -0
- package/src/data/program_configuration.js +782 -0
- package/src/data/raster_bounds_attributes.js +6 -0
- package/src/data/segment.js +63 -0
- package/src/geo/coordinate.js +78 -0
- package/src/geo/lng_lat.js +129 -0
- package/src/geo/lng_lat_bounds.js +253 -0
- package/src/geo/transform.js +605 -0
- package/src/gl/color_mode.js +21 -0
- package/src/gl/context.js +193 -0
- package/src/gl/cull_face_mode.js +22 -0
- package/src/gl/depth_mode.js +18 -0
- package/src/gl/framebuffer.js +28 -0
- package/src/gl/index_buffer.js +52 -0
- package/src/gl/stencil_mode.js +17 -0
- package/src/gl/types.js +0 -0
- package/src/gl/value.js +676 -0
- package/src/gl/vertex_buffer.js +101 -0
- package/src/index.js +50 -0
- package/src/render/draw_background.js +60 -0
- package/src/render/draw_circle.js +55 -0
- package/src/render/draw_collision_debug.js +45 -0
- package/src/render/draw_debug.js +429 -0
- package/src/render/draw_fill.js +143 -0
- package/src/render/draw_fill_extrusion.js +101 -0
- package/src/render/draw_heatmap.js +159 -0
- package/src/render/draw_hillshade.js +144 -0
- package/src/render/draw_line.js +99 -0
- package/src/render/draw_raster.js +151 -0
- package/src/render/draw_symbol.js +231 -0
- package/src/render/glyph_atlas.js +55 -0
- package/src/render/glyph_manager.js +145 -0
- package/src/render/image_atlas.js +97 -0
- package/src/render/image_manager.js +183 -0
- package/src/render/line_atlas.js +139 -0
- package/src/render/painter.js +483 -0
- package/src/render/program/background_program.js +46 -0
- package/src/render/program/circle_program.js +40 -0
- package/src/render/program/clipping_mask_program.js +11 -0
- package/src/render/program/collision_program.js +28 -0
- package/src/render/program/debug_program.js +13 -0
- package/src/render/program/fill_extrusion_program.js +76 -0
- package/src/render/program/fill_program.js +60 -0
- package/src/render/program/heatmap_program.js +46 -0
- package/src/render/program/hillshade_program.js +77 -0
- package/src/render/program/line_program.js +119 -0
- package/src/render/program/pattern.js +57 -0
- package/src/render/program/program_uniforms.js +46 -0
- package/src/render/program/raster_program.js +50 -0
- package/src/render/program/symbol_program.js +112 -0
- package/src/render/program.js +133 -0
- package/src/render/texture.js +88 -0
- package/src/render/tile_mask.js +108 -0
- package/src/render/uniform_binding.js +129 -0
- package/src/render/vertex_array_object.js +155 -0
- package/src/shaders/README.md +42 -0
- package/src/shaders/_prelude.fragment.glsl +17 -0
- package/src/shaders/_prelude.vertex.glsl +73 -0
- package/src/shaders/background.fragment.glsl +10 -0
- package/src/shaders/background.vertex.glsl +7 -0
- package/src/shaders/background_pattern.fragment.glsl +28 -0
- package/src/shaders/background_pattern.vertex.glsl +20 -0
- package/src/shaders/circle.fragment.glsl +39 -0
- package/src/shaders/circle.vertex.glsl +63 -0
- package/src/shaders/clipping_mask.fragment.glsl +3 -0
- package/src/shaders/clipping_mask.vertex.glsl +7 -0
- package/src/shaders/collision_box.fragment.glsl +21 -0
- package/src/shaders/collision_box.vertex.glsl +26 -0
- package/src/shaders/collision_circle.fragment.glsl +34 -0
- package/src/shaders/collision_circle.vertex.glsl +36 -0
- package/src/shaders/debug.fragment.glsl +5 -0
- package/src/shaders/debug.vertex.glsl +7 -0
- package/src/shaders/encode_attribute.js +19 -0
- package/src/shaders/fill.fragment.glsl +13 -0
- package/src/shaders/fill.vertex.glsl +13 -0
- package/src/shaders/fill_extrusion.fragment.glsl +16 -0
- package/src/shaders/fill_extrusion.vertex.glsl +66 -0
- package/src/shaders/fill_extrusion_pattern.fragment.glsl +41 -0
- package/src/shaders/fill_extrusion_pattern.vertex.glsl +76 -0
- package/src/shaders/fill_outline.fragment.glsl +17 -0
- package/src/shaders/fill_outline.vertex.glsl +17 -0
- package/src/shaders/fill_outline_pattern.fragment.glsl +43 -0
- package/src/shaders/fill_outline_pattern.vertex.glsl +41 -0
- package/src/shaders/fill_pattern.fragment.glsl +36 -0
- package/src/shaders/fill_pattern.vertex.glsl +36 -0
- package/src/shaders/heatmap.fragment.glsl +21 -0
- package/src/shaders/heatmap.vertex.glsl +53 -0
- package/src/shaders/heatmap_texture.fragment.glsl +14 -0
- package/src/shaders/heatmap_texture.vertex.glsl +11 -0
- package/src/shaders/hillshade.fragment.glsl +52 -0
- package/src/shaders/hillshade.vertex.glsl +11 -0
- package/src/shaders/hillshade_prepare.fragment.glsl +72 -0
- package/src/shaders/hillshade_prepare.vertex.glsl +15 -0
- package/src/shaders/index.js +194 -0
- package/src/shaders/line.fragment.glsl +28 -0
- package/src/shaders/line.vertex.glsl +84 -0
- package/src/shaders/line_gradient.fragment.glsl +34 -0
- package/src/shaders/line_gradient.vertex.glsl +84 -0
- package/src/shaders/line_pattern.fragment.glsl +69 -0
- package/src/shaders/line_pattern.vertex.glsl +88 -0
- package/src/shaders/line_sdf.fragment.glsl +44 -0
- package/src/shaders/line_sdf.vertex.glsl +95 -0
- package/src/shaders/raster.fragment.glsl +52 -0
- package/src/shaders/raster.vertex.glsl +21 -0
- package/src/shaders/symbol_icon.fragment.glsl +17 -0
- package/src/shaders/symbol_icon.vertex.glsl +91 -0
- package/src/shaders/symbol_sdf.fragment.glsl +50 -0
- package/src/shaders/symbol_sdf.vertex.glsl +117 -0
- package/src/source/geojson_source.js +267 -0
- package/src/source/geojson_worker_source.js +210 -0
- package/src/source/geojson_wrapper.js +67 -0
- package/src/source/image_source.js +213 -0
- package/src/source/load_tilejson.js +40 -0
- package/src/source/pixels_to_tile_units.js +17 -0
- package/src/source/query_features.js +198 -0
- package/src/source/raster_dem_tile_source.js +140 -0
- package/src/source/raster_dem_tile_worker_source.js +26 -0
- package/src/source/raster_tile_source.js +126 -0
- package/src/source/rtl_text_plugin.js +63 -0
- package/src/source/source.js +75 -0
- package/src/source/source_cache.js +794 -0
- package/src/source/source_state.js +55 -0
- package/src/source/tile.js +332 -0
- package/src/source/tile_bounds.js +40 -0
- package/src/source/tile_cache.js +122 -0
- package/src/source/tile_id.js +150 -0
- package/src/source/vector_tile_source.js +144 -0
- package/src/source/vector_tile_worker_source.js +126 -0
- package/src/source/worker.js +175 -0
- package/src/source/worker_source.js +14 -0
- package/src/source/worker_tile.js +199 -0
- package/src/style/create_style_layer.js +25 -0
- package/src/style/evaluation_parameters.js +45 -0
- package/src/style/light.js +112 -0
- package/src/style/load_glyph_range.js +17 -0
- package/src/style/load_sprite.js +26 -0
- package/src/style/parse_glyph_pbf.js +45 -0
- package/src/style/pauseable_placement.js +88 -0
- package/src/style/properties.js +691 -0
- package/src/style/query_utils.js +39 -0
- package/src/style/style.js +955 -0
- package/src/style/style_layer/background_style_layer.js +11 -0
- package/src/style/style_layer/background_style_layer_properties.js +25 -0
- package/src/style/style_layer/circle_style_layer.js +93 -0
- package/src/style/style_layer/circle_style_layer_properties.js +76 -0
- package/src/style/style_layer/fill_extrusion_style_layer.js +194 -0
- package/src/style/style_layer/fill_extrusion_style_layer_properties.js +56 -0
- package/src/style/style_layer/fill_style_layer.js +46 -0
- package/src/style/style_layer/fill_style_layer_properties.js +45 -0
- package/src/style/style_layer/heatmap_style_layer.js +51 -0
- package/src/style/style_layer/heatmap_style_layer_properties.js +52 -0
- package/src/style/style_layer/hillshade_style_layer.js +15 -0
- package/src/style/style_layer/hillshade_style_layer_properties.js +43 -0
- package/src/style/style_layer/line_style_layer.js +129 -0
- package/src/style/style_layer/line_style_layer_properties.js +104 -0
- package/src/style/style_layer/raster_style_layer.js +11 -0
- package/src/style/style_layer/raster_style_layer_properties.js +55 -0
- package/src/style/style_layer/symbol_style_layer.js +66 -0
- package/src/style/style_layer/symbol_style_layer_properties.js +288 -0
- package/src/style/style_layer.js +183 -0
- package/src/style/style_layer_index.js +61 -0
- package/src/style/zoom_history.js +36 -0
- package/src/style-spec/deref.js +51 -0
- package/src/style-spec/error/parsing_error.js +8 -0
- package/src/style-spec/error/validation_error.js +10 -0
- package/src/style-spec/expression/compound_expression.js +118 -0
- package/src/style-spec/expression/definitions/array.js +82 -0
- package/src/style-spec/expression/definitions/assertion.js +69 -0
- package/src/style-spec/expression/definitions/at.js +57 -0
- package/src/style-spec/expression/definitions/case.js +73 -0
- package/src/style-spec/expression/definitions/coalesce.js +68 -0
- package/src/style-spec/expression/definitions/coercion.js +96 -0
- package/src/style-spec/expression/definitions/collator.js +102 -0
- package/src/style-spec/expression/definitions/equals.js +93 -0
- package/src/style-spec/expression/definitions/index.js +407 -0
- package/src/style-spec/expression/definitions/interpolate.js +235 -0
- package/src/style-spec/expression/definitions/length.js +54 -0
- package/src/style-spec/expression/definitions/let.js +60 -0
- package/src/style-spec/expression/definitions/literal.js +64 -0
- package/src/style-spec/expression/definitions/match.js +142 -0
- package/src/style-spec/expression/definitions/step.js +116 -0
- package/src/style-spec/expression/definitions/var.js +38 -0
- package/src/style-spec/expression/evaluation_context.js +35 -0
- package/src/style-spec/expression/index.js +329 -0
- package/src/style-spec/expression/is_constant.js +63 -0
- package/src/style-spec/expression/parsing_context.js +213 -0
- package/src/style-spec/expression/parsing_error.js +9 -0
- package/src/style-spec/expression/runtime_error.js +12 -0
- package/src/style-spec/expression/scope.js +34 -0
- package/src/style-spec/expression/stops.js +37 -0
- package/src/style-spec/expression/types.js +77 -0
- package/src/style-spec/expression/values.js +126 -0
- package/src/style-spec/feature_filter/README.md +55 -0
- package/src/style-spec/feature_filter/index.js +158 -0
- package/src/style-spec/function/convert.js +256 -0
- package/src/style-spec/function/index.js +299 -0
- package/src/style-spec/group_by_layout.js +68 -0
- package/src/style-spec/reference/v8.json +5356 -0
- package/src/style-spec/util/color.js +73 -0
- package/src/style-spec/util/color_spaces.js +128 -0
- package/src/style-spec/util/eval_support.js +8 -0
- package/src/style-spec/util/get_type.js +18 -0
- package/src/style-spec/util/interpolate.js +21 -0
- package/src/style-spec/util/properties.js +17 -0
- package/src/style-spec/util/ref_properties.js +1 -0
- package/src/style-spec/util/result.js +19 -0
- package/src/symbol/anchor.js +21 -0
- package/src/symbol/check_max_angle.js +75 -0
- package/src/symbol/clip_line.js +73 -0
- package/src/symbol/collision_feature.js +230 -0
- package/src/symbol/collision_index.js +379 -0
- package/src/symbol/cross_tile_symbol_index.js +270 -0
- package/src/symbol/get_anchors.js +177 -0
- package/src/symbol/grid_index.js +318 -0
- package/src/symbol/mergelines.js +75 -0
- package/src/symbol/opacity_state.js +21 -0
- package/src/symbol/placement.js +563 -0
- package/src/symbol/projection.js +601 -0
- package/src/symbol/quads.js +173 -0
- package/src/symbol/shaping.js +347 -0
- package/src/symbol/symbol_layout.js +519 -0
- package/src/symbol/symbol_size.js +110 -0
- package/src/symbol/transform_text.js +16 -0
- package/src/ui/anchor.js +24 -0
- package/src/ui/bind_handlers.js +199 -0
- package/src/ui/camera.js +954 -0
- package/src/ui/events.js +210 -0
- package/src/ui/handler/box_zoom.js +151 -0
- package/src/ui/handler/dblclick_zoom.js +91 -0
- package/src/ui/handler/drag_pan.js +285 -0
- package/src/ui/handler/drag_rotate.js +290 -0
- package/src/ui/handler/frame.js +28 -0
- package/src/ui/handler/inertia.js +45 -0
- package/src/ui/handler/keyboard.js +148 -0
- package/src/ui/handler/scroll_zoom.js +284 -0
- package/src/ui/handler/touch_zoom_rotate.js +263 -0
- package/src/ui/map.js +1645 -0
- package/src/util/actor.js +104 -0
- package/src/util/async.js +23 -0
- package/src/util/browser.js +61 -0
- package/src/util/callback.js +26 -0
- package/src/util/classify_rings.js +43 -0
- package/src/util/color_ramp.js +24 -0
- package/src/util/config.js +24 -0
- package/src/util/dictionary_coder.js +25 -0
- package/src/util/dispatcher.js +68 -0
- package/src/util/dom.js +102 -0
- package/src/util/evented.js +182 -0
- package/src/util/find_pole_of_inaccessibility.js +129 -0
- package/src/util/global_worker_pool.js +15 -0
- package/src/util/image.js +124 -0
- package/src/util/interpolate.js +5 -0
- package/src/util/intersection_tests.js +207 -0
- package/src/util/is_char_in_unicode_block.js +287 -0
- package/src/util/loader/image.js +32 -0
- package/src/util/object.js +178 -0
- package/src/util/script_detection.js +337 -0
- package/src/util/struct_array.js +197 -0
- package/src/util/task_queue.js +57 -0
- package/src/util/throttle.js +26 -0
- package/src/util/tile_cover.js +114 -0
- package/src/util/token.js +13 -0
- package/src/util/unique_id.js +12 -0
- package/src/util/util.js +192 -0
- package/src/util/vectortile_to_geojson.js +44 -0
- package/src/util/verticalize_punctuation.js +112 -0
- package/src/util/warn.js +21 -0
- package/src/util/web_worker.js +5 -0
- package/src/util/web_worker_transfer.js +228 -0
- package/src/util/worker_pool.js +41 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
const { Event, ErrorEvent, Evented } = require('../util/evented');
|
|
2
|
+
|
|
3
|
+
const EXTENT = require('../data/extent');
|
|
4
|
+
const browser = require('../util/browser');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A source containing GeoJSON.
|
|
8
|
+
* (See the [Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson) for detailed documentation of options.)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* map.addSource('some id', {
|
|
12
|
+
* type: 'geojson',
|
|
13
|
+
* data: 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_10m_ports.geojson'
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* map.addSource('some id', {
|
|
18
|
+
* type: 'geojson',
|
|
19
|
+
* data: {
|
|
20
|
+
* "type": "FeatureCollection",
|
|
21
|
+
* "features": [{
|
|
22
|
+
* "type": "Feature",
|
|
23
|
+
* "properties": {},
|
|
24
|
+
* "geometry": {
|
|
25
|
+
* "type": "Point",
|
|
26
|
+
* "coordinates": [
|
|
27
|
+
* -76.53063297271729,
|
|
28
|
+
* 39.18174077994108
|
|
29
|
+
* ]
|
|
30
|
+
* }
|
|
31
|
+
* }]
|
|
32
|
+
* }
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* map.getSource('some id').setData({
|
|
37
|
+
* "type": "FeatureCollection",
|
|
38
|
+
* "features": [{
|
|
39
|
+
* "type": "Feature",
|
|
40
|
+
* "properties": { "name": "Null Island" },
|
|
41
|
+
* "geometry": {
|
|
42
|
+
* "type": "Point",
|
|
43
|
+
* "coordinates": [ 0, 0 ]
|
|
44
|
+
* }
|
|
45
|
+
* }]
|
|
46
|
+
* });
|
|
47
|
+
* @see [Draw GeoJSON points](https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/)
|
|
48
|
+
* @see [Add a GeoJSON line](https://www.mapbox.com/mapbox-gl-js/example/geojson-line/)
|
|
49
|
+
* @see [Create a heatmap from points](https://www.mapbox.com/mapbox-gl-js/example/heatmap/)
|
|
50
|
+
*/
|
|
51
|
+
class GeoJSONSource extends Evented {
|
|
52
|
+
/**
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
constructor(id, options, dispatcher, eventedParent) {
|
|
56
|
+
super();
|
|
57
|
+
|
|
58
|
+
this.id = id;
|
|
59
|
+
|
|
60
|
+
// `type` is a property rather than a constant to make it easy for 3rd
|
|
61
|
+
// parties to use GeoJSONSource to build their own source types.
|
|
62
|
+
this.type = 'geojson';
|
|
63
|
+
|
|
64
|
+
this.minzoom = 0;
|
|
65
|
+
this.maxzoom = 18;
|
|
66
|
+
this.tileSize = 512;
|
|
67
|
+
this.isTileClipped = true;
|
|
68
|
+
this.reparseOverscaled = true;
|
|
69
|
+
this._removed = false;
|
|
70
|
+
|
|
71
|
+
this.dispatcher = dispatcher;
|
|
72
|
+
this.setEventedParent(eventedParent);
|
|
73
|
+
|
|
74
|
+
this._data = options.data;
|
|
75
|
+
this._options = Object.assign({}, options);
|
|
76
|
+
|
|
77
|
+
if (options.maxzoom !== undefined) this.maxzoom = options.maxzoom;
|
|
78
|
+
if (options.type) this.type = options.type;
|
|
79
|
+
|
|
80
|
+
const scale = EXTENT / this.tileSize;
|
|
81
|
+
|
|
82
|
+
// sent to the worker, along with `url: ...` or `data: literal geojson`,
|
|
83
|
+
// so that it can load/parse/index the geojson data
|
|
84
|
+
// extending with `options.workerOptions` helps to make it easy for
|
|
85
|
+
// third-party sources to hack/reuse GeoJSONSource.
|
|
86
|
+
this.workerOptions = Object.assign(
|
|
87
|
+
{
|
|
88
|
+
source: this.id,
|
|
89
|
+
cluster: options.cluster || false,
|
|
90
|
+
geojsonVtOptions: {
|
|
91
|
+
buffer: (options.buffer !== undefined ? options.buffer : 128) * scale,
|
|
92
|
+
tolerance: (options.tolerance !== undefined ? options.tolerance : 0.375) * scale,
|
|
93
|
+
extent: EXTENT,
|
|
94
|
+
maxZoom: this.maxzoom,
|
|
95
|
+
lineMetrics: options.lineMetrics || false
|
|
96
|
+
},
|
|
97
|
+
superclusterOptions: {
|
|
98
|
+
maxZoom:
|
|
99
|
+
options.clusterMaxZoom !== undefined
|
|
100
|
+
? Math.min(options.clusterMaxZoom, this.maxzoom - 1)
|
|
101
|
+
: this.maxzoom - 1,
|
|
102
|
+
extent: EXTENT,
|
|
103
|
+
radius: (options.clusterRadius || 50) * scale,
|
|
104
|
+
log: false
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
options.workerOptions
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
load() {
|
|
112
|
+
this.fire(new Event('dataloading', { dataType: 'source' }));
|
|
113
|
+
this._updateWorkerData(err => {
|
|
114
|
+
if (err) {
|
|
115
|
+
this.fire(new ErrorEvent(err));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const data = { dataType: 'source', sourceDataType: 'metadata' };
|
|
120
|
+
|
|
121
|
+
// although GeoJSON sources contain no metadata, we fire this event to let the SourceCache
|
|
122
|
+
// know its ok to start requesting tiles.
|
|
123
|
+
this.fire(new Event('data', data));
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
onAdd(map) {
|
|
128
|
+
this.map = map;
|
|
129
|
+
this.load();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Sets the GeoJSON data and re-renders the map.
|
|
134
|
+
*
|
|
135
|
+
* @param {Object|string} data A GeoJSON data object or a URL to one. The latter is preferable in the case of large GeoJSON files.
|
|
136
|
+
* @returns {GeoJSONSource} this
|
|
137
|
+
*/
|
|
138
|
+
setData(data) {
|
|
139
|
+
this._data = data;
|
|
140
|
+
this.fire(new Event('dataloading', { dataType: 'source' }));
|
|
141
|
+
this._updateWorkerData(err => {
|
|
142
|
+
if (err) {
|
|
143
|
+
return this.fire(new ErrorEvent(err));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const data = { dataType: 'source', sourceDataType: 'content' };
|
|
147
|
+
this.fire(new Event('data', data));
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return this;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/*
|
|
154
|
+
* Responsible for invoking WorkerSource's geojson.loadData target, which
|
|
155
|
+
* handles loading the geojson data and preparing to serve it up as tiles,
|
|
156
|
+
* using geojson-vt or supercluster as appropriate.
|
|
157
|
+
*/
|
|
158
|
+
_updateWorkerData(callback) {
|
|
159
|
+
// biome-ignore lint/suspicious/useAwait: normalize return values as promises
|
|
160
|
+
async function loadGeoJSON(data) {
|
|
161
|
+
if (typeof data === 'function') {
|
|
162
|
+
return data();
|
|
163
|
+
}
|
|
164
|
+
return data;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const data = this._data;
|
|
168
|
+
loadGeoJSON(data)
|
|
169
|
+
.catch(() => {})
|
|
170
|
+
.then(json => {
|
|
171
|
+
if (!json) {
|
|
172
|
+
return callback(new Error('no GeoJSON data'));
|
|
173
|
+
}
|
|
174
|
+
const options = Object.assign({}, this.workerOptions);
|
|
175
|
+
options.data = JSON.stringify(json);
|
|
176
|
+
// target {this.type}.loadData rather than literally geojson.loadData,
|
|
177
|
+
// so that other geojson-like source types can easily reuse this
|
|
178
|
+
// implementation
|
|
179
|
+
this.workerID = this.dispatcher.send(
|
|
180
|
+
`${this.type}.loadData`,
|
|
181
|
+
options,
|
|
182
|
+
(err, result) => {
|
|
183
|
+
if (this._removed || result?.abandoned) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this._loaded = true;
|
|
188
|
+
|
|
189
|
+
if (result?.resourceTiming?.[this.id]) this._resourceTiming = result.resourceTiming[this.id].slice(0);
|
|
190
|
+
// Any `loadData` calls that piled up while we were processing
|
|
191
|
+
// this one will get coalesced into a single call when this
|
|
192
|
+
// 'coalesce' message is processed.
|
|
193
|
+
// We would self-send from the worker if we had access to its
|
|
194
|
+
// message queue. Waiting instead for the 'coalesce' to round-trip
|
|
195
|
+
// through the foreground just means we're throttling the worker
|
|
196
|
+
// to run at a little less than full-throttle.
|
|
197
|
+
this.dispatcher.send(`${this.type}.coalesce`, { source: options.source }, null, this.workerID);
|
|
198
|
+
callback(err);
|
|
199
|
+
},
|
|
200
|
+
this.workerID
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
loadTile(tile, callback) {
|
|
206
|
+
const message = tile.workerID === undefined ? 'loadTile' : 'reloadTile';
|
|
207
|
+
const params = {
|
|
208
|
+
type: this.type,
|
|
209
|
+
uid: tile.uid,
|
|
210
|
+
tileID: tile.tileID,
|
|
211
|
+
zoom: tile.tileID.overscaledZ,
|
|
212
|
+
maxZoom: this.maxzoom,
|
|
213
|
+
tileSize: this.tileSize,
|
|
214
|
+
source: this.id,
|
|
215
|
+
pixelRatio: browser.devicePixelRatio,
|
|
216
|
+
showCollisionBoxes: this.map.showCollisionBoxes
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
tile.workerID = this.dispatcher.send(
|
|
220
|
+
message,
|
|
221
|
+
params,
|
|
222
|
+
(err, data) => {
|
|
223
|
+
tile.unloadVectorData();
|
|
224
|
+
|
|
225
|
+
if (tile.aborted) {
|
|
226
|
+
return callback(null);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (err) {
|
|
230
|
+
return callback(err);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
tile.loadVectorData(data, this.map.painter, message === 'reloadTile');
|
|
234
|
+
|
|
235
|
+
return callback(null);
|
|
236
|
+
},
|
|
237
|
+
this.workerID
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
abortTile(tile) {
|
|
242
|
+
tile.aborted = true;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
unloadTile(tile) {
|
|
246
|
+
tile.unloadVectorData();
|
|
247
|
+
this.dispatcher.send('removeTile', { uid: tile.uid, type: this.type, source: this.id }, null, tile.workerID);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
onRemove() {
|
|
251
|
+
this._removed = true;
|
|
252
|
+
this.dispatcher.send('removeSource', { type: this.type, source: this.id }, null, this.workerID);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
serialize() {
|
|
256
|
+
return Object.assign({}, this._options, {
|
|
257
|
+
type: this.type,
|
|
258
|
+
data: this._data
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
hasTransition() {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
module.exports = GeoJSONSource;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
const rewind = require('@mapwhit/geojson-rewind');
|
|
2
|
+
const GeoJSONWrapper = require('./geojson_wrapper');
|
|
3
|
+
const vtpbf = require('@mapwhit/vt-pbf');
|
|
4
|
+
const supercluster = require('supercluster');
|
|
5
|
+
const geojsonvt = require('geojson-vt');
|
|
6
|
+
const assert = require('assert');
|
|
7
|
+
const VectorTileWorkerSource = require('./vector_tile_worker_source');
|
|
8
|
+
|
|
9
|
+
function loadGeoJSONTile(params, callback) {
|
|
10
|
+
const canonical = params.tileID.canonical;
|
|
11
|
+
|
|
12
|
+
if (!this._geoJSONIndex) {
|
|
13
|
+
return callback(null, null); // we couldn't load the file
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const geoJSONTile = this._geoJSONIndex.getTile(canonical.z, canonical.x, canonical.y);
|
|
17
|
+
if (!geoJSONTile) {
|
|
18
|
+
return callback(null, null); // nothing in the given tile
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const geojsonWrapper = new GeoJSONWrapper(geoJSONTile.features);
|
|
22
|
+
|
|
23
|
+
// Encode the geojson-vt tile into binary vector tile form. This
|
|
24
|
+
// is a convenience that allows `FeatureIndex` to operate the same way
|
|
25
|
+
// across `VectorTileSource` and `GeoJSONSource` data.
|
|
26
|
+
let pbf = vtpbf(geojsonWrapper);
|
|
27
|
+
if (pbf.byteOffset !== 0 || pbf.byteLength !== pbf.buffer.byteLength) {
|
|
28
|
+
// Compatibility with node Buffer (https://github.com/mapbox/pbf/issues/35)
|
|
29
|
+
pbf = new Uint8Array(pbf);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
callback(null, {
|
|
33
|
+
vectorTile: geojsonWrapper,
|
|
34
|
+
rawData: pbf.buffer
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// 'loadData' received while coalescing, trigger one more 'loadData' on receiving 'coalesced'
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The {@link WorkerSource} implementation that supports {@link GeoJSONSource}.
|
|
42
|
+
* This class is designed to be easily reused to support custom source types
|
|
43
|
+
* for data formats that can be parsed/converted into an in-memory GeoJSON
|
|
44
|
+
* representation. To do so, create it with
|
|
45
|
+
* `new GeoJSONWorkerSource(actor, layerIndex, customLoadGeoJSONFunction)`.
|
|
46
|
+
* For a full example, see [mapbox-gl-topojson](https://github.com/developmentseed/mapbox-gl-topojson).
|
|
47
|
+
*
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
class GeoJSONWorkerSource extends VectorTileWorkerSource {
|
|
51
|
+
/**
|
|
52
|
+
* @param [loadGeoJSON] Optional method for custom loading/parsing of
|
|
53
|
+
* GeoJSON based on parameters passed from the main-thread Source.
|
|
54
|
+
* See {@link GeoJSONWorkerSource#loadGeoJSON}.
|
|
55
|
+
*/
|
|
56
|
+
constructor(actor, layerIndex, loadGeoJSON) {
|
|
57
|
+
super(actor, layerIndex, loadGeoJSONTile);
|
|
58
|
+
if (loadGeoJSON) {
|
|
59
|
+
this.loadGeoJSON = loadGeoJSON;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Fetches (if appropriate), parses, and index geojson data into tiles. This
|
|
65
|
+
* preparatory method must be called before {@link GeoJSONWorkerSource#loadTile}
|
|
66
|
+
* can correctly serve up tiles.
|
|
67
|
+
*
|
|
68
|
+
* Defers to {@link GeoJSONWorkerSource#loadGeoJSON} for the fetching/parsing,
|
|
69
|
+
* expecting `callback(error, data)` to be called with either an error or a
|
|
70
|
+
* parsed GeoJSON object.
|
|
71
|
+
*
|
|
72
|
+
* When `loadData` requests come in faster than they can be processed,
|
|
73
|
+
* they are coalesced into a single request using the latest data.
|
|
74
|
+
* See {@link GeoJSONWorkerSource#coalesce}
|
|
75
|
+
*
|
|
76
|
+
* @param params
|
|
77
|
+
* @param callback
|
|
78
|
+
*/
|
|
79
|
+
loadData(params, callback) {
|
|
80
|
+
if (this._pendingCallback) {
|
|
81
|
+
// Tell the foreground the previous call has been abandoned
|
|
82
|
+
this._pendingCallback(null, { abandoned: true });
|
|
83
|
+
}
|
|
84
|
+
this._pendingCallback = callback;
|
|
85
|
+
this._pendingLoadDataParams = params;
|
|
86
|
+
|
|
87
|
+
if (this._state && this._state !== 'Idle') {
|
|
88
|
+
this._state = 'NeedsLoadData';
|
|
89
|
+
} else {
|
|
90
|
+
this._state = 'Coalescing';
|
|
91
|
+
this._loadData();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Internal implementation: called directly by `loadData`
|
|
97
|
+
* or by `coalesce` using stored parameters.
|
|
98
|
+
*/
|
|
99
|
+
_loadData() {
|
|
100
|
+
if (!this._pendingCallback || !this._pendingLoadDataParams) {
|
|
101
|
+
assert(false);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const callback = this._pendingCallback;
|
|
105
|
+
const params = this._pendingLoadDataParams;
|
|
106
|
+
delete this._pendingCallback;
|
|
107
|
+
delete this._pendingLoadDataParams;
|
|
108
|
+
this.loadGeoJSON(params, (err, data) => {
|
|
109
|
+
if (err || !data) {
|
|
110
|
+
return callback(err);
|
|
111
|
+
}
|
|
112
|
+
if (typeof data !== 'object') {
|
|
113
|
+
return callback(new Error('Input data is not a valid GeoJSON object.'));
|
|
114
|
+
}
|
|
115
|
+
rewind(data, true);
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
this._geoJSONIndex = params.cluster
|
|
119
|
+
? supercluster(params.superclusterOptions).load(data.features)
|
|
120
|
+
: geojsonvt(data, params.geojsonVtOptions);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
return callback(err);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.loaded = {};
|
|
126
|
+
|
|
127
|
+
const result = {};
|
|
128
|
+
callback(null, result);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* While processing `loadData`, we coalesce all further
|
|
134
|
+
* `loadData` messages into a single call to _loadData
|
|
135
|
+
* that will happen once we've finished processing the
|
|
136
|
+
* first message. {@link GeoJSONSource#_updateWorkerData}
|
|
137
|
+
* is responsible for sending us the `coalesce` message
|
|
138
|
+
* at the time it receives a response from `loadData`
|
|
139
|
+
*
|
|
140
|
+
* State: Idle
|
|
141
|
+
* ↑ |
|
|
142
|
+
* 'coalesce' 'loadData'
|
|
143
|
+
* | (triggers load)
|
|
144
|
+
* | ↓
|
|
145
|
+
* State: Coalescing
|
|
146
|
+
* ↑ |
|
|
147
|
+
* (triggers load) |
|
|
148
|
+
* 'coalesce' 'loadData'
|
|
149
|
+
* | ↓
|
|
150
|
+
* State: NeedsLoadData
|
|
151
|
+
*/
|
|
152
|
+
coalesce() {
|
|
153
|
+
if (this._state === 'Coalescing') {
|
|
154
|
+
this._state = 'Idle';
|
|
155
|
+
} else if (this._state === 'NeedsLoadData') {
|
|
156
|
+
this._state = 'Coalescing';
|
|
157
|
+
this._loadData();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Implements {@link WorkerSource#reloadTile}.
|
|
163
|
+
*
|
|
164
|
+
* If the tile is loaded, uses the implementation in VectorTileWorkerSource.
|
|
165
|
+
* Otherwise, such as after a setData() call, we load the tile fresh.
|
|
166
|
+
*
|
|
167
|
+
* @param params
|
|
168
|
+
* @param params.uid The UID for this tile.
|
|
169
|
+
*/
|
|
170
|
+
reloadTile(params, callback) {
|
|
171
|
+
const loaded = this.loaded;
|
|
172
|
+
const uid = params.uid;
|
|
173
|
+
|
|
174
|
+
if (loaded?.[uid]) {
|
|
175
|
+
return super.reloadTile(params, callback);
|
|
176
|
+
}
|
|
177
|
+
return this.loadTile(params, callback);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Fetch and parse GeoJSON according to the given params. Calls `callback`
|
|
182
|
+
* with `(err, data)`, where `data` is a parsed GeoJSON object.
|
|
183
|
+
*
|
|
184
|
+
* GeoJSON is expected as a literal (string or object) `params.data`.
|
|
185
|
+
*
|
|
186
|
+
* @param params
|
|
187
|
+
* @param [params.data] Literal GeoJSON data. Must be provided.
|
|
188
|
+
*/
|
|
189
|
+
loadGeoJSON(params, callback) {
|
|
190
|
+
if (typeof params.data === 'string') {
|
|
191
|
+
try {
|
|
192
|
+
return callback(null, JSON.parse(params.data));
|
|
193
|
+
} catch (e) {
|
|
194
|
+
return callback(new Error('Input data is not a valid GeoJSON object.'));
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
return callback(new Error('Input data is not a valid GeoJSON object.'));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
removeSource(params, callback) {
|
|
202
|
+
if (this._pendingCallback) {
|
|
203
|
+
// Don't leak callbacks
|
|
204
|
+
this._pendingCallback(null, { abandoned: true });
|
|
205
|
+
}
|
|
206
|
+
callback();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
module.exports = GeoJSONWorkerSource;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const Point = require('@mapbox/point-geometry');
|
|
2
|
+
|
|
3
|
+
const mvt = require('@mapbox/vector-tile');
|
|
4
|
+
const toGeoJSON = mvt.VectorTileFeature.prototype.toGeoJSON;
|
|
5
|
+
const EXTENT = require('../data/extent');
|
|
6
|
+
|
|
7
|
+
// The feature type used by geojson-vt and supercluster. Should be extracted to
|
|
8
|
+
// global type and used in module definitions for those two modules.
|
|
9
|
+
|
|
10
|
+
class FeatureWrapper {
|
|
11
|
+
constructor(feature) {
|
|
12
|
+
this._feature = feature;
|
|
13
|
+
|
|
14
|
+
this.extent = EXTENT;
|
|
15
|
+
this.type = feature.type;
|
|
16
|
+
this.properties = feature.tags;
|
|
17
|
+
|
|
18
|
+
// If the feature has a top-level `id` property, copy it over, but only
|
|
19
|
+
// if it can be coerced to an integer, because this wrapper is used for
|
|
20
|
+
// serializing geojson feature data into vector tile PBF data, and the
|
|
21
|
+
// vector tile spec only supports integer values for feature ids --
|
|
22
|
+
// allowing non-integer values here results in a non-compliant PBF
|
|
23
|
+
// that causes an exception when it is parsed with vector-tile-js
|
|
24
|
+
if ('id' in feature && !isNaN(feature.id)) {
|
|
25
|
+
this.id = Number.parseInt(feature.id, 10);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
loadGeometry() {
|
|
30
|
+
if (this._feature.type === 1) {
|
|
31
|
+
const geometry = [];
|
|
32
|
+
for (const point of this._feature.geometry) {
|
|
33
|
+
geometry.push([new Point(point[0], point[1])]);
|
|
34
|
+
}
|
|
35
|
+
return geometry;
|
|
36
|
+
}
|
|
37
|
+
const geometry = [];
|
|
38
|
+
for (const ring of this._feature.geometry) {
|
|
39
|
+
const newRing = [];
|
|
40
|
+
for (const point of ring) {
|
|
41
|
+
newRing.push(new Point(point[0], point[1]));
|
|
42
|
+
}
|
|
43
|
+
geometry.push(newRing);
|
|
44
|
+
}
|
|
45
|
+
return geometry;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
toGeoJSON(x, y, z) {
|
|
49
|
+
return toGeoJSON.call(this, x, y, z);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class GeoJSONWrapper {
|
|
54
|
+
constructor(features) {
|
|
55
|
+
this.layers = { _geojsonTileLayer: this };
|
|
56
|
+
this.name = '_geojsonTileLayer';
|
|
57
|
+
this.extent = EXTENT;
|
|
58
|
+
this.length = features.length;
|
|
59
|
+
this._features = features;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
feature(i) {
|
|
63
|
+
return new FeatureWrapper(this._features[i]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = GeoJSONWrapper;
|