UNPKG

@deck.gl/carto

Version:

CARTO official integration with Deck.gl. Build geospatial applications using CARTO and Deck.gl.

1,427 lines (1,381 loc) 104 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // dist/index.js var dist_exports = {}; __export(dist_exports, { BASEMAP: () => basemap_default, CARTO_LAYERS: () => CARTO_LAYERS, CARTO_SOURCES: () => import_api_client3.CARTO_SOURCES, CartoAPIError: () => import_api_client3.CartoAPIError, ClusterTileLayer: () => cluster_tile_layer_default, H3TileLayer: () => h3_tile_layer_default, HeatmapTileLayer: () => heatmap_tile_layer_default, LayerFactory: () => LayerFactory, PointLabelLayer: () => point_label_layer_default, QuadbinTileLayer: () => quadbin_tile_layer_default, RasterTileLayer: () => raster_tile_layer_default, SOURCE_DEFAULTS: () => import_api_client3.SOURCE_DEFAULTS, VectorTileLayer: () => vector_tile_layer_default, _GOOGLE_BASEMAPS: () => GOOGLE_BASEMAPS, _QuadbinLayer: () => quadbin_layer_default, _RasterLayer: () => raster_layer_default, _STYLE_LAYER_GROUPS: () => STYLE_LAYER_GROUPS, _SpatialIndexTileLayer: () => spatial_index_tile_layer_default, _applyLayerGroupFilters: () => applyLayerGroupFilters, _fetchStyle: () => fetchStyle, _getStyleUrl: () => getStyleUrl, boundaryQuerySource: () => import_api_client3.boundaryQuerySource, boundaryTableSource: () => import_api_client3.boundaryTableSource, colorBins: () => colorBins, colorCategories: () => colorCategories, colorContinuous: () => colorContinuous, fetchBasemapProps: () => fetchBasemapProps, fetchMap: () => fetchMap, h3QuerySource: () => import_api_client3.h3QuerySource, h3TableSource: () => import_api_client3.h3TableSource, h3TilesetSource: () => import_api_client3.h3TilesetSource, quadbinQuerySource: () => import_api_client3.quadbinQuerySource, quadbinTableSource: () => import_api_client3.quadbinTableSource, quadbinTilesetSource: () => import_api_client3.quadbinTilesetSource, query: () => import_api_client3.query, rasterSource: () => import_api_client3.rasterSource, vectorQuerySource: () => import_api_client3.vectorQuerySource, vectorTableSource: () => import_api_client3.vectorTableSource, vectorTilesetSource: () => import_api_client3.vectorTilesetSource }); module.exports = __toCommonJS(dist_exports); // dist/layers/cluster-tile-layer.js var import_layers = require("@deck.gl/layers"); var import_geo_layers3 = require("@deck.gl/geo-layers"); var import_core5 = require("@loaders.gl/core"); var import_gis = require("@loaders.gl/gis"); var import_core6 = require("@deck.gl/core"); // dist/layers/cluster-utils.js var import_quadbin = require("quadbin"); var import_h3_js = require("h3-js"); var import_core2 = require("@deck.gl/core"); // dist/utils.js var import_core = require("@deck.gl/core"); function assert(condition, message) { import_core.log.assert(condition, message); } function createBinaryProxy(data, index) { const { properties, numericProps } = data; return new Proxy(properties[index] || {}, { get(target, property) { if (property in numericProps) { return numericProps[property].value[index]; } return target[property]; }, has(target, property) { return property in numericProps || property in target; }, ownKeys(target) { return [...Object.keys(numericProps), ...Reflect.ownKeys(target)]; }, getOwnPropertyDescriptor(target, prop) { return { enumerable: true, configurable: true }; } }); } function getWorkerUrl(id5, version) { return `https://unpkg.com/@deck.gl/carto@${version}/dist/${id5}-worker.js`; } var EMPTY_UINT16ARRAY = new Uint16Array(); var EMPTY_BINARY_PROPS = { positions: { value: new Float32Array(), size: 2 }, properties: [], numericProps: {}, featureIds: { value: EMPTY_UINT16ARRAY, size: 1 }, globalFeatureIds: { value: EMPTY_UINT16ARRAY, size: 1 } }; function createEmptyBinary() { return { shape: "binary-feature-collection", points: { type: "Point", ...EMPTY_BINARY_PROPS }, lines: { type: "LineString", pathIndices: { value: EMPTY_UINT16ARRAY, size: 1 }, ...EMPTY_BINARY_PROPS }, polygons: { type: "Polygon", polygonIndices: { value: EMPTY_UINT16ARRAY, size: 1 }, primitivePolygonIndices: { value: EMPTY_UINT16ARRAY, size: 1 }, ...EMPTY_BINARY_PROPS } }; } function createBinaryPointFeature(positions, featureIds, globalFeatureIds, numericProps, properties, size = 2) { return { type: "Point", positions: { value: new Float32Array(positions), size }, featureIds: { value: new Uint16Array(featureIds), size: 1 }, globalFeatureIds: { value: new Uint32Array(globalFeatureIds), size: 1 }, numericProps, properties }; } function initializeNumericProps(numPoints, sourceProps) { const numericProps = {}; if (sourceProps) { Object.keys(sourceProps).forEach((prop) => { numericProps[prop] = { value: new Float32Array(numPoints), size: 1 }; }); } return numericProps; } function copyNumericProps(sourceProps, targetProps, sourceIndex, targetIndex) { Object.keys(sourceProps).forEach((prop) => { targetProps[prop].value[targetIndex] = sourceProps[prop].value[sourceIndex]; }); } // dist/layers/cluster-utils.js function aggregateTile(tile, tileAggregationCache, aggregationLevels, properties = [], getPosition, getWeight, scheme = "quadbin") { var _a; if (!tile.content) return false; if (!tile.userData) tile.userData = {}; const cell0 = (_a = tileAggregationCache.get(aggregationLevels)) == null ? void 0 : _a[0]; if (cell0) { if (properties.every((property) => property.name in cell0)) { return false; } tileAggregationCache.clear(); } const out = {}; for (const cell of tile.content) { let id5 = cell.id; const position = typeof getPosition === "function" ? getPosition(cell, {}) : getPosition; for (let i = 0; i < aggregationLevels - 1; i++) { if (scheme === "h3") { const currentResolution = (0, import_h3_js.getResolution)(id5); id5 = (0, import_h3_js.cellToParent)(id5, Math.max(0, currentResolution - 1)); } else { id5 = (0, import_quadbin.cellToParent)(id5); } } const parentId = String(id5); if (!(parentId in out)) { out[parentId] = { id: id5, count: 0, position: [0, 0] }; for (const { name, aggregation } of properties) { if (aggregation === "any") { out[parentId][name] = cell.properties[name]; } else { out[parentId][name] = 0; } } } const prevTotalW = out[parentId].count; out[parentId].count += typeof getWeight === "function" ? getWeight(cell, {}) : getWeight; const totalW = out[parentId].count; const W = totalW - prevTotalW; out[parentId].position[0] = (prevTotalW * out[parentId].position[0] + W * position[0]) / totalW; out[parentId].position[1] = (prevTotalW * out[parentId].position[1] + W * position[1]) / totalW; for (const { name, aggregation } of properties) { const prevValue = out[parentId][name]; const value = cell.properties[name]; if (aggregation === "average") { out[parentId][name] = (prevTotalW * prevValue + W * value) / totalW; } else if (aggregation === "count" || aggregation === "sum") { out[parentId][name] = prevValue + value; } else if (aggregation === "max") { out[parentId][name] = Math.max(prevValue, value); } else if (aggregation === "min") { out[parentId][name] = Math.min(prevValue, value); } } } tileAggregationCache.set(aggregationLevels, Object.values(out)); return true; } function extractAggregationProperties(tile) { const properties = []; const validAggregations = ["any", "average", "count", "min", "max", "sum"]; for (const name of Object.keys(tile.content[0].properties)) { let aggregation = name.split("_").pop().toLowerCase(); if (!validAggregations.includes(aggregation)) { import_core2.log.warn(`No valid aggregation present in ${name} property`)(); aggregation = "any"; } properties.push({ name, aggregation }); } return properties; } function computeAggregationStats(data, properties) { const stats = {}; for (const { name, aggregation } of properties) { stats[name] = { min: Infinity, max: -Infinity }; if (aggregation !== "any") { for (const d of data) { stats[name].min = Math.min(stats[name].min, d[name]); stats[name].max = Math.max(stats[name].max, d[name]); } } } return stats; } function clustersToBinary(data) { const positions = new Float32Array(data.length * 2); const featureIds = new Uint16Array(data.length); for (let i = 0; i < data.length; i++) { positions.set(data[i].position, 2 * i); featureIds[i] = i; } return { ...createEmptyBinary(), points: createBinaryPointFeature(positions, featureIds, featureIds, {}, data) }; } // dist/constants.js var DEFAULT_TILE_SIZE = 512; // dist/layers/quadbin-tileset-2d.js var import_geo_layers = require("@deck.gl/geo-layers"); var import_quadbin2 = require("quadbin"); var QuadbinTileset2D = class extends import_geo_layers._Tileset2D { // @ts-expect-error for spatial indices, TileSet2d should be parametrized by TileIndexT getTileIndices(opts) { return super.getTileIndices(opts).map(import_quadbin2.tileToCell).map((q) => ({ q, i: (0, import_quadbin2.bigIntToHex)(q) })); } // @ts-expect-error TileIndex must be generic getTileId({ q, i }) { return i || (0, import_quadbin2.bigIntToHex)(q); } // @ts-expect-error TileIndex must be generic getTileMetadata({ q }) { return super.getTileMetadata((0, import_quadbin2.cellToTile)(q)); } // @ts-expect-error TileIndex must be generic getTileZoom({ q }) { return Number((0, import_quadbin2.getResolution)(q)); } // @ts-expect-error TileIndex must be generic getParentIndex({ q }) { return { q: (0, import_quadbin2.cellToParent)(q) }; } }; // dist/layers/h3-tileset-2d.js var import_geo_layers2 = require("@deck.gl/geo-layers"); var import_h3_js2 = require("h3-js"); var MAX_LATITUDE = 85.051128; function padBoundingBox({ west, north, east, south }, resolution, scale = 1) { const corners = [ [north, east], [south, east], [south, west], [north, west] ]; const cornerCells = corners.map((c) => (0, import_h3_js2.latLngToCell)(c[0], c[1], resolution)); const cornerEdgeLengths = cornerCells.map((c) => Math.max(...(0, import_h3_js2.originToDirectedEdges)(c).map((e) => (0, import_h3_js2.edgeLength)(e, import_h3_js2.UNITS.rads))) * 180 / Math.PI); const bufferLat = Math.max(...cornerEdgeLengths) * scale; const bufferLon = Math.min(180, bufferLat / Math.cos((north + south) / 2 * Math.PI / 180)); return { north: Math.min(north + bufferLat, MAX_LATITUDE), east: east + bufferLon, south: Math.max(south - bufferLat, -MAX_LATITUDE), west: west - bufferLon }; } function getHexagonsInBoundingBox({ west, north, east, south }, resolution) { const longitudeSpan = Math.abs(east - west); if (longitudeSpan > 180) { const nSegments = Math.ceil(longitudeSpan / 180); let h3Indices = []; for (let s = 0; s < nSegments; s++) { const segmentWest = west + s * 180; const segmentEast = Math.min(segmentWest + 179.9999999, east); h3Indices = h3Indices.concat(getHexagonsInBoundingBox({ west: segmentWest, north, east: segmentEast, south }, resolution)); } return [...new Set(h3Indices)]; } const polygon = [ [north, east], [south, east], [south, west], [north, west], [north, east] ]; return (0, import_h3_js2.polygonToCells)(polygon, resolution); } function tileToBoundingBox(index) { const coordinates = (0, import_h3_js2.cellToBoundary)(index); const latitudes = coordinates.map((c) => c[0]); const longitudes = coordinates.map((c) => c[1]); const west = Math.min(...longitudes); const south = Math.min(...latitudes); const east = Math.max(...longitudes); const north = Math.max(...latitudes); const bbox = { west, south, east, north }; return padBoundingBox(bbox, (0, import_h3_js2.getResolution)(index), 0.12); } var BIAS = 2; function getHexagonResolution(viewport, tileSize) { const zoomOffset = Math.log2(tileSize / 512); const hexagonScaleFactor = 2 / 3 * (viewport.zoom - zoomOffset); const latitudeScaleFactor = Math.log(1 / Math.cos(Math.PI * viewport.latitude / 180)); return Math.max(0, Math.floor(hexagonScaleFactor + latitudeScaleFactor - BIAS)); } var H3Tileset2D = class extends import_geo_layers2._Tileset2D { /** * Returns all tile indices in the current viewport. If the current zoom level is smaller * than minZoom, return an empty array. If the current zoom level is greater than maxZoom, * return tiles that are on maxZoom. */ // @ts-expect-error Tileset2D should be generic over TileIndex getTileIndices({ viewport, minZoom, maxZoom }) { if (viewport.latitude === void 0) return []; const [west, south, east, north] = viewport.getBounds(); const { tileSize } = this.opts; let z = getHexagonResolution(viewport, tileSize); let indices; if (typeof minZoom === "number" && Number.isFinite(minZoom) && z < minZoom) { return []; } if (typeof maxZoom === "number" && Number.isFinite(maxZoom) && z > maxZoom) { z = maxZoom; const center = (0, import_h3_js2.latLngToCell)(viewport.latitude, viewport.longitude, maxZoom); indices = (0, import_h3_js2.gridDisk)(center, 1); } else { const paddedBounds = padBoundingBox({ west, north, east, south }, z); indices = getHexagonsInBoundingBox(paddedBounds, z); } return indices.map((i) => ({ i })); } // @ts-expect-error Tileset2D should be generic over TileIndex getTileId({ i }) { return i; } // @ts-expect-error Tileset2D should be generic over TileIndex getTileMetadata({ i }) { return { bbox: tileToBoundingBox(i) }; } // @ts-expect-error Tileset2D should be generic over TileIndex getTileZoom({ i }) { return (0, import_h3_js2.getResolution)(i); } // @ts-expect-error Tileset2D should be generic over TileIndex getParentIndex(index) { const resolution = (0, import_h3_js2.getResolution)(index.i); const i = (0, import_h3_js2.cellToParent)(index.i, resolution - 1); return { i }; } }; // dist/layers/quadbin-utils.js var import_web_mercator = require("@math.gl/web-mercator"); var import_quadbin3 = require("quadbin"); var TILE_SIZE = 512; function quadbinToOffset(quadbin) { const { x, y, z } = (0, import_quadbin3.cellToTile)(quadbin); const scale = TILE_SIZE / (1 << z); return [x * scale, TILE_SIZE - y * scale, scale]; } function quadbinToWorldBounds(quadbin, coverage) { const [xOffset, yOffset, scale] = quadbinToOffset(quadbin); return [ [xOffset, yOffset], [xOffset + coverage * scale, yOffset - coverage * scale] ]; } function getQuadbinPolygon(quadbin, coverage = 1) { const [topLeft, bottomRight] = quadbinToWorldBounds(quadbin, coverage); const [w, n] = (0, import_web_mercator.worldToLngLat)(topLeft); const [e, s] = (0, import_web_mercator.worldToLngLat)(bottomRight); return [e, n, e, s, w, s, w, n, e, n]; } // dist/layers/cluster-tile-layer.js var import_h3_js3 = require("h3-js"); // dist/layers/schema/fast-pbf.js var import_compression = require("@loaders.gl/compression"); function readPackedTypedArray(TypedArray, pbf, obj, options) { const end = pbf.type === 2 ? pbf.readVarint() + pbf.pos : pbf.pos + 1; const data = pbf.buf.buffer.slice(pbf.pos, end); if ((options == null ? void 0 : options.compression) === "gzip") { const compression = new import_compression.GZipCompression(); const decompressedData = compression.decompressSync(data); obj.value = new TypedArray(decompressedData); } else { obj.value = new TypedArray(data); } pbf.pos = end; return obj.value; } // dist/layers/schema/carto-tile.js var KeyValueObjectReader = class { static read(pbf, end) { return pbf.readFields(KeyValueObjectReader._readField, { key: "", value: null }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.key = pbf.readString(); else if (tag === 2) obj.value = pbf.readString(); } }; var PropertiesReader = class { static read(pbf, end) { return pbf.readFields(PropertiesReader._readField, {}, end); } static _readField(tag, obj, pbf) { if (tag === 1) { const { key, value } = KeyValueObjectReader.read(pbf, pbf.readVarint() + pbf.pos); obj[key] = value; } } }; var DoublesReader = class { static read(pbf, end) { const { value, size } = pbf.readFields(DoublesReader._readField, { value: [], size: 0 }, end); return { value, size }; } static _readField(tag, obj, pbf) { if (tag === 1) readPackedTypedArray(Float64Array, pbf, obj); else if (tag === 2) obj.size = pbf.readVarint(true); } }; var IntsReader = class { static read(pbf, end) { const { value, size } = pbf.readFields(IntsReader._readField, { value: [], size: 0 }, end); return { value: new Uint32Array(value), size }; } static _readField(tag, obj, pbf) { if (tag === 1) pbf.readPackedVarint(obj.value); else if (tag === 2) obj.size = pbf.readVarint(true); } }; var FieldsReader = class { static read(pbf, end) { return pbf.readFields(FieldsReader._readField, { id: 0 }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.id = pbf.readVarint(); } }; var NumericPropReader = class { static read(pbf, end) { return pbf.readFields(NumericPropReader._readField, { value: [] }, end); } static _readField(tag, obj, pbf) { if (tag === 1) readPackedTypedArray(Float64Array, pbf, obj); } }; var NumericPropKeyValueReader = class { static read(pbf, end) { return pbf.readFields(NumericPropKeyValueReader._readField, { key: "", value: null }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.key = pbf.readString(); else if (tag === 2) obj.value = NumericPropReader.read(pbf, pbf.readVarint() + pbf.pos); } }; var PointsReader = class { static read(pbf, end) { return pbf.readFields(PointsReader._readField, { positions: null, globalFeatureIds: null, featureIds: null, properties: [], numericProps: {}, fields: [] }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.positions = DoublesReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 2) obj.globalFeatureIds = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 3) obj.featureIds = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 4) obj.properties.push(PropertiesReader.read(pbf, pbf.readVarint() + pbf.pos)); else if (tag === 5) { const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos); obj.numericProps[entry.key] = entry.value; } else if (tag === 6) obj.fields.push(FieldsReader.read(pbf, pbf.readVarint() + pbf.pos)); } }; var LinesReader = class { static read(pbf, end) { return pbf.readFields(LinesReader._readField, { positions: null, pathIndices: null, globalFeatureIds: null, featureIds: null, properties: [], numericProps: {}, fields: [] }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.positions = DoublesReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 2) obj.pathIndices = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 3) obj.globalFeatureIds = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 4) obj.featureIds = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 5) obj.properties.push(PropertiesReader.read(pbf, pbf.readVarint() + pbf.pos)); else if (tag === 6) { const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos); obj.numericProps[entry.key] = entry.value; } else if (tag === 7) obj.fields.push(FieldsReader.read(pbf, pbf.readVarint() + pbf.pos)); } }; var PolygonsReader = class { static read(pbf, end) { return pbf.readFields(PolygonsReader._readField, { positions: null, polygonIndices: null, globalFeatureIds: null, featureIds: null, primitivePolygonIndices: null, triangles: null, properties: [], numericProps: {}, fields: [] }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.positions = DoublesReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 2) obj.polygonIndices = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 3) obj.globalFeatureIds = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 4) obj.featureIds = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 5) obj.primitivePolygonIndices = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 6) obj.triangles = IntsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 7) obj.properties.push(PropertiesReader.read(pbf, pbf.readVarint() + pbf.pos)); else if (tag === 8) { const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos); obj.numericProps[entry.key] = entry.value; } else if (tag === 9) obj.fields.push(FieldsReader.read(pbf, pbf.readVarint() + pbf.pos)); } }; var TileReader = class { static read(pbf, end) { return pbf.readFields(TileReader._readField, { points: null, lines: null, polygons: null }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.points = PointsReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 2) obj.lines = LinesReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 3) obj.polygons = PolygonsReader.read(pbf, pbf.readVarint() + pbf.pos); } }; // dist/layers/schema/carto-spatial-tile.js var IndicesReader = class { static read(pbf, end) { return pbf.readFields(IndicesReader._readField, { value: [] }, end); } static _readField(tag, obj, pbf) { if (tag === 1) readPackedTypedArray(BigUint64Array, pbf, obj); } }; var CellsReader = class { static read(pbf, end) { return pbf.readFields(CellsReader._readField, { indices: null, properties: [], numericProps: {} }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.indices = IndicesReader.read(pbf, pbf.readVarint() + pbf.pos); else if (tag === 2) obj.properties.push(PropertiesReader.read(pbf, pbf.readVarint() + pbf.pos)); else if (tag === 3) { const entry = NumericPropKeyValueReader.read(pbf, pbf.readVarint() + pbf.pos); obj.numericProps[entry.key] = entry.value; } } }; var TileReader2 = class { static read(pbf, end) { return pbf.readFields(TileReader2._readField, { scheme: 0, cells: null }, end); } static _readField(tag, obj, pbf) { if (tag === 1) obj.scheme = pbf.readVarint(); else if (tag === 2) obj.cells = CellsReader.read(pbf, pbf.readVarint() + pbf.pos); } }; // dist/layers/schema/tile-loader-utils.js var import_pbf = __toESM(require("pbf"), 1); function parsePbf(buffer, TileReader5) { const pbf = new import_pbf.default(buffer); const tile = TileReader5.read(pbf); return tile; } // dist/layers/schema/spatialjson-utils.js var import_quadbin4 = require("quadbin"); function binaryToSpatialjson(binary) { const { cells, scheme } = binary; const count = cells.indices.value.length; const spatial = []; for (let i = 0; i < count; i++) { const id5 = scheme === "h3" ? (0, import_quadbin4.bigIntToHex)(cells.indices.value[i]) : cells.indices.value[i]; const properties = { ...cells.properties[i] }; for (const key of Object.keys(cells.numericProps)) { properties[key] = cells.numericProps[key].value[i]; } spatial.push({ id: id5, properties }); } return spatial; } // dist/layers/schema/carto-spatial-tile-loader.js var VERSION = true ? "9.2.6" : "latest"; var id = "cartoSpatialTile"; var DEFAULT_OPTIONS = { cartoSpatialTile: { scheme: "quadbin", workerUrl: getWorkerUrl(id, VERSION) } }; var CartoSpatialTileLoader = { name: "CARTO Spatial Tile", version: VERSION, id, module: "carto", extensions: ["pbf"], mimeTypes: ["application/vnd.carto-spatial-tile"], category: "geometry", parse: async (arrayBuffer, options) => parseCartoSpatialTile(arrayBuffer, options), parseSync: parseCartoSpatialTile, worker: true, options: DEFAULT_OPTIONS }; function parseCartoSpatialTile(arrayBuffer, options) { var _a; if (!arrayBuffer) return null; const tile = parsePbf(arrayBuffer, TileReader2); const { cells } = tile; const scheme = (_a = options == null ? void 0 : options.cartoSpatialTile) == null ? void 0 : _a.scheme; const data = { cells, scheme }; return binaryToSpatialjson(data); } var carto_spatial_tile_loader_default = CartoSpatialTileLoader; // dist/layers/utils.js var import_core3 = require("@deck.gl/core"); var import_core4 = require("@deck.gl/core"); function mergeLoadOptions(loadOptions, additionalOptions, depth = 0) { if (!loadOptions) { return additionalOptions; } if (!additionalOptions) { return loadOptions; } if (depth > 10) { return additionalOptions; } const result = { ...loadOptions }; for (const key in additionalOptions) { const value = additionalOptions[key]; if (value === loadOptions || value === additionalOptions) { continue; } if (typeof value === "object" && value !== null) { result[key] = mergeLoadOptions(loadOptions[key], value, depth + 1); } else { result[key] = value; } } return result; } function mergeBoundaryData(geometry, properties) { const mapping = {}; for (const { geoid, ...rest } of properties.properties) { if (geoid in mapping) { import_core3.log.warn("Duplicate geoid key in boundary mapping, using first occurance")(); } else { mapping[geoid] = rest; } } for (const type of ["points", "lines", "polygons"]) { const geom = geometry[type]; if (geom.positions.value.length === 0) { continue; } geom.properties = geom.properties.map(({ geoid }) => mapping[geoid]); const { positions, globalFeatureIds } = geom; let indices = null; if (type === "lines") indices = geom.pathIndices.value; if (type === "polygons") indices = geom.polygonIndices.value; const length = positions.value.length / positions.size; for (const key in properties.numericProps) { const sourceProp = properties.numericProps[key].value; const TypedArray = sourceProp.constructor; const destProp = new TypedArray(length); geom.numericProps[key] = { value: destProp, size: 1 }; if (!indices) { for (let i = 0; i < length; i++) { const featureId = globalFeatureIds.value[i]; destProp[i] = sourceProp[featureId]; } } else { for (let i = 0; i < indices.length - 1; i++) { const startIndex = indices[i]; const endIndex = indices[i + 1]; const featureId = globalFeatureIds.value[startIndex]; destProp.fill(sourceProp[featureId], startIndex, endIndex); } } } } return geometry; } var TilejsonPropType = { type: "object", value: null, validate: (value, propType) => propType.optional && value === null || typeof value === "object" && Array.isArray(value.tiles) && value.tiles.every((url) => typeof url === "string"), equal: (value1, value2) => { return (0, import_core4._deepEqual)(value1, value2, 2); }, async: true }; // dist/layers/cluster-tile-layer.js (0, import_core5.registerLoaders)([carto_spatial_tile_loader_default]); function getScheme(tilesetClass) { if (tilesetClass === H3Tileset2D) return "h3"; if (tilesetClass === QuadbinTileset2D) return "quadbin"; throw new Error("Invalid tileset class"); } var defaultProps = { data: TilejsonPropType, clusterLevel: { type: "number", value: 5, min: 1 }, getPosition: { type: "accessor", value: ({ id: id5 }) => { if (typeof id5 === "string") { const [lat, lng] = (0, import_h3_js3.cellToLatLng)(id5); return [lng, lat]; } return getQuadbinPolygon(id5, 0.5).slice(2, 4); } }, getWeight: { type: "accessor", value: 1 }, refinementStrategy: "no-overlap", tileSize: DEFAULT_TILE_SIZE }; var ClusterGeoJsonLayer = class extends import_geo_layers3.TileLayer { initializeState() { super.initializeState(); this.state.aggregationCache = /* @__PURE__ */ new WeakMap(); this.state.scheme = getScheme(this.props.TilesetClass); } updateState(opts) { const { props } = opts; const scheme = getScheme(props.TilesetClass); if (this.state.scheme !== scheme) { this.setState({ scheme, tileset: null }); this.state.aggregationCache = /* @__PURE__ */ new WeakMap(); } super.updateState(opts); } // eslint-disable-next-line max-statements renderLayers() { var _a; const visibleTiles = (_a = this.state.tileset) == null ? void 0 : _a.tiles.filter((tile) => { return tile.isLoaded && tile.content && this.state.tileset.isTileVisible(tile); }); if (!(visibleTiles == null ? void 0 : visibleTiles.length) || !this.state.tileset) { return null; } visibleTiles.sort((a, b) => b.zoom - a.zoom); const { getPosition, getWeight } = this.props; const { aggregationCache, scheme } = this.state; const isH3 = scheme === "h3"; const properties = extractAggregationProperties(visibleTiles[0]); const data = []; let needsUpdate = false; const aggregationLevels = this._getAggregationLevels(visibleTiles); for (const tile of visibleTiles) { let tileAggregationCache = aggregationCache.get(tile.content); if (!tileAggregationCache) { tileAggregationCache = /* @__PURE__ */ new Map(); aggregationCache.set(tile.content, tileAggregationCache); } const didAggregate = aggregateTile(tile, tileAggregationCache, aggregationLevels, properties, getPosition, getWeight, isH3 ? "h3" : "quadbin"); needsUpdate || (needsUpdate = didAggregate); data.push(...tileAggregationCache.get(aggregationLevels)); } data.sort((a, b) => Number(b.count - a.count)); const clusterIds = data == null ? void 0 : data.map((tile) => tile.id); needsUpdate || (needsUpdate = !(0, import_core6._deepEqual)(clusterIds, this.state.clusterIds, 1)); this.setState({ clusterIds }); if (needsUpdate) { const stats = computeAggregationStats(data, properties); const binaryData = clustersToBinary(data); binaryData.points.attributes = { stats }; this.setState({ data: binaryData }); } const props = { ...this.props, id: "clusters", data: this.state.data, dataComparator: (data2, oldData) => { var _a2, _b, _c, _d; const newIds = (_b = (_a2 = data2 == null ? void 0 : data2.points) == null ? void 0 : _a2.properties) == null ? void 0 : _b.map((tile) => tile.id); const oldIds = (_d = (_c = oldData == null ? void 0 : oldData.points) == null ? void 0 : _c.properties) == null ? void 0 : _d.map((tile) => tile.id); return (0, import_core6._deepEqual)(newIds, oldIds, 1); } }; return new import_layers.GeoJsonLayer(this.getSubLayerProps(props)); } getPickingInfo(params) { const info = params.info; if (info.index !== -1) { const { data } = params.sourceLayer.props; info.object = (0, import_gis.binaryToGeojson)(data, { globalFeatureId: info.index }); } return info; } _updateAutoHighlight(info) { for (const layer of this.getSubLayers()) { layer.updateAutoHighlight(info); } } filterSubLayer() { return true; } _getAggregationLevels(visibleTiles) { const isH3 = this.state.scheme === "h3"; const firstTile = visibleTiles[0]; let tileResolution; let viewportResolution; if (isH3) { tileResolution = (0, import_h3_js3.getResolution)(firstTile.id); viewportResolution = getHexagonResolution(this.context.viewport, this.state.tileset.opts.tileSize); } else { tileResolution = firstTile.zoom; viewportResolution = this.context.viewport.zoom; } const resolutionDiff = Math.round(viewportResolution - tileResolution); const aggregationLevels = Math.round(this.props.clusterLevel) - resolutionDiff; return aggregationLevels; } }; ClusterGeoJsonLayer.layerName = "ClusterGeoJsonLayer"; ClusterGeoJsonLayer.defaultProps = defaultProps; var ClusterTileLayer = class extends import_core6.CompositeLayer { getLoadOptions() { const tileJSON = this.props.data; const scheme = tileJSON && "scheme" in tileJSON ? tileJSON.scheme : "quadbin"; return mergeLoadOptions(super.getLoadOptions(), { fetch: { headers: { Authorization: `Bearer ${tileJSON.accessToken}` } }, cartoSpatialTile: { scheme } }); } renderLayers() { const tileJSON = this.props.data; if (!tileJSON) return null; const { tiles: data, maxresolution: maxZoom } = tileJSON; const isH3 = tileJSON && "scheme" in tileJSON && tileJSON.scheme === "h3"; const TilesetClass = isH3 ? H3Tileset2D : QuadbinTileset2D; return [ // @ts-ignore new ClusterGeoJsonLayer(this.props, { id: `cluster-geojson-layer-${this.props.id}`, data, // TODO: Tileset2D should be generic over TileIndex type TilesetClass, maxZoom, loadOptions: this.getLoadOptions() }) ]; } }; ClusterTileLayer.layerName = "ClusterTileLayer"; ClusterTileLayer.defaultProps = defaultProps; var cluster_tile_layer_default = ClusterTileLayer; // dist/layers/h3-tile-layer.js var import_core8 = require("@deck.gl/core"); var import_geo_layers5 = require("@deck.gl/geo-layers"); // dist/layers/spatial-index-tile-layer.js var import_core7 = require("@loaders.gl/core"); var import_geo_layers4 = require("@deck.gl/geo-layers"); (0, import_core7.registerLoaders)([carto_spatial_tile_loader_default]); function isFeatureIdDefined(value) { return value !== void 0 && value !== null && value !== ""; } var defaultProps2 = { tileSize: DEFAULT_TILE_SIZE }; var SpatialIndexTileLayer = class extends import_geo_layers4.TileLayer { _updateAutoHighlight(info) { const { hoveredFeatureId } = this.state; const hoveredFeature = info.object; let newHoveredFeatureId = null; if (hoveredFeature) { newHoveredFeatureId = hoveredFeature.id; } if (hoveredFeatureId !== newHoveredFeatureId) { let { highlightColor } = this.props; if (typeof highlightColor === "function") { highlightColor = highlightColor(info); } this.setState({ highlightColor, hoveredFeatureId: newHoveredFeatureId }); } } getSubLayerPropsByTile(tile) { return { highlightedObjectIndex: this.getHighlightedObjectIndex(tile), highlightColor: this.state.highlightColor }; } getHighlightedObjectIndex(tile) { const { hoveredFeatureId } = this.state; const data = tile.content; const isFeatureIdPresent = isFeatureIdDefined(hoveredFeatureId); if (!isFeatureIdPresent || !Array.isArray(data) || // Quick check for whether id is within tile. data.findIndex is expensive !this._featureInTile(tile, hoveredFeatureId)) { return -1; } return data.findIndex((feature) => feature.id === hoveredFeatureId); } _featureInTile(tile, featureId) { const tileset = this.state.tileset; const tileZoom = tileset.getTileZoom(tile.index); const KEY = tile.index.q ? "q" : "i"; let featureIndex = { [KEY]: featureId }; let featureZoom = tileset.getTileZoom(featureIndex); while (!(featureZoom <= tileZoom)) { featureIndex = tileset.getParentIndex(featureIndex); featureZoom = tileset.getTileZoom(featureIndex); } return featureIndex[KEY] === tile.index[KEY]; } }; SpatialIndexTileLayer.layerName = "SpatialIndexTileLayer"; SpatialIndexTileLayer.defaultProps = defaultProps2; var spatial_index_tile_layer_default = SpatialIndexTileLayer; // dist/layers/h3-tile-layer.js var renderSubLayers = (props) => { const { data } = props; const { index } = props.tile; if (!data || !data.length) return null; return new import_geo_layers5.H3HexagonLayer(props, { getHexagon: (d) => d.id, centerHexagon: index, highPrecision: true }); }; var defaultProps3 = { data: TilejsonPropType, tileSize: DEFAULT_TILE_SIZE }; var H3TileLayer = class extends import_core8.CompositeLayer { initializeState() { import_geo_layers5.H3HexagonLayer._checkH3Lib(); } getLoadOptions() { const tileJSON = this.props.data; return mergeLoadOptions(super.getLoadOptions(), { fetch: { headers: { Authorization: `Bearer ${tileJSON.accessToken}` } }, cartoSpatialTile: { scheme: "h3" } }); } renderLayers() { const tileJSON = this.props.data; if (!tileJSON) return null; const { tiles: data } = tileJSON; let { minresolution, maxresolution } = tileJSON; if (this.props.minZoom) { minresolution = Math.max(minresolution, getHexagonResolution({ zoom: this.props.minZoom, latitude: 0 }, this.props.tileSize)); } if (this.props.maxZoom) { maxresolution = Math.min(maxresolution, getHexagonResolution({ zoom: this.props.maxZoom, latitude: 0 }, this.props.tileSize)); } const SubLayerClass = this.getSubLayerClass("spatial-index-tile", spatial_index_tile_layer_default); return new SubLayerClass(this.props, { id: `h3-tile-layer-${this.props.id}`, data, // TODO: Tileset2D should be generic over TileIndex type TilesetClass: H3Tileset2D, renderSubLayers, // minZoom and maxZoom are H3 resolutions, however we must use this naming as that is what the Tileset2D class expects minZoom: minresolution, maxZoom: maxresolution, loadOptions: this.getLoadOptions() }); } }; H3TileLayer.layerName = "H3TileLayer"; H3TileLayer.defaultProps = defaultProps3; var h3_tile_layer_default = H3TileLayer; // dist/layers/heatmap-tile-layer.js var import_quadbin6 = require("quadbin"); var import_h3_js4 = require("h3-js"); var import_core11 = require("@deck.gl/core"); var import_layers2 = require("@deck.gl/layers"); // dist/layers/heatmap.js var fs = ( /* glsl */ `uniform heatmapUniforms { vec2 colorDomain; vec2 delta; float intensity; float opacity; float radiusPixels; } heatmap; uniform sampler2D colorTexture; vec3 colorGradient(float value) { return texture(colorTexture, vec2(value, 0.5)).rgb; } const vec3 SHIFT = vec3(1.0, 256.0, 256.0 * 256.0); const float MAX_VAL = SHIFT.z * 255.0; const float SCALE = MAX_VAL / 8.0; vec4 pack(float value) { return vec4(mod(vec3(value, floor(value / SHIFT.yz)), 256.0), 255.0) / 255.0; } float unpack(vec3 color) { return 255.0 * dot(color, SHIFT); } vec4 heatmap_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { bool firstPass = (heatmap.delta.y < 0.5); float accumulator = 0.0; // Controls quality of heatmap, larger values increase quality at expense of performance float SUPPORT = clamp(heatmap.radiusPixels / 2.0, 8.0, 32.0); // Gaussian normalization parameters float sigma = SUPPORT / 3.0; float a = -0.5 / (sigma * sigma); float w0 = 0.3989422804014327 / sigma; // 1D normalization for (float t = -SUPPORT; t <= SUPPORT; t++) { vec2 percent = (t * heatmap.delta - 0.5) / SUPPORT; vec2 delta = percent * heatmap.radiusPixels / texSize; vec4 offsetColor = texture(source, texCoord + delta); // Unpack float float value = unpack(offsetColor.rgb); // Gaussian float weight = w0 * exp(a * t * t); accumulator += value * weight; } if (firstPass) { return pack(accumulator); } // Undo scaling to obtain normalized density float density = 10.0 * heatmap.intensity * accumulator / SCALE; // Domain also in normalized density units vec2 domain = heatmap.colorDomain; // Apply domain float f = (density - domain[0]) / (domain[1] - domain[0]); // sqrt/log scaling?? // float f = (log(density) - log(domain[0] + 1.0)) / (log(domain[1] + 1.0) - log(domain[0] + 1.0)); // f = sqrt(f); // Color map vec4 color = vec4(0.0); color.rgb = colorGradient(f); color.a = smoothstep(0.0, 0.1, f); color.a = pow(color.a, 1.0 / 2.2); color.a *= heatmap.opacity; // Use premultiplied alpha for compatibility with blending in ScreenPass color.rgb *= color.a; return color; } ` ); var heatmap = { name: "heatmap", uniformPropTypes: { colorDomain: { value: [0, 1] }, delta: { value: [0, 1] }, intensity: { value: 1, min: 0.1, max: 10 }, opacity: { value: 1, min: 0, max: 1 }, radiusPixels: { value: 20, min: 0, softMax: 100 } }, uniformTypes: { colorDomain: "vec2<f32>", delta: "vec2<f32>", intensity: "f32", opacity: "f32", radiusPixels: "f32" }, // @ts-ignore TODO v9.1 getUniforms: (opts) => { if (!opts) return {}; const { colorDomain = [0, 1], colorTexture, delta = [1, 0], intensity = 1, opacity = 1, radiusPixels = 20 } = opts; return { colorDomain, colorTexture, delta, intensity, opacity, radiusPixels }; }, fs, passes: [ // @ts-expect-error Seems typing in luma.gl should be Partial<> { sampler: true, uniforms: { delta: [1, 0] } }, // @ts-expect-error Seems typing in luma.gl should be Partial<> { sampler: true, uniforms: { delta: [0, 1] } } ] }; // dist/layers/post-process-utils.js var import_core9 = require("@deck.gl/core"); var TEXTURE_PROPS = { format: "rgba8unorm", width: 1, height: 1, sampler: { minFilter: "linear", magFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" } }; function getPostProcessLayer(layer) { while (layer.parent && !layer.applyPostProcess) { layer = layer.parent; } return layer; } var DrawCallbackLayer = class extends import_core9.Layer { initializeState() { this.id = `draw-callback-${getPostProcessLayer(this).props.id}`; } _drawLayer() { getPostProcessLayer(this).applyPostProcess(); } }; DrawCallbackLayer.layerName = "DrawCallbackLayer"; function RTTModifier(BaseLayer) { var _a; return _a = class RTTLayer extends BaseLayer { draw(opts) { const { shaderModuleProps } = opts; const { picking } = shaderModuleProps; const postProcessLayer = getPostProcessLayer(this); const enableRTT = !picking.isActive && postProcessLayer.enableRTT; if (enableRTT) { postProcessLayer.enableRTT(opts); } super.draw(opts); if (enableRTT) { postProcessLayer.disableRTT(); } } }, // @ts-expect-error typescript doesn't see static property _a.layerName = `RTT-${BaseLayer.layerName}`, _a; } function PostProcessModifier(BaseLayer, effect) { var _a; return _a = class PostProcessLayer extends BaseLayer { initializeState(context) { super.initializeState(context); this._createTextures(); this.internalState.postProcess = new import_core9.PostProcessEffect(effect, this.props); this.internalState.postProcess.setup(context); } updateState(params) { super.updateState(params); this.internalState.postProcess.setProps(this.props); } renderLayers() { let subLayers = super.renderLayers(); if (!subLayers) { return null; } subLayers = Array.isArray(subLayers) ? subLayers : [subLayers]; return [...subLayers, new DrawCallbackLayer()]; } _createTextures() { const { device } = this.context; this.internalState.renderBuffers = [0, 1].map((i) => { return device.createFramebuffer({ id: `layer-fbo-${i}`, colorAttachments: [device.createTexture(TEXTURE_PROPS)], depthStencilAttachment: "depth16unorm" }); }); } _resizeBuffers(opts) { const { shaderModuleProps } = opts; const { viewport } = this.context; const { devicePixelRatio } = shaderModuleProps.project; const width = devicePixelRatio * viewport.width; const height = devicePixelRatio * viewport.height; this.internalState.renderBuffers.forEach((fbo) => fbo.resize({ width, height })); } enableRTT(opts) { this._resizeBuffers(opts); this.internalState.originalRenderPass = this.context.renderPass; const [framebuffer] = this.internalState.renderBuffers; this.internalState.internalRenderPass = this.context.device.beginRenderPass({ framebuffer, parameters: { viewport: [0, 0, framebuffer.width, framebuffer.height] }, // Only clear on first render clearColor: this.internalState.renderInProgress ? false : [0, 0, 0, 0] }); this.internalState.renderInProgress = true; this.context.renderPass = this.internalState.internalRenderPass; } disableRTT() { this.internalState.internalRenderPass.end(); this.context.renderPass = this.internalState.originalRenderPass; } applyPostProcess() { if (!this.internalState.renderInProgress) { return; } const [inputBuffer, swapBuffer] = this.internalState.renderBuffers; const { framebuffer: target } = this.context.renderPass.props; this.internalState.postProcess.postRender({ inputBuffer, swapBuffer, target }); this.internalState.renderInProgress = false; } _finalize() { this.internalState.renderBuffers.forEach((fbo) => { fbo.destroy(); }); this.internalState.renderBuffers = null; this.internalState.postProcess.cleanup(); } }, _a.layerName = `PostProcess${BaseLayer.layerName}`, _a; } var fs2 = ( /* glsl */ `vec4 copy_filterColor_ext(vec4 color, vec2 texSize, vec2 texCoord) { return color; } ` ); var copy = { name: "copy", fs: fs2, getUniforms: () => ({}), passes: [{ filter: true }] }; // dist/layers/quadbin-tile-layer.js var import_core10 = require("@deck.gl/core"); // dist/layers/quadbin-layer.js var import_geo_layers6 = require("@deck.gl/geo-layers"); var defaultProps4 = { getQuadbin: { type: "accessor", value: (d) => d.quadbin } }; var QuadbinLayer = class extends import_geo_layers6._GeoCellLayer { indexToBounds() { const { data, extruded, getQuadbin } = this.props; const coverage = extruded ? 0.99 : 1; return { data, _normalize: false, positionFormat: "XY", getPolygon: (x, objectInfo) => getQuadbinPolygon(getQuadbin(x, objectInfo), coverage), updateTriggers: { getPolygon: coverage } }; } }; QuadbinLayer.layerName = "QuadbinLayer"; QuadbinLayer.defaultProps = defaultProps4; var quadbin_layer_default = QuadbinLayer; // dist/layers/quadbin-tile-layer.js var import_quadbin5 = require("quadbin"); var renderSubLayers2 = (props) => { const { data } = props; if (!data || !data.length) return null; const isBigInt = typeof data[0].id === "bigint"; return new quadbin_layer_default(props, { getQuadbin: isBigInt ? (d) => d.id : (d) => (0, import_quadbin5.hexToBigInt)(d.id) }); }; var defaultProps5 = { data: TilejsonPropType, tileSize: DEFAULT_TILE_SIZE }; var QuadbinTileLayer = class extends import_core10.CompositeLayer { getLoadOptions() { const tileJSON = this.props.data; return mergeLoadOptions(super.getLoadOptions(), { fetch: { headers: { Authorization: `Bearer ${tileJSON.accessToken}` } }, cartoSpatialTile: { scheme: "quadbin" } }); } renderLayers() { const tileJSON = this.props.data; if (!tileJSON) return null; const { tiles: data, maxresolution: maxZoom } = tileJSON; const SubLayerClass = this.getSubLayerClass("spatial-index-tile", spatial_index_tile_layer_default); return new SubLayerClass(this.props, { id: `quadbin-tile-layer-${this.props.id}`, data, // TODO: Tileset2D should be generic over TileIndex type TilesetClass: QuadbinTileset2D, renderSubLayers: renderSubLayers2, maxZoom, loadOptions: this.getLoadOptions() }); } }; QuadbinTileLayer.layerName = "QuadbinTileLayer"; QuadbinTileLayer.defaultProps = defaultProps5; var quadbin_tile_layer_default = QuadbinTileLayer; // dist/layers/heatmap-tile-l