diff --git a/SatelliteProvider.Services/GoogleMapsDownloaderV2.cs b/SatelliteProvider.Services/GoogleMapsDownloaderV2.cs index 02c1b09..e8f0d0a 100644 --- a/SatelliteProvider.Services/GoogleMapsDownloaderV2.cs +++ b/SatelliteProvider.Services/GoogleMapsDownloaderV2.cs @@ -75,7 +75,7 @@ public class GoogleMapsDownloaderV2 Directory.CreateDirectory(_tilesDirectory); var timestamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss"); - var fileName = $"raw_tile_{zoomLevel}_{tileX}_{tileY}_{timestamp}.jpg"; + var fileName = $"tile_{zoomLevel}_{tileX}_{tileY}_{timestamp}.jpg"; var filePath = Path.Combine(_tilesDirectory, fileName); using var httpClient = _httpClientFactory.CreateClient(); @@ -111,7 +111,12 @@ public class GoogleMapsDownloaderV2 return metersPerPixel * TILE_SIZE_PIXELS; } - public async Task> GetTilesWithMetadataAsync(GeoPoint centerGeoPoint, double radiusM, int zoomLevel, CancellationToken token = default) + public async Task> GetTilesWithMetadataAsync( + GeoPoint centerGeoPoint, + double radiusM, + int zoomLevel, + IEnumerable existingTiles, + CancellationToken token = default) { if (!ALLOWED_ZOOM_LEVELS.Contains(zoomLevel)) { @@ -123,12 +128,12 @@ public class GoogleMapsDownloaderV2 var (xMin, yMin) = GeoUtils.WorldToTilePos(new GeoPoint(latMax, lonMin), zoomLevel); var (xMax, yMax) = GeoUtils.WorldToTilePos(new GeoPoint(latMin, lonMax), zoomLevel); - _logger.LogInformation("Downloading tiles for region: center=({Lat}, {Lon}), radius={Radius}m, zoom={Zoom}", + _logger.LogInformation("Checking tiles for region: center=({Lat}, {Lon}), radius={Radius}m, zoom={Zoom}", centerGeoPoint.Lat, centerGeoPoint.Lon, radiusM, zoomLevel); _logger.LogInformation("Tile range: X=[{XMin}, {XMax}], Y=[{YMin}, {YMax}]", xMin, xMax, yMin, yMax); - var sessionToken = await GetSessionToken(); var downloadedTiles = new List(); + int skippedCount = 0; for (var y = yMin; y <= yMax; y++) { @@ -137,19 +142,33 @@ public class GoogleMapsDownloaderV2 token.ThrowIfCancellationRequested(); var tileCenter = GeoUtils.TileToWorldPos(x, y, zoomLevel); + + var existingTile = existingTiles.FirstOrDefault(t => + Math.Abs(t.Latitude - tileCenter.Lat) < 0.0001 && + Math.Abs(t.Longitude - tileCenter.Lon) < 0.0001 && + t.ZoomLevel == zoomLevel); + + if (existingTile != null) + { + skippedCount++; + _logger.LogInformation("Skipping tile ({X}, {Y}) - already exists at {FilePath}", x, y, existingTile.FilePath); + continue; + } + var tileSizeMeters = CalculateTileSizeInMeters(zoomLevel, tileCenter.Lat); - var server = (x + y) % 4; - var url = string.Format(TILE_URL_TEMPLATE, server, x, y, zoomLevel, sessionToken); - - Directory.CreateDirectory(_tilesDirectory); - - var timestamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss"); - var fileName = $"tile_{zoomLevel}_{x}_{y}_{timestamp}.jpg"; - var filePath = Path.Combine(_tilesDirectory, fileName); - try { + var sessionToken = await GetSessionToken(); + var server = (x + y) % 4; + var url = string.Format(TILE_URL_TEMPLATE, server, x, y, zoomLevel, sessionToken); + + Directory.CreateDirectory(_tilesDirectory); + + var timestamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss"); + var fileName = $"tile_{zoomLevel}_{x}_{y}_{timestamp}.jpg"; + var filePath = Path.Combine(_tilesDirectory, fileName); + using var httpClient = _httpClientFactory.CreateClient(); httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(USER_AGENT); @@ -173,7 +192,7 @@ public class GoogleMapsDownloaderV2 } } - _logger.LogInformation("Downloaded {Count} tiles for region", downloadedTiles.Count); + _logger.LogInformation("Downloaded {Count} new tiles, skipped {Skipped} existing tiles", downloadedTiles.Count, skippedCount); return downloadedTiles; } } diff --git a/SatelliteProvider.Services/TileService.cs b/SatelliteProvider.Services/TileService.cs index dc4ff62..a1fcef0 100644 --- a/SatelliteProvider.Services/TileService.cs +++ b/SatelliteProvider.Services/TileService.cs @@ -46,72 +46,46 @@ public class TileService : ITileService } var centerPoint = new GeoPoint(latitude, longitude); - var downloadedTiles = await _downloader.GetTilesWithMetadataAsync(centerPoint, sizeMeters / 2, zoomLevel, cancellationToken); + var downloadedTiles = await _downloader.GetTilesWithMetadataAsync( + centerPoint, + sizeMeters / 2, + zoomLevel, + existingTilesList, + cancellationToken); - _logger.LogInformation("Downloaded {Count} tiles from Google:", downloadedTiles.Count); - foreach (var dt in downloadedTiles) - { - _logger.LogInformation(" Downloaded: Lat={Lat:F12}, Lon={Lon:F12}, Zoom={Zoom}", dt.CenterLatitude, dt.CenterLongitude, dt.ZoomLevel); - } + _logger.LogInformation("Downloaded {Count} new tiles from Google", downloadedTiles.Count); var result = new List(); - int reusedCount = 0; - int downloadedCount = 0; + int reusedCount = existingTilesList.Count; + int downloadedCount = downloadedTiles.Count; + + foreach (var existingTile in existingTilesList) + { + result.Add(MapToMetadata(existingTile)); + } foreach (var downloadedTile in downloadedTiles) { - var existingTile = existingTilesList.FirstOrDefault(t => - Math.Abs(t.Latitude - downloadedTile.CenterLatitude) < 0.0001 && - Math.Abs(t.Longitude - downloadedTile.CenterLongitude) < 0.0001 && - t.ZoomLevel == downloadedTile.ZoomLevel); - - if (existingTile != null) + var now = DateTime.UtcNow; + var tileEntity = new TileEntity { - reusedCount++; - _logger.LogInformation("REUSED tile at ({Lat:F12}, {Lon:F12}) - matched DB tile ID {Id}", downloadedTile.CenterLatitude, downloadedTile.CenterLongitude, existingTile.Id); - result.Add(MapToMetadata(existingTile)); - } - else - { - downloadedCount++; - _logger.LogInformation("NEW tile needed at ({Lat:F12}, {Lon:F12}) - no match in DB", downloadedTile.CenterLatitude, downloadedTile.CenterLongitude); - - var closestTile = existingTilesList - .Select(t => new { - Tile = t, - LatDiff = Math.Abs(t.Latitude - downloadedTile.CenterLatitude), - LonDiff = Math.Abs(t.Longitude - downloadedTile.CenterLongitude) - }) - .OrderBy(x => x.LatDiff + x.LonDiff) - .FirstOrDefault(); - - if (closestTile != null) - { - _logger.LogInformation(" Closest DB tile: Lat={Lat:F12} (diff={LatDiff:F12}), Lon={Lon:F12} (diff={LonDiff:F12})", - closestTile.Tile.Latitude, closestTile.LatDiff, closestTile.Tile.Longitude, closestTile.LonDiff); - } - - var now = DateTime.UtcNow; - var tileEntity = new TileEntity - { - Id = Guid.NewGuid(), - ZoomLevel = downloadedTile.ZoomLevel, - Latitude = downloadedTile.CenterLatitude, - Longitude = downloadedTile.CenterLongitude, - TileSizeMeters = downloadedTile.TileSizeMeters, - TileSizePixels = 256, - ImageType = "jpg", - MapsVersion = $"downloaded_{now:yyyy-MM-dd}", - Version = currentVersion, - FilePath = downloadedTile.FilePath, - CreatedAt = now, - UpdatedAt = now - }; + Id = Guid.NewGuid(), + ZoomLevel = downloadedTile.ZoomLevel, + Latitude = downloadedTile.CenterLatitude, + Longitude = downloadedTile.CenterLongitude, + TileSizeMeters = downloadedTile.TileSizeMeters, + TileSizePixels = 256, + ImageType = "jpg", + MapsVersion = $"downloaded_{now:yyyy-MM-dd}", + Version = currentVersion, + FilePath = downloadedTile.FilePath, + CreatedAt = now, + UpdatedAt = now + }; - await _tileRepository.InsertAsync(tileEntity); - _logger.LogInformation("Saved new tile {Id} at ({Lat:F12}, {Lon:F12}) version {Version}", tileEntity.Id, tileEntity.Latitude, tileEntity.Longitude, currentVersion); - result.Add(MapToMetadata(tileEntity)); - } + await _tileRepository.InsertAsync(tileEntity); + _logger.LogInformation("Saved new tile {Id} at ({Lat:F12}, {Lon:F12}) version {Version}", tileEntity.Id, tileEntity.Latitude, tileEntity.Longitude, currentVersion); + result.Add(MapToMetadata(tileEntity)); } _logger.LogInformation("Tile processing summary: {Reused} reused, {Downloaded} new", reusedCount, downloadedCount);