201 lines
7.1 KiB
Markdown
201 lines
7.1 KiB
Markdown
# 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
|