@deck.gl/carto 8.7.7 → 8.8.0-alpha.2
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 +32922 -40161
- package/dist/es5/api/layer-map.js +43 -16
- package/dist/es5/api/layer-map.js.map +1 -1
- package/dist/es5/api/maps-api-common.js.map +1 -1
- package/dist/es5/api/maps-v3-client.js +56 -31
- package/dist/es5/api/maps-v3-client.js.map +1 -1
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/layers/carto-layer.js +22 -12
- package/dist/es5/layers/carto-layer.js.map +1 -1
- package/dist/esm/api/layer-map.js +27 -6
- package/dist/esm/api/layer-map.js.map +1 -1
- package/dist/esm/api/maps-api-common.js.map +1 -1
- package/dist/esm/api/maps-v3-client.js +58 -30
- package/dist/esm/api/maps-v3-client.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/layers/carto-layer.js +23 -7
- package/dist/esm/layers/carto-layer.js.map +1 -1
- package/dist.min.js +4 -4
- package/package.json +9 -8
- package/src/api/layer-map.ts +32 -6
- package/src/api/maps-api-common.ts +3 -3
- package/src/api/maps-v3-client.ts +78 -29
- package/src/index.ts +2 -0
- package/src/layers/{carto-layer.js → carto-layer.ts} +147 -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.
|
|
5
|
+
"version": "8.8.0-alpha.2",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
"prepublishOnly": "npm run build-bundle && npm run build-bundle -- --env.dev"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@loaders.gl/gis": "^3.
|
|
35
|
-
"@loaders.gl/loader-utils": "^3.
|
|
36
|
-
"@loaders.gl/mvt": "^3.
|
|
37
|
-
"@loaders.gl/tiles": "^3.
|
|
34
|
+
"@loaders.gl/gis": "^3.2.0-alpha.4",
|
|
35
|
+
"@loaders.gl/loader-utils": "^3.2.0-alpha.4",
|
|
36
|
+
"@loaders.gl/mvt": "^3.2.0-alpha.4",
|
|
37
|
+
"@loaders.gl/tiles": "^3.2.0-alpha.4",
|
|
38
38
|
"@luma.gl/constants": "^8.5.10",
|
|
39
|
-
"@math.gl/web-mercator": "
|
|
39
|
+
"@math.gl/web-mercator": "3.6.0-alpha.5",
|
|
40
40
|
"cartocolor": "^4.0.2",
|
|
41
41
|
"d3-array": "^2.8.0",
|
|
42
42
|
"d3-color": "^2.0.0",
|
|
@@ -53,9 +53,10 @@
|
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@deck.gl/aggregation-layers": "^8.0.0",
|
|
55
55
|
"@deck.gl/core": "^8.0.0",
|
|
56
|
+
"@deck.gl/extensions": "^8.0.0",
|
|
56
57
|
"@deck.gl/geo-layers": "^8.0.0",
|
|
57
58
|
"@deck.gl/layers": "^8.0.0",
|
|
58
|
-
"@loaders.gl/core": "^3.
|
|
59
|
+
"@loaders.gl/core": "^3.0.0"
|
|
59
60
|
},
|
|
60
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "a52215449dff06fb683f5afd6399526353d11f35"
|
|
61
62
|
}
|
package/src/api/layer-map.ts
CHANGED
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
scalePoint,
|
|
8
8
|
scaleQuantile,
|
|
9
9
|
scaleQuantize,
|
|
10
|
-
scaleSqrt
|
|
10
|
+
scaleSqrt,
|
|
11
|
+
scaleThreshold
|
|
11
12
|
} from 'd3-scale';
|
|
12
13
|
import {format as d3Format} from 'd3-format';
|
|
13
14
|
import moment from 'moment-timezone';
|
|
@@ -27,10 +28,13 @@ const SCALE_FUNCS = {
|
|
|
27
28
|
point: scalePoint,
|
|
28
29
|
quantile: scaleQuantile,
|
|
29
30
|
quantize: scaleQuantize,
|
|
30
|
-
sqrt: scaleSqrt
|
|
31
|
+
sqrt: scaleSqrt,
|
|
32
|
+
custom: scaleThreshold
|
|
31
33
|
};
|
|
32
34
|
export type SCALE_TYPE = keyof typeof SCALE_FUNCS;
|
|
33
35
|
|
|
36
|
+
const UNKNOWN_COLOR = '#868d91';
|
|
37
|
+
|
|
34
38
|
export const AGGREGATION = {
|
|
35
39
|
average: 'MEAN',
|
|
36
40
|
maximum: 'MAX',
|
|
@@ -179,7 +183,11 @@ function domainFromAttribute(attribute, scaleType: SCALE_TYPE) {
|
|
|
179
183
|
|
|
180
184
|
function domainFromValues(values, scaleType: SCALE_TYPE) {
|
|
181
185
|
if (scaleType === 'ordinal') {
|
|
182
|
-
return
|
|
186
|
+
return groupSort(
|
|
187
|
+
values,
|
|
188
|
+
g => -g.length,
|
|
189
|
+
d => d
|
|
190
|
+
);
|
|
183
191
|
} else if (scaleType === 'quantile') {
|
|
184
192
|
return values.sort((a, b) => a - b);
|
|
185
193
|
} else if (scaleType === 'log') {
|
|
@@ -226,13 +234,31 @@ export function getColorValueAccessor({name}, colorAggregation, data: any) {
|
|
|
226
234
|
export function getColorAccessor(
|
|
227
235
|
{name},
|
|
228
236
|
scaleType: SCALE_TYPE,
|
|
229
|
-
{colors},
|
|
237
|
+
{colors, colorMap},
|
|
230
238
|
opacity: number | undefined,
|
|
231
239
|
data: any
|
|
232
240
|
) {
|
|
233
241
|
const scale = SCALE_FUNCS[scaleType as any]();
|
|
234
|
-
|
|
235
|
-
|
|
242
|
+
let domain: (string | number)[] = [];
|
|
243
|
+
let scaleColor: string[] = [];
|
|
244
|
+
|
|
245
|
+
if (Array.isArray(colorMap)) {
|
|
246
|
+
colorMap.forEach(([value, color]) => {
|
|
247
|
+
domain.push(value);
|
|
248
|
+
scaleColor.push(color);
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
domain = calculateDomain(data, name, scaleType);
|
|
252
|
+
scaleColor = colors;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (scaleType === 'ordinal') {
|
|
256
|
+
domain = domain.slice(0, scaleColor.length);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
scale.domain(domain);
|
|
260
|
+
scale.range(scaleColor);
|
|
261
|
+
scale.unknown(UNKNOWN_COLOR);
|
|
236
262
|
const alpha = opacity !== undefined ? Math.round(255 * Math.pow(opacity, 1 / 2.2)) : 255;
|
|
237
263
|
|
|
238
264
|
const accessor = properties => {
|
|
@@ -20,8 +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
|
+
export const COLUMNS_SUPPORT: MapType[] = [MAP_TYPES.TABLE];
|
|
24
|
+
export const GEO_COLUMN_SUPPORT: MapType[] = [MAP_TYPES.QUERY, MAP_TYPES.TABLE];
|
|
25
25
|
|
|
26
26
|
// AVAILABLE FORMATS
|
|
27
27
|
export const FORMATS = {
|
|
@@ -59,7 +59,7 @@ export interface SchemaField {
|
|
|
59
59
|
export interface MapInstantiation extends MapInstantiationFormats {
|
|
60
60
|
nrows: number;
|
|
61
61
|
size?: number;
|
|
62
|
-
schema
|
|
62
|
+
schema: SchemaField[];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
type MapInstantiationFormats = Record<
|
|
@@ -112,10 +112,11 @@ type FetchLayerDataParams = {
|
|
|
112
112
|
credentials: CloudNativeCredentials;
|
|
113
113
|
geoColumn?: string;
|
|
114
114
|
columns?: string[];
|
|
115
|
-
schema?: boolean;
|
|
116
115
|
clientId?: string;
|
|
117
116
|
format?: Format;
|
|
118
117
|
formatTiles?: TileFormat;
|
|
118
|
+
aggregationExp?: string;
|
|
119
|
+
aggregationResLevel?: number;
|
|
119
120
|
};
|
|
120
121
|
|
|
121
122
|
/**
|
|
@@ -126,23 +127,27 @@ function getParameters({
|
|
|
126
127
|
source,
|
|
127
128
|
geoColumn,
|
|
128
129
|
columns,
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
clientId,
|
|
131
|
+
aggregationExp,
|
|
132
|
+
aggregationResLevel
|
|
131
133
|
}: Omit<FetchLayerDataParams, 'connection' | 'credentials'>) {
|
|
132
134
|
const parameters = [encodeParameter('client', clientId || DEFAULT_CLIENT)];
|
|
133
|
-
if (schema) {
|
|
134
|
-
parameters.push(encodeParameter('schema', true));
|
|
135
|
-
}
|
|
136
135
|
|
|
137
136
|
const sourceName = type === MAP_TYPES.QUERY ? 'q' : 'name';
|
|
138
137
|
parameters.push(encodeParameter(sourceName, source));
|
|
139
138
|
|
|
140
|
-
if (
|
|
139
|
+
if (geoColumn) {
|
|
141
140
|
parameters.push(encodeParameter('geo_column', geoColumn));
|
|
142
141
|
}
|
|
143
|
-
if (
|
|
142
|
+
if (columns) {
|
|
144
143
|
parameters.push(encodeParameter('columns', columns.join(',')));
|
|
145
144
|
}
|
|
145
|
+
if (aggregationExp) {
|
|
146
|
+
parameters.push(encodeParameter('aggregationExp', aggregationExp));
|
|
147
|
+
}
|
|
148
|
+
if (aggregationResLevel) {
|
|
149
|
+
parameters.push(encodeParameter('aggregationResLevel', aggregationResLevel));
|
|
150
|
+
}
|
|
146
151
|
|
|
147
152
|
return parameters.join('&');
|
|
148
153
|
}
|
|
@@ -154,11 +159,20 @@ export async function mapInstantiation({
|
|
|
154
159
|
credentials,
|
|
155
160
|
geoColumn,
|
|
156
161
|
columns,
|
|
157
|
-
|
|
158
|
-
|
|
162
|
+
clientId,
|
|
163
|
+
aggregationExp,
|
|
164
|
+
aggregationResLevel
|
|
159
165
|
}: FetchLayerDataParams): Promise<MapInstantiation> {
|
|
160
166
|
const baseUrl = `${credentials.mapsUrl}/${connection}/${type}`;
|
|
161
|
-
const url = `${baseUrl}?${getParameters({
|
|
167
|
+
const url = `${baseUrl}?${getParameters({
|
|
168
|
+
type,
|
|
169
|
+
source,
|
|
170
|
+
geoColumn,
|
|
171
|
+
columns,
|
|
172
|
+
clientId,
|
|
173
|
+
aggregationExp,
|
|
174
|
+
aggregationResLevel
|
|
175
|
+
})}`;
|
|
162
176
|
const {accessToken} = credentials;
|
|
163
177
|
|
|
164
178
|
if (url.length > MAX_GET_LENGTH && type === MAP_TYPES.QUERY) {
|
|
@@ -187,7 +201,11 @@ function checkFetchLayerDataParameters({
|
|
|
187
201
|
type,
|
|
188
202
|
source,
|
|
189
203
|
connection,
|
|
190
|
-
credentials
|
|
204
|
+
credentials,
|
|
205
|
+
geoColumn,
|
|
206
|
+
columns,
|
|
207
|
+
aggregationExp,
|
|
208
|
+
aggregationResLevel
|
|
191
209
|
}: FetchLayerDataParams) {
|
|
192
210
|
assert(connection, 'Must define connection');
|
|
193
211
|
assert(type, 'Must define a type');
|
|
@@ -196,12 +214,35 @@ function checkFetchLayerDataParameters({
|
|
|
196
214
|
assert(credentials.apiVersion === API_VERSIONS.V3, 'Method only available for v3');
|
|
197
215
|
assert(credentials.apiBaseUrl, 'Must define apiBaseUrl');
|
|
198
216
|
assert(credentials.accessToken, 'Must define an accessToken');
|
|
217
|
+
|
|
218
|
+
if (columns) {
|
|
219
|
+
assert(
|
|
220
|
+
COLUMNS_SUPPORT.includes(type),
|
|
221
|
+
`The columns parameter is not supported by type ${type}`
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
if (geoColumn) {
|
|
225
|
+
assert(
|
|
226
|
+
GEO_COLUMN_SUPPORT.includes(type),
|
|
227
|
+
`The geoColumn parameter is not supported by type ${type}`
|
|
228
|
+
);
|
|
229
|
+
} else {
|
|
230
|
+
assert(!aggregationExp, 'Have aggregationExp, but geoColumn parameter is missing');
|
|
231
|
+
assert(!aggregationResLevel, 'Have aggregationResLevel, but geoColumn parameter is missing');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (!aggregationExp) {
|
|
235
|
+
assert(
|
|
236
|
+
!aggregationResLevel,
|
|
237
|
+
'Have aggregationResLevel, but aggregationExp parameter is missing'
|
|
238
|
+
);
|
|
239
|
+
}
|
|
199
240
|
}
|
|
200
241
|
|
|
201
242
|
export interface FetchLayerDataResult {
|
|
202
243
|
data: any;
|
|
203
|
-
format
|
|
204
|
-
schema
|
|
244
|
+
format?: Format;
|
|
245
|
+
schema: SchemaField[];
|
|
205
246
|
}
|
|
206
247
|
export async function fetchLayerData({
|
|
207
248
|
type,
|
|
@@ -212,8 +253,9 @@ export async function fetchLayerData({
|
|
|
212
253
|
columns,
|
|
213
254
|
format,
|
|
214
255
|
formatTiles,
|
|
215
|
-
|
|
216
|
-
|
|
256
|
+
clientId,
|
|
257
|
+
aggregationExp,
|
|
258
|
+
aggregationResLevel
|
|
217
259
|
}: FetchLayerDataParams): Promise<FetchLayerDataResult> {
|
|
218
260
|
// Internally we split data fetching into two parts to allow us to
|
|
219
261
|
// conditionally fetch the actual data, depending on the metadata state
|
|
@@ -226,16 +268,13 @@ export async function fetchLayerData({
|
|
|
226
268
|
columns,
|
|
227
269
|
format,
|
|
228
270
|
formatTiles,
|
|
229
|
-
|
|
230
|
-
|
|
271
|
+
clientId,
|
|
272
|
+
aggregationExp,
|
|
273
|
+
aggregationResLevel
|
|
231
274
|
});
|
|
232
275
|
|
|
233
276
|
const data = await requestData({url, format: mapFormat, accessToken});
|
|
234
|
-
const result: FetchLayerDataResult = {data, format: mapFormat};
|
|
235
|
-
if (schema) {
|
|
236
|
-
result.schema = metadata.schema;
|
|
237
|
-
}
|
|
238
|
-
|
|
277
|
+
const result: FetchLayerDataResult = {data, format: mapFormat, schema: metadata.schema};
|
|
239
278
|
return result;
|
|
240
279
|
}
|
|
241
280
|
|
|
@@ -248,8 +287,9 @@ async function _fetchDataUrl({
|
|
|
248
287
|
columns,
|
|
249
288
|
format,
|
|
250
289
|
formatTiles,
|
|
251
|
-
|
|
252
|
-
|
|
290
|
+
clientId,
|
|
291
|
+
aggregationExp,
|
|
292
|
+
aggregationResLevel
|
|
253
293
|
}: FetchLayerDataParams) {
|
|
254
294
|
const defaultCredentials = getDefaultCredentials();
|
|
255
295
|
// Only pick up default credentials if they have been defined for
|
|
@@ -258,7 +298,16 @@ async function _fetchDataUrl({
|
|
|
258
298
|
...(defaultCredentials.apiVersion === API_VERSIONS.V3 && defaultCredentials),
|
|
259
299
|
...credentials
|
|
260
300
|
};
|
|
261
|
-
checkFetchLayerDataParameters({
|
|
301
|
+
checkFetchLayerDataParameters({
|
|
302
|
+
type,
|
|
303
|
+
source,
|
|
304
|
+
connection,
|
|
305
|
+
credentials: localCreds,
|
|
306
|
+
geoColumn,
|
|
307
|
+
columns,
|
|
308
|
+
aggregationExp,
|
|
309
|
+
aggregationResLevel
|
|
310
|
+
});
|
|
262
311
|
|
|
263
312
|
if (!localCreds.mapsUrl) {
|
|
264
313
|
localCreds.mapsUrl = buildMapsUrlFromBase(localCreds.apiBaseUrl);
|
|
@@ -271,8 +320,9 @@ async function _fetchDataUrl({
|
|
|
271
320
|
credentials: localCreds,
|
|
272
321
|
geoColumn,
|
|
273
322
|
columns,
|
|
274
|
-
|
|
275
|
-
|
|
323
|
+
clientId,
|
|
324
|
+
aggregationExp,
|
|
325
|
+
aggregationResLevel
|
|
276
326
|
});
|
|
277
327
|
let url: string | null = null;
|
|
278
328
|
let mapFormat: Format | undefined;
|
|
@@ -325,7 +375,6 @@ export async function getData({
|
|
|
325
375
|
geoColumn,
|
|
326
376
|
columns,
|
|
327
377
|
format,
|
|
328
|
-
schema: false,
|
|
329
378
|
clientId
|
|
330
379
|
});
|
|
331
380
|
return layerData.data;
|
package/src/index.ts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
|
-
import {CompositeLayer, log} from '@deck.gl/core';
|
|
1
|
+
import {CompositeLayer, Layer, log} from '@deck.gl/core';
|
|
2
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
6
|
import {
|
|
7
7
|
COLUMNS_SUPPORT,
|
|
8
|
+
Format,
|
|
8
9
|
FORMATS,
|
|
9
10
|
GEO_COLUMN_SUPPORT,
|
|
11
|
+
MapType,
|
|
10
12
|
MAP_TYPES,
|
|
13
|
+
TileFormat,
|
|
11
14
|
TILE_FORMATS
|
|
12
15
|
} from '../api/maps-api-common';
|
|
13
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
ClassicCredentials,
|
|
18
|
+
CloudNativeCredentials,
|
|
19
|
+
Credentials,
|
|
20
|
+
getDefaultCredentials
|
|
21
|
+
} from '../config';
|
|
22
|
+
import {CompositeLayerProps, LayerProps} from 'modules/core/src/types/layer-props';
|
|
23
|
+
import {ChangeFlags} from 'modules/core/src/lib/layer-state';
|
|
24
|
+
import {FetchLayerDataResult} from '../api/maps-v3-client';
|
|
25
|
+
import {assert} from '../utils';
|
|
14
26
|
|
|
15
27
|
const defaultProps = {
|
|
16
28
|
// (String, required): data resource to load. table name, sql query or tileset name.
|
|
@@ -46,19 +58,105 @@ const defaultProps = {
|
|
|
46
58
|
columns: {type: 'array', value: null}
|
|
47
59
|
};
|
|
48
60
|
|
|
49
|
-
export
|
|
50
|
-
|
|
61
|
+
export interface CartoLayerProps<DataT = any> extends CompositeLayerProps<DataT> {
|
|
62
|
+
/**
|
|
63
|
+
* Either a SQL query or a name of dataset/tileset.
|
|
64
|
+
*/
|
|
65
|
+
data: string;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Data type.
|
|
69
|
+
*
|
|
70
|
+
* Possible values are:
|
|
71
|
+
* * `MAP_TYPES.QUERY`, if data is a SQL query.
|
|
72
|
+
* * `MAP_TYPES.TILESET`, if data is a tileset name.
|
|
73
|
+
* * `MAP_TYPES.TABLE`, if data is a dataset name. Only supported with API v3.
|
|
74
|
+
*/
|
|
75
|
+
type: MapType;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Name of the connection registered in the CARTO workspace.
|
|
79
|
+
*
|
|
80
|
+
* Required when apiVersion is `API_VERSIONS.V3`.
|
|
81
|
+
*/
|
|
82
|
+
connection?: string;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Use to override the default data format.
|
|
86
|
+
*
|
|
87
|
+
* Only supported when apiVersion is `API_VERSIONS.V3`.
|
|
88
|
+
*
|
|
89
|
+
* Possible values are: `FORMATS.GEOJSON`, `FORMATS.JSON` and `FORMATS.TILEJSON`.
|
|
90
|
+
*/
|
|
91
|
+
format?: Format;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Use to override the default tile data format.
|
|
95
|
+
*
|
|
96
|
+
* Only supported when apiVersion is `API_VERSIONS.V3` and format is `FORMATS.TILEJSON`.
|
|
97
|
+
*
|
|
98
|
+
* Possible values are: `TILE_FORMATS.BINARY`, `TILE_FORMATS.GEOJSON` and `TILE_FORMATS.MVT`.
|
|
99
|
+
*/
|
|
100
|
+
formatTiles?: TileFormat;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Name of the geo_column in the CARTO platform.
|
|
104
|
+
*
|
|
105
|
+
* Use this override the default column (`'geom'`), from which the geometry information should be fetched.
|
|
106
|
+
*
|
|
107
|
+
* Only supported when apiVersion is `API_VERSIONS.V3` and type is `MAP_TYPES.TABLE`.
|
|
108
|
+
*/
|
|
109
|
+
geoColumn?: string;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Names of columns to fetch.
|
|
113
|
+
*
|
|
114
|
+
* By default, all columns are fetched
|
|
115
|
+
*
|
|
116
|
+
* Only supported when apiVersion is `API_VERSIONS.V3` and type is `MAP_TYPES.TABLE`.
|
|
117
|
+
*/
|
|
118
|
+
columns?: string[];
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* A string pointing to a unique attribute at the result of the query.
|
|
122
|
+
*
|
|
123
|
+
* A unique attribute is needed for highlighting with vector tiles when a feature is split across two or more tiles.
|
|
124
|
+
*/
|
|
125
|
+
uniqueIdProperty?: string;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Optional. Overrides the configuration to connect with CARTO.
|
|
129
|
+
*
|
|
130
|
+
* @see Credentials
|
|
131
|
+
*/
|
|
132
|
+
credentials?: Credentials;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Called when the request to the CARTO Maps API failed.
|
|
136
|
+
*
|
|
137
|
+
* By default the Error is thrown.
|
|
138
|
+
*/
|
|
139
|
+
onDataError?: (err: unknown) => void;
|
|
140
|
+
|
|
141
|
+
clientId?: string;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export default class CartoLayer<DataT = any> extends CompositeLayer<CartoLayerProps<DataT>> {
|
|
145
|
+
static layerName = 'CartoLayer';
|
|
146
|
+
static defaultProps = defaultProps as any;
|
|
147
|
+
|
|
148
|
+
initializeState(): void {
|
|
51
149
|
this.state = {
|
|
52
150
|
data: null,
|
|
53
151
|
apiVersion: null
|
|
54
152
|
};
|
|
55
153
|
}
|
|
56
154
|
|
|
57
|
-
get isLoaded() {
|
|
155
|
+
get isLoaded(): boolean {
|
|
58
156
|
return this.getSubLayers().length > 0 && super.isLoaded;
|
|
59
157
|
}
|
|
60
158
|
|
|
61
|
-
_checkProps(props) {
|
|
159
|
+
_checkProps(props: CartoLayerProps): void {
|
|
62
160
|
const {type, credentials, connection, geoColumn, columns} = props;
|
|
63
161
|
const localCreds = {...getDefaultCredentials(), ...credentials};
|
|
64
162
|
const {apiVersion} = localCreds;
|
|
@@ -97,7 +195,16 @@ export default class CartoLayer extends CompositeLayer {
|
|
|
97
195
|
}
|
|
98
196
|
}
|
|
99
197
|
|
|
100
|
-
updateState({
|
|
198
|
+
updateState({
|
|
199
|
+
props,
|
|
200
|
+
oldProps,
|
|
201
|
+
changeFlags
|
|
202
|
+
}: {
|
|
203
|
+
props: CartoLayerProps;
|
|
204
|
+
oldProps: CartoLayerProps;
|
|
205
|
+
context: any;
|
|
206
|
+
changeFlags: ChangeFlags;
|
|
207
|
+
}): void {
|
|
101
208
|
this._checkProps(props);
|
|
102
209
|
const shouldUpdateData =
|
|
103
210
|
changeFlags.dataChanged ||
|
|
@@ -111,40 +218,57 @@ export default class CartoLayer extends CompositeLayer {
|
|
|
111
218
|
|
|
112
219
|
if (shouldUpdateData) {
|
|
113
220
|
this.setState({data: null, apiVersion: null});
|
|
221
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
114
222
|
this._updateData();
|
|
115
223
|
}
|
|
116
224
|
}
|
|
117
225
|
|
|
118
|
-
async _updateData() {
|
|
226
|
+
async _updateData(): Promise<void> {
|
|
119
227
|
try {
|
|
120
|
-
const {type, data: source, clientId, credentials, ...rest} = this.props;
|
|
228
|
+
const {type, data: source, clientId, credentials, connection, ...rest} = this.props;
|
|
121
229
|
const localConfig = {...getDefaultCredentials(), ...credentials};
|
|
122
230
|
const {apiVersion} = localConfig;
|
|
123
231
|
|
|
124
|
-
let result;
|
|
232
|
+
let result: FetchLayerDataResult;
|
|
125
233
|
if (apiVersion === API_VERSIONS.V1 || apiVersion === API_VERSIONS.V2) {
|
|
126
|
-
result = {
|
|
234
|
+
result = {
|
|
235
|
+
data: await getDataV2({type, source, credentials: credentials as ClassicCredentials})
|
|
236
|
+
};
|
|
127
237
|
} else {
|
|
128
|
-
result = await fetchLayerData({
|
|
238
|
+
result = await fetchLayerData({
|
|
239
|
+
type,
|
|
240
|
+
source,
|
|
241
|
+
clientId,
|
|
242
|
+
credentials: credentials as CloudNativeCredentials,
|
|
243
|
+
connection: connection as string,
|
|
244
|
+
...rest
|
|
245
|
+
});
|
|
129
246
|
}
|
|
130
247
|
|
|
131
248
|
this.setState({...result, apiVersion});
|
|
132
|
-
|
|
249
|
+
|
|
250
|
+
this.props.onDataLoad?.(result.data, {
|
|
251
|
+
propName: 'data',
|
|
252
|
+
layer: this
|
|
253
|
+
});
|
|
133
254
|
} catch (err) {
|
|
134
255
|
if (this.props.onDataError) {
|
|
135
|
-
this.props.onDataError(err);
|
|
256
|
+
this.props.onDataError(err as Error);
|
|
136
257
|
} else {
|
|
137
258
|
throw err;
|
|
138
259
|
}
|
|
139
260
|
}
|
|
140
261
|
}
|
|
141
262
|
|
|
142
|
-
_getSubLayerAndProps() {
|
|
263
|
+
_getSubLayerAndProps(): [any, LayerProps] {
|
|
264
|
+
assert(this.state);
|
|
265
|
+
|
|
143
266
|
const {data, format, apiVersion} = this.state;
|
|
144
267
|
|
|
145
268
|
const {uniqueIdProperty} = defaultProps;
|
|
146
|
-
|
|
147
|
-
|
|
269
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
270
|
+
const {data: _notUsed, ...propsNoData} = this.props;
|
|
271
|
+
const props = {uniqueIdProperty, ...propsNoData};
|
|
148
272
|
|
|
149
273
|
if (apiVersion === API_VERSIONS.V1 || apiVersion === API_VERSIONS.V2) {
|
|
150
274
|
return [MVTLayer, props];
|
|
@@ -155,7 +279,9 @@ export default class CartoLayer extends CompositeLayer {
|
|
|
155
279
|
const tileUrl = new URL(data.tiles[0]);
|
|
156
280
|
|
|
157
281
|
props.formatTiles =
|
|
158
|
-
props.formatTiles ||
|
|
282
|
+
props.formatTiles ||
|
|
283
|
+
(tileUrl.searchParams.get('formatTiles') as TileFormat) ||
|
|
284
|
+
TILE_FORMATS.MVT;
|
|
159
285
|
|
|
160
286
|
return props.formatTiles === TILE_FORMATS.MVT ? [MVTLayer, props] : [CartoTileLayer, props];
|
|
161
287
|
}
|
|
@@ -164,7 +290,9 @@ export default class CartoLayer extends CompositeLayer {
|
|
|
164
290
|
return [GeoJsonLayer, props];
|
|
165
291
|
}
|
|
166
292
|
|
|
167
|
-
renderLayers() {
|
|
293
|
+
renderLayers(): Layer | null {
|
|
294
|
+
assert(this.state);
|
|
295
|
+
|
|
168
296
|
const {data} = this.state;
|
|
169
297
|
|
|
170
298
|
if (!data) return null;
|
|
@@ -184,6 +312,3 @@ export default class CartoLayer extends CompositeLayer {
|
|
|
184
312
|
);
|
|
185
313
|
}
|
|
186
314
|
}
|
|
187
|
-
|
|
188
|
-
CartoLayer.layerName = 'CartoLayer';
|
|
189
|
-
CartoLayer.defaultProps = defaultProps;
|