data = (
lng = [-122.45, -122.42, -122.38, -122.50, -122.47, -122.41],
lat = [37.78, 37.76, 37.79, 37.77, 37.80, 37.75],
size = [80, 200, 120, 300, 150, 250]
)
Deck(
ScatterplotLayer(
data = data,
get_position = [:lng, :lat],
get_radius = :size,
get_fill_color = [255, 140, 0, 200],
radius_min_pixels = 3
),
initial_view_state = ViewState(longitude=-122.44, latitude=37.77, zoom=12)
)Layers
DeckGL.jl provides a variety of layer types for different visualization needs. Each example below is self-contained and ready to copy-paste.
Core Layers
Core layers render individual data points directly without aggregation.
ScatterplotLayer
Renders circles at given coordinates.
| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_position |
Symbol/Vector{Symbol} | required | Position accessor [:lng, :lat] |
get_radius |
Real/Symbol | 1 |
Circle radius in meters |
get_fill_color |
Vector/Symbol | [0,0,0,255] |
Fill color RGBA |
get_line_color |
Vector/Symbol | [0,0,0,255] |
Outline color RGBA |
get_line_width |
Real/Symbol | 1 |
Outline width |
radius_scale |
Real | 1 |
Radius multiplier |
radius_min_pixels |
Real | 0 |
Minimum radius in pixels |
radius_max_pixels |
Real | Inf |
Maximum radius in pixels |
stroked |
Bool | false |
Draw outline |
filled |
Bool | true |
Draw fill |
billboard |
Bool | false |
Always face camera |
opacity |
Real | 1 |
Layer opacity (0-1) |
pickable |
Bool | false |
Enable interactions |
ArcLayer
Renders arcs between source and target coordinates.
trips = (
src_lng = [-122.45, -122.50, -122.42],
src_lat = [37.78, 37.77, 37.76],
dst_lng = [-122.38, -122.41, -122.47],
dst_lat = [37.79, 37.75, 37.80]
)
Deck(
ArcLayer(
data = trips,
get_source_position = [:src_lng, :src_lat],
get_target_position = [:dst_lng, :dst_lat],
get_source_color = [0, 128, 255],
get_target_color = [255, 0, 128],
get_width = 3
),
initial_view_state = ViewState(longitude=-122.44, latitude=37.77, zoom=12)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_source_position |
Symbol/Vector{Symbol} | required | Source position |
get_target_position |
Symbol/Vector{Symbol} | required | Target position |
get_source_color |
Vector/Symbol | [0,0,0,255] |
Source end color |
get_target_color |
Vector/Symbol | [0,0,0,255] |
Target end color |
get_width |
Real/Symbol | 1 |
Arc width in pixels |
get_height |
Real/Symbol | 1 |
Arc height multiplier (0-1) |
get_tilt |
Real/Symbol | 0 |
Arc tilt in degrees |
great_circle |
Bool | false |
Use great circle arcs |
width_scale |
Real | 1 |
Width multiplier |
opacity |
Real | 1 |
Layer opacity (0-1) |
LineLayer
Renders straight lines between source and target coordinates.
connections = (
from_lng = [-122.45, -122.50, -122.42, -122.48],
from_lat = [37.78, 37.77, 37.76, 37.79],
to_lng = [-122.38, -122.41, -122.47, -122.43],
to_lat = [37.79, 37.75, 37.80, 37.74]
)
Deck(
LineLayer(
data = connections,
get_source_position = [:from_lng, :from_lat],
get_target_position = [:to_lng, :to_lat],
get_color = [255, 0, 0],
get_width = 2
),
initial_view_state = ViewState(longitude=-122.44, latitude=37.77, zoom=12)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_source_position |
Symbol/Vector{Symbol} | required | Source position |
get_target_position |
Symbol/Vector{Symbol} | required | Target position |
get_color |
Vector/Symbol | [0,0,0,255] |
Line color |
get_width |
Real/Symbol | 1 |
Line width |
width_units |
String | "pixels" |
Width units |
opacity |
Real | 1 |
Layer opacity (0-1) |
PathLayer
Renders paths/polylines from coordinate sequences.
routes = (
path = [
[[-122.45, 37.78], [-122.43, 37.79], [-122.40, 37.78], [-122.38, 37.79]],
[[-122.50, 37.77], [-122.48, 37.76], [-122.45, 37.75], [-122.42, 37.76]],
[[-122.47, 37.80], [-122.44, 37.81], [-122.41, 37.80], [-122.39, 37.81]]
],
)
Deck(
PathLayer(
data = routes,
get_path = :path,
get_color = [0, 128, 255],
get_width = 5,
cap_rounded = true,
joint_rounded = true
),
initial_view_state = ViewState(longitude=-122.44, latitude=37.78, zoom=12)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_path |
Symbol | required | Path coordinates column |
get_color |
Vector/Symbol | [0,0,0,255] |
Path color |
get_width |
Real/Symbol | 1 |
Path width |
cap_rounded |
Bool | false |
Round line caps |
joint_rounded |
Bool | false |
Round line joints |
billboard |
Bool | false |
Always face camera |
miter_limit |
Real | 4 |
Miter limit for sharp corners |
opacity |
Real | 1 |
Layer opacity (0-1) |
PolygonLayer
Renders filled and/or stroked polygons.
regions = (
polygon = [
[[-122.46, 37.78], [-122.44, 37.78], [-122.44, 37.80], [-122.46, 37.80], [-122.46, 37.78]],
[[-122.43, 37.76], [-122.40, 37.76], [-122.40, 37.78], [-122.43, 37.78], [-122.43, 37.76]],
[[-122.48, 37.74], [-122.45, 37.74], [-122.45, 37.76], [-122.48, 37.76], [-122.48, 37.74]]
],
value = [500, 1200, 800]
)
Deck(
PolygonLayer(
data = regions,
get_polygon = :polygon,
get_fill_color = [255, 140, 0, 100],
get_line_color = [255, 140, 0, 255],
get_line_width = 2,
extruded = true,
get_elevation = :value,
elevation_scale = 1
),
initial_view_state = ViewState(longitude=-122.44, latitude=37.77, zoom=12, pitch=45)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_polygon |
Symbol | required | Polygon coordinates column |
get_fill_color |
Vector/Symbol | [0,0,0,255] |
Fill color |
get_line_color |
Vector/Symbol | [0,0,0,255] |
Outline color |
get_line_width |
Real/Symbol | 1 |
Outline width |
filled |
Bool | true |
Draw fill |
stroked |
Bool | true |
Draw outline |
extruded |
Bool | false |
Extrude as 3D |
wireframe |
Bool | false |
Draw 3D wireframe |
get_elevation |
Real/Symbol | 1000 |
Polygon height for 3D |
elevation_scale |
Real | 1 |
Elevation multiplier |
opacity |
Real | 1 |
Layer opacity (0-1) |
TextLayer
Renders text labels at coordinates.
cities = (
lng = [-122.42, -122.47, -122.39, -122.50, -122.44],
lat = [37.78, 37.76, 37.79, 37.77, 37.75],
name = ["Downtown", "Sunset", "Marina", "Richmond", "Mission"]
)
Deck(
TextLayer(
data = cities,
get_position = [:lng, :lat],
get_text = :name,
get_size = 18,
get_color = [0, 0, 128],
font_family = "Helvetica, Arial, sans-serif",
background = true,
get_background_color = [255, 255, 255, 200]
),
initial_view_state = ViewState(longitude=-122.44, latitude=37.77, zoom=12)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_position |
Symbol/Vector{Symbol} | required | Position accessor |
get_text |
Symbol | required | Text content column |
get_size |
Real/Symbol | 32 |
Text size in pixels |
get_color |
Vector/Symbol | [0,0,0,255] |
Text color |
get_angle |
Real/Symbol | 0 |
Rotation in degrees |
get_text_anchor |
String | "middle" |
Horizontal anchor |
get_alignment_baseline |
String | "center" |
Vertical anchor |
font_family |
String | "Monaco, monospace" |
Font family |
billboard |
Bool | true |
Always face camera |
background |
Bool | false |
Draw background |
opacity |
Real | 1 |
Layer opacity (0-1) |
Aggregation Layers
Aggregation layers bin data points and render aggregated values.
HexagonLayer
Aggregates data into hexagonal bins and renders as 3D hexagons.
# Generate random earthquake-like data around San Francisco
earthquakes = let
n = 200
(
lng = -122.4 .+ 0.2 * randn(n),
lat = 37.8 .+ 0.15 * randn(n),
magnitude = 1.0 .+ 3.0 * rand(n)
)
end
Deck(
HexagonLayer(
data = earthquakes,
get_position = [:lng, :lat],
get_elevation_weight = :magnitude,
radius = 500,
elevation_scale = 50,
extruded = true,
coverage = 0.9
),
initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=11, pitch=45)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_position |
Symbol/Vector{Symbol} | required | Position accessor |
radius |
Real | 1000 |
Hexagon radius in meters |
coverage |
Real | 1 |
Hexagon coverage (0-1) |
extruded |
Bool | true |
Render as 3D |
elevation_scale |
Real | 1 |
Elevation multiplier |
elevation_range |
Vector | [0, 1000] |
Min/max elevation |
get_color_weight |
Real/Symbol | 1 |
Color aggregation weight |
get_elevation_weight |
Real/Symbol | 1 |
Elevation aggregation weight |
color_aggregation |
String | "SUM" |
Aggregation method |
elevation_aggregation |
String | "SUM" |
Aggregation method |
color_range |
Vector | yellow-red scale | Color gradient |
upper_percentile |
Real | 100 |
Upper filter percentile |
lower_percentile |
Real | 0 |
Lower filter percentile |
opacity |
Real | 1 |
Layer opacity (0-1) |
GridLayer
Aggregates data into rectangular grid cells.
# Generate random points around San Francisco
points = let
n = 300
(
lng = -122.4 .+ 0.15 * randn(n),
lat = 37.8 .+ 0.1 * randn(n),
)
end
Deck(
GridLayer(
data = points,
get_position = [:lng, :lat],
cell_size = 400,
elevation_scale = 10,
extruded = true,
coverage = 0.8
),
initial_view_state = ViewState(longitude=-122.4, latitude=37.8, zoom=11, pitch=45)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_position |
Symbol/Vector{Symbol} | required | Position accessor |
cell_size |
Real | 1000 |
Grid cell size in meters |
coverage |
Real | 1 |
Cell coverage (0-1) |
extruded |
Bool | true |
Render as 3D |
elevation_scale |
Real | 1 |
Elevation multiplier |
get_color_weight |
Real/Symbol | 1 |
Color aggregation weight |
get_elevation_weight |
Real/Symbol | 1 |
Elevation aggregation weight |
color_aggregation |
String | "SUM" |
Aggregation method |
elevation_aggregation |
String | "SUM" |
Aggregation method |
opacity |
Real | 1 |
Layer opacity (0-1) |
HeatmapLayer
Renders a heatmap based on point density and weights.
# Generate clustered incident data
incidents = let
n = 500
# Two clusters
lng1 = -122.45 .+ 0.03 * randn(n ÷ 2)
lat1 = 37.78 .+ 0.02 * randn(n ÷ 2)
lng2 = -122.40 .+ 0.02 * randn(n ÷ 2)
lat2 = 37.76 .+ 0.015 * randn(n ÷ 2)
(
lng = vcat(lng1, lng2),
lat = vcat(lat1, lat2),
severity = 1.0 .+ 4.0 * rand(n)
)
end
Deck(
HeatmapLayer(
data = incidents,
get_position = [:lng, :lat],
get_weight = :severity,
radius_pixels = 50,
intensity = 1,
threshold = 0.03
),
initial_view_state = ViewState(longitude=-122.43, latitude=37.77, zoom=12)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Any | required | Tables.jl-compatible data source |
get_position |
Symbol/Vector{Symbol} | required | Position accessor |
radius_pixels |
Real | 30 |
Radius of influence in pixels |
intensity |
Real | 1 |
Intensity multiplier |
threshold |
Real | 0.05 |
Minimum density threshold |
get_weight |
Real/Symbol | 1 |
Point weight |
color_range |
Vector | blue-green-yellow-red | Color gradient |
aggregation |
String | "SUM" |
Aggregation method |
opacity |
Real | 1 |
Layer opacity (0-1) |
Composite Layers
Composite layers render complex data types using multiple sub-layers.
GeoJsonLayer
Renders GeoJSON data as points, lines, and polygons.
geojson_data = Dict(
"type" => "FeatureCollection",
"features" => [
Dict(
"type" => "Feature",
"geometry" => Dict(
"type" => "Polygon",
"coordinates" => [[
[-122.46, 37.78], [-122.44, 37.78], [-122.44, 37.80],
[-122.46, 37.80], [-122.46, 37.78]
]]
),
"properties" => Dict("name" => "Area A")
),
Dict(
"type" => "Feature",
"geometry" => Dict(
"type" => "Point",
"coordinates" => [-122.42, 37.77]
),
"properties" => Dict("name" => "Point B")
),
Dict(
"type" => "Feature",
"geometry" => Dict(
"type" => "LineString",
"coordinates" => [
[-122.48, 37.76], [-122.45, 37.75], [-122.42, 37.76]
]
),
"properties" => Dict("name" => "Route C")
)
]
)
Deck(
GeoJsonLayer(
data = geojson_data,
get_fill_color = [0, 100, 200, 100],
get_line_color = [0, 100, 200, 255],
get_line_width = 3,
get_point_radius = 200,
line_width_min_pixels = 2
),
initial_view_state = ViewState(longitude=-122.44, latitude=37.77, zoom=12)
)| Property | Type | Default | Description |
|---|---|---|---|
data |
Dict/String | required | GeoJSON Dict or URL |
filled |
Bool | true |
Fill polygons |
stroked |
Bool | true |
Draw outlines |
extruded |
Bool | false |
Extrude polygons |
get_fill_color |
Vector/Symbol | [0,0,0,255] |
Fill color |
get_line_color |
Vector/Symbol | [0,0,0,255] |
Line color |
get_line_width |
Real/Symbol | 1 |
Line width |
get_point_radius |
Real/Symbol | 1 |
Point radius |
get_elevation |
Real/Symbol | 1000 |
Polygon elevation |
point_type |
String | "circle" |
Point rendering type |
opacity |
Real | 1 |
Layer opacity (0-1) |
GeoInterface.jl Integration
Convert GeoInterface-compatible geometries to GeoJSON:
using Shapefile
using DeckGL
# Load shapefile
shp = Shapefile.Table("boundaries.shp")
# Convert to GeoJSON and create layer
layer = geojson_layer(shp, get_fill_color=[255, 0, 0, 100])
# Or manually convert
geojson_dict = to_geojson(shp)
layer = GeoJsonLayer(data=geojson_dict)Supported geometry types:
- Point, MultiPoint
- LineString, MultiLineString
- Polygon, MultiPolygon
- GeometryCollection
- Feature, FeatureCollection