@carto/api-client 0.4.2-alpha.0 → 0.4.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/CHANGELOG.md +5 -1
- package/build/api/query.d.ts +1 -1
- package/build/api-client.cjs +48 -229
- package/build/api-client.cjs.map +1 -1
- package/build/api-client.modern.js +56 -232
- package/build/api-client.modern.js.map +1 -1
- package/build/models/model.d.ts +1 -7
- package/build/sources/types.d.ts +41 -36
- package/build/utils.d.ts +1 -1
- package/build/widget-sources/types.d.ts +1 -8
- package/build/widget-sources/widget-base-source.d.ts +1 -0
- package/package.json +1 -1
- package/src/api/query.ts +2 -1
- package/src/models/model.ts +24 -47
- package/src/sources/h3-query-source.ts +1 -7
- package/src/sources/h3-table-source.ts +1 -6
- package/src/sources/quadbin-query-source.ts +1 -6
- package/src/sources/quadbin-table-source.ts +1 -6
- package/src/sources/types.ts +45 -41
- package/src/sources/vector-query-source.ts +1 -4
- package/src/sources/vector-table-source.ts +1 -5
- package/src/utils.ts +1 -1
- package/src/widget-sources/types.ts +1 -9
- package/src/widget-sources/widget-base-source.ts +21 -190
- package/build/spatial-index.d.ts +0 -11
- package/src/spatial-index.ts +0 -119
|
@@ -16,10 +16,9 @@ import {
|
|
|
16
16
|
TableResponse,
|
|
17
17
|
TimeSeriesRequestOptions,
|
|
18
18
|
TimeSeriesResponse,
|
|
19
|
-
ViewState,
|
|
20
19
|
} from './types.js';
|
|
21
20
|
import {FilterLogicalOperator, Filter} from '../types.js';
|
|
22
|
-
import {
|
|
21
|
+
import {getApplicableFilters, normalizeObjectKeys} from '../utils.js';
|
|
23
22
|
import {getClient} from '../client.js';
|
|
24
23
|
import {ModelSource} from '../models/model.js';
|
|
25
24
|
import {SourceOptions} from '../sources/index.js';
|
|
@@ -28,11 +27,10 @@ import {
|
|
|
28
27
|
DEFAULT_GEO_COLUMN,
|
|
29
28
|
DEFAULT_TILE_RESOLUTION,
|
|
30
29
|
} from '../constants-internal.js';
|
|
31
|
-
import {getSpatialFiltersResolution} from '../spatial-index.js';
|
|
32
|
-
import {AggregationOptions} from '../sources/types.js';
|
|
33
30
|
|
|
34
31
|
export interface WidgetBaseSourceProps extends Omit<SourceOptions, 'filters'> {
|
|
35
32
|
apiVersion?: ApiVersion;
|
|
33
|
+
geoColumn?: string;
|
|
36
34
|
filters?: Record<string, Filter>;
|
|
37
35
|
filtersLogicalOperator?: FilterLogicalOperator;
|
|
38
36
|
}
|
|
@@ -53,6 +51,7 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
53
51
|
clientId: getClient(),
|
|
54
52
|
filters: {},
|
|
55
53
|
filtersLogicalOperator: 'and',
|
|
54
|
+
geoColumn: DEFAULT_GEO_COLUMN,
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
constructor(props: Props) {
|
|
@@ -79,9 +78,7 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
79
78
|
connectionName: props.connectionName,
|
|
80
79
|
filters: getApplicableFilters(owner, props.filters),
|
|
81
80
|
filtersLogicalOperator: props.filtersLogicalOperator,
|
|
82
|
-
|
|
83
|
-
spatialDataColumn: props.spatialDataColumn,
|
|
84
|
-
dataResolution: (props as Partial<AggregationOptions>).dataResolution,
|
|
81
|
+
geoColumn: props.geoColumn,
|
|
85
82
|
};
|
|
86
83
|
}
|
|
87
84
|
|
|
@@ -96,35 +93,14 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
96
93
|
async getCategories(
|
|
97
94
|
options: CategoryRequestOptions
|
|
98
95
|
): Promise<CategoryResponse> {
|
|
99
|
-
const {
|
|
100
|
-
filterOwner,
|
|
101
|
-
spatialFilter,
|
|
102
|
-
spatialFiltersMode,
|
|
103
|
-
abortController,
|
|
104
|
-
viewState,
|
|
105
|
-
...params
|
|
106
|
-
} = options;
|
|
96
|
+
const {filterOwner, spatialFilter, abortController, ...params} = options;
|
|
107
97
|
const {column, operation, operationColumn} = params;
|
|
108
|
-
const source = this.getModelSource(filterOwner);
|
|
109
|
-
|
|
110
|
-
let spatialFiltersResolution: number | undefined;
|
|
111
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
112
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
113
|
-
source,
|
|
114
|
-
viewState,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
98
|
|
|
118
99
|
type CategoriesModelResponse = {rows: {name: string; value: number}[]};
|
|
119
100
|
|
|
120
101
|
return executeModel({
|
|
121
102
|
model: 'category',
|
|
122
|
-
source: {
|
|
123
|
-
...source,
|
|
124
|
-
spatialFiltersResolution,
|
|
125
|
-
spatialFiltersMode,
|
|
126
|
-
spatialFilter,
|
|
127
|
-
},
|
|
103
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
128
104
|
params: {
|
|
129
105
|
column,
|
|
130
106
|
operation,
|
|
@@ -149,35 +125,14 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
149
125
|
async getFeatures(
|
|
150
126
|
options: FeaturesRequestOptions
|
|
151
127
|
): Promise<FeaturesResponse> {
|
|
152
|
-
const {
|
|
153
|
-
filterOwner,
|
|
154
|
-
spatialFilter,
|
|
155
|
-
spatialFiltersMode,
|
|
156
|
-
abortController,
|
|
157
|
-
viewState,
|
|
158
|
-
...params
|
|
159
|
-
} = options;
|
|
128
|
+
const {filterOwner, spatialFilter, abortController, ...params} = options;
|
|
160
129
|
const {columns, dataType, featureIds, z, limit, tileResolution} = params;
|
|
161
|
-
const source = this.getModelSource(filterOwner);
|
|
162
|
-
|
|
163
|
-
let spatialFiltersResolution: number | undefined;
|
|
164
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
165
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
166
|
-
source,
|
|
167
|
-
viewState,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
130
|
|
|
171
131
|
type FeaturesModelResponse = {rows: Record<string, unknown>[]};
|
|
172
132
|
|
|
173
133
|
return executeModel({
|
|
174
134
|
model: 'pick',
|
|
175
|
-
source: {
|
|
176
|
-
...source,
|
|
177
|
-
spatialFiltersResolution,
|
|
178
|
-
spatialFiltersMode,
|
|
179
|
-
spatialFilter,
|
|
180
|
-
},
|
|
135
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
181
136
|
params: {
|
|
182
137
|
columns,
|
|
183
138
|
dataType,
|
|
@@ -187,9 +142,8 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
187
142
|
tileResolution: tileResolution || DEFAULT_TILE_RESOLUTION,
|
|
188
143
|
},
|
|
189
144
|
opts: {abortController},
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}));
|
|
145
|
+
// Avoid `normalizeObjectKeys()`, which changes column names.
|
|
146
|
+
}).then(({rows}: FeaturesModelResponse) => ({rows}));
|
|
193
147
|
}
|
|
194
148
|
|
|
195
149
|
/****************************************************************************
|
|
@@ -204,33 +158,17 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
204
158
|
const {
|
|
205
159
|
filterOwner,
|
|
206
160
|
spatialFilter,
|
|
207
|
-
spatialFiltersMode,
|
|
208
161
|
abortController,
|
|
209
162
|
operationExp,
|
|
210
|
-
viewState,
|
|
211
163
|
...params
|
|
212
164
|
} = options;
|
|
213
165
|
const {column, operation} = params;
|
|
214
|
-
const source = this.getModelSource(filterOwner);
|
|
215
|
-
|
|
216
|
-
let spatialFiltersResolution: number | undefined;
|
|
217
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
218
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
219
|
-
source,
|
|
220
|
-
viewState,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
166
|
|
|
224
167
|
type FormulaModelResponse = {rows: {value: number}[]};
|
|
225
168
|
|
|
226
169
|
return executeModel({
|
|
227
170
|
model: 'formula',
|
|
228
|
-
source: {
|
|
229
|
-
...source,
|
|
230
|
-
spatialFiltersResolution,
|
|
231
|
-
spatialFiltersMode,
|
|
232
|
-
spatialFilter,
|
|
233
|
-
},
|
|
171
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
234
172
|
params: {column: column ?? '*', operation, operationExp},
|
|
235
173
|
opts: {abortController},
|
|
236
174
|
}).then((res: FormulaModelResponse) => normalizeObjectKeys(res.rows[0]));
|
|
@@ -247,35 +185,14 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
247
185
|
async getHistogram(
|
|
248
186
|
options: HistogramRequestOptions
|
|
249
187
|
): Promise<HistogramResponse> {
|
|
250
|
-
const {
|
|
251
|
-
filterOwner,
|
|
252
|
-
spatialFilter,
|
|
253
|
-
spatialFiltersMode,
|
|
254
|
-
abortController,
|
|
255
|
-
viewState,
|
|
256
|
-
...params
|
|
257
|
-
} = options;
|
|
188
|
+
const {filterOwner, spatialFilter, abortController, ...params} = options;
|
|
258
189
|
const {column, operation, ticks} = params;
|
|
259
|
-
const source = this.getModelSource(filterOwner);
|
|
260
|
-
|
|
261
|
-
let spatialFiltersResolution: number | undefined;
|
|
262
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
263
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
264
|
-
source,
|
|
265
|
-
viewState,
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
190
|
|
|
269
191
|
type HistogramModelResponse = {rows: {tick: number; value: number}[]};
|
|
270
192
|
|
|
271
193
|
const data = await executeModel({
|
|
272
194
|
model: 'histogram',
|
|
273
|
-
source: {
|
|
274
|
-
...source,
|
|
275
|
-
spatialFiltersResolution,
|
|
276
|
-
spatialFiltersMode,
|
|
277
|
-
spatialFilter,
|
|
278
|
-
},
|
|
195
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
279
196
|
params: {column, operation, ticks},
|
|
280
197
|
opts: {abortController},
|
|
281
198
|
}).then((res: HistogramModelResponse) => normalizeObjectKeys(res.rows));
|
|
@@ -303,35 +220,14 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
303
220
|
* or rendering a range slider UI for filtering.
|
|
304
221
|
*/
|
|
305
222
|
async getRange(options: RangeRequestOptions): Promise<RangeResponse> {
|
|
306
|
-
const {
|
|
307
|
-
filterOwner,
|
|
308
|
-
spatialFilter,
|
|
309
|
-
spatialFiltersMode,
|
|
310
|
-
abortController,
|
|
311
|
-
viewState,
|
|
312
|
-
...params
|
|
313
|
-
} = options;
|
|
223
|
+
const {filterOwner, spatialFilter, abortController, ...params} = options;
|
|
314
224
|
const {column} = params;
|
|
315
|
-
const source = this.getModelSource(filterOwner);
|
|
316
|
-
|
|
317
|
-
let spatialFiltersResolution: number | undefined;
|
|
318
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
319
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
320
|
-
source,
|
|
321
|
-
viewState,
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
225
|
|
|
325
226
|
type RangeModelResponse = {rows: {min: number; max: number}[]};
|
|
326
227
|
|
|
327
228
|
return executeModel({
|
|
328
229
|
model: 'range',
|
|
329
|
-
source: {
|
|
330
|
-
...source,
|
|
331
|
-
spatialFiltersResolution,
|
|
332
|
-
spatialFiltersMode,
|
|
333
|
-
spatialFilter,
|
|
334
|
-
},
|
|
230
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
335
231
|
params: {column},
|
|
336
232
|
opts: {abortController},
|
|
337
233
|
}).then((res: RangeModelResponse) => normalizeObjectKeys(res.rows[0]));
|
|
@@ -346,27 +242,10 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
346
242
|
* values. Suitable for rendering scatter plots.
|
|
347
243
|
*/
|
|
348
244
|
async getScatter(options: ScatterRequestOptions): Promise<ScatterResponse> {
|
|
349
|
-
const {
|
|
350
|
-
filterOwner,
|
|
351
|
-
spatialFilter,
|
|
352
|
-
spatialFiltersMode,
|
|
353
|
-
abortController,
|
|
354
|
-
viewState,
|
|
355
|
-
...params
|
|
356
|
-
} = options;
|
|
245
|
+
const {filterOwner, spatialFilter, abortController, ...params} = options;
|
|
357
246
|
const {xAxisColumn, xAxisJoinOperation, yAxisColumn, yAxisJoinOperation} =
|
|
358
247
|
params;
|
|
359
248
|
|
|
360
|
-
const source = this.getModelSource(filterOwner);
|
|
361
|
-
|
|
362
|
-
let spatialFiltersResolution: number | undefined;
|
|
363
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
364
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
365
|
-
source,
|
|
366
|
-
viewState,
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
|
|
370
249
|
// Make sure this is sync with the same constant in cloud-native/maps-api
|
|
371
250
|
const HARD_LIMIT = 500;
|
|
372
251
|
|
|
@@ -374,12 +253,7 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
374
253
|
|
|
375
254
|
return executeModel({
|
|
376
255
|
model: 'scatterplot',
|
|
377
|
-
source: {
|
|
378
|
-
...source,
|
|
379
|
-
spatialFiltersResolution,
|
|
380
|
-
spatialFiltersMode,
|
|
381
|
-
spatialFilter,
|
|
382
|
-
},
|
|
256
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
383
257
|
params: {
|
|
384
258
|
xAxisColumn,
|
|
385
259
|
xAxisJoinOperation,
|
|
@@ -402,24 +276,8 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
402
276
|
* sorting. Suitable for displaying tables and lists.
|
|
403
277
|
*/
|
|
404
278
|
async getTable(options: TableRequestOptions): Promise<TableResponse> {
|
|
405
|
-
const {
|
|
406
|
-
filterOwner,
|
|
407
|
-
spatialFilter,
|
|
408
|
-
spatialFiltersMode,
|
|
409
|
-
abortController,
|
|
410
|
-
viewState,
|
|
411
|
-
...params
|
|
412
|
-
} = options;
|
|
279
|
+
const {filterOwner, spatialFilter, abortController, ...params} = options;
|
|
413
280
|
const {columns, sortBy, sortDirection, offset = 0, limit = 10} = params;
|
|
414
|
-
const source = this.getModelSource(filterOwner);
|
|
415
|
-
|
|
416
|
-
let spatialFiltersResolution: number | undefined;
|
|
417
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
418
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
419
|
-
source,
|
|
420
|
-
viewState,
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
281
|
|
|
424
282
|
type TableModelResponse = {
|
|
425
283
|
rows: Record<string, number | string>[];
|
|
@@ -428,12 +286,7 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
428
286
|
|
|
429
287
|
return executeModel({
|
|
430
288
|
model: 'table',
|
|
431
|
-
source: {
|
|
432
|
-
...source,
|
|
433
|
-
spatialFiltersResolution,
|
|
434
|
-
spatialFiltersMode,
|
|
435
|
-
spatialFilter,
|
|
436
|
-
},
|
|
289
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
437
290
|
params: {
|
|
438
291
|
column: columns,
|
|
439
292
|
sortBy,
|
|
@@ -460,14 +313,7 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
460
313
|
async getTimeSeries(
|
|
461
314
|
options: TimeSeriesRequestOptions
|
|
462
315
|
): Promise<TimeSeriesResponse> {
|
|
463
|
-
const {
|
|
464
|
-
filterOwner,
|
|
465
|
-
abortController,
|
|
466
|
-
spatialFilter,
|
|
467
|
-
spatialFiltersMode,
|
|
468
|
-
viewState,
|
|
469
|
-
...params
|
|
470
|
-
} = options;
|
|
316
|
+
const {filterOwner, abortController, spatialFilter, ...params} = options;
|
|
471
317
|
const {
|
|
472
318
|
column,
|
|
473
319
|
operationColumn,
|
|
@@ -480,16 +326,6 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
480
326
|
splitByCategoryValues,
|
|
481
327
|
} = params;
|
|
482
328
|
|
|
483
|
-
const source = this.getModelSource(filterOwner);
|
|
484
|
-
|
|
485
|
-
let spatialFiltersResolution: number | undefined;
|
|
486
|
-
if (spatialFilter && source.spatialDataType !== 'geo') {
|
|
487
|
-
spatialFiltersResolution = getSpatialFiltersResolution({
|
|
488
|
-
source,
|
|
489
|
-
viewState,
|
|
490
|
-
});
|
|
491
|
-
}
|
|
492
|
-
|
|
493
329
|
type TimeSeriesModelResponse = {
|
|
494
330
|
rows: {name: string; value: number}[];
|
|
495
331
|
metadata: {categories: string[]};
|
|
@@ -497,12 +333,7 @@ export abstract class WidgetBaseSource<Props extends WidgetBaseSourceProps> {
|
|
|
497
333
|
|
|
498
334
|
return executeModel({
|
|
499
335
|
model: 'timeseries',
|
|
500
|
-
source: {
|
|
501
|
-
...source,
|
|
502
|
-
spatialFiltersResolution,
|
|
503
|
-
spatialFiltersMode,
|
|
504
|
-
spatialFilter,
|
|
505
|
-
},
|
|
336
|
+
source: {...this.getModelSource(filterOwner), spatialFilter},
|
|
506
337
|
params: {
|
|
507
338
|
column,
|
|
508
339
|
stepSize,
|
package/build/spatial-index.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ModelSource } from './models/model';
|
|
2
|
-
import type { AggregationOptions } from './sources/types';
|
|
3
|
-
import type { ViewState } from './widget-sources';
|
|
4
|
-
export declare function getSpatialFiltersResolution({ source, viewState, }: {
|
|
5
|
-
source: Partial<ModelSource & AggregationOptions>;
|
|
6
|
-
viewState?: ViewState;
|
|
7
|
-
}): number | undefined;
|
|
8
|
-
export declare function getHexagonResolution(viewport: {
|
|
9
|
-
zoom: number;
|
|
10
|
-
latitude: number;
|
|
11
|
-
}, tileSize: number): number;
|
package/src/spatial-index.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
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,
|
|
15
|
-
viewState,
|
|
16
|
-
}: {
|
|
17
|
-
source: Partial<ModelSource & AggregationOptions>;
|
|
18
|
-
viewState?: ViewState;
|
|
19
|
-
}) {
|
|
20
|
-
assert(
|
|
21
|
-
viewState,
|
|
22
|
-
'viewState prop is required to compute automatic spatialFiltersResolution when using spatialFilter with spatial indexes. Either pass a `spatialFiltersResolution` prop or a `viewState` prop to avoid this error'
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
const dataResolution = source.dataResolution ?? Number.MAX_VALUE;
|
|
26
|
-
|
|
27
|
-
const aggregationResLevel =
|
|
28
|
-
source.aggregationResLevel ??
|
|
29
|
-
(source.spatialDataType === 'h3'
|
|
30
|
-
? DEFAULT_AGGREGATION_RES_LEVEL_H3
|
|
31
|
-
: DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN);
|
|
32
|
-
|
|
33
|
-
const aggregationResLevelOffset = Math.max(
|
|
34
|
-
0,
|
|
35
|
-
Math.floor(aggregationResLevel)
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
const currentZoomInt = Math.ceil(viewState.zoom);
|
|
39
|
-
if (source.spatialDataType === 'h3') {
|
|
40
|
-
const tileSize = DEFAULT_TILE_SIZE;
|
|
41
|
-
const maxResolutionForZoom =
|
|
42
|
-
maxH3SpatialFiltersResolutions.find(
|
|
43
|
-
([zoom]) => zoom === currentZoomInt
|
|
44
|
-
)?.[1] ?? Math.max(0, currentZoomInt - 3);
|
|
45
|
-
|
|
46
|
-
const maxSpatialFiltersResolution = maxResolutionForZoom
|
|
47
|
-
? Math.min(dataResolution, maxResolutionForZoom)
|
|
48
|
-
: dataResolution;
|
|
49
|
-
|
|
50
|
-
const hexagonResolution =
|
|
51
|
-
getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
|
|
52
|
-
|
|
53
|
-
return Math.min(hexagonResolution, maxSpatialFiltersResolution);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (source.spatialDataType === 'quadbin') {
|
|
57
|
-
const maxResolutionForZoom = currentZoomInt + QUADBIN_ZOOM_MAX_OFFSET;
|
|
58
|
-
const maxSpatialFiltersResolution = Math.min(
|
|
59
|
-
dataResolution,
|
|
60
|
-
maxResolutionForZoom
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
const quadsResolution =
|
|
64
|
-
Math.floor(viewState.zoom) + aggregationResLevelOffset;
|
|
65
|
-
return Math.min(quadsResolution, maxSpatialFiltersResolution);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const maxH3SpatialFiltersResolutions = [
|
|
72
|
-
[20, 14],
|
|
73
|
-
[19, 13],
|
|
74
|
-
[18, 12],
|
|
75
|
-
[17, 11],
|
|
76
|
-
[16, 10],
|
|
77
|
-
[15, 9],
|
|
78
|
-
[14, 8],
|
|
79
|
-
[13, 7],
|
|
80
|
-
[12, 7],
|
|
81
|
-
[11, 7],
|
|
82
|
-
[10, 6],
|
|
83
|
-
[9, 6],
|
|
84
|
-
[8, 5],
|
|
85
|
-
[7, 4],
|
|
86
|
-
[6, 4],
|
|
87
|
-
[5, 3],
|
|
88
|
-
[4, 2],
|
|
89
|
-
[3, 1],
|
|
90
|
-
[2, 1],
|
|
91
|
-
[1, 0],
|
|
92
|
-
];
|
|
93
|
-
|
|
94
|
-
// stolen from https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
|
|
95
|
-
|
|
96
|
-
// Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
|
|
97
|
-
const BIAS = 2;
|
|
98
|
-
|
|
99
|
-
// Resolution conversion function. Takes a WebMercatorViewport and returns
|
|
100
|
-
// a H3 resolution such that the screen space size of the hexagons is
|
|
101
|
-
// similar
|
|
102
|
-
export function getHexagonResolution(
|
|
103
|
-
viewport: {zoom: number; latitude: number},
|
|
104
|
-
tileSize: number
|
|
105
|
-
): number {
|
|
106
|
-
// Difference in given tile size compared to deck's internal 512px tile size,
|
|
107
|
-
// expressed as an offset to the viewport zoom.
|
|
108
|
-
const zoomOffset = Math.log2(tileSize / DEFAULT_TILE_SIZE);
|
|
109
|
-
const hexagonScaleFactor = (2 / 3) * (viewport.zoom - zoomOffset);
|
|
110
|
-
const latitudeScaleFactor = Math.log(
|
|
111
|
-
1 / Math.cos((Math.PI * viewport.latitude) / 180)
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
// Clip and bias
|
|
115
|
-
return Math.max(
|
|
116
|
-
0,
|
|
117
|
-
Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS)
|
|
118
|
-
);
|
|
119
|
-
}
|