@carto/api-client 0.5.0-alpha.2 → 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.
@@ -6,6 +6,7 @@ import { featureCollection, feature, polygon, multiPolygon } from '@turf/helpers
6
6
  import intersects from '@turf/boolean-intersects';
7
7
  import booleanWithin from '@turf/boolean-within';
8
8
  import intersect from '@turf/intersect';
9
+ import { getResolution as getResolution$1, geometryToCells, cellToChildren, cellToTile } from 'quadbin';
9
10
  import { getResolution as getResolution$2, polygonToCells } from 'h3-js';
10
11
 
11
12
  /**
@@ -635,7 +636,7 @@ function excludeURLParameters(baseUrlString, parameters) {
635
636
  return baseUrl.toString();
636
637
  }
637
638
 
638
- const _excluded$2 = ["accessToken", "connectionName", "cache"];
639
+ const _excluded$3 = ["accessToken", "connectionName", "cache"];
639
640
  const SOURCE_DEFAULTS = {
640
641
  apiBaseUrl: DEFAULT_API_BASE_URL,
641
642
  clientId: getClient(),
@@ -649,7 +650,7 @@ async function baseSource(endpoint, options, urlParameters) {
649
650
  connectionName,
650
651
  cache
651
652
  } = options,
652
- optionalOptions = _objectWithoutPropertiesLoose(options, _excluded$2);
653
+ optionalOptions = _objectWithoutPropertiesLoose(options, _excluded$3);
653
654
  const mergedOptions = _extends({}, SOURCE_DEFAULTS, {
654
655
  accessToken,
655
656
  connectionName,
@@ -777,7 +778,7 @@ function getSpatialFiltersResolution(source, viewState) {
777
778
  const tileSize = DEFAULT_TILE_SIZE;
778
779
  const maxResolutionForZoom = (_maxH3SpatialFiltersR = (_maxH3SpatialFiltersR2 = maxH3SpatialFiltersResolutions.find(([zoom]) => zoom === currentZoomInt)) == null ? void 0 : _maxH3SpatialFiltersR2[1]) != null ? _maxH3SpatialFiltersR : Math.max(0, currentZoomInt - 3);
779
780
  const maxSpatialFiltersResolution = maxResolutionForZoom ? Math.min(dataResolution, maxResolutionForZoom) : dataResolution;
780
- const hexagonResolution = getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
781
+ const hexagonResolution = _getHexagonResolution(viewState, tileSize) + aggregationResLevelOffset;
781
782
  return Math.min(hexagonResolution, maxSpatialFiltersResolution);
782
783
  }
783
784
  if (source.spatialDataType === 'quadbin') {
@@ -792,10 +793,13 @@ const maxH3SpatialFiltersResolutions = [[20, 14], [19, 13], [18, 12], [17, 11],
792
793
  // stolen from https://github.com/visgl/deck.gl/blob/master/modules/carto/src/layers/h3-tileset-2d.ts
793
794
  // Relative scale factor (0 = no biasing, 2 = a few hexagons cover view)
794
795
  const BIAS = 2;
795
- // Resolution conversion function. Takes a WebMercatorViewport and returns
796
- // a H3 resolution such that the screen space size of the hexagons is
797
- // similar
798
- function getHexagonResolution(viewport, tileSize) {
796
+ /**
797
+ * Resolution conversion function. Takes a WebMercatorViewport and returns
798
+ * a H3 resolution such that the screen space size of the hexagons is
799
+ * "similar" to the given tileSize on screen. Intended for use with deck.gl.
800
+ * @internal
801
+ */
802
+ function _getHexagonResolution(viewport, tileSize) {
799
803
  // Difference in given tile size compared to deck's internal 512px tile size,
800
804
  // expressed as an offset to the viewport zoom.
801
805
  const zoomOffset = Math.log2(tileSize / DEFAULT_TILE_SIZE);
@@ -1013,7 +1017,7 @@ function objectToURLSearchParams(object) {
1013
1017
  return params;
1014
1018
  }
1015
1019
 
1016
- const _excluded$1 = ["filterOwner", "spatialFilter", "spatialFiltersMode", "spatialIndexReferenceViewState", "abortController"],
1020
+ const _excluded$2 = ["filterOwner", "spatialFilter", "spatialFiltersMode", "spatialIndexReferenceViewState", "abortController"],
1017
1021
  _excluded2 = ["filterOwner", "spatialFilter", "spatialFiltersMode", "spatialIndexReferenceViewState", "abortController"],
1018
1022
  _excluded3 = ["filterOwner", "spatialFilter", "spatialFiltersMode", "spatialIndexReferenceViewState", "abortController", "operationExp"],
1019
1023
  _excluded4 = ["filterOwner", "spatialFilter", "spatialFiltersMode", "spatialIndexReferenceViewState", "abortController"],
@@ -1035,7 +1039,7 @@ class WidgetRemoteSource extends WidgetSource {
1035
1039
  spatialIndexReferenceViewState,
1036
1040
  abortController
1037
1041
  } = options,
1038
- params = _objectWithoutPropertiesLoose(options, _excluded$1);
1042
+ params = _objectWithoutPropertiesLoose(options, _excluded$2);
1039
1043
  const {
1040
1044
  column,
1041
1045
  operation,
@@ -1380,37 +1384,6 @@ class WidgetQuerySource extends WidgetRemoteSource {
1380
1384
  }
1381
1385
  }
1382
1386
 
1383
- /**
1384
- * Source for Widget API requests on a data source defined as a table.
1385
- *
1386
- * Generally not intended to be constructed directly. Instead, call
1387
- * {@link vectorTableSource}, {@link h3TableSource}, or {@link quadbinTableSource},
1388
- * which can be shared with map layers. Sources contain a `widgetSource` property,
1389
- * for use by widget implementations.
1390
- *
1391
- * Example:
1392
- *
1393
- * ```javascript
1394
- * import { vectorTableSource } from '@carto/api-client';
1395
- *
1396
- * const data = vectorTableSource({
1397
- * accessToken: '••••',
1398
- * connectionName: 'carto_dw',
1399
- * tableName: 'carto-demo-data.demo_tables.retail_stores'
1400
- * });
1401
- *
1402
- * const { widgetSource } = await data;
1403
- * ```
1404
- */
1405
- class WidgetTableSource extends WidgetRemoteSource {
1406
- getModelSource(owner) {
1407
- return _extends({}, super._getModelSource(owner), {
1408
- type: 'table',
1409
- data: this.props.tableName
1410
- });
1411
- }
1412
- }
1413
-
1414
1387
  function makeIntervalComplete(intervals) {
1415
1388
  return intervals.map(val => {
1416
1389
  if (val[0] === undefined || val[0] === null) {
@@ -2107,369 +2080,6 @@ function createIndicesForPoints(data) {
2107
2080
  data.pointIndices = pointIndices;
2108
2081
  }
2109
2082
 
2110
- // a tile is an array [x,y,z]
2111
- var d2r = Math.PI / 180,
2112
- r2d = 180 / Math.PI;
2113
- function tileToBBOX(tile) {
2114
- var e = tile2lon(tile[0] + 1, tile[2]);
2115
- var w = tile2lon(tile[0], tile[2]);
2116
- var s = tile2lat(tile[1] + 1, tile[2]);
2117
- var n = tile2lat(tile[1], tile[2]);
2118
- return [w, s, e, n];
2119
- }
2120
- function tileToGeoJSON(tile) {
2121
- var bbox = tileToBBOX(tile);
2122
- var poly = {
2123
- type: 'Polygon',
2124
- coordinates: [[[bbox[0], bbox[1]], [bbox[0], bbox[3]], [bbox[2], bbox[3]], [bbox[2], bbox[1]], [bbox[0], bbox[1]]]]
2125
- };
2126
- return poly;
2127
- }
2128
- function tile2lon(x, z) {
2129
- return x / Math.pow(2, z) * 360 - 180;
2130
- }
2131
- function tile2lat(y, z) {
2132
- var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
2133
- return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
2134
- }
2135
- function pointToTile(lon, lat, z) {
2136
- var tile = pointToTileFraction(lon, lat, z);
2137
- tile[0] = Math.floor(tile[0]);
2138
- tile[1] = Math.floor(tile[1]);
2139
- return tile;
2140
- }
2141
- function getChildren(tile) {
2142
- 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]];
2143
- }
2144
- function getParent(tile) {
2145
- // top left
2146
- if (tile[0] % 2 === 0 && tile[1] % 2 === 0) {
2147
- return [tile[0] / 2, tile[1] / 2, tile[2] - 1];
2148
- }
2149
- // bottom left
2150
- else if (tile[0] % 2 === 0 && !tile[1] % 2 === 0) {
2151
- return [tile[0] / 2, (tile[1] - 1) / 2, tile[2] - 1];
2152
- }
2153
- // top right
2154
- else if (!tile[0] % 2 === 0 && tile[1] % 2 === 0) {
2155
- return [(tile[0] - 1) / 2, tile[1] / 2, tile[2] - 1];
2156
- }
2157
- // bottom right
2158
- else {
2159
- return [(tile[0] - 1) / 2, (tile[1] - 1) / 2, tile[2] - 1];
2160
- }
2161
- }
2162
- function getSiblings(tile) {
2163
- return getChildren(getParent(tile));
2164
- }
2165
- function hasSiblings(tile, tiles) {
2166
- var siblings = getSiblings(tile);
2167
- for (var i = 0; i < siblings.length; i++) {
2168
- if (!hasTile(tiles, siblings[i])) return false;
2169
- }
2170
- return true;
2171
- }
2172
- function hasTile(tiles, tile) {
2173
- for (var i = 0; i < tiles.length; i++) {
2174
- if (tilesEqual(tiles[i], tile)) return true;
2175
- }
2176
- return false;
2177
- }
2178
- function tilesEqual(tile1, tile2) {
2179
- return tile1[0] === tile2[0] && tile1[1] === tile2[1] && tile1[2] === tile2[2];
2180
- }
2181
- function tileToQuadkey(tile) {
2182
- var index = '';
2183
- for (var z = tile[2]; z > 0; z--) {
2184
- var b = 0;
2185
- var mask = 1 << z - 1;
2186
- if ((tile[0] & mask) !== 0) b++;
2187
- if ((tile[1] & mask) !== 0) b += 2;
2188
- index += b.toString();
2189
- }
2190
- return index;
2191
- }
2192
- function quadkeyToTile(quadkey) {
2193
- var x = 0;
2194
- var y = 0;
2195
- var z = quadkey.length;
2196
- for (var i = z; i > 0; i--) {
2197
- var mask = 1 << i - 1;
2198
- switch (quadkey[z - i]) {
2199
- case '0':
2200
- break;
2201
- case '1':
2202
- x |= mask;
2203
- break;
2204
- case '2':
2205
- y |= mask;
2206
- break;
2207
- case '3':
2208
- x |= mask;
2209
- y |= mask;
2210
- break;
2211
- }
2212
- }
2213
- return [x, y, z];
2214
- }
2215
- function bboxToTile(bboxCoords) {
2216
- var min = pointToTile(bboxCoords[0], bboxCoords[1], 32);
2217
- var max = pointToTile(bboxCoords[2], bboxCoords[3], 32);
2218
- var bbox = [min[0], min[1], max[0], max[1]];
2219
- var z = getBboxZoom(bbox);
2220
- if (z === 0) return [0, 0, 0];
2221
- var x = bbox[0] >>> 32 - z;
2222
- var y = bbox[1] >>> 32 - z;
2223
- return [x, y, z];
2224
- }
2225
- function getBboxZoom(bbox) {
2226
- var MAX_ZOOM = 28;
2227
- for (var z = 0; z < MAX_ZOOM; z++) {
2228
- var mask = 1 << 32 - (z + 1);
2229
- if ((bbox[0] & mask) != (bbox[2] & mask) || (bbox[1] & mask) != (bbox[3] & mask)) {
2230
- return z;
2231
- }
2232
- }
2233
- return MAX_ZOOM;
2234
- }
2235
- function pointToTileFraction(lon, lat, z) {
2236
- var sin = Math.sin(lat * d2r),
2237
- z2 = Math.pow(2, z),
2238
- x = z2 * (lon / 360 + 0.5),
2239
- y = z2 * (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI);
2240
- return [x, y, z];
2241
- }
2242
- var tilebelt = {
2243
- tileToGeoJSON: tileToGeoJSON,
2244
- tileToBBOX: tileToBBOX,
2245
- getChildren: getChildren,
2246
- getParent: getParent,
2247
- getSiblings: getSiblings,
2248
- hasTile: hasTile,
2249
- hasSiblings: hasSiblings,
2250
- tilesEqual: tilesEqual,
2251
- tileToQuadkey: tileToQuadkey,
2252
- quadkeyToTile: quadkeyToTile,
2253
- pointToTile: pointToTile,
2254
- bboxToTile: bboxToTile,
2255
- pointToTileFraction: pointToTileFraction
2256
- };
2257
-
2258
- /**
2259
- * Given a geometry, create cells and return them in their raw form,
2260
- * as an array of cell identifiers.
2261
- *
2262
- * @alias tiles
2263
- * @param {Object} geom GeoJSON geometry
2264
- * @param {Object} limits an object with min_zoom and max_zoom properties
2265
- * specifying the minimum and maximum level to be tiled.
2266
- * @returns {Array<Array<number>>} An array of tiles given as [x, y, z] arrays
2267
- */
2268
- var tiles = getTiles;
2269
- function getTiles(geom, limits) {
2270
- var i,
2271
- tile,
2272
- coords = geom.coordinates,
2273
- maxZoom = limits.max_zoom,
2274
- tileHash = {},
2275
- tiles = [];
2276
- if (geom.type === 'Point') {
2277
- return [tilebelt.pointToTile(coords[0], coords[1], maxZoom)];
2278
- } else if (geom.type === 'MultiPoint') {
2279
- for (i = 0; i < coords.length; i++) {
2280
- tile = tilebelt.pointToTile(coords[i][0], coords[i][1], maxZoom);
2281
- tileHash[toID(tile[0], tile[1], tile[2])] = true;
2282
- }
2283
- } else if (geom.type === 'LineString') {
2284
- lineCover(tileHash, coords, maxZoom);
2285
- } else if (geom.type === 'MultiLineString') {
2286
- for (i = 0; i < coords.length; i++) {
2287
- lineCover(tileHash, coords[i], maxZoom);
2288
- }
2289
- } else if (geom.type === 'Polygon') {
2290
- polygonCover(tileHash, tiles, coords, maxZoom);
2291
- } else if (geom.type === 'MultiPolygon') {
2292
- for (i = 0; i < coords.length; i++) {
2293
- polygonCover(tileHash, tiles, coords[i], maxZoom);
2294
- }
2295
- } else {
2296
- throw new Error('Geometry type not implemented');
2297
- }
2298
- if (limits.min_zoom !== maxZoom) {
2299
- // sync tile hash and tile array so that both contain the same tiles
2300
- var len = tiles.length;
2301
- appendHashTiles(tileHash, tiles);
2302
- for (i = 0; i < len; i++) {
2303
- var t = tiles[i];
2304
- tileHash[toID(t[0], t[1], t[2])] = true;
2305
- }
2306
- return mergeTiles(tileHash, tiles, limits);
2307
- }
2308
- appendHashTiles(tileHash, tiles);
2309
- return tiles;
2310
- }
2311
- function mergeTiles(tileHash, tiles, limits) {
2312
- var mergedTiles = [];
2313
- for (var z = limits.max_zoom; z > limits.min_zoom; z--) {
2314
- var parentTileHash = {};
2315
- var parentTiles = [];
2316
- for (var i = 0; i < tiles.length; i++) {
2317
- var t = tiles[i];
2318
- if (t[0] % 2 === 0 && t[1] % 2 === 0) {
2319
- var id2 = toID(t[0] + 1, t[1], z),
2320
- id3 = toID(t[0], t[1] + 1, z),
2321
- id4 = toID(t[0] + 1, t[1] + 1, z);
2322
- if (tileHash[id2] && tileHash[id3] && tileHash[id4]) {
2323
- tileHash[toID(t[0], t[1], t[2])] = false;
2324
- tileHash[id2] = false;
2325
- tileHash[id3] = false;
2326
- tileHash[id4] = false;
2327
- var parentTile = [t[0] / 2, t[1] / 2, z - 1];
2328
- if (z - 1 === limits.min_zoom) mergedTiles.push(parentTile);else {
2329
- parentTileHash[toID(t[0] / 2, t[1] / 2, z - 1)] = true;
2330
- parentTiles.push(parentTile);
2331
- }
2332
- }
2333
- }
2334
- }
2335
- for (i = 0; i < tiles.length; i++) {
2336
- t = tiles[i];
2337
- if (tileHash[toID(t[0], t[1], t[2])]) mergedTiles.push(t);
2338
- }
2339
- tileHash = parentTileHash;
2340
- tiles = parentTiles;
2341
- }
2342
- return mergedTiles;
2343
- }
2344
- function polygonCover(tileHash, tileArray, geom, zoom) {
2345
- var intersections = [];
2346
- for (var i = 0; i < geom.length; i++) {
2347
- var ring = [];
2348
- lineCover(tileHash, geom[i], zoom, ring);
2349
- for (var j = 0, len = ring.length, k = len - 1; j < len; k = j++) {
2350
- var m = (j + 1) % len;
2351
- var y = ring[j][1];
2352
-
2353
- // add interesction if it's not local extremum or duplicate
2354
- if ((y > ring[k][1] || y > ring[m][1]) && (
2355
- // not local minimum
2356
- y < ring[k][1] || y < ring[m][1]) &&
2357
- // not local maximum
2358
- y !== ring[m][1]) intersections.push(ring[j]);
2359
- }
2360
- }
2361
- intersections.sort(compareTiles); // sort by y, then x
2362
-
2363
- for (i = 0; i < intersections.length; i += 2) {
2364
- // fill tiles between pairs of intersections
2365
- y = intersections[i][1];
2366
- for (var x = intersections[i][0] + 1; x < intersections[i + 1][0]; x++) {
2367
- var id = toID(x, y, zoom);
2368
- if (!tileHash[id]) {
2369
- tileArray.push([x, y, zoom]);
2370
- }
2371
- }
2372
- }
2373
- }
2374
- function compareTiles(a, b) {
2375
- return a[1] - b[1] || a[0] - b[0];
2376
- }
2377
- function lineCover(tileHash, coords, maxZoom, ring) {
2378
- var prevX, prevY;
2379
- for (var i = 0; i < coords.length - 1; i++) {
2380
- var start = tilebelt.pointToTileFraction(coords[i][0], coords[i][1], maxZoom),
2381
- stop = tilebelt.pointToTileFraction(coords[i + 1][0], coords[i + 1][1], maxZoom),
2382
- x0 = start[0],
2383
- y0 = start[1],
2384
- x1 = stop[0],
2385
- y1 = stop[1],
2386
- dx = x1 - x0,
2387
- dy = y1 - y0;
2388
- if (dy === 0 && dx === 0) continue;
2389
- var sx = dx > 0 ? 1 : -1,
2390
- sy = dy > 0 ? 1 : -1,
2391
- x = Math.floor(x0),
2392
- y = Math.floor(y0),
2393
- tMaxX = dx === 0 ? Infinity : Math.abs(((dx > 0 ? 1 : 0) + x - x0) / dx),
2394
- tMaxY = dy === 0 ? Infinity : Math.abs(((dy > 0 ? 1 : 0) + y - y0) / dy),
2395
- tdx = Math.abs(sx / dx),
2396
- tdy = Math.abs(sy / dy);
2397
- if (x !== prevX || y !== prevY) {
2398
- tileHash[toID(x, y, maxZoom)] = true;
2399
- if (ring && y !== prevY) ring.push([x, y]);
2400
- prevX = x;
2401
- prevY = y;
2402
- }
2403
- while (tMaxX < 1 || tMaxY < 1) {
2404
- if (tMaxX < tMaxY) {
2405
- tMaxX += tdx;
2406
- x += sx;
2407
- } else {
2408
- tMaxY += tdy;
2409
- y += sy;
2410
- }
2411
- tileHash[toID(x, y, maxZoom)] = true;
2412
- if (ring && y !== prevY) ring.push([x, y]);
2413
- prevX = x;
2414
- prevY = y;
2415
- }
2416
- }
2417
- if (ring && y === ring[0][1]) ring.pop();
2418
- }
2419
- function appendHashTiles(hash, tiles) {
2420
- var keys = Object.keys(hash);
2421
- for (var i = 0; i < keys.length; i++) {
2422
- tiles.push(fromID(+keys[i]));
2423
- }
2424
- }
2425
- function toID(x, y, z) {
2426
- var dim = 2 * (1 << z);
2427
- return (dim * y + x) * 32 + z;
2428
- }
2429
- function fromID(id) {
2430
- var z = id % 32,
2431
- dim = 2 * (1 << z),
2432
- xy = (id - z) / 32,
2433
- x = xy % dim,
2434
- y = (xy - x) / dim % dim;
2435
- return [x, y, z];
2436
- }
2437
-
2438
- const B = [0x5555555555555555n, 0x3333333333333333n, 0x0f0f0f0f0f0f0f0fn, 0x00ff00ff00ff00ffn, 0x0000ffff0000ffffn, 0x00000000ffffffffn];
2439
- const S = [0n, 1n, 2n, 4n, 8n, 16n];
2440
- function tileToCell(tile) {
2441
- if (tile.z < 0 || tile.z > 26) {
2442
- throw new Error('Wrong zoom');
2443
- }
2444
- const z = BigInt(tile.z);
2445
- let x = BigInt(tile.x) << 32n - z;
2446
- let y = BigInt(tile.y) << 32n - z;
2447
- for (let i = 0; i < 5; i++) {
2448
- const s = S[5 - i];
2449
- const b = B[4 - i];
2450
- x = (x | x << s) & b;
2451
- y = (y | y << s) & b;
2452
- }
2453
- const quadbin = 0x4000000000000000n | 1n << 59n |
2454
- // | (mode << 59) | (mode_dep << 57)
2455
- z << 52n | (x | y << 1n) >> 12n | 0xfffffffffffffn >> z * 2n;
2456
- return quadbin;
2457
- }
2458
- function getResolution$1(quadbin) {
2459
- return quadbin >> 52n & 0x1fn;
2460
- }
2461
- function geometryToCells(geometry, resolution) {
2462
- const zoom = Number(resolution);
2463
- return tiles(geometry, {
2464
- min_zoom: zoom,
2465
- max_zoom: zoom
2466
- }).map(([x, y, z]) => tileToCell({
2467
- x,
2468
- y,
2469
- z
2470
- }));
2471
- }
2472
-
2473
2083
  function tileFeaturesSpatialIndex({
2474
2084
  tiles,
2475
2085
  spatialFilter,
@@ -2544,6 +2154,81 @@ function getSpatialIndex(spatialDataType) {
2544
2154
  }
2545
2155
  }
2546
2156
 
2157
+ const _excluded$1 = ["tiles"];
2158
+ function tileFeaturesRaster(_ref) {
2159
+ let {
2160
+ tiles
2161
+ } = _ref,
2162
+ options = _objectWithoutPropertiesLoose(_ref, _excluded$1);
2163
+ // Cache band metadata for faster lookup while iterating over pixels.
2164
+ const bandMetadataByName = {};
2165
+ for (const band of options.rasterMetadata.bands) {
2166
+ bandMetadataByName[band.name] = band;
2167
+ }
2168
+ // Omit empty and invisible tiles for simpler processing and types.
2169
+ tiles = tiles.filter(isRasterTileVisible);
2170
+ if (tiles.length === 0) return [];
2171
+ // Raster tiles, and all pixels, are quadbin cells. Resolution of a pixel is
2172
+ // the resolution of the tile, plus the number of subdivisions. Block size
2173
+ // must be square, N x N, where N is a power of two.
2174
+ const tileResolution = getResolution$1(tiles[0].index.q);
2175
+ const tileBlockSize = tiles[0].data.blockSize;
2176
+ const cellResolution = tileResolution + BigInt(Math.log2(tileBlockSize));
2177
+ // Compute covering cells for the spatial filter, at same resolution as the
2178
+ // raster pixels, to be used as a mask.
2179
+ const spatialFilterCells = new Set(geometryToCells(options.spatialFilter, cellResolution));
2180
+ const data = new Map();
2181
+ for (const tile of tiles) {
2182
+ const parent = tile.index.q;
2183
+ const children = cellToChildrenSorted(parent, cellResolution);
2184
+ // For each pixel/cell within the spatial filter, create a FeatureData.
2185
+ // Order is row-major, starting from NW and ending at SE.
2186
+ for (let i = 0; i < children.length; i++) {
2187
+ if (!spatialFilterCells.has(children[i])) continue;
2188
+ const cellData = {};
2189
+ let cellDataExists = false;
2190
+ for (const band in tile.data.cells.numericProps) {
2191
+ const value = tile.data.cells.numericProps[band].value[i];
2192
+ // TODO(cleanup): nodata should be a number, not a string.
2193
+ if (Number(bandMetadataByName[band].nodata) !== value) {
2194
+ cellData[band] = tile.data.cells.numericProps[band].value[i];
2195
+ cellDataExists = true;
2196
+ }
2197
+ }
2198
+ if (cellDataExists) {
2199
+ data.set(children[i], cellData);
2200
+ }
2201
+ }
2202
+ }
2203
+ return Array.from(data.values());
2204
+ }
2205
+ /**
2206
+ * Detects whether a given {@link Tile} is a {@link RasterTile}.
2207
+ * @privateRemarks Method of detection is arbitrary, and may be changed.
2208
+ */
2209
+ function isRasterTile(tile) {
2210
+ return tile.data ? tile.data.hasOwnProperty('cells') : false;
2211
+ }
2212
+ function isRasterTileVisible(tile) {
2213
+ var _tile$data;
2214
+ return !!(tile.isVisible && (_tile$data = tile.data) != null && (_tile$data = _tile$data.cells) != null && _tile$data.numericProps);
2215
+ }
2216
+ /**
2217
+ * For the raster format, children are sorted in row-major order, starting from
2218
+ * NW and ending at SE. Order returned by quadbin's cellToChildren() is not
2219
+ * defined (and not related to the raster format), so sort explicitly here.
2220
+ */
2221
+ function cellToChildrenSorted(parent, resolution) {
2222
+ return cellToChildren(parent, resolution).sort((cellA, cellB) => {
2223
+ const tileA = cellToTile(cellA);
2224
+ const tileB = cellToTile(cellB);
2225
+ if (tileA.y !== tileB.y) {
2226
+ return tileA.y > tileB.y ? 1 : -1;
2227
+ }
2228
+ return tileA.x > tileB.x ? 1 : -1;
2229
+ });
2230
+ }
2231
+
2547
2232
  /** @internalRemarks Source: @carto/react-core */
2548
2233
  function tileFeatures({
2549
2234
  tiles,
@@ -2552,6 +2237,7 @@ function tileFeatures({
2552
2237
  tileFormat,
2553
2238
  spatialDataColumn = DEFAULT_GEO_COLUMN,
2554
2239
  spatialDataType,
2240
+ rasterMetadata,
2555
2241
  options = {}
2556
2242
  }) {
2557
2243
  // TODO(cleanup): Is an empty response the expected result when spatialFilter
@@ -2559,20 +2245,30 @@ function tileFeatures({
2559
2245
  if (!spatialFilter) {
2560
2246
  return [];
2561
2247
  }
2562
- if (spatialDataType !== 'geo') {
2563
- return tileFeaturesSpatialIndex({
2248
+ if (spatialDataType === 'geo') {
2249
+ return tileFeaturesGeometries({
2250
+ tiles,
2251
+ tileFormat,
2252
+ spatialFilter,
2253
+ uniqueIdProperty,
2254
+ options
2255
+ });
2256
+ }
2257
+ if (tiles.some(isRasterTile)) {
2258
+ assert$1(rasterMetadata, 'Missing raster metadata');
2259
+ return tileFeaturesRaster({
2564
2260
  tiles: tiles,
2565
2261
  spatialFilter,
2566
2262
  spatialDataColumn,
2567
- spatialDataType
2263
+ spatialDataType,
2264
+ rasterMetadata
2568
2265
  });
2569
2266
  }
2570
- return tileFeaturesGeometries({
2571
- tiles,
2572
- tileFormat,
2267
+ return tileFeaturesSpatialIndex({
2268
+ tiles: tiles,
2573
2269
  spatialFilter,
2574
- uniqueIdProperty,
2575
- options
2270
+ spatialDataColumn,
2271
+ spatialDataType
2576
2272
  });
2577
2273
  }
2578
2274
 
@@ -3024,15 +2720,12 @@ class WidgetTilesetSource extends WidgetSource {
3024
2720
  uniqueIdProperty,
3025
2721
  options
3026
2722
  }) {
3027
- this._features = tileFeatures({
2723
+ this._features = tileFeatures(_extends({
3028
2724
  tiles: this._tiles,
3029
2725
  options,
3030
2726
  spatialFilter,
3031
- uniqueIdProperty,
3032
- tileFormat: this.props.tileFormat,
3033
- spatialDataColumn: this.props.spatialDataColumn,
3034
- spatialDataType: this.props.spatialDataType
3035
- });
2727
+ uniqueIdProperty
2728
+ }, this.props));
3036
2729
  }
3037
2730
  /** Loads features as GeoJSON (used for testing). */
3038
2731
  loadGeoJSON({
@@ -3253,6 +2946,39 @@ function normalizeColumns(columns) {
3253
2946
  return Array.isArray(columns) ? columns : typeof columns === 'string' ? [columns] : [];
3254
2947
  }
3255
2948
 
2949
+ class WidgetRasterSource extends WidgetTilesetSource {}
2950
+
2951
+ /**
2952
+ * Source for Widget API requests on a data source defined as a table.
2953
+ *
2954
+ * Generally not intended to be constructed directly. Instead, call
2955
+ * {@link vectorTableSource}, {@link h3TableSource}, or {@link quadbinTableSource},
2956
+ * which can be shared with map layers. Sources contain a `widgetSource` property,
2957
+ * for use by widget implementations.
2958
+ *
2959
+ * Example:
2960
+ *
2961
+ * ```javascript
2962
+ * import { vectorTableSource } from '@carto/api-client';
2963
+ *
2964
+ * const data = vectorTableSource({
2965
+ * accessToken: '••••',
2966
+ * connectionName: 'carto_dw',
2967
+ * tableName: 'carto-demo-data.demo_tables.retail_stores'
2968
+ * });
2969
+ *
2970
+ * const { widgetSource } = await data;
2971
+ * ```
2972
+ */
2973
+ class WidgetTableSource extends WidgetRemoteSource {
2974
+ getModelSource(owner) {
2975
+ return _extends({}, super._getModelSource(owner), {
2976
+ type: 'table',
2977
+ data: this.props.tableName
2978
+ });
2979
+ }
2980
+ }
2981
+
3256
2982
  const h3QuerySource = async function h3QuerySource(options) {
3257
2983
  const {
3258
2984
  aggregationExp,
@@ -3339,9 +3065,6 @@ const h3TilesetSource = async function h3TilesetSource(options) {
3339
3065
  }));
3340
3066
  };
3341
3067
 
3342
- // deck.gl
3343
- // SPDX-License-Identifier: MIT
3344
- // Copyright (c) vis.gl contributors
3345
3068
  const rasterSource = async function rasterSource(options) {
3346
3069
  const {
3347
3070
  tableName,
@@ -3353,7 +3076,14 @@ const rasterSource = async function rasterSource(options) {
3353
3076
  if (filters) {
3354
3077
  urlParameters.filters = filters;
3355
3078
  }
3356
- return baseSource('raster', options, urlParameters);
3079
+ return baseSource('raster', options, urlParameters).then(result => _extends({}, result, {
3080
+ widgetSource: new WidgetRasterSource(_extends({}, options, {
3081
+ tileFormat: getTileFormat(result),
3082
+ spatialDataColumn: 'quadbin',
3083
+ spatialDataType: 'quadbin',
3084
+ rasterMetadata: result.raster_metadata
3085
+ }))
3086
+ }));
3357
3087
  };
3358
3088
 
3359
3089
  const quadbinQuerySource = async function quadbinQuerySource(options) {
@@ -3570,5 +3300,5 @@ const query = async function query(options) {
3570
3300
  });
3571
3301
  };
3572
3302
 
3573
- export { ApiVersion, CartoAPIError, DEFAULT_API_BASE_URL, FEATURE_GEOM_PROPERTY, FilterType, Provider, SOURCE_DEFAULTS, SpatialIndex, TileFormat, WidgetQuerySource, WidgetRemoteSource, WidgetSource, WidgetTableSource, WidgetTilesetSource, addFilter, aggregate, aggregationFunctions, applyFilters, applySorting, boundaryQuerySource, boundaryTableSource, buildBinaryFeatureFilter, buildFeatureFilter, buildPublicMapUrl, buildStatsUrl, clearFilters, createPolygonSpatialFilter, createViewportSpatialFilter, filterFunctions, geojsonFeatures, getClient, getFilter, groupValuesByColumn, groupValuesByDateColumn, h3QuerySource, h3TableSource, h3TilesetSource, hasFilter, histogram, makeIntervalComplete, quadbinQuerySource, quadbinTableSource, quadbinTilesetSource, query, rasterSource, removeFilter, requestWithParameters, scatterPlot, setClient, tileFeatures, tileFeaturesGeometries, tileFeaturesSpatialIndex, transformToTileCoords, vectorQuerySource, vectorTableSource, vectorTilesetSource };
3303
+ export { ApiVersion, CartoAPIError, DEFAULT_API_BASE_URL, FEATURE_GEOM_PROPERTY, FilterType, Provider, SOURCE_DEFAULTS, SpatialIndex, TileFormat, WidgetQuerySource, WidgetRasterSource, WidgetRemoteSource, WidgetSource, WidgetTableSource, WidgetTilesetSource, _getHexagonResolution, addFilter, aggregate, aggregationFunctions, applyFilters, applySorting, boundaryQuerySource, boundaryTableSource, buildBinaryFeatureFilter, buildFeatureFilter, buildPublicMapUrl, buildStatsUrl, clearFilters, createPolygonSpatialFilter, createViewportSpatialFilter, filterFunctions, geojsonFeatures, getClient, getFilter, groupValuesByColumn, groupValuesByDateColumn, h3QuerySource, h3TableSource, h3TilesetSource, hasFilter, histogram, makeIntervalComplete, quadbinQuerySource, quadbinTableSource, quadbinTilesetSource, query, rasterSource, removeFilter, requestWithParameters, scatterPlot, setClient, tileFeatures, tileFeaturesGeometries, tileFeaturesSpatialIndex, transformToTileCoords, vectorQuerySource, vectorTableSource, vectorTilesetSource };
3574
3304
  //# sourceMappingURL=api-client.modern.js.map