@deck.gl/carto 8.7.0-beta.2 → 8.7.0-beta.6
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 +1425 -306
- package/dist/es5/api/index.js +6 -0
- package/dist/es5/api/index.js.map +1 -1
- package/dist/es5/api/layer-map.js +32 -17
- package/dist/es5/api/layer-map.js.map +1 -1
- package/dist/es5/api/maps-api-common.js +21 -1
- package/dist/es5/api/maps-api-common.js.map +1 -1
- package/dist/es5/api/maps-client.js +15 -18
- package/dist/es5/api/maps-client.js.map +1 -1
- package/dist/es5/api/maps-v3-client.js +241 -181
- package/dist/es5/api/maps-v3-client.js.map +1 -1
- package/dist/es5/api/parseMap.js +9 -12
- package/dist/es5/api/parseMap.js.map +1 -1
- package/dist/es5/basemap.js +7 -7
- package/dist/es5/basemap.js.map +1 -1
- package/dist/es5/config.js.map +1 -1
- package/dist/es5/index.js +15 -1
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/layers/carto-layer.js +27 -16
- package/dist/es5/layers/carto-layer.js.map +1 -1
- package/dist/es5/layers/{carto-dynamic-tile-layer.js → carto-tile-layer.js} +79 -32
- package/dist/es5/layers/carto-tile-layer.js.map +1 -0
- package/dist/es5/layers/schema/carto-tile.js +197 -0
- package/dist/es5/layers/schema/carto-tile.js.map +1 -0
- package/dist/es5/style/color-bins-style.js +1 -1
- package/dist/es5/style/color-bins-style.js.map +1 -1
- package/dist/es5/style/color-categories-style.js +1 -1
- package/dist/es5/style/color-categories-style.js.map +1 -1
- package/dist/es5/style/color-continuous-style.js +1 -1
- package/dist/es5/style/color-continuous-style.js.map +1 -1
- package/dist/es5/style/palette.js +1 -6
- package/dist/es5/style/palette.js.map +1 -1
- package/dist/es5/style/utils.js +2 -6
- package/dist/es5/style/utils.js.map +1 -1
- package/dist/es5/utils.js +13 -0
- package/dist/es5/utils.js.map +1 -0
- package/dist/esm/api/index.js +1 -1
- package/dist/esm/api/index.js.map +1 -1
- package/dist/esm/api/layer-map.js +28 -12
- package/dist/esm/api/layer-map.js.map +1 -1
- package/dist/esm/api/maps-api-common.js +19 -0
- package/dist/esm/api/maps-api-common.js.map +1 -1
- package/dist/esm/api/maps-client.js +6 -10
- package/dist/esm/api/maps-client.js.map +1 -1
- package/dist/esm/api/maps-v3-client.js +73 -38
- package/dist/esm/api/maps-v3-client.js.map +1 -1
- package/dist/esm/api/parseMap.js +9 -8
- package/dist/esm/api/parseMap.js.map +1 -1
- package/dist/esm/basemap.js +7 -7
- package/dist/esm/basemap.js.map +1 -1
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/index.js +3 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/layers/carto-layer.js +25 -13
- package/dist/esm/layers/carto-layer.js.map +1 -1
- package/dist/esm/layers/carto-tile-layer.js +141 -0
- package/dist/esm/layers/carto-tile-layer.js.map +1 -0
- package/dist/esm/layers/schema/carto-tile.js +190 -0
- package/dist/esm/layers/schema/carto-tile.js.map +1 -0
- 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-categories-style.js +1 -1
- package/dist/esm/style/color-categories-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/esm/style/palette.js +1 -6
- package/dist/esm/style/palette.js.map +1 -1
- package/dist/esm/style/utils.js +2 -6
- package/dist/esm/style/utils.js.map +1 -1
- package/dist/esm/utils.js +5 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist.min.js +14 -14
- package/package.json +10 -3
- package/src/api/{index.js → index.ts} +1 -1
- package/src/api/{layer-map.js → layer-map.ts} +50 -23
- package/src/api/maps-api-common.ts +76 -0
- package/src/api/{maps-client.js → maps-client.ts} +55 -20
- package/src/api/{maps-v3-client.js → maps-v3-client.ts} +145 -57
- package/src/api/{parseMap.js → parseMap.ts} +8 -7
- package/src/basemap.ts +10 -0
- package/src/{config.js → config.ts} +22 -6
- package/src/{index.js → index.ts} +3 -1
- package/src/layers/carto-layer.js +30 -19
- package/src/layers/carto-tile-layer.js +121 -0
- package/src/layers/schema/carto-tile.js +195 -0
- package/src/style/color-bins-style.ts +26 -0
- package/src/style/{color-categories-style.js → color-categories-style.ts} +10 -4
- package/src/style/color-continuous-style.ts +25 -0
- package/src/style/{palette.js → palette.ts} +18 -15
- package/src/style/{utils.js → utils.ts} +7 -10
- package/src/utils.ts +5 -0
- package/dist/es5/layers/carto-dynamic-tile-layer.js.map +0 -1
- package/dist/esm/layers/carto-dynamic-tile-layer.js +0 -97
- package/dist/esm/layers/carto-dynamic-tile-layer.js.map +0 -1
- package/src/api/maps-api-common.js +0 -34
- package/src/basemap.js +0 -10
- package/src/layers/carto-dynamic-tile-layer.js +0 -86
- package/src/style/color-bins-style.js +0 -21
- package/src/style/color-continuous-style.js +0 -20
|
@@ -1,21 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Maps API Client for Carto 3
|
|
3
3
|
*/
|
|
4
|
-
import {getDefaultCredentials, buildMapsUrlFromBase} from '../config';
|
|
5
|
-
import {
|
|
4
|
+
import {getDefaultCredentials, buildMapsUrlFromBase, CloudNativeCredentials} from '../config';
|
|
5
|
+
import {
|
|
6
|
+
API_VERSIONS,
|
|
7
|
+
encodeParameter,
|
|
8
|
+
Format,
|
|
9
|
+
FORMATS,
|
|
10
|
+
MapInstantiation,
|
|
11
|
+
MapType,
|
|
12
|
+
MAP_TYPES,
|
|
13
|
+
SchemaField
|
|
14
|
+
} from './maps-api-common';
|
|
6
15
|
import {parseMap} from './parseMap';
|
|
7
16
|
import {log} from '@deck.gl/core';
|
|
17
|
+
import {assert} from '../utils';
|
|
8
18
|
|
|
9
19
|
const MAX_GET_LENGTH = 2048;
|
|
10
20
|
const DEFAULT_CLIENT = 'deck-gl-carto';
|
|
11
21
|
|
|
22
|
+
interface RequestParams {
|
|
23
|
+
method?: string;
|
|
24
|
+
url: string;
|
|
25
|
+
accessToken?: string;
|
|
26
|
+
body?: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
12
29
|
/**
|
|
13
30
|
* Request against Maps API
|
|
14
31
|
*/
|
|
15
|
-
async function request({method, url,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const headers = {
|
|
32
|
+
async function request({method, url, accessToken, body}: RequestParams): Promise<Response> {
|
|
33
|
+
const headers: Record<string, string> = {
|
|
19
34
|
Accept: 'application/json'
|
|
20
35
|
};
|
|
21
36
|
|
|
@@ -29,8 +44,7 @@ async function request({method, url, format, accessToken, body}) {
|
|
|
29
44
|
|
|
30
45
|
try {
|
|
31
46
|
/* global fetch */
|
|
32
|
-
|
|
33
|
-
response = await fetch(url, {
|
|
47
|
+
return await fetch(url, {
|
|
34
48
|
method,
|
|
35
49
|
headers,
|
|
36
50
|
body
|
|
@@ -38,24 +52,44 @@ async function request({method, url, format, accessToken, body}) {
|
|
|
38
52
|
} catch (error) {
|
|
39
53
|
throw new Error(`Failed to connect to Maps API: ${error}`);
|
|
40
54
|
}
|
|
55
|
+
}
|
|
41
56
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
async function requestJson<T = unknown>({
|
|
58
|
+
method,
|
|
59
|
+
url,
|
|
60
|
+
accessToken,
|
|
61
|
+
body
|
|
62
|
+
}: RequestParams): Promise<T> {
|
|
63
|
+
const response = await request({method, url, accessToken, body});
|
|
46
64
|
const json = await response.json();
|
|
47
65
|
|
|
48
66
|
if (!response.ok) {
|
|
49
67
|
dealWithError({response, error: json.error});
|
|
50
68
|
}
|
|
69
|
+
return json as T;
|
|
70
|
+
}
|
|
51
71
|
|
|
52
|
-
|
|
72
|
+
async function requestData({
|
|
73
|
+
method,
|
|
74
|
+
url,
|
|
75
|
+
accessToken,
|
|
76
|
+
format,
|
|
77
|
+
body
|
|
78
|
+
}: RequestParams & {
|
|
79
|
+
format: Format;
|
|
80
|
+
}): Promise<Response | unknown> {
|
|
81
|
+
if (format === FORMATS.NDJSON) {
|
|
82
|
+
return request({method, url, accessToken, body});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const data = await requestJson<any>({method, url, accessToken, body});
|
|
86
|
+
return data.rows ? data.rows : data;
|
|
53
87
|
}
|
|
54
88
|
|
|
55
89
|
/**
|
|
56
90
|
* Display proper message from Maps API error
|
|
57
91
|
*/
|
|
58
|
-
function dealWithError({response, error}) {
|
|
92
|
+
function dealWithError({response, error}: {response: Response; error?: string}): never {
|
|
59
93
|
switch (response.status) {
|
|
60
94
|
case 400:
|
|
61
95
|
throw new Error(`Bad request. ${error}`);
|
|
@@ -67,10 +101,29 @@ function dealWithError({response, error}) {
|
|
|
67
101
|
}
|
|
68
102
|
}
|
|
69
103
|
|
|
104
|
+
type FetchLayerDataParams = {
|
|
105
|
+
type: MapType;
|
|
106
|
+
source: string;
|
|
107
|
+
connection: string;
|
|
108
|
+
credentials: CloudNativeCredentials;
|
|
109
|
+
geoColumn?: string;
|
|
110
|
+
columns?: string[];
|
|
111
|
+
schema?: boolean;
|
|
112
|
+
clientId?: string;
|
|
113
|
+
format?: Format;
|
|
114
|
+
};
|
|
115
|
+
|
|
70
116
|
/**
|
|
71
117
|
* Build a URL with all required parameters
|
|
72
118
|
*/
|
|
73
|
-
function getParameters({
|
|
119
|
+
function getParameters({
|
|
120
|
+
type,
|
|
121
|
+
source,
|
|
122
|
+
geoColumn,
|
|
123
|
+
columns,
|
|
124
|
+
schema,
|
|
125
|
+
clientId
|
|
126
|
+
}: Omit<FetchLayerDataParams, 'connection' | 'credentials'>) {
|
|
74
127
|
const parameters = [encodeParameter('client', clientId || DEFAULT_CLIENT)];
|
|
75
128
|
if (schema) {
|
|
76
129
|
parameters.push(encodeParameter('schema', true));
|
|
@@ -100,26 +153,24 @@ export async function mapInstantiation({
|
|
|
100
153
|
columns,
|
|
101
154
|
schema,
|
|
102
155
|
clientId
|
|
103
|
-
}) {
|
|
156
|
+
}: FetchLayerDataParams): Promise<MapInstantiation> {
|
|
104
157
|
const baseUrl = `${credentials.mapsUrl}/${connection}/${type}`;
|
|
105
158
|
const url = `${baseUrl}?${getParameters({type, source, geoColumn, columns, schema, clientId})}`;
|
|
106
159
|
const {accessToken} = credentials;
|
|
107
160
|
|
|
108
|
-
const format = 'json';
|
|
109
|
-
|
|
110
161
|
if (url.length > MAX_GET_LENGTH && type === MAP_TYPES.QUERY) {
|
|
111
162
|
// need to be a POST request
|
|
112
163
|
const body = JSON.stringify({
|
|
113
164
|
q: source,
|
|
114
165
|
client: clientId || DEFAULT_CLIENT
|
|
115
166
|
});
|
|
116
|
-
return await
|
|
167
|
+
return await requestJson({method: 'POST', url: baseUrl, accessToken, body});
|
|
117
168
|
}
|
|
118
169
|
|
|
119
|
-
return await
|
|
170
|
+
return await requestJson({url, accessToken});
|
|
120
171
|
}
|
|
121
172
|
|
|
122
|
-
function getUrlFromMetadata(metadata, format) {
|
|
173
|
+
function getUrlFromMetadata(metadata: MapInstantiation, format: Format): string | null {
|
|
123
174
|
const m = metadata[format];
|
|
124
175
|
|
|
125
176
|
if (m && !m.error && m.url) {
|
|
@@ -129,16 +180,26 @@ function getUrlFromMetadata(metadata, format) {
|
|
|
129
180
|
return null;
|
|
130
181
|
}
|
|
131
182
|
|
|
132
|
-
function checkFetchLayerDataParameters({
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
183
|
+
function checkFetchLayerDataParameters({
|
|
184
|
+
type,
|
|
185
|
+
source,
|
|
186
|
+
connection,
|
|
187
|
+
credentials
|
|
188
|
+
}: FetchLayerDataParams) {
|
|
189
|
+
assert(connection, 'Must define connection');
|
|
190
|
+
assert(type, 'Must define a type');
|
|
191
|
+
assert(source, 'Must define a source');
|
|
192
|
+
|
|
193
|
+
assert(credentials.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
|
|
194
|
+
assert(credentials.apiBaseUrl, 'Must define apiBaseUrl');
|
|
195
|
+
assert(credentials.accessToken, 'Must define an accessToken');
|
|
140
196
|
}
|
|
141
197
|
|
|
198
|
+
export interface FetchLayerDataResult {
|
|
199
|
+
data: any;
|
|
200
|
+
format: Format;
|
|
201
|
+
schema?: SchemaField[];
|
|
202
|
+
}
|
|
142
203
|
export async function fetchLayerData({
|
|
143
204
|
type,
|
|
144
205
|
source,
|
|
@@ -149,7 +210,7 @@ export async function fetchLayerData({
|
|
|
149
210
|
format,
|
|
150
211
|
schema,
|
|
151
212
|
clientId
|
|
152
|
-
}) {
|
|
213
|
+
}: FetchLayerDataParams): Promise<FetchLayerDataResult> {
|
|
153
214
|
// Internally we split data fetching into two parts to allow us to
|
|
154
215
|
// conditionally fetch the actual data, depending on the metadata state
|
|
155
216
|
const {url, accessToken, mapFormat, metadata} = await _fetchDataUrl({
|
|
@@ -164,8 +225,8 @@ export async function fetchLayerData({
|
|
|
164
225
|
clientId
|
|
165
226
|
});
|
|
166
227
|
|
|
167
|
-
const data = await
|
|
168
|
-
const result = {data, format: mapFormat};
|
|
228
|
+
const data = await requestData({url, format: mapFormat, accessToken});
|
|
229
|
+
const result: FetchLayerDataResult = {data, format: mapFormat};
|
|
169
230
|
if (schema) {
|
|
170
231
|
result.schema = metadata.schema;
|
|
171
232
|
}
|
|
@@ -183,7 +244,7 @@ async function _fetchDataUrl({
|
|
|
183
244
|
format,
|
|
184
245
|
schema,
|
|
185
246
|
clientId
|
|
186
|
-
}) {
|
|
247
|
+
}: FetchLayerDataParams) {
|
|
187
248
|
const defaultCredentials = getDefaultCredentials();
|
|
188
249
|
// Only pick up default credentials if they have been defined for
|
|
189
250
|
// correct API version
|
|
@@ -191,7 +252,7 @@ async function _fetchDataUrl({
|
|
|
191
252
|
...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
|
|
192
253
|
...credentials
|
|
193
254
|
};
|
|
194
|
-
checkFetchLayerDataParameters({type, source, connection, localCreds});
|
|
255
|
+
checkFetchLayerDataParameters({type, source, connection, credentials: localCreds});
|
|
195
256
|
|
|
196
257
|
if (!localCreds.mapsUrl) {
|
|
197
258
|
localCreds.mapsUrl = buildMapsUrlFromBase(localCreds.apiBaseUrl);
|
|
@@ -207,13 +268,13 @@ async function _fetchDataUrl({
|
|
|
207
268
|
schema,
|
|
208
269
|
clientId
|
|
209
270
|
});
|
|
210
|
-
let url;
|
|
211
|
-
let mapFormat;
|
|
271
|
+
let url: string | null = null;
|
|
272
|
+
let mapFormat: Format | undefined;
|
|
212
273
|
|
|
213
274
|
if (format) {
|
|
214
275
|
mapFormat = format;
|
|
215
276
|
url = getUrlFromMetadata(metadata, format);
|
|
216
|
-
|
|
277
|
+
assert(url, `Format ${format} not available`);
|
|
217
278
|
} else {
|
|
218
279
|
// guess map format
|
|
219
280
|
const prioritizedFormats = [FORMATS.GEOJSON, FORMATS.JSON, FORMATS.NDJSON, FORMATS.TILEJSON];
|
|
@@ -224,6 +285,7 @@ async function _fetchDataUrl({
|
|
|
224
285
|
break;
|
|
225
286
|
}
|
|
226
287
|
}
|
|
288
|
+
assert(url && mapFormat, 'Unsupported data formats received from backend.');
|
|
227
289
|
}
|
|
228
290
|
|
|
229
291
|
const {accessToken} = localCreds;
|
|
@@ -239,7 +301,7 @@ export async function getData({
|
|
|
239
301
|
columns,
|
|
240
302
|
format,
|
|
241
303
|
clientId
|
|
242
|
-
}) {
|
|
304
|
+
}: FetchLayerDataParams) {
|
|
243
305
|
log.deprecated('getData', 'fetchLayerData')();
|
|
244
306
|
const layerData = await fetchLayerData({
|
|
245
307
|
type,
|
|
@@ -255,8 +317,13 @@ export async function getData({
|
|
|
255
317
|
return layerData.data;
|
|
256
318
|
}
|
|
257
319
|
|
|
258
|
-
/* global clearInterval, setInterval,
|
|
259
|
-
async function _fetchMapDataset(
|
|
320
|
+
/* global clearInterval, setInterval, URL */
|
|
321
|
+
async function _fetchMapDataset(
|
|
322
|
+
dataset,
|
|
323
|
+
accessToken: string,
|
|
324
|
+
credentials: CloudNativeCredentials,
|
|
325
|
+
clientId?: string
|
|
326
|
+
) {
|
|
260
327
|
// First fetch metadata
|
|
261
328
|
const {connectionName: connection, source, type} = dataset;
|
|
262
329
|
const {url, mapFormat} = await _fetchDataUrl({
|
|
@@ -268,54 +335,75 @@ async function _fetchMapDataset(dataset, accessToken, credentials, clientId) {
|
|
|
268
335
|
});
|
|
269
336
|
|
|
270
337
|
// Extract the last time the data changed
|
|
271
|
-
const cache = parseInt(new
|
|
338
|
+
const cache = parseInt(new URL(url).searchParams.get('cache') || '', 10);
|
|
272
339
|
if (cache && dataset.cache === cache) {
|
|
273
340
|
return false;
|
|
274
341
|
}
|
|
275
342
|
dataset.cache = cache;
|
|
276
343
|
|
|
277
344
|
// Only fetch if the data has changed
|
|
278
|
-
|
|
279
|
-
|
|
345
|
+
dataset.data = await requestData({url, format: mapFormat, accessToken});
|
|
346
|
+
|
|
280
347
|
return true;
|
|
281
348
|
}
|
|
282
349
|
|
|
283
|
-
async function fillInMapDatasets(
|
|
350
|
+
async function fillInMapDatasets(
|
|
351
|
+
{datasets, token},
|
|
352
|
+
clientId: string,
|
|
353
|
+
credentials: CloudNativeCredentials
|
|
354
|
+
) {
|
|
284
355
|
const promises = datasets.map(dataset => _fetchMapDataset(dataset, token, credentials, clientId));
|
|
285
356
|
return await Promise.all(promises);
|
|
286
357
|
}
|
|
287
358
|
|
|
288
|
-
export async function fetchMap({
|
|
359
|
+
export async function fetchMap({
|
|
360
|
+
cartoMapId,
|
|
361
|
+
clientId,
|
|
362
|
+
credentials,
|
|
363
|
+
autoRefresh,
|
|
364
|
+
onNewData
|
|
365
|
+
}: {
|
|
366
|
+
cartoMapId: string;
|
|
367
|
+
clientId: string;
|
|
368
|
+
credentials?: CloudNativeCredentials;
|
|
369
|
+
autoRefresh?: number;
|
|
370
|
+
onNewData?: (map: any) => void;
|
|
371
|
+
}) {
|
|
289
372
|
const defaultCredentials = getDefaultCredentials();
|
|
290
373
|
const localCreds = {
|
|
291
374
|
...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
|
|
292
375
|
...credentials
|
|
293
|
-
};
|
|
376
|
+
} as CloudNativeCredentials;
|
|
377
|
+
const {accessToken} = localCreds;
|
|
294
378
|
|
|
295
|
-
|
|
379
|
+
assert(cartoMapId, 'Must define CARTO map id: fetchMap({cartoMapId: "XXXX-XXXX-XXXX"})');
|
|
296
380
|
|
|
297
|
-
|
|
298
|
-
|
|
381
|
+
assert(localCreds.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
|
|
382
|
+
assert(localCreds.apiBaseUrl, 'Must define apiBaseUrl');
|
|
299
383
|
if (!localCreds.mapsUrl) {
|
|
300
384
|
localCreds.mapsUrl = buildMapsUrlFromBase(localCreds.apiBaseUrl);
|
|
301
385
|
}
|
|
302
386
|
|
|
303
387
|
if (autoRefresh || onNewData) {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
388
|
+
assert(onNewData, 'Must define `onNewData` when using autoRefresh');
|
|
389
|
+
assert(typeof onNewData === 'function', '`onNewData` must be a function');
|
|
390
|
+
assert(
|
|
391
|
+
typeof autoRefresh === 'number' && autoRefresh > 0,
|
|
392
|
+
'`autoRefresh` must be a positive number'
|
|
393
|
+
);
|
|
307
394
|
}
|
|
308
395
|
|
|
309
396
|
const url = `${localCreds.mapsUrl}/public/${cartoMapId}`;
|
|
310
|
-
const map = await
|
|
397
|
+
const map = await requestJson<any>({url, accessToken});
|
|
311
398
|
|
|
312
399
|
// Periodically check if the data has changed. Note that this
|
|
313
400
|
// will not update when a map is published.
|
|
314
|
-
let stopAutoRefresh;
|
|
401
|
+
let stopAutoRefresh: (() => void) | undefined;
|
|
315
402
|
if (autoRefresh) {
|
|
403
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
316
404
|
const intervalId = setInterval(async () => {
|
|
317
|
-
const changed = await fillInMapDatasets(map, clientId,
|
|
318
|
-
if (changed.some(v => v === true)) {
|
|
405
|
+
const changed = await fillInMapDatasets(map, clientId, localCreds);
|
|
406
|
+
if (onNewData && changed.some(v => v === true)) {
|
|
319
407
|
onNewData(parseMap(map));
|
|
320
408
|
}
|
|
321
409
|
}, autoRefresh * 1000);
|
|
@@ -325,7 +413,7 @@ export async function fetchMap({cartoMapId, clientId, credentials, autoRefresh,
|
|
|
325
413
|
}
|
|
326
414
|
|
|
327
415
|
// Mutates map.datasets so that dataset.data contains data
|
|
328
|
-
await fillInMapDatasets(map, clientId,
|
|
416
|
+
await fillInMapDatasets(map, clientId, localCreds);
|
|
329
417
|
return {
|
|
330
418
|
...parseMap(map),
|
|
331
419
|
...{stopAutoRefresh}
|
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
getTextPixelOffsetAccessor
|
|
8
8
|
} from './layer-map';
|
|
9
9
|
import {_flatten as flatten, log} from '@deck.gl/core';
|
|
10
|
+
import {assert} from '../utils';
|
|
10
11
|
|
|
11
12
|
export function parseMap(json) {
|
|
12
13
|
const {keplerMapConfig, datasets} = json;
|
|
13
|
-
|
|
14
|
+
assert(keplerMapConfig.version === 'v1', 'Only support Kepler v1');
|
|
14
15
|
const {mapState, mapStyle} = keplerMapConfig.config;
|
|
15
16
|
const {layers, layerBlending, interactionConfig} = keplerMapConfig.config.visState;
|
|
16
17
|
|
|
@@ -24,12 +25,12 @@ export function parseMap(json) {
|
|
|
24
25
|
mapStyle,
|
|
25
26
|
layers: extractTextLayers(layers.reverse()).map(({id, type, config, visualChannels}) => {
|
|
26
27
|
try {
|
|
27
|
-
const {Layer, propMap, defaultProps} = getLayer(type, config);
|
|
28
28
|
const {dataId} = config;
|
|
29
29
|
const dataset = datasets.find(d => d.id === dataId);
|
|
30
|
-
|
|
30
|
+
assert(dataset, `No dataset matching dataId: ${dataId}`);
|
|
31
31
|
const {data} = dataset;
|
|
32
|
-
|
|
32
|
+
assert(data, `No data loaded for dataId: ${dataId}`);
|
|
33
|
+
const {Layer, propMap, defaultProps} = getLayer(type, config, dataset);
|
|
33
34
|
return new Layer({
|
|
34
35
|
id,
|
|
35
36
|
data,
|
|
@@ -39,7 +40,7 @@ export function parseMap(json) {
|
|
|
39
40
|
...createStyleProps(config, propMap),
|
|
40
41
|
...createChannelProps(visualChannels, type, config, data) // Must come after style
|
|
41
42
|
});
|
|
42
|
-
} catch (e) {
|
|
43
|
+
} catch (e: any) {
|
|
43
44
|
log.error(e.message)();
|
|
44
45
|
return undefined;
|
|
45
46
|
}
|
|
@@ -121,7 +122,7 @@ function mapProps(source, target, mapping) {
|
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
function createStyleProps(config, mapping) {
|
|
124
|
-
const result = {};
|
|
125
|
+
const result: Record<string, any> = {};
|
|
125
126
|
mapProps(config, result, mapping);
|
|
126
127
|
result.highlightColor = config.visConfig.enable3d ? [255, 255, 255, 60] : [252, 242, 26, 255];
|
|
127
128
|
return result;
|
|
@@ -137,7 +138,7 @@ function createChannelProps(visualChannels, type, config, data) {
|
|
|
137
138
|
heightScale = sizeScale;
|
|
138
139
|
}
|
|
139
140
|
const {textLabel, visConfig} = config;
|
|
140
|
-
const result = {};
|
|
141
|
+
const result: Record<string, any> = {};
|
|
141
142
|
const textLabelField = textLabel && textLabel.field;
|
|
142
143
|
if (colorField) {
|
|
143
144
|
result.getFillColor = getColorAccessor(
|
package/src/basemap.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const baseUrl = 'https://basemaps.cartocdn.com/gl/{basemap}-gl-style/style.json';
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
VOYAGER: baseUrl.replace('{basemap}', 'voyager'),
|
|
5
|
+
POSITRON: baseUrl.replace('{basemap}', 'positron'),
|
|
6
|
+
DARK_MATTER: baseUrl.replace('{basemap}', 'dark-matter'),
|
|
7
|
+
VOYAGER_NOLABELS: baseUrl.replace('{basemap}', 'voyager-nolabels'),
|
|
8
|
+
POSITRON_NOLABELS: baseUrl.replace('{basemap}', 'positron-nolabels'),
|
|
9
|
+
DARK_MATTER_NOLABELS: baseUrl.replace('{basemap}', 'dark-matter-nolabels')
|
|
10
|
+
} as const;
|
|
@@ -4,17 +4,33 @@ export const defaultClassicCredentials = {
|
|
|
4
4
|
apiKey: 'default_public',
|
|
5
5
|
region: 'us',
|
|
6
6
|
username: 'public'
|
|
7
|
-
};
|
|
7
|
+
} as const;
|
|
8
8
|
|
|
9
9
|
export const defaultCloudNativeCredentials = {
|
|
10
10
|
apiBaseUrl: 'https://gcp-us-east1.api.carto.com'
|
|
11
|
-
};
|
|
11
|
+
} as const;
|
|
12
|
+
|
|
13
|
+
export interface ClassicCredentials {
|
|
14
|
+
apiVersion: 'v1' | 'v2';
|
|
15
|
+
apiKey: string;
|
|
16
|
+
region: string;
|
|
17
|
+
username: string;
|
|
18
|
+
mapsUrl?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CloudNativeCredentials {
|
|
22
|
+
apiVersion: 'v3';
|
|
23
|
+
apiBaseUrl: string;
|
|
24
|
+
accessToken?: string;
|
|
25
|
+
mapsUrl?: string;
|
|
26
|
+
}
|
|
12
27
|
|
|
13
|
-
|
|
28
|
+
export type Credentials = ClassicCredentials | CloudNativeCredentials;
|
|
29
|
+
let credentials: Credentials = {} as Credentials;
|
|
14
30
|
|
|
15
31
|
setDefaultCredentials({});
|
|
16
32
|
|
|
17
|
-
export function setDefaultCredentials({apiVersion, ...rest}) {
|
|
33
|
+
export function setDefaultCredentials({apiVersion, ...rest}: Partial<Credentials>) {
|
|
18
34
|
apiVersion = apiVersion || API_VERSIONS.V3;
|
|
19
35
|
|
|
20
36
|
switch (apiVersion) {
|
|
@@ -30,11 +46,11 @@ export function setDefaultCredentials({apiVersion, ...rest}) {
|
|
|
30
46
|
}
|
|
31
47
|
}
|
|
32
48
|
|
|
33
|
-
export function getDefaultCredentials() {
|
|
49
|
+
export function getDefaultCredentials(): Credentials {
|
|
34
50
|
return credentials;
|
|
35
51
|
}
|
|
36
52
|
|
|
37
|
-
export function buildMapsUrlFromBase(apiBaseUrl) {
|
|
53
|
+
export function buildMapsUrlFromBase(apiBaseUrl: string): string {
|
|
38
54
|
let suffix = '/v3/maps';
|
|
39
55
|
if (apiBaseUrl.endsWith('/')) {
|
|
40
56
|
suffix = suffix.substring(1);
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
export {getDefaultCredentials, setDefaultCredentials} from './config
|
|
1
|
+
export {getDefaultCredentials, setDefaultCredentials} from './config';
|
|
2
2
|
export {default as CartoLayer} from './layers/carto-layer';
|
|
3
|
+
export {default as _CartoTileLayer} from './layers/carto-tile-layer';
|
|
3
4
|
export {default as BASEMAP} from './basemap';
|
|
4
5
|
export {default as colorBins} from './style/color-bins-style';
|
|
5
6
|
export {default as colorCategories} from './style/color-categories-style';
|
|
6
7
|
export {default as colorContinuous} from './style/color-continuous-style';
|
|
7
8
|
export {
|
|
8
9
|
FORMATS,
|
|
10
|
+
TILE_FORMATS,
|
|
9
11
|
MAP_TYPES,
|
|
10
12
|
API_VERSIONS,
|
|
11
13
|
fetchLayerData,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {CompositeLayer, log} from '@deck.gl/core';
|
|
2
|
-
import
|
|
2
|
+
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} from '../api/maps-api-common';
|
|
6
|
+
import {FORMATS, MAP_TYPES, TILE_FORMATS} from '../api/maps-api-common';
|
|
7
7
|
import {getDefaultCredentials} from '../config';
|
|
8
8
|
|
|
9
9
|
const defaultProps = {
|
|
@@ -27,6 +27,9 @@ const defaultProps = {
|
|
|
27
27
|
// (String, optional): format of data
|
|
28
28
|
format: null,
|
|
29
29
|
|
|
30
|
+
// (String, optional): force format of data for tiles
|
|
31
|
+
formatTiles: null,
|
|
32
|
+
|
|
30
33
|
// (String, optional): clientId identifier used for internal tracing, place here a string to identify the client who is doing the request.
|
|
31
34
|
clientId: null,
|
|
32
35
|
|
|
@@ -123,29 +126,37 @@ export default class CartoLayer extends CompositeLayer {
|
|
|
123
126
|
}
|
|
124
127
|
}
|
|
125
128
|
|
|
126
|
-
|
|
129
|
+
_getRenderLayer() {
|
|
127
130
|
const {data, format, apiVersion} = this.state;
|
|
128
131
|
|
|
129
|
-
if (
|
|
132
|
+
if (apiVersion === API_VERSIONS.V1 || apiVersion === API_VERSIONS.V2) {
|
|
133
|
+
return MVTLayer;
|
|
134
|
+
}
|
|
130
135
|
|
|
131
|
-
|
|
136
|
+
if (format === FORMATS.TILEJSON) {
|
|
137
|
+
/* global URL */
|
|
138
|
+
const formatTiles =
|
|
139
|
+
this.props.formatTiles ||
|
|
140
|
+
new URL(data.tiles[0]).searchParams.get('formatTiles') ||
|
|
141
|
+
TILE_FORMATS.MVT;
|
|
142
|
+
return formatTiles === TILE_FORMATS.MVT ? MVTLayer : CartoTileLayer;
|
|
143
|
+
}
|
|
132
144
|
|
|
133
|
-
|
|
145
|
+
// It's a geojson layer
|
|
146
|
+
return GeoJsonLayer;
|
|
147
|
+
}
|
|
134
148
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
} else {
|
|
144
|
-
layer = GeoJsonLayer;
|
|
145
|
-
}
|
|
149
|
+
renderLayers() {
|
|
150
|
+
const {data} = this.state;
|
|
151
|
+
|
|
152
|
+
if (!data) return null;
|
|
153
|
+
|
|
154
|
+
const {updateTriggers} = this.props;
|
|
155
|
+
|
|
156
|
+
const layer = this._getRenderLayer();
|
|
146
157
|
|
|
147
|
-
const {uniqueIdProperty} = defaultProps;
|
|
148
|
-
const props = {uniqueIdProperty, ...this.props};
|
|
158
|
+
const {formatTiles, uniqueIdProperty} = defaultProps;
|
|
159
|
+
const props = {formatTiles, uniqueIdProperty, ...this.props};
|
|
149
160
|
delete props.data;
|
|
150
161
|
|
|
151
162
|
// eslint-disable-next-line new-cap
|