337 lines
12 KiB
Markdown
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/)
|