Files
satellite-provider/_docs/02_document/modules/services_tile_service.md
T
Oleksandr Bezdieniezhnykh 7c37636fdf [AZ-373] Refactor C20: drop MapsVersion from new writes (option a)
- Stop writing "downloaded_YYYY-MM-DD" into tiles.maps_version: new rows
  bind @MapsVersion to NULL via TileService.BuildTileEntity.
- Retain the tiles.maps_version column (coderule.mdc forbids unprompted
  column drops); pre-existing rows keep their values for forensics.
- Remove MapsVersion property from DownloadTileResponse (API wire shape)
  and TileMetadata (internal DTO); OpenAPI schema regenerates from the
  DTO via Swashbuckle.
- Add 3 AC tests in TileServiceTests covering the captured-entity write
  (AC-1) and the DTO/wire-shape removal (AC-2).
- Update integration-test local DTO + console output; refresh docs in
  common_dtos.md, services_tile_service.md, data_model.md.
- Archive AZ-373 task file: todo/ -> done/.

174 unit + 5 smoke pass.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 04:05:40 +03:00

2.9 KiB

Module: Services/TileService

Purpose

Orchestrates tile downloading and persistence. Bridges the downloader (Google Maps) with the tile repository (PostgreSQL), handling in-memory caching, entity creation, and metadata mapping. Single ownership point for all tile read/write business logic — both region-batch and single-tile API endpoints route through this service.

csproj: SatelliteProvider.Services.TileDownloader/TileService.cs

Public Interface

TileService (implements ITileService)

  • DownloadAndStoreTilesAsync(double lat, double lon, double sizeMeters, int zoomLevel, CancellationToken) → Task<List<TileMetadata>>:
    1. Queries existing tiles in the region from the repository (latest per (latitude, longitude, zoom_level, tile_size_meters) post-AZ-357)
    2. Calls ISatelliteDownloader.GetTilesWithMetadataAsync with existing tiles to skip
    3. Creates TileEntity for each newly downloaded tile and inserts via repository (upsert)
    4. Returns combined list of existing + new tile metadata
  • GetTileAsync(Guid id) → Task<TileMetadata?>: single tile lookup
  • GetTilesByRegionAsync(double lat, double lon, double sizeMeters, int zoomLevel) → Task<IEnumerable<TileMetadata>>: query tiles in a region
  • GetOrDownloadTileAsync(int z, int x, int y, CancellationToken) → Task<TileBytes> (AZ-310): cache → repository → downloader fallback for single Z/X/Y serving
  • DownloadAndStoreSingleTileAsync(double latitude, double longitude, int zoomLevel, CancellationToken) → Task<TileMetadata> (AZ-311): download one tile by lat/lon, persist, return metadata

Internal Logic

  • New rows write Version = null and MapsVersion = null (post-AZ-357 / AZ-373); the version and maps_version columns are retained for backward compatibility with pre-existing rows
  • MapToMetadata(TileEntity) → TileMetadata: entity-to-DTO mapping (static helper); MapsVersion is no longer projected onto TileMetadata / DownloadTileResponse
  • TileSizePixels sourced from MapConfig.TileSizePixels (default 256, post-AZ-371); image type fixed at "jpg"
  • IMemoryCache keyed by (z, x, y) with 1h absolute / 30min sliding expiration; populated on first hit and on downloader fallback

Dependencies

  • ISatelliteDownloader (resolved via DI; concrete is GoogleMapsDownloaderV2)
  • ITileRepository
  • IMemoryCache (registered by AddTileDownloader())
  • SatelliteProvider.Common.DTO — GeoPoint, TileMetadata, TileBytes
  • SatelliteProvider.DataAccess.Models — TileEntity

Consumers

  • RegionService.ProcessRegionAsync — downloads and retrieves tiles for a region

Data Models

Transforms between TileEntity (persistence) and TileMetadata (DTO).

Configuration

None directly; relies on GoogleMapsDownloaderV2's configuration.

External Integrations

Indirect: Google Maps (via downloader), PostgreSQL (via repository).

Security

None.

Tests

No dedicated tests.