# 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`: validates input, computes intermediate points, persists route + points, creates geofence regions if specified - `GetRouteAsync(Guid id) → Task`: 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`.