A cycling route plotter that generates loop routes preferring quiet, narrow rural roads.
laneplotter takes a start point and a target ride distance and generates a circular loop route optimised for cyclists who prefer country lanes over main roads. Key features:
- Road preference: Prefers unclassified and residential roads (narrow rural lanes) over A-roads and B-roads. Major roads are penalised in the cost function.
- Turn bias: Biases toward left turns for left-hand traffic countries (e.g. the UK). This can be reversed for right-hand traffic countries.
- Gradient/elevation: Incorporates elevation data as a cost factor, allowing routes to be tuned for hilliness preference.
- Loop generation: Given a start point (lat/lon) and a target distance (km), generates a closed loop route back to the start.
from laneplotter.routing.loops import generate_loop
route = generate_loop(
start=(54.533, -5.887), # lat, lon
target_distance_km=40,
drive_side="left", # "left" or "right"
)Or via the API:
uvicorn laneplotter.api.server:app --reload
# POST /generate-route {"lat": 54.533, "lon": -5.887, "distance_km": 40}pip install -e ".[dev]"laneplotter/
├── graph/
│ ├── loader.py # OSM data loading via osmnx
│ ├── cost.py # Edge cost function (road class, turns, gradient)
│ └── elevation.py # Elevation data integration (SRTM)
├── routing/
│ ├── router.py # A* routing engine
│ └── loops.py # Loop generation logic
├── api/
│ └── server.py # FastAPI REST endpoint
└── viz/
└── map.py # Folium/Leaflet map output