GridLayer aggregates data into a regular grid-based heatmap using square cells. It provides similar functionality to HexagonLayer but with rectangular binning, making it ideal for aligned geographic data visualization and cases where regular grid patterns are preferred.
Creates a layer that aggregates data points into rectangular grid cells with configurable cell size and optional 3D extrusion.
/**
* Aggregate data into a grid-based heatmap
* @param props - Configuration properties for the grid layer
*/
class GridLayer<DataT = any> extends AggregationLayer<DataT, GridLayerProps<DataT>> {
constructor(props: GridLayerProps<DataT>);
}
interface GridLayerProps<DataT> extends LayerProps {
/** Array of data objects to aggregate */
data: DataT[];
/** Function to extract position from data object (default: d => d.position) */
getPosition?: Accessor<DataT, Position>;
/** Function to extract weight value for color aggregation (default: 1) */
getColorWeight?: Accessor<DataT, number>;
/** Function to extract weight value for elevation aggregation (default: 1) */
getElevationWeight?: Accessor<DataT, number>;
/** After data objects are aggregated into cells, this accessor is called on each cell to get the value that its color is based on. Not supported by GPU aggregation. */
getColorValue?: AggregateAccessor<DataT> | null;
/** After data objects are aggregated into cells, this accessor is called on each cell to get the value that its elevation is based on. Not supported by GPU aggregation. */
getElevationValue?: AggregateAccessor<DataT> | null;
/** Size of grid cells in meters (default: 1000) */
cellSize?: number;
/** Cell size multiplier (0-1) (default: 1) */
coverage?: number;
/** Whether to extrude grid cells in 3D (default: false) */
extruded?: boolean;
/** Cell elevation multiplier (default: 1) */
elevationScale?: number;
/** Aggregation operation for color values (default: 'SUM') */
colorAggregation?: AggregationOperation;
/** Aggregation operation for elevation values (default: 'SUM') */
elevationAggregation?: AggregationOperation;
/** Array of colors for the color scale (default: 6-class YlOrRd) */
colorRange?: Color[];
/** Color scale domain, default is set to the extent of aggregated weights in each cell */
colorDomain?: [number, number] | null;
/** Scaling function used to determine the color of the grid cell (default: 'quantize') */
colorScaleType?: 'quantize' | 'linear' | 'quantile' | 'ordinal';
/** Elevation scale output range (default: [0, 1000]) */
elevationRange?: [number, number];
/** Elevation scale input domain, default is set to between 0 and the max of aggregated weights in each cell */
elevationDomain?: [number, number] | null;
/** Scaling function used to determine the elevation of the grid cell (default: 'linear') */
elevationScaleType?: 'linear' | 'quantile';
/** Whether to use GPU aggregation (default: true) */
gpuAggregation?: boolean;
/** Filter cells and re-calculate color by lowerPercentile (0-100) (default: 0) */
lowerPercentile?: number;
/** Filter cells and re-calculate color by upperPercentile (0-100) (default: 100) */
upperPercentile?: number;
/** Filter cells and re-calculate elevation by elevationLowerPercentile (0-100) (default: 0) */
elevationLowerPercentile?: number;
/** Filter cells and re-calculate elevation by elevationUpperPercentile (0-100) (default: 100) */
elevationUpperPercentile?: number;
/** Custom accessor to retrieve a grid bin index from each data object. Not supported by GPU aggregation. */
gridAggregator?: ((position: number[], cellSize: number) => [number, number]) | null;
/** Material settings for lighting effect. Applies if extruded: true */
material?: Material;
/** This callback will be called when bin color domain has been calculated */
onSetColorDomain?: (minMax: [number, number]) => void;
/** This callback will be called when bin elevation domain has been calculated */
onSetElevationDomain?: (minMax: [number, number]) => void;
}
interface GridLayerPickingInfo<DataT = any> extends PickingInfo<DataT> {
/** The aggregated bin data */
object: AggregatedBin | null;
/** Grid cell coordinates [col, row] */
index: [number, number];
/** Total count of points in the bin */
count: number;
/** Aggregated color value for the bin */
colorValue?: number;
/** Aggregated elevation value for the bin */
elevationValue?: number;
/** Array indices of points in this bin (CPU aggregation only) */
pointIndices?: number[];
}Usage Examples:
import { GridLayer } from "@deck.gl/aggregation-layers";
// Basic grid layer for retail locations
const retailLayer = new GridLayer({
id: "retail-grid",
data: storeData,
getPosition: (d) => [d.longitude, d.latitude],
getColorWeight: (d) => d.revenue,
getElevationWeight: (d) => d.customers,
cellSize: 2000, // 2km grid cells
extruded: true,
elevationScale: 5,
colorRange: [
[65, 182, 196],
[127, 205, 187],
[199, 233, 180],
[237, 248, 177],
[255, 255, 204]
],
pickable: true
});
// Urban analysis with separate metrics
const urbanLayer = new GridLayer({
id: "urban-analysis",
data: urbanData,
getPosition: (d) => d.location,
getColorWeight: (d) => d.buildingDensity,
getElevationWeight: (d) => d.populationDensity,
cellSize: 1000, // 1km cells
coverage: 0.9,
extruded: true,
elevationScale: 8,
colorAggregation: 'MEAN',
elevationAggregation: 'MEAN',
colorRange: [
[255, 255, 178, 200],
[254, 204, 92, 200],
[253, 141, 60, 200],
[240, 59, 32, 200],
[189, 0, 38, 200]
],
elevationRange: [0, 200],
colorScaleType: 'quantize',
elevationScaleType: 'linear',
gpuAggregation: true,
pickable: true,
onHover: (info) => {
if (info.object) {
console.log(`Cell [${info.index[0]}, ${info.index[1]}]: Buildings: ${info.colorValue}, Population: ${info.elevationValue}`);
}
}
});Controls the size and appearance of grid cells.
/** Size of grid cells in meters (default: 1000) */
cellSize?: number;
/** Cell size multiplier, 0-1 where 1 = full size (default: 1) */
coverage?: number;
/** Whether to extrude grid cells in 3D (default: false) */
extruded?: boolean;
/** Custom grid aggregator function for advanced binning */
gridAggregator?: ((position: number[], cellSize: number) => [number, number]) | null;Controls color mapping for grid cells based on aggregated values.
/** Function to extract weight value for color aggregation */
getColorWeight?: Accessor<DataT, number>;
/** Aggregation operation for color values (default: 'SUM') */
colorAggregation?: AggregationOperation;
/** Array of colors for the color scale */
colorRange?: Color[];
/** Domain for color scale [min, max] */
colorDomain?: [number, number] | null;
/** Scaling function used to determine the color of the grid cell (default: 'quantize') */
colorScaleType?: 'quantize' | 'linear' | 'quantile' | 'ordinal';
/** Filter cells and re-calculate color by lowerPercentile (0-100) (default: 0) */
lowerPercentile?: number;
/** Filter cells and re-calculate color by upperPercentile (0-100) (default: 100) */
upperPercentile?: number;Controls 3D height of grid cells when extruded is true.
/** Function to extract weight value for elevation aggregation */
getElevationWeight?: Accessor<DataT, number>;
/** Aggregation operation for elevation values (default: 'SUM') */
elevationAggregation?: AggregationOperation;
/** Range of elevation values [min, max] (default: [0, 1000]) */
elevationRange?: [number, number];
/** Domain for elevation scale [min, max] */
elevationDomain?: [number, number] | null;
/** Scale factor for elevation values (default: 1) */
elevationScale?: number;
/** Scaling function used to determine the elevation of the grid cell (default: 'linear') */
elevationScaleType?: 'linear' | 'quantile';
/** Filter cells and re-calculate elevation by elevationLowerPercentile (0-100) (default: 0) */
elevationLowerPercentile?: number;
/** Filter cells and re-calculate elevation by elevationUpperPercentile (0-100) (default: 100) */
elevationUpperPercentile?: number;
/** Material properties for 3D rendering */
material?: Material;The layer uses a rectangular grid binning algorithm that:
// Default grid binning function
function defaultGridAggregator(position: [number, number], cellSize: number): [number, number] {
const col = Math.floor(position[0] / cellSize);
const row = Math.floor(position[1] / cellSize);
return [col, row];
}// Real estate price analysis
const realEstateLayer = new GridLayer({
id: "real-estate",
data: propertyData,
getPosition: (d) => [d.lng, d.lat],
getColorWeight: (d) => d.price,
getElevationWeight: (d) => d.squareFootage,
cellSize: 5000, // 5km cells for neighborhood analysis
extruded: true,
elevationScale: 0.1, // Scale down for building heights
colorAggregation: 'MEAN', // Average price per area
elevationAggregation: 'MEAN', // Average size per area
colorRange: [
[0, 128, 0], // Green for lower prices
[255, 255, 0], // Yellow for medium
[255, 0, 0] // Red for high prices
]
});
// Environmental monitoring
const environmentalLayer = new GridLayer({
id: "environmental",
data: sensorData,
getPosition: (d) => d.coordinates,
getColorWeight: (d) => d.airQuality,
getElevationWeight: (d) => d.noiseLevel,
cellSize: 500, // 500m fine-grained analysis
coverage: 0.8,
extruded: true,
elevationScale: 20,
colorAggregation: 'MEAN',
elevationAggregation: 'MAX', // Peak noise levels
colorDomain: [0, 100], // Air quality index
elevationDomain: [0, 80], // Decibel levels
gpuAggregation: true
});
// Transportation flow analysis
const transportLayer = new GridLayer({
id: "transport",
data: vehicleData,
getPosition: (d) => d.currentLocation,
getColorWeight: (d) => d.speed,
getElevationWeight: (d) => 1, // Count vehicles
cellSize: 200, // 200m for traffic analysis
extruded: true,
colorAggregation: 'MEAN', // Average speed
elevationAggregation: 'COUNT', // Vehicle count
colorRange: [
[255, 0, 0], // Red for slow traffic
[255, 255, 0], // Yellow for medium
[0, 255, 0] // Green for fast traffic
],
elevationScale: 10
});| Feature | GridLayer | HexagonLayer |
|---|---|---|
| Cell Shape | Square/Rectangle | Hexagon |
| Alignment | Grid-aligned | Natural clustering |
| Edge Effects | More pronounced | Minimized |
| Computation | Slightly faster | More complex |
| Visual Appeal | Regular/structured | Organic/natural |
| Use Cases | Urban planning, aligned data | Population studies, natural phenomena |