@carto/api-client 0.5.0-alpha.14 → 0.5.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,268 @@
1
+ import {LayerType, SCALE_TYPE} from './layer-map.js';
2
+ import {Format, MapType, ProviderType, QueryParameters} from '../types.js';
3
+ import {TilejsonResult, GeojsonResult, JsonResult} from '../sources/types.js';
4
+
5
+ export type VisualChannelField = {
6
+ name: string;
7
+ type: string;
8
+ colorColumn?: string;
9
+ };
10
+
11
+ export type VisualChannels = {
12
+ colorField?: VisualChannelField;
13
+ colorScale?: SCALE_TYPE;
14
+
15
+ customMarkersField?: VisualChannelField;
16
+ customMarkersScale?: SCALE_TYPE;
17
+
18
+ radiusField?: VisualChannelField;
19
+ radiusScale?: SCALE_TYPE;
20
+
21
+ rotationScale?: SCALE_TYPE;
22
+ rotationField?: VisualChannelField;
23
+
24
+ sizeField?: VisualChannelField;
25
+ sizeScale?: SCALE_TYPE;
26
+
27
+ strokeColorField?: VisualChannelField;
28
+ strokeColorScale?: SCALE_TYPE;
29
+
30
+ heightField?: VisualChannelField;
31
+ heightScale?: SCALE_TYPE;
32
+
33
+ weightField?: VisualChannelField;
34
+ };
35
+
36
+ export type ColorRange = {
37
+ category: string;
38
+ colors: string[];
39
+ colorMap: string[][] | undefined;
40
+ name: string;
41
+ type: string;
42
+ };
43
+
44
+ export type CustomMarkersRange = {
45
+ markerMap: {
46
+ value: string;
47
+ markerUrl?: string;
48
+ }[];
49
+ othersMarker?: string;
50
+ };
51
+
52
+ export type VisConfig = {
53
+ filled?: boolean;
54
+ opacity?: number;
55
+ enable3d?: boolean;
56
+
57
+ colorAggregation?: any;
58
+ colorRange: ColorRange;
59
+
60
+ customMarkers?: boolean;
61
+ customMarkersRange?: CustomMarkersRange | null;
62
+ customMarkersUrl?: string | null;
63
+
64
+ radius: number;
65
+ radiusRange?: number[];
66
+
67
+ sizeAggregation?: any;
68
+ sizeRange?: any;
69
+
70
+ strokeColorAggregation?: any;
71
+ strokeOpacity?: number;
72
+ strokeColorRange?: ColorRange;
73
+
74
+ heightRange?: any;
75
+ heightAggregation?: any;
76
+
77
+ weightAggregation?: any;
78
+ };
79
+
80
+ export type TextLabel = {
81
+ field: VisualChannelField | null | undefined;
82
+ alignment?: 'center' | 'bottom' | 'top';
83
+ anchor?: 'middle' | 'start' | 'end';
84
+ size: number;
85
+ color?: number[];
86
+ offset?: [number, number];
87
+ outlineColor?: number[];
88
+ };
89
+
90
+ export type MapLayerConfig = {
91
+ columns?: Record<string, any>;
92
+ color?: number[];
93
+ label?: string;
94
+ dataId: string;
95
+ textLabel: TextLabel[];
96
+ visConfig: VisConfig;
97
+ };
98
+
99
+ export type MapConfigLayer = {
100
+ type: LayerType;
101
+ id: string;
102
+ config: MapLayerConfig;
103
+ visualChannels: VisualChannels;
104
+ };
105
+
106
+ export interface CustomStyle {
107
+ url?: string;
108
+ style?: any;
109
+ customAttribution?: string;
110
+ }
111
+
112
+ // TODO replace with more complete type from Builder
113
+ export type KeplerMapConfig = {
114
+ filters: any;
115
+ mapState: any;
116
+ mapStyle: {
117
+ styleType: string;
118
+ visibleLayerGroups: Record<string, boolean>;
119
+ };
120
+ popupSettings: any;
121
+ visState: {
122
+ layers: MapConfigLayer[];
123
+ layerBlending: any;
124
+ interactionConfig: any;
125
+ };
126
+ customBaseMaps?: {
127
+ customStyle?: CustomStyle;
128
+ };
129
+ };
130
+
131
+ export type BasemapType = 'maplibre' | 'google-maps';
132
+
133
+ export type Basemap = MapLibreBasemap | GoogleBasemap;
134
+
135
+ export type BasemapCommon = {
136
+ /**
137
+ * Type of basemap.
138
+ */
139
+ type: BasemapType;
140
+
141
+ /**
142
+ * Custom attribution for style data if not provided by style definition.
143
+ */
144
+ attribution?: string;
145
+
146
+ /**
147
+ * Properties of the basemap. These properties are specific to the basemap type.
148
+ */
149
+ props: Record<string, any>;
150
+ };
151
+
152
+ export type MapLibreBasemap = BasemapCommon & {
153
+ type: 'maplibre';
154
+
155
+ /**
156
+ * MapLibre map properties.
157
+ *
158
+ * Meant to be passed to directly to `maplibregl.Map` object.
159
+ */
160
+ props: MapLibreBasemapProps;
161
+
162
+ /**
163
+ * Layer groups to be displayed in the basemap.
164
+ */
165
+ visibleLayerGroups?: Record<string, boolean>;
166
+
167
+ /**
168
+ * If `style` has been filtered by `visibleLayerGroups` then this property contains original style object, so user
169
+ * can use `applyLayerGroupFilters` again with new settings.
170
+ */
171
+ rawStyle?: string | Record<string, any>;
172
+ };
173
+
174
+ // Cherry-pick of maplibregl Map API props that are supported/provided by fetchMap interface
175
+ export type MapLibreBasemapProps = {
176
+ style: string | Record<string, any>;
177
+ center: [number, number];
178
+ zoom: number;
179
+ pitch?: number;
180
+ bearing?: number;
181
+ };
182
+
183
+ export type GoogleBasemap = BasemapCommon & {
184
+ type: 'google-maps';
185
+
186
+ /**
187
+ * Google map properties.
188
+ *
189
+ * Meant to be passed to directly to `google.maps.Map` object.
190
+ */
191
+ props: GoogleBasemapProps;
192
+ };
193
+
194
+ // Cherry-pick of Google Map API props that are supported/provided by fetchMap interface
195
+ export type GoogleBasemapProps = {
196
+ mapTypeId: string;
197
+ mapId?: string;
198
+ center?: {lat: number; lng: number};
199
+ zoom?: number;
200
+ tilt?: number;
201
+ heading?: number;
202
+ };
203
+
204
+ export type Dataset = {
205
+ id: string;
206
+ type: MapType;
207
+ source: string;
208
+ cache?: number;
209
+ connectionName: string;
210
+ geoColumn: string;
211
+ data: TilejsonResult | GeojsonResult | JsonResult;
212
+ columns: string[];
213
+ format: Format;
214
+ aggregationExp: string;
215
+ aggregationResLevel: number;
216
+ queryParameters: QueryParameters;
217
+ connectionId?: string;
218
+ providerId: ProviderType;
219
+ createdAt?: string;
220
+ updatedAt?: string;
221
+ label?: string;
222
+ color?: string;
223
+ uniqueIdProperty?: string;
224
+ queryTemplate?: string | null;
225
+ name?: string | null;
226
+ spatialIndex?: string | null;
227
+ exportToBucketAvailable?: boolean;
228
+ };
229
+
230
+ export type AttributeType = 'String' | 'Number' | 'Timestamp' | 'Boolean';
231
+
232
+ export type AttributeStatsBase = {
233
+ attribute: string;
234
+ type: AttributeType;
235
+ };
236
+
237
+ export type AttributeStatsNumber = AttributeStatsBase & {
238
+ type: 'Number';
239
+ min: number;
240
+ avg: number;
241
+ max: number;
242
+ sum: number;
243
+ quantiles: number[][];
244
+ };
245
+
246
+ export type AttributeStatsTimestamp = AttributeStatsBase & {
247
+ type: 'Timestamp';
248
+ min: string;
249
+ max: string;
250
+ };
251
+
252
+ export interface AttributeStatsStringCategory {
253
+ category: string;
254
+ frequency: number;
255
+ }
256
+
257
+ export type AttributeStatsString = AttributeStatsBase & {
258
+ type: 'String' | 'Boolean';
259
+ categories: AttributeStatsStringCategory[];
260
+ };
261
+
262
+ /**
263
+ * Result of getAttributeStats request to backend.
264
+ */
265
+ export type AttributeStats =
266
+ | AttributeStatsString
267
+ | AttributeStatsNumber
268
+ | AttributeStatsTimestamp;
@@ -0,0 +1,69 @@
1
+ import type {BinaryFeature} from '@loaders.gl/schema';
2
+ import type {Dataset} from './types.js';
3
+ type Properties = BinaryFeature['properties'];
4
+ type NumericProps = BinaryFeature['numericProps'];
5
+
6
+ // Returns a Proxy object that allows accessing binary data
7
+ // as if it were JSON properties
8
+ export function createBinaryProxy(
9
+ data: {numericProps: NumericProps; properties: Properties[]},
10
+ index: number
11
+ ) {
12
+ const {properties, numericProps} = data;
13
+ return new Proxy(properties[index] || {}, {
14
+ get(target, property) {
15
+ if (property in numericProps) {
16
+ return numericProps[property as string].value[index];
17
+ }
18
+ return target[property as any];
19
+ },
20
+
21
+ has(target, property) {
22
+ return property in numericProps || property in target;
23
+ },
24
+
25
+ ownKeys(target) {
26
+ return [...Object.keys(numericProps), ...Reflect.ownKeys(target)];
27
+ },
28
+
29
+ getOwnPropertyDescriptor() {
30
+ return {enumerable: true, configurable: true};
31
+ },
32
+ });
33
+ }
34
+
35
+ export function scaleIdentity() {
36
+ let unknown: any;
37
+
38
+ function scale(x: any) {
39
+ return x === null ? unknown : x;
40
+ }
41
+
42
+ scale.invert = scale;
43
+
44
+ scale.domain = scale.range = (d: any) => d;
45
+
46
+ scale.unknown = (u: any) => {
47
+ if (u) {
48
+ unknown = u;
49
+ }
50
+
51
+ return unknown;
52
+ };
53
+
54
+ scale.copy = () => {
55
+ const scaleCopy = scaleIdentity();
56
+ scaleCopy.unknown(unknown);
57
+ return scaleCopy;
58
+ };
59
+
60
+ return scale;
61
+ }
62
+
63
+ export function isRemoteCalculationSupported(dataset: Dataset) {
64
+ if (dataset?.type === 'tileset' || dataset.providerId === 'databricks') {
65
+ return false;
66
+ }
67
+
68
+ return true;
69
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './client.js';
2
2
  export * from './constants.js';
3
3
  export * from './deck/index.js';
4
+ export * from './fetch-map/index.js';
4
5
  export * from './filters.js';
5
6
  export * from './geo.js';
6
7
  export * from './sources/index.js';
@@ -39,10 +39,7 @@ export interface ModelSource {
39
39
  queryParameters?: QueryParameters;
40
40
  spatialDataColumn?: string;
41
41
  spatialDataType?: SpatialDataType;
42
- spatialFiltersResolution?: number;
43
42
  spatialFiltersMode?: SpatialFilterPolyfillMode;
44
- /** original resolution of the spatial index data as stored in the DW */
45
- dataResolution?: number;
46
43
  }
47
44
 
48
45
  const {V3} = ApiVersion;
@@ -86,7 +83,6 @@ export function executeModel(props: {
86
83
  filtersLogicalOperator = 'and',
87
84
  spatialDataType = 'geo',
88
85
  spatialFiltersMode = 'intersects',
89
- spatialFiltersResolution = 0,
90
86
  } = source;
91
87
 
92
88
  const queryParams: Record<string, unknown> = {
@@ -118,9 +114,6 @@ export function executeModel(props: {
118
114
  }
119
115
 
120
116
  if (spatialDataType !== 'geo') {
121
- if (spatialFiltersResolution > 0) {
122
- queryParams.spatialFiltersResolution = spatialFiltersResolution;
123
- }
124
117
  queryParams.spatialFiltersMode = spatialFiltersMode;
125
118
  }
126
119
 
@@ -18,9 +18,8 @@ import {MapType} from '../types.js';
18
18
  import {APIErrorContext} from '../api/index.js';
19
19
  import {getClient} from '../client.js';
20
20
 
21
- export const SOURCE_DEFAULTS: SourceOptionalOptions = {
21
+ export const SOURCE_DEFAULTS: Omit<SourceOptionalOptions, 'clientId'> = {
22
22
  apiBaseUrl: DEFAULT_API_BASE_URL,
23
- clientId: getClient(),
24
23
  format: 'tilejson',
25
24
  headers: {},
26
25
  maxLengthURL: DEFAULT_MAX_LENGTH_URL,
@@ -34,6 +33,7 @@ export async function baseSource<UrlParameters extends Record<string, unknown>>(
34
33
  const {accessToken, connectionName, cache, ...optionalOptions} = options;
35
34
  const mergedOptions = {
36
35
  ...SOURCE_DEFAULTS,
36
+ clientId: getClient(),
37
37
  accessToken,
38
38
  connectionName,
39
39
  endpoint,
@@ -80,6 +80,7 @@ export async function baseSource<UrlParameters extends Record<string, unknown>>(
80
80
  if (format === 'tilejson') {
81
81
  const json = await requestWithParameters<TilejsonResult>({
82
82
  baseUrl: dataUrl,
83
+ parameters: {client: clientId},
83
84
  headers,
84
85
  errorContext,
85
86
  maxLengthURL,
@@ -93,6 +94,7 @@ export async function baseSource<UrlParameters extends Record<string, unknown>>(
93
94
 
94
95
  return await requestWithParameters<GeojsonResult | JsonResult>({
95
96
  baseUrl: dataUrl,
97
+ parameters: {client: clientId},
96
98
  headers,
97
99
  errorContext,
98
100
  maxLengthURL,
@@ -2,12 +2,12 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
+ import {baseSource} from './base-source.js';
5
6
  import {getTileFormat} from '../utils/getTileFormat.js';
6
7
  import {
7
8
  WidgetTilesetSource,
8
9
  WidgetTilesetSourceResult,
9
10
  } from '../widget-sources/index.js';
10
- import {baseSource} from './base-source.js';
11
11
  import type {
12
12
  SourceOptions,
13
13
  TilejsonResult,
@@ -2,12 +2,12 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
+ import {baseSource} from './base-source.js';
5
6
  import {getTileFormat} from '../utils/getTileFormat.js';
6
7
  import {
7
8
  WidgetTilesetSource,
8
9
  WidgetTilesetSourceResult,
9
10
  } from '../widget-sources/index.js';
10
- import {baseSource} from './base-source.js';
11
11
  import type {
12
12
  SourceOptions,
13
13
  TilejsonResult,
@@ -116,11 +116,6 @@ export type AggregationOptions = {
116
116
  * @default 6 for quadbin and 4 for h3 sources
117
117
  */
118
118
  aggregationResLevel?: number;
119
-
120
- /**
121
- * Original resolution of the spatial index data as stored in the DW
122
- */
123
- dataResolution?: number;
124
119
  };
125
120
 
126
121
  export type FilterOptions = {
@@ -2,13 +2,13 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
+ import {baseSource} from './base-source.js';
5
6
  import {DEFAULT_GEO_COLUMN} from '../constants-internal.js';
6
7
  import {getTileFormat} from '../utils/getTileFormat.js';
7
8
  import {
8
9
  WidgetTilesetSource,
9
10
  WidgetTilesetSourceResult,
10
11
  } from '../widget-sources/index.js';
11
- import {baseSource} from './base-source.js';
12
12
  import type {
13
13
  SourceOptions,
14
14
  TilesetSourceOptions,
@@ -1,88 +1,6 @@
1
- import {
2
- DEFAULT_AGGREGATION_RES_LEVEL_H3,
3
- DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN,
4
- } from './constants-internal.js';
5
- import type {ModelSource} from './models/model.js';
6
- import type {AggregationOptions} from './sources/types.js';
7
- import type {ViewState} from './widget-sources/index.js';
8
-
1
+ // Default tile display size in deck.gl, in viewport pixels. May differ
2
+ // from size or resolution assumed when generating the tile data,
9
3
  const DEFAULT_TILE_SIZE = 512;
10
- const QUADBIN_ZOOM_MAX_OFFSET = 4;
11
-
12
- export function getSpatialFiltersResolution(
13
- source: Partial<ModelSource & AggregationOptions>,
14
- viewState: ViewState
15
- ): number | undefined {
16
- const dataResolution = source.dataResolution ?? Number.MAX_VALUE;
17
-
18
- const aggregationResLevel =
19
- source.aggregationResLevel ??
20
- (source.spatialDataType === 'h3'
21
- ? DEFAULT_AGGREGATION_RES_LEVEL_H3
22
- : DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN);
23
-
24
- const aggregationResLevelOffset = Math.max(
25
- 0,
26
- Math.floor(aggregationResLevel)
27
- );
28
-
29
- const currentZoomInt = Math.ceil(viewState.zoom);
30
- if (source.spatialDataType === 'h3') {
31
- const tileSize = DEFAULT_TILE_SIZE;
32
- const maxResolutionForZoom =
33
- maxH3SpatialFiltersResolutions.find(
34
- ([zoom]) => zoom === currentZoomInt
35
- )?.[1] ?? Math.max(0, currentZoomInt - 3);
36
-
37
- const maxSpatialFiltersResolution = maxResolutionForZoom
38
- ? Math.min(dataResolution, maxResolutionForZoom)
39
- : dataResolution;
40
-
41
- const hexagonResolution =
42
- _getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
43
-
44
- return Math.min(hexagonResolution, maxSpatialFiltersResolution);
45
- }
46
-
47
- if (source.spatialDataType === 'quadbin') {
48
- const maxResolutionForZoom = currentZoomInt + QUADBIN_ZOOM_MAX_OFFSET;
49
- const maxSpatialFiltersResolution = Math.min(
50
- dataResolution,
51
- maxResolutionForZoom
52
- );
53
-
54
- const quadsResolution =
55
- Math.floor(viewState.zoom) + aggregationResLevelOffset;
56
- return Math.min(quadsResolution, maxSpatialFiltersResolution);
57
- }
58
-
59
- return undefined;
60
- }
61
-
62
- const maxH3SpatialFiltersResolutions = [
63
- [20, 14],
64
- [19, 13],
65
- [18, 12],
66
- [17, 11],
67
- [16, 10],
68
- [15, 9],
69
- [14, 8],
70
- [13, 7],
71
- [12, 7],
72
- [11, 7],
73
- [10, 6],
74
- [9, 6],
75
- [8, 5],
76
- [7, 4],
77
- [6, 4],
78
- [5, 3],
79
- [4, 2],
80
- [3, 1],
81
- [2, 1],
82
- [1, 0],
83
- ];
84
-
85
- // stolen from https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
86
4
 
87
5
  // Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
88
6
  const BIAS = 2;
@@ -92,6 +10,7 @@ const BIAS = 2;
92
10
  * a H3 resolution such that the screen space size of the hexagons is
93
11
  * "similar" to the given tileSize on screen. Intended for use with deck.gl.
94
12
  * @internal
13
+ * @privateRemarks Source: https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
95
14
  */
96
15
  export function _getHexagonResolution(
97
16
  viewport: {zoom: number; latitude: number},
package/src/types.ts CHANGED
@@ -12,6 +12,16 @@ export type Format = 'json' | 'geojson' | 'tilejson';
12
12
  /** @privateRemarks Source: @carto/constants, @deck.gl/carto */
13
13
  export type MapType = 'boundary' | 'query' | 'table' | 'tileset' | 'raster';
14
14
 
15
+ /** @privateRemarks Source: cloud-native */
16
+ export type ProviderType =
17
+ | 'bigquery'
18
+ | 'postgres'
19
+ | 'snowflake'
20
+ | 'redshift'
21
+ | 'databricks'
22
+ | 'carto'
23
+ | 'carto_dw';
24
+
15
25
  /**
16
26
  * Alias for GeoJSON 'BBox' type, semantically representing a viewport.
17
27
  * Order of values is "west", "south", "east", "north".
@@ -22,8 +22,6 @@ interface BaseRequestOptions {
22
22
  signal?: AbortSignal;
23
23
  spatialFilter?: SpatialFilter;
24
24
  spatialFiltersMode?: SpatialFilterPolyfillMode;
25
- /** Required for table- and query-based spatial index sources (H3, Quadbin). */
26
- spatialIndexReferenceViewState?: ViewState;
27
25
  /** Overrides source filters, if any. */
28
26
  filters?: Filters;
29
27
  filterOwner?: string;