mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 14:21:14 +00:00
b0fffa6d42
Phase A baseline outputs from /autodev (Steps 1-5): - Problem & solution docs (_docs/00_problem, _docs/01_solution) - Codebase documentation (_docs/02_document) incl. architecture, module-layout, glossary, system-flows, baseline compliance scan - Test specs (blackbox, performance, resilience, security, resource, traceability matrix) - Test task decomposition (_docs/02_tasks/todo): AZ-285..AZ-290 - Testability refactor (_docs/04_refactoring/01-testability-refactoring): - TC-01 Move DownloadedTileInfoV2 + new ExistingTileInfo to Common.DTO - TC-02 Replace dead ISatelliteDownloader API with real signatures - TC-03 GoogleMapsDownloaderV2 implements ISatelliteDownloader - TC-04 TileService depends on ISatelliteDownloader (mockable) - TC-05 DI + endpoints use ISatelliteDownloader - Test runner scripts (scripts/run-tests.sh, run-performance-tests.sh) - Autodev state pointer (_docs/_autodev_state.md) Prepares the codebase for AZ-285..AZ-290 unit/integration test work. Co-authored-by: Cursor <cursoragent@cursor.com>
4.6 KiB
4.6 KiB
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 specifiedGetRouteAsync(Guid id) → Task<RouteResponse?>: retrieves route with all points
RouteProcessingService (BackgroundService)
ExecuteAsync(CancellationToken): polls every 5 seconds for routes withrequest_maps = true AND maps_ready = false, then processes each sequentially
Internal Logic
RouteService.CreateRouteAsync
- Validation: minimum 2 points, region size 100–10000m, name required
- 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
- Persistence: inserts
RouteEntity+ bulk insertsRoutePointEntityvia repository - Geofencing (if
Geofences.Polygonsprovided):- Validates each polygon: non-null corners, non-zero coordinates, valid lat/lon ranges, NW lat > SE lat
- Calls
CreateGeofenceRegionGridto divide the polygon bounding box into a grid of region centers - For each grid point, calls
RegionService.RequestRegionAsyncand links to route as geofence region
- Returns
RouteResponsewith 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
- Checks route needs processing (
RequestMaps && !MapsReady) - Loads route points and linked region IDs (both regular and geofence)
- If no regions linked yet: creates region requests for each route point
- Checks completion status of all linked regions
- When enough regions complete: generates consolidated outputs
- Retries failed regions by creating new region requests
GenerateRouteMapsAsync
- Collects all tile data from completed region CSVs, deduplicating by coordinates
- Generates consolidated route CSV
- If
RequestMaps: stitches all tiles into a single image with:- Geofence polygon borders (yellow rectangles)
- Route point markers (red crosses, 50px arms, 10px thickness)
- If
CreateTilesZip: creates ZIP archive of all tile files with directory structure preserved - Generates route summary text file
- Updates route record (
MapsReady = true, file paths) - 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,IRegionServiceSatelliteProvider.Common.DTO— GeoPoint, RoutePointDto, CreateRouteRequest, RouteResponse, GeofencePolygonSatelliteProvider.Common.Utils.GeoUtilsSatelliteProvider.DataAccess.Models— RouteEntity, RoutePointEntity, RegionEntitySixLabors.ImageSharp— tile stitchingSystem.IO.Compression— ZIP creationIServiceProvider— creates scopedIRegionServiceinstances
Consumers
Program.csAPI endpoints —CreateRouteAsync,GetRouteAsync
Data Models
- Input:
CreateRouteRequest,RoutePoint,GeofencePolygon - Output:
RouteResponse,RoutePointDto, CSV/summary/stitched/zip files - Persistence:
RouteEntity,RoutePointEntity,route_regionsjunction
Configuration
StorageConfig.ReadyDirectory— output directoryStorageConfig.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.