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

spatial-indexing.mddocs/

Spatial Indexing Systems

Layers for visualizing various spatial indexing and gridding systems including H3 hexagons, S2 cells, Geohash, and Quadkeys with optimized rendering for large-scale geospatial data analysis.

Capabilities

H3 Hexagon Layer

Layer for rendering H3 hexagonal grid cells with automatic precision adjustment and clustering support.

/**
 * Layer for rendering H3 hexagonal grid cells
 * Provides efficient visualization of H3 spatial indexing system
 */
class H3HexagonLayer<DataT = any> extends CompositeLayer {
  constructor(props: H3HexagonLayerProps<DataT>);
}

interface H3HexagonLayerProps<DataT = unknown> extends 
  Omit<PolygonLayerProps<DataT>, 'getPolygon'> {
    
  /** Accessor function to get H3 cell ID from data */
  getHexagon?: AccessorFunction<DataT, H3Index>;
  
  /** Coverage ratio for hexagon size (0-1) */
  coverage?: number;
  
  /** Center hexagon for high precision coordinate mode */
  centerHexagon?: H3Index | null;
  
  /** Use high precision rendering (auto, true, false) */
  highPrecision?: boolean | 'auto';
}

type H3Index = string;

Usage Examples:

import { H3HexagonLayer } from "@deck.gl/geo-layers";

// Basic H3 hexagon visualization
const h3Layer = new H3HexagonLayer({
  id: 'h3-hexagons',
  data: [
    { hex: '882681a3ecfffff', count: 150, category: 'residential' },
    { hex: '882681a3edfffff', count: 320, category: 'commercial' },
    { hex: '882681a3eafffff', count: 89, category: 'industrial' }
  ],
  
  getHexagon: d => d.hex,
  getFillColor: d => {
    switch (d.category) {
      case 'residential': return [255, 255, 0, 180];
      case 'commercial': return [255, 0, 255, 180];
      case 'industrial': return [0, 255, 255, 180];
      default: return [200, 200, 200, 180];
    }
  },
  getElevation: d => d.count * 10,
  
  coverage: 0.8,
  extruded: true,
  pickable: true
});

// High-precision H3 layer for detailed areas
const precisionH3Layer = new H3HexagonLayer({
  id: 'precision-h3',
  data: detailedHexData,
  
  getHexagon: d => d.h3_index,
  getFillColor: d => [d.value * 255, 0, (1 - d.value) * 255, 200],
  getElevation: d => d.value * 1000,
  
  // Use high precision for accurate coordinate positioning
  highPrecision: true,
  centerHexagon: '882681a3ecfffff', // Reference hexagon for precision
  
  coverage: 0.95,
  extruded: true,
  wireframe: true
});

// Clustered H3 visualization with coverage adjustment
const clusteredH3Layer = new H3HexagonLayer({
  id: 'clustered-h3',
  data: spatialData,
  
  getHexagon: d => d.hex_id,
  getFillColor: d => {
    const intensity = Math.min(d.point_count / 100, 1);
    return [255 * intensity, 0, 255 * (1 - intensity), 150];
  },
  getLineColor: [255, 255, 255],
  getLineWidth: 2,
  
  // Adjust coverage based on zoom level
  coverage: 0.7,
  
  extruded: false,
  stroked: true,
  pickable: true
});

H3 Cluster Layer

Layer for rendering multiple H3 hexagons as unified clusters with multi-polygon support.

/**
 * Layer for rendering clusters of H3 hexagons as unified polygons
 * Automatically generates multi-polygon geometries from H3 cell arrays
 */
class H3ClusterLayer<DataT = any> extends CompositeLayer {
  constructor(props: H3ClusterLayerProps<DataT>);
}

interface H3ClusterLayerProps<DataT = unknown> extends 
  Omit<PolygonLayerProps<DataT>, 'getPolygon'> {
    
  /** Accessor function to get array of H3 cell IDs from data */
  getHexagons?: AccessorFunction<DataT, H3Index[]>;
}

type H3Index = string;

Clustering Examples:

import { H3ClusterLayer } from "@deck.gl/geo-layers";

// Render H3 hexagon clusters as unified multi-polygons
const clusterLayer = new H3ClusterLayer({
  id: 'h3-clusters',
  data: [
    { 
      hexagons: ['882681a3ecfffff', '882681a3edfffff', '882681a340fffff'], 
      cluster_id: 'cluster_1',
      density: 'high'
    },
    { 
      hexagons: ['882681a3eafffff', '882681a341fffff'], 
      cluster_id: 'cluster_2',
      density: 'medium'
    }
  ],
  
  getHexagons: d => d.hexagons,
  getFillColor: d => {
    switch (d.density) {
      case 'high': return [255, 0, 0, 200];
      case 'medium': return [255, 255, 0, 200];
      case 'low': return [0, 255, 0, 200];
      default: return [128, 128, 128, 200];
    }
  },
  
  getElevation: d => d.hexagons.length * 100,
  extruded: true,
  pickable: true
});

// Multi-polygon H3 clusters with complex geometries
const complexClusterLayer = new H3ClusterLayer({
  id: 'complex-clusters',
  data: complexClusterData,
  
  getHexagons: d => d.h3_cells,
  getFillColor: d => {
    const cellCount = d.h3_cells.length;
    const intensity = Math.min(cellCount / 20, 1);
    return [255 * intensity, 255 * (1 - intensity), 128, 180];
  },
  
  getLineColor: [255, 255, 255],
  getLineWidth: 2,
  
  stroked: true,
  filled: true,
  extruded: false,
  pickable: true
});

S2 Geometry Layer

Layer for rendering Google S2 geometry cells with full S2 spatial indexing support.

/**
 * Layer for rendering Google S2 geometry cells
 * Supports S2 spatial indexing system for spherical geometry
 */
class S2Layer<DataT = any> extends CompositeLayer {
  constructor(props: S2LayerProps<DataT>);
}

interface S2LayerProps<DataT = unknown> extends 
  Omit<PolygonLayerProps<DataT>, 'getPolygon'> {
    
  /** Accessor function to get S2 cell token from data */
  getS2Token?: AccessorFunction<DataT, string>;
}

S2 Examples:

import { S2Layer } from "@deck.gl/geo-layers";

// S2 cell visualization
const s2Layer = new S2Layer({
  id: 's2-cells',
  data: [
    { token: '89c259', population: 15000, density: 'high' },
    { token: '89c25b', population: 8500, density: 'medium' },
    { token: '89c25d', population: 3200, density: 'low' }
  ],
  
  getS2Token: d => d.token,
  getFillColor: d => {
    switch (d.density) {
      case 'high': return [255, 0, 0, 150];
      case 'medium': return [255, 255, 0, 150];
      case 'low': return [0, 255, 0, 150];
      default: return [128, 128, 128, 150];
    }
  },
  getElevation: d => d.population / 10,
  
  extruded: true,
  stroked: true,
  getLineColor: [255, 255, 255],
  lineWidthMinPixels: 1,
  pickable: true
});

Geohash Layer

Layer for rendering Geohash grid cells with precision-based visualization.

/**
 * Layer for rendering Geohash grid cells
 * Supports variable-precision geohash spatial indexing
 */
class GeohashLayer<DataT = any> extends CompositeLayer {
  constructor(props: GeohashLayerProps<DataT>);
}

interface GeohashLayerProps<DataT = unknown> extends 
  Omit<PolygonLayerProps<DataT>, 'getPolygon'> {
    
  /** Accessor function to get geohash string from data */
  getGeohash?: AccessorFunction<DataT, string>;
}

Geohash Examples:

import { GeohashLayer } from "@deck.gl/geo-layers";

// Geohash cell visualization with variable precision
const geohashLayer = new GeohashLayer({
  id: 'geohash-cells',
  data: [
    { hash: 'dr5reg', activity: 0.8, type: 'urban' },
    { hash: 'dr5rek', activity: 0.4, type: 'suburban' },
    { hash: 'dr5rem', activity: 0.1, type: 'rural' }
  ],
  
  getGeohash: d => d.hash,
  getFillColor: d => {
    const intensity = d.activity;
    return [255 * intensity, 255 * (1 - intensity), 0, 180];
  },
  getLineColor: [255, 255, 255],
  getLineWidth: 2,
  
  stroked: true,
  filled: true,
  pickable: true
});

// Multi-precision geohash display
const multiPrecisionLayer = new GeohashLayer({
  id: 'multi-precision',
  data: variablePrecisionData, // Mix of different precision geohashes
  
  getGeohash: d => d.geohash,
  getFillColor: d => {
    const precision = d.geohash.length;
    // Color by precision level
    const hue = (precision - 3) * 60; // 3-8 precision range
    return [
      Math.sin(hue * Math.PI / 180) * 127 + 128,
      Math.cos(hue * Math.PI / 180) * 127 + 128,
      Math.sin((hue + 90) * Math.PI / 180) * 127 + 128,
      150
    ];
  },
  
  getElevation: d => d.geohash.length * 100, // Height by precision
  extruded: true,
  pickable: true
});

Quadkey Layer

Layer for rendering Microsoft Quadkey tile system cells.

/**
 * Layer for rendering Quadkey tile system cells
 * Supports Microsoft's quadtree spatial indexing system
 */
class QuadkeyLayer<DataT = any> extends CompositeLayer {
  constructor(props: QuadkeyLayerProps<DataT>);
}

interface QuadkeyLayerProps<DataT = unknown> extends 
  Omit<PolygonLayerProps<DataT>, 'getPolygon'> {
    
  /** Accessor function to get quadkey string from data */
  getQuadkey?: AccessorFunction<DataT, string>;
}

Quadkey Examples:

import { QuadkeyLayer } from "@deck.gl/geo-layers";

// Quadkey tile visualization
const quadkeyLayer = new QuadkeyLayer({
  id: 'quadkey-tiles',
  data: [
    { quadkey: '120102', traffic: 'heavy', incidents: 5 },
    { quadkey: '120103', traffic: 'medium', incidents: 2 },
    { quadkey: '120110', traffic: 'light', incidents: 0 }
  ],
  
  getQuadkey: d => d.quadkey,
  getFillColor: d => {
    switch (d.traffic) {
      case 'heavy': return [255, 0, 0, 200];
      case 'medium': return [255, 128, 0, 200];
      case 'light': return [0, 255, 0, 200];
      default: return [128, 128, 128, 200];
    }
  },
  getElevation: d => d.incidents * 100,
  
  extruded: true,
  stroked: true,
  getLineColor: [255, 255, 255],
  pickable: true
});

// Hierarchical quadkey display
const hierarchicalLayer = new QuadkeyLayer({
  id: 'hierarchical-quadkeys',
  data: hierarchicalData,
  
  getQuadkey: d => d.qk,
  getFillColor: d => {
    const level = d.qk.length;
    // Transparency increases with zoom level detail
    const alpha = Math.min(50 + level * 30, 255);
    return [100 + level * 20, 150, 255 - level * 20, alpha];
  },
  
  getLineColor: d => {
    const level = d.qk.length;
    return level > 10 ? [255, 255, 255] : [200, 200, 200];
  },
  getLineWidth: d => Math.max(3 - d.qk.length * 0.2, 0.5),
  
  stroked: true,
  filled: true,
  pickable: true
});

Spatial Index Utilities

Index Conversion and Operations

Utility functions for working with different spatial indexing systems.

// H3 utilities (from h3-js library)
/**
 * Convert lat/lng to H3 cell index
 */
function latLngToCell(lat: number, lng: number, resolution: number): H3Index;

/**
 * Convert H3 cell index to lat/lng
 */
function cellToLatLng(h3Index: H3Index): [number, number];

/**
 * Get H3 cell resolution level
 */
function getResolution(h3Index: H3Index): number;

/**
 * Check if H3 cell is a pentagon
 */
function isPentagon(h3Index: H3Index): boolean;

/**
 * Calculate distance between two H3 cells
 */
function gridDistance(origin: H3Index, destination: H3Index): number;

// Geohash utilities
/**
 * Encode lat/lng to geohash
 */
function encodeGeohash(lat: number, lng: number, precision: number): string;

/**
 * Decode geohash to lat/lng bounds
 */
function decodeGeohash(geohash: string): {
  latitude: [number, number];
  longitude: [number, number];
};

// Quadkey utilities  
/**
 * Convert tile coordinates to quadkey
 */
function tileToQuadkey(x: number, y: number, z: number): string;

/**
 * Convert quadkey to tile coordinates
 */
function quadkeyToTile(quadkey: string): {x: number, y: number, z: number};

Performance Considerations

Precision and Performance Trade-offs

Different spatial indexing systems have various performance characteristics:

// H3 - Best for hexagonal analysis, good performance
const h3Config = {
  resolution: 8,        // Balance detail vs performance
  highPrecision: 'auto', // Auto-adjust based on zoom
  coverage: 0.8         // Reduce overdraw
};

// S2 - Best for spherical geometry, moderate performance
const s2Config = {
  // S2 cells naturally adapt to different sizes
  // Performance depends on cell level in token
};

// Geohash - Good general purpose, fast lookup
const geohashConfig = {
  precision: 6,         // 6-8 characters typical
  // Shorter hashes = better performance, less precision
};

// Quadkey - Best for tile-based systems, very fast
const quadkeyConfig = {
  // Inherits zoom level from tile system
  // Performance scales with tile system
};