@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,620 @@
|
|
|
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 type {PropertyCache, PropertyContext, PropertyFunction, PropertyStop, PropertyTransform, PointSizeCache, PointSizeFlags, PointSizeImage, StyleParserRuntime, UnitValue} from './property-types';
|
|
7
|
+
|
|
8
|
+
import Utils from '../utils/utils';
|
|
9
|
+
import {compileFunctionString} from '../utils/functions';
|
|
10
|
+
import Geo from '../utils/geo';
|
|
11
|
+
import log from '../utils/log';
|
|
12
|
+
|
|
13
|
+
import parseCSSColor from 'csscolorparser';
|
|
14
|
+
|
|
15
|
+
// This macro is stringified and evaluated inside wrapFunction's feature scope.
|
|
16
|
+
declare const feature: {id: string};
|
|
17
|
+
|
|
18
|
+
// Members are installed below before this object is exposed to callers.
|
|
19
|
+
const StyleParser = {} as StyleParserRuntime;
|
|
20
|
+
export default StyleParser;
|
|
21
|
+
|
|
22
|
+
// Helpers for string converstion / NaN handling
|
|
23
|
+
const clampPositive = (v: unknown) => Math.max(v as number, 0);
|
|
24
|
+
const noNaN = (v: number) => isNaN(v) ? 0 : v;
|
|
25
|
+
const parseNumber = ((v: unknown) => Array.isArray(v) ? v.map(parseFloat).map(noNaN) : noNaN(parseFloat(v as string))) as StyleParserRuntime['parseNumber'];
|
|
26
|
+
const parsePositiveNumber = ((v: unknown) => Array.isArray(v) ? v.map(parseNumber).map(clampPositive) : clampPositive(parseNumber(v) as number)) as StyleParserRuntime['parsePositiveNumber'];
|
|
27
|
+
|
|
28
|
+
Object.assign(StyleParser, {clampPositive, noNaN, parseNumber, parsePositiveNumber});
|
|
29
|
+
|
|
30
|
+
// Wraps style functions and provides a scope of commonly accessible data:
|
|
31
|
+
// - feature: the 'properties' of the feature, e.g. accessed as 'feature.name'
|
|
32
|
+
// - global: user-defined properties on the `global` object in the scene file
|
|
33
|
+
// - $zoom: the current map zoom level
|
|
34
|
+
// - $geometry: the type of geometry, 'point', 'line', or 'polygon'
|
|
35
|
+
// - $meters_per_pixel: conversion for meters/pixels at current map zoom
|
|
36
|
+
StyleParser.wrapFunction = function (func, preserveNaN = false) {
|
|
37
|
+
var f = `
|
|
38
|
+
var feature = context.feature.properties;
|
|
39
|
+
var global = context.global;
|
|
40
|
+
var $zoom = context.zoom;
|
|
41
|
+
var $layer = context.layer;
|
|
42
|
+
var $source = context.source;
|
|
43
|
+
var $geometry = context.geometry;
|
|
44
|
+
var $meters_per_pixel = context.meters_per_pixel;
|
|
45
|
+
var $id = context.id;
|
|
46
|
+
|
|
47
|
+
var val = (function(){ ${func} }());
|
|
48
|
+
|
|
49
|
+
${preserveNaN ? '' : `if (typeof val === 'number' && isNaN(val)) {
|
|
50
|
+
val = null; // convert NaNs to nulls
|
|
51
|
+
}`}
|
|
52
|
+
|
|
53
|
+
return val;
|
|
54
|
+
`;
|
|
55
|
+
return f;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
// Style parsing
|
|
60
|
+
|
|
61
|
+
StyleParser.zeroPair = Object.freeze([0, 0] as [number, number]); // single allocation for zero values that won't be modified
|
|
62
|
+
|
|
63
|
+
// Style defaults
|
|
64
|
+
StyleParser.defaults = {
|
|
65
|
+
color: [1, 1, 1, 1],
|
|
66
|
+
width: 1,
|
|
67
|
+
size: 1,
|
|
68
|
+
extrude: false,
|
|
69
|
+
height: 20,
|
|
70
|
+
min_height: 0,
|
|
71
|
+
order: 0,
|
|
72
|
+
z: 0,
|
|
73
|
+
outline: {
|
|
74
|
+
color: [0, 0, 0, 0],
|
|
75
|
+
width: 0
|
|
76
|
+
},
|
|
77
|
+
material: {
|
|
78
|
+
ambient: 1,
|
|
79
|
+
diffuse: 1
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Style macros
|
|
84
|
+
StyleParser.macros = {
|
|
85
|
+
// pseudo-random color by geometry id
|
|
86
|
+
'Style.color.pseudoRandomColor': function() {
|
|
87
|
+
return [
|
|
88
|
+
0.7 * (parseInt(feature.id, 16) / 100 % 1), // eslint-disable-line no-undef
|
|
89
|
+
0.7 * (parseInt(feature.id, 16) / 10000 % 1), // eslint-disable-line no-undef
|
|
90
|
+
0.7 * (parseInt(feature.id, 16) / 1000000 % 1), // eslint-disable-line no-undef
|
|
91
|
+
1
|
|
92
|
+
];
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
// random color
|
|
96
|
+
'Style.color.randomColor': function() {
|
|
97
|
+
return [0.7 * Math.random(), 0.7 * Math.random(), 0.7 * Math.random(), 1];
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// A context object that is passed to style parsing functions to provide a scope of commonly used values
|
|
102
|
+
StyleParser.getFeatureParseContext = function (feature, tile, global) {
|
|
103
|
+
return {
|
|
104
|
+
feature,
|
|
105
|
+
id: feature.id,
|
|
106
|
+
tile,
|
|
107
|
+
global,
|
|
108
|
+
zoom: tile.style_z,
|
|
109
|
+
geometry: Geo.geometryType(feature.geometry.type),
|
|
110
|
+
meters_per_pixel: tile.meters_per_pixel,
|
|
111
|
+
meters_per_pixel_sq: tile.meters_per_pixel_sq,
|
|
112
|
+
units_per_meter_overzoom: tile.units_per_meter_overzoom
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Build a style param cache object
|
|
117
|
+
// `value` is a raw value, cache methods will add other properties as needed
|
|
118
|
+
// `transform` is an optional, one-time transform function to run on values during setup
|
|
119
|
+
// `dynamic_transform` is an optional post-processing function applied to the result of function-based properties
|
|
120
|
+
const CACHE_TYPE = {
|
|
121
|
+
STATIC: 0,
|
|
122
|
+
DYNAMIC: 1,
|
|
123
|
+
ZOOM: 2
|
|
124
|
+
};
|
|
125
|
+
StyleParser.CACHE_TYPE = CACHE_TYPE;
|
|
126
|
+
|
|
127
|
+
StyleParser.createPropertyCache = function (obj, transform = null, dynamic_transform = null) {
|
|
128
|
+
if (obj == null) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if ((obj as PropertyCache).value) {
|
|
133
|
+
return { value: (obj as PropertyCache).value, zoom: ((obj as PropertyCache).zoom ? {} : null), type: (obj as PropertyCache).type }; // clone existing cache object
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let c: PropertyCache = { value: obj, type: CACHE_TYPE.STATIC };
|
|
137
|
+
|
|
138
|
+
// does value contain zoom stops to be interpolated?
|
|
139
|
+
if (Array.isArray(c.value) && Array.isArray(c.value[0])) {
|
|
140
|
+
c.zoom = {}; // will hold values interpolated by zoom
|
|
141
|
+
c.type = CACHE_TYPE.ZOOM;
|
|
142
|
+
}
|
|
143
|
+
else if (typeof c.value === 'function') {
|
|
144
|
+
c.type = CACHE_TYPE.DYNAMIC;
|
|
145
|
+
c.dynamic_transform = (typeof dynamic_transform === 'function' ? dynamic_transform : null);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// apply optional transform function - usually a parsing function
|
|
149
|
+
if (typeof transform === 'function') {
|
|
150
|
+
if (c.zoom) { // apply to each zoom stop value
|
|
151
|
+
c.value = (c.value as PropertyStop[]).map((v, i) => [v[0], transform(v[1], i)]);
|
|
152
|
+
}
|
|
153
|
+
else if (typeof c.value !== 'function') { // don't transform functions
|
|
154
|
+
c.value = transform(c.value, 0); // single value, 0 = the first and only item in the array
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return c;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Convert old-style color macro into a function
|
|
162
|
+
// TODO: deprecate this macro syntax
|
|
163
|
+
StyleParser.createColorPropertyCache = function (obj) {
|
|
164
|
+
return StyleParser.createPropertyCache(obj, v => {
|
|
165
|
+
if (v === 'Style.color.pseudoRandomColor') {
|
|
166
|
+
return compileFunctionString(StyleParser.wrapFunction(StyleParser.macros['Style.color.pseudoRandomColor']));
|
|
167
|
+
}
|
|
168
|
+
else if (v === 'Style.color.randomColor') {
|
|
169
|
+
return StyleParser.macros['Style.color.randomColor'];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return v;
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// Parse point sizes, which include optional %-based or aspect-ratio-constrained scaling from sprite size
|
|
177
|
+
// Returns a cache object if successful, otherwise throws error message
|
|
178
|
+
const isPercent = (v: unknown) => typeof v === 'string' && v[v.length-1] === '%'; // size computed by %
|
|
179
|
+
const isRatio = (v: unknown) => v === 'auto'; // size derived from aspect ratio of one dimension
|
|
180
|
+
const isComputed = (v: unknown) => isPercent(v) || isRatio(v);
|
|
181
|
+
const dualRatioError = '\'size\' can specify either width or height as derived from aspect ratio, but not both';
|
|
182
|
+
StyleParser.createPointSizePropertyCache = function (obj, texture) {
|
|
183
|
+
// obj is the value to be parsed eg "64px" "100%" "auto"
|
|
184
|
+
// mimics the structure of the size value (at each zoom stop if applicable),
|
|
185
|
+
// stores flags indicating if each element is a %-based size or not, or derived from aspect
|
|
186
|
+
let has_pct: PointSizeFlags | null = null;
|
|
187
|
+
let has_ratio: PointSizeFlags | null = null;
|
|
188
|
+
if (isPercent(obj)) { // 1D size
|
|
189
|
+
has_pct = [true];
|
|
190
|
+
}
|
|
191
|
+
else if (Array.isArray(obj)) {
|
|
192
|
+
// track which fields are % vals
|
|
193
|
+
if (Array.isArray(obj[0])) { // zoom stops
|
|
194
|
+
// could be a 1D value (that could be a %), or a 2D value (either width or height or both could be a %)
|
|
195
|
+
if (obj.some(v => Array.isArray(v[1]) ? v[1].some(w => isComputed(w)) : isPercent(v[1]))) {
|
|
196
|
+
has_pct = obj.map(v => Array.isArray(v[1]) ? v[1].map(w => isPercent(w)) : isPercent(v[1]));
|
|
197
|
+
has_ratio = obj.map(v => Array.isArray(v[1]) && v[1].map(w => isRatio(w)));
|
|
198
|
+
if (has_ratio.some(v => Array.isArray(v) && v.every(c => c))) {
|
|
199
|
+
throw dualRatioError; // invalid case where both dims are ratios
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else if (obj.some(isComputed)) { // 2D size
|
|
204
|
+
has_pct = [obj.map(isPercent)];
|
|
205
|
+
has_ratio = [obj.map(isRatio)];
|
|
206
|
+
if ((has_ratio[0] as boolean[]).every(c => c)) {
|
|
207
|
+
throw dualRatioError; // invalid case where both dims are ratios
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (isRatio(obj)) {
|
|
212
|
+
throw 'this value only allowed as half of an array, eg [16px, auto]:';
|
|
213
|
+
// TODO: add this error check for zoom stop parsing above
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (has_pct || has_ratio) {
|
|
217
|
+
// texture is required when % or ratio sizes are used
|
|
218
|
+
if (!texture) {
|
|
219
|
+
throw '% or \'auto\' keywords can only be used to specify point size when a texture is defined';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// per-sprite based evaluation
|
|
223
|
+
obj = { value: obj };
|
|
224
|
+
(obj as PointSizeCache).has_pct = has_pct;
|
|
225
|
+
(obj as PointSizeCache).has_ratio = has_ratio;
|
|
226
|
+
(obj as PointSizeCache).sprites = {}; // cache by sprite
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
// no % or aspect ratio sizing, one cache for texture or all sprites
|
|
230
|
+
obj = StyleParser.createPropertyCache(obj, parsePositiveNumber);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return obj as PointSizeCache | undefined;
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
StyleParser.evalCachedPointSizeProperty = function (val, sprite_info, texture_info, context) {
|
|
237
|
+
if (val == null) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// no percentage-based calculation, one cache for all sprites
|
|
242
|
+
if (!val.has_pct && !val.has_ratio) {
|
|
243
|
+
return StyleParser.evalCachedProperty(val, context);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (sprite_info) {
|
|
247
|
+
// per-sprite based evaluation, cache sizes per sprite
|
|
248
|
+
if (!val.sprites![sprite_info.sprite!]) {
|
|
249
|
+
val.sprites![sprite_info.sprite!] = createPointSizeCacheEntry(val, sprite_info);
|
|
250
|
+
}
|
|
251
|
+
return StyleParser.evalCachedProperty(val.sprites![sprite_info.sprite!], context);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
// texture-based evaluation
|
|
255
|
+
// apply percentage or ratio sizing to a texture
|
|
256
|
+
val.texture = val.texture || createPointSizeCacheEntry(val, texture_info!);
|
|
257
|
+
return StyleParser.evalCachedProperty(val.texture, context);
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
function createPointSizeCacheEntry (val: PointSizeCache, image_info: PointSizeImage): PropertyCache | undefined {
|
|
262
|
+
// the cache property transform function needs access to the image in `val`
|
|
263
|
+
// so it's accessed via a closure here
|
|
264
|
+
return StyleParser.createPropertyCache(val.value, (v, i) => {
|
|
265
|
+
if (Array.isArray(v)) { // 2D size
|
|
266
|
+
// either width or height or both could be a %
|
|
267
|
+
v = v.
|
|
268
|
+
map((c, j) => (val.has_ratio![i] as boolean[])[j] ? c : parsePositiveNumber(c)). // convert non-ratio values to px
|
|
269
|
+
map((c, j) => (val.has_pct![i] as boolean[])[j] ? image_info.css_size[j] * (c as number) / 100 : c); // apply % scaling as needed
|
|
270
|
+
|
|
271
|
+
// either width or height could be a ratio
|
|
272
|
+
if ((val.has_ratio![i] as boolean[])[0]) {
|
|
273
|
+
(v as number[])[0] = (v as number[])[1] * image_info.aspect;
|
|
274
|
+
}
|
|
275
|
+
else if ((val.has_ratio![i] as boolean[])[1]) {
|
|
276
|
+
(v as number[])[1] = (v as number[])[0] / image_info.aspect;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else { // 1D size
|
|
280
|
+
v = parsePositiveNumber(v);
|
|
281
|
+
if (val.has_pct![i]) {
|
|
282
|
+
v = image_info.css_size.map(c => c * (v as number) / 100); // set size as % of image
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
v = [v, v]; // expand 1D size to 2D
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return v;
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Interpolation and caching for a generic property (not a color or distance)
|
|
293
|
+
// { value: original, static: val, zoom: { 1: val1, 2: val2, ... }, dynamic: function(){...} }
|
|
294
|
+
StyleParser.evalCachedProperty = function(val, context) {
|
|
295
|
+
if (val == null) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
else if (val.dynamic) { // function, compute each time (no caching)
|
|
299
|
+
return tryEval(val.dynamic, context);
|
|
300
|
+
}
|
|
301
|
+
else if (val.static) { // single static value
|
|
302
|
+
return val.static;
|
|
303
|
+
}
|
|
304
|
+
else if (val.zoom && val.zoom[context.zoom!]) { // interpolated, cached
|
|
305
|
+
return val.zoom[context.zoom!];
|
|
306
|
+
}
|
|
307
|
+
else { // not yet evaulated for cache
|
|
308
|
+
// Dynamic function-based
|
|
309
|
+
if (typeof val.value === 'function') {
|
|
310
|
+
if (val.dynamic_transform) {
|
|
311
|
+
// apply an optional post-eval transform function
|
|
312
|
+
// e.g. apply device pixel ratio to font sizes, unit conversions, etc.
|
|
313
|
+
val.dynamic = function(context) {
|
|
314
|
+
return val.dynamic_transform!((val.value as PropertyFunction)(context));
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
val.dynamic = val.value as PropertyFunction;
|
|
319
|
+
}
|
|
320
|
+
return tryEval(val.dynamic, context);
|
|
321
|
+
}
|
|
322
|
+
// Array of zoom-interpolated stops, e.g. [zoom, value] pairs
|
|
323
|
+
else if (Array.isArray(val.value) && Array.isArray(val.value[0])) {
|
|
324
|
+
// Calculate value for current zoom
|
|
325
|
+
val.zoom = val.zoom || {};
|
|
326
|
+
val.zoom[context.zoom!] = Utils.interpolate(context.zoom!, val.value);
|
|
327
|
+
return val.zoom[context.zoom!];
|
|
328
|
+
}
|
|
329
|
+
// Single static value
|
|
330
|
+
else {
|
|
331
|
+
val.static = val.value;
|
|
332
|
+
return val.static;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
StyleParser.convertUnits = function(val, context) {
|
|
338
|
+
// pre-parsed units
|
|
339
|
+
if ((val as UnitValue).value != null) {
|
|
340
|
+
if ((val as UnitValue).units === 'px') { // convert from pixels
|
|
341
|
+
return ((val as UnitValue).value as number) * Geo.metersPerPixel(context.zoom!);
|
|
342
|
+
}
|
|
343
|
+
return (val as UnitValue).value;
|
|
344
|
+
}
|
|
345
|
+
// un-parsed unit string
|
|
346
|
+
else if (typeof val === 'string') {
|
|
347
|
+
if (val.trim().slice(-2) === 'px') {
|
|
348
|
+
val = parseNumber(val);
|
|
349
|
+
(val as number) *= Geo.metersPerPixel(context.zoom!); // convert from pixels
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
val = parseNumber(val);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// multiple values or stops
|
|
356
|
+
else if (Array.isArray(val)) {
|
|
357
|
+
// Array of arrays, e.g. zoom-interpolated stops
|
|
358
|
+
if (Array.isArray(val[0])) {
|
|
359
|
+
return val.map(v => [v[0], StyleParser.convertUnits(v[1], context)]);
|
|
360
|
+
}
|
|
361
|
+
// Array of values
|
|
362
|
+
else {
|
|
363
|
+
return val.map(v => StyleParser.convertUnits(v, context));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return val;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
// Pre-parse units from string values
|
|
370
|
+
StyleParser.parseUnits = function (value) {
|
|
371
|
+
var obj: UnitValue = { value: parseNumber(value) };
|
|
372
|
+
if (obj.value !== 0 && typeof value === 'string' && value.trim().slice(-2) === 'px') {
|
|
373
|
+
obj.units = 'px';
|
|
374
|
+
}
|
|
375
|
+
return obj;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
/** Keep invalid projected heights visible to validation, including wrapped scene functions. */
|
|
379
|
+
StyleParser.createProjectedHeightPropertyCache = function (value) {
|
|
380
|
+
if (typeof value === 'function' && 'source' in value && typeof value.source === 'string') {
|
|
381
|
+
// Recompile from the authored body, not the legacy NaN-to-null wrapper.
|
|
382
|
+
// Leave the shared compiled function untouched for other style properties.
|
|
383
|
+
value = compileFunctionString(`function(context) {${value.source}}`,
|
|
384
|
+
source => StyleParser.wrapFunction(source, true));
|
|
385
|
+
}
|
|
386
|
+
return StyleParser.createPropertyCache(value, height => {
|
|
387
|
+
const parsedHeight = typeof height === 'string' ? parseFloat(height) : height;
|
|
388
|
+
if (typeof parsedHeight !== 'number' || !Number.isFinite(parsedHeight)) {
|
|
389
|
+
throw new Error('Projected annotation height must be a finite number');
|
|
390
|
+
}
|
|
391
|
+
return StyleParser.parseUnits(height);
|
|
392
|
+
});
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
/** Dynamic projected heights must reach packing validation without legacy error fallback. */
|
|
396
|
+
StyleParser.evalProjectedHeightProperty = function (value, context) {
|
|
397
|
+
return typeof value?.value === 'function' ? value.value(context) :
|
|
398
|
+
StyleParser.evalCachedDistanceProperty(value, context);
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
// Takes a distance cache object and returns a distance value for this zoom
|
|
402
|
+
// (caching the result for future use)
|
|
403
|
+
// { value: original, zoom: { z: meters }, dynamic: function(){...} }
|
|
404
|
+
StyleParser.evalCachedDistanceProperty = function(val, context) {
|
|
405
|
+
if (val == null) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
else if (val.dynamic) {
|
|
409
|
+
return tryEval(val.dynamic, context);
|
|
410
|
+
}
|
|
411
|
+
else if (val.zoom && val.zoom[context.zoom!]) {
|
|
412
|
+
return val.zoom[context.zoom!];
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
// Dynamic function-based
|
|
416
|
+
if (typeof val.value === 'function') {
|
|
417
|
+
val.dynamic = val.value as PropertyFunction;
|
|
418
|
+
return tryEval(val.dynamic, context);
|
|
419
|
+
}
|
|
420
|
+
// Array of zoom-interpolated stops, e.g. [zoom, value] pairs
|
|
421
|
+
else if (val.zoom) {
|
|
422
|
+
// Calculate value for current zoom
|
|
423
|
+
// Do final unit conversion as late as possible, when interpolation values have been determined
|
|
424
|
+
val.zoom[context.zoom!] = Utils.interpolate(context.zoom!, val.value as PropertyStop[],
|
|
425
|
+
v => StyleParser.convertUnits(v, context) as number);
|
|
426
|
+
|
|
427
|
+
return val.zoom[context.zoom!];
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
return StyleParser.convertUnits(val.value, context);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
// Cache previously parsed color strings
|
|
436
|
+
StyleParser.string_colors = {};
|
|
437
|
+
StyleParser.colorForString = function(string) {
|
|
438
|
+
// Cached
|
|
439
|
+
if (StyleParser.string_colors[string]) {
|
|
440
|
+
return StyleParser.string_colors[string];
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Calculate and cache
|
|
444
|
+
let color: number[] | undefined = parseCSSColor.parseCSSColor(string);
|
|
445
|
+
if (color && color.length === 4) {
|
|
446
|
+
color[0] /= 255;
|
|
447
|
+
color[1] /= 255;
|
|
448
|
+
color[2] /= 255;
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
color = StyleParser.defaults.color;
|
|
452
|
+
}
|
|
453
|
+
StyleParser.string_colors[string] = color;
|
|
454
|
+
return color;
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
// Takes a color cache object and returns a color value for this zoom
|
|
458
|
+
// (caching the result for future use)
|
|
459
|
+
// { value: original, static: [r,g,b,a], zoom: { z: [r,g,b,a] }, dynamic: function(){...} }
|
|
460
|
+
StyleParser.evalCachedColorProperty = function(val, context = {}) {
|
|
461
|
+
if (val == null) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
else if (val.dynamic) {
|
|
465
|
+
let v = tryEval(val.dynamic, context) as number[] | string | undefined;
|
|
466
|
+
|
|
467
|
+
if (typeof v === 'string') {
|
|
468
|
+
v = StyleParser.colorForString(v);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (v && v[3] == null) {
|
|
472
|
+
v[3] = 1; // default alpha
|
|
473
|
+
}
|
|
474
|
+
return v;
|
|
475
|
+
}
|
|
476
|
+
else if (val.static) {
|
|
477
|
+
return val.static as number[];
|
|
478
|
+
}
|
|
479
|
+
else if (val.zoom && val.zoom[context.zoom!]) {
|
|
480
|
+
return val.zoom[context.zoom!] as number[];
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
// Dynamic function-based color
|
|
484
|
+
if (typeof val.value === 'function') {
|
|
485
|
+
val.dynamic = val.value as PropertyFunction;
|
|
486
|
+
let v = tryEval(val.dynamic, context) as number[] | string | undefined;
|
|
487
|
+
|
|
488
|
+
if (typeof v === 'string') {
|
|
489
|
+
v = StyleParser.colorForString(v);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (v && v[3] == null) {
|
|
493
|
+
v[3] = 1; // default alpha
|
|
494
|
+
}
|
|
495
|
+
return v;
|
|
496
|
+
}
|
|
497
|
+
// Single string color
|
|
498
|
+
else if (typeof val.value === 'string') {
|
|
499
|
+
val.static = StyleParser.colorForString(val.value);
|
|
500
|
+
return val.static as number[];
|
|
501
|
+
}
|
|
502
|
+
// Array of zoom-interpolated stops, e.g. [zoom, color] pairs
|
|
503
|
+
else if (val.zoom) {
|
|
504
|
+
// Parse any string colors inside stops, the first time we encounter this property
|
|
505
|
+
if (!val.zoom_preprocessed) {
|
|
506
|
+
for (let i=0; i < (val.value as PropertyStop[]).length; i++) {
|
|
507
|
+
let v = (val.value as PropertyStop[])[i];
|
|
508
|
+
if (v && typeof v[1] === 'string') {
|
|
509
|
+
v[1] = StyleParser.colorForString(v[1]);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
val.zoom_preprocessed = true;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Calculate color for current zoom
|
|
516
|
+
val.zoom[context.zoom!] = Utils.interpolate(context.zoom!, val.value as PropertyStop[]);
|
|
517
|
+
(val.zoom[context.zoom!] as number[])[3] = (val.zoom[context.zoom!] as number[])[3] || 1; // default alpha
|
|
518
|
+
return val.zoom[context.zoom!] as number[];
|
|
519
|
+
}
|
|
520
|
+
// Single array color
|
|
521
|
+
else {
|
|
522
|
+
val.static = (val.value as number[]).map(x => x); // copy to avoid modifying
|
|
523
|
+
if (val.static && (val.static as number[])[3] == null) {
|
|
524
|
+
(val.static as number[])[3] = 1; // default alpha
|
|
525
|
+
}
|
|
526
|
+
return val.static as number[];
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
// Evaluate color cache object and apply optional alpha override (alpha arg is a single value cache object)
|
|
532
|
+
StyleParser.evalCachedColorPropertyWithAlpha = function (val, alpha_prop, context) {
|
|
533
|
+
const color = StyleParser.evalCachedColorProperty(val, context);
|
|
534
|
+
if (color != null && alpha_prop != null) {
|
|
535
|
+
const alpha = StyleParser.evalCachedProperty(alpha_prop, context);
|
|
536
|
+
if (alpha != null) {
|
|
537
|
+
return [color[0], color[1], color[2], alpha];
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return color;
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
StyleParser.parseColor = function(val, context = {}) {
|
|
544
|
+
if (typeof val === 'function') {
|
|
545
|
+
val = tryEval(val as PropertyFunction, context);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Parse CSS-style colors
|
|
549
|
+
// TODO: change all colors to use 0-255 range internally to avoid dividing and then re-multiplying in geom builder
|
|
550
|
+
if (typeof val === 'string') {
|
|
551
|
+
val = StyleParser.colorForString(val);
|
|
552
|
+
}
|
|
553
|
+
else if (Array.isArray(val) && Array.isArray(val[0])) {
|
|
554
|
+
// Array of zoom-interpolated stops, e.g. [zoom, color] pairs
|
|
555
|
+
for (let i=0; i < val.length; i++) {
|
|
556
|
+
let v = val[i];
|
|
557
|
+
if (typeof v[1] === 'string') {
|
|
558
|
+
v[1] = StyleParser.colorForString(v[1]);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
if (context.zoom) {
|
|
563
|
+
val = Utils.interpolate(context.zoom, val);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Defaults
|
|
568
|
+
if (Array.isArray(val)) {
|
|
569
|
+
val = val.map(x => x); // copy to avoid modifying
|
|
570
|
+
// alpha
|
|
571
|
+
if ((val as number[])[3] == null) {
|
|
572
|
+
(val as number[])[3] = 1;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
val = [0, 0, 0, 1];
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
return val as number[];
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
StyleParser.calculateOrder = function(order, context) {
|
|
583
|
+
// Computed order
|
|
584
|
+
if (typeof order === 'function') {
|
|
585
|
+
order = tryEval(order as PropertyFunction, context);
|
|
586
|
+
}
|
|
587
|
+
else if (typeof order === 'string') {
|
|
588
|
+
// Order tied to feature property
|
|
589
|
+
if (context.feature!.properties[order]) {
|
|
590
|
+
order = context.feature!.properties[order];
|
|
591
|
+
}
|
|
592
|
+
// Explicit order value
|
|
593
|
+
else {
|
|
594
|
+
order = parsePositiveNumber(order);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return order;
|
|
599
|
+
};
|
|
600
|
+
|
|
601
|
+
// Evaluate a function-based property, or pass-through static value
|
|
602
|
+
StyleParser.evalProperty = function(prop, context) {
|
|
603
|
+
if (typeof prop === 'function') {
|
|
604
|
+
return tryEval(prop as PropertyFunction, context);
|
|
605
|
+
}
|
|
606
|
+
return prop;
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
// eval property function with try/catch
|
|
610
|
+
function tryEval (func: PropertyFunction, context: PropertyContext): unknown {
|
|
611
|
+
try {
|
|
612
|
+
return func(context);
|
|
613
|
+
} catch(e) {
|
|
614
|
+
log('warn',
|
|
615
|
+
`Property function in layer '${context.layers![context.layers!.length-1]}' failed with\n`,
|
|
616
|
+
`error ${(e as Error).stack}\n`,
|
|
617
|
+
`function '${func.source}'\n`,
|
|
618
|
+
context.feature, context);
|
|
619
|
+
}
|
|
620
|
+
}
|