Specialized layer for rendering Mapbox Vector Tiles (MVT) with automatic GeoJSON conversion, highlighting support, and optimized binary data processing.
Layer for rendering Mapbox Vector Tiles with full GeoJSON compatibility and cross-tile feature highlighting.
/**
* Layer for rendering Mapbox Vector Tiles (MVT) with automatic GeoJSON conversion
* Extends TileLayer with MVT-specific functionality and optimizations
*/
class MVTLayer<FeaturePropertiesT = unknown> extends TileLayer<ParsedMvtTile> {
constructor(props: MVTLayerProps<FeaturePropertiesT>);
}
interface MVTLayerProps<FeaturePropertiesT = unknown> extends
Omit<TileLayerProps<ParsedMvtTile>, 'data'>,
Omit<GeoJsonLayerProps<FeaturePropertiesT>, 'data'> {
/** TileJSON specification or URL template for MVT tiles */
data: TileJson | URLTemplate;
/** Called if data is a TileJSON URL when it is successfully fetched */
onDataLoad?: ((tilejson: TileJson | null) => void) | null;
/** Needed for highlighting a feature split across two or more tiles */
uniqueIdProperty?: string;
/** A feature with ID corresponding to the supplied value will be highlighted */
highlightedFeatureId?: string | number | null;
/** Use tile data in binary format for better performance */
binary?: boolean;
/** Loaders for processing MVT data */
loaders?: any[];
}
interface MVTLayerPickingInfo<FeaturePropertiesT = {}> extends
TileLayerPickingInfo<ParsedMvtTile, PickingInfo<Feature<Geometry, FeaturePropertiesT>>> {
/** Additional MVT-specific picking information */
}
type ParsedMvtTile = Feature[] | BinaryFeatureCollection;Usage Examples:
import { MVTLayer } from "@deck.gl/geo-layers";
// Basic MVT layer with Mapbox tiles
const mvtLayer = new MVTLayer({
id: 'mvt-layer',
data: 'https://api.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/{z}/{x}/{y}.vector.pbf?access_token={token}',
// GeoJSON styling props
getFillColor: [140, 170, 180, 200],
getLineColor: [255, 255, 255],
getLineWidth: 1,
lineWidthMinPixels: 1,
pickable: true
});
// MVT layer with TileJSON specification
const tileJsonLayer = new MVTLayer({
id: 'tilejson-layer',
data: 'https://api.example.com/tiles.json',
onDataLoad: (tilejson) => {
console.log('TileJSON loaded:', tilejson);
},
getFillColor: [160, 180, 200],
pickable: true
});
// MVT layer with feature highlighting
const highlightLayer = new MVTLayer({
id: 'highlight-layer',
data: 'https://tiles.example.com/data/{z}/{x}/{y}.mvt',
uniqueIdProperty: 'id',
highlightedFeatureId: 12345,
getFillColor: f => f.properties.id === 12345 ? [255, 0, 0] : [140, 170, 180],
getLineColor: [255, 255, 255],
pickable: true,
onHover: info => {
if (info.object) {
// Update highlighting based on hover
layer.setProps({
highlightedFeatureId: info.object.properties.id
});
}
}
});
// MVT layer with custom binary processing
const binaryMvtLayer = new MVTLayer({
id: 'binary-mvt',
data: 'https://tiles.example.com/{z}/{x}/{y}.mvt',
binary: true, // Use binary format for better performance
// Custom styling based on binary feature properties
getFillColor: f => {
const category = f.properties?.category;
switch (category) {
case 'residential': return [255, 255, 0, 100];
case 'commercial': return [255, 0, 255, 100];
case 'industrial': return [0, 255, 255, 100];
default: return [200, 200, 200, 100];
}
},
getLineColor: [255, 255, 255],
lineWidthMinPixels: 1,
pickable: true
});Standard TileJSON specification support for MVT layer configuration.
interface TileJson {
/** TileJSON specification version */
tilejson: string;
/** An array of tile endpoints */
tiles: string[];
/** Vector layer information */
vector_layers: VectorLayer[];
/** Attribution text for the tiles */
attribution?: string;
/** Tile scheme (xyz or tms) */
scheme?: string;
/** Maximum zoom level */
maxzoom?: number;
/** Minimum zoom level */
minzoom?: number;
/** TileJSON version */
version?: string;
/** Tile bounds */
bounds?: [number, number, number, number];
/** Tile center */
center?: [number, number, number];
}
interface VectorLayer {
/** Layer identifier */
id: string;
/** Layer description */
description?: string;
/** Minimum zoom level for this layer */
minzoom?: number;
/** Maximum zoom level for this layer */
maxzoom?: number;
/** Attribute fields for features in this layer */
fields?: {[key: string]: string};
}TileJSON Usage:
// Using TileJSON URL
const layer = new MVTLayer({
id: 'tilejson-layer',
data: 'https://api.example.com/tiles.json',
onDataLoad: (tilejson) => {
console.log('Available layers:', tilejson.vector_layers);
console.log('Zoom range:', tilejson.minzoom, '-', tilejson.maxzoom);
}
});
// Using TileJSON object directly
const tileJsonSpec: TileJson = {
tilejson: '2.2.0',
tiles: ['https://tiles.example.com/{z}/{x}/{y}.mvt'],
vector_layers: [
{
id: 'buildings',
fields: { height: 'Number', type: 'String' },
minzoom: 10,
maxzoom: 14
}
],
minzoom: 0,
maxzoom: 14
};
const layer = new MVTLayer({
id: 'direct-tilejson',
data: tileJsonSpec,
getFillColor: [140, 170, 180]
});Support for highlighting features that span multiple tiles using unique identifiers.
interface HighlightingProps {
/** Property name to use as unique identifier across tiles */
uniqueIdProperty?: string;
/** Feature ID to highlight */
highlightedFeatureId?: string | number | null;
}Highlighting Examples:
// Enable cross-tile highlighting
const layer = new MVTLayer({
id: 'highlighted-layer',
data: 'https://tiles.example.com/{z}/{x}/{y}.mvt',
uniqueIdProperty: 'osm_id', // Property that uniquely identifies features
highlightedFeatureId: null, // Initially no highlight
getFillColor: f => {
// Highlight logic
const isHighlighted = f.properties.osm_id === layer.props.highlightedFeatureId;
return isHighlighted ? [255, 255, 0] : [140, 170, 180];
},
getLineColor: f => {
const isHighlighted = f.properties.osm_id === layer.props.highlightedFeatureId;
return isHighlighted ? [255, 0, 0] : [255, 255, 255];
},
pickable: true,
onHover: info => {
// Update highlight on hover
if (info.object) {
layer.setProps({
highlightedFeatureId: info.object.properties.osm_id
});
} else {
layer.setProps({
highlightedFeatureId: null
});
}
}
});MVTLayer supports binary data processing for improved performance with large datasets.
interface BinaryFeatureCollection {
shape: 'binary-feature-collection';
points?: BinaryPointFeatures;
lines?: BinaryLineFeatures;
polygons?: BinaryPolygonFeatures;
}
interface BinaryPointFeatures {
positions: Float64Array;
properties: any[];
numericProps?: {[key: string]: Float32Array};
}
interface BinaryLineFeatures {
pathIndices: Uint16Array;
positions: Float64Array;
properties: any[];
numericProps?: {[key: string]: Float32Array};
}
interface BinaryPolygonFeatures {
polygonIndices: Uint16Array;
positions: Float64Array;
properties: any[];
numericProps?: {[key: string]: Float32Array};
}Binary Processing Examples:
// Enable binary processing for better performance
const binaryLayer = new MVTLayer({
id: 'binary-layer',
data: 'https://tiles.example.com/{z}/{x}/{y}.mvt',
binary: true,
// Access binary data structures directly
getFillColor: (f, {index, data}) => {
if (data.binary) {
// Access numeric properties from binary format
const category = data.polygons?.numericProps?.category?.[index] || 0;
return category === 1 ? [255, 0, 0] : [0, 255, 0];
}
return [140, 170, 180];
},
// Use binary data for performance-critical operations
getElevation: (f, {index, data}) => {
if (data.binary && data.polygons?.numericProps?.height) {
return data.polygons.numericProps.height[index] * 10;
}
return 0;
}
});