Metadata-Version: 2.5
Name: yoro-maps
Version: 0.7.0
Summary: Offline maps, routing, and POI, worldwide — companion to yoro geocoding
Project-URL: Homepage, https://github.com/Altius-Academy-SNC/yoro-maps
Project-URL: Documentation, https://altius-academy-snc.github.io/yoro-maps
Project-URL: Repository, https://github.com/Altius-Academy-SNC/yoro-maps
Author-email: Paul Guindo <paulguindo@altius-group.ch>
License-Expression: MIT
License-File: LICENSE
Keywords: africa,maps,mbtiles,offline,osm,routing
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Django
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: GIS
Requires-Python: >=3.10
Requires-Dist: httpx>=0.24
Requires-Dist: yoro>=0.5.0
Provides-Extra: all
Requires-Dist: django>=4.2; extra == 'all'
Requires-Dist: mercantile>=1.2; extra == 'all'
Requires-Dist: osmium>=4.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: django-stubs; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: types-requests; extra == 'dev'
Provides-Extra: django
Requires-Dist: django>=4.2; extra == 'django'
Provides-Extra: docs
Requires-Dist: mkdocs-material; extra == 'docs'
Requires-Dist: mkdocstrings[python]; extra == 'docs'
Provides-Extra: extract
Requires-Dist: osmium>=4.0; extra == 'extract'
Provides-Extra: tiles
Requires-Dist: mercantile>=1.2; extra == 'tiles'
Description-Content-Type: text/markdown

# Yoro Maps

**[Documentation](https://altius-academy-snc.github.io/yoro-maps/)** | **[PyPI](https://pypi.org/project/yoro-maps/)** | **[GitHub](https://github.com/Altius-Academy-SNC/yoro-maps)**

Offline maps, routing, and POI, worldwide — companion to [yoro](https://pypi.org/project/yoro/) geocoding.

## Install

```bash
pip install yoro-maps
pip install yoro-maps[extract]  # OSM data extraction
pip install yoro-maps[django]   # Django integration
pip install yoro-maps[tiles]    # Tile downloading
```

## Build a map database

```bash
yoromaps download ML --output mali.yoromaps
```

## Route between Yoro codes

```bash
yoromaps route mali.yoromaps ML-4V7AK ML-5G62E
```

```python
import yoromaps

conn = yoromaps.open_db("mali.yoromaps")
graph = yoromaps.get_graph("mali.yoromaps")  # loaded once, cached per process

r = graph.route(12.639, -8.003, 14.489, -4.197)  # Bamako → Mopti
print(f"{r.distance_km} km, {r.duration_min} min")  # 551.8 km, 681.0 min

# Points of interest — every POI gets a Yoro code automatically
poi = yoromaps.add_poi(conn, 12.639, -8.002, "Grand marche", category="market")
print(poi["yoro_code"])  # "ML-4V7AK"
yoromaps.pois_near(conn, 12.64, -8.0, radius_m=500)  # sorted by distance
yoromaps.pois_in_cell(conn, "ML-4V7AK")  # who lives at this address?
```

A build already fills that table from OpenStreetMap: the shops, schools,
hospitals, markets and places of worship in the extract are read out, given
their Yoro code and stored under `source="osm"`. Re-running an extraction
replaces only those rows, so locally added POIs survive every refresh.

```python
from yoromaps.osm_poi import extract_pois, categorize

categorize({"amenity": "pharmacy"})  # "pharmacy"
categorize({"amenity": "parking"})  # None — not every tag is a place

stats = extract_pois("togo-latest.osm.pbf", conn)
stats["pois"]  # 16940
stats["unmapped"]  # the tags we walked past, most frequent first
```

Tagging is an allowlist, so noise stays out; `stats["unmapped"]` is what tells
you which categories are worth adding next. Nameless features are skipped.

```bash
yoromaps download ML -o mali.yoromaps --no-pois   # routing graph only
```

## Update maps

```bash
yoromaps update mali.yoromaps
# → Downloads only if OSM data has changed. POI and tiles are preserved.
```

## Tested performance

| Route | Distance | Compute |
|-------|----------|---------|
| Bamako → Mopti | 551.8 km | 6.3s |
| Bamako → Tombouctou | 812.2 km | 6.6s |
| Urban (Bamako) | 3.8 km | 0.5s |

## Django integration

```python
import yoromaps

DATABASES = {
    "default": {...},
    "maps": yoromaps.db_config("/data/mali.yoromaps"),
}
```

## License

MIT — Paul Guindo / Altius Academy SNC.
