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

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 +398 -343
  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 +237 -177
  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 +20 -18
  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} +24 -24
  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 +72 -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 +15 -17
  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} +16 -16
  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 +4 -4
  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} +146 -57
  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 +13 -12
  82. package/src/layers/{carto-dynamic-tile-layer.js → carto-tile-layer.js} +14 -14
  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
+ }
71
+
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
+ }
51
84
 
52
- return json.rows ? json.rows : json;
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,67 +318,94 @@ 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
+ ) {
327
+ const {connectionName: connection, columns, geoColumn, source, type} = dataset;
260
328
  // First fetch metadata
261
- const {connectionName: connection, source, type} = dataset;
262
329
  const {url, mapFormat} = await _fetchDataUrl({
263
330
  credentials: {...credentials, accessToken},
264
331
  connection,
332
+ columns,
333
+ geoColumn,
265
334
  source,
266
335
  type,
267
336
  clientId
268
337
  });
269
338
 
270
339
  // Extract the last time the data changed
271
- const cache = parseInt(new URL(url).searchParams.get('cache'), 10);
340
+ const cache = parseInt(new URL(url).searchParams.get('cache') || '', 10);
272
341
  if (cache && dataset.cache === cache) {
273
342
  return false;
274
343
  }
275
344
  dataset.cache = cache;
276
345
 
277
346
  // Only fetch if the data has changed
278
- const data = await request({url, format: mapFormat, accessToken});
279
- dataset.data = data;
347
+ dataset.data = await requestData({url, format: mapFormat, accessToken});
348
+
280
349
  return true;
281
350
  }
282
351
 
283
- async function fillInMapDatasets({datasets, token}, clientId, credentials) {
352
+ async function fillInMapDatasets(
353
+ {datasets, token},
354
+ clientId: string,
355
+ credentials: CloudNativeCredentials
356
+ ) {
284
357
  const promises = datasets.map(dataset => _fetchMapDataset(dataset, token, credentials, clientId));
285
358
  return await Promise.all(promises);
286
359
  }
287
360
 
288
- export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh, onNewData}) {
361
+ export async function fetchMap({
362
+ cartoMapId,
363
+ clientId,
364
+ credentials,
365
+ autoRefresh,
366
+ onNewData
367
+ }: {
368
+ cartoMapId: string;
369
+ clientId: string;
370
+ credentials?: CloudNativeCredentials;
371
+ autoRefresh?: number;
372
+ onNewData?: (map: any) => void;
373
+ }) {
289
374
  const defaultCredentials = getDefaultCredentials();
290
375
  const localCreds = {
291
376
  ...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
292
377
  ...credentials
293
- };
378
+ } as CloudNativeCredentials;
294
379
  const {accessToken} = localCreds;
295
380
 
296
- log.assert(cartoMapId, `Must define CARTO map id: fetchMap({cartoMapId: 'XXXX-XXXX-XXXX'})`);
381
+ assert(cartoMapId, 'Must define CARTO map id: fetchMap({cartoMapId: "XXXX-XXXX-XXXX"})');
297
382
 
298
- log.assert(localCreds.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
299
- log.assert(localCreds.apiBaseUrl, 'Must define apiBaseUrl');
383
+ assert(localCreds.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
384
+ assert(localCreds.apiBaseUrl, 'Must define apiBaseUrl');
300
385
  if (!localCreds.mapsUrl) {
301
386
  localCreds.mapsUrl = buildMapsUrlFromBase(localCreds.apiBaseUrl);
302
387
  }
303
388
 
304
389
  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');
390
+ assert(onNewData, 'Must define `onNewData` when using autoRefresh');
391
+ assert(typeof onNewData === 'function', '`onNewData` must be a function');
392
+ assert(
393
+ typeof autoRefresh === 'number' && autoRefresh > 0,
394
+ '`autoRefresh` must be a positive number'
395
+ );
308
396
  }
309
397
 
310
398
  const url = `${localCreds.mapsUrl}/public/${cartoMapId}`;
311
- const map = await request({url, accessToken});
399
+ const map = await requestJson<any>({url, accessToken});
312
400
 
313
401
  // Periodically check if the data has changed. Note that this
314
402
  // will not update when a map is published.
315
- let stopAutoRefresh;
403
+ let stopAutoRefresh: (() => void) | undefined;
316
404
  if (autoRefresh) {
405
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
317
406
  const intervalId = setInterval(async () => {
318
- const changed = await fillInMapDatasets(map, clientId, credentials);
319
- if (changed.some(v => v === true)) {
407
+ const changed = await fillInMapDatasets(map, clientId, localCreds);
408
+ if (onNewData && changed.some(v => v === true)) {
320
409
  onNewData(parseMap(map));
321
410
  }
322
411
  }, autoRefresh * 1000);
@@ -326,7 +415,7 @@ export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh,
326
415
  }
327
416
 
328
417
  // Mutates map.datasets so that dataset.data contains data
329
- await fillInMapDatasets(map, clientId, credentials);
418
+ await fillInMapDatasets(map, clientId, localCreds);
330
419
  return {
331
420
  ...parseMap(map),
332
421
  ...{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';
@@ -126,24 +126,29 @@ export default class CartoLayer extends CompositeLayer {
126
126
  }
127
127
  }
128
128
 
129
- _getRenderLayer() {
129
+ _getSubLayerAndProps() {
130
130
  const {data, format, apiVersion} = this.state;
131
131
 
132
+ const {uniqueIdProperty} = defaultProps;
133
+ const props = {uniqueIdProperty, ...this.props};
134
+ delete props.data;
135
+
132
136
  if (apiVersion === API_VERSIONS.V1 || apiVersion === API_VERSIONS.V2) {
133
- return MVTLayer;
137
+ return [MVTLayer, props];
134
138
  }
135
139
 
136
140
  if (format === FORMATS.TILEJSON) {
137
141
  /* global URL */
138
- const formatTiles =
139
- this.props.formatTiles ||
142
+ props.formatTiles =
143
+ props.formatTiles ||
140
144
  new URL(data.tiles[0]).searchParams.get('formatTiles') ||
141
145
  TILE_FORMATS.MVT;
142
- return formatTiles === TILE_FORMATS.MVT ? MVTLayer : CartoDynamicTileLayer;
146
+
147
+ return props.formatTiles === TILE_FORMATS.MVT ? [MVTLayer, props] : [CartoTileLayer, props];
143
148
  }
144
149
 
145
150
  // It's a geojson layer
146
- return GeoJsonLayer;
151
+ return [GeoJsonLayer, props];
147
152
  }
148
153
 
149
154
  renderLayers() {
@@ -153,11 +158,7 @@ export default class CartoLayer extends CompositeLayer {
153
158
 
154
159
  const {updateTriggers} = this.props;
155
160
 
156
- const layer = this._getRenderLayer();
157
-
158
- const {formatTiles, uniqueIdProperty} = defaultProps;
159
- const props = {formatTiles, uniqueIdProperty, ...this.props};
160
- delete props.data;
161
+ const [layer, props] = this._getSubLayerAndProps();
161
162
 
162
163
  // eslint-disable-next-line new-cap
163
164
  return new 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
- formatTiles: TILE_FORMATS.GEOJSON
64
+ formatTiles: TILE_FORMATS.BINARY
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
+ }