@deck.gl/carto 8.8.0-beta.3 → 8.8.0-beta.4
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/dist/dist.dev.js +1049 -1079
- package/dist/es5/api/index.js +0 -6
- package/dist/es5/api/index.js.map +1 -1
- package/dist/es5/api/maps-v3-client.js +44 -86
- package/dist/es5/api/maps-v3-client.js.map +1 -1
- package/dist/es5/index.js +0 -6
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/layers/carto-layer.js +13 -18
- package/dist/es5/layers/carto-layer.js.map +1 -1
- package/dist/es5/layers/h3-tile-layer.js +2 -0
- package/dist/es5/layers/h3-tile-layer.js.map +1 -1
- package/dist/esm/api/index.js +1 -1
- package/dist/esm/api/index.js.map +1 -1
- package/dist/esm/api/maps-v3-client.js +0 -24
- package/dist/esm/api/maps-v3-client.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/layers/carto-layer.js +11 -16
- package/dist/esm/layers/carto-layer.js.map +1 -1
- package/dist/esm/layers/h3-tile-layer.js +2 -0
- package/dist/esm/layers/h3-tile-layer.js.map +1 -1
- package/dist.min.js +3 -3
- package/package.json +2 -2
- package/src/api/index.ts +1 -1
- package/src/api/maps-v3-client.ts +0 -24
- package/src/index.ts +0 -1
- package/src/layers/carto-layer.ts +17 -32
- package/src/layers/h3-tile-layer.ts +1 -0
- package/typed/api/index.d.ts +1 -1
- package/typed/api/index.d.ts.map +1 -1
- package/typed/api/index.js +3 -0
- package/typed/api/layer-map.js +264 -0
- package/typed/api/maps-api-common.js +50 -0
- package/typed/api/maps-client.js +125 -0
- package/typed/api/maps-v3-client.d.ts +0 -1
- package/typed/api/maps-v3-client.d.ts.map +1 -1
- package/typed/api/maps-v3-client.js +304 -0
- package/typed/api/parseMap.js +178 -0
- package/typed/basemap.js +9 -0
- package/typed/config.js +35 -0
- package/typed/index.d.ts +1 -1
- package/typed/index.d.ts.map +1 -1
- package/typed/index.js +10 -0
- package/typed/layers/carto-layer.d.ts +2 -10
- package/typed/layers/carto-layer.d.ts.map +1 -1
- package/typed/layers/carto-layer.js +173 -0
- package/typed/layers/carto-tile-layer.js +105 -0
- package/typed/layers/h3-tile-layer.d.ts.map +1 -1
- package/typed/layers/h3-tile-layer.js +47 -0
- package/typed/layers/h3-tileset-2d.js +85 -0
- package/typed/layers/quadkey-tile-layer.js +42 -0
- package/typed/layers/quadkey-tileset-2d.js +36 -0
- package/typed/layers/schema/carto-tile.js +161 -0
- package/typed/layers/spatial-index-tile-layer.js +40 -0
- package/typed/style/color-bins-style.js +12 -0
- package/typed/style/color-categories-style.js +16 -0
- package/typed/style/color-continuous-style.js +12 -0
- package/typed/style/palette.js +62 -0
- package/typed/style/utils.js +15 -0
- package/typed/utils.js +4 -0
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.8.0-beta.
|
|
5
|
+
"version": "8.8.0-beta.4",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -61,5 +61,5 @@
|
|
|
61
61
|
"@deck.gl/layers": "^8.0.0",
|
|
62
62
|
"@loaders.gl/core": "^3.0.0"
|
|
63
63
|
},
|
|
64
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "36bc4928487797eb4f7518fd612963b0f3e744bc"
|
|
65
65
|
}
|
package/src/api/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export {FORMATS, TILE_FORMATS, MAP_TYPES, API_VERSIONS} from './maps-api-common';
|
|
2
2
|
export {getDataV2, CONNECTIONS} from './maps-client';
|
|
3
|
-
export {fetchLayerData, fetchMap,
|
|
3
|
+
export {fetchLayerData, fetchMap, mapInstantiation} from './maps-v3-client';
|
|
@@ -356,30 +356,6 @@ async function _fetchDataUrl({
|
|
|
356
356
|
return {url, accessToken, mapFormat, metadata};
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
export async function getData({
|
|
360
|
-
type,
|
|
361
|
-
source,
|
|
362
|
-
connection,
|
|
363
|
-
credentials,
|
|
364
|
-
geoColumn,
|
|
365
|
-
columns,
|
|
366
|
-
format,
|
|
367
|
-
clientId
|
|
368
|
-
}: FetchLayerDataParams) {
|
|
369
|
-
log.deprecated('getData', 'fetchLayerData')();
|
|
370
|
-
const layerData = await fetchLayerData({
|
|
371
|
-
type,
|
|
372
|
-
source,
|
|
373
|
-
connection,
|
|
374
|
-
credentials,
|
|
375
|
-
geoColumn,
|
|
376
|
-
columns,
|
|
377
|
-
format,
|
|
378
|
-
clientId
|
|
379
|
-
});
|
|
380
|
-
return layerData.data;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
359
|
/* global clearInterval, setInterval, URL */
|
|
384
360
|
async function _fetchMapDataset(
|
|
385
361
|
dataset,
|
package/src/index.ts
CHANGED
|
@@ -10,11 +10,9 @@ import CartoTileLayer from './carto-tile-layer';
|
|
|
10
10
|
import H3TileLayer from './h3-tile-layer';
|
|
11
11
|
import QuadkeyTileLayer from './quadkey-tile-layer';
|
|
12
12
|
import {MVTLayer} from '@deck.gl/geo-layers';
|
|
13
|
-
import {GeoJsonLayer} from '@deck.gl/layers';
|
|
14
13
|
import {fetchLayerData, getDataV2, API_VERSIONS} from '../api';
|
|
15
14
|
import {
|
|
16
15
|
COLUMNS_SUPPORT,
|
|
17
|
-
Format,
|
|
18
16
|
FORMATS,
|
|
19
17
|
GEO_COLUMN_SUPPORT,
|
|
20
18
|
MapType,
|
|
@@ -98,19 +96,10 @@ type _CartoLayerProps = {
|
|
|
98
96
|
*/
|
|
99
97
|
connection?: string;
|
|
100
98
|
|
|
101
|
-
/**
|
|
102
|
-
* Use to override the default data format.
|
|
103
|
-
*
|
|
104
|
-
* Only supported when apiVersion is `API_VERSIONS.V3`.
|
|
105
|
-
*
|
|
106
|
-
* Possible values are: `FORMATS.GEOJSON`, `FORMATS.JSON` and `FORMATS.TILEJSON`.
|
|
107
|
-
*/
|
|
108
|
-
format?: Format;
|
|
109
|
-
|
|
110
99
|
/**
|
|
111
100
|
* Use to override the default tile data format.
|
|
112
101
|
*
|
|
113
|
-
* Only supported when apiVersion is `API_VERSIONS.V3
|
|
102
|
+
* Only supported when apiVersion is `API_VERSIONS.V3`.
|
|
114
103
|
*
|
|
115
104
|
* Possible values are: `TILE_FORMATS.BINARY`, `TILE_FORMATS.GEOJSON` and `TILE_FORMATS.MVT`.
|
|
116
105
|
*/
|
|
@@ -237,7 +226,6 @@ export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
|
237
226
|
props.aggregationResLevel !== oldProps.aggregationResLevel ||
|
|
238
227
|
props.connection !== oldProps.connection ||
|
|
239
228
|
props.geoColumn !== oldProps.geoColumn ||
|
|
240
|
-
props.format !== oldProps.format ||
|
|
241
229
|
props.formatTiles !== oldProps.formatTiles ||
|
|
242
230
|
props.type !== oldProps.type ||
|
|
243
231
|
JSON.stringify(props.columns) !== JSON.stringify(oldProps.columns) ||
|
|
@@ -268,7 +256,9 @@ export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
|
268
256
|
clientId,
|
|
269
257
|
credentials: credentials as CloudNativeCredentials,
|
|
270
258
|
connection,
|
|
271
|
-
...rest
|
|
259
|
+
...rest,
|
|
260
|
+
// CartoLayer only supports tiled output from v8.8, force data format
|
|
261
|
+
format: FORMATS.TILEJSON
|
|
272
262
|
});
|
|
273
263
|
}
|
|
274
264
|
|
|
@@ -290,7 +280,7 @@ export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
|
290
280
|
_getSubLayerAndProps(): [any, LayerProps] {
|
|
291
281
|
assert(this.state);
|
|
292
282
|
|
|
293
|
-
const {data,
|
|
283
|
+
const {data, apiVersion} = this.state;
|
|
294
284
|
|
|
295
285
|
const {uniqueIdProperty} = defaultProps;
|
|
296
286
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -302,26 +292,21 @@ export default class CartoLayer<ExtraProps = {}> extends CompositeLayer<
|
|
|
302
292
|
return [MVTLayer, props];
|
|
303
293
|
}
|
|
304
294
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const tileUrl = new URL(data.tiles[0]);
|
|
295
|
+
/* global URL */
|
|
296
|
+
const tileUrl = new URL(data.tiles[0]);
|
|
308
297
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
298
|
+
props.formatTiles =
|
|
299
|
+
props.formatTiles ||
|
|
300
|
+
(tileUrl.searchParams.get('formatTiles') as TileFormat) ||
|
|
301
|
+
TILE_FORMATS.MVT;
|
|
313
302
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
if (data.scheme === 'quadkey') {
|
|
318
|
-
return [QuadkeyTileLayer, props];
|
|
319
|
-
}
|
|
320
|
-
return props.formatTiles === TILE_FORMATS.MVT ? [MVTLayer, props] : [CartoTileLayer, props];
|
|
303
|
+
if (data.scheme === 'h3') {
|
|
304
|
+
return [H3TileLayer, props];
|
|
321
305
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
306
|
+
if (data.scheme === 'quadkey') {
|
|
307
|
+
return [QuadkeyTileLayer, props];
|
|
308
|
+
}
|
|
309
|
+
return props.formatTiles === TILE_FORMATS.MVT ? [MVTLayer, props] : [CartoTileLayer, props];
|
|
325
310
|
}
|
|
326
311
|
|
|
327
312
|
renderLayers(): Layer | null {
|
package/typed/api/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { FORMATS, TILE_FORMATS, MAP_TYPES, API_VERSIONS } from './maps-api-common';
|
|
2
2
|
export { getDataV2, CONNECTIONS } from './maps-client';
|
|
3
|
-
export { fetchLayerData, fetchMap,
|
|
3
|
+
export { fetchLayerData, fetchMap, mapInstantiation } from './maps-v3-client';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/typed/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,EAAC,cAAc,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAC,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAC,SAAS,EAAE,WAAW,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,EAAC,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAC,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { deviation, extent, groupSort, median, variance } from 'd3-array';
|
|
2
|
+
import { rgb } from 'd3-color';
|
|
3
|
+
import { scaleLinear, scaleOrdinal, scaleLog, scalePoint, scaleQuantile, scaleQuantize, scaleSqrt, scaleThreshold } from 'd3-scale';
|
|
4
|
+
import { format as d3Format } from 'd3-format';
|
|
5
|
+
import moment from 'moment-timezone';
|
|
6
|
+
import { CPUGridLayer, HeatmapLayer, HexagonLayer } from '@deck.gl/aggregation-layers';
|
|
7
|
+
import { GeoJsonLayer } from '@deck.gl/layers';
|
|
8
|
+
import { H3HexagonLayer, MVTLayer } from '@deck.gl/geo-layers';
|
|
9
|
+
import CartoTileLayer from '../layers/carto-tile-layer';
|
|
10
|
+
import { TILE_FORMATS } from './maps-api-common';
|
|
11
|
+
import { assert } from '../utils';
|
|
12
|
+
const SCALE_FUNCS = {
|
|
13
|
+
linear: scaleLinear,
|
|
14
|
+
ordinal: scaleOrdinal,
|
|
15
|
+
log: scaleLog,
|
|
16
|
+
point: scalePoint,
|
|
17
|
+
quantile: scaleQuantile,
|
|
18
|
+
quantize: scaleQuantize,
|
|
19
|
+
sqrt: scaleSqrt,
|
|
20
|
+
custom: scaleThreshold
|
|
21
|
+
};
|
|
22
|
+
const UNKNOWN_COLOR = '#868d91';
|
|
23
|
+
export const AGGREGATION = {
|
|
24
|
+
average: 'MEAN',
|
|
25
|
+
maximum: 'MAX',
|
|
26
|
+
minimum: 'MIN',
|
|
27
|
+
sum: 'SUM'
|
|
28
|
+
};
|
|
29
|
+
export const OPACITY_MAP = {
|
|
30
|
+
getFillColor: 'opacity',
|
|
31
|
+
getLineColor: 'strokeOpacity',
|
|
32
|
+
getTextColor: 'opacity'
|
|
33
|
+
};
|
|
34
|
+
const AGGREGATION_FUNC = {
|
|
35
|
+
'count unique': (values, accessor) => groupSort(values, v => v.length, accessor).length,
|
|
36
|
+
median,
|
|
37
|
+
// Unfortunately mode() is only available in d3-array@3+ which is ESM only
|
|
38
|
+
mode: (values, accessor) => groupSort(values, v => v.length, accessor).pop(),
|
|
39
|
+
stddev: deviation,
|
|
40
|
+
variance
|
|
41
|
+
};
|
|
42
|
+
const hexToRGBA = c => {
|
|
43
|
+
const { r, g, b, opacity } = rgb(c);
|
|
44
|
+
return [r, g, b, 255 * opacity];
|
|
45
|
+
};
|
|
46
|
+
// Kepler -> Deck.gl
|
|
47
|
+
const sharedPropMap = {
|
|
48
|
+
color: 'getFillColor',
|
|
49
|
+
isVisible: 'visible',
|
|
50
|
+
label: 'cartoLabel',
|
|
51
|
+
textLabel: {
|
|
52
|
+
alignment: 'getTextAlignmentBaseline',
|
|
53
|
+
anchor: 'getTextAnchor',
|
|
54
|
+
color: 'getTextColor',
|
|
55
|
+
size: 'getTextSize'
|
|
56
|
+
},
|
|
57
|
+
visConfig: {
|
|
58
|
+
enable3d: 'extruded',
|
|
59
|
+
elevationScale: 'elevationScale',
|
|
60
|
+
filled: 'filled',
|
|
61
|
+
strokeColor: 'getLineColor',
|
|
62
|
+
stroked: 'stroked',
|
|
63
|
+
thickness: 'getLineWidth',
|
|
64
|
+
radius: 'getPointRadius',
|
|
65
|
+
wireframe: 'wireframe'
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const aggregationVisConfig = {
|
|
69
|
+
colorAggregation: x => ({ colorAggregation: AGGREGATION[x] || AGGREGATION.sum }),
|
|
70
|
+
colorRange: x => ({ colorRange: x.colors.map(hexToRGBA) }),
|
|
71
|
+
coverage: 'coverage',
|
|
72
|
+
elevationPercentile: ['elevationLowerPercentile', 'elevationUpperPercentile'],
|
|
73
|
+
percentile: ['lowerPercentile', 'upperPercentile']
|
|
74
|
+
};
|
|
75
|
+
const defaultProps = {
|
|
76
|
+
lineMiterLimit: 2,
|
|
77
|
+
lineWidthUnits: 'pixels',
|
|
78
|
+
pointRadiusUnits: 'pixels',
|
|
79
|
+
rounded: true,
|
|
80
|
+
wrapLongitude: false
|
|
81
|
+
};
|
|
82
|
+
function mergePropMaps(a = {}, b = {}) {
|
|
83
|
+
return { ...a, ...b, visConfig: { ...a.visConfig, ...b.visConfig } };
|
|
84
|
+
}
|
|
85
|
+
export function getLayer(type, config, dataset) {
|
|
86
|
+
if (type === 'mvt' || type === 'tileset') {
|
|
87
|
+
return getTileLayer(dataset);
|
|
88
|
+
}
|
|
89
|
+
const geoColumn = dataset?.geoColumn;
|
|
90
|
+
const getPosition = d => d[geoColumn].coordinates;
|
|
91
|
+
const hexagonId = config.columns?.hex_id;
|
|
92
|
+
const layerTypeDefs = {
|
|
93
|
+
point: {
|
|
94
|
+
Layer: GeoJsonLayer,
|
|
95
|
+
propMap: { visConfig: { outline: 'stroked' } }
|
|
96
|
+
},
|
|
97
|
+
geojson: {
|
|
98
|
+
Layer: GeoJsonLayer
|
|
99
|
+
},
|
|
100
|
+
grid: {
|
|
101
|
+
Layer: CPUGridLayer,
|
|
102
|
+
propMap: { visConfig: { ...aggregationVisConfig, worldUnitSize: x => ({ cellSize: 1000 * x }) } },
|
|
103
|
+
defaultProps: { getPosition }
|
|
104
|
+
},
|
|
105
|
+
heatmap: {
|
|
106
|
+
Layer: HeatmapLayer,
|
|
107
|
+
propMap: { visConfig: { ...aggregationVisConfig, radius: 'radiusPixels' } },
|
|
108
|
+
defaultProps: { getPosition }
|
|
109
|
+
},
|
|
110
|
+
hexagon: {
|
|
111
|
+
Layer: HexagonLayer,
|
|
112
|
+
propMap: { visConfig: { ...aggregationVisConfig, worldUnitSize: x => ({ radius: 1000 * x }) } },
|
|
113
|
+
defaultProps: { getPosition }
|
|
114
|
+
},
|
|
115
|
+
hexagonId: {
|
|
116
|
+
Layer: H3HexagonLayer,
|
|
117
|
+
propMap: { visConfig: { coverage: 'coverage' } },
|
|
118
|
+
defaultProps: { getHexagon: d => d[hexagonId], stroked: false }
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const layer = layerTypeDefs[type];
|
|
122
|
+
assert(layer, `Unsupported layer type: ${type}`);
|
|
123
|
+
return {
|
|
124
|
+
...layer,
|
|
125
|
+
propMap: mergePropMaps(sharedPropMap, layer.propMap),
|
|
126
|
+
defaultProps: { ...defaultProps, ...layer.defaultProps }
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function getTileLayer(dataset) {
|
|
130
|
+
const { data: { tiles: [tileUrl] } } = dataset;
|
|
131
|
+
/* global URL */
|
|
132
|
+
const formatTiles = new URL(tileUrl).searchParams.get('formatTiles') || TILE_FORMATS.MVT;
|
|
133
|
+
return {
|
|
134
|
+
Layer: formatTiles === TILE_FORMATS.MVT ? MVTLayer : CartoTileLayer,
|
|
135
|
+
propMap: sharedPropMap,
|
|
136
|
+
defaultProps: {
|
|
137
|
+
...defaultProps,
|
|
138
|
+
uniqueIdProperty: 'geoid',
|
|
139
|
+
formatTiles
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function domainFromAttribute(attribute, scaleType) {
|
|
144
|
+
if (scaleType === 'ordinal' || scaleType === 'point') {
|
|
145
|
+
return attribute.categories.map(c => c.category).filter(c => c !== undefined && c !== null);
|
|
146
|
+
}
|
|
147
|
+
let { min } = attribute;
|
|
148
|
+
if (scaleType === 'log' && min === 0) {
|
|
149
|
+
min = 1e-5;
|
|
150
|
+
}
|
|
151
|
+
return [min, attribute.max];
|
|
152
|
+
}
|
|
153
|
+
function domainFromValues(values, scaleType) {
|
|
154
|
+
if (scaleType === 'ordinal') {
|
|
155
|
+
return groupSort(values, g => -g.length, d => d);
|
|
156
|
+
}
|
|
157
|
+
else if (scaleType === 'quantile') {
|
|
158
|
+
return values.sort((a, b) => a - b);
|
|
159
|
+
}
|
|
160
|
+
else if (scaleType === 'log') {
|
|
161
|
+
const [d0, d1] = extent(values);
|
|
162
|
+
return [d0 === 0 ? 1e-5 : d0, d1];
|
|
163
|
+
}
|
|
164
|
+
return extent(values);
|
|
165
|
+
}
|
|
166
|
+
function calculateDomain(data, name, scaleType) {
|
|
167
|
+
if (data.tilestats) {
|
|
168
|
+
// Tileset data type
|
|
169
|
+
const { attributes } = data.tilestats.layers[0];
|
|
170
|
+
const attribute = attributes.find(a => a.attribute === name);
|
|
171
|
+
return domainFromAttribute(attribute, scaleType);
|
|
172
|
+
}
|
|
173
|
+
else if (data.features) {
|
|
174
|
+
// GeoJSON data type
|
|
175
|
+
const values = data.features.map(({ properties }) => properties[name]);
|
|
176
|
+
return domainFromValues(values, scaleType);
|
|
177
|
+
}
|
|
178
|
+
else if (Array.isArray(data) && data[0][name] !== undefined) {
|
|
179
|
+
// JSON data type
|
|
180
|
+
const values = data.map(properties => properties[name]);
|
|
181
|
+
return domainFromValues(values, scaleType);
|
|
182
|
+
}
|
|
183
|
+
return [0, 1];
|
|
184
|
+
}
|
|
185
|
+
function normalizeAccessor(accessor, data) {
|
|
186
|
+
if (data.features || data.tilestats) {
|
|
187
|
+
return ({ properties }) => {
|
|
188
|
+
return accessor(properties);
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
return accessor;
|
|
192
|
+
}
|
|
193
|
+
export function opacityToAlpha(opacity) {
|
|
194
|
+
return opacity !== undefined ? Math.round(255 * Math.pow(opacity, 1 / 2.2)) : 255;
|
|
195
|
+
}
|
|
196
|
+
export function getColorValueAccessor({ name }, colorAggregation, data) {
|
|
197
|
+
const aggregator = AGGREGATION_FUNC[colorAggregation];
|
|
198
|
+
const accessor = values => aggregator(values, p => p[name]);
|
|
199
|
+
return normalizeAccessor(accessor, data);
|
|
200
|
+
}
|
|
201
|
+
export function getColorAccessor({ name }, scaleType, { colors, colorMap }, opacity, data) {
|
|
202
|
+
const scale = SCALE_FUNCS[scaleType]();
|
|
203
|
+
let domain = [];
|
|
204
|
+
let scaleColor = [];
|
|
205
|
+
if (Array.isArray(colorMap)) {
|
|
206
|
+
colorMap.forEach(([value, color]) => {
|
|
207
|
+
domain.push(value);
|
|
208
|
+
scaleColor.push(color);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
domain = calculateDomain(data, name, scaleType);
|
|
213
|
+
scaleColor = colors;
|
|
214
|
+
}
|
|
215
|
+
if (scaleType === 'ordinal') {
|
|
216
|
+
domain = domain.slice(0, scaleColor.length);
|
|
217
|
+
}
|
|
218
|
+
scale.domain(domain);
|
|
219
|
+
scale.range(scaleColor);
|
|
220
|
+
scale.unknown(UNKNOWN_COLOR);
|
|
221
|
+
const alpha = opacityToAlpha(opacity);
|
|
222
|
+
const accessor = properties => {
|
|
223
|
+
const propertyValue = properties[name];
|
|
224
|
+
const { r, g, b } = rgb(scale(propertyValue));
|
|
225
|
+
return [r, g, b, propertyValue === null ? 0 : alpha];
|
|
226
|
+
};
|
|
227
|
+
return normalizeAccessor(accessor, data);
|
|
228
|
+
}
|
|
229
|
+
export function getSizeAccessor({ name }, scaleType, range, data) {
|
|
230
|
+
const scale = SCALE_FUNCS[scaleType]();
|
|
231
|
+
scale.domain(calculateDomain(data, name, scaleType));
|
|
232
|
+
scale.range(range);
|
|
233
|
+
const accessor = properties => {
|
|
234
|
+
return scale(properties[name]);
|
|
235
|
+
};
|
|
236
|
+
return normalizeAccessor(accessor, data);
|
|
237
|
+
}
|
|
238
|
+
const FORMATS = {
|
|
239
|
+
date: s => moment.utc(s).format('MM/DD/YY HH:mm:ssa'),
|
|
240
|
+
integer: d3Format('i'),
|
|
241
|
+
float: d3Format('.5f'),
|
|
242
|
+
timestamp: s => moment.utc(s).format('X'),
|
|
243
|
+
default: String
|
|
244
|
+
};
|
|
245
|
+
export function getTextAccessor({ name, type }, data) {
|
|
246
|
+
const format = FORMATS[type] || FORMATS.default;
|
|
247
|
+
const accessor = properties => {
|
|
248
|
+
return format(properties[name]);
|
|
249
|
+
};
|
|
250
|
+
return normalizeAccessor(accessor, data);
|
|
251
|
+
}
|
|
252
|
+
export function getTextPixelOffsetAccessor({ alignment, anchor, size }, radius) {
|
|
253
|
+
const padding = 20;
|
|
254
|
+
const signX = anchor === 'middle' ? 0 : anchor === 'start' ? 1 : -1;
|
|
255
|
+
const signY = alignment === 'center' ? 0 : alignment === 'bottom' ? 1 : -1;
|
|
256
|
+
const sizeOffset = alignment === 'center' ? 0 : size;
|
|
257
|
+
const calculateOffset = r => [signX * (r + padding), signY * (r + padding + sizeOffset)];
|
|
258
|
+
return typeof radius === 'function'
|
|
259
|
+
? d => {
|
|
260
|
+
return calculateOffset(radius(d));
|
|
261
|
+
}
|
|
262
|
+
: calculateOffset(radius);
|
|
263
|
+
}
|
|
264
|
+
export { domainFromValues as _domainFromValues };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const DEFAULT_USER_COMPONENT_IN_URL = '{user}';
|
|
2
|
+
export const DEFAULT_REGION_COMPONENT_IN_URL = '{region}';
|
|
3
|
+
export const API_VERSIONS = {
|
|
4
|
+
V1: 'v1',
|
|
5
|
+
V2: 'v2',
|
|
6
|
+
V3: 'v3'
|
|
7
|
+
};
|
|
8
|
+
export const DEFAULT_MAPS_URL_FORMAT = {
|
|
9
|
+
[API_VERSIONS.V1]: `https://${DEFAULT_USER_COMPONENT_IN_URL}.carto.com/api/v1/map`,
|
|
10
|
+
[API_VERSIONS.V2]: `https://maps-api-v2.${DEFAULT_REGION_COMPONENT_IN_URL}.carto.com/user/${DEFAULT_USER_COMPONENT_IN_URL}`
|
|
11
|
+
};
|
|
12
|
+
export const MAP_TYPES = {
|
|
13
|
+
QUERY: 'query',
|
|
14
|
+
TABLE: 'table',
|
|
15
|
+
TILESET: 'tileset'
|
|
16
|
+
};
|
|
17
|
+
export const COLUMNS_SUPPORT = [MAP_TYPES.TABLE];
|
|
18
|
+
export const GEO_COLUMN_SUPPORT = [MAP_TYPES.QUERY, MAP_TYPES.TABLE];
|
|
19
|
+
// AVAILABLE FORMATS
|
|
20
|
+
export const FORMATS = {
|
|
21
|
+
GEOJSON: 'geojson',
|
|
22
|
+
NDJSON: 'ndjson',
|
|
23
|
+
TILEJSON: 'tilejson',
|
|
24
|
+
JSON: 'json'
|
|
25
|
+
};
|
|
26
|
+
// AVAILABLE FORMATS FOR TILES
|
|
27
|
+
export const TILE_FORMATS = {
|
|
28
|
+
MVT: 'mvt',
|
|
29
|
+
JSON: 'json',
|
|
30
|
+
GEOJSON: 'geojson',
|
|
31
|
+
BINARY: 'binary'
|
|
32
|
+
};
|
|
33
|
+
export var SchemaFieldType;
|
|
34
|
+
(function (SchemaFieldType) {
|
|
35
|
+
SchemaFieldType["Number"] = "number";
|
|
36
|
+
SchemaFieldType["Bigint"] = "bigint";
|
|
37
|
+
SchemaFieldType["String"] = "string";
|
|
38
|
+
SchemaFieldType["Geometry"] = "geometry";
|
|
39
|
+
SchemaFieldType["Timestamp"] = "timestamp";
|
|
40
|
+
SchemaFieldType["Object"] = "object";
|
|
41
|
+
SchemaFieldType["Boolean"] = "boolean";
|
|
42
|
+
SchemaFieldType["Variant"] = "variant";
|
|
43
|
+
SchemaFieldType["Unknown"] = "unknown";
|
|
44
|
+
})(SchemaFieldType || (SchemaFieldType = {}));
|
|
45
|
+
/**
|
|
46
|
+
* Simple encode parameter
|
|
47
|
+
*/
|
|
48
|
+
export function encodeParameter(name, value) {
|
|
49
|
+
return `${name}=${encodeURIComponent(value)}`;
|
|
50
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps API Client for Maps API v1 and Maps API v2
|
|
3
|
+
*/
|
|
4
|
+
import { defaultClassicCredentials, defaultCloudNativeCredentials, getDefaultCredentials } from '../config';
|
|
5
|
+
import { API_VERSIONS, DEFAULT_MAPS_URL_FORMAT, DEFAULT_REGION_COMPONENT_IN_URL, DEFAULT_USER_COMPONENT_IN_URL, encodeParameter, MAP_TYPES } from './maps-api-common';
|
|
6
|
+
export const CONNECTIONS = {
|
|
7
|
+
BIGQUERY: 'bigquery',
|
|
8
|
+
CARTO: 'carto'
|
|
9
|
+
};
|
|
10
|
+
const BUFFER_SIZE = 16;
|
|
11
|
+
const TILE_EXTENT = 4096;
|
|
12
|
+
/**
|
|
13
|
+
* Obtain a TileJson from Maps API v1 and v2
|
|
14
|
+
*/
|
|
15
|
+
export async function getDataV2({ type, source, credentials }) {
|
|
16
|
+
const defaultCredentials = getDefaultCredentials();
|
|
17
|
+
const apiVersion = credentials?.apiVersion || defaultCredentials.apiVersion;
|
|
18
|
+
// Only pick up default credentials if they have been defined for
|
|
19
|
+
// correct API version
|
|
20
|
+
const localCreds = {
|
|
21
|
+
...(apiVersion === API_VERSIONS.V3 ? defaultCloudNativeCredentials : defaultClassicCredentials),
|
|
22
|
+
mapsUrl: DEFAULT_MAPS_URL_FORMAT[apiVersion],
|
|
23
|
+
...(defaultCredentials.apiVersion === apiVersion && defaultCredentials),
|
|
24
|
+
...credentials
|
|
25
|
+
};
|
|
26
|
+
let url;
|
|
27
|
+
const connection = type === MAP_TYPES.TILESET ? CONNECTIONS.BIGQUERY : CONNECTIONS.CARTO;
|
|
28
|
+
switch (apiVersion) {
|
|
29
|
+
case API_VERSIONS.V1:
|
|
30
|
+
// Maps API v1
|
|
31
|
+
const mapConfig = createMapConfig(source);
|
|
32
|
+
url = buildURLMapsAPIv1({ mapConfig, credentials: localCreds });
|
|
33
|
+
const layergroup = await request({ url, credentials: localCreds });
|
|
34
|
+
return layergroup.metadata.tilejson.vector;
|
|
35
|
+
case API_VERSIONS.V2:
|
|
36
|
+
// Maps API v2
|
|
37
|
+
url = buildURLMapsAPIv2({ connection, type, source, credentials: localCreds });
|
|
38
|
+
return await request({ url, credentials: localCreds });
|
|
39
|
+
default:
|
|
40
|
+
throw new Error(`Invalid maps API version. It should be ${API_VERSIONS.V1} or ${API_VERSIONS.V2}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Request against Maps API
|
|
45
|
+
*/
|
|
46
|
+
async function request({ url, credentials }) {
|
|
47
|
+
let response;
|
|
48
|
+
try {
|
|
49
|
+
/* global fetch */
|
|
50
|
+
response = await fetch(url, {
|
|
51
|
+
headers: {
|
|
52
|
+
Accept: 'application/json'
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
throw new Error(`Failed to connect to Maps API: ${error}`);
|
|
58
|
+
}
|
|
59
|
+
const json = await response.json();
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
dealWithError({ response, json, credentials });
|
|
62
|
+
}
|
|
63
|
+
return json;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Display proper message from Maps API error
|
|
67
|
+
*/
|
|
68
|
+
function dealWithError({ response, json, credentials }) {
|
|
69
|
+
switch (response.status) {
|
|
70
|
+
case 401:
|
|
71
|
+
throw new Error(`Unauthorized access to Maps API: invalid combination of user ('${credentials.username}') and apiKey ('${credentials.apiKey}')`);
|
|
72
|
+
case 403:
|
|
73
|
+
throw new Error(`Unauthorized access to dataset: the provided apiKey('${credentials.apiKey}') doesn't provide access to the requested data`);
|
|
74
|
+
default:
|
|
75
|
+
const e = credentials.apiVersion === API_VERSIONS.V1 ? JSON.stringify(json.errors) : json.error;
|
|
76
|
+
throw new Error(e);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function initURLParameters(credentials) {
|
|
80
|
+
const encodedApiKey = encodeParameter('api_key', credentials.apiKey);
|
|
81
|
+
const encodedClient = encodeParameter('client', 'deck-gl-carto');
|
|
82
|
+
return [encodedApiKey, encodedClient];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build a URL with all required parameters
|
|
86
|
+
*/
|
|
87
|
+
function buildURLMapsAPIv1({ mapConfig, credentials }) {
|
|
88
|
+
const parameters = initURLParameters(credentials);
|
|
89
|
+
const cfg = JSON.stringify(mapConfig);
|
|
90
|
+
return `${mapsUrl(credentials)}?${parameters.join('&')}&${encodeParameter('config', cfg)}`;
|
|
91
|
+
}
|
|
92
|
+
function buildURLMapsAPIv2({ connection, type, source, credentials }) {
|
|
93
|
+
const parameters = initURLParameters(credentials);
|
|
94
|
+
// Query type is mapped to 'sql' at maps api v1
|
|
95
|
+
const mapsApiType = type === MAP_TYPES.QUERY ? 'sql' : type;
|
|
96
|
+
let url = `${mapsUrl(credentials)}/${connection}/${mapsApiType}?`;
|
|
97
|
+
url += `${encodeParameter('source', source)}&format=tilejson&${parameters.join('&')}`;
|
|
98
|
+
return url;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Prepare a url valid for the specified user
|
|
102
|
+
*/
|
|
103
|
+
function mapsUrl(credentials) {
|
|
104
|
+
return credentials.mapsUrl
|
|
105
|
+
.replace(DEFAULT_USER_COMPONENT_IN_URL, credentials.username)
|
|
106
|
+
.replace(DEFAULT_REGION_COMPONENT_IN_URL, credentials.region);
|
|
107
|
+
}
|
|
108
|
+
function createMapConfig(sql) {
|
|
109
|
+
return {
|
|
110
|
+
version: '1.3.1',
|
|
111
|
+
buffersize: {
|
|
112
|
+
mvt: BUFFER_SIZE
|
|
113
|
+
},
|
|
114
|
+
layers: [
|
|
115
|
+
{
|
|
116
|
+
type: 'mapnik',
|
|
117
|
+
options: {
|
|
118
|
+
sql,
|
|
119
|
+
// eslint-disable-next-line camelcase
|
|
120
|
+
vector_extent: TILE_EXTENT
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
};
|
|
125
|
+
}
|
|
@@ -23,7 +23,6 @@ export interface FetchLayerDataResult {
|
|
|
23
23
|
schema: SchemaField[];
|
|
24
24
|
}
|
|
25
25
|
export declare function fetchLayerData({ type, source, connection, credentials, geoColumn, columns, format, formatTiles, clientId, aggregationExp, aggregationResLevel }: FetchLayerDataParams): Promise<FetchLayerDataResult>;
|
|
26
|
-
export declare function getData({ type, source, connection, credentials, geoColumn, columns, format, clientId }: FetchLayerDataParams): Promise<any>;
|
|
27
26
|
export declare function fetchMap({ cartoMapId, clientId, credentials, autoRefresh, onNewData }: {
|
|
28
27
|
cartoMapId: string;
|
|
29
28
|
clientId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maps-v3-client.d.ts","sourceRoot":"","sources":["../../src/api/maps-v3-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAA8C,sBAAsB,EAAC,MAAM,WAAW,CAAC;AAC9F,OAAO,EAIL,MAAM,EAGN,gBAAgB,EAChB,OAAO,EAEP,WAAW,EACX,UAAU,EAEX,MAAM,mBAAmB,CAAC;AA0F3B,aAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,sBAAsB,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAmCF,wBAAsB,gBAAgB,CAAC,EACrC,IAAI,EACJ,MAAM,EACN,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,QAAQ,EACR,cAAc,EACd,mBAAmB,EACpB,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuBlD;AAsDD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AACD,wBAAsB,cAAc,CAAC,EACnC,IAAI,EACJ,MAAM,EACN,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,cAAc,EACd,mBAAmB,EACpB,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAoBtD;
|
|
1
|
+
{"version":3,"file":"maps-v3-client.d.ts","sourceRoot":"","sources":["../../src/api/maps-v3-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAA8C,sBAAsB,EAAC,MAAM,WAAW,CAAC;AAC9F,OAAO,EAIL,MAAM,EAGN,gBAAgB,EAChB,OAAO,EAEP,WAAW,EACX,UAAU,EAEX,MAAM,mBAAmB,CAAC;AA0F3B,aAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,sBAAsB,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAmCF,wBAAsB,gBAAgB,CAAC,EACrC,IAAI,EACJ,MAAM,EACN,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,QAAQ,EACR,cAAc,EACd,mBAAmB,EACpB,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuBlD;AAsDD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AACD,wBAAsB,cAAc,CAAC,EACnC,IAAI,EACJ,MAAM,EACN,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,MAAM,EACN,WAAW,EACX,QAAQ,EACR,cAAc,EACd,mBAAmB,EACpB,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAoBtD;AA0HD,wBAAsB,QAAQ,CAAC,EAC7B,UAAU,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,SAAS,EACV,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;CAChC;4BA8B6B,IAAI;;;;;;;;;GA8BjC"}
|