mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 22:21:15 +00:00
6b373082c8
Phase C of architecture coupling refactor (epic AZ-309). Closes the
last baseline finding (F5 — DataAccess incorrectly documented as
importing Common) and synchronizes the rest of _docs/02_document/
with the post-split project layout from AZ-312/313/314:
- module-layout.md: per-component sections for the three new csprojs
with explicit ProjectReferences and the no-cross-sibling-reference
invariant the split enforces.
- architecture.md: components and internal-communication tables
updated to show calls flow through Common interfaces.
- architecture_compliance_baseline.md: F1..F5 marked Resolved with
task IDs and commit refs; baseline summary now 0 findings.
- diagrams/components.md, components/03_tile_downloader/description.md,
modules/{common_interfaces,services_tile_service,
services_google_maps_downloader,tests_unit}.md updated for the
split, RateLimitException relocation, and new ITileService methods.
Documentation-only batch — no code, no tests, no build changes.
Epic AZ-309 complete (6 tasks across 3 batches).
Co-authored-by: Cursor <cursoragent@cursor.com>
4.2 KiB
4.2 KiB
Module: Services/GoogleMapsDownloaderV2
Purpose
Downloads satellite imagery tiles from Google Maps. Handles session token management, concurrent download throttling, retry logic with exponential backoff, and tile deduplication.
csproj: SatelliteProvider.Services.TileDownloader/GoogleMapsDownloaderV2.cs
Public Interface
GoogleMapsDownloaderV2
- Constructor:
GoogleMapsDownloaderV2(ILogger, IOptions<MapConfig>, IOptions<StorageConfig>, IOptions<ProcessingConfig>, IHttpClientFactory) DownloadSingleTileAsync(double lat, double lon, int zoomLevel, CancellationToken) → Task<DownloadedTileInfoV2>: downloads one tile at specified coordinates. Validates zoom level, creates session token, downloads image, saves to disk.GetTilesWithMetadataAsync(GeoPoint center, double radiusM, int zoomLevel, IEnumerable<TileEntity> existingTiles, CancellationToken) → Task<List<DownloadedTileInfoV2>>: downloads all tiles in a bounding box, skipping those already present inexistingTiles. Manages session token rotation.
DownloadedTileInfoV2 (record)
X,Y(int),ZoomLevel(int),CenterLatitude,CenterLongitude(double),FilePath(string),TileSizeMeters(double)
RateLimitException (exception)
Lives in SatelliteProvider.Common.Exceptions (relocated from this module in epic AZ-309 so RegionProcessing can catch it without acquiring a ProjectReference to TileDownloader). Thrown when Google Maps returns 429 Too Many Requests and retries are exhausted.
Internal Logic
- Allowed zoom levels: 15, 16, 17, 18, 19 — throws
ArgumentExceptionfor others - URL template:
https://mt{server}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}&token={token} - Session tokens: obtained via
https://tile.googleapis.com/v1/createSession?key={apiKey}, rotated everySessionTokenReuseCounttiles (default: 100) - Concurrency control:
SemaphoreSlimlimits parallel downloads toMaxConcurrentDownloads(default: 4) - Deduplication:
ConcurrentDictionary<string, Task<DownloadedTileInfoV2>>(_activeDownloads) prevents duplicate concurrent downloads of the same tile - Retry logic: exponential backoff (1s base, 30s max, 5 retries) for 429 and 5xx errors. Cancellation and auth errors (401, 403) propagate immediately.
- Server selection:
(x + y) % 4distributes requests acrossmt0–mt3; single-tile downloads always usemt0 - Delay between requests: configurable via
ProcessingConfig.DelayBetweenRequestsMs - Tile size calculation:
CalculateTileSizeInMetersuses Earth circumference × cos(latitude) / (2^zoom × 256)
Dependencies
SatelliteProvider.Common.Configs— MapConfig, StorageConfig, ProcessingConfigSatelliteProvider.Common.DTO— GeoPointSatelliteProvider.Common.Exceptions— RateLimitExceptionSatelliteProvider.Common.Utils— GeoUtilsSatelliteProvider.DataAccess.Models— TileEntity (for existingTiles parameter)- NuGet:
Newtonsoft.Json,Microsoft.Extensions.Http,Microsoft.Extensions.Options
Consumers
TileService—GetTilesWithMetadataAsyncandDownloadSingleTileAsync(the API endpoints reach this class only throughITileServicepost AZ-310 / AZ-311)
Data Models
Produces DownloadedTileInfoV2 records; accepts TileEntity for cache checks.
Configuration
| Config | Key | Used For |
|---|---|---|
| MapConfig | ApiKey | Session token requests |
| StorageConfig | TilesDirectory | File save paths |
| ProcessingConfig | MaxConcurrentDownloads | SemaphoreSlim capacity |
| ProcessingConfig | DelayBetweenRequestsMs | Throttle delay |
| ProcessingConfig | SessionTokenReuseCount | Token rotation threshold |
External Integrations
| Integration | Protocol | Details |
|---|---|---|
| Google Maps Tile API | HTTPS | mt*.google.com/vt/lyrs=s for tiles |
| Google Maps Session API | HTTPS | tile.googleapis.com/v1/createSession |
| File system | Local FS | Writes JPEG tiles to StorageConfig.TilesDirectory |
Security
- API key transmitted over HTTPS to Google endpoints
- User-Agent spoofs a Chrome browser to match expected Google Maps client
Tests
No dedicated unit tests (the test file GoogleMapsDownloaderTests.cs contains only a dummy test).