Settings & palettes¶
Every styling default is a setting you can override without touching code: palettes, opacities, camera, base map, API keys.
Settings levels¶
Each level overrides the ones above it. State only what changes; everything else keeps the bundled default.
| level | where | scope |
|---|---|---|
| 1. bundled | roadstyle/data/defaults.json in the package |
the defaults |
| 2. user | $XDG_CONFIG_HOME/roadstyle/roadstyle.json (else ~/.config/roadstyle/roadstyle.json) |
read at import |
| 3. project | ./roadstyle.json in the working directory |
read at import |
| 4. explicit file | the path in $ROADSTYLE_CONFIG |
read at import |
| 5. code | rs.use_settings("my.json") or a dict (several allowed; none = drop them) |
rest of the process |
| 6. one call | rs.render_edges(edges, settings={...}) |
this render only |
Files at levels 2-4 are read when roadstyle is imported: create them before import roadstyle.
A file that is not valid JSON is skipped.
The settings file¶
Every level uses the same layout as defaults.json:
| section | holds | merges |
|---|---|---|
palettes |
{palette: {class: RoadStyle fields}}; a new name adds a palette |
per road class |
config |
the StyleConfig fields: opacities, labels, arrows, camera, basemap, bridge decks, tiles, API keys |
per key |
selection |
selection colours: core, glow, glow_opacity, casing |
per key |
roads |
the web width and draw-order model: width, width_zoom_rate, casing_ratio, group, links, zoom_stops, z_order |
per table entry |
{
"palettes": {
"highsat": { "service": { "fill": "#E0E0E0" } }, // retint one class
"mytheme": { "motorway": { "fill": "#f00", "width": 6, "casing_width": 8 } }
},
"config": { "fill_opacity": 0.95, "basemap": "positron", "api_keys": { "carto": "…" } },
"selection": { "core": "#FF0000" },
"roads": { "z_order": { "service": 5 } }
}
A palette entry may also be wrapped as {"roads": {...}}, the form save_palette writes.
Palettes¶
Pick one with palette=. Widths are px at city zoom; the web backend scales them with zoom. All
three palettes: opacity 1.0.
Bright fills, light-grey casing on major roads, no casing on minor ones.
| highway | fill | casing | width / casing width | dash |
|---|---|---|---|---|
| motorway | #00E5FF |
#bcbcbc |
6.0 / 8.0 | |
| trunk | #FF007F |
#bcbcbc |
5.5 / 7.5 | |
| primary | #FF9100 |
#bcbcbc |
4.5 / 6.5 | |
| secondary | #FFEA00 |
#bcbcbc |
3.5 / 5.5 | |
| tertiary | #00E676 |
#bcbcbc |
2.5 / 4.5 | |
| unclassified, residential | #FFFFFF |
#bcbcbc |
2.0 / 4.0 | |
| living_street | #DDDDDD |
none | 2.0 | |
| pedestrian | #DDDDDD |
none | 1.5 | |
| service | #F0F0F0 |
none | 1.0 | |
| track | #9E7B54 |
none | 1.5 | |
| cycleway | #2980B9 |
none | 1.5 | 6, 4 |
| footway, path | #D98880 |
none | 1.5 | 4, 4 |
The OpenStreetMap Carto look: muted fills, a darker casing per class.
| highway | fill | casing | width / casing width | dash |
|---|---|---|---|---|
| motorway | #e892a2 |
#dc2a48 |
6.0 / 8.0 | |
| trunk | #f9b29c |
#c84e2f |
5.5 / 7.5 | |
| primary | #fcd6a4 |
#a06b00 |
4.5 / 6.5 | |
| secondary | #f7fabf |
#707d00 |
3.5 / 5.5 | |
| tertiary | #ffffff |
#bcbcbc |
2.5 / 4.0 | |
| unclassified, residential | #ffffff |
#bcbcbc |
2.0 / 3.5 | |
| living_street | #ededed |
#cccccc |
1.8 / 3.0 | |
| service | #ffffff |
#d4d4d4 |
1.2 / 2.2 | |
| track | #9e7b54 |
same | 1.5 | 4, 4 |
| cycleway | #5c7cb6 |
same | 1.2 | 3, 3 |
| footway | #C59D9D |
same | 1.2 | 4, 4 |
| path | #C59D9D |
same | 1.2 | 2, 5 |
Greys only: a quiet base for data colours (palette="mono" + color_options).
| highway | fill | casing | width / casing width | dash |
|---|---|---|---|---|
| motorway | #707070 |
#3c3c3c |
6.0 / 8.0 | |
| trunk | #7a7a7a |
#444444 |
5.5 / 7.5 | |
| primary | #8a8a8a |
#4f4f4f |
4.5 / 6.5 | |
| secondary | #9c9c9c |
#5c5c5c |
3.5 / 5.5 | |
| tertiary | #b0b0b0 |
#6e6e6e |
2.5 / 4.0 | |
| unclassified, residential | #c4c4c4 |
#828282 |
2.0 / 3.5 | |
| living_street | #d4d4d4 |
#9a9a9a |
1.8 / 3.0 | |
| service | #e4e4e4 |
#bcbcbc |
1.2 / 2.2 | |
| track | #9a9a9a |
same | 1.5 | 4, 4 |
| cycleway | #888888 |
same | 1.2 | 3, 3 |
| footway | #ABABAB |
same | 1.2 | 4, 4 |
| path | #ABABAB |
same | 1.2 | 2, 5 |
In every palette:
*_linkroads take the parent's colour, 0.7 × the width (link_scale).- Tunnels fade to 0.45 × opacity and turn dashed. Bridges get a black casing 1.5 px wider.
- An unknown class draws as
unclassified.
Custom palettes¶
| call | does |
|---|---|
rs.register_palette("mine", {"motorway": rs.RoadStyle("#f00", 6, 8), ...}) |
add or replace a palette; then palette="mine" |
rs.PALETTES["highsat"]["busway"] = rs.RoadStyle("#FF00AA", 2.0, 4.0) |
add one class to a palette |
rs.save_palette("highsat", "mine.json", name="mine") |
write {"name", "roads": {class: fields}} to edit by hand |
rs.load_palette("mine.json") |
read it back and register it under its name (register=False to skip) |
rs.palette_to_dict(p) / rs.palette_from_dict(d) |
the same as plain dicts |
A RoadStyle needs fill, width, casing_width; casing (default #bcbcbc, None = none),
dash ([on, off] px) and opacity (1.0) are optional. For a non-OSM class column, register a
palette keyed by your classes and pass highway_col=.
Base maps & API keys¶
basemap= picks the base map; the default is voyager (config.basemap). All built-ins are in
rs.BASEMAPS.
| key | tiles | key needed |
|---|---|---|
voyager, voyager_nolabels, positron, dark_matter |
CARTO | yes (see below) |
osm |
OpenStreetMap | no |
esri_gray, esri_street, esri_dark_gray |
Esri light grey / streets / dark grey | no |
satellite |
Esri World Imagery | no |
blank, blank_dark |
none: a plain canvas, no network requests, fully offline | no |
Other sources:
- A tile URL:
basemap="https://tiles.example.com/{z}/{x}/{y}.png". It may contain an{api_key}or{accessToken}placeholder. - xyzservices: any provider object, e.g.
basemap=xyz.CartoDB.Positron(pip install "roadstyle[basemaps]"). - Your own, by name: register it once, then use
basemap="mytiles"and list it inbasemaps=.
rs.register_basemap(rs.Basemap("mytiles", "My tiles",
"https://tiles.example.com/{z}/{x}/{y}.png", "© My tiles",
maxzoom=18)) # its last zoom level with tiles (default 19)
CARTO watermark
Without a key, CARTO tiles (voyager, voyager_nolabels, positron, dark_matter) load but
are stamped API KEY REQUIRED. roadstyle warns when it renders one. Get a free key at
carto.com/basemaps/apikey, or use a keyless map:
esri_street, esri_dark_gray, osm, blank.
A keyed provider (CARTO, Mapbox, Stadia, MapTiler, …) uses the first key it finds:
| order | source | example |
|---|---|---|
| 1 | the call | rs.render_edges(edges, api_key="pk.…") |
| 2 | the session, this provider, then any provider | rs.set_api_key("pk.…", provider="mapbox"), rs.set_api_key("…") |
| 3 | settings, this provider, then any provider | {"config": {"api_keys": {"carto": "…"}, "api_key": "…"}} |
| 4 | environment, this provider | CARTO_API_KEY, MAPBOX_ACCESS_TOKEN (suffixes _API_KEY, _ACCESS_TOKEN, _TOKEN, _KEY) |
| 5 | environment, any provider | ROADSTYLE_API_KEY |
Settings keep keys out of your code: put them in ~/.config/roadstyle/roadstyle.json.
See also: Style the roads · Every parameter · Command line