or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

3d-tiles.mdanimation.mdindex.mdspatial-indexing.mdterrain.mdtile-layers.mdvector-tiles.md
tile.json

vector-tiles.mddocs/

Vector Tile Rendering

Specialized layer for rendering Mapbox Vector Tiles (MVT) with automatic GeoJSON conversion, highlighting support, and optimized binary data processing.

Capabilities

MVTLayer

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
});

TileJSON Support

TileJSON Interface

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]
});

Feature Highlighting

Cross-tile Feature Highlighting

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
      });
    }
  }
});

Binary Data Processing

Binary Format Support

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;
  }
});