@carto/api-client 0.4.3 → 0.5.0-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 +4 -0
- package/build/api/query.d.ts +1 -1
- package/build/api-client.cjs +2388 -261
- package/build/api-client.cjs.map +1 -1
- package/build/api-client.modern.js +2237 -262
- package/build/api-client.modern.js.map +1 -1
- package/build/constants.d.ts +22 -0
- package/build/filters/Filter.d.ts +13 -0
- package/build/filters/FilterTypes.d.ts +3 -0
- package/build/filters/geosjonFeatures.d.ts +8 -0
- package/build/filters/index.d.ts +6 -0
- package/build/filters/tileFeatures.d.ts +20 -0
- package/build/filters/tileFeaturesGeometries.d.ts +13 -0
- package/build/filters/tileFeaturesSpatialIndex.d.ts +10 -0
- package/build/index.d.ts +4 -0
- package/build/models/index.d.ts +1 -1
- package/build/models/model.d.ts +7 -1
- package/build/operations/aggregation.d.ts +8 -0
- package/build/operations/applySorting.d.ts +20 -0
- package/build/operations/groupBy.d.ts +15 -0
- package/build/operations/groupByDate.d.ts +11 -0
- package/build/operations/histogram.d.ts +13 -0
- package/build/operations/index.d.ts +6 -0
- package/build/operations/scatterPlot.d.ts +14 -0
- package/build/sources/h3-tileset-source.d.ts +2 -1
- package/build/sources/index.d.ts +1 -1
- package/build/sources/quadbin-tileset-source.d.ts +2 -1
- package/build/sources/types.d.ts +36 -41
- package/build/sources/vector-tileset-source.d.ts +2 -1
- package/build/spatial-index.d.ts +8 -0
- package/build/types-internal.d.ts +4 -0
- package/build/types.d.ts +61 -1
- package/build/utils/dateUtils.d.ts +10 -0
- package/build/utils/getTileFormat.d.ts +3 -0
- package/build/utils/makeIntervalComplete.d.ts +2 -0
- package/build/utils/transformTileCoordsToWGS84.d.ts +8 -0
- package/build/utils/transformToTileCoords.d.ts +9 -0
- package/build/utils.d.ts +1 -1
- package/build/widget-sources/index.d.ts +2 -1
- package/build/widget-sources/types.d.ts +40 -23
- package/build/widget-sources/widget-query-source.d.ts +2 -2
- package/build/widget-sources/widget-remote-source.d.ts +18 -0
- package/build/widget-sources/{widget-base-source.d.ts → widget-source.d.ts} +16 -41
- package/build/widget-sources/widget-table-source.d.ts +2 -2
- package/build/widget-sources/widget-tileset-source.d.ts +67 -0
- package/package.json +36 -35
- package/src/api/query.ts +1 -2
- package/src/constants.ts +25 -0
- package/src/filters/Filter.ts +169 -0
- package/src/filters/FilterTypes.ts +109 -0
- package/src/filters/geosjonFeatures.ts +32 -0
- package/src/filters/index.ts +6 -0
- package/src/filters/tileFeatures.ts +56 -0
- package/src/filters/tileFeaturesGeometries.ts +444 -0
- package/src/filters/tileFeaturesSpatialIndex.ts +119 -0
- package/src/index.ts +6 -0
- package/src/models/index.ts +1 -1
- package/src/models/model.ts +47 -24
- package/src/operations/aggregation.ts +154 -0
- package/src/operations/applySorting.ts +109 -0
- package/src/operations/groupBy.ts +59 -0
- package/src/operations/groupByDate.ts +98 -0
- package/src/operations/histogram.ts +66 -0
- package/src/operations/index.ts +6 -0
- package/src/operations/scatterPlot.ts +50 -0
- package/src/sources/h3-query-source.ts +7 -1
- package/src/sources/h3-table-source.ts +6 -1
- package/src/sources/h3-tileset-source.ts +18 -6
- package/src/sources/index.ts +1 -1
- package/src/sources/quadbin-query-source.ts +6 -1
- package/src/sources/quadbin-table-source.ts +6 -1
- package/src/sources/quadbin-tileset-source.ts +18 -6
- package/src/sources/raster-source.ts +1 -0
- package/src/sources/types.ts +41 -45
- package/src/sources/vector-query-source.ts +10 -3
- package/src/sources/vector-table-source.ts +10 -3
- package/src/sources/vector-tileset-source.ts +19 -6
- package/src/spatial-index.ts +111 -0
- package/src/types-internal.ts +6 -0
- package/src/types.ts +60 -2
- package/src/utils/dateUtils.ts +28 -0
- package/src/utils/getTileFormat.ts +9 -0
- package/src/utils/makeIntervalComplete.ts +17 -0
- package/src/utils/transformTileCoordsToWGS84.ts +77 -0
- package/src/utils/transformToTileCoords.ts +85 -0
- package/src/utils.ts +9 -6
- package/src/widget-sources/index.ts +2 -1
- package/src/widget-sources/types.ts +42 -23
- package/src/widget-sources/widget-query-source.ts +6 -3
- package/src/widget-sources/{widget-base-source.ts → widget-remote-source.ts} +169 -144
- package/src/widget-sources/widget-source.ts +160 -0
- package/src/widget-sources/widget-table-source.ts +6 -3
- package/src/widget-sources/widget-tileset-source.ts +396 -0
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
import {getTileFormat} from '../utils/getTileFormat';
|
|
6
|
+
import {
|
|
7
|
+
WidgetTilesetSource,
|
|
8
|
+
WidgetTilesetSourceResult,
|
|
9
|
+
} from '../widget-sources';
|
|
5
10
|
import {baseSource} from './base-source';
|
|
6
11
|
import type {
|
|
7
12
|
SourceOptions,
|
|
@@ -12,17 +17,24 @@ import type {
|
|
|
12
17
|
export type QuadbinTilesetSourceOptions = SourceOptions & TilesetSourceOptions;
|
|
13
18
|
type UrlParameters = {name: string};
|
|
14
19
|
|
|
15
|
-
export type QuadbinTilesetSourceResponse = TilejsonResult
|
|
20
|
+
export type QuadbinTilesetSourceResponse = TilejsonResult &
|
|
21
|
+
WidgetTilesetSourceResult;
|
|
16
22
|
|
|
17
23
|
export const quadbinTilesetSource = async function (
|
|
18
24
|
options: QuadbinTilesetSourceOptions
|
|
19
25
|
): Promise<QuadbinTilesetSourceResponse> {
|
|
20
|
-
const {tableName} = options;
|
|
26
|
+
const {tableName, spatialDataColumn = 'quadbin'} = options;
|
|
21
27
|
const urlParameters: UrlParameters = {name: tableName};
|
|
22
28
|
|
|
23
|
-
return baseSource<UrlParameters>(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
return baseSource<UrlParameters>('tileset', options, urlParameters).then(
|
|
30
|
+
(result) => ({
|
|
31
|
+
...(result as TilejsonResult),
|
|
32
|
+
widgetSource: new WidgetTilesetSource({
|
|
33
|
+
...options,
|
|
34
|
+
tileFormat: getTileFormat(result as TilejsonResult),
|
|
35
|
+
spatialDataColumn,
|
|
36
|
+
spatialDataType: 'quadbin',
|
|
37
|
+
}),
|
|
38
|
+
})
|
|
27
39
|
) as Promise<QuadbinTilesetSourceResponse>;
|
|
28
40
|
};
|
package/src/sources/types.ts
CHANGED
|
@@ -48,6 +48,33 @@ export type SourceOptionalOptions = {
|
|
|
48
48
|
*/
|
|
49
49
|
maxLengthURL?: number;
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* The column name and the type of geospatial support.
|
|
53
|
+
*
|
|
54
|
+
* If not present, defaults to `'geom'` for generic queries, `'quadbin'` for Quadbin sources and `'h3'` for H3 sources.
|
|
55
|
+
*/
|
|
56
|
+
spatialDataColumn?: string;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The type of geospatial support. Defaults to `'geo'`.
|
|
60
|
+
*/
|
|
61
|
+
spatialDataType?: SpatialDataType;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Relative resolution of a tile. Higher values increase density and data size. At `tileResolution = 1`, tile geometry is
|
|
65
|
+
* quantized to a 1024x1024 grid. Increasing or decreasing the resolution will increase or decrease the dimensions of
|
|
66
|
+
* the quantization grid proportionately.
|
|
67
|
+
*
|
|
68
|
+
* Supported `tileResolution` values, with corresponding grid sizes:
|
|
69
|
+
*
|
|
70
|
+
* - 0.25: 256x256
|
|
71
|
+
* - 0.5: 512x512
|
|
72
|
+
* - 1: 1024x1024
|
|
73
|
+
* - 2: 2048x2048
|
|
74
|
+
* - 4: 4096x4096
|
|
75
|
+
*/
|
|
76
|
+
tileResolution?: TileResolution;
|
|
77
|
+
|
|
51
78
|
/**
|
|
52
79
|
* By default, local in-memory caching is enabled.
|
|
53
80
|
*/
|
|
@@ -89,6 +116,11 @@ export type AggregationOptions = {
|
|
|
89
116
|
* @default 6 for quadbin and 4 for h3 sources
|
|
90
117
|
*/
|
|
91
118
|
aggregationResLevel?: number;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Original resolution of the spatial index data as stored in the DW
|
|
122
|
+
*/
|
|
123
|
+
dataResolution?: number;
|
|
92
124
|
};
|
|
93
125
|
|
|
94
126
|
export type FilterOptions = {
|
|
@@ -99,31 +131,9 @@ export type FilterOptions = {
|
|
|
99
131
|
};
|
|
100
132
|
|
|
101
133
|
export type QuerySourceOptions = {
|
|
102
|
-
/**
|
|
103
|
-
* The column name and the type of geospatial support.
|
|
104
|
-
*
|
|
105
|
-
* If not present, defaults to `'geom'` for generic queries, `'quadbin'` for Quadbin sources and `'h3'` for H3 sources.
|
|
106
|
-
*/
|
|
107
|
-
spatialDataColumn?: string;
|
|
108
|
-
|
|
109
|
-
/** SQL query. */
|
|
134
|
+
/** Full SQL query with query paremeter placeholders (if any). */
|
|
110
135
|
sqlQuery: string;
|
|
111
136
|
|
|
112
|
-
/**
|
|
113
|
-
* Relative resolution of a tile. Higher values increase density and data size. At `tileResolution = 1`, tile geometry is
|
|
114
|
-
* quantized to a 1024x1024 grid. Increasing or decreasing the resolution will increase or decrease the dimensions of
|
|
115
|
-
* the quantization grid proportionately.
|
|
116
|
-
*
|
|
117
|
-
* Supported `tileResolution` values, with corresponding grid sizes:
|
|
118
|
-
*
|
|
119
|
-
* - 0.25: 256x256
|
|
120
|
-
* - 0.5: 512x512
|
|
121
|
-
* - 1: 1024x1024
|
|
122
|
-
* - 2: 2048x2048
|
|
123
|
-
* - 4: 4096x4096
|
|
124
|
-
*/
|
|
125
|
-
tileResolution?: TileResolution;
|
|
126
|
-
|
|
127
137
|
/**
|
|
128
138
|
* Values for named or positional paramteres in the query.
|
|
129
139
|
*
|
|
@@ -166,28 +176,6 @@ export type TableSourceOptions = {
|
|
|
166
176
|
*/
|
|
167
177
|
tableName: string;
|
|
168
178
|
|
|
169
|
-
/**
|
|
170
|
-
* The column name and the type of geospatial support.
|
|
171
|
-
*
|
|
172
|
-
* If not present, defaults to `'geom'` for generic tables, `'quadbin'` for Quadbin sources and `'h3'` for H3 sources.
|
|
173
|
-
*/
|
|
174
|
-
spatialDataColumn?: string;
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Relative resolution of a tile. Higher values increase density and data size. At `tileResolution = 1`, tile geometry is
|
|
178
|
-
* quantized to a 1024x1024 grid. Increasing or decreasing the resolution will increase or decrease the dimensions of
|
|
179
|
-
* the quantization grid proportionately.
|
|
180
|
-
*
|
|
181
|
-
* Supported `tileResolution` values, with corresponding grid sizes:
|
|
182
|
-
*
|
|
183
|
-
* - 0.25: 256x256
|
|
184
|
-
* - 0.5: 512x512
|
|
185
|
-
* - 1: 1024x1024
|
|
186
|
-
* - 2: 2048x2048
|
|
187
|
-
* - 4: 4096x4096
|
|
188
|
-
*/
|
|
189
|
-
tileResolution?: TileResolution;
|
|
190
|
-
|
|
191
179
|
/**
|
|
192
180
|
* Comma-separated aggregation expressions. If assigned on a vector source, source is grouped by geometry and then aggregated.
|
|
193
181
|
*
|
|
@@ -216,6 +204,14 @@ export type ColumnsOption = {
|
|
|
216
204
|
|
|
217
205
|
export type SpatialDataType = 'geo' | 'h3' | 'quadbin';
|
|
218
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Strategy used for covering spatial filter geometry with spatial indexes.
|
|
209
|
+
* See https://docs.carto.com/data-and-analysis/analytics-toolbox-for-bigquery/sql-reference/quadbin#quadbin_polyfill_mode
|
|
210
|
+
* or https://docs.carto.com/data-and-analysis/analytics-toolbox-for-bigquery/sql-reference/h3#h3_polyfill_mode for more information.
|
|
211
|
+
* @internalRemarks Source: cloud-native maps-api
|
|
212
|
+
* */
|
|
213
|
+
export type SpatialFilterPolyfillMode = 'center' | 'intersects' | 'contains';
|
|
214
|
+
|
|
219
215
|
export type TilejsonMapInstantiation = MapInstantiation & {
|
|
220
216
|
tilejson: {url: string[]};
|
|
221
217
|
};
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
/* eslint-disable camelcase */
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
DEFAULT_GEO_COLUMN,
|
|
8
|
+
DEFAULT_TILE_RESOLUTION,
|
|
9
|
+
} from '../constants-internal.js';
|
|
7
10
|
import {
|
|
8
11
|
WidgetQuerySource,
|
|
9
12
|
WidgetQuerySourceResult,
|
|
@@ -43,7 +46,7 @@ export const vectorQuerySource = async function (
|
|
|
43
46
|
const {
|
|
44
47
|
columns,
|
|
45
48
|
filters,
|
|
46
|
-
spatialDataColumn =
|
|
49
|
+
spatialDataColumn = DEFAULT_GEO_COLUMN,
|
|
47
50
|
sqlQuery,
|
|
48
51
|
tileResolution = DEFAULT_TILE_RESOLUTION,
|
|
49
52
|
queryParameters,
|
|
@@ -72,7 +75,11 @@ export const vectorQuerySource = async function (
|
|
|
72
75
|
return baseSource<UrlParameters>('query', options, urlParameters).then(
|
|
73
76
|
(result) => ({
|
|
74
77
|
...(result as TilejsonResult),
|
|
75
|
-
widgetSource: new WidgetQuerySource(
|
|
78
|
+
widgetSource: new WidgetQuerySource({
|
|
79
|
+
...options,
|
|
80
|
+
spatialDataColumn,
|
|
81
|
+
spatialDataType: 'geo',
|
|
82
|
+
}),
|
|
76
83
|
})
|
|
77
84
|
);
|
|
78
85
|
};
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
5
|
/* eslint-disable camelcase */
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
DEFAULT_GEO_COLUMN,
|
|
8
|
+
DEFAULT_TILE_RESOLUTION,
|
|
9
|
+
} from '../constants-internal.js';
|
|
7
10
|
import {
|
|
8
11
|
WidgetTableSource,
|
|
9
12
|
WidgetTableSourceResult,
|
|
@@ -42,7 +45,7 @@ export const vectorTableSource = async function (
|
|
|
42
45
|
const {
|
|
43
46
|
columns,
|
|
44
47
|
filters,
|
|
45
|
-
spatialDataColumn =
|
|
48
|
+
spatialDataColumn = DEFAULT_GEO_COLUMN,
|
|
46
49
|
tableName,
|
|
47
50
|
tileResolution = DEFAULT_TILE_RESOLUTION,
|
|
48
51
|
aggregationExp,
|
|
@@ -67,7 +70,11 @@ export const vectorTableSource = async function (
|
|
|
67
70
|
return baseSource<UrlParameters>('table', options, urlParameters).then(
|
|
68
71
|
(result) => ({
|
|
69
72
|
...(result as TilejsonResult),
|
|
70
|
-
widgetSource: new WidgetTableSource(
|
|
73
|
+
widgetSource: new WidgetTableSource({
|
|
74
|
+
...options,
|
|
75
|
+
spatialDataColumn,
|
|
76
|
+
spatialDataType: 'geo',
|
|
77
|
+
}),
|
|
71
78
|
})
|
|
72
79
|
);
|
|
73
80
|
};
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
// Copyright (c) vis.gl contributors
|
|
4
4
|
|
|
5
|
+
import {DEFAULT_GEO_COLUMN} from '../constants-internal';
|
|
6
|
+
import {getTileFormat} from '../utils/getTileFormat';
|
|
7
|
+
import {
|
|
8
|
+
WidgetTilesetSource,
|
|
9
|
+
WidgetTilesetSourceResult,
|
|
10
|
+
} from '../widget-sources';
|
|
5
11
|
import {baseSource} from './base-source';
|
|
6
12
|
import type {
|
|
7
13
|
SourceOptions,
|
|
@@ -12,17 +18,24 @@ import type {
|
|
|
12
18
|
export type VectorTilesetSourceOptions = SourceOptions & TilesetSourceOptions;
|
|
13
19
|
type UrlParameters = {name: string};
|
|
14
20
|
|
|
15
|
-
export type VectorTilesetSourceResponse = TilejsonResult
|
|
21
|
+
export type VectorTilesetSourceResponse = TilejsonResult &
|
|
22
|
+
WidgetTilesetSourceResult;
|
|
16
23
|
|
|
17
24
|
export const vectorTilesetSource = async function (
|
|
18
25
|
options: VectorTilesetSourceOptions
|
|
19
26
|
): Promise<VectorTilesetSourceResponse> {
|
|
20
|
-
const {tableName} = options;
|
|
27
|
+
const {tableName, spatialDataColumn = DEFAULT_GEO_COLUMN} = options;
|
|
21
28
|
const urlParameters: UrlParameters = {name: tableName};
|
|
22
29
|
|
|
23
|
-
return baseSource<UrlParameters>(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
return baseSource<UrlParameters>('tileset', options, urlParameters).then(
|
|
31
|
+
(result) => ({
|
|
32
|
+
...(result as TilejsonResult),
|
|
33
|
+
widgetSource: new WidgetTilesetSource({
|
|
34
|
+
...options,
|
|
35
|
+
tileFormat: getTileFormat(result as TilejsonResult),
|
|
36
|
+
spatialDataColumn,
|
|
37
|
+
spatialDataType: 'geo',
|
|
38
|
+
}),
|
|
39
|
+
})
|
|
27
40
|
) as Promise<VectorTilesetSourceResponse>;
|
|
28
41
|
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_AGGREGATION_RES_LEVEL_H3,
|
|
3
|
+
DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN,
|
|
4
|
+
} from './constants-internal';
|
|
5
|
+
import type {ModelSource} from './models/model';
|
|
6
|
+
import type {AggregationOptions} from './sources/types';
|
|
7
|
+
import {assert} from './utils';
|
|
8
|
+
import type {ViewState} from './widget-sources';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_TILE_SIZE = 512;
|
|
11
|
+
const QUADBIN_ZOOM_MAX_OFFSET = 4;
|
|
12
|
+
|
|
13
|
+
export function getSpatialFiltersResolution(
|
|
14
|
+
source: Partial<ModelSource & AggregationOptions>,
|
|
15
|
+
viewState: ViewState
|
|
16
|
+
): number | undefined {
|
|
17
|
+
const dataResolution = source.dataResolution ?? Number.MAX_VALUE;
|
|
18
|
+
|
|
19
|
+
const aggregationResLevel =
|
|
20
|
+
source.aggregationResLevel ??
|
|
21
|
+
(source.spatialDataType === 'h3'
|
|
22
|
+
? DEFAULT_AGGREGATION_RES_LEVEL_H3
|
|
23
|
+
: DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN);
|
|
24
|
+
|
|
25
|
+
const aggregationResLevelOffset = Math.max(
|
|
26
|
+
0,
|
|
27
|
+
Math.floor(aggregationResLevel)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const currentZoomInt = Math.ceil(viewState.zoom);
|
|
31
|
+
if (source.spatialDataType === 'h3') {
|
|
32
|
+
const tileSize = DEFAULT_TILE_SIZE;
|
|
33
|
+
const maxResolutionForZoom =
|
|
34
|
+
maxH3SpatialFiltersResolutions.find(
|
|
35
|
+
([zoom]) => zoom === currentZoomInt
|
|
36
|
+
)?.[1] ?? Math.max(0, currentZoomInt - 3);
|
|
37
|
+
|
|
38
|
+
const maxSpatialFiltersResolution = maxResolutionForZoom
|
|
39
|
+
? Math.min(dataResolution, maxResolutionForZoom)
|
|
40
|
+
: dataResolution;
|
|
41
|
+
|
|
42
|
+
const hexagonResolution =
|
|
43
|
+
getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
|
|
44
|
+
|
|
45
|
+
return Math.min(hexagonResolution, maxSpatialFiltersResolution);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (source.spatialDataType === 'quadbin') {
|
|
49
|
+
const maxResolutionForZoom = currentZoomInt + QUADBIN_ZOOM_MAX_OFFSET;
|
|
50
|
+
const maxSpatialFiltersResolution = Math.min(
|
|
51
|
+
dataResolution,
|
|
52
|
+
maxResolutionForZoom
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const quadsResolution =
|
|
56
|
+
Math.floor(viewState.zoom) + aggregationResLevelOffset;
|
|
57
|
+
return Math.min(quadsResolution, maxSpatialFiltersResolution);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const maxH3SpatialFiltersResolutions = [
|
|
64
|
+
[20, 14],
|
|
65
|
+
[19, 13],
|
|
66
|
+
[18, 12],
|
|
67
|
+
[17, 11],
|
|
68
|
+
[16, 10],
|
|
69
|
+
[15, 9],
|
|
70
|
+
[14, 8],
|
|
71
|
+
[13, 7],
|
|
72
|
+
[12, 7],
|
|
73
|
+
[11, 7],
|
|
74
|
+
[10, 6],
|
|
75
|
+
[9, 6],
|
|
76
|
+
[8, 5],
|
|
77
|
+
[7, 4],
|
|
78
|
+
[6, 4],
|
|
79
|
+
[5, 3],
|
|
80
|
+
[4, 2],
|
|
81
|
+
[3, 1],
|
|
82
|
+
[2, 1],
|
|
83
|
+
[1, 0],
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
// stolen from https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
|
|
87
|
+
|
|
88
|
+
// Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
|
|
89
|
+
const BIAS = 2;
|
|
90
|
+
|
|
91
|
+
// Resolution conversion function. Takes a WebMercatorViewport and returns
|
|
92
|
+
// a H3 resolution such that the screen space size of the hexagons is
|
|
93
|
+
// similar
|
|
94
|
+
export function getHexagonResolution(
|
|
95
|
+
viewport: {zoom: number; latitude: number},
|
|
96
|
+
tileSize: number
|
|
97
|
+
): number {
|
|
98
|
+
// Difference in given tile size compared to deck's internal 512px tile size,
|
|
99
|
+
// expressed as an offset to the viewport zoom.
|
|
100
|
+
const zoomOffset = Math.log2(tileSize / DEFAULT_TILE_SIZE);
|
|
101
|
+
const hexagonScaleFactor = (2 / 3) * (viewport.zoom - zoomOffset);
|
|
102
|
+
const latitudeScaleFactor = Math.log(
|
|
103
|
+
1 / Math.cos((Math.PI * viewport.latitude) / 180)
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// Clip and bias
|
|
107
|
+
return Math.max(
|
|
108
|
+
0,
|
|
109
|
+
Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS)
|
|
110
|
+
);
|
|
111
|
+
}
|
package/src/types-internal.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type {FilterType} from './constants.js';
|
|
2
|
-
import type {Polygon, MultiPolygon} from 'geojson';
|
|
2
|
+
import type {Polygon, MultiPolygon, Feature} from 'geojson';
|
|
3
|
+
import type {BinaryFeature, BinaryFeatureCollection} from '@loaders.gl/schema';
|
|
3
4
|
|
|
4
5
|
/******************************************************************************
|
|
5
6
|
* MAPS AND TILES
|
|
@@ -11,6 +12,43 @@ export type Format = 'json' | 'geojson' | 'tilejson';
|
|
|
11
12
|
/** @internalRemarks Source: @carto/constants, @deck.gl/carto */
|
|
12
13
|
export type MapType = 'boundary' | 'query' | 'table' | 'tileset' | 'raster';
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Alias for GeoJSON 'BBox' type, semantically representing a viewport.
|
|
17
|
+
* Order of values is "west", "south", "east", "north".
|
|
18
|
+
*/
|
|
19
|
+
export type Viewport = [number, number, number, number];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Subset of deck.gl's Tile2DHeader type, containing only the properties
|
|
23
|
+
* required for local widget calculations. Deeper dependencies on deck.gl
|
|
24
|
+
* APIs should be minimized within this library: @deck.gl/carto depends
|
|
25
|
+
* on the API client, not the other way around.
|
|
26
|
+
* @internalRemarks Source: @deck.gl/geo-layers
|
|
27
|
+
*/
|
|
28
|
+
export type Tile = {
|
|
29
|
+
index: {x: number; y: number; z: number};
|
|
30
|
+
id: string;
|
|
31
|
+
content: unknown;
|
|
32
|
+
zoom: number;
|
|
33
|
+
bbox: {west: number; east: number; north: number; south: number};
|
|
34
|
+
isVisible: boolean;
|
|
35
|
+
data?: BinaryFeatureCollection;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** Subset of deck.gl's Tile2DHeader type, for spatial indexes. */
|
|
39
|
+
export type SpatialIndexTile = Tile & {
|
|
40
|
+
data?: (Feature & {id: bigint})[];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** @internalRemarks Source: @deck.gl/carto */
|
|
44
|
+
export type Raster = {
|
|
45
|
+
blockSize: number;
|
|
46
|
+
cells: {
|
|
47
|
+
numericProps: BinaryFeature['numericProps'];
|
|
48
|
+
properties: BinaryFeature['properties'];
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
14
52
|
/******************************************************************************
|
|
15
53
|
* AGGREGATION
|
|
16
54
|
*/
|
|
@@ -49,12 +87,32 @@ export interface Filter {
|
|
|
49
87
|
/** [a, b) a is included, b is not. */
|
|
50
88
|
[FilterType.CLOSED_OPEN]?: {owner?: string; values: number[][]};
|
|
51
89
|
[FilterType.TIME]?: {owner?: string; values: number[][]};
|
|
52
|
-
[FilterType.STRING_SEARCH]?: {
|
|
90
|
+
[FilterType.STRING_SEARCH]?: {
|
|
91
|
+
owner?: string;
|
|
92
|
+
values: string[];
|
|
93
|
+
params?: StringSearchOptions;
|
|
94
|
+
};
|
|
53
95
|
}
|
|
54
96
|
|
|
55
97
|
/** @internalRemarks Source: @carto/react-core */
|
|
56
98
|
export type FilterLogicalOperator = 'and' | 'or';
|
|
57
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Type for minimum or maximum value of an interval. Values 'null' and
|
|
102
|
+
* 'undefined' are intentionally allowed, and represent an unbounded value.
|
|
103
|
+
*/
|
|
104
|
+
export type FilterIntervalExtremum = number | null | undefined;
|
|
105
|
+
export type FilterInterval = [FilterIntervalExtremum, FilterIntervalExtremum];
|
|
106
|
+
export type FilterIntervalComplete = [number, number];
|
|
107
|
+
|
|
108
|
+
export type StringSearchOptions = {
|
|
109
|
+
useRegExp?: boolean;
|
|
110
|
+
mustStart?: boolean;
|
|
111
|
+
mustEnd?: boolean;
|
|
112
|
+
caseSensitive?: boolean;
|
|
113
|
+
keepSpecialCharacters?: boolean;
|
|
114
|
+
};
|
|
115
|
+
|
|
58
116
|
/******************************************************************************
|
|
59
117
|
* GROUPING
|
|
60
118
|
*/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns midnight (local time) on the Monday preceeding a given date, in
|
|
3
|
+
* milliseconds since the UNIX epoch.
|
|
4
|
+
*/
|
|
5
|
+
export function getMonday(date: number | Date): number {
|
|
6
|
+
const dateCp = new Date(date);
|
|
7
|
+
const day = dateCp.getDay();
|
|
8
|
+
const diff = dateCp.getDate() - day + (day ? 1 : -6); // adjust when day is sunday
|
|
9
|
+
dateCp.setDate(diff);
|
|
10
|
+
dateCp.setHours(0, 0, 0, 0);
|
|
11
|
+
return dateCp.getTime();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Returns midnight (UTC) on the Monday preceeding a given date, in
|
|
16
|
+
* milliseconds since the UNIX epoch.
|
|
17
|
+
*/
|
|
18
|
+
export function getUTCMonday(date: number | Date): number {
|
|
19
|
+
const dateCp = new Date(date);
|
|
20
|
+
const day = dateCp.getUTCDay();
|
|
21
|
+
const diff = dateCp.getUTCDate() - day + (day ? 1 : -6); // adjust when day is sunday
|
|
22
|
+
dateCp.setUTCDate(diff);
|
|
23
|
+
return Date.UTC(
|
|
24
|
+
dateCp.getUTCFullYear(),
|
|
25
|
+
dateCp.getUTCMonth(),
|
|
26
|
+
dateCp.getUTCDate()
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {TileFormat} from '../constants.js';
|
|
2
|
+
import {Tilejson} from '../sources/types.js';
|
|
3
|
+
|
|
4
|
+
export function getTileFormat(tilejson: Tilejson): TileFormat {
|
|
5
|
+
const tileParams = new URL(tilejson.tiles[0]).searchParams;
|
|
6
|
+
return tileParams.get('formatTiles') === 'mvt'
|
|
7
|
+
? TileFormat.MVT
|
|
8
|
+
: TileFormat.BINARY;
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {FilterInterval, FilterIntervalComplete} from '../types';
|
|
2
|
+
|
|
3
|
+
export function makeIntervalComplete(
|
|
4
|
+
intervals: FilterInterval[]
|
|
5
|
+
): FilterIntervalComplete[] {
|
|
6
|
+
return intervals.map((val) => {
|
|
7
|
+
if (val[0] === undefined || val[0] === null) {
|
|
8
|
+
return [Number.MIN_SAFE_INTEGER, val[1]];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (val[1] === undefined || val[1] === null) {
|
|
12
|
+
return [val[0], Number.MAX_SAFE_INTEGER];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return val;
|
|
16
|
+
}) as FilterIntervalComplete[];
|
|
17
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {lerp} from '@math.gl/core';
|
|
2
|
+
import {lngLatToWorld, worldToLngLat} from '@math.gl/web-mercator';
|
|
3
|
+
import {BBox, GeoJsonGeometryTypes, Geometry, Position} from 'geojson';
|
|
4
|
+
|
|
5
|
+
type TransformFn = (coordinates: any[], bbox: Position[]) => any[];
|
|
6
|
+
|
|
7
|
+
const TRANSFORM_FN: Record<
|
|
8
|
+
Exclude<GeoJsonGeometryTypes, 'GeometryCollection'>,
|
|
9
|
+
TransformFn
|
|
10
|
+
> = {
|
|
11
|
+
Point: transformPoint,
|
|
12
|
+
MultiPoint: transformMultiPoint,
|
|
13
|
+
LineString: transformLineString,
|
|
14
|
+
MultiLineString: transformMultiLineString,
|
|
15
|
+
Polygon: transformPolygon,
|
|
16
|
+
MultiPolygon: transformMultiPolygon,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Transform tile coords to WGS84 coordinates.
|
|
21
|
+
*
|
|
22
|
+
* @param geometry - any valid geojson geometry
|
|
23
|
+
* @param bbox - geojson bbox
|
|
24
|
+
*/
|
|
25
|
+
export function transformTileCoordsToWGS84<T extends Geometry>(
|
|
26
|
+
geometry: T,
|
|
27
|
+
bbox: BBox
|
|
28
|
+
): T {
|
|
29
|
+
const [west, south, east, north] = bbox;
|
|
30
|
+
const nw = lngLatToWorld([west, north]);
|
|
31
|
+
const se = lngLatToWorld([east, south]);
|
|
32
|
+
const projectedBbox = [nw, se];
|
|
33
|
+
|
|
34
|
+
if (geometry.type === 'GeometryCollection') {
|
|
35
|
+
throw new Error('Unsupported geometry type GeometryCollection');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const transformFn = TRANSFORM_FN[geometry.type];
|
|
39
|
+
const coordinates = transformFn(geometry.coordinates, projectedBbox);
|
|
40
|
+
return {...geometry, coordinates};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function transformPoint([pointX, pointY]: Position, [nw, se]: Position[]) {
|
|
44
|
+
const x = lerp(nw[0], se[0], pointX);
|
|
45
|
+
const y = lerp(nw[1], se[1], pointY);
|
|
46
|
+
|
|
47
|
+
return worldToLngLat([x, y]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getPoints(geometry: Position[], bbox: Position[]) {
|
|
51
|
+
return geometry.map((g) => transformPoint(g, bbox));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function transformMultiPoint(multiPoint: Position[], bbox: Position[]) {
|
|
55
|
+
return getPoints(multiPoint, bbox);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function transformLineString(line: Position[], bbox: Position[]) {
|
|
59
|
+
return getPoints(line, bbox);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function transformMultiLineString(
|
|
63
|
+
multiLineString: Position[][],
|
|
64
|
+
bbox: Position[]
|
|
65
|
+
) {
|
|
66
|
+
return multiLineString.map((lineString) =>
|
|
67
|
+
transformLineString(lineString, bbox)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function transformPolygon(polygon: Position[][], bbox: Position[]) {
|
|
72
|
+
return polygon.map((polygonRing) => getPoints(polygonRing, bbox));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function transformMultiPolygon(multiPolygon: Position[][][], bbox: Position[]) {
|
|
76
|
+
return multiPolygon.map((polygon) => transformPolygon(polygon, bbox));
|
|
77
|
+
}
|