docs/api-reference/layers/path-layer.md
import {PathLayerDemo} from '@site/src/doc-demos/layers';
<PathLayerDemo />The PathLayer renders lists of coordinate points as extruded polylines with mitering.
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
<Tabs groupId="language"> <TabItem value="js" label="JavaScript">import {Deck} from '@deck.gl/core';
import {PathLayer} from '@deck.gl/layers';
const layer = new PathLayer({
id: 'PathLayer',
data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-lines.json',
getColor: d => {
const hex = d.color;
// convert to RGB
return hex.match(/[0-9a-f]{2}/g).map(x => parseInt(x, 16));
},
getPath: d => d.path,
getWidth: 100,
pickable: true
});
new Deck({
initialViewState: {
longitude: -122.4,
latitude: 37.74,
zoom: 11
},
controller: true,
getTooltip: ({object}) => object && object.name,
layers: [layer]
});
import {Deck, PickingInfo} from '@deck.gl/core';
import {PathLayer} from '@deck.gl/layers';
type BartLine = {
name: string;
color: string;
path: [longitude: number, latitude: number][];
};
const layer = new PathLayer<BartLine>({
id: 'PathLayer',
data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-lines.json',
getColor: (d: BartLine) => {
const hex = d.color;
// convert to RGB
return hex.match(/[0-9a-f]{2}/g).map(x => parseInt(x, 16));
},
getPath: (d: BartLine) => d.path,
getWidth: 100,
pickable: true
});
new Deck({
initialViewState: {
longitude: -122.4,
latitude: 37.74,
zoom: 11
},
controller: true,
getTooltip: ({object}: PickingInfo<BartLine>) => object && object.name,
layers: [layer]
});
import React from 'react';
import {DeckGL} from '@deck.gl/react';
import {PathLayer} from '@deck.gl/layers';
import type {PickingInfo} from '@deck.gl/core';
type BartLine = {
name: string;
color: string;
path: [longitude: number, latitude: number][];
};
function App() {
const layer = new PathLayer<BartLine>({
id: 'PathLayer',
data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-lines.json',
getColor: (d: BartLine) => {
const hex = d.color;
// convert to RGB
return hex.match(/[0-9a-f]{2}/g).map(x => parseInt(x, 16));
},
getPath: (d: BartLine) => d.path,
getWidth: 100,
pickable: true
});
return <DeckGL
initialViewState={{
longitude: -122.4,
latitude: 37.74,
zoom: 11
}}
controller
getTooltip={({object}: PickingInfo<BartLine>) => object && object.name}
layers={[layer]}
/>;
}
To install the dependencies from NPM:
npm install deck.gl
# or
npm install @deck.gl/core @deck.gl/layers
import {PathLayer} from '@deck.gl/layers';
import type {PathLayerProps} from '@deck.gl/layers';
new PathLayer<DataT>(...props: PathLayerProps<DataT>[]);
To use pre-bundled scripts:
<script src="https://unpkg.com/deck.gl@^9.0.0/dist.min.js"></script>
<!-- or -->
<script src="https://unpkg.com/@deck.gl/core@^9.0.0/dist.min.js"></script>
<script src="https://unpkg.com/@deck.gl/layers@^9.0.0/dist.min.js"></script>
new deck.PathLayer({});
Inherits from all Base Layer properties.
widthUnits (string, optional) {#widthunits}'meters'The units of the line width, one of 'meters', 'common', and 'pixels'. See unit system.
widthScale (number, optional) {#widthscale}1The path width multiplier that multiplied to all paths.
widthMinPixels (number, optional) {#widthminpixels}0The minimum path width in pixels. This prop can be used to prevent the path from getting too thin when zoomed out.
widthMaxPixels (number, optional) {#widthmaxpixels}The maximum path width in pixels. This prop can be used to prevent the path from getting too thick when zoomed in.
capRounded (boolean, optional) {#caprounded}falseType of caps. If true, draw round caps. Otherwise draw square caps.
jointRounded (boolean, optional) {#jointrounded}falseType of joint. If true, draw round joints. Otherwise draw miter joints.
billboard (boolean, optional) {#billboard}falseIf true, extrude the path in screen space (width always faces the camera).
If false, the width always faces up.
miterLimit (number, optional) {#miterlimit}4The maximum extent of a joint in ratio to the stroke width.
Only works if jointRounded is false.
_pathType (object, optional) {#_pathtype}nullNote: This prop is experimental
One of null, 'loop' or 'open'.
If 'loop' or 'open', will skip normalizing the coordinates returned by getPath and instead assume all paths are to be loops or open paths. Disabling normalization improves performance during data update, but makes the layer prone to error in case the data is malformed. It is only recommended when you use this layer with preprocessed static data or validation on the backend.
When normalization is disabled, paths must be specified in the format of flat array. Open paths must contain at least 2 vertices and closed paths must contain at least 3 vertices. See getPath below for details.
getPath (Accessor<PathGeometry>, optional) {#getpath}object => object.pathCalled on each object in the data stream to retrieve its corresponding path.
A path can be one of the following formats:
[x, y, z]). Compatible with the GeoJSON LineString specification.[x0, y0, z0, x1, y1, z1, ...]. By default, each coordinate is assumed to contain 3 consecutive numbers. If each coordinate contains only two numbers (x, y), set the positionFormat prop of the layer to XY:new PathLayer<{vertices: Float32Array}>({
getPath: d => d.vertices, // [x0, y0, x1, y1, x2, y2, ...]
positionFormat: 'XY'
})
getColor (Accessor<Color>, optional) {#getcolor}[0, 0, 0, 255]The rgba color of each object, in r, g, b, [a]. Each component is in the 0-255 range.
getWidth (Accessor<number>, optional) {#getwidth}1The width of each path, in units specified by widthUnits (default meters).
This section is about the special requirements when supplying attributes directly to a PathLayer.
Because each path has a different number of vertices, when data.attributes.getPath is supplied, the layer also requires an array data.startIndices that describes the vertex index at the start of each path. For example, if there are 3 paths of 2, 3, and 4 vertices each, startIndices should be [0, 2, 5, 9].
Additionally, all other attributes (getColor, getWidth, etc.), if supplied, must contain the same layout (number of vertices) as the getPath buffer.
To truly realize the performance gain from using binary data, the app likely wants to skip all data processing in this layer. Specify the _pathType prop to skip normalization.
Example use case:
const PATH_DATA = [
{
path: [[-122.4, 37.7], [-122.5, 37.8], [-122.6, 37.85]],
name: 'Richmond - Millbrae',
color: [255, 0, 0]
},
// ...
];
new PathLayer({
data: PATH_DATA,
getPath: d => d.path,
getColor: d => d.color
})
The equivalent binary attributes would be:
// Flatten PATH_DATA into several binary buffers. This is typically done on the server or in a worker
// [-122.4, 37.7, -122.5, 37.8, -122.6, 37.85, ...]
const positions = new Float64Array(PATH_DATA.map(d => d.path).flat(2));
// The color attribute must supply one color for each vertex
// [255, 0, 0, 255, 0, 0, 255, 0, 0, ...]
const colors = new Uint8Array(PATH_DATA.map(d => d.path.map(_ => d.color)).flat(2));
// The "layout" that tells PathLayer where each path starts
const startIndices = new Uint16Array(PATH_DATA.reduce((acc, d) => {
const lastIndex = acc[acc.length - 1];
acc.push(lastIndex + d.path.length);
return acc;
}, [0]));
new PathLayer({
data: {
length: PATH_DATA.length,
startIndices: startIndices, // this is required to render the paths correctly!
attributes: {
getPath: {value: positions, size: 2},
getColor: {value: colors, size: 3}
}
},
_pathType: 'open' // this instructs the layer to skip normalization and use the binary as-is
})