@carto/api-client 0.5.0-alpha.9 → 0.5.1-alpha.0
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/CHANGELOG.md +30 -1
- package/build/api-client.cjs +15241 -3358
- package/build/api-client.cjs.map +1 -0
- package/build/api-client.d.cts +528 -181
- package/build/api-client.d.ts +528 -181
- package/build/api-client.js +14685 -2911
- package/build/api-client.js.map +1 -0
- package/build/worker.js +5117 -619
- package/build/worker.js.map +1 -0
- package/package.json +49 -32
- package/src/api/query.ts +2 -1
- package/src/constants-internal.ts +10 -0
- package/src/constants.ts +5 -1
- package/src/deck/get-data-filter-extension-props.ts +27 -9
- package/src/fetch-map/basemap-styles.ts +159 -0
- package/src/fetch-map/basemap.ts +120 -0
- package/src/fetch-map/fetch-map.ts +331 -0
- package/src/fetch-map/index.ts +13 -0
- package/src/fetch-map/layer-map.ts +461 -0
- package/src/fetch-map/parse-map.ts +425 -0
- package/src/fetch-map/source.ts +233 -0
- package/src/fetch-map/types.ts +268 -0
- package/src/fetch-map/utils.ts +69 -0
- package/src/filters/tileFeatures.ts +27 -10
- package/src/filters/tileFeaturesRaster.ts +122 -0
- package/src/index.ts +1 -0
- package/src/models/model.ts +0 -7
- package/src/sources/base-source.ts +4 -2
- package/src/sources/h3-tileset-source.ts +1 -1
- package/src/sources/quadbin-tileset-source.ts +1 -1
- package/src/sources/raster-source.ts +18 -5
- package/src/sources/types.ts +15 -8
- package/src/sources/vector-tileset-source.ts +1 -1
- package/src/spatial-index.ts +3 -84
- package/src/types.ts +16 -2
- package/src/widget-sources/index.ts +1 -0
- package/src/widget-sources/types.ts +1 -3
- package/src/widget-sources/widget-raster-source.ts +14 -0
- package/src/widget-sources/widget-remote-source.ts +16 -91
- package/src/widget-sources/widget-source.ts +9 -25
- package/src/widget-sources/widget-tileset-source-impl.ts +16 -19
- package/src/widget-sources/widget-tileset-source.ts +24 -21
- package/src/workers/widget-tileset-worker.ts +1 -1
package/package.json
CHANGED
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
"homepage": "https://github.com/CartoDB/carto-api-client#readme",
|
|
9
9
|
"author": "Don McCurdy <donmccurdy@carto.com>",
|
|
10
10
|
"packageManager": "yarn@4.3.1",
|
|
11
|
-
"version": "0.5.
|
|
11
|
+
"version": "0.5.1-alpha.0",
|
|
12
12
|
"license": "MIT",
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
13
16
|
"type": "module",
|
|
14
17
|
"sideEffects": false,
|
|
15
18
|
"exports": {
|
|
@@ -46,7 +49,7 @@
|
|
|
46
49
|
"format:check": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --check",
|
|
47
50
|
"clean": "rimraf build/*",
|
|
48
51
|
"postversion": "yarn postversion:check && yarn postversion:commit && yarn postversion:push",
|
|
49
|
-
"postversion:check": "yarn lint && yarn test",
|
|
52
|
+
"postversion:check": "yarn lint && yarn format:check && yarn test",
|
|
50
53
|
"postversion:commit": "node scripts/postversion-commit.js",
|
|
51
54
|
"postversion:push": "git push && git push --tags",
|
|
52
55
|
"prepublish": "yarn lint && yarn test",
|
|
@@ -60,56 +63,70 @@
|
|
|
60
63
|
],
|
|
61
64
|
"dependencies": {
|
|
62
65
|
"@loaders.gl/schema": "^4.3.3",
|
|
66
|
+
"@types/geojson": "^7946.0.16",
|
|
67
|
+
"d3-format": "^3.1.0",
|
|
68
|
+
"d3-scale": "^4.0.2",
|
|
69
|
+
"h3-js": "4.1.0",
|
|
70
|
+
"quadbin": "^0.4.1-alpha.0"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@deck.gl/aggregation-layers": "~9.1.6",
|
|
74
|
+
"@deck.gl/carto": "~9.1.6",
|
|
75
|
+
"@deck.gl/core": "~9.1.6",
|
|
76
|
+
"@deck.gl/extensions": "~9.1.6",
|
|
77
|
+
"@deck.gl/geo-layers": "~9.1.6",
|
|
78
|
+
"@deck.gl/google-maps": "~9.1.6",
|
|
79
|
+
"@deck.gl/layers": "~9.1.6",
|
|
80
|
+
"@deck.gl/mapbox": "~9.1.6",
|
|
81
|
+
"@deck.gl/mesh-layers": "~9.1.6",
|
|
82
|
+
"@eslint/js": "^9.21.0",
|
|
83
|
+
"@googlemaps/js-api-loader": "^1.16.6",
|
|
84
|
+
"@lit/react": "^1.0.7",
|
|
85
|
+
"@lit/task": "^1.0.2",
|
|
86
|
+
"@loaders.gl/core": "^4.3.3",
|
|
87
|
+
"@luma.gl/core": "~9.1.5",
|
|
88
|
+
"@luma.gl/engine": "~9.1.5",
|
|
89
|
+
"@luma.gl/shadertools": "~9.1.5",
|
|
90
|
+
"@luma.gl/webgl": "~9.1.5",
|
|
63
91
|
"@turf/bbox-clip": "^7.2.0",
|
|
64
92
|
"@turf/bbox-polygon": "^7.2.0",
|
|
65
93
|
"@turf/boolean-equal": "^7.2.0",
|
|
66
94
|
"@turf/boolean-intersects": "^7.2.0",
|
|
67
95
|
"@turf/boolean-within": "^7.2.0",
|
|
96
|
+
"@turf/buffer": "^7.2.0",
|
|
68
97
|
"@turf/helpers": "^7.2.0",
|
|
69
98
|
"@turf/intersect": "^7.2.0",
|
|
70
99
|
"@turf/invariant": "^7.2.0",
|
|
71
|
-
"@turf/union": "^7.2.0",
|
|
72
|
-
"@types/geojson": "^7946.0.16",
|
|
73
|
-
"h3-js": "4.1.0"
|
|
74
|
-
},
|
|
75
|
-
"devDependencies": {
|
|
76
|
-
"@deck.gl/aggregation-layers": "~9.1.0",
|
|
77
|
-
"@deck.gl/carto": "~9.1.0",
|
|
78
|
-
"@deck.gl/core": "~9.1.0",
|
|
79
|
-
"@deck.gl/extensions": "~9.1.0",
|
|
80
|
-
"@deck.gl/geo-layers": "~9.1.0",
|
|
81
|
-
"@deck.gl/layers": "~9.1.0",
|
|
82
|
-
"@deck.gl/mesh-layers": "~9.1.0",
|
|
83
|
-
"@eslint/js": "^9.20.0",
|
|
84
|
-
"@lit/react": "^1.0.7",
|
|
85
|
-
"@lit/task": "^1.0.2",
|
|
86
|
-
"@loaders.gl/core": "^4.3.3",
|
|
87
|
-
"@luma.gl/core": "~9.1.0",
|
|
88
|
-
"@luma.gl/engine": "~9.1.0",
|
|
89
|
-
"@luma.gl/shadertools": "~9.1.0",
|
|
90
|
-
"@turf/buffer": "^7.2.0",
|
|
91
100
|
"@turf/random": "^7.2.0",
|
|
101
|
+
"@turf/union": "^7.2.0",
|
|
102
|
+
"@types/d3-format": "^3.0.4",
|
|
103
|
+
"@types/d3-scale": "^4.0.9",
|
|
92
104
|
"@types/json-schema": "^7.0.15",
|
|
93
105
|
"@types/react": "^18.3.18",
|
|
94
106
|
"@types/semver": "^7.5.8",
|
|
95
|
-
"@vitest/coverage-istanbul": "^3.0.
|
|
107
|
+
"@vitest/coverage-istanbul": "^3.0.9",
|
|
96
108
|
"@webcomponents/webcomponentsjs": "^2.8.0",
|
|
97
109
|
"concurrently": "^9.1.2",
|
|
98
110
|
"echarts": "^5.6.0",
|
|
99
|
-
"eslint": "^9.
|
|
111
|
+
"eslint": "^9.22.0",
|
|
100
112
|
"lit": "^3.2.1",
|
|
101
113
|
"lit-analyzer": "^2.0.3",
|
|
102
|
-
"maplibre-gl": "^5.
|
|
103
|
-
"prettier": "^3.
|
|
114
|
+
"maplibre-gl": "^5.2.0",
|
|
115
|
+
"prettier": "^3.5.3",
|
|
116
|
+
"resolve-package-path": "^4.0.3",
|
|
104
117
|
"rimraf": "^6.0.1",
|
|
105
118
|
"semver": "^7.7.1",
|
|
106
119
|
"thenby": "^1.3.4",
|
|
107
|
-
"tinybench": "^
|
|
120
|
+
"tinybench": "^4.0.1",
|
|
108
121
|
"tsup": "^8.3.6",
|
|
109
|
-
"typescript": "~5.
|
|
110
|
-
"typescript-eslint": "^8.
|
|
111
|
-
"vite": "^6.
|
|
112
|
-
"vitest": "3.
|
|
122
|
+
"typescript": "~5.8.2",
|
|
123
|
+
"typescript-eslint": "^8.26.1",
|
|
124
|
+
"vite": "^6.2.2",
|
|
125
|
+
"vitest": "3.1.1"
|
|
126
|
+
},
|
|
127
|
+
"resolutions": {
|
|
128
|
+
"@carto/api-client": "portal:./",
|
|
129
|
+
"rollup": "^4.20.0"
|
|
113
130
|
},
|
|
114
|
-
"stableVersion": "0.
|
|
131
|
+
"stableVersion": "0.5.0"
|
|
115
132
|
}
|
package/src/api/query.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
import {buildQueryUrl} from './endpoints.js';
|
|
12
12
|
import {requestWithParameters} from './request-with-parameters.js';
|
|
13
13
|
import {APIErrorContext} from './carto-api-error.js';
|
|
14
|
+
import {getClient} from '../client.js';
|
|
14
15
|
|
|
15
16
|
export type QueryOptions = SourceOptions & QuerySourceOptions;
|
|
16
17
|
type UrlParameters = {q: string; queryParameters?: string};
|
|
@@ -20,8 +21,8 @@ export const query = async function (
|
|
|
20
21
|
): Promise<QueryResult> {
|
|
21
22
|
const {
|
|
22
23
|
apiBaseUrl = SOURCE_DEFAULTS.apiBaseUrl,
|
|
23
|
-
clientId = SOURCE_DEFAULTS.clientId,
|
|
24
24
|
maxLengthURL = SOURCE_DEFAULTS.maxLengthURL,
|
|
25
|
+
clientId = getClient(),
|
|
25
26
|
localCache,
|
|
26
27
|
connectionName,
|
|
27
28
|
sqlQuery,
|
|
@@ -13,6 +13,12 @@ export const DEFAULT_MAX_LENGTH_URL = 7000;
|
|
|
13
13
|
/** @privateRemarks Source: @deck.gl/carto */
|
|
14
14
|
export const DEFAULT_TILE_RESOLUTION = 0.5;
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @todo TODO(v0.5): Update DEFAULT_TILE_RESOLUTION and remove this constant.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export const REDUCED_QUERIES_TILE_RESOLUTION = 1;
|
|
21
|
+
|
|
16
22
|
/**
|
|
17
23
|
* @privateRemarks Source: @deck.gl/carto
|
|
18
24
|
* @internal
|
|
@@ -24,3 +30,7 @@ export const DEFAULT_AGGREGATION_RES_LEVEL_H3 = 4;
|
|
|
24
30
|
* @internal
|
|
25
31
|
*/
|
|
26
32
|
export const DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN = 6;
|
|
33
|
+
|
|
34
|
+
/** @internal */
|
|
35
|
+
export const DEFAULT_AGGREGATION_EXP_ALIAS = '__aggregationValue';
|
|
36
|
+
export const DEFAULT_AGGREGATION_EXP = `1 AS ${DEFAULT_AGGREGATION_EXP_ALIAS}`;
|
package/src/constants.ts
CHANGED
|
@@ -43,7 +43,6 @@ export enum TileFormat {
|
|
|
43
43
|
/** @privateRemarks Source: @carto/react-core */
|
|
44
44
|
export enum SpatialIndex {
|
|
45
45
|
H3 = 'h3',
|
|
46
|
-
S2 = 's2',
|
|
47
46
|
QUADBIN = 'quadbin',
|
|
48
47
|
}
|
|
49
48
|
|
|
@@ -56,3 +55,8 @@ export enum Provider {
|
|
|
56
55
|
DATABRICKS = 'databricks',
|
|
57
56
|
DATABRICKS_REST = 'databricksRest',
|
|
58
57
|
}
|
|
58
|
+
|
|
59
|
+
export const SpatialIndexColumn = Object.freeze({
|
|
60
|
+
[SpatialIndex.H3]: ['h3', 'hex', 'h3id', 'hex_id', 'h3hex'],
|
|
61
|
+
[SpatialIndex.QUADBIN]: ['quadbin'],
|
|
62
|
+
});
|
|
@@ -8,6 +8,16 @@ type TimeFilter = Filters['string'][FilterType.TIME] & {
|
|
|
8
8
|
params?: {offsetBy?: number};
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* deck.gl's DataFilterExtension supports GPU filtering with 1–4 values. We
|
|
13
|
+
* allocate filters[0] to generic filters and filters[1] to time filters.
|
|
14
|
+
*
|
|
15
|
+
* getFilterValue() _must_ return an array of the same size as the filterSize
|
|
16
|
+
* used to initialize the DataFilterExtension. We document that users must use
|
|
17
|
+
* filterSize=4 for compatibility with @link {getDataFilterExtensionProps}.
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_FILTER_SIZE = 4;
|
|
20
|
+
|
|
11
21
|
/** @experimental Prefer type definition from deck.gl. */
|
|
12
22
|
export type _DataFilterExtensionProps = {
|
|
13
23
|
filterRange: number[][];
|
|
@@ -17,22 +27,30 @@ export type _DataFilterExtensionProps = {
|
|
|
17
27
|
|
|
18
28
|
/**
|
|
19
29
|
* Creates props for DataFilterExtension, from `@deck.gl/extensions`, given
|
|
20
|
-
* a set of filters.
|
|
30
|
+
* a set of filters. Requires that DataFilterExtension is initialized with
|
|
31
|
+
* filterSize=4, where the CARTO filters will occupy the first two slots.
|
|
32
|
+
*
|
|
33
|
+
* @example To create a deck.gl layer with GPU data filtering:
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import {DataFilterExtension} from '@deck.gl/extensions';
|
|
36
|
+
* import {VectorTileLayer} from '@deck.gl/layers';
|
|
37
|
+
* import {getDataFilterExtensionProps} from '@carto/api-client';
|
|
21
38
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
39
|
+
* const layer = new VectorTileLayer({
|
|
40
|
+
* data: data,
|
|
41
|
+
* extensions: [new DataFilterExtension({filterSize: 4})],
|
|
42
|
+
* ...getDataFilterExtensionProps(filters),
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
25
45
|
*/
|
|
26
46
|
export function getDataFilterExtensionProps(
|
|
27
47
|
filters: Filters,
|
|
28
|
-
filtersLogicalOperator?: FilterLogicalOperator
|
|
29
|
-
filterSize?: 0 | 1 | 2 | 3 | 4
|
|
48
|
+
filtersLogicalOperator?: FilterLogicalOperator
|
|
30
49
|
): _DataFilterExtensionProps {
|
|
31
|
-
filterSize ??= 4;
|
|
32
50
|
const {filtersWithoutTimeType, timeColumn, timeFilter} =
|
|
33
51
|
getFiltersByType(filters);
|
|
34
52
|
return {
|
|
35
|
-
filterRange: getFilterRange(timeFilter,
|
|
53
|
+
filterRange: getFilterRange(timeFilter, DEFAULT_FILTER_SIZE),
|
|
36
54
|
updateTriggers: getUpdateTriggers(
|
|
37
55
|
filtersWithoutTimeType,
|
|
38
56
|
timeColumn,
|
|
@@ -42,7 +60,7 @@ export function getDataFilterExtensionProps(
|
|
|
42
60
|
filtersWithoutTimeType,
|
|
43
61
|
timeColumn,
|
|
44
62
|
timeFilter,
|
|
45
|
-
|
|
63
|
+
DEFAULT_FILTER_SIZE,
|
|
46
64
|
filtersLogicalOperator
|
|
47
65
|
),
|
|
48
66
|
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import {CartoAPIError, APIErrorContext} from '../api/index.js';
|
|
2
|
+
import {GoogleBasemapProps} from './types.js';
|
|
3
|
+
|
|
4
|
+
const cartoStyleUrlTemplate =
|
|
5
|
+
'https://basemaps.cartocdn.com/gl/{basemap}-gl-style/style.json';
|
|
6
|
+
|
|
7
|
+
export const CARTO_MAP_STYLES = ['positron', 'dark-matter', 'voyager'];
|
|
8
|
+
|
|
9
|
+
export const GOOGLE_BASEMAPS: Record<string, GoogleBasemapProps> = {
|
|
10
|
+
roadmap: {
|
|
11
|
+
mapTypeId: 'roadmap',
|
|
12
|
+
mapId: '3754c817b510f791',
|
|
13
|
+
},
|
|
14
|
+
'google-positron': {
|
|
15
|
+
mapTypeId: 'roadmap',
|
|
16
|
+
mapId: 'ea84ae4203ef21cd',
|
|
17
|
+
},
|
|
18
|
+
'google-dark-matter': {
|
|
19
|
+
mapTypeId: 'roadmap',
|
|
20
|
+
mapId: '2fccc3b36c22a0e2',
|
|
21
|
+
},
|
|
22
|
+
'google-voyager': {
|
|
23
|
+
mapTypeId: 'roadmap',
|
|
24
|
+
mapId: '885caf1e15bb9ef2',
|
|
25
|
+
},
|
|
26
|
+
satellite: {
|
|
27
|
+
mapTypeId: 'satellite',
|
|
28
|
+
},
|
|
29
|
+
hybrid: {
|
|
30
|
+
mapTypeId: 'hybrid',
|
|
31
|
+
},
|
|
32
|
+
terrain: {
|
|
33
|
+
mapTypeId: 'terrain',
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type StyleLayerGroupSlug =
|
|
38
|
+
| 'label'
|
|
39
|
+
| 'road'
|
|
40
|
+
| 'border'
|
|
41
|
+
| 'building'
|
|
42
|
+
| 'water'
|
|
43
|
+
| 'land';
|
|
44
|
+
type StyleLayerGroup = {
|
|
45
|
+
slug: StyleLayerGroupSlug;
|
|
46
|
+
filter: (layer: any) => boolean;
|
|
47
|
+
defaultVisibility: boolean;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const STYLE_LAYER_GROUPS: StyleLayerGroup[] = [
|
|
51
|
+
{
|
|
52
|
+
slug: 'label',
|
|
53
|
+
filter: ({id}: {id: string}) =>
|
|
54
|
+
Boolean(
|
|
55
|
+
id.match(
|
|
56
|
+
/(?=(label|_label|place-|place_|poi-|poi_|watername_|roadname_|housenumber))/
|
|
57
|
+
)
|
|
58
|
+
),
|
|
59
|
+
defaultVisibility: true,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
slug: 'road',
|
|
63
|
+
filter: ({id}: {id: string}) =>
|
|
64
|
+
Boolean(id.match(/(?=(road|railway|tunnel|street|bridge))(?!.*label)/)),
|
|
65
|
+
defaultVisibility: true,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
slug: 'border',
|
|
69
|
+
filter: ({id}: {id: string}) =>
|
|
70
|
+
Boolean(id.match(/border|boundaries|boundary_/)),
|
|
71
|
+
defaultVisibility: false,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
slug: 'building',
|
|
75
|
+
filter: ({id}: {id: string}) => Boolean(id.match(/building/)),
|
|
76
|
+
defaultVisibility: true,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
slug: 'water',
|
|
80
|
+
filter: ({id}: {id: string}) =>
|
|
81
|
+
Boolean(id.match(/(?=(water|stream|ferry))/)),
|
|
82
|
+
defaultVisibility: true,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
slug: 'land',
|
|
86
|
+
filter: ({id}: {id: string}) =>
|
|
87
|
+
Boolean(
|
|
88
|
+
id.match(/(?=(parks|landcover|industrial|sand|hillshade|park_))/)
|
|
89
|
+
),
|
|
90
|
+
defaultVisibility: true,
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
export function applyLayerGroupFilters(
|
|
95
|
+
style: any,
|
|
96
|
+
visibleLayerGroups: Record<StyleLayerGroupSlug, boolean>
|
|
97
|
+
) {
|
|
98
|
+
if (!Array.isArray(style?.layers)) {
|
|
99
|
+
return style;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const removedLayerFilters = STYLE_LAYER_GROUPS.filter(
|
|
103
|
+
(lg) => !visibleLayerGroups[lg.slug]
|
|
104
|
+
).map((lg) => lg.filter);
|
|
105
|
+
|
|
106
|
+
const visibleLayers = style.layers.filter((layer: any) =>
|
|
107
|
+
removedLayerFilters.every((match) => !match(layer))
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
...style,
|
|
112
|
+
layers: visibleLayers,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function someLayerGroupsDisabled(
|
|
117
|
+
visibleLayerGroups?: Record<StyleLayerGroupSlug, boolean>
|
|
118
|
+
) {
|
|
119
|
+
return (
|
|
120
|
+
visibleLayerGroups &&
|
|
121
|
+
Object.values(visibleLayerGroups).every(Boolean) === false
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function getStyleUrl(styleType: string) {
|
|
126
|
+
return cartoStyleUrlTemplate.replace('{basemap}', styleType);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function fetchStyle({
|
|
130
|
+
styleUrl,
|
|
131
|
+
errorContext,
|
|
132
|
+
}: {
|
|
133
|
+
styleUrl: string;
|
|
134
|
+
errorContext?: APIErrorContext;
|
|
135
|
+
}) {
|
|
136
|
+
/* global fetch */
|
|
137
|
+
let response: Response | undefined;
|
|
138
|
+
return await fetch(styleUrl, {mode: 'cors'})
|
|
139
|
+
.then((res) => {
|
|
140
|
+
response = res;
|
|
141
|
+
return res.json();
|
|
142
|
+
})
|
|
143
|
+
.catch((error) => {
|
|
144
|
+
throw new CartoAPIError(
|
|
145
|
+
error,
|
|
146
|
+
{...errorContext, requestType: 'Basemap style'},
|
|
147
|
+
response
|
|
148
|
+
);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export default {
|
|
153
|
+
VOYAGER: getStyleUrl('voyager'),
|
|
154
|
+
POSITRON: getStyleUrl('positron'),
|
|
155
|
+
DARK_MATTER: getStyleUrl('dark-matter'),
|
|
156
|
+
VOYAGER_NOLABELS: getStyleUrl('voyager-nolabels'),
|
|
157
|
+
POSITRON_NOLABELS: getStyleUrl('positron-nolabels'),
|
|
158
|
+
DARK_MATTER_NOLABELS: getStyleUrl('dark-matter-nolabels'),
|
|
159
|
+
} as const;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GOOGLE_BASEMAPS,
|
|
3
|
+
CARTO_MAP_STYLES,
|
|
4
|
+
applyLayerGroupFilters,
|
|
5
|
+
fetchStyle,
|
|
6
|
+
getStyleUrl,
|
|
7
|
+
someLayerGroupsDisabled,
|
|
8
|
+
} from './basemap-styles.js';
|
|
9
|
+
import {Basemap, KeplerMapConfig, MapLibreBasemapProps} from './types.js';
|
|
10
|
+
import {APIErrorContext} from '../api/index.js';
|
|
11
|
+
|
|
12
|
+
const CUSTOM_STYLE_ID_PREFIX = 'custom:';
|
|
13
|
+
const DEFAULT_CARTO_STYLE = 'positron';
|
|
14
|
+
|
|
15
|
+
// Subset of type from @deck.gl/core to avoid adding dependency
|
|
16
|
+
type MapViewState = {
|
|
17
|
+
/** Longitude of the map center */
|
|
18
|
+
longitude: number;
|
|
19
|
+
/** Latitude of the map center */
|
|
20
|
+
latitude: number;
|
|
21
|
+
/** Zoom level */
|
|
22
|
+
zoom: number;
|
|
23
|
+
/** Pitch (tilt) of the map, in degrees. `0` looks top down */
|
|
24
|
+
pitch?: number;
|
|
25
|
+
/** Bearing (rotation) of the map, in degrees. `0` is north up */
|
|
26
|
+
bearing?: number;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function mapLibreViewpros(
|
|
30
|
+
config: KeplerMapConfig
|
|
31
|
+
): Omit<MapLibreBasemapProps, 'style'> {
|
|
32
|
+
const {longitude, latitude, ...rest} = config.mapState as MapViewState;
|
|
33
|
+
return {
|
|
34
|
+
center: [longitude, latitude],
|
|
35
|
+
...rest,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get basemap properties for Carto map.
|
|
41
|
+
*
|
|
42
|
+
* For maplibre-based basemaps it returns style or style URL that can be used with `maplibregl.Map` compatible component.
|
|
43
|
+
* * style url is returned for non-filtered standard Carto basemaps or if user used style URL directly in configuration
|
|
44
|
+
* * filtered style object returned for Carto basemaps with layer groups filtered
|
|
45
|
+
*
|
|
46
|
+
* For Google-maps base maps, it returns options that can be used with `google.maps.Map` constructor.
|
|
47
|
+
*/
|
|
48
|
+
export async function fetchBasemapProps({
|
|
49
|
+
config,
|
|
50
|
+
errorContext,
|
|
51
|
+
|
|
52
|
+
applyLayerFilters = true,
|
|
53
|
+
}: {
|
|
54
|
+
config: KeplerMapConfig;
|
|
55
|
+
|
|
56
|
+
/** By default `fetchBasemapProps` applies layers filters to style. Set this to `false` to disable it. */
|
|
57
|
+
applyLayerFilters?: boolean;
|
|
58
|
+
errorContext?: APIErrorContext;
|
|
59
|
+
}): Promise<Basemap | null> {
|
|
60
|
+
const {mapStyle} = config;
|
|
61
|
+
const styleType = mapStyle.styleType || DEFAULT_CARTO_STYLE;
|
|
62
|
+
if (styleType.startsWith(CUSTOM_STYLE_ID_PREFIX)) {
|
|
63
|
+
const currentCustomStyle = config.customBaseMaps?.customStyle;
|
|
64
|
+
if (currentCustomStyle) {
|
|
65
|
+
return {
|
|
66
|
+
type: 'maplibre',
|
|
67
|
+
props: {
|
|
68
|
+
style: currentCustomStyle.style || currentCustomStyle.url,
|
|
69
|
+
...mapLibreViewpros(config),
|
|
70
|
+
},
|
|
71
|
+
attribution: currentCustomStyle.customAttribution,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (CARTO_MAP_STYLES.includes(styleType)) {
|
|
77
|
+
const {visibleLayerGroups} = mapStyle;
|
|
78
|
+
const styleUrl = getStyleUrl(styleType);
|
|
79
|
+
let style = styleUrl;
|
|
80
|
+
let rawStyle = styleUrl;
|
|
81
|
+
if (
|
|
82
|
+
applyLayerFilters &&
|
|
83
|
+
visibleLayerGroups &&
|
|
84
|
+
someLayerGroupsDisabled(visibleLayerGroups)
|
|
85
|
+
) {
|
|
86
|
+
rawStyle = await fetchStyle({styleUrl, errorContext});
|
|
87
|
+
style = applyLayerGroupFilters(rawStyle, visibleLayerGroups);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
type: 'maplibre',
|
|
91
|
+
props: {
|
|
92
|
+
style,
|
|
93
|
+
...mapLibreViewpros(config),
|
|
94
|
+
},
|
|
95
|
+
visibleLayerGroups,
|
|
96
|
+
rawStyle,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const googleBasemapDef = GOOGLE_BASEMAPS[styleType];
|
|
100
|
+
if (googleBasemapDef) {
|
|
101
|
+
const {mapState} = config;
|
|
102
|
+
return {
|
|
103
|
+
type: 'google-maps',
|
|
104
|
+
props: {
|
|
105
|
+
...googleBasemapDef,
|
|
106
|
+
center: {lat: mapState.latitude, lng: mapState.longitude},
|
|
107
|
+
zoom: mapState.zoom + 1,
|
|
108
|
+
tilt: mapState.pitch,
|
|
109
|
+
heading: mapState.bearing,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
type: 'maplibre',
|
|
115
|
+
props: {
|
|
116
|
+
style: getStyleUrl(DEFAULT_CARTO_STYLE),
|
|
117
|
+
...mapLibreViewpros(config),
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|