158 lines
5.2 KiB
Markdown
158 lines
5.2 KiB
Markdown
# Privacy Maps
|
|
|
|
A privacy-first Google Maps alternative. No tracking, no accounts, no third-party API calls. All services are self-hosted.
|
|
|
|
**Stack:** Flutter (mobile) · Rust/Actix-web (backend) · PostgreSQL/PostGIS · Martin (tiles) · Photon (geocoding) · OSRM (routing)
|
|
|
|
---
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
maps/
|
|
├── docs/ # Specs, architecture, API contracts, data model
|
|
├── backend/ # Rust API gateway + Docker Compose for all services
|
|
│ ├── scripts/ # Data import scripts
|
|
│ └── initdb/ # PostgreSQL init SQL (runs on first startup)
|
|
└── mobile/ # Flutter app
|
|
```
|
|
|
|
---
|
|
|
|
## Backend Setup
|
|
|
|
### Requirements
|
|
|
|
- Docker or Podman + Compose
|
|
- ~50 GB free disk (for OSM data, OSRM graphs, Photon index)
|
|
- ARM64 (Raspberry Pi) or amd64 host
|
|
|
|
### 1. First-time setup
|
|
|
|
```bash
|
|
cd backend
|
|
|
|
# Build the custom images (PostGIS arm64 + importer toolchain)
|
|
podman compose build
|
|
|
|
# Start PostgreSQL first — extensions are enabled automatically on first start
|
|
podman compose up -d postgres
|
|
|
|
# Wait until ready
|
|
podman compose exec postgres pg_isready -U maps
|
|
```
|
|
|
|
### 2. Import data (first time)
|
|
|
|
Run each script individually rather than `update_all.sh` on first setup — the download takes ~6 minutes and you only need it once.
|
|
|
|
```bash
|
|
# Step 1: Download OSM PBF extract (~1.2 GB for Netherlands, ~6 min)
|
|
podman compose run --rm importer /app/scripts/01_download.sh
|
|
|
|
# Step 2: Import tile data into PostGIS (~10-20 min)
|
|
podman compose run --rm importer /app/scripts/02_import_tiles.sh
|
|
|
|
# Step 3: Import POI data into PostGIS
|
|
podman compose run --rm importer /app/scripts/03_import_pois.sh
|
|
|
|
# Step 4: Download Photon geocoding index (~2.3 GB for Netherlands)
|
|
podman compose run --rm importer /app/scripts/04_import_geocoding.sh
|
|
|
|
# Step 5: Preprocess OSRM routing graphs — run on the HOST, not in the container
|
|
# Builds a local ARM64 OSRM image on first run (~30-60 min), then preprocesses
|
|
# car/foot/bicycle profiles. Subsequent runs skip the image build.
|
|
bash backend/scripts/05_import_routing_host.sh ~/dev/maps/data
|
|
|
|
# Step 6: Register offline regions in the database
|
|
podman compose run --rm importer /app/scripts/06_build_offline_packages.sh
|
|
```
|
|
|
|
To change the country for step 4, use the full country name:
|
|
```bash
|
|
PHOTON_COUNTRY=germany podman compose run --rm importer /app/scripts/04_import_geocoding.sh
|
|
```
|
|
|
|
### 3. Start all services
|
|
|
|
```bash
|
|
podman compose up -d --scale importer=0
|
|
```
|
|
|
|
After startup, restart the services that depend on the imported data:
|
|
|
|
```bash
|
|
podman compose restart martin
|
|
podman compose restart osrm-driving osrm-walking osrm-cycling
|
|
```
|
|
|
|
### 4. Weekly data refresh
|
|
|
|
Use `update_all.sh` for scheduled updates. It re-downloads the PBF only if the file has changed on the server (`wget -N`), then reimports everything. Note: OSRM preprocessing is not included — run it separately on the host if routing data has changed.
|
|
|
|
```bash
|
|
podman compose run --rm importer /app/scripts/update_all.sh
|
|
|
|
# If routing data changed, also run on the host:
|
|
bash backend/scripts/05_import_routing_host.sh ~/dev/maps/data
|
|
podman compose restart osrm-driving osrm-walking osrm-cycling
|
|
```
|
|
|
|
To refresh only specific data (e.g. tiles changed but routing didn't):
|
|
|
|
```bash
|
|
podman compose run --rm importer /app/scripts/01_download.sh
|
|
podman compose run --rm importer /app/scripts/02_import_tiles.sh
|
|
podman compose restart martin
|
|
```
|
|
|
|
### Service ports
|
|
|
|
| Service | Port | Description |
|
|
|------------|-------|--------------------------|
|
|
| backend | 8080 | Rust API gateway |
|
|
| postgres | 5432 | PostGIS database |
|
|
| redis | 6379 | Tile/route cache |
|
|
| martin | 3001 | Vector tile server |
|
|
| photon | 2322 | Geocoding (search) |
|
|
| osrm-driving | 5000 | Car routing |
|
|
| osrm-walking | 5001 | Walking routing |
|
|
| osrm-cycling | 5002 | Cycling routing |
|
|
|
|
---
|
|
|
|
## Mobile App Setup
|
|
|
|
```bash
|
|
cd mobile
|
|
flutter pub get
|
|
dart run build_runner build --delete-conflicting-outputs
|
|
flutter run
|
|
```
|
|
|
|
On first launch, go to **Settings** and enter your backend URL (e.g. `http://your-pi-ip:8080`).
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
**PostGIS extension error** — The postgres container must be recreated to pick up the init scripts:
|
|
```bash
|
|
podman compose down postgres
|
|
podman compose up -d postgres
|
|
```
|
|
|
|
**Podman short-name error** — All images use full `docker.io/` registry paths. If you see this on another service, prefix its image with `docker.io/`.
|
|
|
|
**Exec format error on Pi** — The postgres image is built locally from `postgis.Dockerfile` using `arm64v8/postgres` as base. Run `podman compose build postgres` to rebuild it.
|
|
|
|
**OSRM exec format error** — `osrm/osrm-backend` is amd64-only. The project uses `osrm-arm64.Dockerfile` to build a native ARM64 image. Run `podman compose build osrm-driving` (builds once, shared by all three OSRM services) or let `05_import_routing_host.sh` build it automatically.
|
|
|
|
---
|
|
|
|
## Attribution
|
|
|
|
- Map data © [OpenStreetMap contributors](https://www.openstreetmap.org/copyright) (ODbL)
|
|
- Routing: [OSRM](https://project-osrm.org/) (BSD-2)
|
|
- Geocoding: [Photon](https://photon.komoot.io/) (Apache 2.0)
|
|
- Tile server: [Martin](https://martin.maplibre.org/) (MIT/Apache 2.0)
|