9.6 KiB
Satellite Provider - Agent Documentation
System Overview
This is a .NET 8.0 ASP.NET Web API service that downloads, stores, and manages satellite imagery tiles from Google Maps. The service supports region-based tile requests, route planning with intermediate points, and geofencing capabilities.
Tech Stack
- .NET 8.0 with ASP.NET Core Web API
- PostgreSQL database (via Docker)
- Dapper for data access (ORM)
- DbUp for database migrations
- Serilog for logging
- Swagger/OpenAPI for API documentation
- XUnit and Moq for testing
- ImageSharp for image processing
- Docker for containerization
Architecture
Project Structure
SatelliteProvider.Api/ # Web API layer (Program.cs)
SatelliteProvider.Common/ # DTOs, interfaces, configs, utils
SatelliteProvider.DataAccess/ # Database entities, repositories, migrations
SatelliteProvider.Services/ # Business logic implementations
SatelliteProvider.Tests/ # Unit tests
SatelliteProvider.IntegrationTests/ # Integration tests (console app)
Key Components
-
API Layer (
Program.cs)- Minimal API endpoints
- Dependency injection configuration
- Swagger documentation
- Database migration on startup
-
Services
TileService: Downloads and stores individual tilesRegionService: Manages region requests and processes tiles for regionsRouteService: Creates routes with intermediate points and manages route regionsGoogleMapsDownloaderV2: Handles actual tile downloads from Google MapsRegionProcessingService: Background hosted service for processing region requestsRouteProcessingService: Background hosted service for processing route map requests
-
Data Access
- Repositories:
TileRepository,RegionRepository,RouteRepository - Entities:
TileEntity,RegionEntity,RouteEntity,RoutePointEntity - Migrations in
SatelliteProvider.DataAccess/Migrations/(numbered SQL files)
- Repositories:
-
Async Processing
- Queue-based processing via
IRegionRequestQueue - Background services process requests asynchronously
- Status tracking via database
- Queue-based processing via
Database Schema
Tables
tiles
- Stores downloaded satellite tiles
- Fields: id, zoom_level, latitude, longitude, tile_size_meters, tile_size_pixels, image_type, maps_version, version, file_path, created_at, updated_at
- Composite index on (latitude, longitude, tile_size_meters, zoom_level)
regions
- Stores region requests and their processing status
- Fields: id, latitude, longitude, size_meters, zoom_level, status, stitch_tiles, stitched_image_path, csv_file_path, summary_file_path, tiles_downloaded, tiles_reused, created_at, updated_at
- Status values: "pending", "processing", "completed", "failed"
routes
- Stores route definitions
- Fields: id, name, description, region_size_meters, zoom_level, total_distance_meters, total_points, request_maps, create_tiles_zip, tiles_zip_path, geofence_polygons, created_at, updated_at
route_points
- Stores all points (original and interpolated) for routes
- Fields: id, route_id, sequence_number, latitude, longitude, point_type, segment_index, distance_from_previous, created_at
- Point types: "original", "intermediate"
route_regions
- Junction table linking routes to regions for map tile requests
- Fields: route_id, region_id, inside_geofence, created_at
Migration Strategy
- SQL-based migrations managed by DbUp
- Embedded resources in assembly
- Sequential numbered files (001_, 002_, etc.)
- Runs automatically on application startup
API Endpoints
Tile Management
GET /api/satellite/tiles/latlon- Download single tile by lat/lon and zoom levelGET /api/satellite/tiles/mgrs- Get tiles by MGRS coordinates (stub)
Region Management
POST /api/satellite/request- Request tiles for a region (async processing)GET /api/satellite/region/{id}- Get region status and file paths
Route Management
POST /api/satellite/route- Create route with intermediate pointsGET /api/satellite/route/{id}- Get route information
Image Upload
POST /api/satellite/upload- Upload image with metadata (stub)
Key Patterns and Conventions
Naming
- Database: snake_case (tiles, route_points)
- C# Code: PascalCase for classes, camelCase for parameters
- Entities suffix:
Entity(TileEntity, RegionEntity) - Interfaces prefix:
I(ITileService, IRegionService)
Configuration
Configuration sections in appsettings.json:
MapConfig: Google Maps API settingsStorageConfig: File storage paths (tiles, ready directories)ProcessingConfig: Concurrency and processing limitsConnectionStrings: Database connection
File Storage
- Tiles stored in:
./tiles/{zoomLevel}/{x}/{y}.jpg - CSV outputs:
./ready/region_{id}_ready.csv - Summary files:
./ready/region_{id}_summary.txt - Stitched images:
./ready/region_{id}_stitched.jpg - Route zip files:
./ready/route_{id}_tiles.zip
Async Processing Flow
- Client posts request to API
- Request queued in
IRegionRequestQueue - Background service picks up request
- Downloads/processes tiles
- Updates database status
- Creates output files
Geofencing
- Routes can define multiple polygon geofences
- Each geofence has an array of lat/lon points
- Route regions are marked if they fall inside/outside geofences
- Used to filter which regions to process for map tiles
Route Processing
- Routes broken into segments between original points
- Intermediate points calculated every ~200 meters
- Each point becomes center of a region request
- Distance calculations use Haversine formula
Development Workflow
Running Locally
Start service and dependencies:
docker-compose up --build
Run tests:
docker-compose -f docker-compose.yml -f docker-compose.tests.yml up --build --abort-on-container-exit
Important Notes
-
DO NOT run
dotnet buildordotnet restorevia terminal tools - these commands hang. Ask user to run manually. -
Test verification: Primary method is via Docker Compose with tests.
-
File system structure: Service expects mounted volumes for:
./tiles- tile storage./ready- output files./logs- application logs
-
Database: Auto-creates schema on startup via migrations.
Configuration Values
Development defaults:
- PostgreSQL: localhost:5432, user/pass: postgres/postgres
- API: http://localhost:5100
- Max zoom level: 20
- Default zoom level: 18
- Queue capacity: 1000
- Max concurrent downloads: 4
- Max concurrent regions: 20
Testing
Integration Tests
- Console application in
SatelliteProvider.IntegrationTests - Tests run in Docker container
- Tests cover:
- Tile downloads
- Region requests and processing
- Route creation and point interpolation
- Geofencing logic
- Extended routes with map requests
Test Helpers
RouteTestHelpers.cs provides utilities:
- Waiting for region completion
- Creating test geofence polygons
- Common test data builders
Common Tasks
Adding New Migration
- Create numbered SQL file in
SatelliteProvider.DataAccess/Migrations/ - Set Build Action to
EmbeddedResource - Follow naming:
NNN_DescriptiveName.sql - Migration runs automatically on next startup
Adding New API Endpoint
- Add endpoint mapping in
Program.cs - Add handler method (async preferred)
- Define request/response DTOs
- Add Swagger documentation with
.WithOpenApi() - Update interfaces if adding service methods
Adding New Configuration
- Add config class in
SatelliteProvider.Common/Configs/ - Register in
Program.cswithbuilder.Services.Configure<T>() - Add section to
appsettings.jsonandappsettings.Development.json - Inject via
IOptions<T>in services
Code Style Guidelines
- No comments in code (self-documenting code preferred)
- No excessive logging (only exceptions unless specifically needed)
- Simple, concise solutions preferred
- Minimal code changes related to task
- Avoid renaming database objects without confirmation
- Check for duplicate code before adding new functionality
- Consider environment differences (dev/prod)
Dependencies and Versions
Key packages (all .NET 8.0):
- Microsoft.AspNetCore.OpenApi 8.0.21
- Swashbuckle.AspNetCore 6.6.2
- Serilog.AspNetCore 8.0.3
- SixLabors.ImageSharp 3.1.11
- Newtonsoft.Json 13.0.4
- Dapper (check DataAccess csproj)
- Npgsql (check DataAccess csproj)
- DbUp (check DataAccess csproj)
Outstanding TODOs
From goal.md:
- ✅ Add geo fences (2 regions) - IMPLEMENTED
- ✅ Add parameter to zip resulting tiles, 50 mb max - IMPLEMENTED
- ✅ Implement API to download tile - lat, lon and zoom level - IMPLEMENTED
- ⚠️ Implement parallel tiles fetching from google maps - PARTIAL (session token reuse implemented)
Docker Structure
docker-compose.yml:
- PostgreSQL database service
- SatelliteProvider.Api service
- Shared network
- Volume mounts for tiles, ready, logs
docker-compose.tests.yml:
- Integration tests service
- Depends on api and db services
- Runs and exits after completion
Troubleshooting
Database connection issues:
- Check PostgreSQL container is running
- Verify connection string in appsettings
- Check network connectivity between containers
Tile download failures:
- Check Google Maps API key in MapConfig
- Verify internet connectivity
- Check rate limiting settings
Test failures:
- Ensure all services are up before tests run
- Check logs in
./logs/directory - Verify database migrations completed
Queue processing stuck:
- Check RegionProcessingService and RouteProcessingService are running
- Verify queue capacity not exceeded
- Check database connection for status updates