UNPKG

s2maps-gpu

Version:

S2 Maps GPU - An open source, high-performance, and GPU-accelerated map engine for rendering large-scale, interactive maps.

1,464 lines 169 kB
import type { ClusterOptions } from 'workers/source/pointCluster/index.js'; import type { ColorArray } from './color/index.js'; import type { EaseType } from './easingFunctions.js'; import type { UrlMap } from 'util/index.js'; import type { View } from 'ui/camera/projector/index.js'; import type { Attributions, BBox, JSONCollection, Point, Properties, TileStoreOptions } from 'gis-tools/index.js'; import type { Center, Encoding, Extensions, Face, ImageExtensions, LayersMetaData, S2Bounds, Scheme, SourceType, TileStatsMetadata, VectorLayer, WMBounds } from 's2-tilejson'; import type { Filter, FilterFunction } from './parseFilter.js'; export type { ClusterOptions } from 'workers/source/pointCluster/index.js'; export type { BBox, JSONCollection, VectorPoint, Properties, TileStoreOptions, } from 'gis-tools/index.js'; export type * from './parseFilter.js'; export type * from './easingFunctions.js'; export type { MapOptions } from 'ui/s2mapUI.js'; export type * from './color/index.js'; export type { View } from 'ui/camera/projector/index.js'; export type * from 's2-tilejson'; /** Whether the projection is S2 or WM */ export type Projection = 'S2' | 'WM'; /** Optionalized tile metadata. Helps source workers to parse malformed tilesets */ export interface OptionalizedTileMetadata { /** The version of the s2-tilejson spec */ s2tilejson?: string; /** The type of the tileset */ type?: SourceType; /** The extension when requesting a tile */ extension?: Extensions; /** List of faces that have tileset */ faces?: Face[]; /** minzoom at which to request tiles. [default=0] */ minzoom?: number; /** maxzoom at which to request tiles. [default=27] */ maxzoom?: number; /** Track layer metadata */ layers?: LayersMetaData; /** WM Tile fetching bounds. Helpful to not make unecessary requests for tiles we know don't exist */ wmbounds?: WMBounds; /** S2 Tile fetching bounds. Helpful to not make unecessary requests for tiles we know don't exist */ s2bounds?: S2Bounds; /** Floating point bounding box array [west, south, east, north]. */ bounds?: BBox; /** { ['human readable string']: 'href' } */ attributions?: Attributions; /** The version of the tileset. Matches the pattern: `\d+\.\d+\.\d+\w?[\w\d]*`. */ version?: string; /** The name of the tileset */ name?: string; /** The scheme of the tileset */ scheme?: Scheme; /** The description of the tileset */ description?: string; /** The encoding of the tileset */ encoding?: Encoding; /** The center of the tileset */ centerpoint?: Center; /** Track tile stats for each face and total overall */ tilestats?: TileStatsMetadata; /** Allow additional properties */ [key: string]: unknown; /** track basic layer metadata */ vector_layers?: VectorLayer[]; /** * Version of the TileJSON spec used. * Matches the pattern: `\d+\.\d+\.\d+\w?[\w\d]*`. */ tilejson?: string; /** Array of tile URL templates. */ tiles?: string[]; /** Attribution string. */ attribution?: string; /** Center coordinate array [longitude, latitude, zoom]. */ center?: [lon: number, lat: number, zoom: number]; /** Fill zoom level. Must be between 0 and 30. */ fillzoom?: number; /** Array of UTFGrid URL templates. */ grids?: string[]; /** Legend of the tileset. */ legend?: string; /** Template for interactivity. */ template?: string; } /** All source input objects contain these shapes */ export type SourceMetadata = OptionalizedTileMetadata & ClusterOptions & TileStoreOptions & { /** Sometimes provided for to have easier access to fetch the source data */ path?: string; /** The size of the tile in pixels if some form of raster data */ size?: number; /** * The time interval in milliseconds each frame is. * Used by sensor sources. */ interval?: number; /** * Specify the name of the source in order to access it. * This is useful if you want to make requests without first having to request the metadata */ sourceName?: string; /** If you want to directly inject the geojson or s2json data */ data?: JSONCollection; /** Other build engines place layer data inside a json string */ json?: string; }; /** JSON Source allows inlined geometry in your style */ export interface JSONSource { type: 'json'; data: JSONCollection; } /** Local Source has predefined geometry you can use */ export type LocalSource = '_local'; /** A Marker source is a local cache that specifically tracks and maintains markers */ export interface MarkerSource { type: 'markers'; path: '_markers'; data: JSONCollection; } /** List of all source inputs. A String is just a href to SourceMetadata */ export type Source = string | SourceMetadata | JSONSource | LocalSource | MarkerSource; /** * Where to fetch data and JSON guides on how to fetch them. If JSON data, it can be included directly in the source * * ex. * ```json * "sources": { * "countries": "/s2json/countriesHD.s2json", * "earthquakes": "/s2json/earthquakes.s2json" * } * ``` */ export type Sources = Record<string, Source>; /** GLYPHS, FONTS, SPRITES, AND ICONS */ /** * Glyph Data (both fonts and icons) and how to fetch them * * ex. * ```json * "glyphs": { * "robotoMedium": "/api/glyphs-v2/RobotoMedium", * "streets": "/api/glyphs-v2/streets" * } * ``` */ export type Glyphs = Record<string, string>; /** * Fonts and how to fetch them * * ex. * ```json * "fonts": { * "robotoMedium": "/api/glyphs-v2/RobotoMedium" * } * ``` */ export type Fonts = Glyphs; /** * Icons and how to fetch them * * ex. * ```json * "icons": { * "streets": "/api/glyphs-v2/streets" * } * ``` */ export type Icons = Glyphs; /** * Sprites names and where to fetch * * Sprites have a default expectancy of a `png` image. * * If you want to use a different format, you can use an object instead of a string. * * See {@link UrlMap} to use your own scheme/protocol for the URL path. * * ### Parameters * - `path`: The path to the sprite * - `fileType`: The file type of the sprite * * ex. * ```json * "sprites": { * "streets": "/sprites/streets/sprite@2x" * } * ``` * * ex. * ```json * "sprites": { * "streets": { * "path": "/sprites/streets/sprite@2x", * "fileType": "jpg" * } * } * ``` */ export type Sprites = Record<string, string | { /** The URL path to the sprite */ path: string; /** The file type of the sprite. e.g. `png`, `jpg`, `webp`, etc. */ fileType?: ImageExtensions; }>; /** * # Cursor Options * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/cursor) * * Matches the `CSSStyleDeclaration['cursor']` property * * The default is `"default"` * * ### Common Options * - `"pointer"` * - `"progress"` * - `"crosshair"` * - `"move"` * - `"text"` * - `"grab"` * - `"grabbing"` * - `"help"` * - `"none"` * - `"zoom-in"` * - `"zoom-out"` */ export type Cursor = CSSStyleDeclaration['cursor']; /** The workflow takes a layer and builds a function that modifies a feature into renderable data */ export type LayerWorkerFunction<U> = (code: number[], properties: Properties, zoom: number) => U; /** An workflow interpretor to create code for the GPU to translate into renderable data */ export type BuildCodeFunction = (zoom: number, properties: Properties) => [number[], number[]]; /** An workflow interpretor to create code for the GPU to translate into renderable data */ export type BuildCodeFunctionZoom = (zoom: number) => number[]; /** * # Comparator * * One of `"==" | "!=" | ">" | ">=" | "<" | "<=" | "in" | "!in" | "has" | "!has"` * * Used by the filter function to determine if a feature should be included in the render. * * `NOTE`: "in" means "in the array" and "has" means "has the key" * * ex. * ```json * { "filter": { "key": "type", "comparator": "in", "value": ["ocean", "lake"] } } * ``` * this would be used to filter features where `feature.properties.type` is either "ocean" or "lake" * * ex. * ```json * { "filter": { "key": "type", "comparator": "has", "value": "ocean" } } * ``` * this would be used to filter features where `feature.properties.type` is an array that has the key "ocean" */ export type Comparator = '==' | '!=' | '>' | '>=' | '<' | '<=' | 'in' | '!in' | 'has' | '!has'; /** * # Nested Key * * Access value in feature properties by either its key or dive into a neste key * * ### Key * - If the key is immediately accessible, set the key. * - If the key is `class` for example, this would be used to filter feature's values where `feature.properties.class === 'ocean'` * * ex. * ```json * { "filter": { "key": "class", "comparator": "==", "value": "ocean" } } * ``` * * ### Nested Key * - Nested conditions are used to dive into nested properties * - If the feature properties has say `feature.properties.class.type === 'ocean'` and we want to access the `type` key * * ex. * ```json * { "filter": { "nestedKey": "class", "key": { "key": "type", "comparator": "==", "value": "ocean" } } } * ``` * ex. */ export interface NestedKey { /** * nested conditions are used to dive into nested properties * * ex. * ```json * { "filter": { "nestedKey": "class", "key": { "key": "type", "comparator": "==", "value": "ocean" } } } * ``` * * this would be used to filter features where `feature.properties.class.type === 'ocean'` */ nestedKey?: string; /** If the key is `class` for example, this would be used to filter feature's values where `feature.properties.class === 'ocean'` */ key: string | NestedKey; } /** * # Input Value * * Input values directly access properties data from the feature. * * ex. * * Lets say you have a feature with the following properties: * ```ts * const properties = { * class: { * type: 'blue', * subclass: 'deep' * } * } * ``` * * You can utilize/access the `type` property with the following: * * ```json * { * "color": { * "inputValue": { * "key": { * "nestedKey": "class", * "key": "type" * }, * "fallback": "blue" * } * } * } * ``` * * ### Properties: * - `key`: [See {@link NestedKey}] Access value in feature properties by either its key or a nested key. * - `fallback`: If the property search for a key turns up no value, the fallback is used. */ export interface InputValue<T extends NotNullOrObject> { /** * Access value in feature properties by either its key or a nested key. * * If the key is `class` for example, this would be used to filter feature's values where `feature.properties.class === 'ocean'` * * nested conditions are used to dive into nested properties * * ex. * ```json * { "filter": { "nestedKey": "class", "key": { "key": "type", "comparator": "==", "value": "ocean" } } } * ``` * this would be used to filter features where `feature.properties.class.type === 'ocean'` */ key: string | NestedKey; /** If the property search for a key turns up no value, the fallback is used. */ fallback: T; } /** * # Condition * * Data conditions are used to filter features based on what property values the feature has. * - If the condition's filter passes, the input is used. * - If all conditions fail, the fallback is used. * * ### Properties: * - `filter`: [See {@link Filter}] Filter conditions are used to filter features based on what property values the feature has. * - `input`: [See {@link Property}] Input values directly access properties data from the feature. The input value must be a {@link NotNullOrObject} * * ex. * ```json * { * "filter": { "key": "country", "comparator": "==", "value": "US" }, * "input": "#007bfe" * } * ``` */ export interface ConditionFilter<T extends NotNullOrObject> { filter: Filter; input: T | Property<T>; } /** * # Data Condition * * Data conditions are used to filter features based on what property values the feature has. * - If the condition's filter passes, the input is used. * - If all conditions fail, the fallback is used. * - Input value must be at a minimum a {@link NotNullOrObject} * * ### Properties: * - `conditions`: [See {@link ConditionFilter}] array of `{ filter: Filter, input: T | Property<T> }`. If Filter passes, the input is used * - `fallback`: if all else fails, use this value. A value of `T` itself or pull from feature properties using {@link Property} * * ex. * ```json * "color": { * "dataCondition": { * "conditions": [ * { * "filter": { "key": "country", "comparator": "==", "value": "US" }, * "input": "#007bfe" * } * ], * "fallback": "#23374d" * } * } * ``` * */ export interface DataCondition<T extends NotNullOrObject> { /** * conditions is an array of `{ filter: Filter, input: T | Property<T> }` * If the filter passes, the input is used. */ conditions: ConditionFilter<T>[]; /** If the conditional search fails, the fallback is used. */ fallback: T | Property<T>; } /** One of {@link DataRangeEase} or {@link DataRangeStep} */ export type DataRange<T> = DataRangeEase<NumberColor<T>> | DataRangeStep<ValueType<T>>; /** One of {@link InputRangeEase} or {@link InputRangeStep} */ export type InputRange<T> = InputRangeEase<NumberColor<T>> | InputRangeStep<ValueType<T>>; /** * # Range * * Set the range stops and the input values to apply at those stops. * * ### Properties * - `stop`: A stop point in the range. * - `input`: [See {@link Property}] A value to apply at the stop. The input value must be a {@link NotNullOrObject} * * ex. * ```json * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 5, "input": 0.5 }, * { "stop": 8, "input": 1 } * ] * ``` */ export interface Range<T extends NotNullOrObject> { stop: number; input: T | Property<T>; } /** * # Data Range Ease * * Data Range is used to group features based on a range of values and apply specific design attributes for those groups. * If the feature's value falls within the range, the fallback is used. * * ex. * ```json * "weight": { * "dataRange": { * "key": "mag", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 8, "input": 1 } * ] * } * } * ``` * * ### Properties: * - `key`: [See {@link NestedKey}] Access value in feature properties by either its key or a nested key. * - `ease`: [See {@link EaseType}] The ease effect. Choose between `lin` | `expo` | `quad` | `cubic` | `step` [default: `lin`] * - `base`: Used by `expo`, `quad`, or `cubic` ease functions. Ranges from 0 -> 2 where 1 is linear, 0 is slow start, 2 is slow finish. [default: 1] * - `ranges`: [See {@link Range}] Set the range stops and the input values to apply at those stops. */ export interface DataRangeEase<T extends number | string> { /** * Access value in feature properties by either its key or a nested key. * * If the key is `class` for example, this would be used to filter feature's values where `feature.properties.class === 'ocean'` * * nested conditions are used to dive into nested properties * ex. * ```json * { "filter": { "nestedKey": "class", "key": { "key": "type", "comparator": "==", "value": "ocean" } } } * ``` * this would be used to filter features where `feature.properties.class.type === 'ocean'` */ key: string | NestedKey; /** * `lin` | `expo` | `quad` | `cubic` | `step` [default: `lin`] */ ease?: EaseType; /** * Used by `expo`, `quad`, or `cubic` ease functions * * Ranges from 0 -> 2 [default: 1] * * - `1` is the default and a linear ease * - `0` is the slowest ease early on * - `2` is the fastest ease */ base?: number; /** * Set the range stops and the input values to apply at those stops. * * ex. * ```json * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 5, "input": 0.5 }, * { "stop": 8, "input": 1 } * ] * ``` */ ranges: Range<T>[]; } /** * # Data Range Step * * Data Range Step is used to group features based on a range of values and apply specific design * attributes for those groups. If the feature's value falls within the range, the fallback is used. * * The "step" type is more limited than an ease type, often used by LAYOUT styling where the change is * immediate to each stop. * * ex. * ```json * "opacity": { * "inputRange": { * "type": "zoom", * "ease": "step", * "ranges": [ * { "stop": 0, "input": 1 }, * { "stop": 5, "input": 0 } * ] * } * } * ``` * * ### Properties * - `ease`: Must be `"step"` if provided * - `key`: [See {@link NestedKey}] Access value in feature properties by either its key or a nested key. * - `ranges`: [See {@link Range}] Set the range stops and the input values to apply at those stops. */ export interface DataRangeStep<T extends NotNullOrObject> { ease?: 'step'; /** * Access value in feature properties by either its key or a nested key. * * If the key is `class` for example, this would be used to filter feature's values where `feature.properties.class === 'ocean'` * * nested conditions are used to dive into nested properties * * ex. * ```json * { "filter": { "nestedKey": "class", "key": { "key": "type", "comparator": "==", "value": "ocean" } } } * ``` * this would be used to filter features where `feature.properties.class.type === 'ocean'` */ key: string | NestedKey; /** Unused by "step" ease functions. Kept to avoid errors in Typescript */ base?: number; /** * Set the range stops and the input values to apply at those stops. * See {@link Range} * * ex. * ```json * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 5, "input": 0.5 }, * { "stop": 8, "input": 1 } * ] * ``` */ ranges: Range<T>[]; } /** * # Input Range Ease * * Input Range is used to group features based on a range of values based upon a `type` provided and apply specific design attributes for those groups. * If the feature's value falls within the range, the fallback is used. * * ex. * ```json * "radius": { * "inputRange": { * "type": "zoom", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 3 }, * { "stop": 8, "input": 30 } * ] * } * } * ``` * * ### Properties * - `type`: The type of input to use. Options are `zoom` | `lon` | `lat` | `angle` | `pitch` * - `ease`: [See {@link EaseType}] The ease effect. Choose between `lin` | `expo` | `quad` | `cubic` | `step` [default: `lin`] * - `base`: Used by `expo`, `quad`, or `cubic` ease functions. Ranges from 0 -> 2 where 1 is linear, 0 is slow start, 2 is slow finish. [default: 1] * - `ranges`: [See {@link Range}] Set the range stops and the input values to apply at those stops. */ export interface InputRangeEase<T extends number | string> { /** `zoom` | `lon` | `lat` | `angle` | `pitch` */ type: 'zoom' | 'lon' | 'lat' | 'angle' | 'pitch'; /** * `lin` | `expo` | `quad` | `cubic` | `step` [default: `lin`] */ ease?: EaseType; /** * Used by `expo`, `quad`, or `cubic` ease functions * * Ranges from 0 -> 2 [default: 1] * * - `1` is the default and a linear ease * - `0` is the slowest ease early on * - `2` is the fastest ease */ base?: number; /** * Set the range stops and the input values to apply at those stops. * * ex. * ```json * "ranges": [ * { "stop": 0, "input": "#f28cb1" }, * { "stop": 100, "input": "#f1f075" }, * { "stop": 750, "input": "#51bbd6" } * ] * ``` */ ranges: Range<T>[]; } /** * # Input Range Step * * Input Range is used to group features based on a range of values based upon a `type` provided and apply specific design attributes for those groups. * If the feature's value falls within the range, the fallback is used. * * The "step" type is more limited than an ease type, often used by LAYOUT styling where the change is * immediate to each stop. * * ex. * ```json * "radius": { * "inputRange": { * "type": "zoom", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 3 }, * { "stop": 8, "input": 30 } * ] * } * } * ``` * * ### Properties * - `ease`: Must be `"step"` * - `type`: The type of input to use. Options are `zoom` | `lon` | `lat` | `angle` | `pitch` * - `ranges`: [See {@link Range}] Set the range stops and the input values to apply at those stops. */ export interface InputRangeStep<T extends NotNullOrObject> { ease: 'step'; /** "zoom" | "lon" | "lat" | "angle" | "pitch" */ type: 'zoom' | 'lon' | 'lat' | 'angle' | 'pitch'; /** Unused by "step" ease functions. Kept to avoid errors in Typescript */ base?: number; /** * Set the range stops and the input values to apply at those stops. * * ex. * ```json * "ranges": [ * { "stop": 0, "input": "#f28cb1" }, * { "stop": 100, "input": "#f1f075" }, * { "stop": 750, "input": "#51bbd6" } * ] * ``` */ ranges: Range<T>[]; } /** * # Feature State * * UNDER CONSTRUCTION - DO NOT USE EXPECTING CONSISTENT RESULTS */ export interface FeatureState<T extends NotNullOrObject> { condition: 'default' | 'active' | 'hover' | 'selected' | 'disabled'; key: string | NestedKey; value: T; input: T | Property<T>; } /** * A value that is not null or an object * Thus possible values are: * - string * - number * - boolean * - bigint * - Array<options above> */ export type NotNullOrObject = string | number | boolean | bigint | Array<string | number | boolean | bigint>; /** An object that is not null. Helper to define what a value actually is */ export type ValueType<T> = T extends NotNullOrObject ? T : never; /** The input must be either a number or a color */ export type NumberColor<T> = T extends number | string ? T : never; /** * # Property * * An extremely maleable input that allows you to style input data as either the value itself or * something that mutates on user input changes, data input changes, feature state like hovering, etc. * * ex. * ```json * { "color": "rgba(240, 2, 5, 1)" } * ``` * * ex. * ```json * { "color": { "inputValue": { "key": "type", "fallback": "blue" } } } * ``` * * ex. * ```json * "weight": { * "dataRange": { * "key": "mag", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 8, "input": 1 } * ] * } * } * ``` * * ### Your list of options are: * - `inputValue`: [See {@link InputValue}] access value in feature properties * - `dataCondition`: [See {@link DataCondition}] filter based on feature property conditions * - `dataRange`: [See {@link DataRange}] filter based on feature property ranges * - `inputRange`: [See {@link InputRange}] filter based on map conditions like "zoom", "lon", "lat", "angle", or "pitch" * - `featureState`: [See {@link FeatureState}] filter based on feature state * - `fallback`: if all else fails, use this value. A value of `T` itself or pull from feature properties using {@link Property} */ export interface Property<T extends NotNullOrObject> { /** * Input values directly access properties data from the feature. * @example Simple Key Access * * Lets say you have a feature with the following properties: * ```ts * const properties = { * class: { * type: 'color-scheme', * subclass: 'deep' * } * } * ``` * * You can utilize/access the `type` property with the following: * * ```json * { * "color": { * "inputValue": { * "key": { * "nestedKey": "class", * "key": "type" * }, * "fallback": "blue" * } * } * } * ``` * @example Nested Key Access * to get a better understanding of the `nestedKey`: (this is a contrived example) * * Lets say you have a feature with the following properties: * ```ts * const properties = { * a: { * b: { * c: '#fff' * } * } * } * ``` * * You can utilize/access the `type` property with the following: * * ```json * { * "color": { * "inputValue": { * "key": { * "nestedKey": "a", * "key": { * "nestedKey": "b", * "key": "c" * } * }, * "fallback": "blue" * } * } * } * ``` */ inputValue?: InputValue<ValueType<T>>; /** * Data conditions are used to filter features based on what property values the feature has. * If the condition's filter passes, the input is used. * If all conditions fail, the fallback is used. * * ex. * ```json * "color": { * "dataCondition": { * "conditions": [ * { * "filter": { "key": "country", "comparator": "==", "value": "US" }, * "input": "#007bfe" * } * ], * "fallback": "#23374d" * } * } * ``` * * ex. * * When using a cluster source you can access its sum: * * ```json * "color": { * "dataCondition": { * "conditions": [ * { * "filter": { "key": "__sum", "comparator": ">", "value": 750 }, * "input": "#f28cb1" * }, * { * "filter": { "key": "__sum", "comparator": ">", "value": 100 }, * "input": "#f1f075" * } * ], * "fallback": "#51bbd6" * } * } * ``` */ dataCondition?: DataCondition<ValueType<T>>; /** * Data Range is used to group features based on a range of values and apply specific design attributes for those groups. * If the feature's value falls within the range, the fallback is used. * * ex. * ```json * "weight": { * "dataRange": { * "key": "mag", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 8, "input": 1 } * ] * } * } * ``` * * ex. * If the layer type is a LAYOUT, you are limited to using the `step` ease function. * ```json * "opacity": { * "dataRange": { * "key": "age", * "ease": "step", * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 50, "input": 1 } * ] * } * } * ``` */ dataRange?: DataRangeEase<NumberColor<T>> | DataRangeStep<ValueType<T>>; /** * Input Range is used to group features based on a range of values based upon a `type` provided and apply specific design attributes for those groups. * If the feature's value falls within the range, the fallback is used. * * The types you can use are: * - `zoom` * - `lon` * - `lat` * - `angle` * - `pitch` * * ex. * ```json * "radius": { * "inputRange": { * "type": "zoom", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 3 }, * { "stop": 8, "input": 30 } * ] * } * } * ``` * * ex. * If the layer type is a LAYOUT, you are limited to using the `step` ease function. * ```json * "opacity": { * "inputRange": { * "type": "zoom", * "ease": "step", * "ranges": [ * { "stop": 0, "input": 1 }, * { "stop": 5, "input": 0 } * ] * } * } * ``` */ inputRange?: InputRangeEase<NumberColor<T>> | InputRangeStep<ValueType<T>>; /** Feature State is still under construction and incomplete */ featureState?: FeatureState<ValueType<T>>; /** * Used in conjunction with one of the other types ("inputValue" | "dataCondition" | "dataRange" | "inputRange" | "featureState"). * You will never directly call this at the top level but as an internal fallback for the other types. */ fallback?: T | Property<T>; } /** * # Property Only Step * * An extremely maleable input that allows you to style input data as either the value itself or * something that mutates on user input changes, data input changes, feature state like hovering, etc. * * The "step" type is more limited than a standard Property, often used by LAYOUT styling where the change is * immediate to each stop if ranges are used. Thus impacts `dataRange` and `inputRange` exclusively. * * ex. * ```json * { "color": "rgba(240, 2, 5, 1)" } * ``` * * ex. * ```json * { "color": { "inputValue": { "key": "type", "fallback": "blue" } } } * ``` * * ex. * ```json * "opacity": { * "dataRange": { * "key": "age", * "ease": "step", * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 50, "input": 1 } * ] * } * } * ``` * * ### Your list of Property options are: * - `inputValue`: [See {@link InputValue}] access value in feature properties * - `dataCondition`: [See {@link DataCondition}] filter based on feature property conditions * - `dataRange`: [See {@link DataRangeStep}] filter based on feature property ranges * - `inputRange`: [See {@link InputRangeStep}] filter based on map conditions like "zoom", "lon", "lat", "angle", or "pitch" * - `featureState`: [See {@link FeatureState}] filter based on feature state * - `fallback`: if all else fails, use this value. A value of `T` itself or pull from feature properties using {@link Property} */ export interface PropertyOnlyStep<T extends NotNullOrObject> { /** * Input values directly access properties data from the feature. * * ex. * * Lets say you have a feature with the following properties: * ```ts * const properties = { * class: { * type: 'blue', * subclass: 'deep' * } * } * ``` * * You can utilize/access the `type` property with the following: * * ```json * { "color": { "inputValue": { "nestedKey": "class", "key": "type", "fallback": "blue" } } } * ``` * * another ex. to get a better understanding of the `nestedKey`: (this is a contrived example) * * Lets say you have a feature with the following properties: * ```ts * const properties = { * a: { * b: { * c: '#fff' * } * } * } * ``` * * You can utilize/access the `type` property with the following: * * ```json * { "color": { "inputValue": { "nestedKey": "a", "key": { "nestedKey": "b", "key": "c" }, "fallback": "blue" } } } * ``` */ inputValue?: InputValue<ValueType<T>>; /** * Data conditions are used to filter features based on what property values the feature has. * If the condition's filter passes, the input is used. * If all conditions fail, the fallback is used. * * ex. * ```json * "color": { * "dataCondition": { * "conditions": [ * { * "filter": { "key": "country", "comparator": "==", "value": "US" }, * "input": "#007bfe" * } * ], * "fallback": "#23374d" * } * } * ``` * * ex. * * When using a cluster source you can access its sum: * * ```json * "color": { * "dataCondition": { * "conditions": [ * { * "filter": { "key": "__sum", "comparator": ">", "value": 750 }, * "input": "#f28cb1" * }, * { * "filter": { "key": "__sum", "comparator": ">", "value": 100 }, * "input": "#f1f075" * } * ], * "fallback": "#51bbd6" * } * } * ``` */ dataCondition?: DataCondition<ValueType<T>>; /** * Data Range is used to group features based on a range of values and apply specific design attributes for those groups. * If the feature's value falls within the range, the fallback is used. * * ex. * ```json * "weight": { * "dataRange": { * "key": "mag", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 8, "input": 1 } * ] * } * } * ``` * * ex. * If the layer type is a LAYOUT, you are limited to using the `step` ease function. * ```json * "opacity": { * "dataRange": { * "key": "age", * "ease": "step", * "ranges": [ * { "stop": 0, "input": 0 }, * { "stop": 50, "input": 1 } * ] * } * } * ``` */ dataRange?: DataRangeStep<ValueType<T>>; /** * Input Range is used to group features based on a range of values based upon a `type` provided and apply specific design attributes for those groups. * If the feature's value falls within the range, the fallback is used. * * The types you can use are: * - `zoom` * - `lon` * - `lat` * - `angle` * - `pitch` * * ex. * ```json * "radius": { * "inputRange": { * "type": "zoom", * "ease": "expo", * "base": 1.5, * "ranges": [ * { "stop": 0, "input": 3 }, * { "stop": 8, "input": 30 } * ] * } * } * ``` * * ex. * If the layer type is a LAYOUT, you are limited to using the `step` ease function. * ```json * "opacity": { * "inputRange": { * "type": "zoom", * "ease": "step", * "ranges": [ * { "stop": 0, "input": 1 }, * { "stop": 5, "input": 0 } * ] * } * } * ``` */ inputRange?: InputRangeStep<ValueType<T>>; /** Feature State is still under construction and incomplete */ featureState?: FeatureState<ValueType<T>>; /** * Used in conjunction with one of the other types ("inputValue" | "dataCondition" | "dataRange" | "inputRange" | "featureState"). * You will never directly call this at the top level but as an internal fallback for the other types. */ fallback?: T | Property<T>; } /** The layer type's that can be used. */ export type LayerType = 'fill' | 'glyph' | 'heatmap' | 'line' | 'point' | 'raster' | 'hillshade' | 'sensor' | 'shade'; /** Layer types that require data to render */ export type LayerDataType = 'fill' | 'glyph' | 'heatmap' | 'line' | 'point' | 'raster' | 'hillshade' | 'sensor'; /** * # Base Layer * * The base layer style. Used by almost all layers to define common attributes. * * - `name`: the name of the layer, useful for sorting a layer on insert or for removal * - `source`: the name of the source whose data this layer will use * - `layer`: the source's layer. Defaults to "default" for JSON data * - `minzoom`: the minimum zoom level at which the layer will be visible * - `maxzoom`: the maximum zoom level at which the layer will be visible * - `filter`: [See {@link Filter}] a filter function to filter out features from the source layer * - `lch`: use LCH coloring instead of RGB. Useful for color changing when the new color is very different from the old one * - `visible`: whether the layer is visible or not * - `metadata`: additional metadata. Used by style generators */ export interface LayerStyleBase<M = unknown> { type?: LayerType; /** The name of the layer - useful for sorting a layer on insert or for removal */ name?: string; /** The source used to generate the layer */ source?: string; /** The source's layer. Default for JSON data */ layer?: string; /** The minimum zoom level at which the layer will be visible */ minzoom?: number; /** The maximum zoom level at which the layer will be visible */ maxzoom?: number; /** * A filter function to filter out features from the source layer. * * example: * * ```json * "filter": { "key": "class", "comparator": "==", "value": "ocean" } * ``` * * another example: * * ```json * "filter": { * "or": [ * { "key": "class", "comparator": "==", "value": "ocean" }, * { "key": "class", "comparator": "==", "value": "bay" } * ] * } * ``` * * another example: * * ```json * "filter": { * "and": [ * { "key": "class", "comparator": "==", "value": "ocean" }, * { "key": "size", "comparator": "==", "value": "large" }, * { "key": "type", "comparator": "!=", "value": "pacific" } * ] * } * ``` */ filter?: Filter; /** Use LCH coloring instead of RGB. Useful for color changing when the new color is very different from the old one */ lch?: boolean; /** Whether the layer is visible or not */ visible?: boolean; /** Additional metadata. Used by style generators. */ metadata?: M; } /** refines the style.json to ensure all variables exist that need to */ export interface LayerDefinitionBase { type: LayerType; name: string; layerIndex: number; source: string; layer: string; minzoom: number; maxzoom: number; lch: boolean; visible: boolean; filter?: Filter; interactive?: boolean; opaque?: boolean; } /** uses definition to create a guide for the workflow (program/pipeline) */ export interface LayerWorkflowGuideBase { sourceName: string; layerIndex: number; layerCode: number[]; lch: boolean; visible: boolean; interactive: boolean; opaque: boolean; } /** worker takes the definition and creates a layer to prep input data for workflow (program/pipeline) */ export interface LayerWorkerBase { type: LayerType; name: string; layerIndex: number; source: string; layer: string; minzoom: number; maxzoom: number; filter: FilterFunction; } /** worker takes the definition and creates a layer to prep input data for workflow (program/pipeline) */ export interface LayerWorkerBaseRaster { type: LayerType; name: string; layerIndex: number; source: string; layer: string; minzoom: number; maxzoom: number; } /** Default case for unknown layer types, should never be used */ export type UnkownLayerStyle = LayerStyleBase; /** The types of vector geometry that can be filtered */ export type GeoFilter = 'point' | 'line' | 'poly'; /** List of vector geometry filters */ export type GeoFilters = GeoFilter[]; /** Color Ramp Interpolation guide */ export interface ColorRampInput { /** A stop position of the color ramp */ stop: number; /** A color at the stop position. Refer to {@link Color} for a list of valid colors */ color: string; } /** Color Ramp options */ export type ColorRamp = 'sinebow' | 'sinebow-extended' | ColorRampInput[]; /** * # Fill Style Guide * * ## Description * * A Fill layer guide defines how polygons should be colored, if they include patterns, * are inverted, interactive, etc. * * ### Base Properties: * [See {@link LayerStyleBase}] * - `name`: the name of the layer, useful for sorting a layer on insert or for removal * - `source`: the name of the source whose data this layer will use * - `layer`: the source's layer. Defaults to "default" for JSON data * - `minzoom`: the minimum zoom level at which the layer will be visible * - `maxzoom`: the maximum zoom level at which the layer will be visible * - `filter`: [See {@link Filter}] a filter function to filter out features from the source layer * - `lch`: use LCH coloring instead of RGB. Useful for color changing when the new color is very different from the old one * - `visible`: whether the layer is visible or not * - `metadata`: additional metadata. Used by style generators * * ### Optional paint properties: * - `color`: {@link Color} of the fill. Input either a `string` pull out the value using a {@link Property}. * - `opacity`: the opacity of the fill. Choose between [0, 1], or pull out the value using a {@link Property}. * * ### Optional layout properties: * - `pattern`: Draw a pattern on the fill given an input image. Input either a `string` pull out the value using a {@link PropertyOnlyStep}. * - `patternMovement`: Boolean flag. If true, the pattern will move with the map rather than being static. Input either a `boolean` or pull out the value using a {@link PropertyOnlyStep}. * - `patternFamily`: If left as the default, the pattern will be searched within any images added to the style. Otherwise use a sprite sheet. Input is either a string to the sprite sheet name, or pull out the value using a {@link PropertyOnlyStep}. * * ### Optional properties: * - `invert`: if true, invert where the fill is drawn to on the map * - `interactive`: boolean flag. If true, when hovering over the fill, the property data will be sent to the UI via an Event * - `cursor`: [See {@link Cursor}] the cursor to use when hovering over the fill * - `opaque`: if true, the fill will be drawn opaque and not allow transparency. Used for performance gains. */ export interface FillStyle extends LayerStyleBase { /** * # Fill Style Guide * * ### Base Properties: * [See {@link LayerStyleBase}] * - `name`: the name of the layer, useful for sorting a layer on insert or for removal * - `source`: the name of the source whose data this layer will use * - `layer`: the source's layer. Defaults to "default" for JSON data * - `minzoom`: the minimum zoom level at which the layer will be visible * - `maxzoom`: the maximum zoom level at which the layer will be visible * - `filter`: [See {@link Filter}] a filter function to filter out features from the source layer * - `lch`: use LCH coloring instead of RGB. Useful for color changing when the new color is very different from the old one * - `visible`: whether the layer is visible or not * - `metadata`: additional metadata. Used by style generators * * ### Optional paint properties: * - `color`: {@link Color} of the fill. Input either a `string` pull out the value using a {@link Property}. * - `opacity` the opacity of the fill. Choose between [0, 1], or pull out the value using a {@link Property}. * * ### Optional layout properties: * - `pattern`: Draw a pattern on the fill given an input image. Input either a `string` pull out the value using a {@link PropertyOnlyStep}. * - `patternMovement`: Boolean flag. If true, the pattern will move with the map rather than being static. Input either a `boolean` or pull out the value using a {@link PropertyOnlyStep}. * - `patternFamily`: If left as the default, the pattern will be searched within any images added to the style. Otherwise use a sprite sheet. Input is either a string to the sprite sheet name, or pull out the value using a {@link PropertyOnlyStep}. * * ### Optional properties: * - `invert`: if true, invert where the fill is drawn to on the map * - `interactive`: boolean flag. If true, when hovering over the fill, the property data will be sent to the UI via an Event * - `cursor`: [See {@link Cursor}] the cursor to use when hovering over the fill * - `opaque`: if true, the fill will be drawn opaque and not allow transparency. Used for performance gains. */ type: 'fill'; /** * A PAINT `Property`. * @defaultValue `"rgba(0, 0, 0, 1)"` * * ex. * * ```json * { "color": "rgba(240, 2, 5, 1)" } * ``` * * ex. * * ```json * { "color": { "inputValue": { "key": "type", "fallback": "blue" } } } * ``` * * ### Your list of {@link Property} options are: * - `inputValue`: [See {@link InputValue}] access value in feature properties * - `dataCondition`: [See {@link DataCondition}] filter based on feature property conditions * - `dataRange`: [See {@link DataRange}] filter based on feature property ranges * - `inputRange`: [See {@link InputRange}] filter based on map conditions like "zoom", "lon", "lat", "angle", or "pitch" * - `featureState`: [See {@link FeatureState}] filter based on feature state * - `fallback`: if all else fails, use this value. A value of `string` itself or pull from feature properties using {@link Property} */ color?: string | Property<string>; /** * A PAINT `Property`. * @defaultValue `1` * * ex. * * ```json * { "opacity": 0.5 } * ``` * * ex. * * ```json * { "opacity": { "inputValue": { "key": "opacity", "fallback": 1 } } } * ``` * * ### Your list of {@link Property} options are: * - `inputValue`: [See {@link InputValue}] access value in feature properties * - `dataCondition`: [See {@link DataCondition}] filter based on feature property conditions * - `dataRange`: [See {@link DataRange}] filter based on feature property ranges * - `inputRange`: [See {@link InputRange}] filter based on map conditions like "zoom", "lon", "lat", "angle", or "pitch" * - `featureState`: [See {@link FeatureState}] filter based on feature state * - `fallback`: if all else fails, use this value. A value of `number` itself or pull from feature properties using {@link Property} */ opacity?: number | Property<number>; /** * A LAYOUT `PropertyOnlyStep`. * @defaultValue `undefined` * * ex. * * Setting up the style definition with an image: * ```ts * const style: StyleDefinition = { * // ... * images: { whale: '/images/whale.jpg' } * } * ``` * * You can then add to the layer: * * ```json * { "type": "fill", "pattern": "whale" } * ``` * * ### Your list of {@link PropertyOnlyStep} options are: * - `inputValue`: [See {@link InputValue}] access value in feature properties * - `dataCondition`: [See {@link DataCondition}] filter based on feature property conditions * - `dataRange`: [See {@link DataRangeStep}] filter based on feature property ranges * - `inputRange`: [See {@link InputRangeStep}] filter based on map conditions like "zoom", "lon", "lat", "angle", or "pitch" * - `featureState`: [See {@link FeatureState}] filter based on feature state * - `fallback`: if all else fails, use this value. A value of `string` itself or pull from feature properties using {@link Property} */ pattern?: string | PropertyOnlyStep<string>; /** * A LAYOUT `PropertyOnlyStep`. * @defaultValue `false` * * ex. * * ```json * { "type": "fill", "pattern": "whale", "patternMovement": true } * ``` * * ### Your list of {@link PropertyOnlyStep} options are: * - `inputValue`: [See {@link InputValue}] access value in feature properties * - `dataCondition`: [See {@link DataCondition}] filter based on feature property conditions * - `dataRange`: [See {@link DataRangeStep}] filter based on feature property ranges * - `inputRange`: [See {@link InputRangeStep}] filter based on map conditions like "zoom", "lon", "lat", "angle", or "pitch" * - `featureState`: [See {@link FeatureState}] filter based on feature state * - `fallback`: if all else fails, use this value. A value of `boolean` itself or pull from feature properties using {@link Property} */ patternMovement?: boolean | PropertyOnlyStep<boolean>; /** * A LAYOUT `PropertyOnlyStep`. * @defaultValue `"__images"` * * If left as the default, the pattern will be searched within any images added to the style. Otherwise, * you're most likely using a sprite sheet and you'll need to specify the "family" of the pattern which is the name of the sprite sheet. * * ex. * * Setting up the style definition with an image: * ```ts * const style: StyleDefinition = { * // ... * sprites: { fishSprites: { path: 'http://...' } } * } * ``` * * See {@link UrlMap} to use your own scheme/protocol for the URL path. * * You can then add to the layer: * * ```json * { "type": "fill", "pattern": "whale", "patternFamily": "fishSprites" } * ``` * * ### Your list of {@link PropertyOnlyStep} options are: * - `inputValue`: [See {@link InputValue}] access value in feature properties * - `dataCondition`: [See {@link DataCondition}] filter based on feature property conditions * - `dataRange`: [See {@link DataRangeStep}] filter based on feature property ranges * - `inputRange`: [See {@link InputRangeStep}] filter based on map conditions like "zoom", "lon", "lat", "angle", or "pitch" * - `featureState`: [See {@link FeatureState}] filter based on feature state * - `fallback`: if all else fails, use this value. A value of `string` itself or pull from feature properties using {@link Property} */ patternFamily?: string | Pro