@tangram.gl/tangram-renderer 0.0.0-stage → 0.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/README.md +59 -2
- package/dist/core.js +36923 -0
- package/dist/core.js.map +6 -0
- package/dist/index.js +32 -0
- package/dist/loaders-gl-worker.js +82 -0
- package/dist/loaders-gl-worker.js.map +6 -0
- package/dist/map-logic.js +2 -0
- package/dist/map-logic.js.map +6 -0
- package/dist/projected-basemaps-worker.js +3 -0
- package/dist/projected-basemaps-worker.js.map +6 -0
- package/dist/shader-modules.js +141 -0
- package/dist/shader-modules.js.map +6 -0
- package/dist/style-schema.js +126 -0
- package/dist/style-schema.js.map +6 -0
- package/dist/tangram-style.schema.json +882 -0
- package/dist/tangram.debug.mjs +37139 -0
- package/dist/tangram.debug.mjs.map +6 -0
- package/dist/tangram.min.mjs +4950 -0
- package/dist/types/builders/earcut.d.ts +15 -0
- package/dist/types/core.d.ts +29 -0
- package/dist/types/gl/constants.d.ts +2 -0
- package/dist/types/gl/globe_mesh.d.ts +48 -0
- package/dist/types/gl/glsl.d.ts +17 -0
- package/dist/types/gl/vertex-constants.d.ts +4 -0
- package/dist/types/gl/vertex-types.d.ts +34 -0
- package/dist/types/gl/vertex_data.d.ts +32 -0
- package/dist/types/gl/vertex_elements.d.ts +8 -0
- package/dist/types/gl/vertex_layout.d.ts +32 -0
- package/dist/types/glsl.d.ts +14 -0
- package/dist/types/gpu/luma_device_renderer.d.ts +66 -0
- package/dist/types/gpu/resource_lifecycle.d.ts +4 -0
- package/dist/types/gpu/tangram_gpu_backend.d.ts +151 -0
- package/dist/types/index.d.ts +155 -0
- package/dist/types/lights/light-definitions.d.ts +121 -0
- package/dist/types/map-logic/draped-terrain-bounds.d.ts +41 -0
- package/dist/types/map-logic/globe-terrain-preparation.d.ts +85 -0
- package/dist/types/map-logic/globe-terrain.d.ts +54 -0
- package/dist/types/map-logic/index.d.ts +33 -0
- package/dist/types/map-logic/label-identity.d.ts +22 -0
- package/dist/types/map-logic/label-placement.d.ts +32 -0
- package/dist/types/map-logic/screen-bounds.d.ts +15 -0
- package/dist/types/map-logic/terrain-data.d.ts +55 -0
- package/dist/types/map-logic/terrain-error.d.ts +51 -0
- package/dist/types/map-logic/terrain-ground-topology.d.ts +26 -0
- package/dist/types/map-logic/terrain-height-field.d.ts +59 -0
- package/dist/types/map-logic/terrain-navigation.d.ts +27 -0
- package/dist/types/map-logic/terrain-neighborhood.d.ts +5 -0
- package/dist/types/map-logic/terrain-query.d.ts +33 -0
- package/dist/types/map-logic/terrain-resource-budget.d.ts +51 -0
- package/dist/types/map-logic/terrain-transition-topology.d.ts +23 -0
- package/dist/types/map-logic/tile-build-queue.d.ts +51 -0
- package/dist/types/map-logic/tile-cache-policy.d.ts +46 -0
- package/dist/types/map-logic/tile-residency.d.ts +17 -0
- package/dist/types/map-logic/triangle-query-index.d.ts +87 -0
- package/dist/types/procedures/js-yaml.d.ts +15 -0
- package/dist/types/procedures/mesh-projector.d.ts +107 -0
- package/dist/types/procedures/mvt-dependencies.d.ts +20 -0
- package/dist/types/procedures/projected-coordinate-transform.d.ts +27 -0
- package/dist/types/procedures/projection-batch-executor.d.ts +53 -0
- package/dist/types/procedures/scene-yaml-legacy.d.ts +6 -0
- package/dist/types/procedures/terrain-draping.d.ts +165 -0
- package/dist/types/procedures/terrain-globe.d.ts +6 -0
- package/dist/types/procedures/terrain-styled-topology.d.ts +34 -0
- package/dist/types/procedures/web-mercator-legacy.d.ts +4 -0
- package/dist/types/procedures/web-mercator-math.d.ts +4 -0
- package/dist/types/scene/globals.d.ts +11 -0
- package/dist/types/scene/ground_footprint.d.ts +16 -0
- package/dist/types/scene/host_frame.d.ts +54 -0
- package/dist/types/scene/projection_math.d.ts +52 -0
- package/dist/types/scene/scene-resource-types.d.ts +177 -0
- package/dist/types/scene/scene_bundle.d.ts +69 -0
- package/dist/types/scene/visibility_adapter.d.ts +106 -0
- package/dist/types/selection/draped-terrain-surface.d.ts +78 -0
- package/dist/types/selection/terrain_surface.d.ts +149 -0
- package/dist/types/shader-modules/globe-horizon.d.ts +15 -0
- package/dist/types/shader-modules/height-decode.d.ts +13 -0
- package/dist/types/shader-modules/hillshade.d.ts +13 -0
- package/dist/types/shader-modules/index.d.ts +6 -0
- package/dist/types/shader-modules/planar.d.ts +12 -0
- package/dist/types/shader-modules/sphere-map.d.ts +13 -0
- package/dist/types/shader-modules/triplanar.d.ts +15 -0
- package/dist/types/sources/decoded_tile_store.d.ts +95 -0
- package/dist/types/sources/tile_source_metadata.d.ts +32 -0
- package/dist/types/styles/text/fontfaceobserver.d.ts +10 -0
- package/dist/types/tile/tile_id.d.ts +37 -0
- package/dist/types/tile/tile_traversal_adapter.d.ts +63 -0
- package/dist/types/types.d.ts +293 -0
- package/dist/types/utils/geo.d.ts +57 -0
- package/dist/types/utils/hash.d.ts +1 -0
- package/dist/types/utils/log.d.ts +27 -0
- package/dist/types/utils/props.d.ts +6 -0
- package/dist/types/utils/subscribe.d.ts +10 -0
- package/dist/types/utils/thread.d.ts +6 -0
- package/dist/types/utils/urls.d.ts +26 -0
- package/dist/types/utils/utils.d.ts +26 -0
- package/dist/types/utils/version.d.ts +2 -0
- package/dist/types/utils/worker-types.d.ts +68 -0
- package/dist/types/utils/worker_broker.d.ts +3 -0
- package/package.json +103 -3
- package/src/builders/common.ts +41 -0
- package/src/builders/earcut.d.ts +15 -0
- package/src/builders/geometry-types.ts +60 -0
- package/src/builders/points.ts +115 -0
- package/src/builders/polygons.ts +225 -0
- package/src/builders/polylines.ts +682 -0
- package/src/builders/wireframe.ts +31 -0
- package/src/core.d.ts +29 -0
- package/src/core.ts +33 -0
- package/src/experimental/loaders-gl-worker.ts +19 -0
- package/src/experimental/projected-basemaps-worker.ts +13 -0
- package/src/experimental/projected-mesh-cache.ts +137 -0
- package/src/experimental/projected-mesh-domain.ts +110 -0
- package/src/experimental/projected-mesh-refinement.ts +193 -0
- package/src/experimental/projected-mesh.ts +399 -0
- package/src/experimental/projected-normal.ts +26 -0
- package/src/experimental/projected-symbol-mesh.ts +74 -0
- package/src/gl/constants.ts +18 -0
- package/src/gl/context.ts +103 -0
- package/src/gl/extensions.ts +30 -0
- package/src/gl/globe_mesh.ts +285 -0
- package/src/gl/glsl.ts +257 -0
- package/src/gl/mesh-types.ts +56 -0
- package/src/gl/render_state.ts +111 -0
- package/src/gl/shader_program.ts +1310 -0
- package/src/gl/texture.ts +814 -0
- package/src/gl/uniform_buffer.ts +340 -0
- package/src/gl/vao.ts +154 -0
- package/src/gl/vbo_mesh.ts +349 -0
- package/src/gl/vertex-constants.ts +19 -0
- package/src/gl/vertex-types.ts +35 -0
- package/src/gl/vertex_data.ts +126 -0
- package/src/gl/vertex_elements.ts +54 -0
- package/src/gl/vertex_layout.ts +241 -0
- package/src/glsl.d.ts +14 -0
- package/src/gpu/luma_device_renderer.ts +579 -0
- package/src/gpu/pixel_readback.ts +51 -0
- package/src/gpu/resource_lifecycle.ts +32 -0
- package/src/gpu/tangram_gpu_backend.ts +195 -0
- package/src/index.d.ts +155 -0
- package/src/index.ts +105 -0
- package/src/labels/collision-types.ts +94 -0
- package/src/labels/collision.ts +273 -0
- package/src/labels/collision_grid.ts +61 -0
- package/src/labels/intersect.ts +30 -0
- package/src/labels/label-types.ts +91 -0
- package/src/labels/label.ts +207 -0
- package/src/labels/label_line.ts +801 -0
- package/src/labels/label_point.ts +131 -0
- package/src/labels/main-pass-types.ts +73 -0
- package/src/labels/main_pass.ts +221 -0
- package/src/labels/point_anchor.ts +100 -0
- package/src/labels/point_placement.ts +150 -0
- package/src/labels/projected-pass.ts +259 -0
- package/src/labels/repeat_group.ts +72 -0
- package/src/lights/ambient_light.glsl +18 -0
- package/src/lights/directional_light.glsl +39 -0
- package/src/lights/geographic-lights.ts +21 -0
- package/src/lights/light-definitions.ts +285 -0
- package/src/lights/light.ts +590 -0
- package/src/lights/lighting-uniforms.ts +80 -0
- package/src/lights/lighting-wgsl.ts +116 -0
- package/src/lights/material.glsl +237 -0
- package/src/lights/material.ts +145 -0
- package/src/lights/native-falloff.ts +37 -0
- package/src/lights/point_light.glsl +96 -0
- package/src/lights/spot_light.glsl +111 -0
- package/src/map-logic/draped-terrain-bounds.ts +71 -0
- package/src/map-logic/globe-terrain-preparation.ts +217 -0
- package/src/map-logic/globe-terrain.ts +296 -0
- package/src/map-logic/index.ts +37 -0
- package/src/map-logic/label-identity.ts +36 -0
- package/src/map-logic/label-placement.ts +117 -0
- package/src/map-logic/screen-bounds.ts +34 -0
- package/src/map-logic/terrain-data.ts +107 -0
- package/src/map-logic/terrain-error.ts +134 -0
- package/src/map-logic/terrain-ground-topology.ts +164 -0
- package/src/map-logic/terrain-height-field.ts +254 -0
- package/src/map-logic/terrain-navigation.ts +50 -0
- package/src/map-logic/terrain-neighborhood.ts +43 -0
- package/src/map-logic/terrain-query.ts +51 -0
- package/src/map-logic/terrain-resource-budget.ts +124 -0
- package/src/map-logic/terrain-transition-topology.ts +164 -0
- package/src/map-logic/tile-build-queue.ts +110 -0
- package/src/map-logic/tile-cache-policy.ts +89 -0
- package/src/map-logic/tile-residency.ts +50 -0
- package/src/map-logic/triangle-query-index.ts +265 -0
- package/src/procedures/js-yaml.d.ts +15 -0
- package/src/procedures/mesh-projector.ts +191 -0
- package/src/procedures/mlt-loaders.ts +55 -0
- package/src/procedures/mvt-dependencies.d.ts +20 -0
- package/src/procedures/mvt-legacy.ts +150 -0
- package/src/procedures/mvt-loaders.ts +53 -0
- package/src/procedures/mvt-parser.ts +48 -0
- package/src/procedures/mvt-properties.ts +36 -0
- package/src/procedures/mvt-tile-provider.ts +72 -0
- package/src/procedures/pmtiles-loader.ts +75 -0
- package/src/procedures/projected-coordinate-transform.ts +79 -0
- package/src/procedures/projection-batch-executor.ts +140 -0
- package/src/procedures/scene-yaml-legacy.ts +16 -0
- package/src/procedures/scene-yaml-loaders.ts +10 -0
- package/src/procedures/terrain-draping.ts +713 -0
- package/src/procedures/terrain-globe.ts +32 -0
- package/src/procedures/terrain-styled-topology.ts +184 -0
- package/src/procedures/web-mercator-legacy.ts +24 -0
- package/src/procedures/web-mercator-math.ts +50 -0
- package/src/scene/camera.ts +298 -0
- package/src/scene/camera_base.ts +116 -0
- package/src/scene/classic_scene.ts +20 -0
- package/src/scene/external_camera.ts +101 -0
- package/src/scene/globals.ts +120 -0
- package/src/scene/ground_footprint.ts +139 -0
- package/src/scene/host_frame.ts +326 -0
- package/src/scene/projected_tile_lod.ts +125 -0
- package/src/scene/projection_math.ts +142 -0
- package/src/scene/projection_shaders.ts +183 -0
- package/src/scene/renderer.ts +516 -0
- package/src/scene/scene-resource-types.ts +174 -0
- package/src/scene/scene.ts +2378 -0
- package/src/scene/scene_bundle.ts +304 -0
- package/src/scene/scene_debug.ts +129 -0
- package/src/scene/scene_loader.ts +402 -0
- package/src/scene/scene_worker.ts +528 -0
- package/src/scene/view.ts +683 -0
- package/src/scene/visibility_adapter.ts +319 -0
- package/src/scene/worker_url.ts +15 -0
- package/src/selection/draped-terrain-surface.ts +377 -0
- package/src/selection/selection-types.ts +79 -0
- package/src/selection/selection.ts +542 -0
- package/src/selection/selection_fragment.glsl +18 -0
- package/src/selection/selection_globals.glsl +9 -0
- package/src/selection/selection_pixels.ts +59 -0
- package/src/selection/selection_vertex.glsl +15 -0
- package/src/selection/terrain_surface.ts +298 -0
- package/src/shader-modules/globe-horizon.ts +52 -0
- package/src/shader-modules/height-decode.ts +41 -0
- package/src/shader-modules/hillshade.ts +70 -0
- package/src/shader-modules/index.ts +10 -0
- package/src/shader-modules/planar.ts +24 -0
- package/src/shader-modules/sphere-map.ts +38 -0
- package/src/shader-modules/triplanar.ts +45 -0
- package/src/sources/aligned_tile_source.ts +122 -0
- package/src/sources/data_source.ts +655 -0
- package/src/sources/decoded_tile_store.ts +245 -0
- package/src/sources/geojson.ts +300 -0
- package/src/sources/mvt.ts +247 -0
- package/src/sources/raster.ts +341 -0
- package/src/sources/shared_tile_source_adapter.ts +117 -0
- package/src/sources/sources.ts +10 -0
- package/src/sources/tile_source_adapter.ts +84 -0
- package/src/sources/tile_source_metadata.ts +65 -0
- package/src/sources/tile_source_state.ts +112 -0
- package/src/sources/topojson.ts +90 -0
- package/src/styles/feature_annotations.ts +16 -0
- package/src/styles/filter.ts +190 -0
- package/src/styles/geometry-style-types.ts +209 -0
- package/src/styles/globe_visibility_wgsl.ts +22 -0
- package/src/styles/layer-types.ts +45 -0
- package/src/styles/layer.ts +586 -0
- package/src/styles/lines/dasharray.ts +49 -0
- package/src/styles/lines/lines.ts +707 -0
- package/src/styles/lines/lines_wgsl.ts +224 -0
- package/src/styles/points/point-runtime-types.ts +125 -0
- package/src/styles/points/points.ts +1079 -0
- package/src/styles/points/points_fragment.glsl +126 -0
- package/src/styles/points/points_vertex.glsl +230 -0
- package/src/styles/points/points_wgsl.ts +189 -0
- package/src/styles/polygons/polygons.ts +268 -0
- package/src/styles/polygons/polygons_fragment.glsl +173 -0
- package/src/styles/polygons/polygons_vertex.glsl +213 -0
- package/src/styles/polygons/polygons_wgsl.ts +127 -0
- package/src/styles/property-types.ts +125 -0
- package/src/styles/raster/raster.ts +33 -0
- package/src/styles/raster/raster_globals.glsl +46 -0
- package/src/styles/style-mixing-types.ts +101 -0
- package/src/styles/style-runtime-types.ts +220 -0
- package/src/styles/style-schema.ts +133 -0
- package/src/styles/style.ts +1033 -0
- package/src/styles/style_globals.glsl +69 -0
- package/src/styles/style_manager.ts +464 -0
- package/src/styles/style_parser.ts +620 -0
- package/src/styles/text/font_manager.ts +180 -0
- package/src/styles/text/fontfaceobserver.d.ts +10 -0
- package/src/styles/text/text-types.ts +220 -0
- package/src/styles/text/text.ts +378 -0
- package/src/styles/text/text_canvas.ts +773 -0
- package/src/styles/text/text_labels.ts +436 -0
- package/src/styles/text/text_segments.ts +142 -0
- package/src/styles/text/text_settings.ts +228 -0
- package/src/styles/text/text_wgsl.ts +159 -0
- package/src/styles/text/text_wrap.ts +194 -0
- package/src/tile/globe_tile_preload.ts +40 -0
- package/src/tile/tangram_tileset_2d.ts +108 -0
- package/src/tile/tile-build-types.ts +155 -0
- package/src/tile/tile.ts +807 -0
- package/src/tile/tile_id.ts +172 -0
- package/src/tile/tile_manager.ts +889 -0
- package/src/tile/tile_pyramid.ts +119 -0
- package/src/tile/tile_resource_cache.ts +91 -0
- package/src/tile/tile_traversal_adapter.ts +132 -0
- package/src/types.ts +332 -0
- package/src/utils/debounce.ts +17 -0
- package/src/utils/debug_settings.ts +43 -0
- package/src/utils/errors.ts +12 -0
- package/src/utils/functions.ts +95 -0
- package/src/utils/geo.ts +364 -0
- package/src/utils/hash.ts +14 -0
- package/src/utils/log.ts +108 -0
- package/src/utils/media_capture.ts +193 -0
- package/src/utils/merge.ts +44 -0
- package/src/utils/obb.ts +134 -0
- package/src/utils/props.ts +43 -0
- package/src/utils/slice.ts +14 -0
- package/src/utils/subscribe.ts +58 -0
- package/src/utils/task.ts +154 -0
- package/src/utils/thread.ts +26 -0
- package/src/utils/urls.ts +223 -0
- package/src/utils/utils.ts +310 -0
- package/src/utils/vector.ts +197 -0
- package/src/utils/version.ts +8 -0
- package/src/utils/worker-types.ts +79 -0
- package/src/utils/worker_broker.ts +523 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// Tangram
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) 2013-2016 Brett Camper and Mapzen
|
|
4
|
+
// Copyright (c) 2026 vis.gl contributors
|
|
5
|
+
|
|
6
|
+
import DataSource, {NetworkTileSource} from './data_source';
|
|
7
|
+
import Geo from '../utils/geo';
|
|
8
|
+
import log from '../utils/log';
|
|
9
|
+
import {
|
|
10
|
+
convertMvtTileWithLegacy,
|
|
11
|
+
decodeMultiPolygon,
|
|
12
|
+
parseMvtWithLegacy,
|
|
13
|
+
type MvtTile
|
|
14
|
+
} from '../procedures/mvt-legacy';
|
|
15
|
+
import {parseMvt, registerMvtDecoder} from '../procedures/mvt-parser';
|
|
16
|
+
import {getMvtTileProvider} from '../procedures/mvt-tile-provider';
|
|
17
|
+
import type {MvtTileProviderSource} from '../procedures/mvt-tile-provider';
|
|
18
|
+
import {parseMvtJsonProperties} from '../procedures/mvt-properties';
|
|
19
|
+
import {createTileSourceMetadata} from './tile_source_metadata';
|
|
20
|
+
import type {TangramTileSourceMetadata} from './tile_source_metadata';
|
|
21
|
+
import {updateTileSourceRequest} from './tile_source_state';
|
|
22
|
+
|
|
23
|
+
const PARSE_JSON_TYPE = {
|
|
24
|
+
NONE: 0,
|
|
25
|
+
ALL: 1,
|
|
26
|
+
SOME: 2
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type MvtSourceConfig = {
|
|
30
|
+
decoder?: string;
|
|
31
|
+
tile_provider?: string;
|
|
32
|
+
parse_json?: boolean | readonly string[];
|
|
33
|
+
name?: string;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type TileData = {
|
|
38
|
+
/** Worker cancellation may precede deferred TileJSON URL resolution. */
|
|
39
|
+
canceled?: boolean;
|
|
40
|
+
min: Record<string, unknown>;
|
|
41
|
+
max: Record<string, unknown>;
|
|
42
|
+
coords: Record<string, unknown> & {x: number; y: number; z: number};
|
|
43
|
+
source_data?: SourceData;
|
|
44
|
+
debug?: Record<string, any>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type SourceData = {
|
|
48
|
+
layers?: Record<string, unknown>;
|
|
49
|
+
url?: string;
|
|
50
|
+
error?: string | null;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
Mapbox Vector Tile format
|
|
55
|
+
@class MVTSource
|
|
56
|
+
*/
|
|
57
|
+
export class MVTSource extends NetworkTileSource {
|
|
58
|
+
|
|
59
|
+
decoder!: string;
|
|
60
|
+
tile_provider?: string;
|
|
61
|
+
parse_json_type!: number;
|
|
62
|
+
parse_json_prop_list?: readonly string[];
|
|
63
|
+
/** Archive handles belong to this source instance, never a global URL cache. */
|
|
64
|
+
private providerSources = new Map<string, MvtTileProviderSource>();
|
|
65
|
+
/** Source replacement cancels every live tile request, including custom function providers. */
|
|
66
|
+
private providerRequests = new Set<AbortController>();
|
|
67
|
+
/** Additional archive credits are retained separately from scene-authored attribution. */
|
|
68
|
+
private providerAttributions: string[] = [];
|
|
69
|
+
/** Disposed instances cannot reopen an archive after asynchronous URL resolution. */
|
|
70
|
+
private disposed = false;
|
|
71
|
+
|
|
72
|
+
/** Resolve a factory once per effective URL; stateless registered functions stay unchanged. */
|
|
73
|
+
private getProviderSource(url: string): MvtTileProviderSource | undefined {
|
|
74
|
+
if (this.disposed) throw new Error('MVT source is disposed');
|
|
75
|
+
const provider = this.tile_provider && getMvtTileProvider(this.tile_provider);
|
|
76
|
+
if (!provider) throw new Error(`MVT tile provider '${this.tile_provider}' is not registered in this worker`);
|
|
77
|
+
if (typeof provider === 'function') return undefined;
|
|
78
|
+
let source = this.providerSources.get(url);
|
|
79
|
+
if (!source) {
|
|
80
|
+
source = provider.createSource(url, {headers: this.request_headers});
|
|
81
|
+
this.providerSources.set(url, source);
|
|
82
|
+
}
|
|
83
|
+
return source;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Include provider credits alongside authored and TileJSON attribution. */
|
|
87
|
+
getAttributions(): string[] { return [...new Set([...super.getAttributions(), ...this.providerAttributions])]; }
|
|
88
|
+
|
|
89
|
+
/** Normalize TileJSON and archive capabilities without changing authored layout or decoder choice. */
|
|
90
|
+
async getMetadata(): Promise<TangramTileSourceMetadata> {
|
|
91
|
+
if (!this.tile_provider) return super.getMetadata();
|
|
92
|
+
const url = await this.resolveURL();
|
|
93
|
+
const provider = this.getProviderSource(url);
|
|
94
|
+
const metadata = await provider?.getMetadata?.();
|
|
95
|
+
if (this.disposed) throw new Error('MVT source is disposed');
|
|
96
|
+
this.providerAttributions = (metadata?.attributions ?? []).filter(value => typeof value === 'string' && value.trim()).map(value => value.trim());
|
|
97
|
+
return createTileSourceMetadata(this, {...this.tile_metadata, ...metadata});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Dispose source-owned archive resources and cancel requests on replacement/removal/worker reset. */
|
|
101
|
+
dispose(): void {
|
|
102
|
+
super.dispose();
|
|
103
|
+
this.disposed = true;
|
|
104
|
+
for (const controller of this.providerRequests) controller.abort();
|
|
105
|
+
this.providerRequests.clear();
|
|
106
|
+
for (const provider of this.providerSources.values()) provider.dispose();
|
|
107
|
+
this.providerSources.clear();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
constructor (source: MvtSourceConfig, sources?: Record<string, unknown>) {
|
|
111
|
+
super(source, sources);
|
|
112
|
+
this.response_type = 'arraybuffer'; // binary data
|
|
113
|
+
this.decoder = source.decoder || 'tangram';
|
|
114
|
+
this.tile_provider = source.tile_provider;
|
|
115
|
+
|
|
116
|
+
// Optionally parse some or all properties from JSON strings
|
|
117
|
+
if (source.parse_json === true) {
|
|
118
|
+
// try to parse all properties (least efficient)
|
|
119
|
+
this.parse_json_type = PARSE_JSON_TYPE.ALL;
|
|
120
|
+
}
|
|
121
|
+
else if (Array.isArray(source.parse_json)) {
|
|
122
|
+
// try to parse a specific list of property names (more efficient)
|
|
123
|
+
this.parse_json_type = PARSE_JSON_TYPE.SOME;
|
|
124
|
+
this.parse_json_prop_list = source.parse_json;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
if (source.parse_json != null) {
|
|
128
|
+
let msg = `Data source '${this.name}': 'parse_json' parameter should be 'true', or an array of ` +
|
|
129
|
+
`property names (was '${JSON.stringify(source.parse_json)}')`;
|
|
130
|
+
log({ level: 'warn', once: true }, msg);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// skip parsing entirely (default behavior)
|
|
134
|
+
this.parse_json_type = PARSE_JSON_TYPE.NONE;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
loadURL (dest: TileData, url_template: string): Promise<any> {
|
|
139
|
+
if (!this.tile_provider) {
|
|
140
|
+
return super.loadURL(dest, url_template);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const tileProvider = getMvtTileProvider(this.tile_provider);
|
|
144
|
+
if (!tileProvider) {
|
|
145
|
+
return Promise.reject(new Error(`MVT tile provider '${this.tile_provider}' is not registered in this worker`));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const url = this.formatURL(url_template, dest);
|
|
149
|
+
const sourceData = dest.source_data as SourceData;
|
|
150
|
+
dest.debug = dest.debug || {};
|
|
151
|
+
const debug = dest.debug;
|
|
152
|
+
debug.network = +new Date();
|
|
153
|
+
sourceData.url = url;
|
|
154
|
+
sourceData.error = null;
|
|
155
|
+
|
|
156
|
+
const providerTileIndex = Geo.wrapTile(dest.coords, {x: true, y: false});
|
|
157
|
+
if (this.tms) {
|
|
158
|
+
providerTileIndex.y = Math.pow(2, providerTileIndex.z) - 1 - providerTileIndex.y;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const controller = new AbortController();
|
|
162
|
+
if (dest.canceled) controller.abort();
|
|
163
|
+
this.providerRequests.add(controller);
|
|
164
|
+
updateTileSourceRequest(dest, {cancel: () => controller.abort()});
|
|
165
|
+
const checkActive = (): void => {
|
|
166
|
+
if (controller.signal.aborted || this.disposed) {
|
|
167
|
+
const error = new Error('MVT provider request aborted');
|
|
168
|
+
error.name = 'AbortError';
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
return Promise.resolve().then(() => {
|
|
173
|
+
checkActive();
|
|
174
|
+
return typeof tileProvider === 'function' ? tileProvider(url, providerTileIndex) :
|
|
175
|
+
this.getProviderSource(url)?.getTile(providerTileIndex, controller.signal);
|
|
176
|
+
}).then(response => {
|
|
177
|
+
checkActive();
|
|
178
|
+
debug.network = +new Date() - debug.network;
|
|
179
|
+
debug.parsing = +new Date();
|
|
180
|
+
const preprocessedResponse = response != null && typeof this.preprocess === 'function'
|
|
181
|
+
? this.preprocess(response)
|
|
182
|
+
: response;
|
|
183
|
+
return Promise.resolve(preprocessedResponse).then(processedResponse => {
|
|
184
|
+
checkActive();
|
|
185
|
+
if (processedResponse != null) {
|
|
186
|
+
this.parseSourceData(dest, sourceData, processedResponse);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
sourceData.layers = {};
|
|
190
|
+
}
|
|
191
|
+
debug.parsing = +new Date() - debug.parsing;
|
|
192
|
+
return dest;
|
|
193
|
+
});
|
|
194
|
+
}).catch(error => {
|
|
195
|
+
sourceData.error = error instanceof Error ? error.stack || error.message : String(error);
|
|
196
|
+
return dest;
|
|
197
|
+
}).finally(() => {
|
|
198
|
+
this.providerRequests.delete(controller);
|
|
199
|
+
updateTileSourceRequest(dest, {cancel: undefined});
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
parseSourceData (tile?: TileData, source?: SourceData, response?: ArrayBuffer | Uint8Array): void {
|
|
204
|
+
if (!tile || !source || !response) {
|
|
205
|
+
throw new Error('MVT source parsing requires a tile, source data and response');
|
|
206
|
+
}
|
|
207
|
+
source.layers = parseMvt(this.decoder, response, {parseJson: this.parseJsonOption()});
|
|
208
|
+
|
|
209
|
+
// Apply optional data transform
|
|
210
|
+
if (typeof this.transform === 'function') {
|
|
211
|
+
const tile_data = {
|
|
212
|
+
min: Object.assign({}, tile.min),
|
|
213
|
+
max: Object.assign({}, tile.max),
|
|
214
|
+
coords: Object.assign({}, tile.coords)
|
|
215
|
+
};
|
|
216
|
+
source.layers = this.transform(source.layers, this.extra_data, tile_data);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Loop through layers/features using Mapbox lib API, convert to GeoJSON features
|
|
222
|
+
// Returns an object with keys for each layer, e.g. { layer: geojson }
|
|
223
|
+
toGeoJSON (tile: MvtTile) {
|
|
224
|
+
return convertMvtTileWithLegacy(tile, {parseJson: this.parseJsonOption()});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Optionally parse some or all feature properties from JSON strings
|
|
228
|
+
parseJSONProperties (feature: {properties: Record<string, unknown>}): void {
|
|
229
|
+
parseMvtJsonProperties(feature, this.parseJsonOption());
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
parseJsonOption (): boolean | readonly string[] | undefined {
|
|
233
|
+
if (this.parse_json_type === PARSE_JSON_TYPE.ALL) {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
if (this.parse_json_type === PARSE_JSON_TYPE.SOME) {
|
|
237
|
+
return this.parse_json_prop_list;
|
|
238
|
+
}
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export {decodeMultiPolygon};
|
|
244
|
+
|
|
245
|
+
DataSource.register('MVT', () => MVTSource);
|
|
246
|
+
|
|
247
|
+
registerMvtDecoder('tangram', parseMvtWithLegacy);
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
// Tangram
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) 2013-2016 Brett Camper and Mapzen
|
|
4
|
+
// Copyright (c) 2026 vis.gl contributors
|
|
5
|
+
|
|
6
|
+
import DataSource, {NetworkTileSource} from './data_source';
|
|
7
|
+
import {TileID} from '../tile/tile_id';
|
|
8
|
+
import Geo from '../utils/geo';
|
|
9
|
+
import Texture from '../gl/texture';
|
|
10
|
+
import Utils from '../utils/utils';
|
|
11
|
+
import hashString from '../utils/hash';
|
|
12
|
+
import log from '../utils/log';
|
|
13
|
+
|
|
14
|
+
type SourceConfig = Record<string, any>;
|
|
15
|
+
type Tile = any;
|
|
16
|
+
type RasterImage = {url: string | null; bounds: any; alpha: number | null};
|
|
17
|
+
|
|
18
|
+
export class RasterTileSource extends NetworkTileSource {
|
|
19
|
+
|
|
20
|
+
filtering: any;
|
|
21
|
+
textures!: Record<string, any>;
|
|
22
|
+
|
|
23
|
+
constructor (source: SourceConfig, sources?: Record<string, unknown>) {
|
|
24
|
+
super(source, sources);
|
|
25
|
+
|
|
26
|
+
if (this.rasters.indexOf(this.name) === -1) {
|
|
27
|
+
this.rasters.unshift(this.name); // add this raster as the first
|
|
28
|
+
}
|
|
29
|
+
this.filtering = source.filtering; // optional texture filtering (nearest, linear, mipmap)
|
|
30
|
+
|
|
31
|
+
// save texture objects by tile key, so URL remains stable if tile is built multiple times,
|
|
32
|
+
// e.g. avoid re-loading the same tile texture under a different subdomain when using tile hosts
|
|
33
|
+
this.textures = {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async load (tile: Tile): Promise<Tile> {
|
|
37
|
+
tile.source_data = {};
|
|
38
|
+
tile.source_data.layers = {};
|
|
39
|
+
tile.pad_scale = this.pad_scale;
|
|
40
|
+
tile.rasters = [...this.rasters]; // copy list of rasters to load for tile
|
|
41
|
+
|
|
42
|
+
// Generate a single quad that fills the entire tile
|
|
43
|
+
let scale = Geo.tile_scale;
|
|
44
|
+
tile.source_data.layers = {
|
|
45
|
+
_default: {
|
|
46
|
+
type: 'FeatureCollection',
|
|
47
|
+
features: [{
|
|
48
|
+
geometry: {
|
|
49
|
+
type: 'Polygon',
|
|
50
|
+
coordinates: [[
|
|
51
|
+
[0, 0], [scale, 0],
|
|
52
|
+
[scale, -scale], [0, -scale], [0, 0]
|
|
53
|
+
]]
|
|
54
|
+
},
|
|
55
|
+
properties: {}
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
tile.default_winding = 'CW';
|
|
61
|
+
return tile;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Return texture info for a raster tile
|
|
65
|
+
async tileTexture (tile: Tile, _options: {blend?: string; generation?: number} = {}): Promise<any> {
|
|
66
|
+
let coords = this.adjustRasterTileZoom(tile);
|
|
67
|
+
let key = coords.key;
|
|
68
|
+
// texture definitions are cached to avoid loading the same raster tile multiple times,
|
|
69
|
+
// e.g. due to slightly different URLs when subdomain pattern is used (a.tile.com vs. b.tile.com)
|
|
70
|
+
if (!this.textures[key]) {
|
|
71
|
+
let url = this.formatURL(this.url as string, { coords });
|
|
72
|
+
this.textures[key] = {
|
|
73
|
+
name: url,
|
|
74
|
+
url,
|
|
75
|
+
filtering: this.filtering,
|
|
76
|
+
coords
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return this.textures[key];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// If the raster is attached to another source, we need to compare their levels of zoom detail
|
|
83
|
+
// to see if any adjustments are needed. Both the `tile_size` and `zoom_offset` data source params
|
|
84
|
+
// cause the zoom level to be downsampled relative to the "base" zoom level of the map view.
|
|
85
|
+
// The attaching source has already applied its own zoom downsampling. If this source has a lower
|
|
86
|
+
// level of detail, we apply the remaining differential here.
|
|
87
|
+
adjustRasterTileZoom (tile: Tile): any {
|
|
88
|
+
let coords = tile.coords;
|
|
89
|
+
const tile_source = this.sources[tile.source];
|
|
90
|
+
if (tile_source !== this) { // no-op if the raster source isn't being rendered as an attachment
|
|
91
|
+
let zdiff = this.zoom_bias - tile_source.zoom_bias; // difference in zoom detail between the sources
|
|
92
|
+
if (zdiff > 0) { // raster source is less detailed
|
|
93
|
+
// do extra zoom adjustment and apply this raster source's max zoom
|
|
94
|
+
coords = TileID.normalizedCoord(tile.coords, {
|
|
95
|
+
zoom_bias: zdiff,
|
|
96
|
+
zooms: this.zooms || []
|
|
97
|
+
} as any);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// raster source supports higher detail, but was downsampled to match (the downsampling already
|
|
101
|
+
// happened upstream, when the attaching source calculated its own tile coordinate)
|
|
102
|
+
if (zdiff < 0) {
|
|
103
|
+
log({ level: 'warn', once: true},
|
|
104
|
+
`Raster source '${this.name}' supports higher zoom detail than source '${tile_source.name}' ` +
|
|
105
|
+
`it's attached to. Downsampling this source ${-zdiff} extra zoom levels to match.`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// no extra zoom adjustment needed, but still need to apply this raster source's max zoom
|
|
110
|
+
coords = TileID.coordForTileZooms(coords, this.zooms || []);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return coords;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Data source for loading standalone, geo-referenced raster images
|
|
119
|
+
// The `bounds` parameter is used to position the raster image on the map
|
|
120
|
+
// Currently, only axis-aligned, rectangular North-up images are supported
|
|
121
|
+
// TODO: add support for arbitrarily rotated images and quadrangle control points
|
|
122
|
+
export class RasterSource extends RasterTileSource {
|
|
123
|
+
|
|
124
|
+
load_image!: Record<string, Promise<HTMLImageElement | null>>;
|
|
125
|
+
alpha: number | null;
|
|
126
|
+
mask_alpha!: boolean;
|
|
127
|
+
preserve_tiles_within_zoom!: number;
|
|
128
|
+
max_display_density?: number;
|
|
129
|
+
images!: RasterImage[];
|
|
130
|
+
|
|
131
|
+
constructor (source: SourceConfig, sources?: Record<string, unknown>) {
|
|
132
|
+
super(source, sources);
|
|
133
|
+
|
|
134
|
+
this.load_image = {}; // resolves to image, cached for life of data source
|
|
135
|
+
|
|
136
|
+
// alpha factor applied at time raster images are loaded and tiled (*not* at shader render-time)
|
|
137
|
+
this.alpha = (source.alpha != null) ? Math.max(Math.min(source.alpha, 1), 0) : null;
|
|
138
|
+
|
|
139
|
+
// non-full-alpha pixels should be discarded (for rendering rasters w/opaque blend)
|
|
140
|
+
this.mask_alpha = true;
|
|
141
|
+
|
|
142
|
+
// don't retain tiles for this source from nearby zooms (to improve memory usage)
|
|
143
|
+
this.preserve_tiles_within_zoom = 0;
|
|
144
|
+
|
|
145
|
+
// optionally set a max pixel density used for generated raster tiles (to improve memory usage)
|
|
146
|
+
this.max_display_density = source.max_display_density;
|
|
147
|
+
|
|
148
|
+
// Optionally composite multiple images into one raster layer
|
|
149
|
+
if (Array.isArray(source.composite)) {
|
|
150
|
+
// TODO: calculate enclosing bounding box to speed tile intersection checks
|
|
151
|
+
this.images = source.composite.map((s: SourceConfig) => {
|
|
152
|
+
return {
|
|
153
|
+
url: s.url,
|
|
154
|
+
bounds: this.parseBounds(s),
|
|
155
|
+
alpha: (s.alpha != null) ? Math.max(Math.min(s.alpha, 1), 0) : null
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// Single image raster layer
|
|
160
|
+
else {
|
|
161
|
+
this.images = [{
|
|
162
|
+
url: this.url,
|
|
163
|
+
bounds: this.bounds,
|
|
164
|
+
alpha: this.alpha
|
|
165
|
+
}];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Render the sub-rectangle of the source raster image for the given tile, to a texture.
|
|
170
|
+
// Clipping the source image to individual raster tiles naturally partitions images
|
|
171
|
+
// (which may be large or only have a small portion in current view), and maintains
|
|
172
|
+
// consistency with the raster tile pipeline allowing for sampling within the fragment shader,
|
|
173
|
+
// and clipping the raster against vector source data.
|
|
174
|
+
async tileTexture (tile: Tile, options: {blend?: string; generation?: number} = {}): Promise<any> {
|
|
175
|
+
const {blend, generation} = options;
|
|
176
|
+
let coords = this.adjustRasterTileZoom(tile);
|
|
177
|
+
const use_alpha = (blend !== 'opaque'); // ignore source alpha multiplier with opaque blending
|
|
178
|
+
const name = `raster-${this.name}-${coords.key}-${use_alpha ? 'alpha' : 'opaque'}-${generation}`; // unique texture name
|
|
179
|
+
|
|
180
|
+
// only render each raster tile once (per scene generation)
|
|
181
|
+
if ((Texture as any).textures[name]) {
|
|
182
|
+
return {
|
|
183
|
+
name,
|
|
184
|
+
coords,
|
|
185
|
+
|
|
186
|
+
// tell style to skip re-creating this texture
|
|
187
|
+
// we have an explicit flag for this because element-based (e.g. canvas) textures
|
|
188
|
+
// are usually considered dynamic and always re-created when a new tile needs them
|
|
189
|
+
// (because the user could have updated the canvas pixel contents outside of Tangram)
|
|
190
|
+
skip_create: true
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Display density, with extra 2x for better intra-zoom scaling, because raster tiles
|
|
195
|
+
// can be scaled up to 100% before next zoom level is loaded
|
|
196
|
+
let dpr = Utils.device_pixel_ratio || 1;
|
|
197
|
+
if (this.max_display_density) {
|
|
198
|
+
dpr = Math.min(dpr, this.max_display_density); // optionally cap pixel density
|
|
199
|
+
}
|
|
200
|
+
dpr *= 2;
|
|
201
|
+
|
|
202
|
+
const canvas = document.createElement('canvas');
|
|
203
|
+
const ctx = canvas.getContext('2d');
|
|
204
|
+
if (!ctx) {
|
|
205
|
+
throw new Error('Raster source requires a 2D canvas context');
|
|
206
|
+
}
|
|
207
|
+
canvas.width = this.tile_size * dpr; // adjusted for display density
|
|
208
|
+
canvas.height = this.tile_size * dpr;
|
|
209
|
+
|
|
210
|
+
// Applies nearest neighbor filtering to the canvas image rendering when data source requests it
|
|
211
|
+
// NB: does not work on IE11 (image will be blurry when scaled)
|
|
212
|
+
ctx.imageSmoothingEnabled = (this.filtering !== 'nearest');
|
|
213
|
+
|
|
214
|
+
// Draw one or more images
|
|
215
|
+
const images = this.images.filter((r: RasterImage) => this.checkBounds(tile.coords, r.bounds));
|
|
216
|
+
await Promise.all(images.map((i: RasterImage) => {
|
|
217
|
+
// TODO: log warning if alpha specified but will be ignored (in opaque mode)?
|
|
218
|
+
const alpha = (use_alpha ? (i.alpha != null ? i.alpha : this.alpha) : 1);
|
|
219
|
+
if (!i.url) {
|
|
220
|
+
return Promise.resolve();
|
|
221
|
+
}
|
|
222
|
+
return this.drawImage(i.url, i.bounds, alpha, tile, dpr, ctx);
|
|
223
|
+
}));
|
|
224
|
+
|
|
225
|
+
// texture config
|
|
226
|
+
return {
|
|
227
|
+
name,
|
|
228
|
+
element: canvas,
|
|
229
|
+
filtering: this.filtering,
|
|
230
|
+
coords
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Draw a single image to the tile canvas based on on its bounds
|
|
235
|
+
async drawImage (
|
|
236
|
+
url: string,
|
|
237
|
+
bounds: any,
|
|
238
|
+
alpha: number | null,
|
|
239
|
+
tile: Tile,
|
|
240
|
+
dpr: number,
|
|
241
|
+
ctx: CanvasRenderingContext2D
|
|
242
|
+
): Promise<void> {
|
|
243
|
+
// Get source raster image
|
|
244
|
+
const key = hashString(url); // use hash of URL for shorter keys
|
|
245
|
+
this.load_image[key] = this.load_image[key] || this.loadImage(url);
|
|
246
|
+
const image = await this.load_image[key];
|
|
247
|
+
|
|
248
|
+
// Meters per pixel for this zoom, adjusted for display density and source tile size (e.g. 512px tiles)
|
|
249
|
+
const mpp = Geo.metersPerPixel(tile.coords.z) / dpr / (this.tile_size / Geo.tile_size);
|
|
250
|
+
|
|
251
|
+
// Raster origin relative to tile origin (get delta in meters, then convert to pixels)
|
|
252
|
+
const dx = (bounds.meters.min[0] - tile.min.x) / mpp;
|
|
253
|
+
const dy = -(bounds.meters.min[1] - tile.min.y) / mpp;
|
|
254
|
+
|
|
255
|
+
// Raster size in pixels for current zoom
|
|
256
|
+
const sx = (bounds.meters.max[0] - bounds.meters.min[0]) / mpp;
|
|
257
|
+
const sy = -(bounds.meters.max[1] - bounds.meters.min[1]) / mpp;
|
|
258
|
+
|
|
259
|
+
// Draw the raster, clipped to the current tile
|
|
260
|
+
// NB: this is drawing the *whole* raster, no matter how large, and relying on the native Canvas clipping.
|
|
261
|
+
// May want to benchmark with a pre-clipped draw area, though the native implementation is likely fast,
|
|
262
|
+
// and has to apply its own clipping check anyway.
|
|
263
|
+
ctx.globalAlpha = (alpha != null) ? alpha : 1;
|
|
264
|
+
if (image) {
|
|
265
|
+
ctx.drawImage(image, dx, dy, sx, sy);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Load source raster image
|
|
270
|
+
loadImage (url: string): Promise<HTMLImageElement | null> {
|
|
271
|
+
return new Promise(resolve => {
|
|
272
|
+
let image = new Image();
|
|
273
|
+
image.onload = () => resolve(image);
|
|
274
|
+
image.onerror = e => {
|
|
275
|
+
// Warn and resolve on error
|
|
276
|
+
log('warn', `Raster source '${this.name}': failed to load url: '${url}'`, e);
|
|
277
|
+
resolve(null);
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// Safari has a bug loading data-URL images with CORS enabled, so it must be disabled in that case
|
|
281
|
+
// https://bugs.webkit.org/show_bug.cgi?id=123978
|
|
282
|
+
if (!(Utils.isSafari() && url.slice(0, 5) === 'data:')) {
|
|
283
|
+
image.crossOrigin = 'anonymous';
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
image.src = url;
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Checks if tile interects any rasters in this source
|
|
291
|
+
includesTile (coords: any, style_z: number): boolean {
|
|
292
|
+
// Checks zoom range and dependent rasters
|
|
293
|
+
if (!DataSource.prototype.includesTile.call(this, coords, style_z)) {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return this.images.some((r: RasterImage) => this.checkBounds(coords, r.bounds)); // check if any images intersect
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
validate (source: SourceConfig): void {
|
|
301
|
+
const is_composite = Array.isArray(source.composite);
|
|
302
|
+
|
|
303
|
+
let url_msg = 'Raster data source must provide a string `url` parameter, or an array of `composite` raster ';
|
|
304
|
+
url_msg += 'image objects that each have a `url` parameter';
|
|
305
|
+
|
|
306
|
+
let bounds_msg = 'Raster data source must provide a `bounds` parameter, or an array of `composite` raster ';
|
|
307
|
+
bounds_msg += 'image objects that each have a `bounds` parameter';
|
|
308
|
+
|
|
309
|
+
let mutex_msg = 'Raster data source must have *either* a single image specified as `url` and `bounds `';
|
|
310
|
+
mutex_msg += 'parameters, or an array of `composite` raster image objects, each with `url` and `bounds`.';
|
|
311
|
+
|
|
312
|
+
if (is_composite) {
|
|
313
|
+
if (source.composite.some((s: SourceConfig) => typeof s.url !== 'string')) {
|
|
314
|
+
throw Error(url_msg);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (source.composite.some((s: SourceConfig) => !(Array.isArray(s.bounds) && s.bounds.length === 4))) {
|
|
318
|
+
throw Error(bounds_msg);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (source.url != null || source.bounds != null) {
|
|
322
|
+
throw Error(mutex_msg);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
if (typeof source.url !== 'string') {
|
|
327
|
+
throw Error(url_msg);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (!(Array.isArray(source.bounds) && source.bounds.length === 4)) {
|
|
331
|
+
throw Error(bounds_msg);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Check for URL tile pattern, if not found, treat as geo-referenced raster layer
|
|
339
|
+
DataSource.register('Raster', (source: SourceConfig) => {
|
|
340
|
+
return RasterTileSource.urlHasTilePattern(source.url) ? RasterTileSource : RasterSource;
|
|
341
|
+
});
|