@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.
- package/dist/dist.dev.js +38143 -16628
- package/dist/es5/api/layer-map.js +4 -3
- package/dist/es5/api/layer-map.js.map +1 -1
- package/dist/es5/api/maps-client.js +2 -2
- package/dist/es5/api/maps-client.js.map +1 -1
- package/dist/es5/api/maps-v3-client.js +57 -43
- package/dist/es5/api/maps-v3-client.js.map +1 -1
- package/dist/es5/api/parseMap.js +9 -13
- package/dist/es5/api/parseMap.js.map +1 -1
- package/dist/es5/config.js +15 -24
- package/dist/es5/config.js.map +1 -1
- package/dist/es5/index.js +0 -16
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/layers/carto-dynamic-tile-layer.js +168 -0
- package/dist/es5/layers/carto-dynamic-tile-layer.js.map +1 -0
- package/dist/es5/layers/carto-layer.js +59 -52
- package/dist/es5/layers/carto-layer.js.map +1 -1
- package/dist/es5/style/color-bins-style.js +6 -2
- package/dist/es5/style/color-bins-style.js.map +1 -1
- package/dist/es5/style/color-categories-style.js +7 -3
- package/dist/es5/style/color-categories-style.js.map +1 -1
- package/dist/es5/style/color-continuous-style.js +6 -2
- package/dist/es5/style/color-continuous-style.js.map +1 -1
- package/dist/es5/style/palette.js +6 -2
- package/dist/es5/style/palette.js.map +1 -1
- package/dist/esm/api/layer-map.js +3 -2
- package/dist/esm/api/layer-map.js.map +1 -1
- package/dist/esm/api/maps-client.js +1 -1
- package/dist/esm/api/maps-client.js.map +1 -1
- package/dist/esm/api/maps-v3-client.js +47 -25
- package/dist/esm/api/maps-v3-client.js.map +1 -1
- package/dist/esm/api/parseMap.js +3 -10
- package/dist/esm/api/parseMap.js.map +1 -1
- package/dist/esm/config.js +11 -26
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/layers/carto-dynamic-tile-layer.js +98 -0
- package/dist/esm/layers/carto-dynamic-tile-layer.js.map +1 -0
- package/dist/esm/layers/carto-layer.js +35 -28
- package/dist/esm/layers/carto-layer.js.map +1 -1
- package/dist/esm/style/color-bins-style.js +1 -1
- package/dist/esm/style/color-bins-style.js.map +1 -1
- package/dist/esm/style/color-continuous-style.js +1 -1
- package/dist/esm/style/color-continuous-style.js.map +1 -1
- package/dist.min.js +14 -14
- package/package.json +8 -7
- package/src/api/layer-map.js +3 -2
- package/src/api/maps-client.js +3 -7
- package/src/api/maps-v3-client.js +53 -25
- package/src/api/parseMap.js +17 -26
- package/src/config.js +8 -39
- package/src/index.js +0 -2
- package/src/layers/carto-dynamic-tile-layer.js +87 -0
- package/src/layers/carto-layer.js +25 -25
- package/src/style/color-bins-style.js +2 -4
- package/src/style/color-continuous-style.js +2 -4
- package/dist/es5/layers/carto-bqtiler-layer.js +0 -65
- package/dist/es5/layers/carto-bqtiler-layer.js.map +0 -1
- package/dist/es5/layers/carto-sql-layer.js +0 -66
- package/dist/es5/layers/carto-sql-layer.js.map +0 -1
- package/dist/esm/layers/carto-bqtiler-layer.js +0 -16
- package/dist/esm/layers/carto-bqtiler-layer.js.map +0 -1
- package/dist/esm/layers/carto-sql-layer.js +0 -17
- package/dist/esm/layers/carto-sql-layer.js.map +0 -1
- package/src/layers/carto-bqtiler-layer.js +0 -21
- 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.
|
|
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/
|
|
35
|
-
"@loaders.gl/
|
|
36
|
-
"@loaders.gl/
|
|
37
|
-
"@
|
|
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.
|
|
50
|
+
"@loaders.gl/core": "^3.1.3"
|
|
50
51
|
},
|
|
51
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "b6c48fb68b66755743c28776a0642b56a2df086a"
|
|
52
53
|
}
|
package/src/api/layer-map.js
CHANGED
|
@@ -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]));
|
package/src/api/maps-client.js
CHANGED
|
@@ -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
|
|
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',
|
|
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:
|
|
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({
|
|
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,
|
|
267
|
-
const promises = datasets.map(dataset => _fetchMapDataset(dataset,
|
|
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({
|
|
272
|
-
const
|
|
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(
|
|
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/${
|
|
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
|
|
328
|
+
await fillInMapDatasets(map, clientId, credentials);
|
|
329
|
+
return {
|
|
330
|
+
...parseMap(map),
|
|
331
|
+
...{stopAutoRefresh}
|
|
332
|
+
};
|
|
305
333
|
}
|
package/src/api/parseMap.js
CHANGED
|
@@ -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
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
6
|
+
username: 'public'
|
|
8
7
|
};
|
|
9
8
|
|
|
10
|
-
const defaultCloudNativeCredentials = {
|
|
11
|
-
|
|
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(
|
|
21
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
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,
|
|
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
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
112
|
+
result = await fetchLayerData({type, source, clientId, credentials, ...rest});
|
|
115
113
|
}
|
|
116
114
|
|
|
117
|
-
this.setState({
|
|
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
|
-
|
|
140
|
+
format === FORMATS.TILEJSON
|
|
142
141
|
) {
|
|
143
142
|
layer = MVTLayer;
|
|
144
143
|
} else {
|
|
145
144
|
layer = GeoJsonLayer;
|
|
146
145
|
}
|
|
147
146
|
|
|
148
|
-
const
|
|
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);
|