@deck.gl/carto 9.0.14 → 9.0.15
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/api/basemap.d.ts +17 -0
- package/dist/api/basemap.d.ts.map +1 -0
- package/dist/api/basemap.js +76 -0
- package/dist/api/fetch-map.d.ts +10 -12
- package/dist/api/fetch-map.d.ts.map +1 -1
- package/dist/api/fetch-map.js +7 -3
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/parse-map.d.ts +21 -1
- package/dist/api/parse-map.d.ts.map +1 -1
- package/dist/api/parse-map.js +1 -0
- package/dist/api/query.d.ts.map +1 -1
- package/dist/api/query.js +4 -3
- package/dist/api/request-with-parameters.js +1 -1
- package/dist/api/types.d.ts +82 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/basemap.d.ts +17 -0
- package/dist/basemap.d.ts.map +1 -1
- package/dist/basemap.js +97 -7
- package/dist/cartoRasterTile-worker.js +1 -1
- package/dist/cartoSpatialTile-worker.js +1 -1
- package/dist/cartoVectorTile-worker.js +1 -1
- package/dist/dist.dev.js +1734 -2360
- package/dist/index.cjs +260 -82
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/layers/heatmap.d.ts +3 -2
- package/dist/layers/heatmap.d.ts.map +1 -1
- package/dist/layers/heatmap.js +18 -6
- package/dist/layers/quadbin-heatmap-tile-layer.d.ts +5 -2
- package/dist/layers/quadbin-heatmap-tile-layer.d.ts.map +1 -1
- package/dist/layers/quadbin-heatmap-tile-layer.js +3 -2
- package/dist/layers/schema/carto-raster-tile-loader.js +1 -1
- package/dist/layers/schema/carto-spatial-tile-loader.js +1 -1
- package/dist/layers/schema/carto-vector-tile-loader.js +1 -1
- package/dist/utils.d.ts +2 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +2 -0
- package/dist.min.js +21 -15
- package/package.json +6 -6
- package/src/api/basemap.ts +100 -0
- package/src/api/fetch-map.ts +20 -6
- package/src/api/index.ts +11 -2
- package/src/api/parse-map.ts +24 -3
- package/src/api/query.ts +4 -2
- package/src/api/request-with-parameters.ts +1 -1
- package/src/api/types.ts +103 -1
- package/src/basemap.ts +134 -7
- package/src/index.ts +14 -2
- package/src/layers/heatmap.ts +23 -8
- package/src/layers/quadbin-heatmap-tile-layer.ts +8 -5
- package/src/utils.ts +5 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "CARTO official integration with Deck.gl. Build geospatial applications using CARTO and Deck.gl.",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "9.0.
|
|
6
|
+
"version": "9.0.15",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"@loaders.gl/mvt": "^4.2.0",
|
|
48
48
|
"@loaders.gl/schema": "^4.2.0",
|
|
49
49
|
"@loaders.gl/tiles": "^4.2.0",
|
|
50
|
-
"@luma.gl/constants": "^9.0.
|
|
51
|
-
"@luma.gl/core": "^9.0.
|
|
52
|
-
"@luma.gl/shadertools": "^9.0.
|
|
50
|
+
"@luma.gl/constants": "^9.0.14",
|
|
51
|
+
"@luma.gl/core": "^9.0.14",
|
|
52
|
+
"@luma.gl/shadertools": "^9.0.14",
|
|
53
53
|
"@math.gl/web-mercator": "^4.0.0",
|
|
54
54
|
"@types/d3-array": "^3.0.2",
|
|
55
55
|
"@types/d3-color": "^1.4.2",
|
|
56
56
|
"@types/d3-scale": "^3.0.0",
|
|
57
|
-
"cartocolor": "^
|
|
57
|
+
"cartocolor": "^5.0.2",
|
|
58
58
|
"d3-array": "^3.2.0",
|
|
59
59
|
"d3-color": "^3.1.0",
|
|
60
60
|
"d3-format": "^3.1.0",
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"@deck.gl/layers": "^9.0.0",
|
|
74
74
|
"@loaders.gl/core": "^4.2.0"
|
|
75
75
|
},
|
|
76
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "4eecc3c070efa04baecc83b3d5f4ddacb4ba147c"
|
|
77
77
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {MapViewState} from '@deck.gl/core';
|
|
2
|
+
import {
|
|
3
|
+
GOOGLE_BASEMAPS,
|
|
4
|
+
CARTO_MAP_STYLES,
|
|
5
|
+
applyLayerGroupFilters,
|
|
6
|
+
fetchStyle,
|
|
7
|
+
getStyleUrl,
|
|
8
|
+
someLayerGroupsDisabled
|
|
9
|
+
} from '../basemap';
|
|
10
|
+
import {APIErrorContext, Basemap, KeplerMapConfig, MapLibreBasemapProps} from './types';
|
|
11
|
+
|
|
12
|
+
const CUSTOM_STYLE_ID_PREFIX = 'custom:';
|
|
13
|
+
const DEFAULT_CARTO_STYLE = 'positron';
|
|
14
|
+
|
|
15
|
+
function mapLibreViewpros(config: KeplerMapConfig): Omit<MapLibreBasemapProps, 'style'> {
|
|
16
|
+
const {longitude, latitude, ...rest} = config.mapState as MapViewState;
|
|
17
|
+
return {
|
|
18
|
+
center: [longitude, latitude],
|
|
19
|
+
...rest
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get basemap properties for Carto map.
|
|
25
|
+
*
|
|
26
|
+
* For maplibre-based basemaps it returns style or style URL that can be used with `maplibregl.Map` compatible component.
|
|
27
|
+
* * style url is returned for non-filtered standard Carto basemaps or if user used style URL directly in configuration
|
|
28
|
+
* * filtered style object returned for Carto basemaps with layer groups filtered
|
|
29
|
+
*
|
|
30
|
+
* For Google-maps base maps, it returns options that can be used with `google.maps.Map` constructor.
|
|
31
|
+
*/
|
|
32
|
+
export async function fetchBasemapProps({
|
|
33
|
+
config,
|
|
34
|
+
errorContext,
|
|
35
|
+
|
|
36
|
+
applyLayerFilters = true
|
|
37
|
+
}: {
|
|
38
|
+
config: KeplerMapConfig;
|
|
39
|
+
|
|
40
|
+
/** By default `fetchBasemapProps` applies layers filters to style. Set this to `false` to disable it. */
|
|
41
|
+
applyLayerFilters?: boolean;
|
|
42
|
+
errorContext?: APIErrorContext;
|
|
43
|
+
}): Promise<Basemap | null> {
|
|
44
|
+
const {mapStyle} = config;
|
|
45
|
+
const styleType = mapStyle.styleType || DEFAULT_CARTO_STYLE;
|
|
46
|
+
if (styleType.startsWith(CUSTOM_STYLE_ID_PREFIX)) {
|
|
47
|
+
const currentCustomStyle = config.customBaseMaps?.customStyle;
|
|
48
|
+
if (currentCustomStyle) {
|
|
49
|
+
return {
|
|
50
|
+
type: 'maplibre',
|
|
51
|
+
props: {
|
|
52
|
+
style: currentCustomStyle.style || currentCustomStyle.url,
|
|
53
|
+
...mapLibreViewpros(config)
|
|
54
|
+
},
|
|
55
|
+
attribution: currentCustomStyle.customAttribution
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (CARTO_MAP_STYLES.includes(styleType)) {
|
|
61
|
+
const {visibleLayerGroups} = mapStyle;
|
|
62
|
+
const styleUrl = getStyleUrl(styleType);
|
|
63
|
+
let style = styleUrl;
|
|
64
|
+
let rawStyle = styleUrl;
|
|
65
|
+
if (applyLayerFilters && visibleLayerGroups && someLayerGroupsDisabled(visibleLayerGroups)) {
|
|
66
|
+
rawStyle = await fetchStyle({styleUrl, errorContext});
|
|
67
|
+
style = applyLayerGroupFilters(rawStyle, visibleLayerGroups);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
type: 'maplibre',
|
|
71
|
+
props: {
|
|
72
|
+
style,
|
|
73
|
+
...mapLibreViewpros(config)
|
|
74
|
+
},
|
|
75
|
+
visibleLayerGroups,
|
|
76
|
+
rawStyle
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const googleBasemapDef = GOOGLE_BASEMAPS[styleType];
|
|
80
|
+
if (googleBasemapDef) {
|
|
81
|
+
const {mapState} = config;
|
|
82
|
+
return {
|
|
83
|
+
type: 'google-maps',
|
|
84
|
+
props: {
|
|
85
|
+
...googleBasemapDef,
|
|
86
|
+
center: {lat: mapState.latitude, lng: mapState.longitude},
|
|
87
|
+
zoom: mapState.zoom + 1,
|
|
88
|
+
tilt: mapState.pitch,
|
|
89
|
+
heading: mapState.bearing
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
type: 'maplibre',
|
|
95
|
+
props: {
|
|
96
|
+
style: getStyleUrl(DEFAULT_CARTO_STYLE),
|
|
97
|
+
...mapLibreViewpros(config)
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
package/src/api/fetch-map.ts
CHANGED
|
@@ -17,10 +17,11 @@ import {
|
|
|
17
17
|
vectorTableSource,
|
|
18
18
|
vectorTilesetSource
|
|
19
19
|
} from '../sources/index';
|
|
20
|
-
import {parseMap} from './parse-map';
|
|
20
|
+
import {ParseMapResult, parseMap} from './parse-map';
|
|
21
21
|
import {requestWithParameters} from './request-with-parameters';
|
|
22
22
|
import {assert} from '../utils';
|
|
23
|
-
import type {APIErrorContext, Format, MapType, QueryParameters} from './types';
|
|
23
|
+
import type {APIErrorContext, Basemap, Format, MapType, QueryParameters} from './types';
|
|
24
|
+
import {fetchBasemapProps} from './basemap';
|
|
24
25
|
|
|
25
26
|
type Dataset = {
|
|
26
27
|
id: string;
|
|
@@ -213,6 +214,14 @@ export type FetchMapOptions = {
|
|
|
213
214
|
onNewData?: (map: any) => void;
|
|
214
215
|
};
|
|
215
216
|
|
|
217
|
+
export type FetchMapResult = ParseMapResult & {
|
|
218
|
+
/**
|
|
219
|
+
* Basemap properties.
|
|
220
|
+
*/
|
|
221
|
+
basemap: Basemap | null;
|
|
222
|
+
stopAutoRefresh?: () => void;
|
|
223
|
+
};
|
|
224
|
+
|
|
216
225
|
/* eslint-disable max-statements */
|
|
217
226
|
export async function fetchMap({
|
|
218
227
|
apiBaseUrl = DEFAULT_API_BASE_URL,
|
|
@@ -221,7 +230,7 @@ export async function fetchMap({
|
|
|
221
230
|
headers = {},
|
|
222
231
|
autoRefresh,
|
|
223
232
|
onNewData
|
|
224
|
-
}: FetchMapOptions) {
|
|
233
|
+
}: FetchMapOptions): Promise<FetchMapResult> {
|
|
225
234
|
assert(cartoMapId, 'Must define CARTO map id: fetchMap({cartoMapId: "XXXX-XXXX-XXXX"})');
|
|
226
235
|
assert(apiBaseUrl, 'Must define apiBaseUrl');
|
|
227
236
|
|
|
@@ -272,12 +281,17 @@ export async function fetchMap({
|
|
|
272
281
|
}
|
|
273
282
|
});
|
|
274
283
|
|
|
275
|
-
|
|
276
|
-
|
|
284
|
+
const [basemap] = await Promise.all([
|
|
285
|
+
fetchBasemapProps({config: map.keplerMapConfig.config, errorContext}),
|
|
286
|
+
|
|
287
|
+
// Mutates map.datasets so that dataset.data contains data
|
|
288
|
+
fillInMapDatasets(map, clientId, apiBaseUrl, headers)
|
|
289
|
+
]);
|
|
277
290
|
|
|
278
291
|
// Mutates attributes in visualChannels to contain tile stats
|
|
279
292
|
await fillInTileStats(map, apiBaseUrl);
|
|
280
|
-
|
|
293
|
+
|
|
294
|
+
const out = {...parseMap(map), basemap, ...{stopAutoRefresh}};
|
|
281
295
|
|
|
282
296
|
const textLayers = out.layers.filter(layer => {
|
|
283
297
|
const pointType = layer.props.pointType || '';
|
package/src/api/index.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
export {CartoAPIError} from './carto-api-error';
|
|
2
2
|
export {fetchMap} from './fetch-map';
|
|
3
|
-
export type {FetchMapOptions} from './fetch-map';
|
|
4
|
-
export type {
|
|
3
|
+
export type {FetchMapOptions, FetchMapResult} from './fetch-map';
|
|
4
|
+
export type {
|
|
5
|
+
APIErrorContext,
|
|
6
|
+
Format,
|
|
7
|
+
MapType,
|
|
8
|
+
RequestType,
|
|
9
|
+
QueryParameters,
|
|
10
|
+
Basemap,
|
|
11
|
+
MapLibreBasemap,
|
|
12
|
+
GoogleBasemap
|
|
13
|
+
} from './types';
|
|
5
14
|
export {query} from './query';
|
|
6
15
|
export type {QueryOptions} from './query';
|
package/src/api/parse-map.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {GL} from '@luma.gl/constants';
|
|
2
|
-
import {log} from '@deck.gl/core';
|
|
2
|
+
import {Layer, log} from '@deck.gl/core';
|
|
3
3
|
import {
|
|
4
4
|
AGGREGATION,
|
|
5
5
|
getLayer,
|
|
@@ -16,14 +16,34 @@ import {
|
|
|
16
16
|
import PointLabelLayer from '../layers/point-label-layer';
|
|
17
17
|
import {CollisionFilterExtension} from '@deck.gl/extensions';
|
|
18
18
|
import {assert} from '../utils';
|
|
19
|
-
import {MapDataset, MapLayerConfig, VisualChannels} from './types';
|
|
19
|
+
import {KeplerMapConfig, MapDataset, MapLayerConfig, VisualChannels} from './types';
|
|
20
20
|
|
|
21
21
|
const collisionFilterExtension = new CollisionFilterExtension();
|
|
22
22
|
|
|
23
|
+
export type ParseMapResult = {
|
|
24
|
+
/** Map id. */
|
|
25
|
+
id: string;
|
|
26
|
+
|
|
27
|
+
/** Title of map. */
|
|
28
|
+
title: string;
|
|
29
|
+
|
|
30
|
+
/** Description of map. */
|
|
31
|
+
description?: string;
|
|
32
|
+
createdAt: string;
|
|
33
|
+
updatedAt: string;
|
|
34
|
+
initialViewState: any;
|
|
35
|
+
|
|
36
|
+
/** @deprecated Use `basemap`. */
|
|
37
|
+
mapStyle: any;
|
|
38
|
+
token: string;
|
|
39
|
+
|
|
40
|
+
layers: Layer[];
|
|
41
|
+
};
|
|
42
|
+
|
|
23
43
|
export function parseMap(json) {
|
|
24
44
|
const {keplerMapConfig, datasets, token} = json;
|
|
25
45
|
assert(keplerMapConfig.version === 'v1', 'Only support Kepler v1');
|
|
26
|
-
const {mapState, mapStyle} = keplerMapConfig.config;
|
|
46
|
+
const {mapState, mapStyle} = keplerMapConfig.config as KeplerMapConfig;
|
|
27
47
|
const {layers, layerBlending, interactionConfig} = keplerMapConfig.config.visState;
|
|
28
48
|
|
|
29
49
|
return {
|
|
@@ -33,6 +53,7 @@ export function parseMap(json) {
|
|
|
33
53
|
createdAt: json.createdAt,
|
|
34
54
|
updatedAt: json.updatedAt,
|
|
35
55
|
initialViewState: mapState,
|
|
56
|
+
/** @deprecated Use `basemap`. */
|
|
36
57
|
mapStyle,
|
|
37
58
|
token,
|
|
38
59
|
layers: layers.reverse().map(({id, type, config, visualChannels}) => {
|
package/src/api/query.ts
CHANGED
|
@@ -10,6 +10,7 @@ type UrlParameters = {q: string; queryParameters?: string};
|
|
|
10
10
|
export const query = async function (options: QueryOptions): Promise<QueryResult> {
|
|
11
11
|
const {
|
|
12
12
|
apiBaseUrl = SOURCE_DEFAULTS.apiBaseUrl,
|
|
13
|
+
clientId = SOURCE_DEFAULTS.clientId,
|
|
13
14
|
connectionName,
|
|
14
15
|
sqlQuery,
|
|
15
16
|
queryParameters
|
|
@@ -22,16 +23,17 @@ export const query = async function (options: QueryOptions): Promise<QueryResult
|
|
|
22
23
|
|
|
23
24
|
const baseUrl = buildQueryUrl({apiBaseUrl, connectionName});
|
|
24
25
|
const headers = {Authorization: `Bearer ${options.accessToken}`, ...options.headers};
|
|
26
|
+
const parameters = {client: clientId, ...urlParameters};
|
|
25
27
|
|
|
26
28
|
const errorContext: APIErrorContext = {
|
|
27
29
|
requestType: 'SQL',
|
|
28
30
|
connection: options.connectionName,
|
|
29
31
|
type: 'query',
|
|
30
|
-
source: JSON.stringify(
|
|
32
|
+
source: JSON.stringify(parameters, undefined, 2)
|
|
31
33
|
};
|
|
32
34
|
return await requestWithParameters<QueryResult>({
|
|
33
35
|
baseUrl,
|
|
34
|
-
parameters
|
|
36
|
+
parameters,
|
|
35
37
|
headers,
|
|
36
38
|
errorContext
|
|
37
39
|
});
|
package/src/api/types.ts
CHANGED
|
@@ -2,7 +2,14 @@ import {SCALE_TYPE} from './layer-map';
|
|
|
2
2
|
|
|
3
3
|
export type Format = 'json' | 'geojson' | 'tilejson';
|
|
4
4
|
export type MapType = 'boundary' | 'query' | 'table' | 'tileset' | 'raster';
|
|
5
|
-
export type RequestType =
|
|
5
|
+
export type RequestType =
|
|
6
|
+
| 'Map data'
|
|
7
|
+
| 'Map instantiation'
|
|
8
|
+
| 'Public map'
|
|
9
|
+
| 'Tile stats'
|
|
10
|
+
| 'SQL'
|
|
11
|
+
| 'Basemap style';
|
|
12
|
+
|
|
6
13
|
export type APIErrorContext = {
|
|
7
14
|
requestType: RequestType;
|
|
8
15
|
mapId?: string;
|
|
@@ -176,3 +183,98 @@ export type MapDataset = {
|
|
|
176
183
|
aggregationResLevel: number | null;
|
|
177
184
|
geoColumn: string;
|
|
178
185
|
};
|
|
186
|
+
|
|
187
|
+
export interface CustomStyle {
|
|
188
|
+
url?: string;
|
|
189
|
+
style?: any;
|
|
190
|
+
customAttribution?: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export type KeplerMapConfig = {
|
|
194
|
+
mapState: any;
|
|
195
|
+
mapStyle: {
|
|
196
|
+
styleType: string;
|
|
197
|
+
visibleLayerGroups: Record<string, boolean>;
|
|
198
|
+
};
|
|
199
|
+
visState: {
|
|
200
|
+
layers: MapConfigLayer[];
|
|
201
|
+
};
|
|
202
|
+
layerBlending: any;
|
|
203
|
+
interactionConfig: any;
|
|
204
|
+
customBaseMaps?: {
|
|
205
|
+
customStyle?: CustomStyle;
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export type BasemapType = 'maplibre' | 'google-maps';
|
|
210
|
+
|
|
211
|
+
export type Basemap = MapLibreBasemap | GoogleBasemap;
|
|
212
|
+
|
|
213
|
+
export type BasemapCommon = {
|
|
214
|
+
/**
|
|
215
|
+
* Type of basemap.
|
|
216
|
+
*/
|
|
217
|
+
type: BasemapType;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Custom attribution for style data if not provided by style definition.
|
|
221
|
+
*/
|
|
222
|
+
attribution?: string;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Properties of the basemap. These properties are specific to the basemap type.
|
|
226
|
+
*/
|
|
227
|
+
props: Record<string, any>;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
export type MapLibreBasemap = BasemapCommon & {
|
|
231
|
+
type: 'maplibre';
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* MapLibre map properties.
|
|
235
|
+
*
|
|
236
|
+
* Meant to be passed to directly to `maplibregl.Map` object.
|
|
237
|
+
*/
|
|
238
|
+
props: MapLibreBasemapProps;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Layer groups to be displayed in the basemap.
|
|
242
|
+
*/
|
|
243
|
+
visibleLayerGroups?: Record<string, boolean>;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* If `style` has been filtered by `visibleLayerGroups` then this property contains original style object, so user
|
|
247
|
+
* can use `applyLayerGroupFilters` again with new settings.
|
|
248
|
+
*/
|
|
249
|
+
rawStyle?: string | Record<string, any>;
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// Cherry-pick of maplibregl Map API props that are supported/provided by fetchMap interface
|
|
253
|
+
export type MapLibreBasemapProps = {
|
|
254
|
+
style: string | Record<string, any>;
|
|
255
|
+
center: [number, number];
|
|
256
|
+
zoom: number;
|
|
257
|
+
pitch?: number;
|
|
258
|
+
bearing?: number;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export type GoogleBasemap = BasemapCommon & {
|
|
262
|
+
type: 'google-maps';
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Google map properties.
|
|
266
|
+
*
|
|
267
|
+
* Meant to be passed to directly to `google.maps.Map` object.
|
|
268
|
+
*/
|
|
269
|
+
props: GoogleBasemapProps;
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Cherry-pick of Google Map API props that are supported/provided by fetchMap interface
|
|
273
|
+
export type GoogleBasemapProps = {
|
|
274
|
+
mapTypeId: string;
|
|
275
|
+
mapId?: string;
|
|
276
|
+
center?: {lat: number; lng: number};
|
|
277
|
+
zoom?: number;
|
|
278
|
+
tilt?: number;
|
|
279
|
+
heading?: number;
|
|
280
|
+
};
|
package/src/basemap.ts
CHANGED
|
@@ -1,10 +1,137 @@
|
|
|
1
|
-
|
|
1
|
+
import {CartoAPIError} from './api/carto-api-error';
|
|
2
|
+
import {APIErrorContext, GoogleBasemapProps} from './api/types';
|
|
3
|
+
|
|
4
|
+
const cartoStyleUrlTemplate = 'https://basemaps.cartocdn.com/gl/{basemap}-gl-style/style.json';
|
|
5
|
+
|
|
6
|
+
export const CARTO_MAP_STYLES = ['positron', 'dark-matter', 'voyager'];
|
|
7
|
+
|
|
8
|
+
export const GOOGLE_BASEMAPS: Record<string, GoogleBasemapProps> = {
|
|
9
|
+
roadmap: {
|
|
10
|
+
mapTypeId: 'roadmap',
|
|
11
|
+
mapId: '3754c817b510f791'
|
|
12
|
+
},
|
|
13
|
+
'google-positron': {
|
|
14
|
+
mapTypeId: 'roadmap',
|
|
15
|
+
mapId: 'ea84ae4203ef21cd'
|
|
16
|
+
},
|
|
17
|
+
'google-dark-matter': {
|
|
18
|
+
mapTypeId: 'roadmap',
|
|
19
|
+
mapId: '2fccc3b36c22a0e2'
|
|
20
|
+
},
|
|
21
|
+
'google-voyager': {
|
|
22
|
+
mapTypeId: 'roadmap',
|
|
23
|
+
mapId: '885caf1e15bb9ef2'
|
|
24
|
+
},
|
|
25
|
+
satellite: {
|
|
26
|
+
mapTypeId: 'satellite'
|
|
27
|
+
},
|
|
28
|
+
hybrid: {
|
|
29
|
+
mapTypeId: 'hybrid'
|
|
30
|
+
},
|
|
31
|
+
terrain: {
|
|
32
|
+
mapTypeId: 'terrain'
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type StyleLayerGroupSlug = 'label' | 'road' | 'border' | 'building' | 'water' | 'land';
|
|
37
|
+
type StyleLayerGroup = {
|
|
38
|
+
slug: StyleLayerGroupSlug;
|
|
39
|
+
filter: (layer: any) => boolean;
|
|
40
|
+
defaultVisibility: boolean;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const STYLE_LAYER_GROUPS: StyleLayerGroup[] = [
|
|
44
|
+
{
|
|
45
|
+
slug: 'label',
|
|
46
|
+
filter: ({id}: {id: string}) =>
|
|
47
|
+
Boolean(
|
|
48
|
+
id.match(/(?=(label|_label|place-|place_|poi-|poi_|watername_|roadname_|housenumber))/)
|
|
49
|
+
),
|
|
50
|
+
defaultVisibility: true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
slug: 'road',
|
|
54
|
+
filter: ({id}: {id: string}) =>
|
|
55
|
+
Boolean(id.match(/(?=(road|railway|tunnel|street|bridge))(?!.*label)/)),
|
|
56
|
+
defaultVisibility: true
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
slug: 'border',
|
|
60
|
+
filter: ({id}: {id: string}) => Boolean(id.match(/border|boundaries|boundary_/)),
|
|
61
|
+
defaultVisibility: false
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
slug: 'building',
|
|
65
|
+
filter: ({id}: {id: string}) => Boolean(id.match(/building/)),
|
|
66
|
+
defaultVisibility: true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
slug: 'water',
|
|
70
|
+
filter: ({id}: {id: string}) => Boolean(id.match(/(?=(water|stream|ferry))/)),
|
|
71
|
+
defaultVisibility: true
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
slug: 'land',
|
|
75
|
+
filter: ({id}: {id: string}) =>
|
|
76
|
+
Boolean(id.match(/(?=(parks|landcover|industrial|sand|hillshade|park_))/)),
|
|
77
|
+
defaultVisibility: true
|
|
78
|
+
}
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
export function applyLayerGroupFilters(
|
|
82
|
+
style,
|
|
83
|
+
visibleLayerGroups: Record<StyleLayerGroupSlug, boolean>
|
|
84
|
+
) {
|
|
85
|
+
if (!Array.isArray(style?.layers)) {
|
|
86
|
+
return style;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const removedLayerFilters = STYLE_LAYER_GROUPS.filter(lg => !visibleLayerGroups[lg.slug]).map(
|
|
90
|
+
lg => lg.filter
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const visibleLayers = style.layers.filter(layer =>
|
|
94
|
+
removedLayerFilters.every(match => !match(layer))
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
...style,
|
|
99
|
+
layers: visibleLayers
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function someLayerGroupsDisabled(visibleLayerGroups?: Record<StyleLayerGroupSlug, boolean>) {
|
|
104
|
+
return visibleLayerGroups && Object.values(visibleLayerGroups).every(Boolean) === false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function getStyleUrl(styleType: string) {
|
|
108
|
+
return cartoStyleUrlTemplate.replace('{basemap}', styleType);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function fetchStyle({
|
|
112
|
+
styleUrl,
|
|
113
|
+
errorContext
|
|
114
|
+
}: {
|
|
115
|
+
styleUrl: string;
|
|
116
|
+
errorContext?: APIErrorContext;
|
|
117
|
+
}) {
|
|
118
|
+
/* global fetch */
|
|
119
|
+
let response: Response | undefined;
|
|
120
|
+
return await fetch(styleUrl, {mode: 'cors'})
|
|
121
|
+
.then(res => {
|
|
122
|
+
response = res;
|
|
123
|
+
return res.json();
|
|
124
|
+
})
|
|
125
|
+
.catch(error => {
|
|
126
|
+
throw new CartoAPIError(error, {...errorContext, requestType: 'Basemap style'}, response);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
2
129
|
|
|
3
130
|
export default {
|
|
4
|
-
VOYAGER:
|
|
5
|
-
POSITRON:
|
|
6
|
-
DARK_MATTER:
|
|
7
|
-
VOYAGER_NOLABELS:
|
|
8
|
-
POSITRON_NOLABELS:
|
|
9
|
-
DARK_MATTER_NOLABELS:
|
|
131
|
+
VOYAGER: getStyleUrl('voyager'),
|
|
132
|
+
POSITRON: getStyleUrl('positron'),
|
|
133
|
+
DARK_MATTER: getStyleUrl('dark-matter'),
|
|
134
|
+
VOYAGER_NOLABELS: getStyleUrl('voyager-nolabels'),
|
|
135
|
+
POSITRON_NOLABELS: getStyleUrl('positron-nolabels'),
|
|
136
|
+
DARK_MATTER_NOLABELS: getStyleUrl('dark-matter-nolabels')
|
|
10
137
|
} as const;
|
package/src/index.ts
CHANGED
|
@@ -22,19 +22,31 @@ export {
|
|
|
22
22
|
VectorTileLayer
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
export {
|
|
25
|
+
export {
|
|
26
|
+
default as BASEMAP,
|
|
27
|
+
GOOGLE_BASEMAPS as _GOOGLE_BASEMAPS,
|
|
28
|
+
getStyleUrl as _getStyleUrl,
|
|
29
|
+
fetchStyle as _fetchStyle,
|
|
30
|
+
applyLayerGroupFilters as _applyLayerGroupFilters,
|
|
31
|
+
STYLE_LAYER_GROUPS as _STYLE_LAYER_GROUPS
|
|
32
|
+
} from './basemap';
|
|
26
33
|
export {default as colorBins} from './style/color-bins-style';
|
|
27
34
|
export {default as colorCategories} from './style/color-categories-style';
|
|
28
35
|
export {default as colorContinuous} from './style/color-continuous-style';
|
|
29
36
|
export {CartoAPIError, fetchMap, query} from './api/index';
|
|
37
|
+
export {fetchBasemapProps} from './api/basemap';
|
|
30
38
|
export type {
|
|
31
39
|
APIErrorContext,
|
|
32
40
|
FetchMapOptions,
|
|
41
|
+
FetchMapResult,
|
|
33
42
|
Format,
|
|
34
43
|
MapType,
|
|
35
44
|
RequestType,
|
|
36
45
|
QueryParameters,
|
|
37
|
-
QueryOptions
|
|
46
|
+
QueryOptions,
|
|
47
|
+
Basemap as _Basemap,
|
|
48
|
+
MapLibreBasemap as _MapLibreBasemap,
|
|
49
|
+
GoogleBasemap as _GoogleBasemap
|
|
38
50
|
} from './api/index';
|
|
39
51
|
|
|
40
52
|
import {
|