@deck.gl/carto 8.7.0-beta.5 → 8.7.0-beta.6

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.
Files changed (97) hide show
  1. package/dist/dist.dev.js +379 -326
  2. package/dist/es5/api/index.js.map +1 -1
  3. package/dist/es5/api/layer-map.js +8 -8
  4. package/dist/es5/api/layer-map.js.map +1 -1
  5. package/dist/es5/api/maps-api-common.js +15 -1
  6. package/dist/es5/api/maps-api-common.js.map +1 -1
  7. package/dist/es5/api/maps-client.js +15 -18
  8. package/dist/es5/api/maps-client.js.map +1 -1
  9. package/dist/es5/api/maps-v3-client.js +234 -176
  10. package/dist/es5/api/maps-v3-client.js.map +1 -1
  11. package/dist/es5/api/parseMap.js +5 -8
  12. package/dist/es5/api/parseMap.js.map +1 -1
  13. package/dist/es5/basemap.js +7 -7
  14. package/dist/es5/basemap.js.map +1 -1
  15. package/dist/es5/config.js.map +1 -1
  16. package/dist/es5/index.js +4 -4
  17. package/dist/es5/index.js.map +1 -1
  18. package/dist/es5/layers/carto-layer.js +2 -2
  19. package/dist/es5/layers/carto-layer.js.map +1 -1
  20. package/dist/es5/layers/{carto-dynamic-tile-layer.js → carto-tile-layer.js} +23 -23
  21. package/dist/es5/layers/carto-tile-layer.js.map +1 -0
  22. package/dist/es5/layers/schema/{carto-dynamic-tile.js → carto-tile.js} +1 -1
  23. package/dist/es5/layers/schema/carto-tile.js.map +1 -0
  24. package/dist/es5/style/color-bins-style.js +1 -1
  25. package/dist/es5/style/color-bins-style.js.map +1 -1
  26. package/dist/es5/style/color-categories-style.js +1 -1
  27. package/dist/es5/style/color-categories-style.js.map +1 -1
  28. package/dist/es5/style/color-continuous-style.js +1 -1
  29. package/dist/es5/style/color-continuous-style.js.map +1 -1
  30. package/dist/es5/style/palette.js +1 -6
  31. package/dist/es5/style/palette.js.map +1 -1
  32. package/dist/es5/style/utils.js +2 -6
  33. package/dist/es5/style/utils.js.map +1 -1
  34. package/dist/es5/utils.js +13 -0
  35. package/dist/es5/utils.js.map +1 -0
  36. package/dist/esm/api/index.js.map +1 -1
  37. package/dist/esm/api/layer-map.js +5 -4
  38. package/dist/esm/api/layer-map.js.map +1 -1
  39. package/dist/esm/api/maps-api-common.js +14 -0
  40. package/dist/esm/api/maps-api-common.js.map +1 -1
  41. package/dist/esm/api/maps-client.js +6 -10
  42. package/dist/esm/api/maps-client.js.map +1 -1
  43. package/dist/esm/api/maps-v3-client.js +68 -37
  44. package/dist/esm/api/maps-v3-client.js.map +1 -1
  45. package/dist/esm/api/parseMap.js +4 -3
  46. package/dist/esm/api/parseMap.js.map +1 -1
  47. package/dist/esm/basemap.js +7 -7
  48. package/dist/esm/basemap.js.map +1 -1
  49. package/dist/esm/config.js.map +1 -1
  50. package/dist/esm/index.js +2 -2
  51. package/dist/esm/index.js.map +1 -1
  52. package/dist/esm/layers/carto-layer.js +2 -2
  53. package/dist/esm/layers/carto-layer.js.map +1 -1
  54. package/dist/esm/layers/{carto-dynamic-tile-layer.js → carto-tile-layer.js} +15 -15
  55. package/dist/esm/layers/carto-tile-layer.js.map +1 -0
  56. package/dist/esm/layers/schema/{carto-dynamic-tile.js → carto-tile.js} +1 -1
  57. package/dist/esm/layers/schema/carto-tile.js.map +1 -0
  58. package/dist/esm/style/color-bins-style.js +1 -1
  59. package/dist/esm/style/color-bins-style.js.map +1 -1
  60. package/dist/esm/style/color-categories-style.js +1 -1
  61. package/dist/esm/style/color-categories-style.js.map +1 -1
  62. package/dist/esm/style/color-continuous-style.js +1 -1
  63. package/dist/esm/style/color-continuous-style.js.map +1 -1
  64. package/dist/esm/style/palette.js +1 -6
  65. package/dist/esm/style/palette.js.map +1 -1
  66. package/dist/esm/style/utils.js +2 -6
  67. package/dist/esm/style/utils.js.map +1 -1
  68. package/dist/esm/utils.js +5 -0
  69. package/dist/esm/utils.js.map +1 -0
  70. package/dist.min.js +2 -2
  71. package/package.json +8 -2
  72. package/src/api/{index.js → index.ts} +0 -0
  73. package/src/api/{layer-map.js → layer-map.ts} +25 -14
  74. package/src/api/maps-api-common.ts +76 -0
  75. package/src/api/{maps-client.js → maps-client.ts} +55 -20
  76. package/src/api/{maps-v3-client.js → maps-v3-client.ts} +143 -56
  77. package/src/api/{parseMap.js → parseMap.ts} +7 -6
  78. package/src/basemap.ts +10 -0
  79. package/src/{config.js → config.ts} +22 -6
  80. package/src/{index.js → index.ts} +2 -2
  81. package/src/layers/carto-layer.js +2 -2
  82. package/src/layers/{carto-dynamic-tile-layer.js → carto-tile-layer.js} +13 -13
  83. package/src/layers/schema/{carto-dynamic-tile.js → carto-tile.js} +0 -0
  84. package/src/style/color-bins-style.ts +26 -0
  85. package/src/style/{color-categories-style.js → color-categories-style.ts} +10 -4
  86. package/src/style/color-continuous-style.ts +25 -0
  87. package/src/style/{palette.js → palette.ts} +18 -15
  88. package/src/style/{utils.js → utils.ts} +7 -10
  89. package/src/utils.ts +5 -0
  90. package/dist/es5/layers/carto-dynamic-tile-layer.js.map +0 -1
  91. package/dist/es5/layers/schema/carto-dynamic-tile.js.map +0 -1
  92. package/dist/esm/layers/carto-dynamic-tile-layer.js.map +0 -1
  93. package/dist/esm/layers/schema/carto-dynamic-tile.js.map +0 -1
  94. package/src/api/maps-api-common.js +0 -41
  95. package/src/basemap.js +0 -10
  96. package/src/style/color-bins-style.js +0 -21
  97. package/src/style/color-continuous-style.js +0 -20
@@ -1,21 +1,36 @@
1
1
  /**
2
2
  * Maps API Client for Carto 3
3
3
  */
4
- import {getDefaultCredentials, buildMapsUrlFromBase} from '../config';
5
- import {API_VERSIONS, encodeParameter, FORMATS, MAP_TYPES} from './maps-api-common';
4
+ import {getDefaultCredentials, buildMapsUrlFromBase, CloudNativeCredentials} from '../config';
5
+ import {
6
+ API_VERSIONS,
7
+ encodeParameter,
8
+ Format,
9
+ FORMATS,
10
+ MapInstantiation,
11
+ MapType,
12
+ MAP_TYPES,
13
+ SchemaField
14
+ } from './maps-api-common';
6
15
  import {parseMap} from './parseMap';
7
16
  import {log} from '@deck.gl/core';
17
+ import {assert} from '../utils';
8
18
 
9
19
  const MAX_GET_LENGTH = 2048;
10
20
  const DEFAULT_CLIENT = 'deck-gl-carto';
11
21
 
22
+ interface RequestParams {
23
+ method?: string;
24
+ url: string;
25
+ accessToken?: string;
26
+ body?: any;
27
+ }
28
+
12
29
  /**
13
30
  * Request against Maps API
14
31
  */
15
- async function request({method, url, format, accessToken, body}) {
16
- let response;
17
-
18
- const headers = {
32
+ async function request({method, url, accessToken, body}: RequestParams): Promise<Response> {
33
+ const headers: Record<string, string> = {
19
34
  Accept: 'application/json'
20
35
  };
21
36
 
@@ -29,8 +44,7 @@ async function request({method, url, format, accessToken, body}) {
29
44
 
30
45
  try {
31
46
  /* global fetch */
32
- /* eslint no-undef: "error" */
33
- response = await fetch(url, {
47
+ return await fetch(url, {
34
48
  method,
35
49
  headers,
36
50
  body
@@ -38,24 +52,44 @@ async function request({method, url, format, accessToken, body}) {
38
52
  } catch (error) {
39
53
  throw new Error(`Failed to connect to Maps API: ${error}`);
40
54
  }
55
+ }
41
56
 
42
- if (format === FORMATS.NDJSON) {
43
- return response;
44
- }
45
-
57
+ async function requestJson<T = unknown>({
58
+ method,
59
+ url,
60
+ accessToken,
61
+ body
62
+ }: RequestParams): Promise<T> {
63
+ const response = await request({method, url, accessToken, body});
46
64
  const json = await response.json();
47
65
 
48
66
  if (!response.ok) {
49
67
  dealWithError({response, error: json.error});
50
68
  }
69
+ return json as T;
70
+ }
51
71
 
52
- return json.rows ? json.rows : json;
72
+ async function requestData({
73
+ method,
74
+ url,
75
+ accessToken,
76
+ format,
77
+ body
78
+ }: RequestParams & {
79
+ format: Format;
80
+ }): Promise<Response | unknown> {
81
+ if (format === FORMATS.NDJSON) {
82
+ return request({method, url, accessToken, body});
83
+ }
84
+
85
+ const data = await requestJson<any>({method, url, accessToken, body});
86
+ return data.rows ? data.rows : data;
53
87
  }
54
88
 
55
89
  /**
56
90
  * Display proper message from Maps API error
57
91
  */
58
- function dealWithError({response, error}) {
92
+ function dealWithError({response, error}: {response: Response; error?: string}): never {
59
93
  switch (response.status) {
60
94
  case 400:
61
95
  throw new Error(`Bad request. ${error}`);
@@ -67,10 +101,29 @@ function dealWithError({response, error}) {
67
101
  }
68
102
  }
69
103
 
104
+ type FetchLayerDataParams = {
105
+ type: MapType;
106
+ source: string;
107
+ connection: string;
108
+ credentials: CloudNativeCredentials;
109
+ geoColumn?: string;
110
+ columns?: string[];
111
+ schema?: boolean;
112
+ clientId?: string;
113
+ format?: Format;
114
+ };
115
+
70
116
  /**
71
117
  * Build a URL with all required parameters
72
118
  */
73
- function getParameters({type, source, geoColumn, columns, schema, clientId}) {
119
+ function getParameters({
120
+ type,
121
+ source,
122
+ geoColumn,
123
+ columns,
124
+ schema,
125
+ clientId
126
+ }: Omit<FetchLayerDataParams, 'connection' | 'credentials'>) {
74
127
  const parameters = [encodeParameter('client', clientId || DEFAULT_CLIENT)];
75
128
  if (schema) {
76
129
  parameters.push(encodeParameter('schema', true));
@@ -100,26 +153,24 @@ export async function mapInstantiation({
100
153
  columns,
101
154
  schema,
102
155
  clientId
103
- }) {
156
+ }: FetchLayerDataParams): Promise<MapInstantiation> {
104
157
  const baseUrl = `${credentials.mapsUrl}/${connection}/${type}`;
105
158
  const url = `${baseUrl}?${getParameters({type, source, geoColumn, columns, schema, clientId})}`;
106
159
  const {accessToken} = credentials;
107
160
 
108
- const format = 'json';
109
-
110
161
  if (url.length > MAX_GET_LENGTH && type === MAP_TYPES.QUERY) {
111
162
  // need to be a POST request
112
163
  const body = JSON.stringify({
113
164
  q: source,
114
165
  client: clientId || DEFAULT_CLIENT
115
166
  });
116
- return await request({method: 'POST', url: baseUrl, format, accessToken, body});
167
+ return await requestJson({method: 'POST', url: baseUrl, accessToken, body});
117
168
  }
118
169
 
119
- return await request({url, format, accessToken});
170
+ return await requestJson({url, accessToken});
120
171
  }
121
172
 
122
- function getUrlFromMetadata(metadata, format) {
173
+ function getUrlFromMetadata(metadata: MapInstantiation, format: Format): string | null {
123
174
  const m = metadata[format];
124
175
 
125
176
  if (m && !m.error && m.url) {
@@ -129,16 +180,26 @@ function getUrlFromMetadata(metadata, format) {
129
180
  return null;
130
181
  }
131
182
 
132
- function checkFetchLayerDataParameters({type, source, connection, localCreds}) {
133
- log.assert(connection, 'Must define connection');
134
- log.assert(type, 'Must define a type');
135
- log.assert(source, 'Must define a source');
136
-
137
- log.assert(localCreds.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
138
- log.assert(localCreds.apiBaseUrl, 'Must define apiBaseUrl');
139
- log.assert(localCreds.accessToken, 'Must define an accessToken');
183
+ function checkFetchLayerDataParameters({
184
+ type,
185
+ source,
186
+ connection,
187
+ credentials
188
+ }: FetchLayerDataParams) {
189
+ assert(connection, 'Must define connection');
190
+ assert(type, 'Must define a type');
191
+ assert(source, 'Must define a source');
192
+
193
+ assert(credentials.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
194
+ assert(credentials.apiBaseUrl, 'Must define apiBaseUrl');
195
+ assert(credentials.accessToken, 'Must define an accessToken');
140
196
  }
141
197
 
198
+ export interface FetchLayerDataResult {
199
+ data: any;
200
+ format: Format;
201
+ schema?: SchemaField[];
202
+ }
142
203
  export async function fetchLayerData({
143
204
  type,
144
205
  source,
@@ -149,7 +210,7 @@ export async function fetchLayerData({
149
210
  format,
150
211
  schema,
151
212
  clientId
152
- }) {
213
+ }: FetchLayerDataParams): Promise<FetchLayerDataResult> {
153
214
  // Internally we split data fetching into two parts to allow us to
154
215
  // conditionally fetch the actual data, depending on the metadata state
155
216
  const {url, accessToken, mapFormat, metadata} = await _fetchDataUrl({
@@ -164,8 +225,8 @@ export async function fetchLayerData({
164
225
  clientId
165
226
  });
166
227
 
167
- const data = await request({url, format: mapFormat, accessToken});
168
- const result = {data, format: mapFormat};
228
+ const data = await requestData({url, format: mapFormat, accessToken});
229
+ const result: FetchLayerDataResult = {data, format: mapFormat};
169
230
  if (schema) {
170
231
  result.schema = metadata.schema;
171
232
  }
@@ -183,7 +244,7 @@ async function _fetchDataUrl({
183
244
  format,
184
245
  schema,
185
246
  clientId
186
- }) {
247
+ }: FetchLayerDataParams) {
187
248
  const defaultCredentials = getDefaultCredentials();
188
249
  // Only pick up default credentials if they have been defined for
189
250
  // correct API version
@@ -191,7 +252,7 @@ async function _fetchDataUrl({
191
252
  ...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
192
253
  ...credentials
193
254
  };
194
- checkFetchLayerDataParameters({type, source, connection, localCreds});
255
+ checkFetchLayerDataParameters({type, source, connection, credentials: localCreds});
195
256
 
196
257
  if (!localCreds.mapsUrl) {
197
258
  localCreds.mapsUrl = buildMapsUrlFromBase(localCreds.apiBaseUrl);
@@ -207,13 +268,13 @@ async function _fetchDataUrl({
207
268
  schema,
208
269
  clientId
209
270
  });
210
- let url;
211
- let mapFormat;
271
+ let url: string | null = null;
272
+ let mapFormat: Format | undefined;
212
273
 
213
274
  if (format) {
214
275
  mapFormat = format;
215
276
  url = getUrlFromMetadata(metadata, format);
216
- log.assert(url, `Format ${format} not available`);
277
+ assert(url, `Format ${format} not available`);
217
278
  } else {
218
279
  // guess map format
219
280
  const prioritizedFormats = [FORMATS.GEOJSON, FORMATS.JSON, FORMATS.NDJSON, FORMATS.TILEJSON];
@@ -224,6 +285,7 @@ async function _fetchDataUrl({
224
285
  break;
225
286
  }
226
287
  }
288
+ assert(url && mapFormat, 'Unsupported data formats received from backend.');
227
289
  }
228
290
 
229
291
  const {accessToken} = localCreds;
@@ -239,7 +301,7 @@ export async function getData({
239
301
  columns,
240
302
  format,
241
303
  clientId
242
- }) {
304
+ }: FetchLayerDataParams) {
243
305
  log.deprecated('getData', 'fetchLayerData')();
244
306
  const layerData = await fetchLayerData({
245
307
  type,
@@ -256,7 +318,12 @@ export async function getData({
256
318
  }
257
319
 
258
320
  /* global clearInterval, setInterval, URL */
259
- async function _fetchMapDataset(dataset, accessToken, credentials, clientId) {
321
+ async function _fetchMapDataset(
322
+ dataset,
323
+ accessToken: string,
324
+ credentials: CloudNativeCredentials,
325
+ clientId?: string
326
+ ) {
260
327
  // First fetch metadata
261
328
  const {connectionName: connection, source, type} = dataset;
262
329
  const {url, mapFormat} = await _fetchDataUrl({
@@ -268,55 +335,75 @@ async function _fetchMapDataset(dataset, accessToken, credentials, clientId) {
268
335
  });
269
336
 
270
337
  // Extract the last time the data changed
271
- const cache = parseInt(new URL(url).searchParams.get('cache'), 10);
338
+ const cache = parseInt(new URL(url).searchParams.get('cache') || '', 10);
272
339
  if (cache && dataset.cache === cache) {
273
340
  return false;
274
341
  }
275
342
  dataset.cache = cache;
276
343
 
277
344
  // Only fetch if the data has changed
278
- const data = await request({url, format: mapFormat, accessToken});
279
- dataset.data = data;
345
+ dataset.data = await requestData({url, format: mapFormat, accessToken});
346
+
280
347
  return true;
281
348
  }
282
349
 
283
- async function fillInMapDatasets({datasets, token}, clientId, credentials) {
350
+ async function fillInMapDatasets(
351
+ {datasets, token},
352
+ clientId: string,
353
+ credentials: CloudNativeCredentials
354
+ ) {
284
355
  const promises = datasets.map(dataset => _fetchMapDataset(dataset, token, credentials, clientId));
285
356
  return await Promise.all(promises);
286
357
  }
287
358
 
288
- export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh, onNewData}) {
359
+ export async function fetchMap({
360
+ cartoMapId,
361
+ clientId,
362
+ credentials,
363
+ autoRefresh,
364
+ onNewData
365
+ }: {
366
+ cartoMapId: string;
367
+ clientId: string;
368
+ credentials?: CloudNativeCredentials;
369
+ autoRefresh?: number;
370
+ onNewData?: (map: any) => void;
371
+ }) {
289
372
  const defaultCredentials = getDefaultCredentials();
290
373
  const localCreds = {
291
374
  ...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
292
375
  ...credentials
293
- };
376
+ } as CloudNativeCredentials;
294
377
  const {accessToken} = localCreds;
295
378
 
296
- log.assert(cartoMapId, `Must define CARTO map id: fetchMap({cartoMapId: 'XXXX-XXXX-XXXX'})`);
379
+ assert(cartoMapId, 'Must define CARTO map id: fetchMap({cartoMapId: "XXXX-XXXX-XXXX"})');
297
380
 
298
- log.assert(localCreds.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
299
- log.assert(localCreds.apiBaseUrl, 'Must define apiBaseUrl');
381
+ assert(localCreds.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
382
+ assert(localCreds.apiBaseUrl, 'Must define apiBaseUrl');
300
383
  if (!localCreds.mapsUrl) {
301
384
  localCreds.mapsUrl = buildMapsUrlFromBase(localCreds.apiBaseUrl);
302
385
  }
303
386
 
304
387
  if (autoRefresh || onNewData) {
305
- log.assert(onNewData, 'Must define `onNewData` when using autoRefresh');
306
- log.assert(typeof onNewData === 'function', '`onNewData` must be a function');
307
- log.assert(autoRefresh > 0, '`autoRefresh` must be a positive number');
388
+ assert(onNewData, 'Must define `onNewData` when using autoRefresh');
389
+ assert(typeof onNewData === 'function', '`onNewData` must be a function');
390
+ assert(
391
+ typeof autoRefresh === 'number' && autoRefresh > 0,
392
+ '`autoRefresh` must be a positive number'
393
+ );
308
394
  }
309
395
 
310
396
  const url = `${localCreds.mapsUrl}/public/${cartoMapId}`;
311
- const map = await request({url, accessToken});
397
+ const map = await requestJson<any>({url, accessToken});
312
398
 
313
399
  // Periodically check if the data has changed. Note that this
314
400
  // will not update when a map is published.
315
- let stopAutoRefresh;
401
+ let stopAutoRefresh: (() => void) | undefined;
316
402
  if (autoRefresh) {
403
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
317
404
  const intervalId = setInterval(async () => {
318
- const changed = await fillInMapDatasets(map, clientId, credentials);
319
- if (changed.some(v => v === true)) {
405
+ const changed = await fillInMapDatasets(map, clientId, localCreds);
406
+ if (onNewData && changed.some(v => v === true)) {
320
407
  onNewData(parseMap(map));
321
408
  }
322
409
  }, autoRefresh * 1000);
@@ -326,7 +413,7 @@ export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh,
326
413
  }
327
414
 
328
415
  // Mutates map.datasets so that dataset.data contains data
329
- await fillInMapDatasets(map, clientId, credentials);
416
+ await fillInMapDatasets(map, clientId, localCreds);
330
417
  return {
331
418
  ...parseMap(map),
332
419
  ...{stopAutoRefresh}
@@ -7,10 +7,11 @@ import {
7
7
  getTextPixelOffsetAccessor
8
8
  } from './layer-map';
9
9
  import {_flatten as flatten, log} from '@deck.gl/core';
10
+ import {assert} from '../utils';
10
11
 
11
12
  export function parseMap(json) {
12
13
  const {keplerMapConfig, datasets} = json;
13
- log.assert(keplerMapConfig.version === 'v1', 'Only support Kepler v1');
14
+ assert(keplerMapConfig.version === 'v1', 'Only support Kepler v1');
14
15
  const {mapState, mapStyle} = keplerMapConfig.config;
15
16
  const {layers, layerBlending, interactionConfig} = keplerMapConfig.config.visState;
16
17
 
@@ -26,9 +27,9 @@ export function parseMap(json) {
26
27
  try {
27
28
  const {dataId} = config;
28
29
  const dataset = datasets.find(d => d.id === dataId);
29
- log.assert(dataset, `No dataset matching dataId: ${dataId}`);
30
+ assert(dataset, `No dataset matching dataId: ${dataId}`);
30
31
  const {data} = dataset;
31
- log.assert(data, `No data loaded for dataId: ${dataId}`);
32
+ assert(data, `No data loaded for dataId: ${dataId}`);
32
33
  const {Layer, propMap, defaultProps} = getLayer(type, config, dataset);
33
34
  return new Layer({
34
35
  id,
@@ -39,7 +40,7 @@ export function parseMap(json) {
39
40
  ...createStyleProps(config, propMap),
40
41
  ...createChannelProps(visualChannels, type, config, data) // Must come after style
41
42
  });
42
- } catch (e) {
43
+ } catch (e: any) {
43
44
  log.error(e.message)();
44
45
  return undefined;
45
46
  }
@@ -121,7 +122,7 @@ function mapProps(source, target, mapping) {
121
122
  }
122
123
 
123
124
  function createStyleProps(config, mapping) {
124
- const result = {};
125
+ const result: Record<string, any> = {};
125
126
  mapProps(config, result, mapping);
126
127
  result.highlightColor = config.visConfig.enable3d ? [255, 255, 255, 60] : [252, 242, 26, 255];
127
128
  return result;
@@ -137,7 +138,7 @@ function createChannelProps(visualChannels, type, config, data) {
137
138
  heightScale = sizeScale;
138
139
  }
139
140
  const {textLabel, visConfig} = config;
140
- const result = {};
141
+ const result: Record<string, any> = {};
141
142
  const textLabelField = textLabel && textLabel.field;
142
143
  if (colorField) {
143
144
  result.getFillColor = getColorAccessor(
package/src/basemap.ts ADDED
@@ -0,0 +1,10 @@
1
+ const baseUrl = 'https://basemaps.cartocdn.com/gl/{basemap}-gl-style/style.json';
2
+
3
+ export default {
4
+ VOYAGER: baseUrl.replace('{basemap}', 'voyager'),
5
+ POSITRON: baseUrl.replace('{basemap}', 'positron'),
6
+ DARK_MATTER: baseUrl.replace('{basemap}', 'dark-matter'),
7
+ VOYAGER_NOLABELS: baseUrl.replace('{basemap}', 'voyager-nolabels'),
8
+ POSITRON_NOLABELS: baseUrl.replace('{basemap}', 'positron-nolabels'),
9
+ DARK_MATTER_NOLABELS: baseUrl.replace('{basemap}', 'dark-matter-nolabels')
10
+ } as const;
@@ -4,17 +4,33 @@ export const defaultClassicCredentials = {
4
4
  apiKey: 'default_public',
5
5
  region: 'us',
6
6
  username: 'public'
7
- };
7
+ } as const;
8
8
 
9
9
  export const defaultCloudNativeCredentials = {
10
10
  apiBaseUrl: 'https://gcp-us-east1.api.carto.com'
11
- };
11
+ } as const;
12
+
13
+ export interface ClassicCredentials {
14
+ apiVersion: 'v1' | 'v2';
15
+ apiKey: string;
16
+ region: string;
17
+ username: string;
18
+ mapsUrl?: string;
19
+ }
20
+
21
+ export interface CloudNativeCredentials {
22
+ apiVersion: 'v3';
23
+ apiBaseUrl: string;
24
+ accessToken?: string;
25
+ mapsUrl?: string;
26
+ }
12
27
 
13
- let credentials = {};
28
+ export type Credentials = ClassicCredentials | CloudNativeCredentials;
29
+ let credentials: Credentials = {} as Credentials;
14
30
 
15
31
  setDefaultCredentials({});
16
32
 
17
- export function setDefaultCredentials({apiVersion, ...rest}) {
33
+ export function setDefaultCredentials({apiVersion, ...rest}: Partial<Credentials>) {
18
34
  apiVersion = apiVersion || API_VERSIONS.V3;
19
35
 
20
36
  switch (apiVersion) {
@@ -30,11 +46,11 @@ export function setDefaultCredentials({apiVersion, ...rest}) {
30
46
  }
31
47
  }
32
48
 
33
- export function getDefaultCredentials() {
49
+ export function getDefaultCredentials(): Credentials {
34
50
  return credentials;
35
51
  }
36
52
 
37
- export function buildMapsUrlFromBase(apiBaseUrl) {
53
+ export function buildMapsUrlFromBase(apiBaseUrl: string): string {
38
54
  let suffix = '/v3/maps';
39
55
  if (apiBaseUrl.endsWith('/')) {
40
56
  suffix = suffix.substring(1);
@@ -1,6 +1,6 @@
1
- export {getDefaultCredentials, setDefaultCredentials} from './config.js';
1
+ export {getDefaultCredentials, setDefaultCredentials} from './config';
2
2
  export {default as CartoLayer} from './layers/carto-layer';
3
- export {default as _CartoDynamicTileLayer} from './layers/carto-dynamic-tile-layer';
3
+ export {default as _CartoTileLayer} from './layers/carto-tile-layer';
4
4
  export {default as BASEMAP} from './basemap';
5
5
  export {default as colorBins} from './style/color-bins-style';
6
6
  export {default as colorCategories} from './style/color-categories-style';
@@ -1,5 +1,5 @@
1
1
  import {CompositeLayer, log} from '@deck.gl/core';
2
- import CartoDynamicTileLayer from './carto-dynamic-tile-layer';
2
+ import CartoTileLayer from './carto-tile-layer';
3
3
  import {MVTLayer} from '@deck.gl/geo-layers';
4
4
  import {GeoJsonLayer} from '@deck.gl/layers';
5
5
  import {fetchLayerData, getDataV2, API_VERSIONS} from '../api';
@@ -139,7 +139,7 @@ export default class CartoLayer extends CompositeLayer {
139
139
  this.props.formatTiles ||
140
140
  new URL(data.tiles[0]).searchParams.get('formatTiles') ||
141
141
  TILE_FORMATS.MVT;
142
- return formatTiles === TILE_FORMATS.MVT ? MVTLayer : CartoDynamicTileLayer;
142
+ return formatTiles === TILE_FORMATS.MVT ? MVTLayer : CartoTileLayer;
143
143
  }
144
144
 
145
145
  // It's a geojson layer
@@ -5,7 +5,7 @@ import {ClipExtension} from '@deck.gl/extensions';
5
5
  import {MVTLayer, _getURLFromTemplate} from '@deck.gl/geo-layers';
6
6
  import {GeoJsonLayer} from '@deck.gl/layers';
7
7
  import {geojsonToBinary} from '@loaders.gl/gis';
8
- import {Tile} from './schema/carto-dynamic-tile';
8
+ import {Tile} from './schema/carto-tile';
9
9
  import {TILE_FORMATS} from '../api/maps-api-common';
10
10
 
11
11
  function parseJSON(arrayBuffer) {
@@ -31,9 +31,9 @@ function unpackProperties(properties) {
31
31
  });
32
32
  }
33
33
 
34
- function parseCartoDynamicTile(arrayBuffer, options) {
34
+ function parseCartoTile(arrayBuffer, options) {
35
35
  if (!arrayBuffer) return null;
36
- const formatTiles = options && options.cartoDynamicTile && options.cartoDynamicTile.formatTiles;
36
+ const formatTiles = options && options.cartoTile && options.cartoTile.formatTiles;
37
37
  if (formatTiles === TILE_FORMATS.GEOJSON) return geojsonToBinary(parseJSON(arrayBuffer).features);
38
38
 
39
39
  const tile = parsePbf(arrayBuffer);
@@ -48,25 +48,25 @@ function parseCartoDynamicTile(arrayBuffer, options) {
48
48
  return data;
49
49
  }
50
50
 
51
- const CartoDynamicTileLoader = {
52
- name: 'CARTO Dynamic Tile',
53
- id: 'cartoDynamicTile',
51
+ const CartoTileLoader = {
52
+ name: 'CARTO Tile',
53
+ id: 'cartoTile',
54
54
  module: 'carto',
55
55
  extensions: ['pbf'],
56
56
  mimeTypes: ['application/x-protobuf'],
57
57
  category: 'geometry',
58
58
  worker: false,
59
- parse: async (arrayBuffer, options) => parseCartoDynamicTile(arrayBuffer, options),
60
- parseSync: parseCartoDynamicTile,
59
+ parse: async (arrayBuffer, options) => parseCartoTile(arrayBuffer, options),
60
+ parseSync: parseCartoTile,
61
61
  options: {
62
- cartoDynamicTile: {
62
+ cartoTile: {
63
63
  // TODO change to BINARY for 8.7 prod release
64
64
  formatTiles: TILE_FORMATS.GEOJSON
65
65
  }
66
66
  }
67
67
  };
68
68
 
69
- export default class CartoDynamicTileLayer extends MVTLayer {
69
+ export default class CartoTileLayer extends MVTLayer {
70
70
  getTileData(tile) {
71
71
  let url = _getURLFromTemplate(this.state.data, tile);
72
72
  if (!url) {
@@ -91,7 +91,7 @@ export default class CartoDynamicTileLayer extends MVTLayer {
91
91
  const newUrl = new URL(url);
92
92
  newUrl.searchParams.set('formatTiles', formatTiles);
93
93
  url = newUrl.toString();
94
- loadOptions.cartoDynamicTile = {formatTiles};
94
+ loadOptions.cartoTile = {formatTiles};
95
95
  }
96
96
 
97
97
  return fetch(url, {propName: 'data', layer: this, loadOptions, signal});
@@ -117,5 +117,5 @@ export default class CartoDynamicTileLayer extends MVTLayer {
117
117
  }
118
118
  }
119
119
 
120
- CartoDynamicTileLayer.layerName = 'CartoDynamicTileLayer';
121
- CartoDynamicTileLayer.defaultProps = {...MVTLayer.defaultProps, loaders: [CartoDynamicTileLoader]};
120
+ CartoTileLayer.layerName = 'CartoTileLayer';
121
+ CartoTileLayer.defaultProps = {...MVTLayer.defaultProps, loaders: [CartoTileLoader]};
@@ -0,0 +1,26 @@
1
+ import {scaleThreshold} from 'd3-scale';
2
+ import getPalette, {Color, DEFAULT_PALETTE, NULL_COLOR} from './palette';
3
+ import {assert, AttributeSelector, getAttrValue} from './utils';
4
+
5
+ export default function colorBins({
6
+ attr,
7
+ domain,
8
+ colors = DEFAULT_PALETTE,
9
+ nullColor = NULL_COLOR
10
+ }: {
11
+ attr: AttributeSelector;
12
+ domain: number[];
13
+ colors?: string | Color[];
14
+ nullColor?: Color;
15
+ }): AttributeSelector {
16
+ assert(Array.isArray(domain), 'Expected "domain" to be an array of numbers');
17
+
18
+ const palette = typeof colors === 'string' ? getPalette(colors, domain.length + 1) : colors;
19
+
20
+ const color = scaleThreshold<number, Color>().domain(domain).range(palette);
21
+
22
+ return d => {
23
+ const value = getAttrValue(attr, d);
24
+ return typeof value === 'number' && Number.isFinite(value) ? color(value) : nullColor;
25
+ };
26
+ }
@@ -1,5 +1,5 @@
1
- import getPalette, {DEFAULT_PALETTE, NULL_COLOR, OTHERS_COLOR} from './palette';
2
- import {assert, getAttrValue} from './utils';
1
+ import getPalette, {Color, DEFAULT_PALETTE, NULL_COLOR, OTHERS_COLOR} from './palette';
2
+ import {assert, AttributeSelector, getAttrValue} from './utils';
3
3
 
4
4
  export default function colorCategories({
5
5
  attr,
@@ -7,7 +7,13 @@ export default function colorCategories({
7
7
  colors = DEFAULT_PALETTE,
8
8
  nullColor = NULL_COLOR,
9
9
  othersColor = OTHERS_COLOR
10
- }) {
10
+ }: {
11
+ attr: AttributeSelector;
12
+ domain: number[];
13
+ colors: string | Color[];
14
+ nullColor?: Color;
15
+ othersColor?: Color;
16
+ }): AttributeSelector {
11
17
  assert(Array.isArray(domain), 'Expected "domain" to be an array of numbers or strings');
12
18
 
13
19
  const colorsByCategory = {};
@@ -19,7 +25,7 @@ export default function colorCategories({
19
25
 
20
26
  return d => {
21
27
  const value = getAttrValue(attr, d);
22
- return Number.isFinite(value) || typeof value === 'string'
28
+ return (typeof value === 'number' && Number.isFinite(value)) || typeof value === 'string'
23
29
  ? colorsByCategory[value] || othersColor
24
30
  : nullColor;
25
31
  };
@@ -0,0 +1,25 @@
1
+ import {scaleLinear} from 'd3-scale';
2
+ import getPalette, {Color, DEFAULT_PALETTE, NULL_COLOR} from './palette';
3
+ import {assert, AttributeSelector, getAttrValue} from './utils';
4
+
5
+ export default function colorContinuous({
6
+ attr,
7
+ domain,
8
+ colors = DEFAULT_PALETTE,
9
+ nullColor = NULL_COLOR
10
+ }: {
11
+ attr: AttributeSelector;
12
+ domain: number[];
13
+ colors?: string | Color[];
14
+ nullColor?: Color;
15
+ }): AttributeSelector {
16
+ assert(Array.isArray(domain), 'Expected "domain" to be an array of numbers');
17
+
18
+ const palette = typeof colors === 'string' ? getPalette(colors, domain.length) : colors;
19
+ const color = scaleLinear<Color>().domain(domain).range(palette);
20
+
21
+ return d => {
22
+ const value = getAttrValue(attr, d);
23
+ return typeof value === 'number' && Number.isFinite(value) ? color(value) : nullColor;
24
+ };
25
+ }