feat(geo-map): add live traffic visualization and traffic-aware routing with pluggable providers and UI integration

This commit is contained in:
2026-02-05 15:07:33 +00:00
parent 1a0fceadc0
commit df690dc329
22 changed files with 2238 additions and 181 deletions

View File

@@ -23,6 +23,9 @@ Geospatial web components library using MapLibre GL JS for map rendering and ter
| `showSearch` | `boolean` | `false` | Show address search input |
| `showNavigation` | `boolean` | `false` | Show A-to-B navigation panel |
| `navigationMode` | `'driving' \| 'walking' \| 'cycling'` | `'driving'` | Transport mode for routing |
| `showTraffic` | `boolean` | `false` | Enable traffic layer visualization |
| `trafficApiKey` | `string` | `''` | HERE API key for traffic data |
| `trafficProvider` | `ITrafficProvider` | `null` | Custom traffic data provider |
### Drawing Tools (TDrawTool)
- `point` - Draw points
@@ -41,6 +44,7 @@ Geospatial web components library using MapLibre GL JS for map rendering and ter
- `draw-finish` - Fired when a shape is completed
- `address-selected` - Fired when a search result is selected
- `route-calculated` - Fired when a navigation route is calculated (includes route, startPoint, endPoint, mode)
- `traffic-updated` - Fired when traffic data is refreshed
### Public Methods
- `getFeatures()` - Get all drawn features
@@ -57,11 +61,19 @@ Geospatial web components library using MapLibre GL JS for map rendering and ter
- `setNavigationStart(coords, address?)` - Set navigation start point
- `setNavigationEnd(coords, address?)` - Set navigation end point
- `clearNavigation()` - Clear all navigation state
- `enableTraffic()` - Enable traffic visualization
- `disableTraffic()` - Disable traffic visualization
- `toggleTraffic()` - Toggle traffic visualization
- `refreshTraffic()` - Refresh traffic data
- `setTrafficProvider(provider)` - Set custom traffic provider
- `supportsTrafficRouting()` - Check if traffic-aware routing is available
- `getTrafficController()` - Get the TrafficController instance
### Context Menu
Right-click on the map to access a context menu with the following options:
- **Drag to Draw** - Toggle between drag mode (click-drag for circles/rectangles) and two-click mode
- **Globe View** - Toggle between globe (3D sphere) and Mercator (flat) projection
- **Show Traffic** - Toggle traffic layer (requires configured traffic provider)
- **Clear All Features** - Remove all drawn features from the map
- **Fit to Features** - Zoom and pan to show all drawn features
@@ -71,6 +83,45 @@ The navigation panel (`showNavigation={true}`) provides A-to-B routing using OSR
- **Point selection**: Type an address or click on the map
- **Route display**: Blue line overlay with turn-by-turn directions
- **API**: Uses free OSRM API (https://router.project-osrm.org) with fair-use rate limit
- **Traffic-aware routing**: When a traffic provider is configured, shows duration with/without traffic
### Traffic Feature
Live traffic visualization with pluggable provider architecture:
#### HERE Traffic Provider (Recommended)
```typescript
// Using API key property
<dees-geo-map trafficApiKey="YOUR_HERE_API_KEY" showTraffic></dees-geo-map>
// Or programmatically
import { HereTrafficProvider } from '@design.estate/dees-catalog-geo';
const map = document.querySelector('dees-geo-map');
const provider = new HereTrafficProvider();
provider.configure({ apiKey: 'YOUR_HERE_API_KEY' });
map.setTrafficProvider(provider);
map.enableTraffic();
```
**Free Tier**: 250,000 transactions/month (no credit card required)
Sign up at: https://developer.here.com
#### Valhalla Traffic Provider (Self-Hosted)
```typescript
import { ValhallaTrafficProvider } from '@design.estate/dees-catalog-geo';
const provider = new ValhallaTrafficProvider();
provider.configure({
serverUrl: 'https://your-valhalla-server.com',
trafficDataUrl: 'https://your-traffic-data-endpoint.com' // optional
});
map.setTrafficProvider(provider);
```
#### Traffic Color Legend
- 🟢 Green - Free flow
- 🟡 Yellow - Light congestion
- 🟠 Orange - Moderate congestion
- 🔴 Red - Heavy congestion
- 🔴 Dark Red - Severe/stopped
## Development
- `pnpm install` - Install dependencies
@@ -90,11 +141,13 @@ ts_web/
├── index.ts
└── dees-geo-map/
├── index.ts # Exports main + modules
├── dees-geo-map.ts # Main component (~550 lines)
├── dees-geo-map.ts # Main component
├── dees-geo-map.demo.ts # Demo function
├── geo-map.icons.ts # Icon SVG definitions (~60 lines)
├── geo-map.search.ts # SearchController class (~180 lines)
── geo-map.navigation.ts # NavigationController class (~530 lines)
├── geo-map.icons.ts # Icon SVG definitions
├── geo-map.search.ts # SearchController class
── geo-map.navigation.ts # NavigationController class
├── geo-map.traffic.ts # TrafficController class
└── geo-map.traffic.providers.ts # Traffic provider implementations
```
## Modular Architecture
@@ -117,6 +170,18 @@ Contains all SVG icon definitions as a `GEO_MAP_ICONS` record and a `renderIcon(
- Map click mode for point selection
- Turn-by-turn directions rendering
- Route overlay on map
- Traffic-aware routing integration (shows congestion level and delay)
### geo-map.traffic.ts
`TrafficController` class for live traffic visualization:
- Traffic layer rendering with color-coded congestion
- Auto-refresh logic with configurable interval
- Supports pluggable traffic providers
### geo-map.traffic.providers.ts
Traffic data provider implementations:
- `HereTrafficProvider` - HERE Traffic API v7 (freemium)
- `ValhallaTrafficProvider` - Self-hosted Valhalla server
### Usage of Controllers
```typescript
@@ -142,6 +207,37 @@ const nav = new NavigationController({
- Terra-draw requires the separate maplibre-gl-adapter package
- The component uses Shadow DOM for style encapsulation
### UI Layout
The component uses a header toolbar above the map for a cleaner layout:
```
┌──────────────────────────────────────────────────────────────────────┐
│ HEADER TOOLBAR │
│ [Draw Tools] | [Search Bar] | [Nav Toggle] [Traffic] [Zoom +/-] │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ [Navigation] MAP │
│ (toggleable) │
│ │
│ [Traffic Legend] [Feature Count] │
└──────────────────────────────────────────────────────────────────────┘
```
**Header Toolbar Sections:**
- **Left**: Draw tools (Point, Line, Polygon, Rectangle, Circle, Freehand, Select, Clear)
- **Center**: Search bar (expandable width)
- **Right**: Navigation toggle, Traffic toggle, Zoom in/out buttons
**Map Overlays:**
- Navigation panel: Toggleable overlay on top-left of map
- Traffic legend: Bottom-left overlay (when traffic enabled)
- Feature count: Bottom-left overlay (when features exist)
**Z-index hierarchy:**
- `z-index: 20` - Dropdowns (search results, nav search results)
- `z-index: 5` - Map overlays (navigation panel, traffic legend, feature count)
### Shadow DOM & Terra-Draw Drawing Fix
Terra-draw's event listeners normally intercept map events through MapLibre's canvas element. In Shadow DOM contexts, these events are scoped locally and don't propagate correctly, causing terra-draw handlers to fail while MapLibre's drag handlers continue working.