import { Dispatch } from 'react'; import { FeatureCollection } from 'geojson'; import { GeoJSON as GeoJSON_2 } from 'geojson'; import { IControl } from 'maplibre-gl'; import { Map as Map_2 } from 'maplibre-gl'; import { PropertyValueSpecification } from 'maplibre-gl'; import { Ref } from 'react'; import { SetStateAction } from 'react'; /** * Thresholds that trip `'auto'` render mode from GeoJSON to dynamic tiles. */ export declare interface AutoThreshold { /** * Maximum feature count rendered as GeoJSON * @default 50000 */ featureCount?: number; /** * Maximum source size in bytes rendered as GeoJSON * @default 26214400 (25 MB) */ byteSize?: number; } /** * Broad geometry category of a layer, used to pick map layer types. */ export declare type GeometryCategory = 'point' | 'line' | 'polygon' | 'mixed' | 'unknown'; /** * How a dataset is ingested into DuckDB. * * - `'table'` - Materialize into an in-memory table with an EPSG:3857 * column and R-Tree index (fast tiles; memory ~= dataset size) * - `'stream'` - GeoParquet only: query the file in place through a * view. Remote files are read with HTTP range requests per tile, * using the GeoParquet bbox covering column for row-group pruning * when present. Nothing is copied into the database. */ declare type IngestMode = 'table' | 'stream'; /** * How point features are rendered (geojson render mode only). * * - `'circle'` - One circle per point (the default) * - `'heatmap'` - A density heatmap surface * - `'cluster'` - Nearby points grouped into counted bubbles */ declare type PointMode = 'circle' | 'heatmap' | 'cluster'; /** * Rendering mode for a vector layer. * * - `'auto'` - Decide based on dataset size thresholds * - `'geojson'` - Convert to GeoJSON and render with a geojson source * - `'tiles'` - Generate dynamic MVT tiles with DuckDB per z/x/y */ export declare type RenderMode = 'auto' | 'geojson' | 'tiles'; /** * Custom hook for managing vector control state in React applications. * * This hook provides a simple way to track and update the state * of a VectorControl from React components. * * @example * ```tsx * function MyComponent() { * const { state, setState, setCollapsed } = useVectorState(); * * return ( *
* * setState(newState)} * /> *
* ); * } * ``` * * @param initialState - Optional initial state values * @returns Object containing state and update functions */ export declare function useVectorState(initialState?: Partial): { state: VectorState; setState: Dispatch>; setCollapsed: (collapsed: boolean) => void; setPanelWidth: (panelWidth: number) => void; setData: (data: Record) => void; reset: () => void; toggle: () => void; }; /** * A MapLibre GL control for visualizing vector data in many formats * (GeoJSON, GeoPackage, Shapefile, GeoParquet, FlatGeobuf, CSV/WKT). * * Small datasets are converted to GeoJSON; large datasets are rendered * as dynamic MVT tiles generated client-side by DuckDB-WASM and served * through a `duckdb://` protocol handler. DuckDB is lazy-loaded from a * CDN only when a non-GeoJSON format (or tile rendering) is requested. * * @example * ```typescript * const control = new VectorControl({ collapsed: false }); * map.addControl(control, 'top-right'); * await control.addData('https://example.com/data.geojson'); * await control.addData('https://example.com/buildings.parquet'); * ``` */ declare class VectorControl implements IControl { private _map?; private _mapContainer?; private _container?; private _panel?; private _content?; private _options; private _state; private _eventHandlers; private _layerManager?; private _enginePromise?; private _disposePanelUI?; private _styleLoadHandler; private _styleRestorePromise; private _removed; private _resizeHandler; private _mapResizeHandler; private _clickOutsideHandler; private _userWidth; private _userHeight; private _resizeDragCleanup; /** * Creates a new VectorControl instance. * * @param options - Configuration options for the control */ constructor(options?: Partial); /** * Called when the control is added to the map. * Implements the IControl interface. * * @param map - The MapLibre GL map instance * @returns The control's container element */ onAdd(map: Map_2): HTMLElement; /** * Called when the control is removed from the map. * Implements the IControl interface. */ onRemove(): void; /** * Loads a vector data source and adds it to the map. * * @param source - URL string, File/Blob, or GeoJSON object * @param options - Layer options * @returns Metadata of the added layer */ addData(source: VectorDataSource, options?: VectorLayerOptions): Promise; /** * Removes a layer added with {@link addData}. * * @param id - The layer id */ removeLayer(id: string): void; /** * Removes all layers added with {@link addData}. */ removeAll(): void; /** * Returns metadata for all loaded layers. */ getLayers(): VectorLayerInfo[]; /** * Returns metadata for a single layer. * * @param id - The layer id */ getLayer(id: string): VectorLayerInfo | undefined; /** * Materializes a layer's features as a GeoJSON FeatureCollection, so a host * can persist the data of a layer loaded from a local file (which a saved * project cannot otherwise recreate). Returns null for an unknown id, or a * layer whose data is not held locally (e.g. a streamed GeoParquet). * * @param id - The layer id. * @returns The features as a FeatureCollection, or null when unavailable. */ getLayerGeoJSON(id: string): Promise; /** * Reads the non-null values of one layer attribute without materializing * engine-backed geometry. * * @param id - The layer id. * @param property - An attribute field name. * @returns The values, or null when the layer or field is unavailable. */ getLayerPropertyValues(id: string, property: string): Promise; /** * Shows or hides a layer. * * @param id - The layer id * @param visible - Whether the layer should be visible */ setLayerVisibility(id: string, visible: boolean): void; /** * Zooms the map to a layer's extent. * * @param id - The layer id */ zoomToLayer(id: string): void; /** * Applies a style patch to a layer. * * @param id - The layer id * @param style - Partial style update */ setLayerStyle(id: string, style: Partial): void; /** * Sets a layer's master opacity, multiplied into every style opacity * (fill, circle, and line layers alike). * * @param id - The layer id * @param opacity - The new opacity (0-1) */ setLayerOpacity(id: string, opacity: number): void; /** * Enables or disables the attribute popup for a layer. * * @param id - The layer id * @param enabled - Whether clicking a feature opens a popup */ setLayerPicker(id: string, enabled: boolean): void; /** * Moves a layer's map layers before another map layer (or to the top * when omitted). * * @param id - The layer id * @param beforeId - Target map layer id, or undefined for the top */ setLayerBeforeId(id: string, beforeId?: string): void; /** * Switches a layer between GeoJSON and dynamic tile rendering. * * @param id - The layer id * @param mode - The requested render mode */ setRenderMode(id: string, mode: RenderMode): Promise; /** * Re-fetches a URL-backed layer's data and re-renders it in place, * keeping the same layer id, source, style, render mode, and position. * In-memory GeoJSON and File sources are static, so reloading them is a * no-op that returns the current layer info. * * @param id - The layer id * @returns The refreshed layer info, or undefined when no such layer exists */ reloadLayer(id: string): Promise; /** * Gets the current state of the control. * * @returns The current control state */ getState(): VectorState; /** * Updates the control state. * * @param newState - Partial state to merge with current state */ setState(newState: Partial): void; /** * Toggles the collapsed state of the control panel. */ toggle(): void; /** * Expands the control panel. */ expand(): void; /** * Collapses the control panel. */ collapse(): void; /** * Registers an event handler. * * @param event - The event type to listen for * @param handler - The callback function */ on(event: VectorControlEvent, handler: VectorControlEventHandler): void; /** * Removes an event handler. * * @param event - The event type * @param handler - The callback function to remove */ off(event: VectorControlEvent, handler: VectorControlEventHandler): void; /** * Gets the map instance. * * @returns The MapLibre GL map instance or undefined if not added to a map */ getMap(): Map_2 | undefined; /** * Gets the control container element. * * @returns The container element or undefined if not added to a map */ getContainer(): HTMLElement | undefined; /** * Gets the panel content element that hosts the control UI. * * @returns The content element or undefined if not added to a map */ getContentElement(): HTMLElement | undefined; /** * Returns the layer manager, throwing when the control has not been * added to a map yet. */ private _manager; /** * Lazily creates the shared DuckDB engine on first use. */ private _getEngine; /** * Emits an event to all registered handlers. * * @param event - The event type to emit * @param extra - Optional layer/error/message context */ private _emit; /** * Creates the main container element for the control. * Contains a toggle button (29x29) matching navigation control size. * * @returns The container element */ private _createContainer; /** * Creates the panel element with header and content areas. * Panel is positioned as a dropdown below the toggle button. * * @returns The panel element */ private _createPanel; /** * Adds drag handles in the panel's bottom-left and bottom-right * corners. Pointer drags resize the panel and the chosen size is kept * (in {@link _userWidth}/{@link _userHeight}) so repositioning does not * reset it. * * @param panel - The panel element to attach handles to */ private _addResizeHandles; /** * Starts a pointer-driven resize from one of the corner handles. * * The panel is first frozen to explicit left/top pixels (clearing any * right/bottom anchor) so the opposite edge stays put no matter which * corner the control sits in. The right handle then grows the panel * rightward, the left handle leftward; both grow it downward. Sizes are * clamped to a sensible minimum and to the map container. * * @param event - The pointerdown event * @param side - Which corner handle started the drag * @param panel - The panel element being resized * @param handle - The handle element (for pointer capture) */ private _beginResize; /** * Setup event listeners for panel positioning and click-outside behavior. */ private _setupEventListeners; /** * Detect which corner the control is positioned in. * * @returns The position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' */ private _getControlPosition; /** * Update the panel position based on button location and control corner. * Positions the panel next to the button, expanding in the appropriate direction. */ private _updatePanelPosition; } /** * Event types emitted by the vector control */ export declare type VectorControlEvent = 'collapse' | 'expand' | 'statechange' | 'layeradded' | 'layerremoved' | 'layerupdated' | 'loading' | 'error'; /** * Event handler function type */ export declare type VectorControlEventHandler = (event: VectorEventPayload) => void; /** * Options for configuring the VectorControl */ export declare interface VectorControlOptions { /** * Host-supplied loader for remote HTTP(S) datasets. * * When set, URL sources are downloaded through this callback and handed to * the control as a Blob/File. Desktop hosts can use a native HTTP client to * load servers that do not permit browser CORS while the public layer source * remains the original URL for persistence and refresh. */ urlLoader?: (url: string) => Promise; /** * Whether the control panel should start collapsed (showing only the toggle button) * @default true */ collapsed?: boolean; /** * Position of the control on the map * @default 'top-right' */ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'; /** * Title displayed in the control header * @default 'Vector Data' */ title?: string; /** * Width of the control panel in pixels * @default 320 */ panelWidth?: number; /** * Custom CSS class name for the control container */ className?: string; /** * Thresholds used by `'auto'` render mode */ autoThreshold?: AutoThreshold; /** * Default render mode for layers that do not specify one * @default 'auto' */ defaultRenderMode?: RenderMode; /** * Maximum zoom level for dynamic tile generation * @default 16 */ maxTileZoom?: number; /** * Attribution string attached to created sources */ attribution?: string; /** * Existing map layer id that new vector layers are inserted before * (e.g. a label layer), so loaded data renders underneath it. * Per-layer `beforeId` overrides this. */ beforeId?: string; /** * Whether clicking a feature opens a popup with its attributes. * Per-layer `picker` overrides this. * @default true */ enablePicker?: boolean; /** * Default ingest mode for new layers (per-layer `ingestMode` wins) * @default 'table' */ defaultIngestMode?: IngestMode; /** * Placeholder text shown in the panel's URL input * @default 'https://example.com/data.parquet' */ urlPlaceholder?: string; /** * Initial value of the panel's URL input, so a host can offer a * ready-to-load sample dataset (the input clears after a successful * load) */ defaultUrl?: string; /** * Automatically load `defaultUrl` when the control is added to the * map, as if the user had pressed Load (no-op without `defaultUrl`) * @default false */ autoLoad?: boolean; /** * Collapse the panel when the user clicks outside it (e.g. on the map). * Set to `false` to keep the panel open until the user closes it with * the header's close button. * @default true */ closeOnOutsideClick?: boolean; /** * Show drag handles in the panel's bottom-left and bottom-right * corners so the user can resize it. The bottom-right handle grows the * panel rightward, the bottom-left handle leftward (keeping the * opposite edge fixed); both grow it downward. The chosen size is kept * for the session. * @default false */ resizable?: boolean; /** * Optional sample datasets offered as one-click "Load sample data" * links below the URL input. Clicking a link fills the URL input; the * user must click Load to fetch the dataset. Omit or leave empty to * hide the row entirely, keeping the URL input clean for the user's own * links. */ sampleData?: VectorSampleDataset[]; /** * Placeholder shown in the sample-data dropdown before a selection * (e.g. 'Load sample data...'). Ignored when {@link sampleData} is * empty. * @default 'Load sample data...' */ sampleDataLabel?: string; /** * Base URL to load DuckDB-WASM from instead of the default jsDelivr CDN. * * Use this to self-host (or mirror) the assets and avoid the CDN request * (and the `script-src https://cdn.jsdelivr.net` CSP allowance it needs). * The base must mirror jsDelivr's layout for the pinned duckdb-wasm * version: an `/+esm` ES-module bundle plus the `/dist/*` wasm and worker * files. For example, `'/vendor/duckdb-wasm-1.31.0'` served from the host's * own origin. Defaults to jsDelivr when unset. */ duckdbWasmBaseUrl?: string; /** * Base URL to load sql.js from instead of the default jsDelivr CDN. * * sql.js is loaded on demand only when a GeoPackage is added, to repair * files missing the `gpkg_ogr_contents` feature-count table (without it, * GDAL crashes single-threaded DuckDB-WASM with a thread-constructor error). * The base must mirror jsDelivr's layout for the pinned sql.js version: a * `/dist/sql-wasm.js` UMD script plus the matching `/dist/sql-wasm.wasm`. * Set this alongside {@link duckdbWasmBaseUrl} to fully self-host and avoid * the `script-src https://cdn.jsdelivr.net` CSP allowance. Defaults to * jsDelivr when unset. */ sqlJsBaseUrl?: string; /** * Path or URL to a prebuilt DuckDB spatial extension. * * When set, the engine loads the extension with `LOAD ''` and skips * the remote `INSTALL spatial` step. Use this in sandboxed or firewalled * environments where DuckDB's extension repository is unreachable: without * it, loading a non-GeoJSON source (or any source routed through the engine) * hangs indefinitely on the blocked `INSTALL spatial`. The path must point at * an extension built for the pinned duckdb-wasm version's DuckDB core. * Defaults to a remote `INSTALL spatial; LOAD spatial;` when unset. */ spatialExtensionPath?: string; /** * Replaces the panel's built-in file browse with a host-supplied picker. * * When set, clicking the panel's drop zone calls this instead of opening * the native `` dialog, and each returned * {@link VectorFileSelection} is loaded through {@link VectorControl.addData} * with its `sourcePath` recorded on the layer's source descriptor. Use it on * a desktop host to open a native dialog that yields real filesystem paths, * so local-file layers can be persisted and re-read when a project reopens. * Drag-and-drop onto the zone still uses the browser's dropped files. */ fileOpener?: VectorFileOpener; /** * How the layers of a multi-layer container (a GeoPackage with several * feature tables, a multi-layer GDAL source, ...) are chosen. * * Unset, the control opens its built-in modal picker over the map with every * layer preselected, so the user can uncheck the ones they do not want * instead of having the whole container added to the map. Supply a * {@link VectorLayerSelector} to replace it with a host dialog, or set * `false` to skip the prompt and load every layer (the behavior before the * picker existed). A per-load {@link VectorLayerOptions.sourceLayers} wins * over this. */ selectLayers?: VectorLayerSelector | false; } /** * React wrapper component for VectorControl. * * This component manages the lifecycle of a VectorControl instance, * adding it to the map on mount and removing it on unmount. * * @example * ```tsx * import { VectorControlReact } from 'maplibre-gl-vector/react'; * * function MyMap() { * const [map, setMap] = useState(null); * const controlRef = useRef(null); * * return ( * <> *
* {map && ( * console.log('added', layer.name)} * /> * )} * * ); * } * ``` * * @param props - Component props including map instance and control options * @returns null - This component renders nothing directly */ export declare function VectorControlReact({ map, onStateChange, onLayerAdded, onLayerRemoved, onError, controlRef: externalRef, ...options }: VectorControlReactComponentProps): null; /** * Props for the React wrapper, extending the control props with an * optional ref exposing the underlying VectorControl instance. */ export declare interface VectorControlReactComponentProps extends VectorControlReactProps { /** * Ref receiving the VectorControl instance for programmatic use * (e.g. `controlRef.current?.addData(url)`) */ controlRef?: Ref; } /** * Props for the React wrapper component */ export declare interface VectorControlReactProps extends VectorControlOptions { /** * MapLibre GL map instance */ map: Map_2; /** * Callback fired when the control state changes */ onStateChange?: (state: VectorState) => void; /** * Callback fired when a layer finishes loading */ onLayerAdded?: (layer: VectorLayerInfo) => void; /** * Callback fired when a layer is removed */ onLayerRemoved?: (layer: VectorLayerInfo) => void; /** * Callback fired when loading data fails */ onError?: (error: Error) => void; } /** * Input data accepted by `VectorControl.addData`: a URL, a local * File/Blob, or a GeoJSON object. */ export declare type VectorDataSource = string | File | Blob | GeoJSON_2; /** * Payload passed to event handlers. */ export declare interface VectorEventPayload { type: VectorControlEvent; state: VectorState; /** The layer involved, for layer events */ layer?: VectorLayerInfo; /** The error, for 'error' events */ error?: Error; /** Human-readable progress message, for 'loading' events */ message?: string; } /** * Supplies the files loaded when the user clicks the panel's drop zone. * * A host sets this through {@link VectorControlOptions.fileOpener} to * replace the panel's built-in `` browse with its own * picker. On a desktop host (e.g. Tauri) this lets the host open a native * dialog that yields real filesystem paths, which it returns as * {@link VectorFileSelection.sourcePath} so layers loaded from local files * become restorable. Returning `null`, `undefined`, or an empty array * (e.g. the user cancelled) loads nothing. */ declare type VectorFileOpener = () => VectorFileSelection[] | null | undefined | Promise; /** * One file returned by a {@link VectorFileOpener}. Pairs the loaded * `File`/`Blob` with an optional host-meaningful `sourcePath` (e.g. an * absolute filesystem path on a desktop host) that the control records * on the resulting layer's {@link VectorSourceDescriptor} so the host * can persist it and re-read the file when a saved project is reopened. */ declare interface VectorFileSelection { /** The file contents to load. */ file: File | Blob; /** Display name when the blob has none (defaults to the file name). */ name?: string; /** * Host-meaningful path the file was read from. Opaque to the control: * it is echoed back unchanged on `VectorLayerInfo.source.path` so the * host can re-open the file later. Typically an absolute filesystem * path on a desktop host. */ sourcePath?: string; } /** * Vector data formats recognized by the control. * * The named values get dedicated readers; any other extension (kml, * gml, tab, dxf, ...) is passed through as-is and read with the * spatial extension's GDAL-backed ST_Read, so every format the * spatial extension supports works. 'unknown' means the format could * not be determined at all (no extension); it is still attempted via * ST_Read. */ export declare type VectorFormat = 'geojson' | 'geopackage' | 'shapefile' | 'geoparquet' | 'flatgeobuf' | 'csv' | 'unknown' | (string & {}); /** * Metadata describing a loaded vector layer. */ export declare interface VectorLayerInfo { /** Unique layer id */ id: string; /** Display name */ name: string; /** Where the data came from */ source: VectorSourceDescriptor; /** Detected source format */ format: VectorFormat; /** Resolved render mode (never 'auto') */ renderMode: 'geojson' | 'tiles'; /** Broad geometry category */ geometryType: GeometryCategory; /** Number of features, when known */ featureCount?: number; /** * Attribute field names found in the layer's features or engine table, when * known. A host uses them to offer attribute-driven choices such as a label * field. */ fields?: string[]; /** Source size in bytes, when known */ byteSize?: number; /** Layer extent in EPSG:4326 [minX, minY, maxX, maxY] */ bbox?: [number, number, number, number]; /** Whether the layer is currently visible */ visible: boolean; /** Master opacity (0-1) multiplied into every style opacity */ opacity: number; /** Whether clicking a feature opens an attribute popup */ picker: boolean; /** How the dataset was ingested ('stream' = queried in place) */ ingestMode: IngestMode; /** Named layer inside a multi-layer container, when one was selected */ sourceLayer?: string; /** Source CRS override used while ingesting this layer, when supplied. */ sourceCrs?: string; /** Map layer id this layer's map layers sit before, when set */ beforeId?: string; /** Current style */ style: VectorLayerStyle; /** Map source id */ sourceId: string; /** Map layer ids created for this layer */ layerIds: string[]; } /** * Options for adding a vector layer via `VectorControl.addData`. */ export declare interface VectorLayerOptions { /** * Unique layer id (auto-generated when omitted) */ id?: string; /** * Display name shown in the layer list (defaults to the file name) */ name?: string; /** * Render mode override for this layer * @default 'auto' */ renderMode?: RenderMode; /** * Whether the layer starts visible * @default true */ visible?: boolean; /** * Master opacity (0-1) multiplied into every style opacity * @default 1 */ opacity?: number; /** * Whether to zoom the map to the layer extent after adding * @default true */ fitBounds?: boolean; /** * Initial style overrides */ style?: Partial; /** * Named layer inside multi-layer containers (e.g. a GeoPackage table) */ sourceLayer?: string; /** * CRS to treat the source coordinates as, such as `EPSG:28992`. * Overrides CRS metadata embedded in the source. Useful for files whose * producer omitted or wrote incorrect CRS metadata. */ sourceCrs?: string; /** * Layers to load from a multi-layer container, as one vector layer each. * * Skips the picker (and {@link VectorControlOptions.selectLayers}), so a * host that already knows the subset — restoring a saved project, driving * the control from its own UI — loads it without prompting. Names are * matched case-insensitively against the container's layers and loaded in * the container's own order; unknown names are ignored, and a list matching * nothing is an error. Ignored when {@link sourceLayer} names a single layer * or the source is not a multi-layer container. */ sourceLayers?: string[]; /** * Explicit format when it cannot be detected from the file name/URL */ format?: VectorFormat; /** * Existing map layer id this layer's map layers are inserted before * (overrides the control-level `beforeId`) */ beforeId?: string; /** * Whether clicking a feature of this layer opens an attribute popup * (overrides the control-level `enablePicker`) */ picker?: boolean; /** * How the dataset is ingested (GeoParquet supports 'stream') * @default 'table' */ ingestMode?: IngestMode; /** * Sidecar files for a loose shapefile picked together with the `.shp` * (`.shx`, `.dbf`, `.prj`, `.cpg`, ...). They are registered under the * `.shp`'s base name so GDAL can resolve them; without at least the `.shx` * and `.dbf` the `.shp` cannot be read. Ignored for non-shapefile sources. */ companionFiles?: File[]; /** * Host-meaningful path a File/Blob source was read from (e.g. an absolute * filesystem path on a desktop host). Opaque to the control: it is echoed * back unchanged on `VectorLayerInfo.source.path` so a host can persist it * and re-read the file when a saved project is reopened. Ignored for URL and * GeoJSON-object sources, which are already restorable from their descriptor. */ sourcePath?: string; } /** * What the user is choosing between when a multi-layer container is loaded. */ declare interface VectorLayerSelectionContext { /** Display name of the container (file name or URL). */ sourceName: string; /** Detected format of the container (e.g. `'geopackage'`). */ format: VectorFormat; } /** * Chooses which layers of a multi-layer container to load. * * Called by `addData` once a container (a GeoPackage with several feature * tables, a multi-layer GDAL source, ...) reports more than one layer and the * caller named neither {@link VectorLayerOptions.sourceLayer} nor * {@link VectorLayerOptions.sourceLayers}. Return the subset to load, an empty * array to load nothing (the load rejects with a * `VectorLayerSelectionCancelledError`), or `null`/`undefined` to load every * layer. Names the container does not contain are ignored. * * Set it through {@link VectorControlOptions.selectLayers} to replace the * built-in picker with a host dialog, or set that option to `false` to load * every layer without prompting. */ declare type VectorLayerSelector = (layers: string[], context: VectorLayerSelectionContext) => string[] | null | undefined | Promise; /** * Per-layer style properties applied to the generated map layers. */ export declare interface VectorLayerStyle { /** Polygon fill color */ fillColor: string; /** Polygon fill opacity (0-1) */ fillOpacity: number; /** Line and polygon outline color */ lineColor: string; /** Line and polygon outline width in pixels */ lineWidth: number; /** Point circle color */ circleColor: string; /** Point circle radius in pixels */ circleRadius: number; /** Point circle opacity (0-1) */ circleOpacity: number; /** * Optional data-driven override for the polygon fill color, e.g. a * categorized `['match', ...]` or graduated `['interpolate', ...]` * expression. When set it takes precedence over `fillColor` (which remains * the flat fallback). Lets a host application apply attribute-driven * styling that a single color cannot express. */ fillColorExpression?: PropertyValueSpecification; /** Optional data-driven override for the line and polygon outline color. */ lineColorExpression?: PropertyValueSpecification; /** Optional data-driven override for the point circle color. */ circleColorExpression?: PropertyValueSpecification; /** * How point features are rendered. Only applies to point layers in the * `'geojson'` render mode (tiles always use circles). * @default 'circle' */ pointMode?: PointMode; /** * Heatmap kernel radius in pixels (when `pointMode` is `'heatmap'`). * @default 30 */ heatmapRadius?: number; /** * Heatmap intensity multiplier (when `pointMode` is `'heatmap'`). * @default 1 */ heatmapIntensity?: number; /** * Cluster radius in pixels (when `pointMode` is `'cluster'`). * @default 50 */ clusterRadius?: number; /** * Maximum zoom at which points still cluster (when `pointMode` is * `'cluster'`). * @default 14 */ clusterMaxZoom?: number; /** * Attribute whose value is rendered as a text label for every feature, via * a dedicated `symbol` map layer drawn on top of the geometry. An empty * string (or omitted) means no labels. Labels apply to every geometry type * and to both render modes; on polygons the label sits at the centroid. */ labelField?: string; /** * Label text size in pixels (when `labelField` is set). * @default 12 */ labelSize?: number; /** * Label text color (when `labelField` is set). * @default '#333333' */ labelColor?: string; /** * Color of the halo drawn behind label text (when `labelField` is set). * @default '#ffffff' */ labelHaloColor?: string; /** * Width of the label text halo in pixels (when `labelField` is set). * @default 1 */ labelHaloWidth?: number; /** * Label placement: `'point'` anchors one label per feature (the polygon * centroid for polygons); `'line'` places labels along line geometry. * @default 'point' */ labelPlacement?: 'point' | 'line'; /** * Let labels overlap instead of hiding colliding ones (when `labelField` * is set). * @default false */ labelAllowOverlap?: boolean; /** * Render polygon features as 3D extrusions (a `fill-extrusion` map layer) * instead of a flat fill. Only affects polygon geometry; line and point * layers ignore it. Toggling it rebuilds the layer's polygon map layers (a * flat `fill`/`outline` pair becomes a single `fill-extrusion` layer and * back), so the change cannot be a plain paint update. * @default false */ extrusionEnabled?: boolean; /** * Extrusion fill color (when `extrusionEnabled`). Falls back to `fillColor` * when unset. */ extrusionColor?: string; /** * Optional data-driven override for the extrusion color, taking precedence * over `extrusionColor` (which remains the flat fallback). */ extrusionColorExpression?: PropertyValueSpecification; /** * Extrusion opacity (0-1) when `extrusionEnabled`. * @default 1 */ extrusionOpacity?: number; /** * Extrusion height in meters: a constant, or a data-driven expression such * as `['get', 'height']`. Features extrude to 0 (flat) when unset. * @default 0 */ extrusionHeight?: number | PropertyValueSpecification; /** * Extrusion base height in meters: a constant or data-driven expression. * @default 0 */ extrusionBase?: number | PropertyValueSpecification; } /** * A named sample dataset offered as a one-click "Load sample data" link * in the panel, rendered below the URL input. Lets a host advertise * examples without prefilling the URL input (which stays empty for the * user's own links). Choosing a sample fills the URL input; the dataset * loads only after the user clicks Load. */ declare interface VectorSampleDataset { /** Link text shown to the user (e.g. 'Countries') */ label: string; /** Source URL inserted into the panel's URL input when the link is clicked */ url: string; /** Display name for the loaded layer (defaults to the file name) */ name?: string; /** * Ingest mode for this sample. When omitted, the panel's streaming * toggle decides, matching a manual URL load. Applied only when the * unchanged sample URL is loaded explicitly. */ ingestMode?: IngestMode; /** Render mode for this sample (defaults to the control's setting) */ renderMode?: RenderMode; } /** * Where a layer's data came from. URL-backed layers can be recreated * from this descriptor (e.g. when a host application restores a saved * project); file- and object-backed layers cannot. A discriminated * union, so a URL-backed descriptor always carries the URL needed to * recreate the layer. */ declare type VectorSourceDescriptor = { /** The data was loaded from a URL */ kind: 'url'; /** The source URL */ url: string; } | { /** The data came from a local File/Blob */ kind: 'file'; /** The local file name (when known) */ fileName?: string; /** * Host-meaningful path the file was read from, echoed from * {@link VectorLayerOptions.sourcePath}. Present only when the host * supplied one (e.g. a desktop file picker); lets the host re-read the * file to recreate the layer when a saved project is reopened. */ path?: string; } | { /** The data was passed as a GeoJSON object */ kind: 'geojson'; }; /** * Internal state of the vector control */ export declare interface VectorState { /** * Whether the control panel is currently collapsed */ collapsed: boolean; /** * Current panel width in pixels */ panelWidth: number; /** * Loaded vector layers */ layers: VectorLayerInfo[]; /** * Any custom state data */ data?: Record; } export { }