# Module: Services/RouteService + RouteProcessingService

## Purpose
Route management and asynchronous map generation. `RouteService` handles route creation with intermediate point interpolation and geofencing. `RouteProcessingService` is a background service that polls for routes needing map generation and produces stitched images, CSVs, summaries, and ZIP archives.

## Public Interface

### RouteService (implements IRouteService)
- `CreateRouteAsync(CreateRouteRequest) → Task<RouteResponse>`: validates input, computes intermediate points, persists route + points, creates geofence regions if specified
- `GetRouteAsync(Guid id) → Task<RouteResponse?>`: retrieves route with all points

### RouteProcessingService (BackgroundService)
- `ExecuteAsync(CancellationToken)`: polls every 5 seconds for routes with `request_maps = true AND maps_ready = false`, then processes each sequentially

## Internal Logic

### RouteService.CreateRouteAsync
1. **Validation**: minimum 2 points, region size 100–10000m, name required
2. **Point interpolation**: for each segment between consecutive input points:
   - First point typed as "start", last as "end", middle as "action"
   - Calls `GeoUtils.CalculateIntermediatePoints(start, end, 200m)` to generate intermediate points
   - Each intermediate point gets `PointType = "intermediate"`
   - Distance from previous point is computed via `GeoUtils.CalculateDistance`
3. **Persistence**: inserts `RouteEntity` + bulk inserts `RoutePointEntity` via repository
4. **Geofencing** (if `Geofences.Polygons` provided):
   - Validates each polygon: non-null corners, non-zero coordinates, valid lat/lon ranges, NW lat > SE lat
   - Calls `CreateGeofenceRegionGrid` to divide the polygon bounding box into a grid of region centers
   - For each grid point, calls `RegionService.RequestRegionAsync` and links to route as geofence region
5. Returns `RouteResponse` with all computed points

### CreateGeofenceRegionGrid
Divides a bounding box (NW → SE) into a regular grid where each cell is `regionSizeMeters` wide. Uses lat/lon step sizes derived from physical distance calculations. Returns a list of center points.

### RouteProcessingService.ProcessRouteSequentiallyAsync
1. Checks route needs processing (`RequestMaps && !MapsReady`)
2. Loads route points and linked region IDs (both regular and geofence)
3. If no regions linked yet: creates region requests for each route point
4. Checks completion status of all linked regions
5. When enough regions complete: generates consolidated outputs
6. Retries failed regions by creating new region requests

### GenerateRouteMapsAsync
1. Collects all tile data from completed region CSVs, deduplicating by coordinates
2. Generates consolidated route CSV
3. If `RequestMaps`: stitches all tiles into a single image with:
   - Geofence polygon borders (yellow rectangles)
   - Route point markers (red crosses, 50px arms, 10px thickness)
4. If `CreateTilesZip`: creates ZIP archive of all tile files with directory structure preserved
5. Generates route summary text file
6. Updates route record (`MapsReady = true`, file paths)
7. Cleans up individual region CSV/summary/stitched files

### Tile Stitching (route-level)
- Extracts tile X/Y from filenames (`tile_{z}_{x}_{y}_{ts}.jpg`)
- Creates grid-sized image, places tiles, draws geofence borders and route points
- Background color: black (for missing tiles)

### TileInfo (helper class)
Simple data holder: `Latitude`, `Longitude`, `FilePath`.

## Dependencies
- `IRouteRepository`, `IRegionRepository`, `IRegionService`
- `SatelliteProvider.Common.DTO` — GeoPoint, RoutePointDto, CreateRouteRequest, RouteResponse, GeofencePolygon
- `SatelliteProvider.Common.Utils.GeoUtils`
- `SatelliteProvider.DataAccess.Models` — RouteEntity, RoutePointEntity, RegionEntity
- `SixLabors.ImageSharp` — tile stitching
- `System.IO.Compression` — ZIP creation
- `IServiceProvider` — creates scoped `IRegionService` instances

## Consumers
- `Program.cs` API endpoints — `CreateRouteAsync`, `GetRouteAsync`

## Data Models
- Input: `CreateRouteRequest`, `RoutePoint`, `GeofencePolygon`
- Output: `RouteResponse`, `RoutePointDto`, CSV/summary/stitched/zip files
- Persistence: `RouteEntity`, `RoutePointEntity`, `route_regions` junction

## Configuration
- `StorageConfig.ReadyDirectory` — output directory
- `StorageConfig.TilesDirectory` — used for ZIP relative paths

## External Integrations
- PostgreSQL (via repositories)
- File system (CSV, summary, stitched image, ZIP in `./ready/`)
- Region processing pipeline (for tile downloading)

## Security
None.

## Tests
Integration tests in `BasicRouteTests.cs`, `ComplexRouteTests.cs`, `ExtendedRouteTests.cs`.
