MapMindLLM is an experimental project to enable offline navigation using OpenStreetMap (OSM) data and Large Language Models (LLMs).
It combines a local OSRM routing engine with a Python pipeline to generate human-friendly directions from raw coordinates or natural-language input — even without internet access.
- Offline routing using OSRM.
- Supports driving, walking, and cycling profiles.
- Accepts coordinates in both
lat,lonandlon,latformats. - Auto-selects travel mode based on distance (or override with
--mode). - Summarizes OSRM's JSON output into simple turn-by-turn instructions.
- Multi-waypoint routing with per-leg direction sections.
- LLM integration via local llama.cpp for natural-language coordinate extraction.
- Works on custom OSM extracts (e.g., Texas or Austin).
- Docker (to run OSRM and optional LLM server)
- Python 3.8+
- Python packages:
python3 -m venv .venv .venv/bin/python -m pip install requests
- Optional local model for LLM inference. Model weights are not committed to this repo; download or copy the GGUF file locally. The filename must match
docker-compose-llm.yml:models/mistral-7b-instruct-v0.2.Q4_K_M.gguf
-
Download OSM data
Example (Texas extract from Geofabrik):mkdir -p data curl -o data/texas-latest.osm.pbf https://download.geofabrik.de/north-america/us/texas-latest.osm.pbf
-
Preprocess the data for OSRM
Using Docker Compose (docker-compose-prep.yml):docker compose -f docker-compose-prep.yml up
This runs
osrm-extract,osrm-partition, andosrm-customizefor OSRM's MLD algorithm. A full Texas extract can take a long time and several GB of RAM. -
Run the routing server
docker compose -f docker-compose.yml up
OSRM will be available at:
http://127.0.0.1:5050 -
Place the local LLM model (optional — required for natural-language input)
The model file is intentionally not included in Git because GGUF weights are large. Create the repo-local model directory and place the GGUF file at the exact path expected by Docker Compose:mkdir -p models # Copy or download your model to: # models/mistral-7b-instruct-v0.2.Q4_K_M.gguf ls -lh models/mistral-7b-instruct-v0.2.Q4_K_M.gguf
The host
./modelsdirectory is mounted into the llama.cpp container as/models, and the compose file starts llama.cpp with:-m /models/mistral-7b-instruct-v0.2.Q4_K_M.gguf
If you use a different GGUF file, update both the filename in
models/and the-mpath indocker-compose-llm.yml. -
Run local LLM server (optional — required for natural-language input)
docker compose -f docker-compose-llm.yml up
llama.cpp server (Mistral 7B) will be available at:
http://127.0.0.1:8080
The modular pipeline is the recommended path:
.venv/bin/python -m map_llm_pipeline.app \
"from (-97.7431, 30.2672) via (-97.7460, 30.2800) to (-97.7536, 30.3006)" \
--profile driving --units metricEnd-to-end flow:
app.pyparses CLI options and builds the clients.llama_cpp.pysends the prompt to llama.cpp atLLAMA_BASEand requests structured waypoint JSON.parsing.pyis used as a regex fallback if LLM extraction fails or--no-llmis set.osrm.pycalls OSRM atOSRM_BASEwith the selected profile.pipeline.pyreturns origin, via points, destination, and cleaned directions by leg.
For deterministic routing without the LLM:
.venv/bin/python -m map_llm_pipeline.app \
"from (-97.7431, 30.2672) via (-97.7460, 30.2800) to (-97.7536, 30.3006)" \
--profile driving --units metric --no-llmValidated locally with OSRM on port 5050 and llama.cpp on port 8080. The sample above produced two route legs and directions from downtown Austin through the via point to the destination.
Configuration defaults can be overridden with environment variables:
OSRM_BASE=http://localhost:5050
LLAMA_BASE=http://localhost:8080
HTTP_TIMEOUT=30
UNITS=metricFetches a route between two coordinates and prints clean directions.
.venv/bin/python route_sample.py "30.441653,-97.780321" "30.396219,-97.745323"Example Output
[driving] Route: 8.5 mi, ~16 min
1. Start on Anderson Mill Rd for 0.2 mi
2. Turn right on US-183 S for 1.1 mi
3. Continue on Research Blvd for 3.5 mi
4. Take the ramp on Mopac Expy for 3.0 mi
5. Arrive at destination
Options
--mode→ force mode (driving,walking,cycling, orauto[default])--units→imperial(mi/ft) ormetric(km/m)--osrm→ set base URL (defaulthttp://127.0.0.1:5050)
Supports multiple via-points and optional natural-language coordinate extraction via a local LLM.
# With explicit coordinates
.venv/bin/python -m map_llm_pipeline.app "from (-97.7431, 30.2672) via (-97.7460, 30.2800) to (-97.7536, 30.3006)"
# Skip LLM, use regex parsing only
.venv/bin/python -m map_llm_pipeline.app --no-llm "from (-97.7431, 30.2672) to (-97.7536, 30.3006)"Options
--profile→driving(default),walking,cycling--units→metric(default) orimperial--no-llm→ disable llama.cpp; use regex-only coordinate parsing--llama-base→ llama.cpp base URL (defaulthttp://localhost:8080)--osrm-base→ OSRM base URL (defaulthttp://localhost:5050)
The same pipeline is available as a Python package:
.venv/bin/python -m map_llm_pipeline.app "from (-97.7431, 30.2672) via (-97.7460, 30.2800) to (-97.7536, 30.3006)" \
--profile driving --units metric- Add POI search (e.g., nearest gas stations) via Overpass API integration.
- Support offline geocoding (address → coordinates) with Nominatim.
MIT
- OSRM for the routing engine.
- OpenStreetMap contributors for the data.