deck.gl layers supporting geospatial use cases and GIS formats with WebGL2/WebGPU acceleration
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
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.
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
});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
});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
});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
});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
});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};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
};Install with Tessl CLI
npx tessl i tessl/npm-deck-gl--geo-layers