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
TypeScript
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