canvas-website/OPEN_MAPPING_PROJECT.md

337 lines
12 KiB
Markdown

# Open Mapping Project
## Overview
**Open Mapping** is a collaborative route planning module for canvas-website that provides advanced mapping functionality beyond traditional tools like Google Maps. Built on open-source foundations (OpenStreetMap, OSRM, Valhalla, MapLibre), it integrates seamlessly with the tldraw canvas environment.
## Vision
Create a "living map" that exists as a layer within the collaborative canvas, enabling teams to:
- Plan multi-destination trips with optimized routing
- Compare alternative routes visually
- Share and collaborate on itineraries in real-time
- Track budgets and schedules alongside geographic planning
- Work offline with cached map data
## Core Features
### 1. Map Canvas Integration
- MapLibre GL JS as the rendering engine
- Seamless embedding within tldraw canvas
- Pan/zoom synchronized with canvas viewport
- Map shapes that can be annotated like any canvas object
### 2. Multi-Path Routing
- Support for multiple routing profiles (car, bike, foot, transit)
- Side-by-side route comparison
- Alternative route suggestions
- Turn-by-turn directions with elevation profiles
### 3. Collaborative Editing
- Real-time waypoint sharing via Y.js/CRDT
- Cursor presence on map (see where collaborators are looking)
- Concurrent route editing without conflicts
- Share links for view-only or edit access
### 4. Layer Management
- Multiple basemap options (OSM, satellite, terrain)
- Custom overlay layers (GeoJSON import)
- Route-specific layers (cycling, hiking trails)
- POI layers with filtering
### 5. Calendar Integration
- Attach time windows to waypoints
- Visualize itinerary timeline
- Sync with external calendars (iCal export)
- Travel time estimation between events
### 6. Budget Tracking
- Cost estimates per route (fuel, tolls)
- Per-waypoint expense tracking
- Trip budget aggregation
- Currency conversion
### 7. Offline Capability
- Tile caching for offline use
- Route pre-computation and storage
- PWA support for mobile
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ Canvas Website │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ tldraw Canvas │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Open Mapping Layer │ │ │
│ │ │ ┌─────────────┐ ┌─────────────────────────┐ │ │ │
│ │ │ │ MapLibre GL │ │ Route Visualization │ │ │ │
│ │ │ │ (basemap) │ │ (polylines/markers) │ │ │ │
│ │ │ └─────────────┘ └─────────────────────────┘ │ │ │
│ │ │ ┌─────────────┐ ┌─────────────────────────┐ │ │ │
│ │ │ │ Layers │ │ Collaboration │ │ │ │
│ │ │ │ Panel │ │ Cursors/Presence │ │ │ │
│ │ │ └─────────────┘ └─────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌───────────┐ ┌─────────────────┐
│ Routing API │ │ Y.js │ │ Tile Server │
│ (OSRM/Valhalla)│ │ (collab) │ │ (MapLibre) │
└─────────────────┘ └───────────┘ └─────────────────┘
┌─────────────────┐
│ VROOM │
│ (optimization) │
└─────────────────┘
```
## Technology Stack
| Component | Technology | License | Notes |
|-----------|------------|---------|-------|
| Map Renderer | MapLibre GL JS | BSD-3 | Open-source Mapbox fork |
| Base Maps | OpenStreetMap | ODbL | Free, community-maintained |
| Routing Engine | OSRM / Valhalla | BSD-2 / MIT | Self-hosted, fast |
| Multi-Route | GraphHopper | Apache 2.0 | Custom profiles |
| Optimization | VROOM | BSD | TSP/VRP solver |
| Collaboration | Y.js | MIT | CRDT-based sync |
| State Management | Jotai | MIT | Already in use |
| Tile Caching | Service Worker | - | PWA standard |
## Routing Provider Comparison
| Feature | OSRM | Valhalla | GraphHopper | ORS |
|---------|------|----------|-------------|-----|
| Speed | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| Profiles | 3 | 6+ | 10+ | 8+ |
| Alternatives | ✅ | ✅ | ✅ | ✅ |
| Isochrones | ❌ | ✅ | ✅ | ✅ |
| Transit | ❌ | ✅ | ⚠️ | ❌ |
| License | BSD-2 | MIT | Apache | GPL |
| Docker Ready | ✅ | ✅ | ✅ | ✅ |
**Recommendation**: Start with OSRM for simplicity and speed, add Valhalla for transit/isochrones.
## Implementation Phases
### Phase 1: Foundation (MVP)
- [ ] MapLibre GL JS integration with tldraw
- [ ] Basic waypoint placement and rendering
- [ ] Single-route calculation via OSRM
- [ ] Route polyline display
- [ ] Simple UI for profile selection (car/bike/foot)
### Phase 2: Multi-Route & Comparison
- [ ] Alternative routes visualization
- [ ] Route comparison panel (distance, time, cost)
- [ ] Profile-based coloring
- [ ] Elevation profile display
- [ ] Drag-to-reroute functionality
### Phase 3: Collaboration
- [ ] Y.js integration for real-time sync
- [ ] Cursor presence on map
- [ ] Concurrent waypoint editing
- [ ] Share link generation
- [ ] Permission management (view/edit)
### Phase 4: Layers & Customization
- [ ] Layer panel UI
- [ ] Multiple basemap options
- [ ] Overlay layer support (GeoJSON)
- [ ] Custom marker icons
- [ ] Style customization
### Phase 5: Calendar & Budget
- [ ] Time window attachment to waypoints
- [ ] Itinerary timeline view
- [ ] Budget tracking per waypoint
- [ ] Cost estimation for routes
- [ ] iCal export
### Phase 6: Optimization & Offline
- [ ] VROOM integration for TSP/VRP
- [ ] Multi-stop optimization
- [ ] Tile caching via Service Worker
- [ ] Offline route storage
- [ ] PWA manifest
## File Structure
```
src/open-mapping/
├── index.ts # Public exports
├── types/
│ └── index.ts # TypeScript definitions
├── components/
│ ├── index.ts
│ ├── MapCanvas.tsx # Main map component
│ ├── RouteLayer.tsx # Route polyline rendering
│ ├── WaypointMarker.tsx # Interactive markers
│ └── LayerPanel.tsx # Layer management UI
├── hooks/
│ ├── index.ts
│ ├── useMapInstance.ts # MapLibre instance management
│ ├── useRouting.ts # Route calculation
│ ├── useCollaboration.ts # Y.js sync
│ └── useLayers.ts # Layer state
├── services/
│ ├── index.ts
│ ├── RoutingService.ts # Multi-provider routing
│ ├── TileService.ts # Tile management/caching
│ └── OptimizationService.ts # VROOM integration
└── utils/
└── index.ts # Helper functions
```
## Docker Deployment
The open-mapping backend services will be deployed to `/opt/apps/open-mapping/` on Netcup RS 8000.
### Services
1. **OSRM** - Primary routing engine
- Pre-processed OSM data for region (Europe/Germany)
- HTTP API on internal port
2. **Valhalla** (optional) - Extended routing
- Transit integration via GTFS
- Isochrone calculations
3. **Tile Server** - Vector tiles
- OpenMapTiles-based
- Serves tiles for offline caching
4. **VROOM** - Route optimization
- Solves complex multi-stop problems
- REST API
### Docker Compose Preview
```yaml
version: '3.8'
services:
osrm:
image: osrm/osrm-backend:latest
volumes:
- ./data/osrm:/data
command: osrm-routed --algorithm mld /data/region.osrm
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.osrm.rule=Host(`routing.jeffemmett.com`)"
tileserver:
image: maptiler/tileserver-gl:latest
volumes:
- ./data/tiles:/data
networks:
- traefik-public
labels:
- "traefik.enable=true"
- "traefik.http.routers.tiles.rule=Host(`tiles.jeffemmett.com`)"
networks:
traefik-public:
external: true
```
## Data Requirements
### OSM Data
- Download PBF files from Geofabrik
- For Europe: ~30GB (full), ~5GB (Germany only)
- Pre-process with `osrm-extract`, `osrm-partition`, `osrm-customize`
### Vector Tiles
- Generate from OSM data using OpenMapTiles
- Or download pre-built from MapTiler
- Storage: ~50GB for detailed regional tiles
## API Endpoints
### Routing API (`/api/route`)
```typescript
POST /api/route
{
waypoints: [{ lat: number, lng: number }],
profile: 'car' | 'bike' | 'foot',
alternatives: number,
}
Response: Route[]
```
### Optimization API (`/api/optimize`)
```typescript
POST /api/optimize
{
waypoints: Waypoint[],
constraints: OptimizationConstraints,
}
Response: OptimizationResult
```
### Isochrone API (`/api/isochrone`)
```typescript
POST /api/isochrone
{
center: { lat: number, lng: number },
minutes: number[],
profile: string,
}
Response: GeoJSON.FeatureCollection
```
## Dependencies to Add
```json
{
"dependencies": {
"maplibre-gl": "^4.x",
"@maplibre/maplibre-gl-geocoder": "^1.x",
"geojson": "^0.5.x"
}
}
```
## Related Projects & Inspiration
- **Mapus** - Real-time collaborative mapping
- **uMap** - OpenStreetMap-based map maker
- **Organic Maps** - Offline-first navigation
- **Komoot** - Outdoor route planning
- **Rome2Rio** - Multi-modal journey planner
- **Wandrer.earth** - Exploration tracking
## Success Metrics
1. **Route Calculation** < 500ms for typical queries
2. **Collaboration Sync** < 100ms latency
3. **Offline Coverage** Entire planned region cached
4. **Budget Accuracy** ±15% for fuel estimates
5. **User Satisfaction** Preferred over Google Maps for trip planning
## Open Questions
1. Should we integrate transit data (GTFS feeds)?
2. What regions should we pre-process initially?
3. How to handle very long routes (cross-country)?
4. Should routes be persisted separately from canvas?
5. Integration with existing canvas tools (markdown notes on waypoints)?
## References
- [OSRM Documentation](https://project-osrm.org/docs/v5.24.0/api/)
- [Valhalla API](https://valhalla.github.io/valhalla/api/)
- [MapLibre GL JS](https://maplibre.org/maplibre-gl-js-docs/api/)
- [VROOM Project](http://vroom-project.org/)
- [Y.js Documentation](https://docs.yjs.dev/)