The interaction contract¶
What roadstyle's engine, the dashboard and the page share: the style's metadata keys, the dashboard's options, the global state, the feature properties, the page's placeholders and the browser storage keys.
The design is in the Rust library plan. This page is the inventory.
tests/test_contract_names.py searches the code for each kind of name below and fails when the code has a name that this page does
not have, or the reverse. The names in the section "Planned names" are not in the code yet.
The style's metadata¶
A style that the Rust engine makes with state: "live" (a page with the dashboard; render_edges(engine="rust")) has the contract.
The export's style (export_style, export_inline: state baked) has roadstyle:interaction, roadstyle:images and
roadstyle:color_options only.
| Key | Content |
|---|---|
roadstyle:contract |
the version of the contract: 1 |
roadstyle:state |
each global state rs_* and its start value |
roadstyle:controls |
the options of rsDashboard that come from the style (the next table) |
roadstyle:interaction |
{popup, tooltip, hover_delay_ms}: the road popup's fields, the hover tooltip, the hover delay |
roadstyle:color_options |
[{name, prop, legend}]: the colour options and their legends |
roadstyle:images |
the images that the host adds (oneway) |
roadstyle:planner, roadstyle:planner_skipped |
the route planner's graphs, or the number of roads past its limit |
layer roadstyle:group |
the group of a layer: roads, or an overlay's label |
layer roadstyle:over |
a base-map layer that goes over the roads (the 3D buildings) |
layer roadstyle:position |
the drawing position of a layer of export_look |
The dashboard's options from the style¶
roadstyle:controls has these options, with the values that render_web.render gives the page (render(_parts=True) returns them).
The dashboard (static/dashboard/index.js, fromStyle) takes each one that the page does not give. The overlays' sources and layers
get the page's prefix.
| Option | Content |
|---|---|
tiles, simple |
the roads in vector tiles; the id of the one road layer of simple mode with inline data (roads-simple), else false |
pitch_3d |
the camera's tilt in 3D |
select_color |
the colour of a selected road (also the Google 3D line) |
filter |
the filter panel: {on, col, classes, access, swatches, bridges, tunnels}, and palettes with a view's palette |
color_active |
the colour option at the start |
overlays |
the Layers box: [{label, source, layers, hit, visible, color, popup, popup_window, tooltip, under, base, select, interactive}] |
tunnel |
the tunnel look: {layers, dash, casing, strength, palette, palettes, ratio, bg, steps, ratios, toward, towards, to, control} |
fill_layers |
the road fill layers that the page recolours |
road_fill |
{on, paint}: the road fill switch and each fill layer's opacity without it |
views |
[{name, set}]: the View menu |
items |
{label, popup, layer} of render's items=, or null |
edge_id_col |
the roads' id column |
arrow_icon, arrow_color, arrow_rules |
the one-way arrow: its image, its colour and the page's rules for where it goes |
The page and control variables¶
"Run time" says whether a page can change the value after it opens. "Gap" marks a value that a page cannot change today and that the contract makes changeable (or a value that is not used).
| Variable | Type, default | Set in | Read by | Run time | API |
|---|---|---|---|---|---|
name (title) |
text, "roadstyle" |
render keyword; look args.name; style name |
page title, host panel | no | |
style |
the style object, or null (the roads come later) | rsDashboard option |
every control | yes | setStyle; restyle (planned) |
prefix |
text, "" |
rsDashboard option |
every control that finds a roads layer or source | no | |
engine.props |
(row) => Promise<props> |
rsDashboard option |
select.js (click, rsSelect, the tooltip, the twin __rs_edge2) |
the engine port | |
engine.restyle |
(change) => Promise<StylePatch> |
rsDashboard option |
the controls that need the engine | the engine port (planned) | |
basemaps, basemap |
keys, DEFAULT_SWITCHER, "voyager" |
render; rsDashboard option (BASEMAPS) |
basemap.js |
yes | rsSetBasemap; rs:basemapchange; window.RS_BASEMAPS |
basemap_switcher |
bool, true | render; option |
basemap.js |
no | |
api_key |
text | render, set_api_key |
the base-map URL | no | |
zoom_readout |
bool, true | render; option |
zoom.js |
no | |
pitch, bearing, max_pitch |
numbers, none, none, 70 | render; defaults.json camera |
the map | the camera: yes; max_pitch: no |
gap: no getter or setter of the camera (only rsFocus) |
pitch_3d |
number, 55 | defaults.json; option |
view3d.js |
yes | rsSetView3D; rs:viewchange |
view_3d (bridge decks) |
bool, false | render; look args.view_3d |
engine (deck layers) | no: the decks are in the style or not | |
| 3D buildings | an overlay (roadstyle:group = buildings 3D) |
engine (mapstyle features) | the Layers box only when Python gives overlays |
gap: a Rust style has no overlay list for the dashboard | rsSetOverlay |
find_control |
bool, false | render; option |
find.js |
no | rsFind |
| find fields | the popup fields, and edge_id_col and edge_ref (_ID_KEYS) |
road_popup, edge_id_col |
find.js |
no | rsFind |
edge_id_col |
text, "edge_id" |
render; option |
find.js, select.js |
no | |
road_popup |
false, null (every field) or fields; DEFAULT_ROAD_POPUP |
render; roadstyle:interaction.popup; option |
select.js, find.js |
gap | |
popup_mode |
"popup" or "panel" |
render; option |
panel.js and every docked control |
no | |
road_tooltip, tooltip |
false, true or fields | render; look args.tooltip; roadstyle:interaction.tooltip |
select.js |
gap | |
hover_delay_ms |
ms, 300 | render; roadstyle:interaction; option; _TIP_DELAY |
select.js, overlays.js |
gap | |
copy_field |
text, "edge_id" |
look args.copy_field (mapstyle passes it) |
folium only | gap: not used by the web page | |
hover_color |
color, selection.hover (#b388ff) |
render; the palette |
engine: a literal in each highlight expression | gap: fixed in the style | planned (see below) |
select_color |
color, selection.select (#7c4dff) |
render; the palette; option (Google 3D line) |
engine (literal), google3d.js |
gap: fixed in the style | planned (see below) |
| the glow | selection.opacity 0.85, glow_opacity 0.35 (palette); the width of the fill (simple mode) |
the palette | engine (_simple_color(glow=...)) |
gap: fixed | planned (see below) |
filter |
{on, col, classes, swatches, palettes, bridges, tunnels, access}, off |
render (filter_control, filter_col, access_col); option |
filter.js, views.js |
yes | rsSetClasses, rsSetBridges, rsSetTunnels, rsSetAccess, rsGetAccess, rsFilter; rs:filterchange; window.RS_CLASSES, RS_CLASS_COL, RS_CLASS_COLORS, RS_ACCESS |
| access colors | access.private, bus, pedestrian, delivery (palette) |
the palette | engine (__rs_access colors) |
no | |
color_options |
[{name, prop, legend}] |
render; roadstyle:color_options; option |
color.js, legend.js, views.js |
the choice: yes; a new option: restyle |
rsSetColorField; rs:colorchange; window.RS_COLOR_OPTIONS |
| the legend | {title, kind, entries} or {title, kind, ramp, vmin, vmax} |
the data styler (bake_color_options) |
legend.js |
follows the option | gap: the metadata does not give the active option |
color_active |
index or name, 0 | render; option |
color.js |
yes | rs_co |
| host colors | [{color, ids}] |
the host page | the fill and item expressions | yes | rsColor, rsColorBase; rs:colorchange |
road_fill |
{on, paint}, on |
render; option |
color.js |
yes | rsSetRoadFill; rs:roadfillchange |
overlays |
[{label, source, layers, popup, tooltip, interactive, under, base, select, color, visible, popup_window}] |
render (Overlay); option |
core.js, overlays.js, filter.js, select.js |
visibility, color: yes | rsSetOverlay; rs:overlaychange; window.RS_OVERLAYS |
overlay_control, overlay_popup |
bool, true | render; option |
overlays.js |
no | |
items, items_popup |
{label, popup, layer} or null |
render; option |
select.js |
no | |
tunnel |
{layers, control, strength, palette, palettes, ratio, ratios, toward, towards, to, steps} |
render (tunnel_control) and the look (tunnels) |
tunnel.js, arrows.js |
yes | rsSetTunnelStyle; rs:tunnelchange; window.RS_TUNNEL_PALETTES, RS_TUNNEL_TOWARDS |
| the bridge look | casing color and width, shadow, deck (look bridges) |
the look | engine | no | |
views |
{name: {setting: value}} |
render; option |
views.js |
yes | rsSetView; rs:viewselect; window.RS_VIEWS |
palette (views) |
text | render; views |
engine (rs_palette) |
yes, among the palettes that the views name | rsSetView |
arrows, labels |
bool, true | render; look args |
engine | gap: no switch at run time (a visibility change is enough) | |
arrow_icon, arrow_color, arrow_rules |
the look (arrows, labels.base_size) |
option | arrows.js |
no | |
street_view |
"window", true, false |
render; option |
streetview.js, svspot.js |
yes | rsSetStreetView; rs:streetviewchange |
| Street View mode | "linked" or classic |
localStorage rs-street-view-mode |
streetview.js |
yes | the window's buttons |
street_view_key |
text, GOOGLE_MAPS_KEY |
render; option |
streetview.js, google3d.js |
no | |
| Street View spot and marker | {edge, m} |
the click; the host | svspot.js |
yes | rsSetStreetViewMarkerAt, rsSetStreetViewMarker, rsStreetViewStep, rsGetStreetViewSpot; rs:streetviewmove, rs:streetviewspot |
google_3d |
bool, false | render; option |
google3d.js |
yes | rsSetGoogle3D; rs:google3dchange |
| the place of the two windows | {left, top, width, height} |
localStorage rs-street-view-window:<path>, rs-google-3d-window:<path> |
float.js |
yes | |
side_panel_html, host_panel_width |
HTML, 320 px | render |
the page, panel.js |
open or closed: yes | rsPanelShow; localStorage rs-host-panel:<path> |
--rs-side |
CSS length | panel.js |
dashboard.css (the controls on the right move with the panel) |
yes | |
| the theme of the page (light, dark) | none on the map page; data-theme on the sidebars of render_dashboard and render_report |
templates/*.html |
the sidebars | the sidebars: yes | gap: dashboard.css and popup.css have literal colors and one CSS variable (--rs-side) |
simple, tiles, fill_layers |
the mode and the road fill layer ids | render; option |
core.js, select.js, svspot.js |
no | |
compress, data_maxzoom, data_tolerance |
render |
engine | no | ||
boundary |
the outline | render |
engine | no | |
| page self-checks | window.__rs_gz, window.__rs_tiles |
_INFLATE_JS, _TILES_JS |
the page's banner | ||
window.map |
the map | the page | the level editor, host scripts | ||
| URL parameters | none today | new: #rs= (getState, setState) |
The global state rs_*¶
The style reads each one with ["global-state", name] (_gs() in render_web.py, gs() in layers.rs). A live style (state: "live")
declares each one in MapLibre's state block and lists its start value in roadstyle:state.
| Name | Type | Start value | Values | Read by | Set by | API |
|---|---|---|---|---|---|---|
rs_co |
integer | color_active |
0 to the number of options - 1 | the fill pieces and items (match on the option) |
Colour by menu, views | rsSetColorField; rs:colorchange |
rs_colors |
object: edge index to color | {} |
colors | the fills, items, end caps, attached overlays (_painted) |
host page | rsColor; rs:colorchange |
rs_base |
object: edge index to color | {} |
colors | the same, under rs_colors |
host page | rsColorBase |
rs_fill_on |
bool | road_fill |
the fill pieces' opacity | road fill switch, views | rsSetRoadFill; rs:roadfillchange |
|
rs_ov_<i> |
object: feature id to color | {} |
colors | the paint of overlay i |
host page | rsColor(..., overlay) |
rs_palette |
text | the start palette | the palettes that the views name | each color that differs between these palettes (__rs_fill@<palette> and the paint values) |
View menu | rsSetView; rs:viewselect |
rs_tun_strength |
number | tunnel_strength (60) |
0 to 100 (steps) |
each tunnel color | Tunnels box | rsSetTunnelStyle; rs:tunnelchange |
rs_tun_toward |
color | tunnel_toward (Sand #d6cfc4) |
towards, or any #rrggbb |
the same | Tunnels box | the same |
rs_tun_two |
bool | the palette has two colors | the tunnel casing | Tunnels box | the same | |
rs_tun_c0, rs_tun_c1 |
colors | tunnel_palettes[tunnel_palette] |
the palettes | the tunnel casing dash and gap | Tunnels box | the same |
rs_tun_ratio |
[dash, gap] |
tunnel_casing_dash ([1, 1]) |
ratios |
the tunnel casing dash layer | Tunnels box | the same |
With state: baked (the export, RustGIS), the engine writes the start values in place of these expressions.
The feature properties __rs_*¶
66 names. None is public for a host page: a host reads the data columns and the API. "Dashboard" marks the names that the dashboard
reads (the internal contract between the engine and the dashboard of the same version). "Leaflet" marks the names of the Leaflet spec
(emit.to_spec, static/roadstyle.js). Each one goes into a typed field of the render model, and the engine writes the property only
when a layer reads it.
| Names | Meaning | Written by | Read by | Kind | Replaced by |
|---|---|---|---|---|---|
__rs_fill, __rs_w, __rs_op, __rs_dash, __rs_casing, __rs_cw, __rs_cop, __rs_class |
the class style of the edge: fill color, width, opacity, dash, casing color, casing width, casing opacity, class | stylers.bake_props, roads.rs |
engine layers, color.js (__rs_fill), Leaflet |
dashboard (__rs_fill), Leaflet |
RoadDraw.class + the look; the layer expressions read the class |
__rs_fill__<i> (__rs_fill__1, ...), __rs_fill@<palette>, __rs_fill__b, __rs_color |
the fill of color option i, of a palette of a view, the twin's fill (end caps), the color_table column |
bake_color_options, _merge_palettes, render.py |
engine, color.js |
dashboard (__rs_fill__<i>) |
RoadDraw.look paint columns (task 1) |
__rs_cl, __rs_fl, __rs_cs, __rs_ce |
the casing (main), fill, casing start and casing end numbers | _mark_levels, roads.rs |
engine | internal | RoadDraw.levels |
__rs_hs, __rs_he, __rs_cap, __rs_cap0, __rs_cap1, __rs_split |
the head lengths, the cap of both ends, of each end, two different ends | render (the head columns), _mark_caps |
engine | internal | RoadDraw.ends |
__rs_band |
always 0 since the positions | _mark_levels |
engine | internal | removed |
__rs_twoway, __rs_oneway, __rs_dup, __rs_twin, __rs_pair |
two directions, the arrow, the second edge of a single-line pair, the edge of the shared casing, the shared casing | _mark_twoway, _mark_single_line, _mark_twin_casing |
engine, arrows.js, svspot.js (__rs_twoway), select.js (__rs_dup) |
dashboard (__rs_twoway, __rs_dup) |
RoadDraw.direction and the derived twin, single_line |
__rs_bridge, __rs_tunnel, __rs_access, __rs_lvl |
the bridge look, the tunnel look, the access kind, the tag level of an attached item | _mark_lvl, access_col, _edge_overlay |
engine, filter.js (__rs_access, __rs_lvl) |
dashboard (__rs_access, __rs_lvl) |
RoadDraw.structure, RoadDraw.look.access |
__rs_cls |
the class column of the edge on every piece, name and arrow (for the class filter) | _mark_cls, roads.rs, slots.rs |
filter.js |
dashboard | the edge label: the dashboard reads the class through the edge |
__rs_kept_ (the prefix of __rs_kept_<column>) |
a data column that has the engine's name of another keyword's column (a column highway when highway_col names another one), kept under this name in between |
the column map (lib.rs, ColumnMap) |
the engine | internal | |
__rs_edge, __rs_edge2, __rs_edges |
the edge label: the edge's row, the twin's row, the rows of a shadow or a deck | every generator | core.js, filter.js, select.js, arrows.js, the level editor |
dashboard | the edge label of each piece (render model) |
__rs_k, __rs_s |
the kind of piece (0 casing, 1 fill, 2 shadow, 3 tunnel gap, 4 tunnel dash, 5 item) and its sort key | _simple_pieces, simple.rs |
engine, core.js, svspot.js (__rs_k) |
dashboard (__rs_k) |
DrawKey |
__rs_main, __rs_seam, __rs_lap, __rs_stub, __rs_nocase |
the main casing piece, a seam, a lap, an end stub, an end cap with no casing ring | _casing_parts, simple.rs, _twin_ends |
engine | internal | the piece generators |
__rs_wm, __rs_cm, __rs_twm |
the width, the casing and the pair width in metres (over cos of the latitude) | _mark_width_m |
engine | internal | RoadDraw.look.width_m |
__rs_ord, __rs_ov, __rs_item, __rs_ic, __rs_iwm, __rs_iom, __rs_imz, __rs_pick |
an attached object's order, its overlay, its row, color, width and offset in metres, minzoom, and "pick it as itself" | _edge_overlay, _item_pieces, _road_items |
engine, select.js (__rs_pick) |
dashboard (__rs_pick) |
Attachment |
__rs_arw |
the number of an arrow slot (for the export's thinning) | _annotation_slots, slots.rs |
engine | internal | the slot attachments |
__rs_base, __rs_height, __rs_casing_slab, __rs_chain |
a 3D deck's base and height, its casing slab, its chain | _bridge_decks |
engine, select.js (__rs_casing_slab) |
dashboard (__rs_casing_slab) |
the deck generator |
__rs_fc_, __rs_fc_frame, __rs_fc_i, __rs_fc_id, __rs_fc_wkb |
not properties: temporary names in the DuckDB query of fastjson.py |
fastjson.py |
internal | removed (the Rust readers) | |
__rs_gz, __rs_tiles |
not properties: the page's self-check globals (window.__rs_gz, window.__rs_tiles) |
_INFLATE_JS, _TILES_JS |
the page's banner | page | the page writer |
__rs_fill__ |
the prefix of __rs_fill__<i> in the code |
The page's placeholders¶
static/web_template.html has one placeholder for each value that render_web._page_html puts in the page:
__TITLE__, __MAPLIBRE_CSS__, __MAPLIBRE_JS__, __RS_TILES__, __DASHBOARD_CSS__, __POPUP_CSS__, __HOST_PANEL_HTML__,
__POPUP_JS__, __DASHBOARD_JS__, __STYLE__, __CENTER__, __PITCH__, __BEARING__, __MAX_PITCH__, __BASEMAPS__,
__BM_SWITCHER__, __RS_TILED__, __RS_LEAN__, __ROAD_POPUP_MODE__, __FIND_CONTROL__, __ZOOM_READOUT__, __PITCH3D__,
__STREET_VIEW__, __SV_WINDOW_KEY__, __GOOGLE_3D__, __SELECT_COLOR__, __FILTER__, __COLOR_OPTIONS__, __CO_ACTIVE__,
__OVERLAYS__, __OVERLAY_CONTROL__, __OVERLAY_POPUP__, __TUNNEL__, __RS_FILL_LAYERS__, __RS_ROAD_FILL__, __VIEWS__,
__ROAD_ITEMS__, __ROAD_POPUP__, __ROAD_TOOLTIP__, __HOVER_DELAY_MS__, __EDGE_ID_COL__, __ARROW_ICON__, __ARROW_COLOR__,
__ARROW_RULES__, __BOUNDS__.
The browser's storage and the CSS variables¶
| Name | Content | Set by |
|---|---|---|
rs-street-view-mode |
the Street View mode (linked or classic) |
streetview.js |
rs-street-view-window:<path>, rs-google-3d-window:<path> |
the place of the two windows | float.js |
rs-host-panel:<path> |
the host panel open or closed | panel.js |
--rs-side |
the width of the side panel (the controls on the right move with it) | panel.js |
Planned names¶
Names of the plan that the code does not have yet (test_contract_names.py does not read this section): the global states
rs_hover, rs_select and rs_glow (setSelectionStyle), the metadata key roadstyle:levels (the source of the drawing positions)
and the layer key roadstyle:role (casing, fill, item, arrows, labels, highlight, deck, base).