Gocoder is a fast, scalable geocoding service written in Go, capable of converting place names to coordinates (forward geocoding) and coordinates to place names (reverse geocoding). It processes data from OpenStreetMap, Who's On First administrative boundaries, and Wikimedia importance scores, creating a highly optimized geographic database.
Gocoder utilizes several custom made data structures to ensure efficient geocoding:
- Trie: Efficient prefix-based matching for exact place names.
- Fuzzy Index: Approximate matching using n-gram indexing and Levenshtein distance.
- KD-Tree: Spatial indexing for reverse geocoding.
- Administrative Boundaries: R-tree indexing for quick administrative lookups.
- Supports all languages available in OpenStreetMap datasets.
- Automatic fallback when language-specific data is unavailable.
- Go 1.23.3 or newer
- Docker (optional)
- osmium-tool
- Sufficient storage (varies by geographic coverage)
git clone https://github.com/hstin-de/gocoder
cd gocoder
go mod download
CGO_ENABLED=0 go build -a -installsuffix cgo -ldflags '-w -s' -o gocoder .
Docker images are published on GitHub Container Registry (GHCR).
docker pull ghcr.io/hstin-de/gocoder:latest
Download the required data manually:
- OpenStreetMap Data (example Germany): Geofabrik
- Who's On First Database: geocode.earth (unzip first)
- Wikimedia Importance Scores: Nominatim
or use the provided download script to automatically fetch and extract all required datasets:
# Make script executable and run
chmod +x download-data.sh
./download-data.sh
Run database generation using Docker:
docker run --rm \
-v $(pwd)/data:/data \
-v $(pwd)/database:/app/database \
-e PLANET=/data/germany-latest.osm.pbf \
-e WHOS_ON_FIRST=/data/whosonfirst-data-admin-latest.db \
-e WIKIMEDIA_IMPORTANCE=/data/wikimedia-importance.csv.gz \
-e OUTPUT=/app/database/germany.gpkg \
ghcr.io/hstin-de/gocoder:latest ./gocoder generate
For configuration parameters, refer to the Configuration file.
Generation includes:
- Administrative boundary extraction.
- Who's On First area processing.
- OpenStreetMap node enrichment.
- Index building (Trie, KD-Tree).
- Binary database serialization.
Docker Compose:
version: '3.8'
services:
gocoder:
image: ghcr.io/hstin-de/gocoder:latest
ports:
- "3000:3000"
volumes:
- ./database:/app/database
environment:
- DATABASE=/app/database/germany.gpkg
- ENABLE_FORWARD=true
- ENABLE_REVERSE=true
command: ["./gocoder", "server"]
restart: unless-stopped
Docker Run:
docker run -d \
-p 3000:3000 \
-v $(pwd)/database:/app/database \
-e DATABASE=/app/database/germany.gpkg \
-e ENABLE_FORWARD=true \
-e ENABLE_REVERSE=true \
ghcr.io/hstin-de/gocoder:latest
- Endpoint:
GET /
Parameters:
q
: Search query (required).max
: Max results (default: 10).complete
: Return all results (default: false).cache
: Enable caching (default: true).lang
: Language preference.
Example:
curl "http://localhost:3000/?q=Berlin&max=5&lang=en"
- Endpoint:
GET /reverse
Parameters:
lat
: Latitude (required).lng
: Longitude (required).lang
: Language preference.
Example:
curl "http://localhost:3000/reverse?lat=52.517&lng=13.389&lang=en"
- Endpoint:
GET /node/:id
Example:
curl "http://localhost:3000/node/240109189?lang=en"
- Worldwide search: Typically <10ms, cached ~1ms.
- Exact Match: Trie lookup, O(m).
- Fuzzy Search: O(n*k) complexity.
- Reverse Geocoding: KD-tree, average O(log n).
- RAM usage: Forward and reverse ~2.5GB; Reverse only ~280MB.
This service processes data subject to licenses from OpenStreetMap, Who's On First, and Wikimedia. Ensure compliance with their respective licenses.
gocoder is released under the MIT License.