Skip to content

Examples

All examples use folium for map output and branca for colormaps.

pip install folium branca

Full runnable source: examples/python_example.py


Walking isochrones

Graduated colour bands from a central point, rendered largest-first so smaller bands appear on top.

import json, graphways as gw, folium

lat, lon = gw.geocode("Marienplatz, Munich, Germany")
time_limits = [300, 600, 900, 1200, 1500, 1800]   # 5-30 min in 5-min steps
colors     = ["#2ecc71", "#27ae60", "#f1c40f", "#e67e22", "#e74c3c", "#c0392b"]
labels     = [f"{t // 60} min walk" for t in time_limits]

graph = gw.SpatialGraph.from_place("Marienplatz, Munich, Germany", network="walk", max_dist=5_000)
isos = graph.isochrone((lat, lon), minutes=[t / 60 for t in time_limits])

m = folium.Map(location=[lat, lon], zoom_start=14, tiles="Cartodb Positron")
folium.Marker(location=[lat, lon], tooltip="Marienplatz").add_to(m)

for iso, color, label in reversed(list(zip(isos, colors, labels))):
    folium.GeoJson(
        json.loads(iso.to_geojson()),
        name=label,
        style_function=lambda _, c=color: {
            "fillColor": c, "color": c, "weight": 1.5, "fillOpacity": 0.2,
        },
        tooltip=label,
    ).add_to(m)

folium.LayerControl().add_to(m)
m.save("isochrones.html")

Gradient route colouring

Each road segment is coloured by midpoint travel time, from green (departure) to red (arrival), with a legend bar.

import json, graphways as gw, folium, branca.colormap

origin = gw.geocode("Marienplatz, Munich, Germany")
dest   = gw.geocode("English Garden, Munich, Germany")

graph = gw.SpatialGraph.from_place("Marienplatz, Munich, Germany", network="drive", max_dist=10_000)
route = graph.route(origin, dest)
route_geojson = json.loads(route.to_geojson())
coords = route_geojson["geometry"]["coordinates"]   # [lon, lat] per GeoJSON spec
times  = route.cumulative_times_s
total  = route.duration_s

m = folium.Map(location=list(origin), zoom_start=14, tiles="Cartodb Positron")

colormap = branca.colormap.LinearColormap(
    ["#2ecc71", "#f1c40f", "#e74c3c"], vmin=0, vmax=total / 60,
    caption="Travel time (minutes)",
)
colormap.add_to(m)

for i in range(len(coords) - 1):
    segment = [[coords[i][1], coords[i][0]], [coords[i+1][1], coords[i+1][0]]]
    t_mid   = (times[i] + times[i+1]) / 2
    folium.PolyLine(
        segment, color=colormap(t_mid / 60), weight=6, opacity=0.85,
        tooltip=f"t = {t_mid:.0f} s",
    ).add_to(m)

folium.Marker(list(origin), tooltip="Start", icon=folium.Icon(color="green")).add_to(m)
folium.Marker(list(dest),   tooltip="End",   icon=folium.Icon(color="red")).add_to(m)

m.save("route.html")

POI discovery within an isochrone

Restaurants reachable within 10 minutes on foot, rendered as map markers.

import json, graphways as gw, folium

lat, lon = gw.geocode("Marienplatz, Munich, Germany")

# Build graph once, reuse for isochrone + POIs
graph = gw.SpatialGraph.from_place("Marienplatz, Munich, Germany", network="walk", max_dist=3_000)
isos  = graph.isochrone((lat, lon), minutes=[10])                     # 10-minute walk
pois = graph.fetch_pois(isos[0])

m = folium.Map(location=[lat, lon], zoom_start=15, tiles="Cartodb Positron")
folium.GeoJson(json.loads(isos[0].to_geojson()), style_function=lambda _: {
    "fillColor": "#3498db", "color": "#2980b9", "weight": 1.5, "fillOpacity": 0.15,
}).add_to(m)

for poi in pois.pois:
    tags = poi.tags
    if tags.get("amenity") != "restaurant":
        continue
    lat_p, lon_p = poi.lat, poi.lon
    name = tags.get("name", "Restaurant")
    cuisine = tags.get("cuisine", "")
    folium.Marker(
        [lat_p, lon_p],
        tooltip=f"<b>{name}</b><br>{cuisine}",
        icon=folium.Icon(color="orange", icon="cutlery", prefix="fa"),
    ).add_to(m)

m.save("pois.html")

Graph visualisation

Render the raw road network (simplified) as a thin line layer.

import json, graphways as gw, folium

graph = gw.SpatialGraph.from_place("Marienplatz, Munich, Germany", network="drive", max_dist=3_000)
edges = json.loads(graph.edges_geojson())

m = folium.Map(location=[48.137, 11.575], zoom_start=14, tiles="Cartodb Positron")
folium.GeoJson(
    edges,
    style_function=lambda f: {
        "color": "#e74c3c" if f["properties"]["highway"] == "motorway" else "#3498db",
        "weight": 2,
        "opacity": 0.6,
    },
    tooltip=folium.GeoJsonTooltip(["highway", "length_m", "speed_kph"]),
).add_to(m)
m.save("network.html")

Multi-origin isochrones with a shared graph

Compute isochrones from several stops on the same network without re-fetching the graph.

import json, graphways as gw, folium

stops = {
    "Marienplatz":  (48.137144, 11.575399),
    "Hauptbahnhof": (48.140232, 11.558335),
    "Ostbahnhof":   (48.127264, 11.602636),
}

# One graph fetch covers all three stops
graph = gw.SpatialGraph.from_place("Marienplatz, Munich, Germany", network="walk", max_dist=5_000)

m = folium.Map(location=[48.137, 11.575], zoom_start=13, tiles="Cartodb Positron")

for name, (lat, lon) in stops.items():
    isos = graph.isochrone((lat, lon), minutes=[10])
    folium.GeoJson(
        json.loads(isos[0].to_geojson()),
        style_function=lambda _: {
            "fillColor": "#3498db", "color": "#2980b9",
            "weight": 1.5, "fillOpacity": 0.15,
        },
        tooltip=f"{name}: 10-min walk",
    ).add_to(m)
    folium.Marker([lat, lon], tooltip=name).add_to(m)

m.save("multi_origin.html")