docs/api-reference/layers/icon-layer.md
import {IconLayerDemo} from '@site/src/doc-demos/layers';
<IconLayerDemo />The IconLayer renders raster icons at given coordinates.
There are two approaches to load icons. You can pre-generated a sprite image (iconAtlas), which packs all your icons
into one layout, and a JSON descriptor (iconMapping), which describes the position and size of each icon in the iconAtlas.
You can create sprite images with tools such as TexturePacker. This is the
most efficient way to load icons.
It is also possible to ask IconLayer to generate iconAtlas dynamically. This is slower but might be useful in certain
use cases.
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 {IconLayer} from '@deck.gl/layers';
const layer = new IconLayer({
id: 'IconLayer',
data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-stations.json',
getColor: d => [Math.sqrt(d.exits), 140, 0],
getIcon: d => 'marker',
getPosition: d => d.coordinates,
getSize: 40,
iconAtlas: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.png',
iconMapping: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.json',
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 {IconLayer} from '@deck.gl/layers';
type BartStation = {
name: string;
entries: number;
exits: number;
coordinates: [longitude: number, latitude: number];
};
const layer = new IconLayer<BartStation>({
id: 'IconLayer',
data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-stations.json',
getColor: (d: BartStation) => [Math.sqrt(d.exits), 140, 0],
getIcon: (d: BartStation) => 'marker',
getPosition: (d: BartStation) => d.coordinates,
getSize: 40,
iconAtlas: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.png',
iconMapping: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.json',
pickable: true
});
new Deck({
initialViewState: {
longitude: -122.4,
latitude: 37.74,
zoom: 11
},
controller: true,
getTooltip: ({object}: PickingInfo<BartStation>) => object && object.name,
layers: [layer]
});
import React from 'react';
import {DeckGL} from '@deck.gl/react';
import {IconLayer} from '@deck.gl/layers';
import type {PickingInfo} from '@deck.gl/core';
type BartStation = {
name: string;
entries: number;
exits: number;
coordinates: [longitude: number, latitude: number];
};
function App() {
const layer = new IconLayer<BartStation>({
id: 'IconLayer',
data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/bart-stations.json',
getColor: (d: BartStation) => [Math.sqrt(d.exits), 140, 0],
getIcon: (d: BartStation) => 'marker',
getPosition: (d: BartStation) => d.coordinates,
getSize: 40,
iconAtlas: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.png',
iconMapping: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.json',
pickable: true
});
return <DeckGL
initialViewState={{
longitude: -122.4,
latitude: 37.74,
zoom: 11
}}
controller
getTooltip={({object}: PickingInfo<BartStation>) => object && object.name}
layers={[layer]}
/>;
}
In some use cases, it is not possible to know the icons that will be used. Instead, each icon needs to be fetched from
a programmatically generated URL at runtime. For example, if you want to visualize avatars of github contributors for
a project on a map, it is not convenient for you to generate the iconAtlas with all the contributors' avatars.
In this case, you can follow this example. Auto packing icons is less efficient than pre-packed.
import {Deck} from '@deck.gl/core';
import {IconLayer} from '@deck.gl/layers';
import {Octokit} from '@octokit/rest';
const octokit = new Octokit();
const layer = new IconLayer<User>({
id: 'IconLayer',
data: octokit.repos.getContributors({owner: 'visgl', repo: 'deck.gl'}),
dataTransform: result => result.data,
getIcon: d => ({
url: d.avatar_url,
width: 128,
height: 128
}),
getPosition: (d, {index}) => [index * 100, Math.sqrt(d.contributions) * 10, 0],
getSize: 40,
pickable: true
});
new Deck({
views: new OrthographicView(),
initialViewState: {
target: [0, 0, 0],
zoom: 0
},
controller: true,
getTooltip: ({object}) => object && `${object.login}`,
layers: [layer]
});
import {Deck, OrthographicView, PickingInfo} from '@deck.gl/core';
import {IconLayer} from '@deck.gl/layers';
import {Octokit} from '@octokit/rest';
const octokit = new Octokit();
// https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#list-repository-contributors
type User = {
id: number;
login: string;
avatar_url: string;
contributions: number;
};
const layer = new IconLayer<User>({
id: 'IconLayer',
data: octokit.repos.getContributors({owner: 'visgl', repo: 'deck.gl'}),
dataTransform: result => result.data,
getIcon: (d: User) => ({
url: d.avatar_url,
width: 128,
height: 128
}),
getPosition: (d: User, {index}) => [index * 100, Math.sqrt(d.contributions) * 10, 0],
getSize: 40,
pickable: true
});
new Deck({
views: new OrthographicView(),
initialViewState: {
target: [0, 0, 0],
zoom: 0
},
controller: true,
getTooltip: ({object}: PickingInfo<User>) => object && `${object.login}`,
layers: [layer]
});
import React from 'react';
import {DeckGL} from '@deck.gl/react';
import {IconLayer} from '@deck.gl/layers';
import type {PickingInfo} from '@deck.gl/core';
import {Octokit} from '@octokit/rest';
const octokit = new Octokit();
// https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#list-repository-contributors
type User = {
id: number;
login: string;
avatar_url: string;
contributions: number;
};
function App() {
const layer = new IconLayer<User>({
id: 'IconLayer',
data: octokit.repos.getContributors({owner: 'visgl', repo: 'deck.gl'}),
dataTransform: result => result.data,
getIcon: (d: User) => ({
url: d.avatar_url,
width: 128,
height: 128
}),
getPosition: (d: User, {index}) => [index * 100, Math.sqrt(d.contributions) * 10, 0],
getSize: 40,
pickable: true
});
return <DeckGL
initialViewState={{
longitude: -122.4,
latitude: 37.74,
zoom: 11
}}
controller
getTooltip={({object}: PickingInfo<User>) => object && `${object.login}`}
layers={[layer]}
/>;
}
To install the dependencies from NPM:
npm install deck.gl
# or
npm install @deck.gl/core @deck.gl/layers
import {IconLayer} from '@deck.gl/layers';
import type {IconLayerProps} from '@deck.gl/layers';
new IconLayer<DataT>(...props: IconLayerProps<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.IconLayer({});
Inherits from all Base Layer properties.
iconAtlas (string | Texture | Image | ImageData | HTMLCanvasElement | HTMLVideoElement | ImageBitmap | Promise | object, optional) {#iconatlas}A pre-packed image that contains all icons.
Texture constructor, e.g. {width: <number>, height: <number>, data: <Uint8Array>}. Note that whenever this object shallowly changes, a new texture will be created.The image data will be converted to a Texture object. See textureParameters prop for advanced customization.
If you go with pre-packed strategy, this prop is required.
If you choose to use auto packing, this prop should be left empty.
iconMapping (object | string, optional) {#iconmapping}Icon names mapped to icon definitions, or a URL to load such mapping from a JSON file. Each icon is defined with the following values:
x (number, required): x position of icon on the atlas imagey (number, required): y position of icon on the atlas imagewidth (number, required): width of icon on the atlas imageheight (number, required): height of icon on the atlas imageanchorX (number, optional): horizontal position of icon anchor. Default: half width.anchorY (number, optional): vertical position of icon anchor. Default: half height.mask (boolean, optional): whether icon is treated as a transparency mask.
If true, user defined color is applied.
If false, pixel color from the image is applied. User still can specify the opacity through getColor.
Default: falseIf you go with pre-packed strategy, this prop is required.
If you choose to use auto packing, this prop should be left empty.
sizeScale (number, optional) {#sizescale}1Icon size multiplier.
sizeBasis (string, optional) {#sizebasis}Determines which dimension the size controls when scaling the icon. Valid values:
'height': The icon size controls the height of the icon (default).
'width': The icon size controls the width of the icon.
This affects how the icon is scaled to maintain its aspect ratio based on the chosen size basis.
sizeUnits (string, optional) {#sizeunits}pixelsThe units of the size, one of 'meters', 'common', and 'pixels'. See unit system.
sizeMinPixels (number, optional) {#sizeminpixels}0The minimum size in pixels. When using non-pixel sizeUnits, this prop can be used to prevent the icon from getting too small when zoomed out.
sizeMaxPixels (number, optional) {#sizemaxpixels}Number.MAX_SAFE_INTEGERThe maximum size in pixels. When using non-pixel sizeUnits, this prop can be used to prevent the icon from getting too big when zoomed in.
billboard (boolean, optional) {#billboard}trueIf true, the icon always faces camera. Otherwise the icon faces up (z).
alphaCutoff (number, optional) {#alphacutoff}0.05Discard pixels whose opacity is below this threshold. A discarded pixel would create a "hole" in the icon that is not considered part of the object. This is useful for customizing picking behavior, e.g. setting alphaCutoff: 0, autoHighlight will highlight an object whenever the cursor moves into its bounding box, instead of over the visible pixels.
loadOptions (object, optional) {#loadoptions}On top of the default options, also accepts options for the following loaders:
iconAtlas prop is an URL, or if getIcon returns URLs for auto-packingtextureParameters (object) {#textureparameters}Customize the texture parameters.
If not specified, the layer uses the following defaults to create a linearly smoothed texture from iconAtlas:
{
minFilter: 'linear',
magFilter: 'linear',
mipmapFilter: 'linear',
addressModeU: 'clamp-to-edge',
addressModeV: 'clamp-to-edge'
}
getIcon (Accessor<string>, optional) {#geticon}d => d.iconMethod called to retrieve the icon name of each object, returns string or object.
If you go with pre-packed strategy, then getIcon should return a string representing name of the icon,
used to retrieve icon definition from given iconMapping.
If you choose to use auto packing, then getIcon should return an object which contains
the following properties.
url (string, required): url to fetch the iconheight (number, required): max height of iconwidth (number, required): max width of iconid: (string, optional): unique identifier of the icon, fall back to url if not specifiedanchorX, anchorY, mask are the same as mentioned in iconMappingIconLayer uses id (fallback to url) to dedupe icons. For icons with the same id, even if their sizes differ, IconLayer will only define one icon according to the first occurrence and ignore the rest of them. Vice versa, for icons with different ids, even if urls are the same, the image will be fetched again to create a new definition with different size, anchor, etc.
The image loaded from url is always resized to fit the box defined by [width, height] while preserving its aspect ratio.
getPosition (Accessor<Position>, optional) {#getposition}d => d.positionMethod called to retrieve the position of each object, returns [lng, lat, z].
getSize (Accessor<number>, optional) {#getsize}1The size of each object, in units specified by sizeUnits (default pixels). By default the size controls the height of the object, this can be changed with the sizeBasis property.
getColor (Accessor<Color>, optional) {#getcolor}[0, 0, 0, 255]The rgba color is in the format of [r, g, b, [a]]. Each channel is a number between 0-255 and a is 255 if not supplied.
mask = false, only the alpha component will be used to control the opacity of the icon.getAngle (Accessor<number>, optional) {#getangle}0The rotating angle of each object, in degrees.
getPixelOffset (Accessor<number[2]>, optional) {#getpixeloffset}[0, 0]Screen space offset relative to the coordinates in pixel unit.
onIconError (Function) {#oniconerror}nullOnly used when using auto-packing. If the attempt to fetch an icon returned by getIcon fails, this callback is called with the following arguments:
event (object)
url (string) - the URL that was trying to fetchloadOptions (object) - the load options used for the fetchsource (object) - the original data object that requested this iconsourceIndex (object) - the index of the original data object that requested this iconerror (Error)This section is about the special requirements when supplying attributes directly to an IconLayer.
If data.attributes.getIcon is supplied, since its value can only be a typed array, iconMapping can only use integers as keys.