@tangram.gl/tangram-renderer 0.0.0-stage → 0.0.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/README.md +60 -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,223 @@
|
|
|
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 log from './log';
|
|
7
|
+
|
|
8
|
+
type URLParameters = Record<string, string | number | boolean | null | undefined>;
|
|
9
|
+
type ObjectURLSource = Blob | MediaSource;
|
|
10
|
+
type URLResult = [string, Array<[string, URLParameters[string]]>];
|
|
11
|
+
|
|
12
|
+
// Adds a base origin to relative URLs
|
|
13
|
+
/** Adds a base origin to a relative URL. */
|
|
14
|
+
export function addBaseURL(url: string, base?: string): string;
|
|
15
|
+
/** An omitted resource URL remains omitted, rather than acquiring a base path. */
|
|
16
|
+
export function addBaseURL(url: string | undefined, base?: string): string | undefined;
|
|
17
|
+
export function addBaseURL(url: string | undefined, base?: string): string | undefined {
|
|
18
|
+
if (!url || !isRelativeURL(url)) {
|
|
19
|
+
return url;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var relative_path = (url[0] !== '/');
|
|
23
|
+
var base_info;
|
|
24
|
+
if (base) {
|
|
25
|
+
base_info = document.createElement('a'); // use a temporary element to parse URL
|
|
26
|
+
base_info.href = base;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
base_info = window.location;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (relative_path) {
|
|
33
|
+
let path = pathForURL(base_info.href);
|
|
34
|
+
url = path + url;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
let origin = base_info.origin;
|
|
38
|
+
if (!origin) {
|
|
39
|
+
origin = base_info.protocol + '//' + base_info.host; // IE11 doesn't have origin property
|
|
40
|
+
}
|
|
41
|
+
url = origin + url;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return url;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Returns the directory path portion of a URL. */
|
|
48
|
+
export function pathForURL(url: string | object | null | undefined): string {
|
|
49
|
+
if (typeof url === 'string' && url.search(/^(data|blob):/) === -1) {
|
|
50
|
+
let qs = url.indexOf('?');
|
|
51
|
+
if (qs > -1) {
|
|
52
|
+
url = url.substr(0, qs);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let hash = url.indexOf('#');
|
|
56
|
+
if (hash > -1) {
|
|
57
|
+
url = url.substr(0, hash);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return url.substr(0, url.lastIndexOf('/') + 1) || '';
|
|
61
|
+
}
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Returns the filename extension portion of a URL. */
|
|
66
|
+
export function extensionForURL(url: string): string | undefined {
|
|
67
|
+
const filename = url.split('/').pop() || '';
|
|
68
|
+
let last_dot = filename.lastIndexOf('.');
|
|
69
|
+
if (last_dot > -1) {
|
|
70
|
+
return filename.substring(last_dot + 1);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Returns whether a URL uses a local data or blob scheme. */
|
|
75
|
+
export function isLocalURL(url: unknown): boolean {
|
|
76
|
+
if (typeof url !== 'string') {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return (url.search(/^(data|blob):/) > -1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Returns whether a URL is relative to its current document. */
|
|
83
|
+
export function isRelativeURL(url: unknown): boolean {
|
|
84
|
+
if (typeof url !== 'string') {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return !(url.search(/^(http|https|data|blob):/) > -1 || url.substr(0, 2) === '//');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Resolves './' and '../' components from relative path, to get a "flattened" path
|
|
91
|
+
/** Resolves dot-directory components in a relative URL path. */
|
|
92
|
+
export function flattenRelativeURL(url: string): string {
|
|
93
|
+
let dirs = (url || '').split('/');
|
|
94
|
+
for (let d = 1; d < dirs.length; d++) {
|
|
95
|
+
if (dirs[d] === '.') {
|
|
96
|
+
dirs.splice(d, 1);
|
|
97
|
+
d--;
|
|
98
|
+
}
|
|
99
|
+
else if (dirs[d] === '..') {
|
|
100
|
+
d = d + 0;
|
|
101
|
+
dirs.splice(d-1, 2);
|
|
102
|
+
d--;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return dirs.join('/');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Add a set of query string params to a URL
|
|
109
|
+
// params: hash of key/value pairs of query string parameters
|
|
110
|
+
// returns array of: [modified URL, array of duplicate param name and values]
|
|
111
|
+
/** Adds query parameters and returns any parameters already present in the URL. */
|
|
112
|
+
export function addParamsToURL(url: string, params?: URLParameters): URLResult {
|
|
113
|
+
if (!params || Object.keys(params).length === 0) {
|
|
114
|
+
return [url, []];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
var qs_index = url.indexOf('?');
|
|
118
|
+
var hash_index = url.indexOf('#');
|
|
119
|
+
|
|
120
|
+
// Save and trim hash
|
|
121
|
+
var hash = '';
|
|
122
|
+
if (hash_index > -1) {
|
|
123
|
+
hash = url.slice(hash_index);
|
|
124
|
+
url = url.slice(0, hash_index);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Start query string
|
|
128
|
+
if (qs_index === -1) {
|
|
129
|
+
qs_index = url.length;
|
|
130
|
+
url += '?';
|
|
131
|
+
}
|
|
132
|
+
qs_index++; // advanced past '?'
|
|
133
|
+
|
|
134
|
+
// Build query string params
|
|
135
|
+
var url_params = '';
|
|
136
|
+
const dupes: Array<[string, URLParameters[string]]> = [];
|
|
137
|
+
for (var p in params) {
|
|
138
|
+
if (getURLParameter(p, url) !== '') {
|
|
139
|
+
dupes.push([p, params[p]]);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
url_params += `${p}=${params[p]}&`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Insert new query string params and restore hash
|
|
146
|
+
url = url.slice(0, qs_index) + url_params + url.slice(qs_index) + hash;
|
|
147
|
+
|
|
148
|
+
return [url, dupes];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Polyfill (for Safari compatibility)
|
|
152
|
+
let createObjectURLFunction: typeof URL.createObjectURL | null | undefined;
|
|
153
|
+
/** Creates a blob URL, using the vendor-prefixed fallback when necessary. */
|
|
154
|
+
export function createObjectURL(url: ObjectURLSource): string | ObjectURLSource {
|
|
155
|
+
if (createObjectURLFunction === undefined) {
|
|
156
|
+
createObjectURLFunction = (window.URL && window.URL.createObjectURL) || (window.webkitURL && window.webkitURL.createObjectURL);
|
|
157
|
+
|
|
158
|
+
if (typeof createObjectURLFunction !== 'function') {
|
|
159
|
+
createObjectURLFunction = null;
|
|
160
|
+
log('warn', 'window.URL.createObjectURL (or vendor prefix) not found, unable to create local blob URLs');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (createObjectURLFunction) {
|
|
165
|
+
return createObjectURLFunction(url);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
return url;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let revokeObjectURLFunction: typeof URL.revokeObjectURL | null | undefined;
|
|
173
|
+
/** Revokes a blob URL, using the vendor-prefixed fallback when necessary. */
|
|
174
|
+
export function revokeObjectURL(url: string): string | undefined {
|
|
175
|
+
if (revokeObjectURLFunction === undefined) {
|
|
176
|
+
revokeObjectURLFunction = (window.URL && window.URL.revokeObjectURL) || (window.webkitURL && window.webkitURL.revokeObjectURL);
|
|
177
|
+
|
|
178
|
+
if (typeof revokeObjectURLFunction !== 'function') {
|
|
179
|
+
revokeObjectURLFunction = null;
|
|
180
|
+
log('warn', 'window.URL.revokeObjectURL (or vendor prefix) not found, unable to create local blob URLs');
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (revokeObjectURLFunction) {
|
|
185
|
+
revokeObjectURLFunction(url);
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
return url;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Get URL that the current script was loaded from
|
|
194
|
+
// If currentScript is not available, loops through <script> elements searching for a list of provided paths
|
|
195
|
+
// e.g. findCurrentURL('tangram.debug.js', 'tangram.min.js');
|
|
196
|
+
/** Finds the URL of the current script or a matching script element. */
|
|
197
|
+
export function findCurrentURL(...paths: string[]): string | undefined {
|
|
198
|
+
// Find currently executing script
|
|
199
|
+
var script = document.currentScript;
|
|
200
|
+
if (script) {
|
|
201
|
+
return (script as HTMLScriptElement).src;
|
|
202
|
+
}
|
|
203
|
+
else if (Array.isArray(paths)) {
|
|
204
|
+
// Fallback on looping through <script> elements if document.currentScript is not supported
|
|
205
|
+
var scripts = document.getElementsByTagName('script');
|
|
206
|
+
for (var s=0; s < scripts.length; s++) {
|
|
207
|
+
for (let p=0; p < paths.length; p++) {
|
|
208
|
+
const script = scripts[s] as HTMLScriptElement;
|
|
209
|
+
if (script.src.indexOf(paths[p]) > -1) {
|
|
210
|
+
return script.src;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Via https://davidwalsh.name/query-string-javascript
|
|
218
|
+
function getURLParameter(name: string, url: string): string {
|
|
219
|
+
name = name.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
|
|
220
|
+
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
|
|
221
|
+
var results = regex.exec(url);
|
|
222
|
+
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
|
|
223
|
+
}
|
|
@@ -0,0 +1,310 @@
|
|
|
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
|
+
// Miscellaneous utilities
|
|
7
|
+
|
|
8
|
+
import log from './log';
|
|
9
|
+
import Thread from './thread';
|
|
10
|
+
import WorkerBroker from './worker_broker';
|
|
11
|
+
import type {TransferEnvelope} from './worker-types';
|
|
12
|
+
|
|
13
|
+
type ControlPoint = [number, number | number[]];
|
|
14
|
+
type InterpolationTransform = (value: number) => number;
|
|
15
|
+
type RequestHeaders = Record<string, string>;
|
|
16
|
+
type RequestResponse = {body: string | ArrayBuffer | null; status: number};
|
|
17
|
+
|
|
18
|
+
interface UtilsApi {
|
|
19
|
+
isSafari(): boolean;
|
|
20
|
+
isMicrosoft(): boolean;
|
|
21
|
+
_requests: Record<string, XMLHttpRequest>;
|
|
22
|
+
_proxy_requests: Record<string, boolean>;
|
|
23
|
+
/** Main-thread proxy calls return an envelope; remote worker calls unwrap the response. */
|
|
24
|
+
io<Proxy extends boolean = false>(
|
|
25
|
+
url: string,
|
|
26
|
+
timeout?: number,
|
|
27
|
+
responseType?: XMLHttpRequestResponseType,
|
|
28
|
+
method?: string,
|
|
29
|
+
headers?: RequestHeaders,
|
|
30
|
+
request_key?: string | null,
|
|
31
|
+
proxy?: Proxy
|
|
32
|
+
): Promise<Proxy extends false ? RequestResponse : RequestResponse | TransferEnvelope<[RequestResponse]>>;
|
|
33
|
+
cancelRequest(key: string): void | Promise<unknown>;
|
|
34
|
+
serializeWithFunctions(obj: unknown): string | undefined;
|
|
35
|
+
use_high_density_display: boolean;
|
|
36
|
+
device_pixel_ratio?: number;
|
|
37
|
+
updateDevicePixelRatio(): boolean;
|
|
38
|
+
isPowerOf2(value: number): boolean;
|
|
39
|
+
interpolate(
|
|
40
|
+
x: number,
|
|
41
|
+
points: ControlPoint[] | unknown,
|
|
42
|
+
transform?: InterpolationTransform
|
|
43
|
+
): unknown;
|
|
44
|
+
toCSSColor(color: number[] | null | undefined): string | undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const Utils = {} as UtilsApi;
|
|
48
|
+
|
|
49
|
+
export default Utils;
|
|
50
|
+
|
|
51
|
+
WorkerBroker.addTarget('Utils', Utils);
|
|
52
|
+
|
|
53
|
+
// Basic Safari detection
|
|
54
|
+
// http://stackoverflow.com/questions/7944460/detect-safari-browser
|
|
55
|
+
Utils.isSafari = function () {
|
|
56
|
+
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Basic IE11 or Edge detection
|
|
60
|
+
Utils.isMicrosoft = function () {
|
|
61
|
+
return /(Trident\/7.0|Edge[ /](\d+[.\d]+))/i.test(navigator.userAgent);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
Utils._requests = {}; // XHR requests on current thread
|
|
65
|
+
Utils._proxy_requests = {}; // XHR requests proxied to main thread
|
|
66
|
+
|
|
67
|
+
// `request_key` is a user-provided key that can be later used to cancel the request
|
|
68
|
+
Utils.io = function (
|
|
69
|
+
url,
|
|
70
|
+
timeout = 60000,
|
|
71
|
+
responseType = 'text',
|
|
72
|
+
method = 'GET',
|
|
73
|
+
headers = {},
|
|
74
|
+
request_key = null,
|
|
75
|
+
proxy: boolean = false
|
|
76
|
+
) {
|
|
77
|
+
if (Thread.is_worker && Utils.isMicrosoft()) {
|
|
78
|
+
// Some versions of IE11 and Edge will hang web workers when performing XHR requests
|
|
79
|
+
// These requests can be proxied through the main thread
|
|
80
|
+
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9545866/
|
|
81
|
+
log('debug', 'Proxying request for URL to worker', url);
|
|
82
|
+
|
|
83
|
+
if (request_key) {
|
|
84
|
+
Utils._proxy_requests[request_key] = true; // mark as proxied
|
|
85
|
+
}
|
|
86
|
+
return WorkerBroker.postMessage<RequestResponse>(
|
|
87
|
+
'Utils.io',
|
|
88
|
+
url,
|
|
89
|
+
timeout,
|
|
90
|
+
responseType,
|
|
91
|
+
method,
|
|
92
|
+
headers,
|
|
93
|
+
request_key,
|
|
94
|
+
true
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const request = new XMLHttpRequest();
|
|
99
|
+
let promise: Promise<RequestResponse | TransferEnvelope<[RequestResponse]>> = new Promise<RequestResponse>((resolve, reject) => {
|
|
100
|
+
request.open(method, url, true);
|
|
101
|
+
request.timeout = timeout;
|
|
102
|
+
request.responseType = responseType as XMLHttpRequestResponseType;
|
|
103
|
+
|
|
104
|
+
// Attach optional request headers
|
|
105
|
+
if (headers && typeof headers === 'object') {
|
|
106
|
+
for (let key in headers) {
|
|
107
|
+
request.setRequestHeader(key, headers[key]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
request.onload = () => {
|
|
112
|
+
if (request.status === 200) {
|
|
113
|
+
if (['text', 'json'].indexOf(request.responseType) > -1) {
|
|
114
|
+
resolve({ body: request.responseText, status: request.status });
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
resolve({ body: request.response, status: request.status });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else if (request.status === 204) { // No Content
|
|
121
|
+
resolve({ body: null, status: request.status });
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
reject(Error('Request error with a status of ' + request.statusText));
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
request.onerror = (evt: ProgressEvent<EventTarget>) => {
|
|
128
|
+
reject(Error('There was a network error' + evt.toString()));
|
|
129
|
+
};
|
|
130
|
+
request.ontimeout = (evt: ProgressEvent<EventTarget>) => {
|
|
131
|
+
reject(Error('timeout '+ evt.toString()));
|
|
132
|
+
};
|
|
133
|
+
request.send();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
promise = promise.then(response => {
|
|
137
|
+
if (request_key) {
|
|
138
|
+
delete Utils._requests[request_key];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (proxy) {
|
|
142
|
+
// This first continuation still receives the original XHR response, not an envelope.
|
|
143
|
+
return WorkerBroker.withTransferables(response as RequestResponse);
|
|
144
|
+
}
|
|
145
|
+
return response;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
if (request_key) {
|
|
149
|
+
Utils._requests[request_key] = request;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return promise;
|
|
153
|
+
}
|
|
154
|
+
} as UtilsApi['io'];
|
|
155
|
+
|
|
156
|
+
// Çancel a pending network request by user-provided request key
|
|
157
|
+
Utils.cancelRequest = function (key) {
|
|
158
|
+
// Check for a request that was proxied to the main thread
|
|
159
|
+
if (Thread.is_worker && Utils._proxy_requests[key]) {
|
|
160
|
+
return WorkerBroker.postMessage('Utils.cancelRequest', key); // forward to main thread
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let req = Utils._requests[key];
|
|
164
|
+
if (req) {
|
|
165
|
+
log('trace', `Cancelling network request key '${key}'`);
|
|
166
|
+
Utils._requests[key].abort();
|
|
167
|
+
delete Utils._requests[key];
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
log('trace', `Could not find network request key '${key}'`);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// Stringify an object into JSON, but convert functions to strings
|
|
175
|
+
Utils.serializeWithFunctions = function (obj) {
|
|
176
|
+
if (typeof obj === 'function') {
|
|
177
|
+
return obj.toString();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const serialized = JSON.stringify(obj, function (_key, value) {
|
|
181
|
+
// Convert functions to strings
|
|
182
|
+
if (typeof value === 'function') {
|
|
183
|
+
return value.toString();
|
|
184
|
+
}
|
|
185
|
+
return value;
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
return serialized;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// Default to allowing high pixel density
|
|
192
|
+
// Returns true if display density changed
|
|
193
|
+
Utils.use_high_density_display = true;
|
|
194
|
+
Utils.updateDevicePixelRatio = function () {
|
|
195
|
+
const prev = Utils.device_pixel_ratio;
|
|
196
|
+
Utils.device_pixel_ratio = (Utils.use_high_density_display && window.devicePixelRatio) || 1;
|
|
197
|
+
return Utils.device_pixel_ratio !== prev;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
if (Thread.is_main) {
|
|
201
|
+
Utils.updateDevicePixelRatio();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Used for differentiating between power-of-2 and non-power-of-2 textures
|
|
205
|
+
// Via: http://stackoverflow.com/questions/19722247/webgl-wait-for-texture-to-load
|
|
206
|
+
Utils.isPowerOf2 = function (value) {
|
|
207
|
+
return (value & (value - 1)) === 0;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// Interpolate 'x' along a series of control points
|
|
211
|
+
// 'points' is an array of control points in the form [x, y]
|
|
212
|
+
//
|
|
213
|
+
// Example:
|
|
214
|
+
// Control points:
|
|
215
|
+
// [0, 5]: when x=0, y=5
|
|
216
|
+
// [4, 10]: when x=4, y=10
|
|
217
|
+
//
|
|
218
|
+
// Utils.interpolate(2, [[0, 5], [4, 10]]);
|
|
219
|
+
// -> computes x=2, halfway between x=0 and x=4: (10 - 5) / 2 +5
|
|
220
|
+
// -> returns 7.5
|
|
221
|
+
//
|
|
222
|
+
// TODO: add other interpolation methods besides linear
|
|
223
|
+
//
|
|
224
|
+
Utils.interpolate = function (x, points, transform) {
|
|
225
|
+
// If this doesn't resemble a list of control points, just return the original value
|
|
226
|
+
if (!Array.isArray(points) || !Array.isArray(points[0])) {
|
|
227
|
+
return points;
|
|
228
|
+
}
|
|
229
|
+
else if (points.length < 1) {
|
|
230
|
+
return points;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
let x1: number;
|
|
234
|
+
let x2: number;
|
|
235
|
+
let d: number;
|
|
236
|
+
let y: unknown;
|
|
237
|
+
let y1: number;
|
|
238
|
+
let y2: number;
|
|
239
|
+
|
|
240
|
+
const controlPoints = points as ControlPoint[];
|
|
241
|
+
|
|
242
|
+
// Min bounds
|
|
243
|
+
if (x <= controlPoints[0][0]) {
|
|
244
|
+
y = controlPoints[0][1];
|
|
245
|
+
if (typeof transform === 'function') {
|
|
246
|
+
y = transform(y as number);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Max bounds
|
|
250
|
+
else if (x >= controlPoints[controlPoints.length - 1][0]) {
|
|
251
|
+
y = controlPoints[controlPoints.length - 1][1];
|
|
252
|
+
if (typeof transform === 'function') {
|
|
253
|
+
y = transform(y as number);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// Find which control points x is between
|
|
257
|
+
else {
|
|
258
|
+
for (let i = 0; i < controlPoints.length - 1; i++) {
|
|
259
|
+
if (x >= controlPoints[i][0] && x < controlPoints[i + 1][0]) {
|
|
260
|
+
// Linear interpolation
|
|
261
|
+
x1 = controlPoints[i][0];
|
|
262
|
+
x2 = controlPoints[i + 1][0];
|
|
263
|
+
|
|
264
|
+
// Multiple values
|
|
265
|
+
const firstValue = controlPoints[i][1];
|
|
266
|
+
const secondValue = controlPoints[i + 1][1];
|
|
267
|
+
if (Array.isArray(firstValue) && Array.isArray(secondValue)) {
|
|
268
|
+
y = [] as number[];
|
|
269
|
+
for (let c = 0; c < firstValue.length; c++) {
|
|
270
|
+
if (typeof transform === 'function') {
|
|
271
|
+
y1 = transform(firstValue[c]);
|
|
272
|
+
y2 = transform(secondValue[c]);
|
|
273
|
+
d = y2 - y1;
|
|
274
|
+
(y as number[])[c] = d * (x - x1) / (x2 - x1) + y1;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
d = secondValue[c] - firstValue[c];
|
|
278
|
+
(y as number[])[c] = d * (x - x1) / (x2 - x1) + firstValue[c];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Single value
|
|
283
|
+
else {
|
|
284
|
+
if (typeof transform === 'function') {
|
|
285
|
+
y1 = transform(firstValue as number);
|
|
286
|
+
y2 = transform(secondValue as number);
|
|
287
|
+
d = y2 - y1;
|
|
288
|
+
y = d * (x - x1) / (x2 - x1) + y1;
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
d = (secondValue as number) - (firstValue as number);
|
|
292
|
+
y = d * (x - x1) / (x2 - x1) + (firstValue as number);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return y;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
Utils.toCSSColor = function (color) {
|
|
303
|
+
if (color != null) {
|
|
304
|
+
if (color[3] === 1) { // full opacity
|
|
305
|
+
return `rgb(${color.slice(0, 3).map(c => Math.round(c * 255)).join(', ')})`;
|
|
306
|
+
}
|
|
307
|
+
// RGB is between [0, 255] opacity is between [0, 1]
|
|
308
|
+
return `rgba(${color.map((channel, index) => (index < 3 && Math.round(channel * 255)) || channel).join(', ')})`;
|
|
309
|
+
}
|
|
310
|
+
};
|