Every parameter¶
Every public name and every keyword, grouped, with its default. Use it as a lookup.
Public API¶
Everything in roadstyle.__all__, as import roadstyle as rs; rs.<name>.
| name | returns | what |
|---|---|---|
| Render | ||
render_edges(gdf, **kw) |
WebMap |
the main call; every keyword below |
render_dashboard(gdf, **kw) |
WebMap |
the map, a panel and the standard toolbox (Pages, Dashboard options) |
render_street_view(gdf, **kw) |
WebMap |
map + Google Street View side by side (Pages) |
sidebar_html(name) |
str |
a bundled sidebar fragment: "dashboard", "street_view" |
export_style(gdf, out_dir, *, base_url, format="xyz", **kw) |
path of style.json |
the roads as a MapLibre style, vector tiles ("xyz" folder or "pmtiles") and a sprite, for other map apps (guide). The style has the roads only: basemap=, views= and color_active= are errors. kw go to render_edges |
export_look(path=None, *, profile=None, palette=None, edges=None, highway_col="highway", oneway_col="oneway", tunnel_col="tunnel", bridge_col="bridge", id_col="edge_id", positions=None) |
the look (dict) | MapLibre layers with no source, for a data layer in another app (the GeoLibre plugin). It makes one casing layer and one fill layer for each drawing position (positions, else those of edges, else -10 to 10) |
snapshot(map_or_html, out_path, *, center, zoom, pitch, bearing, width=1200, height=800, scale=1, settle=2.5, timeout=40) |
path | a PNG via headless Chromium (needs playwright) |
| Read your data | ||
RoadEdges |
the canonical input: EPSG:4326 lines + a class column | |
as_edges(data, *, class_col="highway") |
RoadEdges |
coerce any input below (render_edges does this for you) |
normalize_edges(gdf, *, class_col, rename) |
RoadEdges |
from a GeoDataFrame |
load_edges(path, *, class_col, layer, rename) |
RoadEdges |
from any geo file (layer for GPKG) |
from_geojson(obj, *, class_col, crs=4326, rename) |
RoadEdges |
from a GeoJSON mapping |
from_arrow(table, *, class_col, geometry, crs, rename) |
RoadEdges |
from a pyarrow Table |
from_duckdb(con_or_rel, query=None, *, geometry, class_col, crs=4326, rename) |
RoadEdges |
from DuckDB; select the geometry as ST_AsWKB(geom) |
filter_edges(gdf, include, exclude, highway_col, match_links) |
GeoDataFrame | keep / drop road classes |
highway_types(gdf, highway_col="highway", normalize=True) |
list |
the classes present |
classify(values, method="natural", k=5, *, breaks=None, pivot=None, palette="viridis", reverse=False, fmt="{:g}", missing_label="not counted", missing_color="#e2e8f0") |
Classes |
colour classes for roads: .labels, .breaks, .colors and .option(column) (for color_options). method is natural (Fisher-Jenks), quantile, equal or fixed. A pivot is always a cut. missing_label and missing_color are for roads with no value (parts) |
natural_breaks(values, k), ramp(palette, k) |
cuts, colours | the cuts of classify, and k colours along a palette |
| Base maps, settings (Settings & palettes) | ||
BASEMAPS, Basemap, get_basemap, register_basemap |
base maps (below) | |
set_api_key(key, provider=None) / get_api_key(provider=None) |
/ str |
base-map API keys |
StyleConfig |
global styling knobs (below) | |
use_settings(*sources) |
apply settings (path or dict) for the process; no argument drops them | |
Overlay |
an extra layer for the web backend (below) | |
| Helpers | ||
compute_levels(edges, band_col=None, order="priority", ...) |
edges + 4 columns | the level step in one call (near_rules=False: True also lifts parts that only come near; head_m=5.0 decides once which parts of a stack cross; method="solve"): casing_start, casing_level, casing_end, fill_level (design) |
level_input(edges, id_col="edge_id", ...) |
(roads, pairs) |
the solver's input from any edges: one row per road, one row per relation (meet, stack one row per crossing part of the upper road, order; near with near_rules=True); head_m / heads (a heads.csv table) decide which parts cross |
solve_levels(roads, pairs, edits=None, ...) |
roads + 4 columns | the solver, from the tables only (a stack: one row per part, a_end start / main / end); edits switch rows off or add them; fixed ({road: (casing_start, casing_level, casing_end, fill_level)}) holds those roads' numbers and solves the others (the editor's local re-solve); max_positions limits the number of positions |
level_area.make_area(edges, folder, db=None, ...) / level_area.solve_area(folder) |
(roads, pairs) / solved roads |
an area folder (roadstyle-levels make / solve); with db every solve also writes into that DuckDB file |
render_edges(..., levels_db=file) |
– | reads visualization.edge_levels of a duckOSM file for these edges (some of the edges it was solved for; ids int64 or text); an error with level columns of your own |
save_area_levels(con, folder, *, schema="visualization") / load_area_levels(con, edges, *, schema="visualization", subset=False) |
– / edges + 8 columns | an area's result into visualization.edge_levels and back (the four numbers and each edge's ends); reading checks the edges |
save_levels(con, levels, *, schema="visualization") / load_levels(con, edges=None, *, schema="visualization", **expect) / restore_area_inputs(con, folder, *, schema="visualization") |
– / levels / – | the four level numbers of each edge into a duckOSM file and back; the area's input files from the file |
auto_ends(roads, pairs, zoom=18.0, ...) / casing_parts(roads, head_m=5.0, heads=None) |
tables | the end marks that the solver finds on its own; the casing pieces of each road |
is_directed(edges, driving_col="driving", cycling_col="cycling", highway_col="highway") |
bool column | the directed_col value: an edge open to cars or bikes that is not a path class |
export_inline(edges, **kw) / export_geojson(edges, out_dir, *, format="geojson", keep=None, **kw) / tile_geojson(src_dir, out, *, format="pmtiles", keep=None, base_url="") |
dict / dict / path | the style with its data inside; the style with its data as files; the tiles of those files |
normalize_highway(value) |
(base, is_link) |
strip OSM _link |
A WebMap has .html (the page as a string), .save(path), and shows inline in a notebook (Jupyter Notebook 7, JupyterLab): the
preview loads the bundled MapLibre version (5.24) from the jsDelivr CDN instead of inlining it, so it needs the network.
render_edges¶
render_edges(gdf, **kw): gdf is a GeoDataFrame (LineStrings + a highway column, any CRS) or
a RoadEdges. Every keyword is optional. Backends says which renderers read it; the others
ignore it.
Look¶
| keyword | default | backends | what |
|---|---|---|---|
profile |
None |
all | the name of a profile: every style value that is not a color (default, highsat, or ./profiles/<name>.yaml); None = the one in force (Profiles and palettes) |
backend |
"web" |
"web" (MapLibre, one offline file): the only backend (Big networks) |
|
palette |
"amber" |
all | "amber" (orange to green main roads, slate-grey streets), "carto" (soft OSM Carto tones), "highsat" (bright), "mono" or a registered palette |
basemap |
the basemap setting ("ofm_positron") |
all | a BASEMAPS key, a Basemap, a {z}/{x}/{y} URL or an xyzservices provider |
basemaps |
web: ofm_liberty, ofm_positron, osm, esri_gray, esri_street, satellite, blank (the seven base maps, each with its dark twin) |
web | the base maps offered in the switcher: the base-map tool of the dashboard, and the base-map button of a map page |
basemap_switcher |
True |
web | the base-map tool of the dashboard, or the base-map button of a map page, and its menu; False with a basemaps= list keeps the maps for rsSetBasemap |
zoom_readout |
True |
web | the small "z 13.2" zoom number beside the scale bar (the dashboard shows the scale and the zoom number only when the person turns them on in the settings, or with dashboard={"scale_box": True}); False leaves it out |
api_key |
None |
all | key for a keyed tile provider (order) |
arrows |
True |
web | one-way chevrons along each one-way edge |
labels |
True |
web | curved street names from the name column |
legend |
True |
web | a legend for data colouring (class styling has none). Web: a page key; the style always has the legend data (roadstyle:color_options) |
name |
"roadstyle" |
web | the page title |
hover_color / select_color |
"#b388ff" / "#7c4dff" |
web | highlight of the hovered / selected road |
minzoom |
None (the same for render_dashboard) |
web | hides minor classes when zoomed out. None or True: the minzoom setting. A dict changes parts of it. False: all classes at all zooms. The box under the table has the keys of the dict. |
offset_frac |
0.28 |
web | two-way lane offset, fraction of the road's pixel width; 0 = no lane split |
width_frac |
0.6 |
web | each lane's width, fraction of the full road width |
offset_zoom |
15 |
web | zoom where the two directions start to fan apart |
settings |
None |
all | a settings override for this call only: a dict, or the path of a JSON or YAML file; a file that cannot be read is an error (levels) |
minzoom (dict)
The dict changes parts of the minzoom setting. The key "*" sets every class first: {"*": 0, "service": 14} shows every class at every zoom except the service roads. The key "@private" is the first zoom of the roads with private access (access_col), for any class.
Filtering¶
| keyword | default | backends | what |
|---|---|---|---|
include / exclude |
None |
all | keep only / drop these classes (str or list) |
match_links |
True |
all | primary also matches primary_link |
filter_control |
True |
web | no effect: the floating Roads box is gone. The roads tool of the dashboard is the road filter, and rsSetClasses filters from a script |
filter_col |
None |
web | the column that rsSetClasses filters by, when it differs from highway_col |
find_control |
False |
web | a "Search roads…" box in the top-left stack (the docked panel has its own); the JS rsFind(text) is always defined (design) |
overlay_control |
True |
web | False hides the Layers box of the overlays on a map page, and the one switch of the style's base-map layers on a dashboard; rsSetOverlay still works. A page with a bar has no Layers box |
hillshade |
False |
web | True: the Hillshade switch of the base-map box starts on (the person's saved choice in the browser wins). The shade is drawn under the roads from the DEM of data/basemaps.json ontop.dem (Terrain Tiles on AWS, no key) |
terrain |
False |
web | True: the 3D terrain switch of the base-map box starts on (the saved choice of the person wins). Use pitch= to tilt the camera: a flat camera shows the hillshade only. A tunnel is drawn on the hill above it and a bridge in the valley under it, because MapLibre has no height for a line |
terrain_exaggeration |
None |
web | the height of the 3D terrain as a multiple of the DEM's: 2.0 doubles every hill, 0.5 halves it. None: ontop.terrain.exaggeration of data/basemaps.json (1.0). Read when the terrain switches on |
ground |
None |
web | the area's ground (the design): {id, source, product, vertical_datum, resolution_m, license, terrain}. terrain is the URL of the area's terrain file, a PMTiles archive of Terrarium PNG tiles that roadstyle terrain or the binding terrain_pmtiles makes from the ground grid (a data: URL embeds it). The hillshade and the 3D terrain then come from that file, and the attribution names the ground. roadstyle.duckosm.ground(db) gives it for a duckOSM file with main.elevation_grid, and duckosm.page uses it. None: the AWS Terrain Tiles, and the attribution says "Ground: AWS Terrain Tiles" |
scene_3d |
None |
web | 3D scene: the path of a PMTiles archive of GLB files (SimReady's <area>.page.pmtiles), or {"tiles": path, "url": address, "on": True, "popup": True, "min_zoom": 15, "max_tiles": 49, "cache_mb": 200} (the guide). roadstyle reads the archive's header and metadata when it renders the page: the parts (kinds), the CRS (simready.crs, an EPSG code in data/crs.json: a UTM zone, SWEREF99 TM, L-EST97, Web Mercator) and the ground id. The page fetches the tiles from url (default: the file name, next to the page). The archive's ground id must be the page's ground id: another id, or no ground, is an error that names both ids. A CRS that is not in the table is an error that lists the codes. on: the start of the switch; popup: a click shows the extras of the primitive; min_zoom: no tile is read below this zoom; max_tiles: the most tiles that the view reads (the nearest); cache_mb: the budget of the tiles that stay in memory. The layer draws only with the 3D terrain on |
terrain_tunnels |
"fade" |
web | what a tunnel does while the 3D terrain is on. "fade": its fill, gap and dashes show at ontop.terrain.tunnel_fade of data/basemaps.json (0.25). "hide": they do not show. "show": no change. Without it a tunnel is on the hill above it: MapLibre has no height for a line, so a per-edge height (a z column) cannot be drawn. No effect with the terrain off |
buildings_opacity |
None |
web | the opacity of the 3D buildings of a vector base map, from 0 to 1. None: ontop.buildings.opacity of data/basemaps.json (1, solid). The Opacity slider and rsBuildingsOpacity(value) change it. Another value is an error |
overlay_popup |
True |
web | False: no overlay shows a click popup (it stays clickable and fires rs:select); one overlay: Overlay(popup_window=False) |
access_col |
None |
web | a column with private, bus, pedestrian, delivery or nothing. A road with a value gets the access colour (#c8c8c8, #9db8d9, #dddde8, #e8d2b0) and a row in the roads tool. Use rsSetAccess, rsGetAccess and RS_ACCESS. The class row pedestrian goes when all its roads have an access kind |
Colour by data¶
| keyword | default | backends | what |
|---|---|---|---|
color_by |
None |
all | colour by this column instead of road class |
colors |
None |
all | categorical {value: hex}, or "self" = the value is the colour |
cmap |
"viridis" |
all | numeric ramp: a branca / matplotlib name ("RdYlGn_r") or a list of hex stops |
vmin, vmax |
data min / max | all | ramp range |
width_by |
None |
all | (min_px, max_px): width follows the numeric value |
color_table |
None |
all | per-edge colour: {id: colour}, a Series, or a DataFrame; missing edges grey, class widths kept |
color_key |
"edge_id" |
all | the edges column matched against color_table |
color_col |
"color" |
all | the colour column when color_table is a DataFrame |
color_options |
None |
web | {name: {styler kwargs}}: a Colour by menu that recolours in the browser; the first entry shows on open |
color_active |
0 |
web | the option shown on open (index or name) |
template |
None |
web | "map" (no panel; the default of render_edges) or "dashboard" (the default of render_dashboard). The dashboard sets the panel (empty), the toolbar and the window rules; its map has the defaults of "map". The old sidebar= and the names "classic" and "report" are errors |
layout |
None |
web | the dashboard's frame: "overlay" (default: the map fills the window, the panel floats, a toolbar) or "dock" (the panel is docked at the left and takes its own space, no toolbox). template="dashboard" only |
views |
None |
web | {name: {setting: value}}: a View menu next to Colour by; each view sets several things at once, the first shows on open |
Each color_options value takes color_by, colors, cmap, vmin, vmax, width_by,
palette, style, missing; {} is the class style. See Colour by your data.
A views entry sets only what it names: color (a color_options name), road_fill, bridges, tunnels, view3d
(True / False), overlays ({label: True / False}), classes (a list of road classes), basemap (a key), palette (a palette
name: every color of the map, Profiles and palettes). An unknown setting, or a name the page does not
have, is an error. Each palette that a view names is built once more into the page, so the page is somewhat larger.
A view sets only what it names, so name the same settings in every view when they must switch back. palette switches every color of the map: the road classes, and also the names, arrows, bridges, tunnels and the swatches of the roads tool. A color option with a palette ({"palette": "carto"}) recolors only the road fills. A page with the toolbox bar (the dashboard) hides the View menu: call rsSetView(name) from your own control there. rsSetRoadFill(on) sets the fill alone.
rs.render_edges(edges, views={"Day": {"palette": "amber", "basemap": "ofm_positron"},
"Night": {"palette": "mono", "basemap": "ofm_dark"}})
Popups & hover¶
| keyword | default | backends | what |
|---|---|---|---|
road_popup |
True |
web | on click: True = name, edge_id, edge_ref, highway, lanes, bridge, tunnel; a list = those columns; "all"; "panel" = docked panel; False = none (rs:select still fires) |
popup_mode |
None (= "popup") |
web | "panel" docks the read-out in a side panel with a search box |
side_panel_html |
None |
web | the HTML of your own full-height panel on the right, with the docked panel's » handle, « map button and rsPanelShow(on); the open or closed state is kept per page; --rs-side follows it. An error with popup_mode="panel" |
host_panel_width |
320 |
web | the width of that panel, px |
road_tooltip |
False |
web | on hover: True = every column, a list = those columns. Not on a touch-only device (a phone): a tap is a click |
hover_delay_ms |
300 |
web | a road or an overlay item lights up and shows its tooltip once the mouse rests this long on it (a passing mouse lights nothing); 0: at once |
data_maxzoom |
None |
web | the last zoom MapLibre cuts the GeoJSON sources into tiles at; above it, MapLibre enlarges those tiles and does not cut them again. Positions are as exact as the tile grid of that zoom. None: MapLibre's own |
data_tolerance |
None |
web | how far MapLibre simplifies the road geometry when it cuts tiles in the browser. None: 0.05, which keeps every vertex. A higher value (1) makes a sweep at zoom 12 about three times faster, and the picture is the same from zoom 14 |
tooltip |
None |
web | hover columns. Web: alias of road_tooltip, None = no tooltip. Folium: None = all columns |
Street View¶
| keyword | default | backends | what |
|---|---|---|---|
street_view |
"window" |
web | "window": a map button and a floating window that follows the clicked road. "dock" (dashboard): Street View beside the map, with a divider and no panel (Docked). True: a link in the popup. False: none. The page must be served over http(s) (guide) |
street_view_key |
env GOOGLE_MAPS_KEY |
web | a Google Maps JavaScript API key for the window: its bar offers Linked (a panorama; the map marker walks with the viewer) and Classic (the embed). Written into the page; restrict it to your site's addresses (Keys and tokens) |
mapillary_token |
env MAPILLARY_TOKEN |
web | a free Mapillary client token (mapillary.com/developer) for the Mapillary tab and its coverage layer. A token that the person saves in the settings wins. Panoramax needs no key. The page contains the token: limit it to your site |
google_3d |
on with a toolbar, else False |
web | True: a Google 3D button and a floating window with Google's photorealistic 3D view; its camera and the map's move together, and a clicked road is drawn in it. Needs street_view_key (an error without it) (guide) |
google_3d_layers |
[] |
web | layers for the Google 3D window. Each is {id, kind, source, match, scope, max, on, arrows, style}; a wrong key or kind is an error. A layer draws the features of a GeoJSON source of the page (guide) |
Camera & 3D¶
| keyword | default | backends | what |
|---|---|---|---|
pitch / bearing |
the camera setting (0 / 0) |
web | starting tilt / rotation in degrees |
max_pitch |
the camera setting (70) |
web | the most the map can tilt, in degrees. 60 keeps the view where MapLibre itself uses one tile zoom. Above 60 the page forces one tile zoom on the whole screen (a road has one width everywhere), and that loads 2 to 3.6 times as many tiles |
view_3d |
False |
web | open tilted to camera.pitch_3d, with raised 3D bridge decks |
bridge_heights |
None |
web | {road id: metres} (a dict or a Series; the ids are the values of the edge id column, edge_id_col): the full height of the whole group of bridges that the road is in (the bridge roads that touch each other), and the engine makes the ramps for that height. The id of any road of the group names it; two heights for one group, a negative height, and an id that no road has are errors, and the id of a road that is not a 3D bridge gets a warning. Without it, a group is as high as its length gives (bridge_decks: base_m, max_m, grow_from_m, grow_to_m). Needs view_3d=True |
bridge_height_col |
None |
web | the name of a column of the roads with the full height in metres of the group of bridges that the road is in. A road with no value gives nothing; one value on one road of a group is enough, and the other roads of the group can have the same value or none. Two heights in one group (also with bridge_heights), a text or negative value, and a column that the roads do not have are errors. Roads that are not 3D bridges and have a value get one warning, with their number |
bridge_profile |
None (the empty input {}) |
web | An input profile for the groups of 3D bridges: a dictionary or the path of a JSON file. Every value is optional ({} is the least). The filler keeps what you give and fills the rest, and the maker makes the decks from the complete profile, with the curve smooth; bridge_heights and bridge_height_col do nothing then. Change a node's z_m, a chain's top_m or width_m, and the page changes. Interior points and the curve design are planned. See The bridge profile and its format |
Output & scale¶
| keyword | default | backends | what |
|---|---|---|---|
tiles |
True |
web | True: the roads are embedded PMTiles (MLT, or MVT with tile_format="mvt"). False: the roads are GeoJSON, which MapLibre cuts in the browser. A page with a palette in a view needs tiles=False (an error says so). The box under the table has the measures. |
tile_format |
"mlt" |
web | the format of the embedded tiles and of the tiles of export_style: "mlt" or "mvt" (for an app with MapLibre GL JS older than 5.12). No effect with tiles=False (Make tiles and PMTiles) |
live_data |
False |
web | writes the metadata roadstyle:live (the feature states rs_c and rs_w, the default ramp, the no-data colour; contract) and the page option live, which rs.setData reads |
keep_let |
False |
web | export_style and export_inline only: True keeps the let of the width table in the style (a smaller style). False writes each let as its value, because an app such as RustGIS cannot read let. A page and its tiles always keep the let |
compress |
True |
web | gzip the inlined data; False = plain JSON |
tunnel_control |
False |
web | on a map page with tunnels, shows a Tunnels box with the colour list (tunnels.toward), the strength slider (tunnels.strength), the casing palette and the dash ratio. A page with a bar hides it (design) |
tiles and tile_format
With tiles=False, MapLibre cuts the GeoJSON in the browser and keeps every vertex. On 22,000 roads (Nacka, 173,000 pieces) that draws 2.4 to 2.6 times the triangles at zoom 11 to 13, and panning is slower. MLT is the default format for every path: it is about 60 % of the bytes of MVT after gzip, and the picture is the same.
Returns a WebMap (.save()).
Column mapping¶
| keyword | default | backends | what |
|---|---|---|---|
highway_col |
"highway" |
all | the road-class column (widths, casing, draw order) |
tunnel_col / bridge_col |
"tunnel" / "bridge" |
all | tunnels draw under (faded, two-tone dashed casing), bridges on top |
layer_col |
"layer" |
web | OSM layer; negative sinks an edge when there is no tunnel/bridge column |
casing_start_col / casing_end_col / head_m |
None / None / 5.0 |
web | the casing numbers of the start head and the end head (the main number is casing_level_col). head_m is the length of each head in metres. The box under the table says how the casing is divided. |
head_start_m_col / head_end_m_col |
None |
web | an edge's own head lengths in metres (solve_levels' head_start_m / head_end_m); null = head_m. A road shorter than its two heads is cut in their ratio |
road_fill |
True |
web | False: draw the casing of each road but not its fill (the fill layers stay, invisible, for clicks); the items attached with Overlay(edge_col=...) are the fill |
edge_id_col |
"edge_id" |
web | the column with the id of each edge, the ids that an overlay's edge_col refers to; the docked panel's search always reads it, whatever road_popup lists |
casing_level_col / fill_level_col |
None |
web | two integer columns: the drawing position of the casing and of the fill of an edge (0 = ground). The position alone decides, a bridge too. Not given: render_edges calls rs.compute_levels(edges) (guide, design) |
cap_col |
None |
web | a column of true / false: true draws the edge with square ends (butt caps) instead of round ones, for a road drawn in pieces that meet without a ring; "square" = flat but as far past the end as a round end (the drawn length kept); null / false = round ends |
cap_start_col / cap_end_col |
None |
web | one end each, same values as cap_col (and "round"); null = cap_col's. An edge whose two ends differ is drawn from its casing heads and two fill halves (position mode) |
width_m_col |
None |
web | a column of widths in metres (a lane, a road with a width tag, a canal): from width_m_zoom on the line is drawn exactly that wide, its casing inside; null = the class width |
width_m_zoom |
16 |
web | the zoom from which width_m_col widths apply; below it, the class widths (so a narrow line doesn't vanish zoomed out) |
casing_m |
0.15 |
web | with width_m_col: the casing on each side, in metres, inside the width (two lines side by side show a 2 × casing_m divider) |
casing_min_px |
0 |
web | a casing in metres is never thinner than this many pixels each side of its fill (0 = exact metres, a thin casing goes under a pixel) |
directed_col |
None |
web | a column: true or null = the edge is a direction of travel of its own. False = undirected (for example a footway stored both ways). An edge and its reverse are two lanes only when neither is false; if not, they are one centred line. rs.is_directed(edges) makes the column |
driving_col |
None |
web | a column: true / null = cars may drive the edge, false = they may not (duckOSM's driving). An edge gets a one-way arrow only if it is one-way (oneway, else no twin) and driving. Arrows only: the drawing (two directions or one line) is directed_col's. None = every edge counts as driving |
levels and heads
With the level columns, the casing is divided into a start head, a main part and an end head. An edge at least 2 · head_m long whose three casing numbers differ is drawn as three casing pieces, each at its own number. The fill stays one line (design). At each position the casings come first, then the fills.
directed_col
rs.is_directed(edges) marks an edge open to cars or bikes (driving or cycling) that is not a path class (single_line_classes). So a one-way street whose reverse is a bus lane or a bike lane is two halves, and its arrow is on the car edge.
Overlays & boundary¶
| keyword | default | backends | what |
|---|---|---|---|
overlays |
None |
web | a list of Overlay: zones, points, lines |
items |
None |
web | the line items of a road (lanes, lane lines, marks): a GeoDataFrame or FeatureCollection. Each feature names its road in edge_id_col and has width_m; optional: order, offset_m, color, dash, pick, minzoom. A pick item is clicked as itself (rs:select detail.item); a click on the others goes to their road |
items_popup |
None |
web | the fields a clicked pick item shows (None: all of its fields) |
boundary |
None |
web | a dashed outline on top: shapely geometry, GeoDataFrame or GeoJSON. It is an input: the caller says where it comes from (a duckOSM main.boundary, a city limit, a drawn shape) |
boundary_dim |
False |
web | True: shade the outside of boundary (the opacity is in the template's boundary options) |
dashboard |
None |
web | a partial dashboard option, merged over the defaults of the template dashboard: {"toolbar": {"position": "left"}, "panel": {"sections": [...]}}. A wrong key or value is an error. Every key, default and meaning: Dashboard options. template="dashboard" only |
page_script |
None |
web | JavaScript text that the page runs, the last script of the body, before the page is ready: it sees rs. Put the code in rs.ready(() => ...), which runs it when the panel's sections are there (and at once if they are) (Live data) |
vehicles |
None |
web | a traffic microsimulation run that the page loads at start: {"wasm": url, "fcd": url, "net": url, "routes": url}, URLs from the page: roadstyle_wasm.js built with the feature vehicles, SUMO's FCD output as Parquet (--fcd-output.geo true), the run's net.xml, and (optional) a file with its <vType> elements. The vehicles are 3D boxes in their lanes (rs.vehicles, the design); their colours, sizes and numbers are the look's vehicles section |
page_style |
None |
web | CSS text of the page, the last style of the body |
boundary_limit |
False |
web | True: the camera stays near boundary (the center inside its bounds grown by limit_pad, and the lowest zoom zoom_out levels under the fit) |
Pages¶
Web-only page builders. Each takes every render_edges keyword and returns a WebMap; they only
change the defaults below.
| function | page | changed defaults | own keywords |
|---|---|---|---|
render_dashboard |
the map, an empty panel to which the page adds parts (dashboard={"panel": {"sections": [{"id": "q", "part": "query"}]}}, Dashboards) and the standard toolbox |
template="dashboard"; the map has the defaults of a map page; the panel is at the left, the toolbox at the right edge, no scale box |
layout="dock": the panel is docked at the left and there is no toolbox. The default "overlay" floats the panel over a full map (Dashboard layout) |
render_street_view |
map + Google Street View of the clicked road | name="Roads and Street View", road_popup=False, street_view=True |
see below |
render_street_view keyword |
default | what |
|---|---|---|
layout |
"beside" |
"beside" = Street View right of the map, "below" = under it |
panel_width |
42 |
Street View's share of the window, 20-80 % (of the height when below) |
resizable |
True |
a divider the viewer can drag; the choice is remembered in their browser |
street_view_key |
env GOOGLE_MAPS_KEY |
a Google Maps JavaScript API key: the panel becomes a real panorama, the map marker walks and turns with the viewer, and it shows Google's own street imagery only. Written into the page; restrict it to your site's addresses |
Dashboard options¶
dashboard= is a partial option of the template dashboard. The call merges it over the defaults of the template, field by field. Give only the keys that you change. A wrong key or value is an error, and so is template (use the keyword template=). Guides: Dashboard layout for the frame and the toolbox, Dashboards for the panel.
rs.render_dashboard(edges, dashboard={
"toolbar": {"position": "left"},
"panel": {"side": "right", "look": "card", "width_px": 360},
})
The options are in groups: the frame (layout, scale_box), panel, toolbar, legend, credits, windows, boundary and google_3d. The defaults below are those of layout="overlay". layout="dock" has no toolbar, and its windows default to clamp False and recenter_map True.
Frame
| key | default | meaning |
|---|---|---|
layout |
"overlay" |
"overlay": the map fills the window and the panel floats over it. "dock": the panel takes its own space at the left and there is no toolbox. The page keyword layout= sets it |
scale_box |
False |
True shows the scale and the zoom number at the start. The person can change it in the settings |
panel (None removes the panel: the page is the map and the toolbox)
| key | default | meaning |
|---|---|---|
side |
"left" |
"left" or "right" |
width_px |
400 |
the width of the panel. Fit the content to the panel and do not widen the panel for it |
look |
"card" (layout="overlay"), "frame" (layout="dock") |
"card": a floating card, see-through, over the map. "frame": full height, with a translucent frame and solid cards. |
sections |
[] |
the sections that the page adds to the empty panel, in order. A section is a mapping with the keys of the next table |
panel.help (none by default): {"title", "intro", "terms", "note"}, the "?" in the panel's title and the words of its help window (A help window).
A section (panel.sections; the errors are in Dashboards):
| key | default | meaning |
|---|---|---|
id |
required | the name of the section. It is not empty and not used twice |
part |
none | a part of roadstyle: "query", "road_card" or "chart". A section has one of html, part, tabs and kpis |
html |
none | the page's own HTML |
text |
none | the start text of the part query (none: an empty box) |
fields |
none | the columns that the part road_card shows (none: every column) |
chart |
none | the options of the part chart: the next table (Charts) |
label |
none | the title of the section: a section with a label is a card, and a section without one is a block of the page's HTML with no box |
after, before |
none | the id of an earlier section: this section goes after it, or before it. Give one of them |
fold |
False |
True: the card folds; its title is a button, and its row has a chevron. It needs a label |
note |
– | one line of state under the card's title (rs.sections.note changes it). It needs a label. A card that opens something (open, a function) is JavaScript only: A card that opens something |
background |
True |
False: the card has no colour behind it (the same padding and title row). It needs a label |
tabs |
none | in place of html: [{"id", "label", "html"}, ...], a tab row and one pane for each tab (Tabs) |
kpis |
none | in place of html: [{"title", "value", "sub", "color"}, ...], number tiles; value is a text or a number (Number tiles) |
help |
none | {"title", "intro", "terms": [[term, meaning], ...], "note"}: a "?" in the card's title row that opens the help window. It needs a label |
A chart card (chart of a section with part: "chart"; Charts):
| key | default | meaning |
|---|---|---|
kind |
required | "bar", "line", "histogram", "scatter" or "pie" |
x |
required | a column: the groups (bar, pie), the order (line), the numbers (histogram, scatter) |
y |
none | a number column, or a list of up to 3 (bar, line). None: the count of rows. Not for a histogram; necessary for a scatter |
agg |
"sum" |
how the rows of one value of x join: "sum", "mean", "min", "max" or "count" |
scale |
1 |
a factor for the values of y (0.001: metres to km). Not 0 |
data |
none | the page's own rows: a DataFrame, a GeoDataFrame (its geometry is not used), a list of dicts, or {"columns": [{"name", "type"}], "rows": [[...]]}. None: the map's roads. x and y are columns of data |
title |
none | the title of the chart (none: the card's label is the title) |
height |
220 |
the height of the chart in pixels, 80 or more |
follow |
False |
the map's roads only: True draws the chart again for the roads that the map shows now |
The space of the cards is three CSS variables on :root: --rs-card-gap (12px, between two cards), --rs-card-pad (14px, inside a card) and --rs-panel-bottom (28px, under the last card). See Cards: the panel standard.
There is no hide key and no phone option. The page turns to its phone form by itself when the window is 700 px wide or less (a phone, or a narrow desktop window), with the bar at the top. The page data holds these fixed values as phone.max_width_px (700) and phone.toolbar (top). dashboard= cannot change them.
toolbar (None: no toolbox)
| key | default | meaning |
|---|---|---|
position |
"right" |
"right", "left", "top" or "bottom" |
align |
"middle" |
the place of the bar along its edge: "start" (the left corner of a bar at the top or the bottom, the top corner of a bar at the left or the right), "middle" or "end". The Settings box has it as "Toolbar place" |
navigation |
"box" |
"box": one compass-needle button that opens a box with a zoom, a turn and a tilt slider. "buttons": the buttons zoom in, zoom out, compass and 2D/3D |
settings |
True |
shows the settings tool |
hold |
False |
True keeps the bar hidden until your page calls rs.tools.ready(), or for 6 s |
legend
| key | default | meaning |
|---|---|---|
rows |
[] |
rows that your page adds to the legend box, after the rows of the colour option. A row is {color, label, shape}. shape is "square" (default), "circle" or "line". A wrong shape is an error |
credits
| key | default | meaning |
|---|---|---|
credits |
[{"text": "© OpenStreetMap contributors", "href": "https://www.openstreetmap.org/copyright"}] |
the credits of your own data: [{"text": ..., "href": ...}]. They show before the credits of the base map. [] shows none of them. href is optional |
windows: the rules of the Street View and Google 3D windows
| key | default | meaning |
|---|---|---|
clamp |
True |
keeps a window inside the free part of the screen |
recenter_map |
False |
True moves the map when you drag a window |
restore_open |
True |
opens again the windows that were open at the last visit |
remember |
True |
keeps the size and the place of each window in the browser |
boundary: what the page does with the keyword boundary=
| key | default | meaning |
|---|---|---|
dim |
False |
shades the outside of the boundary (the keyword boundary_dim) |
limit |
False |
keeps the camera near the boundary (the keyword boundary_limit) |
dim_light, dim_dark |
0.16, 0.4 |
the opacity of the shade in the light and in the dark theme |
limit_pad |
2.0 |
the center of the map stays inside the bounds of the boundary, grown by this share of their size |
zoom_out |
3.0 |
the lowest zoom is this many levels under the zoom at which the whole boundary fits the window |
A page with no boundary= has neither the shade nor the limit.
google_3d: the Google 3D window (guide)
| key | default | meaning |
|---|---|---|
fov_deg |
None |
Google's vertical field of view. None: the range comes from the camera distance of the map |
follow |
True |
the window starts with Follow on |
min_alt_m |
80.0 |
under this camera height, in meters, the window shows a note |
min_zoom_drawn |
17.0 |
over this map zoom, the drawn map shows the note |
mesh_altitude_m |
1.5 |
the height in meters over Google's mesh at which a line or a pin lies. At 0.5 m the bumps of the mesh cut a line into pieces |
selection_style |
see the next table | the line, the outline and the arrows of the selected road |
layers |
[] |
layers from GeoJSON sources of the page. The keyword google_3d_layers sets them |
The keys of selection_style:
| key | default | meaning |
|---|---|---|
color, width |
#22d3ee, 8 |
the line |
outline, outline_width |
#0b1020, 2 |
the outline of the line |
arrow_color, arrow_width |
#ffffff, 5 |
the arrows |
arrow_every |
25 |
meters between two arrows |
fill |
rgba(34,211,238,0.35) |
the fill of a polygon |
A layer of google_3d.layers (an error: a missing id, kind or source, an id used twice, or the scope selection without match):
| key | default | meaning |
|---|---|---|
id, label |
required, none | the name of the layer, and its text in the Show menu |
kind |
required | "line", "ribbon", "polygon" or "points" |
source |
required | the id of a GeoJSON source of the page |
scope |
"selection" |
"selection": the features tied to the selected road. "view": the features in the visible area |
match |
none | for the scope selection: the property that ties a feature to the road |
max |
500 |
for the scope view: the most features drawn |
on |
True |
the layer starts shown |
arrows |
False |
for the kind line: direction arrows along the line |
style |
{} |
color, width, outline, outline_width, dash ([m on, m off]), fill, width_m, width_prop (the property that holds the ribbon width) and radius (for points). A key that does not fit the kind has no effect |
Overlay¶
rs.Overlay(data, ...): your own geometry, drawn with one flat style (web only). Defaults come from
the overlays setting. See Add your own layers.
| field | default | what |
|---|---|---|
data |
required | GeoDataFrame, GeoSeries or GeoJSON (any CRS) |
kind |
auto | "fill", "line", "circle" or "text"; auto from the geometry (never "text") |
placement |
"over" |
"under" or "over" the roads |
color |
"#6aa9ff" |
paint colour |
opacity |
fill 0.15, circle 0.85, line 0.9 |
|
outline |
color |
polygon outline colour; a circle's ring colour (default: the circle_stroke setting) |
radius |
6 |
circle radius, px |
width |
2 |
line / outline width, px; a circle's ring width (default 1) |
label |
"Layer N" |
name in the Layers control, and the layer argument of the JS API |
popup |
None = all fields |
fields on click; [] = not clickable |
popup_window |
True |
False: clickable and selected (rs:select fires) but no popup (and no read-out in panel mode) |
tooltip |
None |
fields on hover |
visible |
True |
shown on open |
edge_col |
None |
the property with the id of the feature's edge: the overlay is attached to edges, drawn at its edge's fill number (the guide: Overlays) |
order_col |
None |
with edge_col: the property with the feature's order (whole number, lower first; null = 0) |
select |
"road" |
with edge_col: a hover or click picks the feature's road ("road") or the feature itself ("item": its own highlight and popup, rs:select with item and the road); anything else is an error |
color_col |
None |
the property with a colour per feature (null: color) |
width_m |
None |
a line's width in metres, exact from min_zoom on (replaces width) |
dash |
None |
a line's dash pattern in line widths, [3, 3] |
min_zoom / max_zoom |
None |
the zooms in which the overlay is drawn |
style |
None |
the name of a style in the setting config.overlays.styles (roadstyle has none). An argument given on the overlay wins over the style |
width_m_col / offset_m_col / dash_col |
None |
with edge_col and line features: the property with each item's width in metres (else width_m), its line offset in metres (+ = right of the direction; null = 0) and its dash pattern in line widths ([3, 3] or "3,3"; null = dash) |
text_col / text_size / text_color / text_halo |
None |
kind="text": the property with the text, its size (px), colour and halo colour |
Basemap¶
rs.Basemap(key, label, url, attr, ...): one tile source. Register it with rs.register_basemap.
Built-ins: Settings & palettes.
| field | default | what |
|---|---|---|
key |
required | short id, e.g. "mytiles" |
label |
required | name in the switcher |
url |
required | {z}/{x}/{y} template; "" = no tiles (plain canvas, fully offline) |
attr |
required | attribution |
is_dark |
False |
a dark canvas |
satellite |
False |
apply the satellite colour filter |
bg, preview, subdomains |
"#444", three greys, "abc" |
switcher thumbnail, tile subdomains |
style_url, group, title, dark, swatch, building_3d |
None, "", "", None, "", "" |
the fields of the base-map box (data/basemaps.json): a vector style URL, the group and title of its row, the key of its dark twin, its swatch, the colour of the 3D buildings of a dark vector style |
maxzoom |
19 |
the provider's last zoom level with real tiles; zoomed in further, the map scales that level up instead of showing missing tiles. Built-ins: Esri grey maps 16, the rest 19; xyzservices providers bring their own max_zoom |
StyleConfig¶
The values the stylers read. Every field comes from the profile and palette. The field names below are the config keys; the last column of a row names the profile or palette key where it is stored. Change a value in a profile or palette, not in code.
| field | default | what |
|---|---|---|
fill_opacity / casing_opacity |
0.9 / 0.75 |
line opacities |
casing_extra |
2.0 |
reserved (palettes set casing widths) |
link_scale |
0.6 |
*_link width relative to the parent (theme roads.links.width) |
tunnel_opacity_scale |
0.45 |
tunnel fade |
tunnel_casing_dash |
[1, 1] |
profile tunnels.casing_dash: the tunnel casing's dash and gap, in line widths; a tunnel's casing is its dash layer alone |
tunnel_strength |
60 |
profile tunnels.strength (0-100): everything on a tunnel (fill, names, arrows, attached items) moves toward the tunnels.toward colour. The Tunnels box has the steps 0, 25, 50, 55, 60, 65, 70, 75, 100 (tunnels.steps) |
tunnel_toward / tunnel_towards |
Sand / eight |
palette tunnels.toward and tunnels.towards: the colour a tunnel moves toward. Use a name from towards (Slate, Dark, Light, Graphite, Navy, Stone, Sand, Teal) or any #rrggbb. A bad name or colour is an error that names the choices |
tunnel_palette / tunnel_palettes |
Graphite + silver / seven |
palette tunnels.palette and tunnels.palettes: the tunnel casing. One colour is slate dashes with empty gaps. The other names are [dash, gap] pairs (Slate + ice, Blue + cyan, Warm + sand, Graphite + silver, Indigo + lavender, Teal + mint). A bad name is an error |
tunnel_fill_dash / tunnel_fill_dash_color |
[] (none; e.g. [1.2, 1.2]) / rgba(255,255,255,0.55) |
light dashes along a tunnel's fill, over any road colour ([] = none); a dashed class (steps, a dashed path) keeps only its own dashes |
single_line_classes |
footway, path, steps, pedestrian, cycleway, track, bridleway, corridor, platform | a two-way pair of these classes is drawn as one line at full width, not as two lanes. Both edges keep their data, and a click shows both directions. []: every pair is lanes |
twin_end_caps |
true |
a two-way road ends like one road: one road-wide round cap under its two lanes at each end, where both lanes have the same colour (false = each lane's own round end) |
twin_casing |
"one" |
a two-way road that is two directed edges. "one": one casing around both directions, at the full width of the road. "each": each direction has its own casing, half the width, shifted. The box under the table has the details of "one". |
bridge_casing_m / bridge_casing_px |
0.25 / 1.0 |
with metre widths (width_m_col): the casing of a bridge deck is at least bridge_casing_m metres wide on each side, and never thinner than bridge_casing_px pixels on each side. The bridge look then shows on lines with no casing |
bridge_casing_extra / bridge_casing_color |
1.5 / "#64748b" (slate) |
profile bridges.casing_extra (px wider) / palette bridges.casing_color |
bridge_shadow / bridge_shadow_color / bridge_shadow_blur / bridge_shadow_offset / bridge_shadow_trim_m |
true / rgba(0,0,0,0.25) / 4 / [2, 2] / 3 |
profile bridges.shadow.show, blur, offset, trim_m; palette bridges.shadow.color. A soft shadow under a bridge. Blur is in px; offset is in px right and down; no shadow over the last trim_m metres where the bridge comes down |
minor_no_casing |
cycleway, footway, living_street, path, pedestrian, service, track | classes drawn without casing |
casing.drop_below_px |
1.0 (0 = always a casing) |
a casing piece is not drawn at a zoom where the whole casing line is narrower than this many px (a bridge keeps it). The tiles leave out these pieces. Nothing is dropped from a road in metres when casing_min_px is at least this value |
minzoom |
motorway 4 … residential 13 … footway 15 | class → hidden below this zoom (unless minzoom=False); the tiles leave out a hidden class |
basemap |
"ofm_positron" |
the default base map |
labels |
color #5b5b5b, no halo |
street-name paint; size: [[zoom, px], ...], the names' size per zoom for every class (roads in metres) instead of following each class's width |
arrows |
color #5b5b5b, opacity 0.7 |
one-way chevron paint |
camera |
pitch 0, bearing 0, pitch_3d 55, max_pitch 70 |
starting camera and 3D tilt |
bridge_decks |
base_m 5, max_m 22, grow_from_m 60, grow_to_m 600 (a group of bridges is base_m high up to grow_from_m of length and max_m from grow_to_m), thickness_m 1, ramp_m 40, step_m 2.5, match_zoom 18, opacity 0.7, width_scale 0.6, flat_below 15, casing_px 2 |
3D bridge decks |
overlays |
color #6aa9ff, radius 6, width 2, per-kind opacities, circle_stroke #ffffff |
Overlay defaults |
annotations |
slot_m 100 |
label / arrow spacing along a road, metres |
tiles |
minzoom 6, maxzoom 16, extent 4096, buffer_px 80 |
the tiles=True tileset. The map scales the last zoom's tiles up. The engine gives each zoom the buffer of its widest stroke; buffer_px is the buffer of a zoom where a width cannot be bounded |
api_key / api_keys |
None / {} |
default key / per-provider keys |
twin_casing-one
With "one", the casing is drawn once from the casing pieces of the first edge (numbers, heads, caps). The two edges must agree when one is reversed; if not, a warning names the pair. Each direction keeps its own fill. The end caps are the casing's own. A dead end of a pair is square for the casing and both fills, unless a cap column gives a cap. The bridge shadow and the tunnel dashes follow the casing.
See also: JavaScript API · Settings & palettes · Command line