UNPKG

kepler.gl

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

597 lines (535 loc) 13.5 kB
// SPDX-License-Identifier: MIT // Copyright contributors to the kepler.gl project import {Field, Millisecond} from './types'; import type {MapViewState} from '@deck.gl/core/typed'; export type MapState = { pitch: number; bearing: number; latitude: number; longitude: number; zoom: number; dragRotate: boolean; width: number; height: number; minZoom?: number; maxZoom?: number; maxBounds?: Bounds; initialState?: any; scale?: number; // the following 4 properties assist with split viewports that can optionally have (un)synced viewports and zooms /** Is the application split into 2 maps? */ isSplit: boolean; /** Are the 2 split maps having synced viewports? */ isViewportSynced: boolean; /** If split, are the zooms locked to each other or independent? */ isZoomLocked: boolean; /** An array of either 0 or 2 Viewport objects (index 0 for left map; index 1 for right map) */ splitMapViewports: Viewport[]; }; export type Bounds = [number, number, number, number]; export type RangeFieldDomain = { domain: number[]; step: number; bins?: Bins; }; export type SelectFieldDomain = { domain: boolean[]; }; export type MultiSelectFieldDomain = { domain: string[]; }; export type TimeRangeFieldDomain = { domain: [number, number]; step: number; timeBins?: TimeBins; mappedValue: (Millisecond | null)[]; // auto generated based on time domain defaultTimeFormat?: string | null; // custom ui input timeFormat?: string | null; // custom ui input timezone?: string | null; }; export type FieldDomain = | RangeFieldDomain | TimeRangeFieldDomain | SelectFieldDomain | MultiSelectFieldDomain; export interface LineDatum { x: number; y: number; delta: string; pct: number | null; } export type LineChart = { series: {x: number; y: number}[]; yDomain: number[] | undefined[]; xDomain: number[]; // Is this a valid part of LineChart? aggregation: string; interval: string; yAxis: string; bins?: Bins; }; type FilterViewType = 'side' | 'enlarged' | 'minified'; export type FilterBase<L extends LineChart> = { dataId: string[]; id: string; enabled: boolean; // time range filter specific fixedDomain: boolean; view: FilterViewType; isAnimating: boolean; speed: number; showTimeDisplay?: boolean; // field specific name: string[]; // string type: string | null; fieldIdx: number[]; // [integer] domain: any[] | null; value: any; mappedValue?: number[]; // plot yAxis: Field | null; plotType: { [key: string]: any; }; lineChart?: L; // gpu filter gpu: boolean; gpuChannel?: number[]; fieldType?: string; // polygon layerId?: string[]; }; export type RangeFilter = FilterBase<LineChart> & RangeFieldDomain & { type: 'range'; fieldType: 'real' | 'integer'; value: [number, number]; fixedDomain: true; typeOptions: ['range']; plotType: { [key: string]: any; }; }; export type SelectFilter = FilterBase<LineChart> & SelectFieldDomain & { type: 'select'; fieldType: 'boolean'; value: boolean; }; export type MultiSelectFilter = FilterBase<LineChart> & MultiSelectFieldDomain & { type: 'multiSelect'; fieldType: 'string' | 'date'; value: string[]; }; export type SyncTimelineMode = 0 | 1; export type TimeRangeFilter = FilterBase<LineChart> & TimeRangeFieldDomain & { type: 'timeRange'; fieldType: 'timestamp'; fixedDomain: boolean; value: [number, number]; plotType: { [key: string]: any; }; syncedWithLayerTimeline: boolean; syncTimelineMode: SyncTimelineMode; animationWindow: string; invertTrendColor: boolean; }; export type PolygonFilter = FilterBase<LineChart> & { layerId: string[]; type: 'polygon'; fixedDomain: true; value: Feature; }; export type Filter = | FilterBase<LineChart> | RangeFilter | TimeRangeFilter | SelectFilter | MultiSelectFilter | PolygonFilter; export interface Bin { count: number; indexes: number[]; x0: number; x1: number; } export interface Bins { [dataId: string]: Bin[]; } export interface TimeBins { [dataId: string]: { [interval: string]: Bin[]; }; } export interface PlotType { interval: ValueOf<Interval>; type: ValueOf<PlotTypes>; aggregation: ValueOf<AggregationTypes>; defaultTimeFormat: string; colorsByDataId?: {[dataId: string]: string}; } export type Feature = { id: string; properties: any; geometry: { type: string; coordinates: any; }; type?: string; }; export type FeatureSelectionContext = { rightClick: boolean; position: {x: number; y: number}; mapIndex?: number; }; export type FeatureValue = { id: string; properties: { filterId: string; }; geometry: { type: string; coordinates: any; }; }; export type Editor = { mode: string; features: Feature[]; selectedFeature: any; selectionContext?: FeatureSelectionContext; visible: boolean; }; export type SplitMapLayers = {[key: string]: boolean}; export type SplitMap = { id?: string; layers: SplitMapLayers; }; /** See "Locale aware formats" at https://momentjs.com/docs/#/parsing/string-format/ */ export type AnimationConfigTimeFormat = 'L' | 'L LT' | 'L LTS'; export type AnimationConfig = { domain: [number, number] | null; currentTime: number | null; speed: number; duration?: number | null; isAnimating?: boolean; timeSteps: number[] | null; // auto generated based on time domain defaultTimeFormat: AnimationTimeFormat | null; // custom ui input timeFormat?: AnimationTimeFormat | null; // custom ui input timezone?: string | null; // hide or show control hideControl?: boolean; }; export type FilterAnimationConfig = Pick< TimeRangeFilter, | 'dataId' | 'value' | 'animationWindow' | 'speed' | 'syncedWithLayerTimeline' | 'syncTimelineMode' | 'timezone' >; export type Timeline = { domain: [number, number] | null; value: number | [number, number]; speed: number; isAnimating: boolean; step?: null | number; timeSteps?: null | number[]; defaultTimeFormat?: null | string; timeFormat?: null | string; timezone?: null | string; timeBins?: null | Record<string, any>; animationWindow?: null | Filter['animationWindow']; marks?: null | number[]; } & Record<string, any>; export type BaseInteraction = { label: string; enabled: boolean; }; export type TooltipField = { name: string; format: string | null; }; export type CompareType = string | null; export type TooltipInfo = BaseInteraction & { id: 'tooltip'; config: { fieldsToShow: { [key: string]: TooltipField[]; }; compareMode: boolean; compareType: CompareType; }; }; export type Geocoder = BaseInteraction & { id: 'geocoder'; position: number[] | null; }; export type Brush = BaseInteraction & { id: 'brush'; config: { size: number; }; }; export type Coordinate = BaseInteraction & { id: 'coordinate'; position: number[] | null; }; export type InteractionConfig = { tooltip: TooltipInfo; geocoder: Geocoder; brush: Brush; coordinate: Coordinate; }; export type MapInfo = { title: string; description: string; }; export type FileLoading = { filesToLoad: FileList; onFinish: (payload: any) => any; fileCache: any[]; }; export type FileLoadingProgress = { [key: string]: { percent: number; message: string; fileName: string; error: any; }; }; export type LayerGroup = { slug: string; filter(layer: {id: string}): boolean; defaultVisibility: boolean; }; export type CustomStyleType = | 'LOCAL' | 'MANAGED' // boolean for backwards compatability with previous map configs | boolean; export type BaseMapColorModes = 'NONE' | 'DARK' | 'LIGHT'; export type BaseMapStyle = { id: string; label: string; url: string; icon: string; style?: object; layerGroups: LayerGroup[]; accessToken?: string; custom?: CustomStyleType; colorMode?: BaseMapColorModes; complimentaryStyleId?: string; }; export declare type ExportImage = { ratio: 'SCREEN' | 'FOUR_BY_THREE' | 'SIXTEEN_BY_NINE' | 'CUSTOM'; resolution: 'ONE_X' | 'TWO_X'; legend: boolean; mapH: number; mapW: number; imageSize: { zoomOffset: number; scale: number; imageW: number; imageH: number; }; imageDataUri: string; exporting: boolean; processing: boolean; error: Error | false; center: boolean; }; export type ExportData = { selectedDataset: string; dataType: string; filtered: boolean; }; export type ExportHtml = { exportMapboxAccessToken: null | string; userMapboxToken: string; mode: string; }; export type ExportJson = { hasData: boolean; }; export type ExportMap = { HTML: ExportHtml; JSON: ExportJson; format: 'HTML' | 'JSON'; }; export type MapControlItem = { show: boolean; active: boolean; disableClose?: boolean; activeMapIndex?: number; }; export type MapControlMapLegend = MapControlItem & { disableEdit?: boolean; }; export type MapControls = { visibleLayers?: MapControlItem; mapLegend?: MapControlMapLegend; toggle3d?: MapControlItem; splitMap?: MapControlItem; mapDraw?: MapControlItem; mapLocale?: MapControlItem; effect?: MapControlItem; aiAssistant?: MapControlItem; }; export type LoadFiles = { fileLoading: boolean; }; export type Notifications = { message: string; type: string; topic: string; id: string; count: number; isExpanded?: boolean; }; export type Locale = string; export type PanelListView = string; export type UiState = { readOnly: boolean; activeSidePanel: string | null; currentModal: string | null; datasetKeyToRemove: string | null; visibleDropdown: string | null; // export image modal ui exportImage: ExportImage; // export data modal ui exportData: ExportData; // html export exportMap: ExportMap; // map control panels mapControls: MapControls; // ui notifications notifications: Notifications[]; // load files loadFiles: LoadFiles; // Locale of the UI locale: Locale; // view layers by list or dataset layerPanelListView: PanelListView; // view filters by list or dataset filterPanelListView: PanelListView; // side panel close button visibility isSidePanelCloseButtonVisible: boolean | null; // positive value indicates that something is loading loadingIndicatorValue?: number; }; /** Width of viewport */ export type Viewport = { /** Width of viewport */ width?: number; /** Height of viewport */ height?: number; /** Zoom of viewport */ zoom?: number; /** Camera angle in degrees (0 is straight down) */ pitch?: number; /** Map rotation in degrees (0 means north is up) */ bearing?: number; /** Latitude center of viewport on map in mercator projection */ latitude?: number; /** Longitude Center of viewport on map in mercator projection */ longitude?: number; /** Whether to enable drag and rotate map into perspective viewport */ dragRotate?: boolean; /** Minimum allowed viewport zoom */ minZoom?: number; /** Maximum allowed viewport zoom */ maxZoom?: number; /** Maximum geographical bounds, pan/zoom operations are constrained within those bounds */ maxBounds?: Bounds; /** viewport transition duration use by geocoder panel **/ transitionDuration?: MapViewState['transitionDuration']; /** viewport transition duration use by geocoder panel **/ transitionInterpolator?: MapViewState['transitionInterpolator']; }; export type MapStyles = { [key: string]: BaseMapStyle; }; export type VisibleLayerGroups = { [key: string]: boolean; }; export type InputStyle = { id?: string | null; accessToken: string | null; error: boolean; isValid: boolean; label: string | null; style: any | null; url: string | null; icon: string | null; custom: CustomStyleType; uploadedFile: File | null; }; export type FilterRecord = { dynamicDomain: Filter[]; fixedDomain: Filter[]; cpu: Filter[]; gpu: Filter[]; }; export type FilterDatasetOpt = { // only allow cpu filtering cpuOnly?: boolean; // ignore filter for domain calculation ignoreDomain?: boolean; }; /* DUPLICATES OF FILTER TYPES ABOVE, REMOVE ONCE TYPES ABOVE ARE FIXED */ type FilterBaseOmitRedudant = Omit<FilterBase<LineChart>, 'type' | 'domain'>; export type TypedRangeFilter = FilterBaseOmitRedudant & RangeFieldDomain & { type: 'range'; fieldType: 'real' | 'integer'; value: [number, number]; fixedDomain: true; typeOptions: ['range']; }; export type TypedSelectFilter = FilterBaseOmitRedudant & SelectFieldDomain & { type: 'select'; fieldType: 'boolean'; value: boolean; }; export type TypedMultiSelectFilter = FilterBaseOmitRedudant & MultiSelectFieldDomain & { type: 'multiSelect'; fieldType: 'string' | 'date'; value: string[]; }; export type TypedTimeRangeFilter = FilterBaseOmitRedudant & TimeRangeFieldDomain & { type: 'timeRange'; fieldType: 'timestamp'; fixedDomain: true; value: [number, number]; plotType: { [key: string]: any; }; animationWindow: string; invertTrendColor: boolean; }; export type TypedPolygonFilter = FilterBaseOmitRedudant & { layerId: string[]; type: 'polygon'; fixedDomain: true; value: Feature; }; export type TypedFilter = | TypedRangeFilter | TypedTimeRangeFilter | TypedSelectFilter | TypedMultiSelectFilter | TypedPolygonFilter;