@deck.gl/carto 8.7.4 → 8.7.5

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.4",
5
+ "version": "8.7.5",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
@@ -51,10 +51,11 @@
51
51
  "@types/d3-scale": "^3.0.0"
52
52
  },
53
53
  "peerDependencies": {
54
+ "@deck.gl/aggregation-layers": "^8.0.0",
54
55
  "@deck.gl/core": "^8.0.0",
55
56
  "@deck.gl/geo-layers": "^8.0.0",
56
57
  "@deck.gl/layers": "^8.0.0",
57
58
  "@loaders.gl/core": "^3.1.5"
58
59
  },
59
- "gitHead": "eb545b0af1760f83d8225ef8282aca66754fd0b7"
60
+ "gitHead": "e32b546539b859933be006069f3301a8e4323b1e"
60
61
  }
@@ -1,4 +1,4 @@
1
- import {extent} from 'd3-array';
1
+ import {deviation, extent, groupSort, median, variance} from 'd3-array';
2
2
  import {rgb} from 'd3-color';
3
3
  import {
4
4
  scaleLinear,
@@ -31,6 +31,22 @@ const SCALE_FUNCS = {
31
31
  };
32
32
  export type SCALE_TYPE = keyof typeof SCALE_FUNCS;
33
33
 
34
+ export const AGGREGATION = {
35
+ average: 'MEAN',
36
+ maximum: 'MAX',
37
+ minimum: 'MIN',
38
+ sum: 'SUM'
39
+ };
40
+
41
+ const AGGREGATION_FUNC = {
42
+ 'count unique': (values, accessor) => groupSort(values, v => v.length, accessor).length,
43
+ median,
44
+ // Unfortunately mode() is only available in d3-array@3+ which is ESM only
45
+ mode: (values, accessor) => groupSort(values, v => v.length, accessor).pop(),
46
+ stddev: deviation,
47
+ variance
48
+ };
49
+
34
50
  const hexToRGBA = c => {
35
51
  const {r, g, b, opacity} = rgb(c);
36
52
  return [r, g, b, 255 * opacity];
@@ -61,19 +77,16 @@ const sharedPropMap = {
61
77
  };
62
78
 
63
79
  const aggregationVisConfig = {
64
- colorAggregation: 'colorAggregation',
80
+ colorAggregation: x => ({colorAggregation: AGGREGATION[x] || AGGREGATION.sum}),
65
81
  colorRange: x => ({colorRange: x.colors.map(hexToRGBA)}),
66
82
  coverage: 'coverage',
67
83
  elevationPercentile: ['elevationLowerPercentile', 'elevationUpperPercentile'],
68
84
  percentile: ['lowerPercentile', 'upperPercentile']
69
85
  };
70
86
 
71
- const RADIUS_DOWNSCALE = 0.2;
72
-
73
87
  const defaultProps = {
74
88
  lineMiterLimit: 2,
75
89
  lineWidthUnits: 'pixels',
76
- pointRadiusScale: RADIUS_DOWNSCALE,
77
90
  pointRadiusUnits: 'pixels',
78
91
  rounded: true,
79
92
  wrapLongitude: false
@@ -102,8 +115,7 @@ export function getLayer(
102
115
  propMap: {visConfig: {outline: 'stroked'}}
103
116
  },
104
117
  geojson: {
105
- Layer: GeoJsonLayer,
106
- defaultProps: {lineWidthScale: 2}
118
+ Layer: GeoJsonLayer
107
119
  },
108
120
  grid: {
109
121
  Layer: CPUGridLayer,
@@ -123,7 +135,7 @@ export function getLayer(
123
135
  hexagonId: {
124
136
  Layer: H3HexagonLayer,
125
137
  propMap: {visConfig: {coverage: 'coverage'}},
126
- defaultProps: {getHexagon: d => d[hexagonId]}
138
+ defaultProps: {getHexagon: d => d[hexagonId], stroked: false}
127
139
  }
128
140
  }[type];
129
141
 
@@ -147,8 +159,6 @@ function getTileLayer(dataset) {
147
159
  propMap: sharedPropMap,
148
160
  defaultProps: {
149
161
  ...defaultProps,
150
- pointRadiusScale: 0.3,
151
- lineWidthScale: 2,
152
162
  uniqueIdProperty: 'geoid',
153
163
  formatTiles
154
164
  }
@@ -207,6 +217,12 @@ function normalizeAccessor(accessor, data) {
207
217
  return accessor;
208
218
  }
209
219
 
220
+ export function getColorValueAccessor({name}, colorAggregation, data: any) {
221
+ const aggregator = AGGREGATION_FUNC[colorAggregation];
222
+ const accessor = values => aggregator(values, p => p[name]);
223
+ return normalizeAccessor(accessor, data);
224
+ }
225
+
210
226
  export function getColorAccessor(
211
227
  {name},
212
228
  scaleType: SCALE_TYPE,
@@ -259,10 +275,7 @@ export function getTextPixelOffsetAccessor({alignment, anchor, size}, radius) {
259
275
  const signY = alignment === 'center' ? 0 : alignment === 'bottom' ? 1 : -1;
260
276
  const sizeOffset = alignment === 'center' ? 0 : size;
261
277
 
262
- const calculateOffset = r => {
263
- r = RADIUS_DOWNSCALE * r;
264
- return [signX * (r + padding), signY * (r + padding + sizeOffset)];
265
- };
278
+ const calculateOffset = r => [signX * (r + padding), signY * (r + padding + sizeOffset)];
266
279
 
267
280
  return typeof radius === 'function'
268
281
  ? d => {
@@ -20,6 +20,8 @@ export const MAP_TYPES = {
20
20
  TILESET: 'tileset'
21
21
  } as const;
22
22
  export type MapType = ValuesOf<typeof MAP_TYPES>;
23
+ export const COLUMNS_SUPPORT = [MAP_TYPES.TABLE];
24
+ export const GEO_COLUMN_SUPPORT = [MAP_TYPES.QUERY, MAP_TYPES.TABLE];
23
25
 
24
26
  // AVAILABLE FORMATS
25
27
  export const FORMATS = {
@@ -4,9 +4,11 @@
4
4
  import {getDefaultCredentials, buildMapsUrlFromBase, CloudNativeCredentials} from '../config';
5
5
  import {
6
6
  API_VERSIONS,
7
+ COLUMNS_SUPPORT,
7
8
  encodeParameter,
8
9
  Format,
9
10
  FORMATS,
11
+ GEO_COLUMN_SUPPORT,
10
12
  MapInstantiation,
11
13
  MapType,
12
14
  MAP_TYPES,
@@ -135,13 +137,11 @@ function getParameters({
135
137
  const sourceName = type === MAP_TYPES.QUERY ? 'q' : 'name';
136
138
  parameters.push(encodeParameter(sourceName, source));
137
139
 
138
- if (type === MAP_TYPES.TABLE) {
139
- if (geoColumn) {
140
- parameters.push(encodeParameter('geo_column', geoColumn));
141
- }
142
- if (columns) {
143
- parameters.push(encodeParameter('columns', columns.join(',')));
144
- }
140
+ if (GEO_COLUMN_SUPPORT.includes(type) && geoColumn) {
141
+ parameters.push(encodeParameter('geo_column', geoColumn));
142
+ }
143
+ if (COLUMNS_SUPPORT.includes(type) && columns) {
144
+ parameters.push(encodeParameter('columns', columns.join(',')));
145
145
  }
146
146
 
147
147
  return parameters.join('&');
@@ -429,6 +429,16 @@ export async function fetchMap({
429
429
  };
430
430
  }
431
431
 
432
+ const geojsonLayers = map.keplerMapConfig.config.visState.layers.filter(
433
+ ({type}) => type === 'geojson' || type === 'point'
434
+ );
435
+ const geojsonDatasetIds = geojsonLayers.map(({config}) => config.dataId);
436
+ map.datasets.forEach(dataset => {
437
+ if (geojsonDatasetIds.includes(dataset.id)) {
438
+ dataset.format = 'geojson';
439
+ }
440
+ });
441
+
432
442
  // Mutates map.datasets so that dataset.data contains data
433
443
  await fillInMapDatasets(map, clientId, localCreds);
434
444
  return {
@@ -1,7 +1,9 @@
1
1
  import GL from '@luma.gl/constants';
2
2
  import {
3
+ AGGREGATION,
3
4
  getLayer,
4
5
  getColorAccessor,
6
+ getColorValueAccessor,
5
7
  getSizeAccessor,
6
8
  getTextAccessor,
7
9
  getTextPixelOffsetAccessor
@@ -127,11 +129,17 @@ function mapProps(source, target, mapping) {
127
129
  function createStyleProps(config, mapping) {
128
130
  const result: Record<string, any> = {};
129
131
  mapProps(config, result, mapping);
132
+
133
+ // Kepler format sometimes omits strokeColor. TODO: remove once we can rely on
134
+ // `strokeColor` always being sert when `stroke: true`.
135
+ if (result.stroked && !result.getLineColor) {
136
+ result.getLineColor = result.getFillColor;
137
+ }
130
138
  result.highlightColor = config.visConfig.enable3d ? [255, 255, 255, 60] : [252, 242, 26, 255];
131
139
  return result;
132
140
  }
133
141
 
134
- /* eslint-disable complexity */
142
+ /* eslint-disable complexity, max-statements */
135
143
  function createChannelProps(visualChannels, type, config, data) {
136
144
  const {colorField, colorScale, sizeField, sizeScale, strokeColorField, strokeColorScale} =
137
145
  visualChannels;
@@ -143,7 +151,18 @@ function createChannelProps(visualChannels, type, config, data) {
143
151
  const {textLabel, visConfig} = config;
144
152
  const result: Record<string, any> = {};
145
153
  const textLabelField = textLabel && textLabel.field;
146
- if (colorField) {
154
+
155
+ if (type === 'grid' || type === 'hexagon') {
156
+ result.colorScaleType = colorScale;
157
+ if (colorField) {
158
+ const {colorAggregation} = config.visConfig;
159
+ if (!AGGREGATION[colorAggregation]) {
160
+ result.getColorValue = getColorValueAccessor(colorField, colorAggregation, data);
161
+ } else {
162
+ result.getColorWeight = d => [colorField.name];
163
+ }
164
+ }
165
+ } else if (colorField) {
147
166
  result.getFillColor = getColorAccessor(
148
167
  colorField,
149
168
  colorScale,
@@ -151,9 +170,8 @@ function createChannelProps(visualChannels, type, config, data) {
151
170
  1, // Rely on layer opacity
152
171
  data
153
172
  );
154
- } else if (type === 'grid' || type === 'hexagon') {
155
- result.colorScaleType = colorScale;
156
173
  }
174
+
157
175
  if (strokeColorField) {
158
176
  const opacity = visConfig.strokeOpacity !== undefined ? visConfig.strokeOpacity : 1;
159
177
  result.getLineColor = getColorAccessor(
@@ -3,7 +3,13 @@ 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';
6
- import {FORMATS, MAP_TYPES, TILE_FORMATS} from '../api/maps-api-common';
6
+ import {
7
+ COLUMNS_SUPPORT,
8
+ FORMATS,
9
+ GEO_COLUMN_SUPPORT,
10
+ MAP_TYPES,
11
+ TILE_FORMATS
12
+ } from '../api/maps-api-common';
7
13
  import {getDefaultCredentials} from '../config';
8
14
 
9
15
  const defaultProps = {
@@ -76,9 +82,14 @@ export default class CartoLayer extends CompositeLayer {
76
82
  Object.values(MAP_TYPES).includes(type),
77
83
  `Invalid type ${type}. Use MAP_TYPES enum.`
78
84
  );
79
- if (type !== MAP_TYPES.TABLE) {
80
- log.assert(!geoColumn, `geoColumn prop is only supported for type ${MAP_TYPES.TABLE}`);
81
- log.assert(!columns, `columns prop is only supported for type ${MAP_TYPES.TABLE}`);
85
+ if (!COLUMNS_SUPPORT.includes(type)) {
86
+ log.assert(!columns, `columns prop is only supported for types: ${COLUMNS_SUPPORT.join()}`);
87
+ }
88
+ if (!GEO_COLUMN_SUPPORT.includes(type)) {
89
+ log.assert(
90
+ !geoColumn,
91
+ `geoColumn prop is only supported for types: ${GEO_COLUMN_SUPPORT.join()}`
92
+ );
82
93
  }
83
94
  if (columns) {
84
95
  log.assert(Array.isArray(columns), 'columns prop must be an Array');