# Nigeria Police Station Coverage
A pipeline that builds a geocoded, deduplicated dataset of Nigerian police
stations from public sources, joins it against LGA (Local Government Area)
boundaries, and reports station coverage per LGA — for all 36 states + FCT.
Started as a one-state experiment (Rivers State) to figure out what data was
even available. It wasn't much: OpenStreetMap alone turns up a handful of
stations per state, GRID3's police-station layer only covers ~21 of the
country's 37 states, and neither is close to a complete picture. The
pipeline that emerged combines both with manually-sourced Google Maps
exports, resolves duplicates and cross-state contamination automatically,
and scales the same process to every state.
## Sources
| Source | What it gives | Coverage |
|---|---|---|
| OpenStreetMap (via Overpass API) | `amenity=police` points | Sparse everywhere, ~1–30 per state |
| GRID3 NGA Police Stations feature service | Purpose-built police POI layer | ~21 of 37 states only |
| Google Maps (manual export per state) | Precise, named, building-level pins | The main source of volume — user-collected |
## Pipeline
```
pipeline/
state_config.py path resolution + canonical state name list
fetch_osm.py Overpass query for a state
fetch_grid3.py GRID3 feature service query for a state
parse_google_export.py cleans a Google Maps export: extracts precise
coordinates from place URLs, filters out
landmark-reference rows ("opposite the police
station"), rejects points outside the state's
actual boundary (catches cross-state stragglers
that show up in Maps exports near borders)
scrape_nigeriagalleria.py best-effort scrape of a secondary directory
(heuristic — always review output)
geocode_manual_stations.py Nominatim geocoding for manually-sourced lists
merge_sources.py merges all available sources, dedupes by
proximity and matched name, drops
low-confidence geocodes
compute_coverage.py spatial …