@deck.gl/carto 8.7.0-alpha.1 → 8.7.0-alpha.10

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 (67) hide show
  1. package/dist/dist.dev.js +38143 -16628
  2. package/dist/es5/api/layer-map.js +4 -3
  3. package/dist/es5/api/layer-map.js.map +1 -1
  4. package/dist/es5/api/maps-client.js +2 -2
  5. package/dist/es5/api/maps-client.js.map +1 -1
  6. package/dist/es5/api/maps-v3-client.js +57 -43
  7. package/dist/es5/api/maps-v3-client.js.map +1 -1
  8. package/dist/es5/api/parseMap.js +9 -13
  9. package/dist/es5/api/parseMap.js.map +1 -1
  10. package/dist/es5/config.js +15 -24
  11. package/dist/es5/config.js.map +1 -1
  12. package/dist/es5/index.js +0 -16
  13. package/dist/es5/index.js.map +1 -1
  14. package/dist/es5/layers/carto-dynamic-tile-layer.js +168 -0
  15. package/dist/es5/layers/carto-dynamic-tile-layer.js.map +1 -0
  16. package/dist/es5/layers/carto-layer.js +59 -52
  17. package/dist/es5/layers/carto-layer.js.map +1 -1
  18. package/dist/es5/style/color-bins-style.js +6 -2
  19. package/dist/es5/style/color-bins-style.js.map +1 -1
  20. package/dist/es5/style/color-categories-style.js +7 -3
  21. package/dist/es5/style/color-categories-style.js.map +1 -1
  22. package/dist/es5/style/color-continuous-style.js +6 -2
  23. package/dist/es5/style/color-continuous-style.js.map +1 -1
  24. package/dist/es5/style/palette.js +6 -2
  25. package/dist/es5/style/palette.js.map +1 -1
  26. package/dist/esm/api/layer-map.js +3 -2
  27. package/dist/esm/api/layer-map.js.map +1 -1
  28. package/dist/esm/api/maps-client.js +1 -1
  29. package/dist/esm/api/maps-client.js.map +1 -1
  30. package/dist/esm/api/maps-v3-client.js +47 -25
  31. package/dist/esm/api/maps-v3-client.js.map +1 -1
  32. package/dist/esm/api/parseMap.js +3 -10
  33. package/dist/esm/api/parseMap.js.map +1 -1
  34. package/dist/esm/config.js +11 -26
  35. package/dist/esm/config.js.map +1 -1
  36. package/dist/esm/index.js +0 -2
  37. package/dist/esm/index.js.map +1 -1
  38. package/dist/esm/layers/carto-dynamic-tile-layer.js +98 -0
  39. package/dist/esm/layers/carto-dynamic-tile-layer.js.map +1 -0
  40. package/dist/esm/layers/carto-layer.js +35 -28
  41. package/dist/esm/layers/carto-layer.js.map +1 -1
  42. package/dist/esm/style/color-bins-style.js +1 -1
  43. package/dist/esm/style/color-bins-style.js.map +1 -1
  44. package/dist/esm/style/color-continuous-style.js +1 -1
  45. package/dist/esm/style/color-continuous-style.js.map +1 -1
  46. package/dist.min.js +14 -14
  47. package/package.json +8 -7
  48. package/src/api/layer-map.js +3 -2
  49. package/src/api/maps-client.js +3 -7
  50. package/src/api/maps-v3-client.js +53 -25
  51. package/src/api/parseMap.js +17 -26
  52. package/src/config.js +8 -39
  53. package/src/index.js +0 -2
  54. package/src/layers/carto-dynamic-tile-layer.js +87 -0
  55. package/src/layers/carto-layer.js +25 -25
  56. package/src/style/color-bins-style.js +2 -4
  57. package/src/style/color-continuous-style.js +2 -4
  58. package/dist/es5/layers/carto-bqtiler-layer.js +0 -65
  59. package/dist/es5/layers/carto-bqtiler-layer.js.map +0 -1
  60. package/dist/es5/layers/carto-sql-layer.js +0 -66
  61. package/dist/es5/layers/carto-sql-layer.js.map +0 -1
  62. package/dist/esm/layers/carto-bqtiler-layer.js +0 -16
  63. package/dist/esm/layers/carto-bqtiler-layer.js.map +0 -1
  64. package/dist/esm/layers/carto-sql-layer.js +0 -17
  65. package/dist/esm/layers/carto-sql-layer.js.map +0 -1
  66. package/src/layers/carto-bqtiler-layer.js +0 -21
  67. package/src/layers/carto-sql-layer.js +0 -22
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@deck.gl/carto",
3
3
  "description": "CARTO official integration with Deck.gl. Build geospatial applications using CARTO and Deck.gl.",
4
4
  "license": "MIT",
5
- "version": "8.7.0-alpha.1",
5
+ "version": "8.7.0-alpha.10",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -31,10 +31,11 @@
31
31
  "prepublishOnly": "npm run build-bundle && npm run build-bundle -- --env.dev"
32
32
  },
33
33
  "dependencies": {
34
- "@loaders.gl/loader-utils": "^3.0.8",
35
- "@loaders.gl/mvt": "^3.0.8",
36
- "@loaders.gl/tiles": "^3.0.8",
37
- "@math.gl/web-mercator": "^3.5.4",
34
+ "@loaders.gl/gis": "^3.1.3",
35
+ "@loaders.gl/loader-utils": "^3.1.3",
36
+ "@loaders.gl/mvt": "^3.1.3",
37
+ "@loaders.gl/tiles": "^3.1.3",
38
+ "@math.gl/web-mercator": "^3.5.6",
38
39
  "cartocolor": "^4.0.2",
39
40
  "d3-array": "^2.8.0",
40
41
  "d3-color": "^2.0.0",
@@ -46,7 +47,7 @@
46
47
  "@deck.gl/core": "^8.0.0",
47
48
  "@deck.gl/geo-layers": "^8.0.0",
48
49
  "@deck.gl/layers": "^8.0.0",
49
- "@loaders.gl/core": "^3.0.0"
50
+ "@loaders.gl/core": "^3.1.3"
50
51
  },
51
- "gitHead": "dbaa3941a41f3ddceecad4d2d2879515d97d2510"
52
+ "gitHead": "b6c48fb68b66755743c28776a0642b56a2df086a"
52
53
  }
@@ -28,6 +28,7 @@ const SCALE_FUNCS = {
28
28
  const sharedPropMap = {
29
29
  color: 'getFillColor',
30
30
  isVisible: 'visible',
31
+ label: 'cartoLabel',
31
32
  textLabel: {
32
33
  alignment: 'getTextAlignmentBaseline',
33
34
  anchor: 'getTextAnchor',
@@ -117,7 +118,7 @@ function calculateDomain(data, name, scaleType) {
117
118
  // GeoJSON data type
118
119
  const values = data.features.map(({properties}) => properties[name]);
119
120
  return domainFromValues(values, scaleType);
120
- } else if (Array.isArray(data) && data[0][name]) {
121
+ } else if (Array.isArray(data) && data[0][name] !== undefined) {
121
122
  // JSON data type
122
123
  const values = data.map(properties => properties[name]);
123
124
  return domainFromValues(values, scaleType);
@@ -139,7 +140,7 @@ export function getColorAccessor({name}, scaleType, {colors}, opacity, data) {
139
140
  const scale = SCALE_FUNCS[scaleType]();
140
141
  scale.domain(calculateDomain(data, name, scaleType));
141
142
  scale.range(colors);
142
- const alpha = opacity !== undefined ? 255 * Math.pow(opacity, 1 / 2.2) : 255;
143
+ const alpha = opacity !== undefined ? Math.round(255 * Math.pow(opacity, 1 / 2.2)) : 255;
143
144
 
144
145
  const accessor = properties => {
145
146
  const rgba = rgb(scale(properties[name]));
@@ -56,7 +56,7 @@ export async function getDataV2({type, source, credentials}) {
56
56
 
57
57
  default:
58
58
  throw new Error(
59
- `Invalid maps API version. It shoud be ${API_VERSIONS.V1} or ${API_VERSIONS.V2}`
59
+ `Invalid maps API version. It should be ${API_VERSIONS.V1} or ${API_VERSIONS.V2}`
60
60
  );
61
61
  }
62
62
  }
@@ -95,15 +95,11 @@ function dealWithError({response, json, credentials}) {
95
95
  switch (response.status) {
96
96
  case 401:
97
97
  throw new Error(
98
- `Unauthorized access to Maps API: invalid combination of user ('${
99
- credentials.username
100
- }') and apiKey ('${credentials.apiKey}')`
98
+ `Unauthorized access to Maps API: invalid combination of user ('${credentials.username}') and apiKey ('${credentials.apiKey}')`
101
99
  );
102
100
  case 403:
103
101
  throw new Error(
104
- `Unauthorized access to dataset: the provided apiKey('${
105
- credentials.apiKey
106
- }') doesn't provide access to the requested data`
102
+ `Unauthorized access to dataset: the provided apiKey('${credentials.apiKey}') doesn't provide access to the requested data`
107
103
  );
108
104
 
109
105
  default:
@@ -7,6 +7,7 @@ import {parseMap} from './parseMap';
7
7
  import {log} from '@deck.gl/core';
8
8
 
9
9
  const MAX_GET_LENGTH = 2048;
10
+ const DEFAULT_CLIENT = 'deck-gl-carto';
10
11
 
11
12
  /**
12
13
  * Request against Maps API
@@ -69,8 +70,8 @@ function dealWithError({response, error}) {
69
70
  /**
70
71
  * Build a URL with all required parameters
71
72
  */
72
- function getParameters({type, source, geoColumn, columns, schema}) {
73
- const parameters = [encodeParameter('client', 'deck-gl-carto')];
73
+ function getParameters({type, source, geoColumn, columns, schema, clientId}) {
74
+ const parameters = [encodeParameter('client', clientId || DEFAULT_CLIENT)];
74
75
  if (schema) {
75
76
  parameters.push(encodeParameter('schema', true));
76
77
  }
@@ -97,10 +98,11 @@ export async function mapInstantiation({
97
98
  credentials,
98
99
  geoColumn,
99
100
  columns,
100
- schema
101
+ schema,
102
+ clientId
101
103
  }) {
102
104
  const baseUrl = `${credentials.mapsUrl}/${connection}/${type}`;
103
- const url = `${baseUrl}?${getParameters({type, source, geoColumn, columns, schema})}`;
105
+ const url = `${baseUrl}?${getParameters({type, source, geoColumn, columns, schema, clientId})}`;
104
106
  const {accessToken} = credentials;
105
107
 
106
108
  const format = 'json';
@@ -109,7 +111,7 @@ export async function mapInstantiation({
109
111
  // need to be a POST request
110
112
  const body = JSON.stringify({
111
113
  q: source,
112
- client: 'deck-gl-carto'
114
+ client: clientId || DEFAULT_CLIENT
113
115
  });
114
116
  return await request({method: 'POST', url: baseUrl, format, accessToken, body});
115
117
  }
@@ -145,7 +147,8 @@ export async function fetchLayerData({
145
147
  geoColumn,
146
148
  columns,
147
149
  format,
148
- schema
150
+ schema,
151
+ clientId
149
152
  }) {
150
153
  // Internally we split data fetching into two parts to allow us to
151
154
  // conditionally fetch the actual data, depending on the metadata state
@@ -157,7 +160,8 @@ export async function fetchLayerData({
157
160
  geoColumn,
158
161
  columns,
159
162
  format,
160
- schema
163
+ schema,
164
+ clientId
161
165
  });
162
166
 
163
167
  const data = await request({url, format: mapFormat, accessToken});
@@ -177,7 +181,8 @@ async function _fetchDataUrl({
177
181
  geoColumn,
178
182
  columns,
179
183
  format,
180
- schema
184
+ schema,
185
+ clientId
181
186
  }) {
182
187
  const defaultCredentials = getDefaultCredentials();
183
188
  // Only pick up default credentials if they have been defined for
@@ -199,7 +204,8 @@ async function _fetchDataUrl({
199
204
  credentials: localCreds,
200
205
  geoColumn,
201
206
  columns,
202
- schema
207
+ schema,
208
+ clientId
203
209
  });
204
210
  let url;
205
211
  let mapFormat;
@@ -224,7 +230,16 @@ async function _fetchDataUrl({
224
230
  return {url, accessToken, mapFormat, metadata};
225
231
  }
226
232
 
227
- export async function getData({type, source, connection, credentials, geoColumn, columns, format}) {
233
+ export async function getData({
234
+ type,
235
+ source,
236
+ connection,
237
+ credentials,
238
+ geoColumn,
239
+ columns,
240
+ format,
241
+ clientId
242
+ }) {
228
243
  log.deprecated('getData', 'fetchLayerData')();
229
244
  const layerData = await fetchLayerData({
230
245
  type,
@@ -234,20 +249,22 @@ export async function getData({type, source, connection, credentials, geoColumn,
234
249
  geoColumn,
235
250
  columns,
236
251
  format,
237
- schema: false
252
+ schema: false,
253
+ clientId
238
254
  });
239
255
  return layerData.data;
240
256
  }
241
257
 
242
- /* global setInterval, URLSearchParams */
243
- async function _fetchMapDataset(dataset, accessToken) {
258
+ /* global clearInterval, setInterval, URLSearchParams */
259
+ async function _fetchMapDataset(dataset, accessToken, credentials, clientId) {
244
260
  // First fetch metadata
245
261
  const {connectionName: connection, source, type} = dataset;
246
262
  const {url, mapFormat} = await _fetchDataUrl({
247
- credentials: {accessToken},
263
+ credentials: {...credentials, accessToken},
248
264
  connection,
249
265
  source,
250
- type
266
+ type,
267
+ clientId
251
268
  });
252
269
 
253
270
  // Extract the last time the data changed
@@ -263,15 +280,19 @@ async function _fetchMapDataset(dataset, accessToken) {
263
280
  return true;
264
281
  }
265
282
 
266
- async function fillInMapDatasets({datasets, publicToken}) {
267
- const promises = datasets.map(dataset => _fetchMapDataset(dataset, publicToken));
283
+ async function fillInMapDatasets({datasets, token}, clientId, credentials) {
284
+ const promises = datasets.map(dataset => _fetchMapDataset(dataset, token, credentials, clientId));
268
285
  return await Promise.all(promises);
269
286
  }
270
287
 
271
- export async function fetchMap({mapId, credentials, autoRefresh, onNewData}) {
272
- const localCreds = {...getDefaultCredentials(), ...credentials};
288
+ export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh, onNewData}) {
289
+ const defaultCredentials = getDefaultCredentials();
290
+ const localCreds = {
291
+ ...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
292
+ ...credentials
293
+ };
273
294
 
274
- log.assert(mapId, 'Must define map id');
295
+ log.assert(cartoMapId, `Must define CARTO map id: fetchMap({cartoMapId: 'XXXX-XXXX-XXXX'})`);
275
296
 
276
297
  log.assert(localCreds.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
277
298
  log.assert(localCreds.apiBaseUrl, 'Must define apiBaseUrl');
@@ -285,21 +306,28 @@ export async function fetchMap({mapId, credentials, autoRefresh, onNewData}) {
285
306
  log.assert(autoRefresh > 0, '`autoRefresh` must be a positive number');
286
307
  }
287
308
 
288
- const url = `${localCreds.mapsUrl}/public/${mapId}`;
309
+ const url = `${localCreds.mapsUrl}/public/${cartoMapId}`;
289
310
  const map = await request({url});
290
311
 
291
312
  // Periodically check if the data has changed. Note that this
292
313
  // will not update when a map is published.
314
+ let stopAutoRefresh;
293
315
  if (autoRefresh) {
294
- setInterval(async () => {
295
- const changed = await fillInMapDatasets(map);
316
+ const intervalId = setInterval(async () => {
317
+ const changed = await fillInMapDatasets(map, clientId, credentials);
296
318
  if (changed.some(v => v === true)) {
297
319
  onNewData(parseMap(map));
298
320
  }
299
321
  }, autoRefresh * 1000);
322
+ stopAutoRefresh = () => {
323
+ clearInterval(intervalId);
324
+ };
300
325
  }
301
326
 
302
327
  // Mutates map.datasets so that dataset.data contains data
303
- await fillInMapDatasets(map);
304
- return parseMap(map);
328
+ await fillInMapDatasets(map, clientId, credentials);
329
+ return {
330
+ ...parseMap(map),
331
+ ...{stopAutoRefresh}
332
+ };
305
333
  }
@@ -20,7 +20,7 @@ export function parseMap(json) {
20
20
  description: json.description,
21
21
  createdAt: json.createdAt,
22
22
  updatedAt: json.updatedAt,
23
- mapState,
23
+ initialViewState: mapState,
24
24
  mapStyle,
25
25
  layers: extractTextLayers(layers.reverse()).map(({id, type, config, visualChannels}) => {
26
26
  log.assert(type in LAYER_MAP, `Unsupported layer type: ${type}`);
@@ -53,17 +53,20 @@ function extractTextLayers(layers) {
53
53
  {id, config: configRest, ...rest},
54
54
 
55
55
  // One layer per valid text label, with full opacity
56
- ...textLabel.filter(t => t.field).map(t => {
57
- return {
58
- id: `id-label-${t.field.name}`,
59
- config: {
60
- textLabel: t,
61
- ...configRest,
62
- visConfig: {...configRest.visConfig, opacity: 1}
63
- },
64
- ...rest
65
- };
66
- })
56
+ ...textLabel
57
+ .filter(t => t.field)
58
+ .map(t => {
59
+ return {
60
+ id: `${id}-label-${t.field.name}`,
61
+ config: {
62
+ textLabel: t,
63
+ ...configRest,
64
+ label: `${config.label}-label-${t.field.name}`,
65
+ visConfig: {...configRest.visConfig, opacity: 1}
66
+ },
67
+ ...rest
68
+ };
69
+ })
67
70
  ];
68
71
  })
69
72
  );
@@ -98,12 +101,6 @@ function createInteractionProps(interactionConfig) {
98
101
  }
99
102
 
100
103
  function mapProps(source, target, mapping) {
101
- if (Array.isArray(source)) {
102
- source = source[0];
103
- }
104
- if (!source) {
105
- return;
106
- }
107
104
  for (const sourceKey in mapping) {
108
105
  const sourceValue = source[sourceKey];
109
106
  const targetKey = mapping[sourceKey];
@@ -129,14 +126,8 @@ function createStyleProps(config, mapping) {
129
126
 
130
127
  /* eslint-disable complexity */
131
128
  function createChannelProps(visualChannels, type, config, data) {
132
- const {
133
- colorField,
134
- colorScale,
135
- sizeField,
136
- sizeScale,
137
- strokeColorField,
138
- strokeColorScale
139
- } = visualChannels;
129
+ const {colorField, colorScale, sizeField, sizeScale, strokeColorField, strokeColorScale} =
130
+ visualChannels;
140
131
  let {heightField, heightScale} = visualChannels;
141
132
  if (type === 'hexagonId') {
142
133
  heightField = sizeField;
package/src/config.js CHANGED
@@ -1,60 +1,29 @@
1
- import {API_VERSIONS, DEFAULT_MAPS_URL_FORMAT} from './api/maps-api-common';
1
+ import {API_VERSIONS} from './api/maps-api-common';
2
2
 
3
3
  export const defaultClassicCredentials = {
4
- username: 'public',
5
4
  apiKey: 'default_public',
6
5
  region: 'us',
7
- mapsUrl: null
6
+ username: 'public'
8
7
  };
9
8
 
10
- const defaultCloudNativeCredentials = {
11
- accessToken: null,
12
- apiBaseUrl: null,
13
- mapsUrl: null
9
+ export const defaultCloudNativeCredentials = {
10
+ apiBaseUrl: 'https://gcp-us-east1.api.carto.com'
14
11
  };
15
12
 
16
13
  let credentials = {};
17
14
 
18
15
  setDefaultCredentials({});
19
16
 
20
- export function setDefaultCredentials(opts) {
21
- const apiVersion = opts.apiVersion || API_VERSIONS.V2;
17
+ export function setDefaultCredentials({apiVersion, ...rest}) {
18
+ apiVersion = apiVersion || API_VERSIONS.V3;
22
19
 
23
20
  switch (apiVersion) {
24
21
  case API_VERSIONS.V1:
25
- opts.mapsUrl = opts.mapsUrl || DEFAULT_MAPS_URL_FORMAT[apiVersion];
26
- credentials = {
27
- apiVersion,
28
- ...defaultClassicCredentials,
29
- ...opts
30
- };
31
- break;
32
-
33
22
  case API_VERSIONS.V2:
34
- opts.mapsUrl = opts.mapsUrl || DEFAULT_MAPS_URL_FORMAT[apiVersion];
35
- credentials = {
36
- apiVersion,
37
- ...defaultClassicCredentials,
38
- ...opts
39
- };
40
-
23
+ credentials = {apiVersion, ...defaultClassicCredentials, ...rest};
41
24
  break;
42
25
  case API_VERSIONS.V3:
43
- if (!opts.apiBaseUrl) {
44
- throw new Error(
45
- `API version ${
46
- API_VERSIONS.V3
47
- } requires to define apiBaseUrl at credentials. Go to https://app.carto.com to get your apiBaseUrl.`
48
- );
49
- }
50
-
51
- const apiBaseUrl = opts.apiBaseUrl || defaultCloudNativeCredentials.apiBaseUrl;
52
- opts.mapsUrl = opts.mapsUrl || buildMapsUrlFromBase(apiBaseUrl);
53
- credentials = {
54
- apiVersion,
55
- ...defaultCloudNativeCredentials,
56
- ...opts
57
- };
26
+ credentials = {apiVersion, ...defaultCloudNativeCredentials, ...rest};
58
27
  break;
59
28
  default:
60
29
  throw new Error(`Invalid API version ${apiVersion}. Use API_VERSIONS enum.`);
package/src/index.js CHANGED
@@ -1,6 +1,4 @@
1
1
  export {getDefaultCredentials, setDefaultCredentials} from './config.js';
2
- export {default as CartoSQLLayer} from './layers/carto-sql-layer';
3
- export {default as CartoBQTilerLayer} from './layers/carto-bqtiler-layer';
4
2
  export {default as CartoLayer} from './layers/carto-layer';
5
3
  export {default as BASEMAP} from './basemap';
6
4
  export {default as colorBins} from './style/color-bins-style';
@@ -0,0 +1,87 @@
1
+ /* global TextDecoder */
2
+ import {log} from '@deck.gl/core';
3
+ import {ClipExtension} from '@deck.gl/extensions';
4
+ import {MVTLayer} from '@deck.gl/geo-layers';
5
+ import {GeoJsonLayer} from '@deck.gl/layers';
6
+ import {geojsonToBinary} from '@loaders.gl/gis';
7
+ import {encodeParameter} from '../api/maps-api-common';
8
+ import {getURLFromTemplate} from '@deck.gl/geo-layers/tile-layer/utils';
9
+
10
+ function parseJSON(arrayBuffer) {
11
+ return JSON.parse(new TextDecoder().decode(arrayBuffer));
12
+ }
13
+
14
+ function parseCartoDynamicTile(arrayBuffer, options) {
15
+ if (!arrayBuffer) return null;
16
+ const formatTiles = options && options.cartoDynamicTile && options.cartoDynamicTile.formatTiles;
17
+ if (formatTiles === 'geojson') return geojsonToBinary(parseJSON(arrayBuffer).features);
18
+ return null;
19
+ }
20
+
21
+ const CartoDynamicTileLoader = {
22
+ name: 'CARTO Dynamic Tile',
23
+ id: 'cartoDynamicTile',
24
+ module: 'carto',
25
+ extensions: ['pbf'],
26
+ mimeTypes: ['application/x-protobuf'],
27
+ category: 'geometry',
28
+ worker: false,
29
+ parse: async (arrayBuffer, options) => parseCartoDynamicTile(arrayBuffer, options),
30
+ parseSync: parseCartoDynamicTile,
31
+ options: {
32
+ cartoDynamicTile: {
33
+ formatTiles: 'geojson'
34
+ }
35
+ }
36
+ };
37
+
38
+ export default class CartoDynamicTileLayer extends MVTLayer {
39
+ getTileData(tile) {
40
+ let url = getURLFromTemplate(this.state.data, tile);
41
+ if (!url) {
42
+ return Promise.reject('Invalid URL');
43
+ }
44
+
45
+ let loadOptions = this.getLoadOptions();
46
+ const {fetch, formatTiles} = this.props;
47
+ const {signal} = tile;
48
+
49
+ loadOptions = {
50
+ ...loadOptions,
51
+ mimeType: 'application/x-protobuf'
52
+ };
53
+
54
+ if (formatTiles) {
55
+ log.assert(
56
+ ['geojson'].includes(formatTiles),
57
+ `Invalid value for formatTiles: ${formatTiles}`
58
+ );
59
+ url += `&${encodeParameter('formatTiles', formatTiles)}`;
60
+ loadOptions.cartoBinaryTile = {formatTiles};
61
+ }
62
+
63
+ return fetch(url, {propName: 'data', layer: this, loadOptions, signal});
64
+ }
65
+
66
+ renderSubLayers(props) {
67
+ if (props.data === null) {
68
+ return null;
69
+ }
70
+
71
+ props.autoHighlight = false;
72
+
73
+ const {
74
+ bbox: {west, south, east, north}
75
+ } = props.tile;
76
+ props.extensions = [new ClipExtension()];
77
+ props.clipBounds = [west, south, east, north];
78
+
79
+ const subLayer = new GeoJsonLayer({
80
+ ...props
81
+ });
82
+ return subLayer;
83
+ }
84
+ }
85
+
86
+ CartoDynamicTileLayer.layerName = 'CartoDynamicTileLayer';
87
+ CartoDynamicTileLayer.defaultProps = {...MVTLayer.defaultProps, loaders: [CartoDynamicTileLoader]};
@@ -1,8 +1,9 @@
1
1
  import {CompositeLayer, log} from '@deck.gl/core';
2
+ import CartoDynamicTileLayer from './carto-dynamic-tile-layer';
2
3
  import {MVTLayer} from '@deck.gl/geo-layers';
3
4
  import {GeoJsonLayer} from '@deck.gl/layers';
4
- import {getData, getDataV2, API_VERSIONS} from '../api';
5
- import {MAP_TYPES} from '../api/maps-api-common';
5
+ import {fetchLayerData, getDataV2, API_VERSIONS} from '../api';
6
+ import {FORMATS, MAP_TYPES} from '../api/maps-api-common';
6
7
  import {getDefaultCredentials} from '../config';
7
8
 
8
9
  const defaultProps = {
@@ -12,6 +13,7 @@ const defaultProps = {
12
13
  type: null,
13
14
  onDataLoad: {type: 'function', value: data => {}, compare: false},
14
15
  onDataError: {type: 'function', value: null, compare: false, optional: true},
16
+ uniqueIdProperty: 'cartodb_id',
15
17
 
16
18
  // override carto credentials for the layer, set to null to read from default
17
19
  credentials: null,
@@ -22,6 +24,12 @@ const defaultProps = {
22
24
  // (String, required): connection name at CARTO platform
23
25
  connection: null,
24
26
 
27
+ // (String, optional): format of data
28
+ format: null,
29
+
30
+ // (String, optional): clientId identifier used for internal tracing, place here a string to identify the client who is doing the request.
31
+ clientId: null,
32
+
25
33
  // (String, optional): name of the `geo_column` in the CARTO platform. Use this override the default column ('geom'), from which the geometry information should be fetched.
26
34
  geoColumn: null,
27
35
 
@@ -93,29 +101,19 @@ export default class CartoLayer extends CompositeLayer {
93
101
 
94
102
  async _updateData() {
95
103
  try {
96
- const {type, data: source, connection, credentials, geoColumn, columns} = this.props;
104
+ const {type, data: source, clientId, credentials, ...rest} = this.props;
97
105
  const localConfig = {...getDefaultCredentials(), ...credentials};
98
106
  const {apiVersion} = localConfig;
99
107
 
100
- let data;
101
-
102
- if (apiVersion === API_VERSIONS.V3) {
103
- data = await getData({
104
- type,
105
- source,
106
- connection,
107
- credentials,
108
- geoColumn,
109
- columns
110
- });
111
- } else if (apiVersion === API_VERSIONS.V1 || apiVersion === API_VERSIONS.V2) {
112
- data = await getDataV2({type, source, credentials});
108
+ let result;
109
+ if (apiVersion === API_VERSIONS.V1 || apiVersion === API_VERSIONS.V2) {
110
+ result = {data: await getDataV2({type, source, credentials})};
113
111
  } else {
114
- log.assert(`Unknow apiVersion ${apiVersion}. Use API_VERSIONS enum.`);
112
+ result = await fetchLayerData({type, source, clientId, credentials, ...rest});
115
113
  }
116
114
 
117
- this.setState({data, apiVersion});
118
- this.props.onDataLoad(data);
115
+ this.setState({...result, apiVersion});
116
+ this.props.onDataLoad(result.data);
119
117
  } catch (err) {
120
118
  if (this.props.onDataError) {
121
119
  this.props.onDataError(err);
@@ -126,26 +124,28 @@ export default class CartoLayer extends CompositeLayer {
126
124
  }
127
125
 
128
126
  renderLayers() {
129
- const {data, apiVersion} = this.state;
130
- const {type} = this.props;
127
+ const {data, format, apiVersion} = this.state;
131
128
 
132
129
  if (!data) return null;
133
130
 
134
- const {updateTriggers} = this.props;
131
+ const {type, updateTriggers} = this.props;
135
132
 
136
133
  let layer;
137
134
 
138
- if (
135
+ if (apiVersion === API_VERSIONS.V3 && type === MAP_TYPES.TABLE && format === FORMATS.TILEJSON) {
136
+ layer = CartoDynamicTileLayer;
137
+ } else if (
139
138
  apiVersion === API_VERSIONS.V1 ||
140
139
  apiVersion === API_VERSIONS.V2 ||
141
- type === MAP_TYPES.TILESET
140
+ format === FORMATS.TILEJSON
142
141
  ) {
143
142
  layer = MVTLayer;
144
143
  } else {
145
144
  layer = GeoJsonLayer;
146
145
  }
147
146
 
148
- const props = {...this.props};
147
+ const {uniqueIdProperty} = defaultProps;
148
+ const props = {uniqueIdProperty, ...this.props};
149
149
  delete props.data;
150
150
 
151
151
  // eslint-disable-next-line new-cap
@@ -10,11 +10,9 @@ export default function colorBins({
10
10
  }) {
11
11
  assert(Array.isArray(domain), 'Expected "domain" to be an array of numbers');
12
12
 
13
- const palette = typeof colors === 'string' ? getPalette(colors, domain.length) : colors;
13
+ const palette = typeof colors === 'string' ? getPalette(colors, domain.length + 1) : colors;
14
14
 
15
- const color = scaleThreshold()
16
- .domain(domain)
17
- .range(palette);
15
+ const color = scaleThreshold().domain(domain).range(palette);
18
16
 
19
17
  return d => {
20
18
  const value = getAttrValue(attr, d);
@@ -10,10 +10,8 @@ export default function colorContinuous({
10
10
  }) {
11
11
  assert(Array.isArray(domain), 'Expected "domain" to be an array of numbers');
12
12
 
13
- const palette = typeof colors === 'string' ? getPalette(colors) : colors;
14
- const color = scaleLinear()
15
- .domain(domain)
16
- .range(palette);
13
+ const palette = typeof colors === 'string' ? getPalette(colors, domain.length) : colors;
14
+ const color = scaleLinear().domain(domain).range(palette);
17
15
 
18
16
  return d => {
19
17
  const value = getAttrValue(attr, d);