TomTom Routing

This commit is contained in:
Dimitris
2026-02-07 12:56:45 +01:00
parent eac5b56bcb
commit 0d51c6121d
50 changed files with 8923 additions and 5084 deletions

200
CLAUDE.md Normal file
View File

@@ -0,0 +1,200 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is an Android navigation app built with Jetpack Compose that supports multiple routing providers (OSRM, Valhalla, TomTom) and includes Android Auto/Automotive OS integration. The app uses MapLibre for rendering, ObjectBox for local persistence, and Koin for dependency injection.
## Build Commands
```bash
# Build the app (from repository root)
./gradlew :app:assembleDebug
# Build specific flavor
./gradlew :app:assembleDemoDebug
./gradlew :app:assembleFullDebug
# Run tests
./gradlew test
# Run tests for specific module
./gradlew :common:data:test
./gradlew :common:car:test
# Install on device
./gradlew :app:installDebug
# Clean build
./gradlew clean
```
## Module Structure
The project uses a multi-module architecture:
- **app/** - Main Android app with Jetpack Compose UI for phone
- **common/data/** - Core data layer with routing logic, repositories, and data models (shared by all modules)
- **common/car/** - Android Auto/Automotive OS UI implementation
- **automotive/** - Placeholder for future native Automotive OS app
Dependencies flow: `app``common:car``common:data`
## Architecture
### Routing Providers (Pluggable System)
The app supports three routing engines that implement the `NavigationRepository` abstract class:
1. **OsrmRepository** - OSRM routing engine
2. **ValhallaRepository** - Valhalla routing engine
3. **TomTomRepository** - TomTom routing engine
Each provider has a corresponding mapper class (`OsrmRoute`, `ValhallaRoute`, `TomTomRoute`) that converts provider-specific JSON responses to the universal `Route` data model.
**Adding a new routing provider:**
1. Create `NewProviderRepository` extending `NavigationRepository` in `common/data/src/main/java/com/kouros/navigation/data/`
2. Implement `getRoute()` method
3. Create `NewProviderRoute.kt` with `mapToRoute()` function
4. Add provider detection logic in `Route.Builder.route()`
5. Update `NavigationUtils.getViewModel()` to return appropriate ViewModel
### Data Flow
```
User Action (search/select destination)
ViewModel.loadRoute() [LiveData]
NavigationRepository.getRoute() [Selected provider]
*Route.mapToRoute() [Convert to universal Route model]
RouteModel.startNavigation()
RouteModel.updateLocation() [On each location update]
UI observes LiveData and displays current step
```
### Key Classes
**Navigation Logic:**
- `RouteModel.kt` - Core navigation engine (tracks position, calculates distances, manages steps)
- `RouteCarModel.kt` - Extends RouteModel with Android Auto-specific formatting
- `ViewModel.kt` - androidx.ViewModel with LiveData for route, traffic, places, etc.
**Data Models:**
- `Route.kt` - Universal route structure used by all providers
- `Place.kt` - ObjectBox entity for favorites/recent locations
- `StepData.kt` - Display data for current navigation instruction
**Repositories:**
- `NavigationRepository.kt` - Abstract base class for all routing providers
- Also handles Nominatim geocoding search and TomTom traffic incidents
**Android Auto:**
- `NavigationCarAppService.kt` - Entry point for Android Auto/Automotive OS
- `NavigationSession.kt` - Session management
- `NavigationScreen.kt` - Car screen templates with NavigationType state machine
- `SurfaceRenderer.kt` - Handles virtual display and map rendering
### External APIs
| Service | Purpose | Base URL |
|---------|---------|----------|
| OSRM | Routing | `https://kouros-online.de/osrm/route/v1/driving/` |
| Valhalla | Routing | `https://kouros-online.de/valhalla/route` |
| TomTom | Traffic incidents | `https://api.tomtom.com/traffic/services/5/incidentDetails` |
| Nominatim | Geocoding search | `https://kouros-online.de/nominatim/` |
| Overpass | POI & speed limits | OpenStreetMap Overpass API |
## Important Constants
Located in `Constants.kt` (`common/data`):
```kotlin
NEXT_STEP_THRESHOLD = 120.0 m // Distance to show next maneuver
DESTINATION_ARRIVAL_DISTANCE = 40.0 m // Distance to trigger arrival
MAXIMAL_SNAP_CORRECTION = 50.0 m // Max distance to snap to route
MAXIMAL_ROUTE_DEVIATION = 80.0 m // Max deviation before reroute
```
SharedPreferences keys:
- `ROUTING_ENGINE` - Selected provider (0=Valhalla, 1=OSRM, 2=TomTom)
- `DARK_MODE_SETTINGS` - Theme preference
- `AVOID_MOTORWAY`, `AVOID_TOLLWAY` - Route preferences
## Navigation Flow
1. **Route Loading**: User searches via Nominatim → selects place → ViewModel.loadRoute() calls selected repository
2. **Route Parsing**: Provider JSON → mapper converts to universal Route → RouteModel.startNavigation()
3. **Location Tracking**: FusedLocationProviderClient provides updates → RouteModel.updateLocation()
4. **Step Calculation**: findStep() snaps location to nearest waypoint → updates current step
5. **UI Updates**: currentStep() and nextStep() provide display data (instruction, distance, icon, lanes)
6. **Arrival**: When distance < DESTINATION_ARRIVAL_DISTANCE, navigation ends
## Testing Navigation
The app includes mock location support for testing:
- Set `useMock = true` in MainActivity
- Enable "Mock location app" in Android Developer Options
- Choose test mode:
- `type = 1` - Simulate movement along entire route
- `type = 2` - Test specific step range
- `type = 3` - Replay GPX track file
## ObjectBox Database
ObjectBox is configured in `common/data/build.gradle.kts` with the kapt plugin. The database stores:
- Recent destinations (category: "Recent")
- Favorite places (category: "Favorites")
- Imported contacts (category: "Contacts")
Queries use ObjectBox query builder pattern with generated `Place_` property accessors.
## Compose UI Structure
**Phone App:**
- `MainActivity.kt` - Main entry with permission handling and Navigation Compose
- `NavigationScreen.kt` - Turn-by-turn navigation display
- `SearchSheet.kt` / `NavigationSheet.kt` - Bottom sheet content
- `MapView.kt` - MapLibre rendering with camera state management
**Android Auto:**
- Uses CarAppService Screen templates (NavigationTemplate, MessageTemplate, MapWithContentTemplate)
- NavigationType enum controls which template to display (VIEW, NAVIGATION, REROUTE, RECENT, ARRIVAL)
## Build Flavors
Two product flavors with dimension "version":
- **demo** - applicationId: `com.kouros.navigation.demo`
- **full** - applicationId: `com.kouros.navigation.full`
## Common Patterns
**Dependency Injection (Koin):**
```kotlin
single { OsrmRepository() }
viewModel { ViewModel(get()) }
```
**LiveData Observation:**
```kotlin
viewModel.route.observe(this) { routeJson ->
routeModel.startNavigation(routeJson, context)
}
```
**Step Finding Algorithm:**
RouteModel iterates through all step waypoints, calculates distance to current location, and snaps to the nearest waypoint to determine current step index.
## Known Limitations
- Valhalla route mapping is incomplete (search for TODO comments in ValhallaRoute.kt)
- Rerouting logic exists but needs more testing
- Speed limit queries via Overpass API could be optimized for performance
- TomTom implementation uses local JSON file (R.raw.tomom_routing) instead of live API