Skip to content

Instantly share code, notes, and snippets.

@CraigglesO
Last active October 2, 2023 11:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CraigglesO/ed5b42ff95dd45ec1250535abfb5b8d6 to your computer and use it in GitHub Desktop.
Save CraigglesO/ed5b42ff95dd45ec1250535abfb5b8d6 to your computer and use it in GitHub Desktop.
New Style Spec
export type Properties = Record<string, Value>
export type ConditionFunction = (input: string | number, properties: Properties) => boolean
export type FilterFunction = (properties: Properties) => boolean
export interface Conditional {
keyCondition?: {
key: string
keyFunction: ConditionFunction
}
filterCondition?: FilterFunction
}
export interface Condition {
key: string
comparitor: Comparitor
value?: NotNullOrObject
}
export type Filter = { and: Filter[] } | { or: Filter[] } | Condition
export type Cursor = CSSStyleDeclaration['cursor']
export type LayerWorkerFunction<U> = (code: number[], properties: Properties, zoom: number) => U
export type BuildCodeFunction = (zoom: number, properties: Properties) => [number[], number[]]
export type BuildCodeFunctionZoom = (zoom: number) => number[]
export type Comparitor = '==' | '!=' | '>' | '>=' | '<' | '<=' | 'in' | '!in' | 'has' | '!has'
export interface DataCondition<T extends NotNullOrObject> {
conditions: Array<{
filter: Filter
input: T | Property<T>
}>
fallback: T | Property<T>
}
// export type DataRange<T extends NotNullOrObject> = DataRangeStep<T> | DataRangeEase<T>
export interface DataRangeEase<T extends number | string> {
key: string // the objects[key] -> value used as position on range
ease?: EaseType
base?: number // 0 -> 2
ranges: Array<{
stop: number
input: T | Property<T>
}>
}
export interface DataRangeStep<T extends NotNullOrObject> {
key: string // the objects[key] -> value used as position on range
ease: 'step'
base?: number // 0 -> 2
ranges: Array<{
stop: number
input: T | Property<T>
}>
}
export interface InputRangeEase<T extends number | string> {
type: 'zoom' | 'lon' | 'lat' | 'angle' | 'pitch'
ease?: EaseType
base?: number // 0 -> 2
ranges: Array<{
stop: number
input: T | Property<T>
}>
}
export interface InputRangeStep<T extends NotNullOrObject> {
type: 'zoom' | 'lon' | 'lat' | 'angle' | 'pitch'
ease: 'step'
base?: number // 0 -> 2
ranges: Array<{
stop: number
input: T | Property<T>
}>
}
export interface FeatureState<T extends NotNullOrObject> {
condition: 'default' /* (inactive) */ | 'active' | 'hover' | 'selected' | 'disabled'
key: string
value: T
input: T | Property<T>
}
export type NotNullOrObject = string | number | boolean | bigint | Array<string | number | boolean | bigint>
export type ValueType<T> = T extends NotNullOrObject ? T : never
export type NumberColor<T> = T extends (number | string) ? T : never
export interface Property<T extends NotNullOrObject> {
dataCondition?: DataCondition<ValueType<T>>
dataRange?: DataRangeEase<NumberColor<T>> | DataRangeStep<ValueType<T>>
inputRange?: InputRangeEase<NumberColor<T>> | InputRangeStep<ValueType<T>>
featureState?: FeatureState<ValueType<T>>
fallback?: T | Property<T>
}
export interface LayerStyleBase {
type?: LayerType
name?: string
source?: string
layer?: string
minzoom?: number
maxzoom?: number
filter?: Filter
lch?: boolean
metadata?: unknown
}
export interface HeatmapLayerStyle extends LayerStyleBase {
type: 'heatmap'
// paint
radius?: number | Property<number>
opacity?: number | Property<number>
intensity?: number | Property<number>
// layout
colorRamp?: 'sinebow' | 'sinebow-extended' | Array<{ stop: number, color: string }>
weight?: number | Property<number>
}
// Filter examples:
// filter: { key: 'class', comparitor: '==', value: 'ocean' }
// filter: { or: [{ key: 'class', comparitor: '==', value: 'ocean' }, { key: 'class', comparitor: '==', value: 'river' }] }
// filter: { and: [{ key: 'class', comparitor: '==', value: 'ocean' }, { key: 'class', comparitor: '==', value: 'lake' }, { key: 'class', comparitor: '!=', value: 'river' }] }
const filterEx: Filter = {
and: [
{
key: 'class',
value: 'hilbert',
comparitor: '=='
},
{
key: 'level',
value: 4,
comparitor: '=='
}
]
}
// property examples:
const color: Property<string> = {
inputRange: {
type: 'zoom',
ease: 'expo',
base: 1.5,
ranges: [
{ stop: 1, input: 'rgb(33, 49, 62)' },
{ stop: 6, input: 'rgb(239, 238, 105)' }
]
}
}
const earthquateLayer: HeatmapLayerStyle = {
name: 'earthquakes-heat',
source: 'earthquakes',
type: 'heatmap',
minzoom: 0,
maxzoom: 8,
colorRamp: [
{
stop: 0,
color: 'rgba(33,102,172,0)'
},
{
stop: 0.2,
color: 'rgba(103,169,207, 0.85)'
},
{
stop: 0.4,
color: 'rgb(209,229,240)'
},
{
stop: 0.6,
color: 'rgb(253,219,199)'
},
{
stop: 0.8,
color: 'rgb(239,138,98)'
},
{
stop: 1,
color: 'rgb(178,24,43)'
}
],
weight: {
dataRange: {
key: 'mag',
ranges: [
{ stop: 0, input: 0 },
{ stop: 8, input: 1 }
]
}
},
radius: {
inputRange: {
type: 'zoom',
ranges: [
{ stop: 0, input: 3 },
{ stop: 8, input: 30 }
]
}
},
intensity: {
inputRange: {
type: 'zoom',
ranges: [
{ stop: 0, input: 1 },
{ stop: 8, input: 3 }
]
}
},
opacity: {
inputRange: {
type: 'zoom',
ranges: [
{ stop: 4, input: 1 },
{ stop: 5, input: 0 }
]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment