@deck.gl/carto 8.7.0 → 8.7.3

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.
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",
5
+ "version": "8.7.3",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -56,5 +56,5 @@
56
56
  "@deck.gl/layers": "^8.0.0",
57
57
  "@loaders.gl/core": "^3.1.5"
58
58
  },
59
- "gitHead": "69cc7100ab41c1f074468ea80c1ca8472d4a6146"
59
+ "gitHead": "72504c7acaeaf6862fb85acfa8ea3369d1a6875f"
60
60
  }
@@ -11,8 +11,11 @@ import {
11
11
  } from 'd3-scale';
12
12
  import {format as d3Format} from 'd3-format';
13
13
  import moment from 'moment-timezone';
14
- import {H3HexagonLayer, MVTLayer} from '@deck.gl/geo-layers';
14
+
15
+ import {CPUGridLayer, HeatmapLayer, HexagonLayer} from '@deck.gl/aggregation-layers';
15
16
  import {GeoJsonLayer} from '@deck.gl/layers';
17
+ import {H3HexagonLayer, MVTLayer} from '@deck.gl/geo-layers';
18
+
16
19
  import CartoTileLayer from '../layers/carto-tile-layer';
17
20
  import {TILE_FORMATS} from './maps-api-common';
18
21
  import {assert} from '../utils';
@@ -28,6 +31,11 @@ const SCALE_FUNCS = {
28
31
  };
29
32
  export type SCALE_TYPE = keyof typeof SCALE_FUNCS;
30
33
 
34
+ const hexToRGBA = c => {
35
+ const {r, g, b, opacity} = rgb(c);
36
+ return [r, g, b, 255 * opacity];
37
+ };
38
+
31
39
  // Kepler -> Deck.gl
32
40
  const sharedPropMap = {
33
41
  color: 'getFillColor',
@@ -41,6 +49,7 @@ const sharedPropMap = {
41
49
  },
42
50
  visConfig: {
43
51
  enable3d: 'extruded',
52
+ elevationScale: 'elevationScale',
44
53
  filled: 'filled',
45
54
  opacity: 'opacity',
46
55
  strokeColor: 'getLineColor',
@@ -51,6 +60,14 @@ const sharedPropMap = {
51
60
  }
52
61
  };
53
62
 
63
+ const aggregationVisConfig = {
64
+ colorAggregation: 'colorAggregation',
65
+ colorRange: x => ({colorRange: x.colors.map(hexToRGBA)}),
66
+ coverage: 'coverage',
67
+ elevationPercentile: ['elevationLowerPercentile', 'elevationUpperPercentile'],
68
+ percentile: ['lowerPercentile', 'upperPercentile']
69
+ };
70
+
54
71
  const RADIUS_DOWNSCALE = 0.2;
55
72
 
56
73
  const defaultProps = {
@@ -62,7 +79,7 @@ const defaultProps = {
62
79
  wrapLongitude: false
63
80
  };
64
81
 
65
- function mergePropMaps(a, b) {
82
+ function mergePropMaps(a = {}, b = {}) {
66
83
  return {...a, ...b, visConfig: {...a.visConfig, ...b.visConfig}};
67
84
  }
68
85
 
@@ -75,30 +92,44 @@ export function getLayer(
75
92
  return getTileLayer(dataset);
76
93
  }
77
94
 
95
+ const geoColumn = dataset?.geoColumn;
96
+ const getPosition = d => d[geoColumn].coordinates;
97
+
78
98
  const hexagonId = config.columns?.hex_id;
79
99
  const layer = {
80
100
  point: {
81
101
  Layer: GeoJsonLayer,
82
- propMap: mergePropMaps(sharedPropMap, {
83
- visConfig: {outline: 'stroked'}
84
- }),
85
- defaultProps
102
+ propMap: {visConfig: {outline: 'stroked'}}
86
103
  },
87
104
  geojson: {
88
105
  Layer: GeoJsonLayer,
89
- propMap: sharedPropMap,
90
- defaultProps: {...defaultProps, lineWidthScale: 2}
106
+ defaultProps: {lineWidthScale: 2}
107
+ },
108
+ grid: {
109
+ Layer: CPUGridLayer,
110
+ propMap: {visConfig: {...aggregationVisConfig, worldUnitSize: x => ({cellSize: 1000 * x})}},
111
+ defaultProps: {getPosition}
112
+ },
113
+ heatmap: {
114
+ Layer: HeatmapLayer,
115
+ propMap: {visConfig: {...aggregationVisConfig, radius: 'radiusPixels'}},
116
+ defaultProps: {getPosition}
117
+ },
118
+ hexagon: {
119
+ Layer: HexagonLayer,
120
+ propMap: {visConfig: {...aggregationVisConfig, worldUnitSize: x => ({radius: 1000 * x})}},
121
+ defaultProps: {getPosition}
91
122
  },
92
123
  hexagonId: {
93
124
  Layer: H3HexagonLayer,
94
- propMap: mergePropMaps(sharedPropMap, {
95
- visConfig: {coverage: 'coverage', elevationScale: 'elevationScale'}
96
- }),
97
- defaultProps: {...defaultProps, getHexagon: d => d[hexagonId]}
125
+ propMap: {visConfig: {coverage: 'coverage'}},
126
+ defaultProps: {getHexagon: d => d[hexagonId]}
98
127
  }
99
128
  }[type];
100
129
 
101
130
  assert(layer, `Unsupported layer type: ${type}`);
131
+ layer.propMap = mergePropMaps(sharedPropMap, layer.propMap);
132
+ layer.defaultProps = {...defaultProps, ...layer.defaultProps};
102
133
  return layer;
103
134
  }
104
135
 
@@ -189,8 +220,8 @@ export function getColorAccessor(
189
220
  const alpha = opacity !== undefined ? Math.round(255 * Math.pow(opacity, 1 / 2.2)) : 255;
190
221
 
191
222
  const accessor = properties => {
192
- const rgba = rgb(scale(properties[name]));
193
- return [rgba.r, rgba.g, rgba.b, alpha];
223
+ const {r, g, b} = rgb(scale(properties[name]));
224
+ return [r, g, b, alpha];
194
225
  };
195
226
  return normalizeAccessor(accessor, data);
196
227
  }
@@ -10,7 +10,9 @@ import {
10
10
  MapInstantiation,
11
11
  MapType,
12
12
  MAP_TYPES,
13
- SchemaField
13
+ SchemaField,
14
+ TileFormat,
15
+ TILE_FORMATS
14
16
  } from './maps-api-common';
15
17
  import {parseMap} from './parseMap';
16
18
  import {log} from '@deck.gl/core';
@@ -111,6 +113,7 @@ type FetchLayerDataParams = {
111
113
  schema?: boolean;
112
114
  clientId?: string;
113
115
  format?: Format;
116
+ formatTiles?: TileFormat;
114
117
  };
115
118
 
116
119
  /**
@@ -208,6 +211,7 @@ export async function fetchLayerData({
208
211
  geoColumn,
209
212
  columns,
210
213
  format,
214
+ formatTiles,
211
215
  schema,
212
216
  clientId
213
217
  }: FetchLayerDataParams): Promise<FetchLayerDataResult> {
@@ -221,6 +225,7 @@ export async function fetchLayerData({
221
225
  geoColumn,
222
226
  columns,
223
227
  format,
228
+ formatTiles,
224
229
  schema,
225
230
  clientId
226
231
  });
@@ -242,6 +247,7 @@ async function _fetchDataUrl({
242
247
  geoColumn,
243
248
  columns,
244
249
  format,
250
+ formatTiles,
245
251
  schema,
246
252
  clientId
247
253
  }: FetchLayerDataParams) {
@@ -288,6 +294,14 @@ async function _fetchDataUrl({
288
294
  assert(url && mapFormat, 'Unsupported data formats received from backend.');
289
295
  }
290
296
 
297
+ if (format === FORMATS.TILEJSON && formatTiles) {
298
+ log.assert(
299
+ Object.values(TILE_FORMATS).includes(formatTiles),
300
+ `Invalid value for formatTiles: ${formatTiles}. Use value from TILE_FORMATS`
301
+ );
302
+ url += `&${encodeParameter('formatTiles', formatTiles)}`;
303
+ }
304
+
291
305
  const {accessToken} = localCreds;
292
306
  return {url, accessToken, mapFormat, metadata};
293
307
  }
@@ -324,16 +338,17 @@ async function _fetchMapDataset(
324
338
  credentials: CloudNativeCredentials,
325
339
  clientId?: string
326
340
  ) {
327
- const {connectionName: connection, columns, geoColumn, source, type} = dataset;
341
+ const {connectionName: connection, columns, format, geoColumn, source, type} = dataset;
328
342
  // First fetch metadata
329
343
  const {url, mapFormat} = await _fetchDataUrl({
344
+ clientId,
330
345
  credentials: {...credentials, accessToken},
331
346
  connection,
332
347
  columns,
348
+ format,
333
349
  geoColumn,
334
350
  source,
335
- type,
336
- clientId
351
+ type
337
352
  });
338
353
 
339
354
  // Extract the last time the data changed
@@ -114,8 +114,11 @@ function mapProps(source, target, mapping) {
114
114
  }
115
115
  if (typeof targetKey === 'string') {
116
116
  target[targetKey] = sourceValue;
117
+ } else if (typeof targetKey === 'function') {
118
+ const [key, value] = Object.entries(targetKey(sourceValue))[0];
119
+ target[key] = value;
117
120
  } else if (typeof targetKey === 'object') {
118
- // Nested definition, recurse down one level
121
+ // Nested definition, recurse down one level (also handles arrays)
119
122
  mapProps(sourceValue, target, targetKey);
120
123
  }
121
124
  }
@@ -148,6 +151,8 @@ function createChannelProps(visualChannels, type, config, data) {
148
151
  1, // Rely on layer opacity
149
152
  data
150
153
  );
154
+ } else if (type === 'grid' || type === 'hexagon') {
155
+ result.colorScaleType = colorScale;
151
156
  }
152
157
  if (strokeColorField) {
153
158
  const opacity = visConfig.strokeOpacity !== undefined ? visConfig.strokeOpacity : 1;
@@ -92,8 +92,10 @@ export default class CartoLayer extends CompositeLayer {
92
92
  changeFlags.dataChanged ||
93
93
  props.connection !== oldProps.connection ||
94
94
  props.geoColumn !== oldProps.geoColumn ||
95
- JSON.stringify(props.columns) !== JSON.stringify(oldProps.columns) ||
95
+ props.format !== oldProps.format ||
96
+ props.formatTiles !== oldProps.formatTiles ||
96
97
  props.type !== oldProps.type ||
98
+ JSON.stringify(props.columns) !== JSON.stringify(oldProps.columns) ||
97
99
  JSON.stringify(props.credentials) !== JSON.stringify(oldProps.credentials);
98
100
 
99
101
  if (shouldUpdateData) {
@@ -139,10 +141,10 @@ export default class CartoLayer extends CompositeLayer {
139
141
 
140
142
  if (format === FORMATS.TILEJSON) {
141
143
  /* global URL */
144
+ const tileUrl = new URL(data.tiles[0]);
145
+
142
146
  props.formatTiles =
143
- props.formatTiles ||
144
- new URL(data.tiles[0]).searchParams.get('formatTiles') ||
145
- TILE_FORMATS.MVT;
147
+ props.formatTiles || tileUrl.searchParams.get('formatTiles') || TILE_FORMATS.MVT;
146
148
 
147
149
  return props.formatTiles === TILE_FORMATS.MVT ? [MVTLayer, props] : [CartoTileLayer, props];
148
150
  }
@@ -48,6 +48,8 @@ function parseCartoTile(arrayBuffer, options) {
48
48
  return data;
49
49
  }
50
50
 
51
+ const defaultTileFormat = TILE_FORMATS.BINARY;
52
+
51
53
  const CartoTileLoader = {
52
54
  name: 'CARTO Tile',
53
55
  id: 'cartoTile',
@@ -60,15 +62,20 @@ const CartoTileLoader = {
60
62
  parseSync: parseCartoTile,
61
63
  options: {
62
64
  cartoTile: {
63
- // TODO change to BINARY for 8.7 prod release
64
- formatTiles: TILE_FORMATS.BINARY
65
+ formatTiles: defaultTileFormat
65
66
  }
66
67
  }
67
68
  };
68
69
 
70
+ const defaultProps = {
71
+ ...MVTLayer.defaultProps,
72
+ formatTiles: defaultTileFormat,
73
+ loaders: [CartoTileLoader]
74
+ };
75
+
69
76
  export default class CartoTileLayer extends MVTLayer {
70
77
  getTileData(tile) {
71
- let url = _getURLFromTemplate(this.state.data, tile);
78
+ const url = _getURLFromTemplate(this.state.data, tile);
72
79
  if (!url) {
73
80
  return Promise.reject('Invalid URL');
74
81
  }
@@ -87,10 +94,6 @@ export default class CartoTileLayer extends MVTLayer {
87
94
  Object.values(TILE_FORMATS).includes(formatTiles),
88
95
  `Invalid value for formatTiles: ${formatTiles}. Use value from TILE_FORMATS`
89
96
  );
90
- // eslint-disable-next-line no-undef
91
- const newUrl = new URL(url);
92
- newUrl.searchParams.set('formatTiles', formatTiles);
93
- url = newUrl.toString();
94
97
  loadOptions.cartoTile = {formatTiles};
95
98
  }
96
99
 
@@ -118,4 +121,4 @@ export default class CartoTileLayer extends MVTLayer {
118
121
  }
119
122
 
120
123
  CartoTileLayer.layerName = 'CartoTileLayer';
121
- CartoTileLayer.defaultProps = {...MVTLayer.defaultProps, loaders: [CartoTileLoader]};
124
+ CartoTileLayer.defaultProps = defaultProps;