# mapstyle > A whole OpenStreetMap map in one offline HTML page - roads for every travel mode over a full base map, from a duckOSM database mapstyle draws a whole OpenStreetMap map as one offline HTML page: the roads for driving, walking and cycling over a full base map, from a duckOSM database, with an optional route planner or dashboard and a JavaScript API. An agent skill with the essentials: https://github.com/Khoshkhah/mapstyle/blob/main/skills/mapstyle/SKILL.md # Get started # mapstyle A whole OpenStreetMap map in one offline HTML page: the roads for driving, walking and cycling over a full base map, from one [duckOSM](https://github.com/Khoshkhah/duckOSM) database. [Open the live map](https://khoshkhah.github.io/mapstyle/maps/all.html) [Get started](https://khoshkhah.github.io/mapstyle/get-started/index.md) ``` pip install mapstyle "duckosm @ git+https://github.com/Khoshkhah/duckOSM" curl -LO https://download.geofabrik.de/europe/monaco-latest.osm.pbf duckosm build --pbf monaco-latest.osm.pbf -o monaco.duckdb \ -m driving -m walking -m cycling mapstyle monaco.duckdb # -> monaco_all.html: one file, opens offline ``` ## What you get - **Every travel mode** ______________________________________________________________________ One map for driving, walking and cycling, or one network brought to the front: the roads for cars fade, the paths stand out. [Travel modes & path styles](https://khoshkhah.github.io/mapstyle/guides/modes/index.md) - **A full base map** ______________________________________________________________________ The sea, land use, water, buildings, railways, parking, transit and road furniture, all from the same database. No tile server, no API key. [The base map](https://khoshkhah.github.io/mapstyle/guides/base-map/index.md) - **Roads drawn right** ______________________________________________________________________ Bridges over, tunnels under only where they really pass under a road, raised walkways, footways and crossings never over a street (the zebra marking is), two-way roads as two lanes. [How roads are drawn](https://khoshkhah.github.io/mapstyle/guides/roads/index.md) - **Route planner (demo)** ______________________________________________________________________ A demo of a page built on mapstyle: drag a start and an end, see duckOSM's route. [Route planner](https://khoshkhah.github.io/mapstyle/guides/planner/index.md) - **Dashboard** ______________________________________________________________________ Filter by mode, road class and layer, colour by mode, and read every road and feature you click in a side panel. [Dashboard](https://khoshkhah.github.io/mapstyle/guides/dashboard/index.md) - **A JavaScript API** ______________________________________________________________________ Every page is a [roadstyle](https://khoshkhah.github.io/roadstyle/) page: filter, colour and query roads and layers from your own code, with 3D and vector tiles built in. [JavaScript API](https://khoshkhah.github.io/mapstyle/reference/javascript/index.md) ## How it fits together | Project | Its part | | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | [**duckOSM**](https://github.com/Khoshkhah/duckOSM) | turns an OpenStreetMap extract into one DuckDB file: the driving, walking and cycling networks, plus the base-map layers (`features.*`, the sea included) | | **mapstyle** | reads that file (with `duckdb`, nothing else) and styles all of it as one map | | [**roadstyle**](https://khoshkhah.github.io/roadstyle/) | draws the page: [MapLibre GL](https://maplibre.org/), the road styling, and the JavaScript API | The result is a single HTML file you can open from disk, email, or put on any web server. # Get started From an OpenStreetMap extract to an interactive map in three commands. ## 1. Install ``` pip install mapstyle "duckosm @ git+https://github.com/Khoshkhah/duckOSM" ``` mapstyle needs Python 3.10+. It installs [roadstyle](https://pypi.org/project/roadstyle/) from PyPI; add `"mapstyle[tiles]"` for [vector tiles](#big-areas). duckOSM isn't on PyPI yet: it installs from GitHub. ## 2. Build a database with duckOSM mapstyle's only input is a [duckOSM](https://github.com/Khoshkhah/duckOSM) database: the road networks and the base-map layers of an area, in one DuckDB file. ``` curl -LO https://download.geofabrik.de/europe/monaco-latest.osm.pbf duckosm build --pbf monaco-latest.osm.pbf -o monaco.duckdb \ -m driving -m walking -m cycling ``` Any extract works: [Geofabrik](https://download.geofabrik.de/) has every country and region, and duckOSM can cut a city out of a bigger file by its boundary (see its documentation). The base-map layers are built by default; the sea comes from Overture Maps' ocean polygons and needs the network while building. ## 3. Draw the map ``` mapstyle monaco.duckdb # -> monaco_all.html: the whole map mapstyle monaco.duckdb --mode walking # the walking network in front mapstyle monaco.duckdb --planner # + a route planner mapstyle monaco.duckdb --dashboard # a dashboard with filters ``` ``` import mapstyle as ms ms.render_map("monaco.duckdb").save("monaco.html") ms.render_map("monaco.duckdb", mode="cycling", paths="cyclosm").save("cycling.html") ``` In Jupyter, `ms.render_map(...)` on the last line of a cell shows the map in the notebook. Open the HTML file in any browser. It works offline: the data, the styles and the code are all in the file (the optional raster base maps in the switcher are the only thing loaded from the web). ## What's on the page - **ROADS** (top left): show or hide each road class, bridges and tunnels. - **LAYERS** (under it): show or hide each base-map layer. Both boxes start folded: click a title to open it. - Hover a road for its `edge_id`, OSM id, class and name; click a road or a feature for its details. The `edge_id` is duckOSM's, ready to look up in the database. - Top right: zoom, compass, **3D**, Street View, and the base-map switcher. ## Big areas A city like Monaco or Tartu fits in one page (3-12 MB). For a region, draw the roads as vector tiles inside the page: ``` pip install "mapstyle[tiles]" mapstyle stockholm.duckdb --tiles ``` ## Next - [Travel modes & path styles](https://khoshkhah.github.io/mapstyle/guides/modes/index.md): which network stands out, and how paths look. - [The base map](https://khoshkhah.github.io/mapstyle/guides/base-map/index.md): the layers, and how to change them. - [Gallery](https://khoshkhah.github.io/mapstyle/gallery/index.md): live maps to try. # Guides # Travel modes & path styles A mode picks which network stands out; a path style picks how footways and cycleways look. The two are independent. ## Travel modes Every page has every road. The mode decides what comes to the front: | Mode | What stands out | Live | | --------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------- | | `all` (default) | nothing: every network at its own width, as on a general map | [open](https://khoshkhah.github.io/mapstyle/maps/all.html) | | `driving` | the roads for cars | [open](https://khoshkhah.github.io/mapstyle/maps/driving.html) | | `walking` | footways, paths, steps, pedestrian streets; the roads for cars thinner and faded | [open](https://khoshkhah.github.io/mapstyle/maps/walking.html) | | `cycling` | cycleways; the roads for cars faded | [open](https://khoshkhah.github.io/mapstyle/maps/cycling.html) | all driving walking cycling ``` mapstyle monaco.duckdb --mode walking ``` ``` ms.render_map("monaco.duckdb", mode="walking") ``` In the `walking` and `cycling` modes every road is one centred line (no lanes), so the paths beside it stay readable. On any page, `rsSetModes(["walking"])` shows only the roads a mode can use ([JavaScript API](https://khoshkhah.github.io/mapstyle/reference/javascript/index.md)). ## Path styles How walking and cycling paths look, on top of the mode: | Style | Looks like | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------- | | `google` (default) | Google / Apple Maps: calm, thin, light solid lines | | `osm` | openstreetmap.org: thin dotted and dashed paths ([live](https://khoshkhah.github.io/mapstyle/maps/paths_osm.html)) | | `komoot` | outdoor apps: bold solid colours with a white halo, by type ([live](https://khoshkhah.github.io/mapstyle/maps/paths_komoot.html)) | | `cyclosm` | the CyclOSM map: solid blue cycleways, thin dark dashed footways | google osm komoot cyclosm ``` mapstyle monaco.duckdb --mode walking --paths komoot ``` Both are data: `styles/modes.yaml` and `styles/paths.yaml` ([Styles](https://khoshkhah.github.io/mapstyle/reference/styles/index.md)). # Themes A theme gives the whole map its colours: the roads, the base map and the background. It combines with any travel mode and path style. | Theme | Feel | For | | --------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------- | | `osm` (default) | detailed and colourful, as openstreetmap.org | exploring an area, checking the data | | `google` | clean and friendly: light land, white streets, yellow main roads, light blue water, soft green parks | maps for everyone | | `grey` | quiet greys, a hint of blue water and green parks | your own data on top: flows, routes, sensors | osm google grey ``` mapstyle monaco.duckdb --theme google mapstyle monaco.duckdb --theme grey --dashboard ``` ``` ms.render_map("monaco.duckdb", theme="google") ms.render_map("monaco.duckdb", mode="walking", theme="grey") ``` Live: [google](https://khoshkhah.github.io/mapstyle/maps/theme_google.html) · [grey](https://khoshkhah.github.io/mapstyle/maps/theme_grey.html). ## Your data on top A theme never changes your own colours: `rsColor`, colour options, the dashboard's colouring by mode, the route planner's route. On `grey` they stand out most: osm google grey ## Make your own A theme is one short YAML file in `src/mapstyle/styles/themes/`. It never has to list every colour: a **transform** recolours everything of the `osm` look, then you set the colours that matter. ``` # styles/themes/mine.yaml background: "#f5f5f3" # the land transform: # every osm colour not set below: saturation: 0.3 # keep 30 % of its colour lighten: 0.25 # then 25 % of the way to white roads: colors: primary: {fill: "#fde9a6", casing: "#ead08a"} # same keys as styles/osm_carto.yaml features: areas: water: {fill: "#aadaff"} landcover_pattern: {} # {} empties a section: here, no textures paths: footway: {fill: "#c9c9c9"} # path colours over any path style roadstyle: bridge_casing_color: "#c4c4c4" # roadstyle settings ``` Then `--theme mine`. See [Styles](https://khoshkhah.github.io/mapstyle/reference/styles/index.md) for every key. # The base map Everything that isn't a road comes from the same duckOSM database (its `features.*` layers), styled like openstreetmap.org. No tile server, no API key. The coast at zoom 14: sea, port, parks, built-up areas Monte-Carlo at zoom 17.6: buildings, gardens, parking, bus stops, crossings ## The layers In drawing order, bottom first. Each has a row in the **LAYERS** box, so it can be hidden. | Layer | From duckOSM | Shows | From zoom | | ----------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | `ocean` | `features.ocean` | the sea | | | `landcover` | `features.land` (+ school, hospital and sports grounds from `sites`) | parks, grass, forest, residential and industrial land, cemeteries, beaches…; forests, orchards, cemeteries, wetland and scrub get openstreetmap.org's textures | | | `water` | `features.water_polygons` | lakes, rivers, basins, docks | | | `waterways` | `features.water_lines` | rivers, streams, canals, ditches | | | `buildings` | `features.buildings` | building footprints | 15 | | `railways` | `features.streets` | rail, tram, light rail, subway, funicular, monorail | | | `parking` | `features.sites` | car parks | 15 | | `parking_p` | `features.sites` | a "P" on each car park | 16 | | `bus_station` | `features.sites` | bus station footprints | 15 | | `platform` | `features.sites` | transit platforms | | | `traffic_signals` | `features.traffic` | traffic lights | 16 | | `crossings` | `features.traffic` | pedestrian crossings, turned to lie across their road | 16 | | `bus_stations` | `features.public_transport` | bus stops | 16 | | `train_stations` | `features.public_transport` | railway stations and halts | 12 | | `bicycle` | `features.pois` | bicycle rental | 16 | The roads are drawn between the area layers and the points: the points (icons) are always on top. ## The sea OpenStreetMap has no sea polygons, only coastlines. duckOSM fills `features.ocean` from Overture Maps' ocean polygons (built from OpenStreetMap's coastline) while it builds the database. A database built offline, or with `options.sea: false`, has no sea: the coast's water is then land-coloured. ## Choose the layers ``` ms.render_map(db, layers=["buildings", "crossings"]) # just these ms.render_map(db, layers=False) # roads only ``` ``` mapstyle monaco.duckdb --no-layers ``` A database built without the base map (`duckosm build --no-features`) gives the roads only, with a logged hint. ## Clicks, tooltips and kinds Each layer can be clickable (a popup with its name and kind), show a hover tooltip, or neither: ``` ms.render_map(db, interaction={"crossings": {"tooltip": True}, "landcover": {"clickable": True}}) ``` From JavaScript, `rsSetInteraction`, `rsSetKinds` (only some kinds of a layer, e.g. just parks) and roadstyle's `rsSetOverlay` change them on the page ([JavaScript API](https://khoshkhah.github.io/mapstyle/reference/javascript/index.md)). ## Change the look The base map is data: `styles/layers.yaml` says which layers, in which order, with which filter; `styles/osm_carto.yaml` says how each looks (colours by kind, outlines, textures, icons, zoom ranges). See [Styles](https://khoshkhah.github.io/mapstyle/reference/styles/index.md). The raster maps of roadstyle (CARTO Voyager and Positron, OpenStreetMap, satellite) stay in the base-map switcher (top right) for comparison; they are loaded from the web. # How roads are drawn A road network is not a set of independent lines: roads join, cross over and under each other, and run in two directions. mapstyle draws each edge of the duckOSM network so that junctions read right. Every road edge stays its own feature on the page: hover it, click it, filter it or colour it by its `edge_id`, whatever the drawing does around it. ## Two directions, two lanes duckOSM stores a two-way street as two directed edges. They are drawn side by side, one per direction (from zoom 15), so each can be clicked and coloured on its own, and their shared end is drawn as one round end, not two bumps. A one-way street is one line with arrows. duckOSM also gives it a walking-only reverse edge (pedestrians may walk both ways); mapstyle marks that edge `is_directed = false`, so it doesn't turn the street into a two-way road. Footways, steps and other paths are one line too, whichever way you walk them. Two-way roads as two lanes; crossings drawn over their street ## Over and under The OpenStreetMap `layer`, `bridge` and `tunnel` tags decide what passes over what: - **Bridges** are drawn over the roads they cross, with square deck ends. - **Tunnels** are ordinary roads with a tunnel style: a dashed outline and light dashes on a faded fill. A tunnel is at ground level, so its mouths join their street like any road continuing; it goes under the roads only where it really passes under one (4 m clear of the street's drawn width). - **A road with only a `layer` tag** acts the same: it is at ground level, so a tunnel approach tagged `layer=-1`, or a walkway that starts at a path, still joins the road it meets, and it is drawn over (or under) a street only where it really crosses it. - **How that is drawn.** Every road has a casing number (in three parts: start, main, end) and a fill number, computed by [roadstyle](https://khoshkhah.github.io/roadstyle/guides/levels/) from the roads' levels, the road classes and where roads meet or cross: the roads are painted number by number, lowest first, and at each number all casings before all fills, so joints show no ring and an overpass is over its road. If the database has `visualization.edge_levels` (`duckosm levels`: one level area for all modes, next to the file), the page reads them with each road end's head and shape; if not, they are computed while the page is made. To fix a place by hand: `roadstyle-levels edit monaco.levels`, then make the page again. A click on a road is its own edge. - **Crossings** (`footway=crossing`) are drawn over their street, **mapped sidewalks** under it. - **Slip roads** (`*_link`) are drawn under the streets they join. Tunnel Albert II: the road runs into the tunnel; the tunnel is dashed Promenade Honoré II (a raised walkway) over Rond-Point Canton The **Bridges** and **Tunnels** rows in the **ROADS** box hide them. ## Roads you may not use duckOSM keeps the roads a mode may not use apart (`private_edges`): private roads (driveways, gated streets) and, for cars, bus-only roads and bus lanes. They are on the map in their own colour, **grey** for private and **muted blue** for bus, each with a row in the **ROADS** box (**Private roads**, **Bus lanes**) to hide or show them. They are never part of a route. Which roads count depends on the map's mode: on a driving map, those cars may not use (as duckOSM's driving map); on the map of every mode, bus lanes (even where bikes may use them) and the private roads no mode can use. Your own colours (`rsColor`) paint over them. ## Where it comes from This drawing is [roadstyle](https://khoshkhah.github.io/roadstyle/)'s (0.10 and later), fed by mapstyle with what it knows from duckOSM: which edges are directed (`directed_col`), and which paths are crossings or sidewalks (`band_col`, from duckOSM's `walk_type`), and which stretches of a road pass over or under another (`band_col` again, with `cap_col` for their square ends). # Route planner (demo) A demo of what a mapstyle page can host: drag a start and an end, see the route. The routing itself is duckOSM's job; this page shows it on the map. [Try it](https://khoshkhah.github.io/mapstyle/maps/planner.html) ``` mapstyle monaco.duckdb --planner ``` - Drive, walk, cycle, or walk + drive (needs `duckosm multimodal` on the database). - Gives the same routes as duckOSM's `route_points()`; for routing in your own code, use duckOSM. - Can't be combined with `dashboard=True` or `tiles=True`. # Dashboard One page to explore a database: every road and layer, a side panel to filter, colour and inspect. [Try it](https://khoshkhah.github.io/mapstyle/maps/dashboard.html) ``` mapstyle monaco.duckdb --dashboard ``` ``` ms.render_map("monaco.duckdb", dashboard=True) ``` ## The side panel - **Summary:** how many roads, classes and features are on the map. - **Colour by** road class, or by **mode**: which modes can use each road (all modes, driving + walking, walking only, …), with a legend (when colouring by class, the *Road type* list below is the legend). - **Filter**, in cards: *Roads* (mode, private roads and bus lanes, and road type), then the layers grouped by meaning (*Nature and water*, *Buildings and places*, *Transport*), each with `all` / `none`. - Per layer, the **⚙**: make it clickable or not, turn its hover tooltip and click popup on or off, and show only some of its kinds (just parks, say). - **Search**, and the fields of whatever you clicked: a road, or a feature and the roads under it. The panel is roadstyle's report page (`roadstyle.render_report`); mapstyle adds the mode filter, the mode colouring and the per-layer switches. Each is a [JavaScript call](https://khoshkhah.github.io/mapstyle/reference/javascript/index.md) too, so your own page can drive the same filters. # AI agents Ask your coding agent for a map ("a walking map of Tartu with a route planner") and it can do it right the first time: mapstyle ships what an agent needs in one page. ## The agent skill The [skill](https://github.com/Khoshkhah/mapstyle/blob/main/skills/mapstyle/SKILL.md) is one page for agents that write code (Claude Code, Codex, Cursor, …): the install, the duckOSM step, the one call and its options, the JavaScript API, and the traps (64-bit `edge_id`s, which options can't be combined, what needs the network). **Claude Code**, as a plugin: ``` /plugin marketplace add Khoshkhah/mapstyle /plugin install mapstyle@mapstyle ``` or as a plain skill: ``` mkdir -p ~/.claude/skills/mapstyle && curl -fsSL -o ~/.claude/skills/mapstyle/SKILL.md \ https://raw.githubusercontent.com/Khoshkhah/mapstyle/main/skills/mapstyle/SKILL.md ``` Other agents: point them at that file, or paste it into the project's agent instructions. ## The docs as text The whole site is also published for language models, following the [llms.txt](https://llmstxt.org) convention: - [`llms.txt`](https://khoshkhah.github.io/mapstyle/llms.txt): a short index of the pages; - [`llms-full.txt`](https://khoshkhah.github.io/mapstyle/llms-full.txt): every page as Markdown, in one file. ## Working on mapstyle Coding agents that change mapstyle itself read [`AGENTS.md`](https://github.com/Khoshkhah/mapstyle/blob/main/AGENTS.md): the commands, where things are, and the project's rules (Claude Code reads it through `CLAUDE.md`). ## The rest of the stack [duckOSM](https://github.com/Khoshkhah/duckOSM) and [roadstyle](https://khoshkhah.github.io/roadstyle/guides/agents/) have their own skills; roadstyle also has an MCP server, for drawing maps without code. # Reference # Python API ``` import mapstyle as ms ``` ## `render_map` ``` ms.render_map(db, mode=None, layers=True, planner=False, dashboard=False, interaction=None, paths="google", **kwargs) ``` The whole map of a duckOSM database as one page. Returns roadstyle's map object: `.save(path)` writes the HTML file, `.html` is the page as a string, and in Jupyter it shows itself. | Argument | Default | | | ------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `db` | | path of a duckOSM `.duckdb` file | | `mode` | `"all"` | which network stands out: `all`, `driving`, `walking`, `cycling` ([guide](https://khoshkhah.github.io/mapstyle/guides/modes/index.md)) | | `layers` | `True` | the base-map layers: `True` = all, a list of names, or `False` = roads only ([guide](https://khoshkhah.github.io/mapstyle/guides/base-map/index.md)) | | `paths` | `"google"` | how paths look: `google`, `osm`, `komoot`, `cyclosm` | | `theme` | `"osm"` | the whole map's colours: `osm`, `google`, `grey`, or a file of yours ([guide](https://khoshkhah.github.io/mapstyle/guides/themes/index.md)) | | `planner` | `False` | add the [route planner](https://khoshkhah.github.io/mapstyle/guides/planner/index.md) | | `dashboard` | `False` | make it a [dashboard](https://khoshkhah.github.io/mapstyle/guides/dashboard/index.md) | | `interaction` | `None` | how a layer opens: `{"crossings": {"clickable": True, "tooltip": True, "popup": False}}` | | `**kwargs` | | passed to [`roadstyle.render_edges`](https://khoshkhah.github.io/roadstyle/reference/parameters/): e.g. `tiles=True`, `basemap="positron"`, `view_3d=True`, `arrows=False` (not `palette` or `settings`: the mode sets those) | ``` ms.render_map("tartu.duckdb", mode="cycling", tiles=True).save("tartu.html") ms.render_map("monaco.duckdb", theme="grey", dashboard=True) ms.render_map("monaco.duckdb", layers=["buildings", "water"], basemap="positron") ``` ## `load_roads` ``` roads = ms.load_roads(db) # a GeoDataFrame ``` One row per `edge_id` over the database's mode networks, with `driving` / `walking` / `cycling` flags (which modes can use the edge), the OSM tags mapstyle draws by (`highway`, `name`, `bridge`, `tunnel`, `layer`, `oneway`, …) and duckOSM's `walk_type` (sidewalk, crossing, …). `edge_id` and `osm_id` are strings: duckOSM's hashed ids can pass 2⁵³, more than JavaScript numbers hold. ## `load_layers` ``` fcs = ms.load_layers(db) # {layer name: GeoJSON FeatureCollection} fcs = ms.load_layers(db, ["buildings"]) # a subset ``` The base-map layers of `styles/layers.yaml`, in drawing order, each with `kind`, `name` and the OSM id per feature. A layer whose `features.*` table is missing is skipped with a logged hint. ## `MODES` `("driving", "walking", "cycling")`: the travel modes of a duckOSM database. # Command line ``` mapstyle DB [-o OUT] [--mode {all,driving,walking,cycling}] [--paths {google,osm,komoot,cyclosm}] [--theme {osm,google,grey}] [--no-layers] [--planner] [--dashboard] [--tiles] [--basemap BASEMAP] ``` | Option | | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `DB` | a duckOSM `.duckdb` file | | `-o`, `--out` | the HTML file to write (default: `_.html`) | | `--mode` | which network stands out (default: `all`; `walking` with `--planner`) | | `--paths` | how walking and cycling paths look (default: `google`) | | `--theme` | the whole map's colours: `osm` (default), `google`, `grey` ([Themes](https://khoshkhah.github.io/mapstyle/guides/themes/index.md)) | | `--no-layers` | roads only, no base-map layers | | `--planner` | add the [route planner](https://khoshkhah.github.io/mapstyle/guides/planner/index.md) | | `--dashboard` | a [dashboard](https://khoshkhah.github.io/mapstyle/guides/dashboard/index.md): filter by mode, class, layer and kind | | `--tiles` | the roads as vector tiles inside the page, for large areas (needs `mapstyle[tiles]`) | | `--basemap` | a roadstyle base map to open on, e.g. `blank` (default), `positron`, `satellite` | ``` mapstyle monaco.duckdb mapstyle monaco.duckdb --mode cycling --paths cyclosm -o cycling.html mapstyle stockholm.duckdb --tiles --basemap positron ``` # JavaScript API Every mapstyle page is a roadstyle page, so roadstyle's whole [JavaScript API](https://khoshkhah.github.io/roadstyle/reference/javascript/) works on it: `rsQuery`, `rsFilter`, `rsColor`, `rsSetClasses`, `rsSetOverlay`, the `rs:select` event, and `window.map` (the MapLibre map). mapstyle adds, in the same style: | Function | Does | Fires | | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | | `rsSetModes(list)` | show the roads any of these modes can use (`["walking", "cycling"]`); `null` = all. Combines with `rsSetClasses`; it uses `rsFilter` on the roads, so a later `rsFilter(ids)` replaces it | `rs:filterchange` (`modes`) | | `rsGetModes()` | the modes shown, or `null` for all | | | `rsSetAccess(kind, on)` | show or hide the roads you may not use: `"private"` or `"bus"`; combines with `rsSetModes` | `rs:filterchange` (`access`, `visible`) | | `rsGetAccess()` | `{private: bool, bus: bool}`: shown or not | | | `RS_ACCESS` | `{kind: count}` of those roads on the page | | | `rsSetKinds(layer, list)` | show only these `kind`s of a base-map layer (`["park", "grass"]`); `null` = all | `rs:filterchange` (`overlay`, `kinds`) | | `rsGetKinds(layer)` | the kinds shown, or `null` for all | | | `RS_KINDS` | `{layer: {kind: count}}` | | | `rsSetInteraction(layer, {clickable?, tooltip?, popup?})` | switch a layer's clicks, hover tooltip and click popup; keys left out keep their state. Roads are always clickable | `rs:interactionchange` (`overlay`, `clickable`, `tooltip`, `popup`) | | `rsGetInteraction(layer)` | `{clickable, tooltip, popup}` of a layer | | `layer` is a layer's name (`"crossings"`) or its index. `ms:ready` fires once they are all defined (the layers' icons and textures load first). ``` document.addEventListener("ms:ready", () => { rsSetModes(["cycling"]); // only what a bike can use rsSetKinds("landcover", ["park", "garden"]); // just the green rsColor(rsQuery(p => p.name === "Boulevard du Larvotto"), "#e11d48"); }); ``` # Styles The look is data, in four YAML files in `src/mapstyle/styles/`: | File | Says | | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `modes.yaml` | per travel mode: which classes are drawn in the path style's emphasis width, whether roads are drawn as two lanes, whether the roads for cars fade, and roadstyle `roads` settings (widths by zoom, class groups, order); the dashboard's colours by mode | | `paths.yaml` | per path style (`google`, `osm`, `komoot`, `cyclosm`): the colour, outline (halo) and dash of each path class, the emphasis width by zoom, and how far the roads for cars fade | | `osm_carto.yaml` | the road colours (openstreetmap.org's), and each base-map layer's look: fills and outlines by `kind`, landcover textures, line colours and dashes, point icons, and the zoom each starts at | | `themes/*.yaml` | the themes (`google`, `grey`): a background, a transform for every colour, and the colours that differ ([Themes](https://khoshkhah.github.io/mapstyle/guides/themes/index.md)) | | `layers.yaml` | which `features.*` layers are drawn, in which order, with which filter (`where`), and which become a point at an area's centre (the parking "P") | The road entries are roadstyle settings: see its [settings reference](https://khoshkhah.github.io/roadstyle/reference/settings/) for every key.