roadstyle

io.github.Khoshkhahv0.9.1Updated Sep 29, 2026

Styled, interactive road maps of any place (OpenStreetMap) or road file, with PNG previews.

VerifiedSTDIODesktop onlyLocation & LifestyleFiles & Storage

Installation

In SourceWeft

  1. Open roadstyle in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

[roadstyle logo]

roadstyle

Beautiful, interactive road maps from Python.
One offline HTML file with real road cartography, Google Street View and a JavaScript API.

[PyPI] [Python versions] [Tests] [Docs] [License: MIT]

Install · Quickstart · Gallery · AI agents · Documentation

[A roadstyle map of Södermalm, Stockholm: Hornsgatan selected on the map, and the floating Street View window showing it]

Why roadstyle

  • Real road cartography. Casing and fill, widths that change with zoom, street names, one-way arrows, tunnels drawn under and bridges over, and optional 3D bridge decks.
  • One offline file. Map, data and styling in a single HTML page: open it without a server, email it, or put it on any website.
  • Street View built in. Click any road to see it in Google Street View, facing the way it runs.
  • Any road data. A GeoDataFrame, a file, DuckDB, Arrow, osmnx or duckOSM.
  • Colour by your data. Speed, traffic or any column, with a legend and a menu of colourings.
  • Scriptable. A window.rs* JavaScript API and events for your own dashboard.
  • Ready for AI agents. An MCP server and an agent skill.

Install

bash
pip install roadstyle              # corepip install "roadstyle[all]"       # + studio, numeric ramps, vector tiles, lonboard, DuckDB, …

Python ≥ 3.10. Individual extras and the dev setup: Install.

Quickstart

From OpenStreetMap, no data needed. Any place, with osmnx (pip install osmnx):

python
import osmnx as oximport roadstyle as rs
G = ox.graph_from_place("Tartu, Estonia", network_type="drive", simplify=False)G = ox.simplify_graph(G, edge_attrs_differ=["bridge", "tunnel"])   # keep tunnels and bridges apartrs.render_edges(ox.graph_to_gdfs(G, nodes=False)).save("tartu.html")

From your own data. Any file or GeoDataFrame with line geometry and a highway column:

python
import geopandas as gpdimport roadstyle as rs
edges = gpd.read_file("edges.gpkg")        # LineStrings + a `highway` column, any CRSrs.render_edges(edges).save("map.html")    # open map.html: no server (Street View needs one)

More looks:

python
rs.render_edges(edges, basemap="dark_matter", view_3d=True)            # dark, 3D bridge decksrs.render_edges(edges, palette="carto", basemap="positron")            # the classic OSM lookrs.render_edges(edges, color_by="aadt", cmap="viridis")                # colour by your datars.render_edges(edges, palette="mono", color_options={                 # several colourings,    "Traffic": {"color_by": "aadt", "cmap": "viridis"},                #   switched in the browser    "Speed":   {"color_by": "maxspeed_kmh", "cmap": "magma"}})rs.render_edges(edges, tiles=True)                                     # 100k+ edgesrs.render_dashboard(edges).save("dashboard.html")                      # map + query sidebarrs.render_street_view(edges).save("street_view.html")                  # map and Street View side by side

No Python? roadstyle edges.gpkg -o map.html --basemap dark_matter, or click through it in the workbench: pip install "roadstyle[studio]" && roadstyle studio.

Gallery

[The defaults]
The defaults
rs.render_edges(edges)
[Dark]
Dark
basemap="dark_matter"
[3D bridges]
3D bridges
view_3d=True
[Colour by your data]
Colour by your data
color_by="maxspeed_kmh", cmap="plasma"
[Satellite]
Satellite
basemap="satellite"
[Dashboard]
Dashboard
rs.render_dashboard(edges)

Every look with its code: the gallery.

What goes in

Only geometry and highway are required. Other columns switch features on:

ColumnPowers
geometry (LineString, any CRS)the edges. Each edge is directed: a two-way road is two edges with reversed geometry
highway (OSM class)colour, width, casing, draw order
namestreet labels, popup title
onewaydirection arrows
bridge / tunnel / layergrade separation: tunnels below, bridges on decks above
edge_idpopups; 64-bit ids stay exact
anything elseshown in the popup, queryable from JavaScript

duckOSM (duckosm export-gis) exports exactly this, and osmnx edges work as they are: rs.render_edges(ox.graph_to_gdfs(G, nodes=False)).

Drive it from JavaScript

The saved page exposes window.rs* functions and rs:* events:

js
const ids = rsQuery(p => p.maxspeed_kmh > 30); // feature ids whose properties matchrsColor(ids, "#ff00aa");  rsFocus(ids);       // paint them, fit the cameradocument.addEventListener("rs:select", e => console.log(e.detail.properties));

Every function and event: JavaScript API.

For AI agents

MCP server. Lets any MCP-capable AI app (Claude Code, Claude Desktop, Cursor, …) draw road maps without writing code: render_place("Tartu, Estonia"), render_file("roads.gpkg") and snapshot. Each saves an HTML map and returns its path plus a PNG preview the agent can look at.

bash
claude mcp add roadstyle -- uvx roadstyle-mcp
Claude Desktop, and where the maps go

In claude_desktop_config.json:

json
{"mcpServers": {"roadstyle": {"command": "uvx", "args": ["roadstyle-mcp"]}}}

Maps are saved in ~/roadstyle-maps/. The PNG preview needs Chromium, once: uvx --from roadstyle-mcp playwright install chromium.

Claude Code plugin. The MCP server and the skill below in one install:

text
/plugin marketplace add Khoshkhah/roadstyle/plugin install roadstyle@roadstyle

For agents that write code:

  • skills/roadstyle/SKILL.md: a skill for agents that use roadstyle (the one call, the data contract, the JS API, the traps). Install it for Claude Code:
    bash
    mkdir -p ~/.claude/skills/roadstyle && curl -fsSL -o ~/.claude/skills/roadstyle/SKILL.md \  https://raw.githubusercontent.com/Khoshkhah/roadstyle/main/skills/roadstyle/SKILL.md
  • AGENTS.md: for agents working on this repo.
  • llms.txt: the docs site as a link list for LLMs.

API keys

Both keys are optional. roadstyle works without them, just with less.

  • CARTO, for the default base map. Without a key its tiles are stamped API KEY REQUIRED; set CARTO_API_KEY, or use a keyless base map (esri_street, esri_dark_gray, osm, blank).
  • Google Maps, for Street View. Street View works with no key. A key adds a Linked mode: a real panorama, with the map marker walking and turning with you.
Setting up the CARTO key

The default base map (voyager) and positron and dark_matter come from CARTO. Without a key, their tiles are stamped API KEY REQUIRED. Get a free key at carto.com/basemaps/apikey, then use any one of these:

bash
export CARTO_API_KEY="…"                                          # environment variable
json
{ "config": { "api_keys": { "carto": "…" } } }

Save that JSON as ~/.config/roadstyle/roadstyle.json, or as roadstyle.json in the folder you run from. In Python you can pass rs.render_edges(edges, api_key="…") instead. With no key at all, use a keyless base map: esri_street, esri_dark_gray, osm or blank.

Setting up the Google Maps key

Street View works with no key: the keyless Google embed. With a Google Maps JavaScript API key, the Street View panel and window get a Linked / Classic switch. Linked is a real panorama: the map marker walks and turns with you, and only Google's own street photos are shown. Classic is the keyless embed. To get a key:

  1. In the Google Cloud console, create a project and enable Maps JavaScript API (Google asks for a billing account on the project).
  2. Under APIs & Services > Credentials, create an API key.
  3. Restrict it: Application restrictions = Websites, listing your site's addresses (e.g. https://example.com/*); API restrictions = Maps JavaScript API only.

Then pass it in:

python
rs.render_edges(edges, street_view_key="AIza…")         # the floating Street View windowrs.render_street_view(edges, street_view_key="AIza…")   # the side-by-side page

The key is written into the page, as every browser key is, so the site restriction in step 3 is what protects it. It also means Linked works only on the addresses you listed: to try it on localhost, add http://localhost:*/* to the list. Keep the key out of git, for example in an environment variable.

More: settings & base maps · Google Street View.

Documentation

khoshkhah.github.io/roadstyle, with live maps on every page.

WhereWhat you find
Get startedinstall, a first map, what your data needs
Guidesstyle the roads · colour by your data · your own layers · Google Street View · big networks · dashboards & JavaScript · on a website
Gallerya picture and one line of code per look
Referenceevery parameter · JavaScript API · settings & base maps · command line
Changelogwhat changed in each release

License

MIT. Base-map tiles come from third-party services (CARTO, OSM, Esri) with their own attribution and terms.

Source: README.md at commit 78925a6

Tools

0
Tool metadata has not been indexed yet.

Version history

1
  1. v0.9.1LatestSep 29, 2026