@carto/api-client 0.5.0-alpha.1 → 0.5.0-alpha.3
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/build/api-client.cjs +235 -498
- package/build/api-client.cjs.map +1 -1
- package/build/api-client.modern.js +232 -502
- package/build/api-client.modern.js.map +1 -1
- package/build/filters/tileFeatures.d.ts +3 -2
- package/build/filters/tileFeaturesRaster.d.ts +16 -0
- package/build/index.d.ts +1 -0
- package/build/sources/raster-source.d.ts +2 -1
- package/build/sources/types.d.ts +1 -1
- package/build/spatial-index.d.ts +7 -1
- package/build/types.d.ts +8 -0
- package/build/widget-sources/index.d.ts +2 -0
- package/build/widget-sources/widget-raster-source.d.ts +11 -0
- package/build/widget-sources/widget-tileset-source.d.ts +5 -4
- package/package.json +12 -6
- package/src/filters/tileFeatures.ts +27 -11
- package/src/filters/tileFeaturesRaster.ts +111 -0
- package/src/index.ts +2 -0
- package/src/sources/raster-source.ts +14 -5
- package/src/sources/types.ts +1 -1
- package/src/spatial-index.ts +8 -6
- package/src/types.ts +6 -0
- package/src/widget-sources/index.ts +2 -0
- package/src/widget-sources/widget-raster-source.ts +14 -0
- package/src/widget-sources/widget-tileset-source.ts +6 -9
package/build/api-client.cjs
CHANGED
|
@@ -6,6 +6,7 @@ var helpers = require('@turf/helpers');
|
|
|
6
6
|
var intersects = require('@turf/boolean-intersects');
|
|
7
7
|
var booleanWithin = require('@turf/boolean-within');
|
|
8
8
|
var intersect = require('@turf/intersect');
|
|
9
|
+
var quadbin = require('quadbin');
|
|
9
10
|
var h3Js = require('h3-js');
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -796,6 +797,98 @@ const boundaryTableSource = function (options) {
|
|
|
796
797
|
}
|
|
797
798
|
};
|
|
798
799
|
|
|
800
|
+
const DEFAULT_TILE_SIZE = 512;
|
|
801
|
+
const QUADBIN_ZOOM_MAX_OFFSET = 4;
|
|
802
|
+
function getSpatialFiltersResolution(source, viewState) {
|
|
803
|
+
const dataResolution = source.dataResolution ?? Number.MAX_VALUE;
|
|
804
|
+
const aggregationResLevel = source.aggregationResLevel ?? (source.spatialDataType === 'h3' ? DEFAULT_AGGREGATION_RES_LEVEL_H3 : DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN);
|
|
805
|
+
const aggregationResLevelOffset = Math.max(0, Math.floor(aggregationResLevel));
|
|
806
|
+
const currentZoomInt = Math.ceil(viewState.zoom);
|
|
807
|
+
if (source.spatialDataType === 'h3') {
|
|
808
|
+
const tileSize = DEFAULT_TILE_SIZE;
|
|
809
|
+
const maxResolutionForZoom = maxH3SpatialFiltersResolutions.find(_ref => {
|
|
810
|
+
let [zoom] = _ref;
|
|
811
|
+
return zoom === currentZoomInt;
|
|
812
|
+
})?.[1] ?? Math.max(0, currentZoomInt - 3);
|
|
813
|
+
const maxSpatialFiltersResolution = maxResolutionForZoom ? Math.min(dataResolution, maxResolutionForZoom) : dataResolution;
|
|
814
|
+
const hexagonResolution = _getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
|
|
815
|
+
return Math.min(hexagonResolution, maxSpatialFiltersResolution);
|
|
816
|
+
}
|
|
817
|
+
if (source.spatialDataType === 'quadbin') {
|
|
818
|
+
const maxResolutionForZoom = currentZoomInt + QUADBIN_ZOOM_MAX_OFFSET;
|
|
819
|
+
const maxSpatialFiltersResolution = Math.min(dataResolution, maxResolutionForZoom);
|
|
820
|
+
const quadsResolution = Math.floor(viewState.zoom) + aggregationResLevelOffset;
|
|
821
|
+
return Math.min(quadsResolution, maxSpatialFiltersResolution);
|
|
822
|
+
}
|
|
823
|
+
return undefined;
|
|
824
|
+
}
|
|
825
|
+
const maxH3SpatialFiltersResolutions = [[20, 14], [19, 13], [18, 12], [17, 11], [16, 10], [15, 9], [14, 8], [13, 7], [12, 7], [11, 7], [10, 6], [9, 6], [8, 5], [7, 4], [6, 4], [5, 3], [4, 2], [3, 1], [2, 1], [1, 0]];
|
|
826
|
+
// stolen from https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
|
|
827
|
+
// Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
|
|
828
|
+
const BIAS = 2;
|
|
829
|
+
/**
|
|
830
|
+
* Resolution conversion function. Takes a WebMercatorViewport and returns
|
|
831
|
+
* a H3 resolution such that the screen space size of the hexagons is
|
|
832
|
+
* "similar" to the given tileSize on screen. Intended for use with deck.gl.
|
|
833
|
+
* @internal
|
|
834
|
+
*/
|
|
835
|
+
function _getHexagonResolution(viewport, tileSize) {
|
|
836
|
+
// Difference in given tile size compared to deck's internal 512px tile size,
|
|
837
|
+
// expressed as an offset to the viewport zoom.
|
|
838
|
+
const zoomOffset = Math.log2(tileSize / DEFAULT_TILE_SIZE);
|
|
839
|
+
const hexagonScaleFactor = 2 / 3 * (viewport.zoom - zoomOffset);
|
|
840
|
+
const latitudeScaleFactor = Math.log(1 / Math.cos(Math.PI * viewport.latitude / 180));
|
|
841
|
+
// Clip and bias
|
|
842
|
+
return Math.max(0, Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS));
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* Source for Widget API requests on a data source defined by a SQL query.
|
|
847
|
+
*
|
|
848
|
+
* Abstract class. Use {@link WidgetQuerySource} or {@link WidgetTableSource}.
|
|
849
|
+
*/
|
|
850
|
+
class WidgetSource {
|
|
851
|
+
constructor(props) {
|
|
852
|
+
this.props = void 0;
|
|
853
|
+
this.props = {
|
|
854
|
+
...WidgetSource.defaultProps,
|
|
855
|
+
...props
|
|
856
|
+
};
|
|
857
|
+
}
|
|
858
|
+
_getModelSource(owner) {
|
|
859
|
+
const props = this.props;
|
|
860
|
+
return {
|
|
861
|
+
apiVersion: props.apiVersion,
|
|
862
|
+
apiBaseUrl: props.apiBaseUrl,
|
|
863
|
+
clientId: props.clientId,
|
|
864
|
+
accessToken: props.accessToken,
|
|
865
|
+
connectionName: props.connectionName,
|
|
866
|
+
filters: getApplicableFilters(owner, props.filters),
|
|
867
|
+
filtersLogicalOperator: props.filtersLogicalOperator,
|
|
868
|
+
spatialDataType: props.spatialDataType,
|
|
869
|
+
spatialDataColumn: props.spatialDataColumn,
|
|
870
|
+
dataResolution: props.dataResolution
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
_getSpatialFiltersResolution(source, spatialFilter, referenceViewState) {
|
|
874
|
+
// spatialFiltersResolution applies only to spatial index sources.
|
|
875
|
+
if (!spatialFilter || source.spatialDataType === 'geo') {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
if (!referenceViewState) {
|
|
879
|
+
throw new Error('Missing required option, "spatialIndexReferenceViewState".');
|
|
880
|
+
}
|
|
881
|
+
return getSpatialFiltersResolution(source, referenceViewState);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
WidgetSource.defaultProps = {
|
|
885
|
+
apiVersion: exports.ApiVersion.V3,
|
|
886
|
+
apiBaseUrl: DEFAULT_API_BASE_URL,
|
|
887
|
+
clientId: getClient(),
|
|
888
|
+
filters: {},
|
|
889
|
+
filtersLogicalOperator: 'and'
|
|
890
|
+
};
|
|
891
|
+
|
|
799
892
|
/**
|
|
800
893
|
* Return more descriptive error from API
|
|
801
894
|
* @internalRemarks Source: @carto/react-api
|
|
@@ -990,95 +1083,6 @@ function objectToURLSearchParams(object) {
|
|
|
990
1083
|
return params;
|
|
991
1084
|
}
|
|
992
1085
|
|
|
993
|
-
const DEFAULT_TILE_SIZE = 512;
|
|
994
|
-
const QUADBIN_ZOOM_MAX_OFFSET = 4;
|
|
995
|
-
function getSpatialFiltersResolution(source, viewState) {
|
|
996
|
-
const dataResolution = source.dataResolution ?? Number.MAX_VALUE;
|
|
997
|
-
const aggregationResLevel = source.aggregationResLevel ?? (source.spatialDataType === 'h3' ? DEFAULT_AGGREGATION_RES_LEVEL_H3 : DEFAULT_AGGREGATION_RES_LEVEL_QUADBIN);
|
|
998
|
-
const aggregationResLevelOffset = Math.max(0, Math.floor(aggregationResLevel));
|
|
999
|
-
const currentZoomInt = Math.ceil(viewState.zoom);
|
|
1000
|
-
if (source.spatialDataType === 'h3') {
|
|
1001
|
-
const tileSize = DEFAULT_TILE_SIZE;
|
|
1002
|
-
const maxResolutionForZoom = maxH3SpatialFiltersResolutions.find(_ref => {
|
|
1003
|
-
let [zoom] = _ref;
|
|
1004
|
-
return zoom === currentZoomInt;
|
|
1005
|
-
})?.[1] ?? Math.max(0, currentZoomInt - 3);
|
|
1006
|
-
const maxSpatialFiltersResolution = maxResolutionForZoom ? Math.min(dataResolution, maxResolutionForZoom) : dataResolution;
|
|
1007
|
-
const hexagonResolution = getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
|
|
1008
|
-
return Math.min(hexagonResolution, maxSpatialFiltersResolution);
|
|
1009
|
-
}
|
|
1010
|
-
if (source.spatialDataType === 'quadbin') {
|
|
1011
|
-
const maxResolutionForZoom = currentZoomInt + QUADBIN_ZOOM_MAX_OFFSET;
|
|
1012
|
-
const maxSpatialFiltersResolution = Math.min(dataResolution, maxResolutionForZoom);
|
|
1013
|
-
const quadsResolution = Math.floor(viewState.zoom) + aggregationResLevelOffset;
|
|
1014
|
-
return Math.min(quadsResolution, maxSpatialFiltersResolution);
|
|
1015
|
-
}
|
|
1016
|
-
return undefined;
|
|
1017
|
-
}
|
|
1018
|
-
const maxH3SpatialFiltersResolutions = [[20, 14], [19, 13], [18, 12], [17, 11], [16, 10], [15, 9], [14, 8], [13, 7], [12, 7], [11, 7], [10, 6], [9, 6], [8, 5], [7, 4], [6, 4], [5, 3], [4, 2], [3, 1], [2, 1], [1, 0]];
|
|
1019
|
-
// stolen from https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
|
|
1020
|
-
// Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
|
|
1021
|
-
const BIAS = 2;
|
|
1022
|
-
// Resolution conversion function. Takes a WebMercatorViewport and returns
|
|
1023
|
-
// a H3 resolution such that the screen space size of the hexagons is
|
|
1024
|
-
// similar
|
|
1025
|
-
function getHexagonResolution(viewport, tileSize) {
|
|
1026
|
-
// Difference in given tile size compared to deck's internal 512px tile size,
|
|
1027
|
-
// expressed as an offset to the viewport zoom.
|
|
1028
|
-
const zoomOffset = Math.log2(tileSize / DEFAULT_TILE_SIZE);
|
|
1029
|
-
const hexagonScaleFactor = 2 / 3 * (viewport.zoom - zoomOffset);
|
|
1030
|
-
const latitudeScaleFactor = Math.log(1 / Math.cos(Math.PI * viewport.latitude / 180));
|
|
1031
|
-
// Clip and bias
|
|
1032
|
-
return Math.max(0, Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS));
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
/**
|
|
1036
|
-
* Source for Widget API requests on a data source defined by a SQL query.
|
|
1037
|
-
*
|
|
1038
|
-
* Abstract class. Use {@link WidgetQuerySource} or {@link WidgetTableSource}.
|
|
1039
|
-
*/
|
|
1040
|
-
class WidgetSource {
|
|
1041
|
-
constructor(props) {
|
|
1042
|
-
this.props = void 0;
|
|
1043
|
-
this.props = {
|
|
1044
|
-
...WidgetSource.defaultProps,
|
|
1045
|
-
...props
|
|
1046
|
-
};
|
|
1047
|
-
}
|
|
1048
|
-
_getModelSource(owner) {
|
|
1049
|
-
const props = this.props;
|
|
1050
|
-
return {
|
|
1051
|
-
apiVersion: props.apiVersion,
|
|
1052
|
-
apiBaseUrl: props.apiBaseUrl,
|
|
1053
|
-
clientId: props.clientId,
|
|
1054
|
-
accessToken: props.accessToken,
|
|
1055
|
-
connectionName: props.connectionName,
|
|
1056
|
-
filters: getApplicableFilters(owner, props.filters),
|
|
1057
|
-
filtersLogicalOperator: props.filtersLogicalOperator,
|
|
1058
|
-
spatialDataType: props.spatialDataType,
|
|
1059
|
-
spatialDataColumn: props.spatialDataColumn,
|
|
1060
|
-
dataResolution: props.dataResolution
|
|
1061
|
-
};
|
|
1062
|
-
}
|
|
1063
|
-
_getSpatialFiltersResolution(source, spatialFilter, referenceViewState) {
|
|
1064
|
-
// spatialFiltersResolution applies only to spatial index sources.
|
|
1065
|
-
if (!spatialFilter || source.spatialDataType === 'geo') {
|
|
1066
|
-
return;
|
|
1067
|
-
}
|
|
1068
|
-
if (!referenceViewState) {
|
|
1069
|
-
throw new Error('Missing required option, "spatialIndexReferenceViewState".');
|
|
1070
|
-
}
|
|
1071
|
-
return getSpatialFiltersResolution(source, referenceViewState);
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
WidgetSource.defaultProps = {
|
|
1075
|
-
apiVersion: exports.ApiVersion.V3,
|
|
1076
|
-
apiBaseUrl: DEFAULT_API_BASE_URL,
|
|
1077
|
-
clientId: getClient(),
|
|
1078
|
-
filters: {},
|
|
1079
|
-
filtersLogicalOperator: 'and'
|
|
1080
|
-
};
|
|
1081
|
-
|
|
1082
1086
|
/**
|
|
1083
1087
|
* Source for Widget API requests.
|
|
1084
1088
|
*
|
|
@@ -1491,38 +1495,6 @@ class WidgetQuerySource extends WidgetRemoteSource {
|
|
|
1491
1495
|
}
|
|
1492
1496
|
}
|
|
1493
1497
|
|
|
1494
|
-
/**
|
|
1495
|
-
* Source for Widget API requests on a data source defined as a table.
|
|
1496
|
-
*
|
|
1497
|
-
* Generally not intended to be constructed directly. Instead, call
|
|
1498
|
-
* {@link vectorTableSource}, {@link h3TableSource}, or {@link quadbinTableSource},
|
|
1499
|
-
* which can be shared with map layers. Sources contain a `widgetSource` property,
|
|
1500
|
-
* for use by widget implementations.
|
|
1501
|
-
*
|
|
1502
|
-
* Example:
|
|
1503
|
-
*
|
|
1504
|
-
* ```javascript
|
|
1505
|
-
* import { vectorTableSource } from '@carto/api-client';
|
|
1506
|
-
*
|
|
1507
|
-
* const data = vectorTableSource({
|
|
1508
|
-
* accessToken: '••••',
|
|
1509
|
-
* connectionName: 'carto_dw',
|
|
1510
|
-
* tableName: 'carto-demo-data.demo_tables.retail_stores'
|
|
1511
|
-
* });
|
|
1512
|
-
*
|
|
1513
|
-
* const { widgetSource } = await data;
|
|
1514
|
-
* ```
|
|
1515
|
-
*/
|
|
1516
|
-
class WidgetTableSource extends WidgetRemoteSource {
|
|
1517
|
-
getModelSource(owner) {
|
|
1518
|
-
return {
|
|
1519
|
-
...super._getModelSource(owner),
|
|
1520
|
-
type: 'table',
|
|
1521
|
-
data: this.props.tableName
|
|
1522
|
-
};
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1526
1498
|
function makeIntervalComplete(intervals) {
|
|
1527
1499
|
return intervals.map(val => {
|
|
1528
1500
|
if (val[0] === undefined || val[0] === null) {
|
|
@@ -2236,369 +2208,6 @@ function createIndicesForPoints(data) {
|
|
|
2236
2208
|
data.pointIndices = pointIndices;
|
|
2237
2209
|
}
|
|
2238
2210
|
|
|
2239
|
-
// a tile is an array [x,y,z]
|
|
2240
|
-
var d2r = Math.PI / 180,
|
|
2241
|
-
r2d = 180 / Math.PI;
|
|
2242
|
-
function tileToBBOX(tile) {
|
|
2243
|
-
var e = tile2lon(tile[0] + 1, tile[2]);
|
|
2244
|
-
var w = tile2lon(tile[0], tile[2]);
|
|
2245
|
-
var s = tile2lat(tile[1] + 1, tile[2]);
|
|
2246
|
-
var n = tile2lat(tile[1], tile[2]);
|
|
2247
|
-
return [w, s, e, n];
|
|
2248
|
-
}
|
|
2249
|
-
function tileToGeoJSON(tile) {
|
|
2250
|
-
var bbox = tileToBBOX(tile);
|
|
2251
|
-
var poly = {
|
|
2252
|
-
type: 'Polygon',
|
|
2253
|
-
coordinates: [[[bbox[0], bbox[1]], [bbox[0], bbox[3]], [bbox[2], bbox[3]], [bbox[2], bbox[1]], [bbox[0], bbox[1]]]]
|
|
2254
|
-
};
|
|
2255
|
-
return poly;
|
|
2256
|
-
}
|
|
2257
|
-
function tile2lon(x, z) {
|
|
2258
|
-
return x / Math.pow(2, z) * 360 - 180;
|
|
2259
|
-
}
|
|
2260
|
-
function tile2lat(y, z) {
|
|
2261
|
-
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
|
|
2262
|
-
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
|
2263
|
-
}
|
|
2264
|
-
function pointToTile(lon, lat, z) {
|
|
2265
|
-
var tile = pointToTileFraction(lon, lat, z);
|
|
2266
|
-
tile[0] = Math.floor(tile[0]);
|
|
2267
|
-
tile[1] = Math.floor(tile[1]);
|
|
2268
|
-
return tile;
|
|
2269
|
-
}
|
|
2270
|
-
function getChildren(tile) {
|
|
2271
|
-
return [[tile[0] * 2, tile[1] * 2, tile[2] + 1], [tile[0] * 2 + 1, tile[1] * 2, tile[2] + 1], [tile[0] * 2 + 1, tile[1] * 2 + 1, tile[2] + 1], [tile[0] * 2, tile[1] * 2 + 1, tile[2] + 1]];
|
|
2272
|
-
}
|
|
2273
|
-
function getParent(tile) {
|
|
2274
|
-
// top left
|
|
2275
|
-
if (tile[0] % 2 === 0 && tile[1] % 2 === 0) {
|
|
2276
|
-
return [tile[0] / 2, tile[1] / 2, tile[2] - 1];
|
|
2277
|
-
}
|
|
2278
|
-
// bottom left
|
|
2279
|
-
else if (tile[0] % 2 === 0 && !tile[1] % 2 === 0) {
|
|
2280
|
-
return [tile[0] / 2, (tile[1] - 1) / 2, tile[2] - 1];
|
|
2281
|
-
}
|
|
2282
|
-
// top right
|
|
2283
|
-
else if (!tile[0] % 2 === 0 && tile[1] % 2 === 0) {
|
|
2284
|
-
return [(tile[0] - 1) / 2, tile[1] / 2, tile[2] - 1];
|
|
2285
|
-
}
|
|
2286
|
-
// bottom right
|
|
2287
|
-
else {
|
|
2288
|
-
return [(tile[0] - 1) / 2, (tile[1] - 1) / 2, tile[2] - 1];
|
|
2289
|
-
}
|
|
2290
|
-
}
|
|
2291
|
-
function getSiblings(tile) {
|
|
2292
|
-
return getChildren(getParent(tile));
|
|
2293
|
-
}
|
|
2294
|
-
function hasSiblings(tile, tiles) {
|
|
2295
|
-
var siblings = getSiblings(tile);
|
|
2296
|
-
for (var i = 0; i < siblings.length; i++) {
|
|
2297
|
-
if (!hasTile(tiles, siblings[i])) return false;
|
|
2298
|
-
}
|
|
2299
|
-
return true;
|
|
2300
|
-
}
|
|
2301
|
-
function hasTile(tiles, tile) {
|
|
2302
|
-
for (var i = 0; i < tiles.length; i++) {
|
|
2303
|
-
if (tilesEqual(tiles[i], tile)) return true;
|
|
2304
|
-
}
|
|
2305
|
-
return false;
|
|
2306
|
-
}
|
|
2307
|
-
function tilesEqual(tile1, tile2) {
|
|
2308
|
-
return tile1[0] === tile2[0] && tile1[1] === tile2[1] && tile1[2] === tile2[2];
|
|
2309
|
-
}
|
|
2310
|
-
function tileToQuadkey(tile) {
|
|
2311
|
-
var index = '';
|
|
2312
|
-
for (var z = tile[2]; z > 0; z--) {
|
|
2313
|
-
var b = 0;
|
|
2314
|
-
var mask = 1 << z - 1;
|
|
2315
|
-
if ((tile[0] & mask) !== 0) b++;
|
|
2316
|
-
if ((tile[1] & mask) !== 0) b += 2;
|
|
2317
|
-
index += b.toString();
|
|
2318
|
-
}
|
|
2319
|
-
return index;
|
|
2320
|
-
}
|
|
2321
|
-
function quadkeyToTile(quadkey) {
|
|
2322
|
-
var x = 0;
|
|
2323
|
-
var y = 0;
|
|
2324
|
-
var z = quadkey.length;
|
|
2325
|
-
for (var i = z; i > 0; i--) {
|
|
2326
|
-
var mask = 1 << i - 1;
|
|
2327
|
-
switch (quadkey[z - i]) {
|
|
2328
|
-
case '0':
|
|
2329
|
-
break;
|
|
2330
|
-
case '1':
|
|
2331
|
-
x |= mask;
|
|
2332
|
-
break;
|
|
2333
|
-
case '2':
|
|
2334
|
-
y |= mask;
|
|
2335
|
-
break;
|
|
2336
|
-
case '3':
|
|
2337
|
-
x |= mask;
|
|
2338
|
-
y |= mask;
|
|
2339
|
-
break;
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
return [x, y, z];
|
|
2343
|
-
}
|
|
2344
|
-
function bboxToTile(bboxCoords) {
|
|
2345
|
-
var min = pointToTile(bboxCoords[0], bboxCoords[1], 32);
|
|
2346
|
-
var max = pointToTile(bboxCoords[2], bboxCoords[3], 32);
|
|
2347
|
-
var bbox = [min[0], min[1], max[0], max[1]];
|
|
2348
|
-
var z = getBboxZoom(bbox);
|
|
2349
|
-
if (z === 0) return [0, 0, 0];
|
|
2350
|
-
var x = bbox[0] >>> 32 - z;
|
|
2351
|
-
var y = bbox[1] >>> 32 - z;
|
|
2352
|
-
return [x, y, z];
|
|
2353
|
-
}
|
|
2354
|
-
function getBboxZoom(bbox) {
|
|
2355
|
-
var MAX_ZOOM = 28;
|
|
2356
|
-
for (var z = 0; z < MAX_ZOOM; z++) {
|
|
2357
|
-
var mask = 1 << 32 - (z + 1);
|
|
2358
|
-
if ((bbox[0] & mask) != (bbox[2] & mask) || (bbox[1] & mask) != (bbox[3] & mask)) {
|
|
2359
|
-
return z;
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2362
|
-
return MAX_ZOOM;
|
|
2363
|
-
}
|
|
2364
|
-
function pointToTileFraction(lon, lat, z) {
|
|
2365
|
-
var sin = Math.sin(lat * d2r),
|
|
2366
|
-
z2 = Math.pow(2, z),
|
|
2367
|
-
x = z2 * (lon / 360 + 0.5),
|
|
2368
|
-
y = z2 * (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI);
|
|
2369
|
-
return [x, y, z];
|
|
2370
|
-
}
|
|
2371
|
-
var tilebelt = {
|
|
2372
|
-
tileToGeoJSON: tileToGeoJSON,
|
|
2373
|
-
tileToBBOX: tileToBBOX,
|
|
2374
|
-
getChildren: getChildren,
|
|
2375
|
-
getParent: getParent,
|
|
2376
|
-
getSiblings: getSiblings,
|
|
2377
|
-
hasTile: hasTile,
|
|
2378
|
-
hasSiblings: hasSiblings,
|
|
2379
|
-
tilesEqual: tilesEqual,
|
|
2380
|
-
tileToQuadkey: tileToQuadkey,
|
|
2381
|
-
quadkeyToTile: quadkeyToTile,
|
|
2382
|
-
pointToTile: pointToTile,
|
|
2383
|
-
bboxToTile: bboxToTile,
|
|
2384
|
-
pointToTileFraction: pointToTileFraction
|
|
2385
|
-
};
|
|
2386
|
-
|
|
2387
|
-
/**
|
|
2388
|
-
* Given a geometry, create cells and return them in their raw form,
|
|
2389
|
-
* as an array of cell identifiers.
|
|
2390
|
-
*
|
|
2391
|
-
* @alias tiles
|
|
2392
|
-
* @param {Object} geom GeoJSON geometry
|
|
2393
|
-
* @param {Object} limits an object with min_zoom and max_zoom properties
|
|
2394
|
-
* specifying the minimum and maximum level to be tiled.
|
|
2395
|
-
* @returns {Array<Array<number>>} An array of tiles given as [x, y, z] arrays
|
|
2396
|
-
*/
|
|
2397
|
-
var tiles = getTiles;
|
|
2398
|
-
function getTiles(geom, limits) {
|
|
2399
|
-
var i,
|
|
2400
|
-
tile,
|
|
2401
|
-
coords = geom.coordinates,
|
|
2402
|
-
maxZoom = limits.max_zoom,
|
|
2403
|
-
tileHash = {},
|
|
2404
|
-
tiles = [];
|
|
2405
|
-
if (geom.type === 'Point') {
|
|
2406
|
-
return [tilebelt.pointToTile(coords[0], coords[1], maxZoom)];
|
|
2407
|
-
} else if (geom.type === 'MultiPoint') {
|
|
2408
|
-
for (i = 0; i < coords.length; i++) {
|
|
2409
|
-
tile = tilebelt.pointToTile(coords[i][0], coords[i][1], maxZoom);
|
|
2410
|
-
tileHash[toID(tile[0], tile[1], tile[2])] = true;
|
|
2411
|
-
}
|
|
2412
|
-
} else if (geom.type === 'LineString') {
|
|
2413
|
-
lineCover(tileHash, coords, maxZoom);
|
|
2414
|
-
} else if (geom.type === 'MultiLineString') {
|
|
2415
|
-
for (i = 0; i < coords.length; i++) {
|
|
2416
|
-
lineCover(tileHash, coords[i], maxZoom);
|
|
2417
|
-
}
|
|
2418
|
-
} else if (geom.type === 'Polygon') {
|
|
2419
|
-
polygonCover(tileHash, tiles, coords, maxZoom);
|
|
2420
|
-
} else if (geom.type === 'MultiPolygon') {
|
|
2421
|
-
for (i = 0; i < coords.length; i++) {
|
|
2422
|
-
polygonCover(tileHash, tiles, coords[i], maxZoom);
|
|
2423
|
-
}
|
|
2424
|
-
} else {
|
|
2425
|
-
throw new Error('Geometry type not implemented');
|
|
2426
|
-
}
|
|
2427
|
-
if (limits.min_zoom !== maxZoom) {
|
|
2428
|
-
// sync tile hash and tile array so that both contain the same tiles
|
|
2429
|
-
var len = tiles.length;
|
|
2430
|
-
appendHashTiles(tileHash, tiles);
|
|
2431
|
-
for (i = 0; i < len; i++) {
|
|
2432
|
-
var t = tiles[i];
|
|
2433
|
-
tileHash[toID(t[0], t[1], t[2])] = true;
|
|
2434
|
-
}
|
|
2435
|
-
return mergeTiles(tileHash, tiles, limits);
|
|
2436
|
-
}
|
|
2437
|
-
appendHashTiles(tileHash, tiles);
|
|
2438
|
-
return tiles;
|
|
2439
|
-
}
|
|
2440
|
-
function mergeTiles(tileHash, tiles, limits) {
|
|
2441
|
-
var mergedTiles = [];
|
|
2442
|
-
for (var z = limits.max_zoom; z > limits.min_zoom; z--) {
|
|
2443
|
-
var parentTileHash = {};
|
|
2444
|
-
var parentTiles = [];
|
|
2445
|
-
for (var i = 0; i < tiles.length; i++) {
|
|
2446
|
-
var t = tiles[i];
|
|
2447
|
-
if (t[0] % 2 === 0 && t[1] % 2 === 0) {
|
|
2448
|
-
var id2 = toID(t[0] + 1, t[1], z),
|
|
2449
|
-
id3 = toID(t[0], t[1] + 1, z),
|
|
2450
|
-
id4 = toID(t[0] + 1, t[1] + 1, z);
|
|
2451
|
-
if (tileHash[id2] && tileHash[id3] && tileHash[id4]) {
|
|
2452
|
-
tileHash[toID(t[0], t[1], t[2])] = false;
|
|
2453
|
-
tileHash[id2] = false;
|
|
2454
|
-
tileHash[id3] = false;
|
|
2455
|
-
tileHash[id4] = false;
|
|
2456
|
-
var parentTile = [t[0] / 2, t[1] / 2, z - 1];
|
|
2457
|
-
if (z - 1 === limits.min_zoom) mergedTiles.push(parentTile);else {
|
|
2458
|
-
parentTileHash[toID(t[0] / 2, t[1] / 2, z - 1)] = true;
|
|
2459
|
-
parentTiles.push(parentTile);
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
for (i = 0; i < tiles.length; i++) {
|
|
2465
|
-
t = tiles[i];
|
|
2466
|
-
if (tileHash[toID(t[0], t[1], t[2])]) mergedTiles.push(t);
|
|
2467
|
-
}
|
|
2468
|
-
tileHash = parentTileHash;
|
|
2469
|
-
tiles = parentTiles;
|
|
2470
|
-
}
|
|
2471
|
-
return mergedTiles;
|
|
2472
|
-
}
|
|
2473
|
-
function polygonCover(tileHash, tileArray, geom, zoom) {
|
|
2474
|
-
var intersections = [];
|
|
2475
|
-
for (var i = 0; i < geom.length; i++) {
|
|
2476
|
-
var ring = [];
|
|
2477
|
-
lineCover(tileHash, geom[i], zoom, ring);
|
|
2478
|
-
for (var j = 0, len = ring.length, k = len - 1; j < len; k = j++) {
|
|
2479
|
-
var m = (j + 1) % len;
|
|
2480
|
-
var y = ring[j][1];
|
|
2481
|
-
|
|
2482
|
-
// add interesction if it's not local extremum or duplicate
|
|
2483
|
-
if ((y > ring[k][1] || y > ring[m][1]) && (
|
|
2484
|
-
// not local minimum
|
|
2485
|
-
y < ring[k][1] || y < ring[m][1]) &&
|
|
2486
|
-
// not local maximum
|
|
2487
|
-
y !== ring[m][1]) intersections.push(ring[j]);
|
|
2488
|
-
}
|
|
2489
|
-
}
|
|
2490
|
-
intersections.sort(compareTiles); // sort by y, then x
|
|
2491
|
-
|
|
2492
|
-
for (i = 0; i < intersections.length; i += 2) {
|
|
2493
|
-
// fill tiles between pairs of intersections
|
|
2494
|
-
y = intersections[i][1];
|
|
2495
|
-
for (var x = intersections[i][0] + 1; x < intersections[i + 1][0]; x++) {
|
|
2496
|
-
var id = toID(x, y, zoom);
|
|
2497
|
-
if (!tileHash[id]) {
|
|
2498
|
-
tileArray.push([x, y, zoom]);
|
|
2499
|
-
}
|
|
2500
|
-
}
|
|
2501
|
-
}
|
|
2502
|
-
}
|
|
2503
|
-
function compareTiles(a, b) {
|
|
2504
|
-
return a[1] - b[1] || a[0] - b[0];
|
|
2505
|
-
}
|
|
2506
|
-
function lineCover(tileHash, coords, maxZoom, ring) {
|
|
2507
|
-
var prevX, prevY;
|
|
2508
|
-
for (var i = 0; i < coords.length - 1; i++) {
|
|
2509
|
-
var start = tilebelt.pointToTileFraction(coords[i][0], coords[i][1], maxZoom),
|
|
2510
|
-
stop = tilebelt.pointToTileFraction(coords[i + 1][0], coords[i + 1][1], maxZoom),
|
|
2511
|
-
x0 = start[0],
|
|
2512
|
-
y0 = start[1],
|
|
2513
|
-
x1 = stop[0],
|
|
2514
|
-
y1 = stop[1],
|
|
2515
|
-
dx = x1 - x0,
|
|
2516
|
-
dy = y1 - y0;
|
|
2517
|
-
if (dy === 0 && dx === 0) continue;
|
|
2518
|
-
var sx = dx > 0 ? 1 : -1,
|
|
2519
|
-
sy = dy > 0 ? 1 : -1,
|
|
2520
|
-
x = Math.floor(x0),
|
|
2521
|
-
y = Math.floor(y0),
|
|
2522
|
-
tMaxX = dx === 0 ? Infinity : Math.abs(((dx > 0 ? 1 : 0) + x - x0) / dx),
|
|
2523
|
-
tMaxY = dy === 0 ? Infinity : Math.abs(((dy > 0 ? 1 : 0) + y - y0) / dy),
|
|
2524
|
-
tdx = Math.abs(sx / dx),
|
|
2525
|
-
tdy = Math.abs(sy / dy);
|
|
2526
|
-
if (x !== prevX || y !== prevY) {
|
|
2527
|
-
tileHash[toID(x, y, maxZoom)] = true;
|
|
2528
|
-
if (ring && y !== prevY) ring.push([x, y]);
|
|
2529
|
-
prevX = x;
|
|
2530
|
-
prevY = y;
|
|
2531
|
-
}
|
|
2532
|
-
while (tMaxX < 1 || tMaxY < 1) {
|
|
2533
|
-
if (tMaxX < tMaxY) {
|
|
2534
|
-
tMaxX += tdx;
|
|
2535
|
-
x += sx;
|
|
2536
|
-
} else {
|
|
2537
|
-
tMaxY += tdy;
|
|
2538
|
-
y += sy;
|
|
2539
|
-
}
|
|
2540
|
-
tileHash[toID(x, y, maxZoom)] = true;
|
|
2541
|
-
if (ring && y !== prevY) ring.push([x, y]);
|
|
2542
|
-
prevX = x;
|
|
2543
|
-
prevY = y;
|
|
2544
|
-
}
|
|
2545
|
-
}
|
|
2546
|
-
if (ring && y === ring[0][1]) ring.pop();
|
|
2547
|
-
}
|
|
2548
|
-
function appendHashTiles(hash, tiles) {
|
|
2549
|
-
var keys = Object.keys(hash);
|
|
2550
|
-
for (var i = 0; i < keys.length; i++) {
|
|
2551
|
-
tiles.push(fromID(+keys[i]));
|
|
2552
|
-
}
|
|
2553
|
-
}
|
|
2554
|
-
function toID(x, y, z) {
|
|
2555
|
-
var dim = 2 * (1 << z);
|
|
2556
|
-
return (dim * y + x) * 32 + z;
|
|
2557
|
-
}
|
|
2558
|
-
function fromID(id) {
|
|
2559
|
-
var z = id % 32,
|
|
2560
|
-
dim = 2 * (1 << z),
|
|
2561
|
-
xy = (id - z) / 32,
|
|
2562
|
-
x = xy % dim,
|
|
2563
|
-
y = (xy - x) / dim % dim;
|
|
2564
|
-
return [x, y, z];
|
|
2565
|
-
}
|
|
2566
|
-
|
|
2567
|
-
const B = [0x5555555555555555n, 0x3333333333333333n, 0x0f0f0f0f0f0f0f0fn, 0x00ff00ff00ff00ffn, 0x0000ffff0000ffffn, 0x00000000ffffffffn];
|
|
2568
|
-
const S = [0n, 1n, 2n, 4n, 8n, 16n];
|
|
2569
|
-
function tileToCell(tile) {
|
|
2570
|
-
if (tile.z < 0 || tile.z > 26) {
|
|
2571
|
-
throw new Error('Wrong zoom');
|
|
2572
|
-
}
|
|
2573
|
-
const z = BigInt(tile.z);
|
|
2574
|
-
let x = BigInt(tile.x) << 32n - z;
|
|
2575
|
-
let y = BigInt(tile.y) << 32n - z;
|
|
2576
|
-
for (let i = 0; i < 5; i++) {
|
|
2577
|
-
const s = S[5 - i];
|
|
2578
|
-
const b = B[4 - i];
|
|
2579
|
-
x = (x | x << s) & b;
|
|
2580
|
-
y = (y | y << s) & b;
|
|
2581
|
-
}
|
|
2582
|
-
const quadbin = 0x4000000000000000n | 1n << 59n |
|
|
2583
|
-
// | (mode << 59) | (mode_dep << 57)
|
|
2584
|
-
z << 52n | (x | y << 1n) >> 12n | 0xfffffffffffffn >> z * 2n;
|
|
2585
|
-
return quadbin;
|
|
2586
|
-
}
|
|
2587
|
-
function getResolution$1(quadbin) {
|
|
2588
|
-
return quadbin >> 52n & 0x1fn;
|
|
2589
|
-
}
|
|
2590
|
-
function geometryToCells(geometry, resolution) {
|
|
2591
|
-
const zoom = Number(resolution);
|
|
2592
|
-
return tiles(geometry, {
|
|
2593
|
-
min_zoom: zoom,
|
|
2594
|
-
max_zoom: zoom
|
|
2595
|
-
}).map(([x, y, z]) => tileToCell({
|
|
2596
|
-
x,
|
|
2597
|
-
y,
|
|
2598
|
-
z
|
|
2599
|
-
}));
|
|
2600
|
-
}
|
|
2601
|
-
|
|
2602
2211
|
function tileFeaturesSpatialIndex(_ref) {
|
|
2603
2212
|
let {
|
|
2604
2213
|
tiles,
|
|
@@ -2640,7 +2249,7 @@ function getResolution(tiles, spatialIndex) {
|
|
|
2640
2249
|
return;
|
|
2641
2250
|
}
|
|
2642
2251
|
if (spatialIndex === exports.SpatialIndex.QUADBIN) {
|
|
2643
|
-
return Number(getResolution
|
|
2252
|
+
return Number(quadbin.getResolution(data[0].id));
|
|
2644
2253
|
}
|
|
2645
2254
|
if (spatialIndex === exports.SpatialIndex.H3) {
|
|
2646
2255
|
return h3Js.getResolution(data[0].id);
|
|
@@ -2651,7 +2260,7 @@ const bboxEast = [0, -90, 180, 90];
|
|
|
2651
2260
|
function getCellsCoverGeometry(geometry, spatialIndex, resolution) {
|
|
2652
2261
|
if (spatialIndex === exports.SpatialIndex.QUADBIN) {
|
|
2653
2262
|
// @ts-expect-error TODO: Probably ought to be stricter about number vs. bigint types in this file.
|
|
2654
|
-
return geometryToCells(geometry, resolution);
|
|
2263
|
+
return quadbin.geometryToCells(geometry, resolution);
|
|
2655
2264
|
}
|
|
2656
2265
|
if (spatialIndex === exports.SpatialIndex.H3) {
|
|
2657
2266
|
// The current H3 polyfill algorithm can't deal with polygon segments of greater than 180 degrees longitude
|
|
@@ -2671,6 +2280,79 @@ function getSpatialIndex(spatialDataType) {
|
|
|
2671
2280
|
}
|
|
2672
2281
|
}
|
|
2673
2282
|
|
|
2283
|
+
function tileFeaturesRaster(_ref) {
|
|
2284
|
+
let {
|
|
2285
|
+
tiles,
|
|
2286
|
+
...options
|
|
2287
|
+
} = _ref;
|
|
2288
|
+
// Cache band metadata for faster lookup while iterating over pixels.
|
|
2289
|
+
const bandMetadataByName = {};
|
|
2290
|
+
for (const band of options.rasterMetadata.bands) {
|
|
2291
|
+
bandMetadataByName[band.name] = band;
|
|
2292
|
+
}
|
|
2293
|
+
// Omit empty and invisible tiles for simpler processing and types.
|
|
2294
|
+
tiles = tiles.filter(isRasterTileVisible);
|
|
2295
|
+
if (tiles.length === 0) return [];
|
|
2296
|
+
// Raster tiles, and all pixels, are quadbin cells. Resolution of a pixel is
|
|
2297
|
+
// the resolution of the tile, plus the number of subdivisions. Block size
|
|
2298
|
+
// must be square, N x N, where N is a power of two.
|
|
2299
|
+
const tileResolution = quadbin.getResolution(tiles[0].index.q);
|
|
2300
|
+
const tileBlockSize = tiles[0].data.blockSize;
|
|
2301
|
+
const cellResolution = tileResolution + BigInt(Math.log2(tileBlockSize));
|
|
2302
|
+
// Compute covering cells for the spatial filter, at same resolution as the
|
|
2303
|
+
// raster pixels, to be used as a mask.
|
|
2304
|
+
const spatialFilterCells = new Set(quadbin.geometryToCells(options.spatialFilter, cellResolution));
|
|
2305
|
+
const data = new Map();
|
|
2306
|
+
for (const tile of tiles) {
|
|
2307
|
+
const parent = tile.index.q;
|
|
2308
|
+
const children = cellToChildrenSorted(parent, cellResolution);
|
|
2309
|
+
// For each pixel/cell within the spatial filter, create a FeatureData.
|
|
2310
|
+
// Order is row-major, starting from NW and ending at SE.
|
|
2311
|
+
for (let i = 0; i < children.length; i++) {
|
|
2312
|
+
if (!spatialFilterCells.has(children[i])) continue;
|
|
2313
|
+
const cellData = {};
|
|
2314
|
+
let cellDataExists = false;
|
|
2315
|
+
for (const band in tile.data.cells.numericProps) {
|
|
2316
|
+
const value = tile.data.cells.numericProps[band].value[i];
|
|
2317
|
+
// TODO(cleanup): nodata should be a number, not a string.
|
|
2318
|
+
if (Number(bandMetadataByName[band].nodata) !== value) {
|
|
2319
|
+
cellData[band] = tile.data.cells.numericProps[band].value[i];
|
|
2320
|
+
cellDataExists = true;
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
if (cellDataExists) {
|
|
2324
|
+
data.set(children[i], cellData);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
return Array.from(data.values());
|
|
2329
|
+
}
|
|
2330
|
+
/**
|
|
2331
|
+
* Detects whether a given {@link Tile} is a {@link RasterTile}.
|
|
2332
|
+
* @privateRemarks Method of detection is arbitrary, and may be changed.
|
|
2333
|
+
*/
|
|
2334
|
+
function isRasterTile(tile) {
|
|
2335
|
+
return tile.data ? tile.data.hasOwnProperty('cells') : false;
|
|
2336
|
+
}
|
|
2337
|
+
function isRasterTileVisible(tile) {
|
|
2338
|
+
return !!(tile.isVisible && tile.data?.cells?.numericProps);
|
|
2339
|
+
}
|
|
2340
|
+
/**
|
|
2341
|
+
* For the raster format, children are sorted in row-major order, starting from
|
|
2342
|
+
* NW and ending at SE. Order returned by quadbin's cellToChildren() is not
|
|
2343
|
+
* defined (and not related to the raster format), so sort explicitly here.
|
|
2344
|
+
*/
|
|
2345
|
+
function cellToChildrenSorted(parent, resolution) {
|
|
2346
|
+
return quadbin.cellToChildren(parent, resolution).sort((cellA, cellB) => {
|
|
2347
|
+
const tileA = quadbin.cellToTile(cellA);
|
|
2348
|
+
const tileB = quadbin.cellToTile(cellB);
|
|
2349
|
+
if (tileA.y !== tileB.y) {
|
|
2350
|
+
return tileA.y > tileB.y ? 1 : -1;
|
|
2351
|
+
}
|
|
2352
|
+
return tileA.x > tileB.x ? 1 : -1;
|
|
2353
|
+
});
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2674
2356
|
/** @internalRemarks Source: @carto/react-core */
|
|
2675
2357
|
function tileFeatures(_ref) {
|
|
2676
2358
|
let {
|
|
@@ -2680,6 +2362,7 @@ function tileFeatures(_ref) {
|
|
|
2680
2362
|
tileFormat,
|
|
2681
2363
|
spatialDataColumn = DEFAULT_GEO_COLUMN,
|
|
2682
2364
|
spatialDataType,
|
|
2365
|
+
rasterMetadata,
|
|
2683
2366
|
options = {}
|
|
2684
2367
|
} = _ref;
|
|
2685
2368
|
// TODO(cleanup): Is an empty response the expected result when spatialFilter
|
|
@@ -2687,20 +2370,30 @@ function tileFeatures(_ref) {
|
|
|
2687
2370
|
if (!spatialFilter) {
|
|
2688
2371
|
return [];
|
|
2689
2372
|
}
|
|
2690
|
-
if (spatialDataType
|
|
2691
|
-
return
|
|
2373
|
+
if (spatialDataType === 'geo') {
|
|
2374
|
+
return tileFeaturesGeometries({
|
|
2375
|
+
tiles,
|
|
2376
|
+
tileFormat,
|
|
2377
|
+
spatialFilter,
|
|
2378
|
+
uniqueIdProperty,
|
|
2379
|
+
options
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
if (tiles.some(isRasterTile)) {
|
|
2383
|
+
assert$1(rasterMetadata, 'Missing raster metadata');
|
|
2384
|
+
return tileFeaturesRaster({
|
|
2692
2385
|
tiles: tiles,
|
|
2693
2386
|
spatialFilter,
|
|
2694
2387
|
spatialDataColumn,
|
|
2695
|
-
spatialDataType
|
|
2388
|
+
spatialDataType,
|
|
2389
|
+
rasterMetadata
|
|
2696
2390
|
});
|
|
2697
2391
|
}
|
|
2698
|
-
return
|
|
2699
|
-
tiles,
|
|
2700
|
-
tileFormat,
|
|
2392
|
+
return tileFeaturesSpatialIndex({
|
|
2393
|
+
tiles: tiles,
|
|
2701
2394
|
spatialFilter,
|
|
2702
|
-
|
|
2703
|
-
|
|
2395
|
+
spatialDataColumn,
|
|
2396
|
+
spatialDataType
|
|
2704
2397
|
});
|
|
2705
2398
|
}
|
|
2706
2399
|
|
|
@@ -3185,9 +2878,7 @@ class WidgetTilesetSource extends WidgetSource {
|
|
|
3185
2878
|
options,
|
|
3186
2879
|
spatialFilter,
|
|
3187
2880
|
uniqueIdProperty,
|
|
3188
|
-
|
|
3189
|
-
spatialDataColumn: this.props.spatialDataColumn,
|
|
3190
|
-
spatialDataType: this.props.spatialDataType
|
|
2881
|
+
...this.props
|
|
3191
2882
|
});
|
|
3192
2883
|
}
|
|
3193
2884
|
/** Loads features as GeoJSON (used for testing). */
|
|
@@ -3458,6 +3149,40 @@ function normalizeColumns(columns) {
|
|
|
3458
3149
|
return Array.isArray(columns) ? columns : typeof columns === 'string' ? [columns] : [];
|
|
3459
3150
|
}
|
|
3460
3151
|
|
|
3152
|
+
class WidgetRasterSource extends WidgetTilesetSource {}
|
|
3153
|
+
|
|
3154
|
+
/**
|
|
3155
|
+
* Source for Widget API requests on a data source defined as a table.
|
|
3156
|
+
*
|
|
3157
|
+
* Generally not intended to be constructed directly. Instead, call
|
|
3158
|
+
* {@link vectorTableSource}, {@link h3TableSource}, or {@link quadbinTableSource},
|
|
3159
|
+
* which can be shared with map layers. Sources contain a `widgetSource` property,
|
|
3160
|
+
* for use by widget implementations.
|
|
3161
|
+
*
|
|
3162
|
+
* Example:
|
|
3163
|
+
*
|
|
3164
|
+
* ```javascript
|
|
3165
|
+
* import { vectorTableSource } from '@carto/api-client';
|
|
3166
|
+
*
|
|
3167
|
+
* const data = vectorTableSource({
|
|
3168
|
+
* accessToken: '••••',
|
|
3169
|
+
* connectionName: 'carto_dw',
|
|
3170
|
+
* tableName: 'carto-demo-data.demo_tables.retail_stores'
|
|
3171
|
+
* });
|
|
3172
|
+
*
|
|
3173
|
+
* const { widgetSource } = await data;
|
|
3174
|
+
* ```
|
|
3175
|
+
*/
|
|
3176
|
+
class WidgetTableSource extends WidgetRemoteSource {
|
|
3177
|
+
getModelSource(owner) {
|
|
3178
|
+
return {
|
|
3179
|
+
...super._getModelSource(owner),
|
|
3180
|
+
type: 'table',
|
|
3181
|
+
data: this.props.tableName
|
|
3182
|
+
};
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3185
|
+
|
|
3461
3186
|
// deck.gl
|
|
3462
3187
|
// SPDX-License-Identifier: MIT
|
|
3463
3188
|
// Copyright (c) vis.gl contributors
|
|
@@ -3588,7 +3313,16 @@ const rasterSource = function (options) {
|
|
|
3588
3313
|
if (filters) {
|
|
3589
3314
|
urlParameters.filters = filters;
|
|
3590
3315
|
}
|
|
3591
|
-
return Promise.resolve(baseSource('raster', options, urlParameters)
|
|
3316
|
+
return Promise.resolve(baseSource('raster', options, urlParameters).then(result => ({
|
|
3317
|
+
...result,
|
|
3318
|
+
widgetSource: new WidgetRasterSource({
|
|
3319
|
+
...options,
|
|
3320
|
+
tileFormat: getTileFormat(result),
|
|
3321
|
+
spatialDataColumn: 'quadbin',
|
|
3322
|
+
spatialDataType: 'quadbin',
|
|
3323
|
+
rasterMetadata: result.raster_metadata
|
|
3324
|
+
})
|
|
3325
|
+
})));
|
|
3592
3326
|
} catch (e) {
|
|
3593
3327
|
return Promise.reject(e);
|
|
3594
3328
|
}
|
|
@@ -3880,9 +3614,12 @@ exports.DEFAULT_API_BASE_URL = DEFAULT_API_BASE_URL;
|
|
|
3880
3614
|
exports.FEATURE_GEOM_PROPERTY = FEATURE_GEOM_PROPERTY;
|
|
3881
3615
|
exports.SOURCE_DEFAULTS = SOURCE_DEFAULTS;
|
|
3882
3616
|
exports.WidgetQuerySource = WidgetQuerySource;
|
|
3617
|
+
exports.WidgetRasterSource = WidgetRasterSource;
|
|
3883
3618
|
exports.WidgetRemoteSource = WidgetRemoteSource;
|
|
3619
|
+
exports.WidgetSource = WidgetSource;
|
|
3884
3620
|
exports.WidgetTableSource = WidgetTableSource;
|
|
3885
3621
|
exports.WidgetTilesetSource = WidgetTilesetSource;
|
|
3622
|
+
exports._getHexagonResolution = _getHexagonResolution;
|
|
3886
3623
|
exports.addFilter = addFilter;
|
|
3887
3624
|
exports.aggregate = aggregate;
|
|
3888
3625
|
exports.aggregationFunctions = aggregationFunctions;
|