mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-04-23 00:26:38 +00:00
tiles are cached and reused properly
This commit is contained in:
@@ -75,7 +75,7 @@ public class GoogleMapsDownloaderV2
|
|||||||
Directory.CreateDirectory(_tilesDirectory);
|
Directory.CreateDirectory(_tilesDirectory);
|
||||||
|
|
||||||
var timestamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss");
|
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);
|
var filePath = Path.Combine(_tilesDirectory, fileName);
|
||||||
|
|
||||||
using var httpClient = _httpClientFactory.CreateClient();
|
using var httpClient = _httpClientFactory.CreateClient();
|
||||||
@@ -111,7 +111,12 @@ public class GoogleMapsDownloaderV2
|
|||||||
return metersPerPixel * TILE_SIZE_PIXELS;
|
return metersPerPixel * TILE_SIZE_PIXELS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<DownloadedTileInfoV2>> GetTilesWithMetadataAsync(GeoPoint centerGeoPoint, double radiusM, int zoomLevel, CancellationToken token = default)
|
public async Task<List<DownloadedTileInfoV2>> GetTilesWithMetadataAsync(
|
||||||
|
GeoPoint centerGeoPoint,
|
||||||
|
double radiusM,
|
||||||
|
int zoomLevel,
|
||||||
|
IEnumerable<DataAccess.Models.TileEntity> existingTiles,
|
||||||
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (!ALLOWED_ZOOM_LEVELS.Contains(zoomLevel))
|
if (!ALLOWED_ZOOM_LEVELS.Contains(zoomLevel))
|
||||||
{
|
{
|
||||||
@@ -123,12 +128,12 @@ public class GoogleMapsDownloaderV2
|
|||||||
var (xMin, yMin) = GeoUtils.WorldToTilePos(new GeoPoint(latMax, lonMin), zoomLevel);
|
var (xMin, yMin) = GeoUtils.WorldToTilePos(new GeoPoint(latMax, lonMin), zoomLevel);
|
||||||
var (xMax, yMax) = GeoUtils.WorldToTilePos(new GeoPoint(latMin, lonMax), 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);
|
centerGeoPoint.Lat, centerGeoPoint.Lon, radiusM, zoomLevel);
|
||||||
_logger.LogInformation("Tile range: X=[{XMin}, {XMax}], Y=[{YMin}, {YMax}]", xMin, xMax, yMin, yMax);
|
_logger.LogInformation("Tile range: X=[{XMin}, {XMax}], Y=[{YMin}, {YMax}]", xMin, xMax, yMin, yMax);
|
||||||
|
|
||||||
var sessionToken = await GetSessionToken();
|
|
||||||
var downloadedTiles = new List<DownloadedTileInfoV2>();
|
var downloadedTiles = new List<DownloadedTileInfoV2>();
|
||||||
|
int skippedCount = 0;
|
||||||
|
|
||||||
for (var y = yMin; y <= yMax; y++)
|
for (var y = yMin; y <= yMax; y++)
|
||||||
{
|
{
|
||||||
@@ -137,19 +142,33 @@ public class GoogleMapsDownloaderV2
|
|||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
var tileCenter = GeoUtils.TileToWorldPos(x, y, zoomLevel);
|
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 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
|
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();
|
using var httpClient = _httpClientFactory.CreateClient();
|
||||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(USER_AGENT);
|
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;
|
return downloadedTiles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,72 +46,46 @@ public class TileService : ITileService
|
|||||||
}
|
}
|
||||||
|
|
||||||
var centerPoint = new GeoPoint(latitude, longitude);
|
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);
|
_logger.LogInformation("Downloaded {Count} new 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = new List<TileMetadata>();
|
var result = new List<TileMetadata>();
|
||||||
int reusedCount = 0;
|
int reusedCount = existingTilesList.Count;
|
||||||
int downloadedCount = 0;
|
int downloadedCount = downloadedTiles.Count;
|
||||||
|
|
||||||
|
foreach (var existingTile in existingTilesList)
|
||||||
|
{
|
||||||
|
result.Add(MapToMetadata(existingTile));
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var downloadedTile in downloadedTiles)
|
foreach (var downloadedTile in downloadedTiles)
|
||||||
{
|
{
|
||||||
var existingTile = existingTilesList.FirstOrDefault(t =>
|
var now = DateTime.UtcNow;
|
||||||
Math.Abs(t.Latitude - downloadedTile.CenterLatitude) < 0.0001 &&
|
var tileEntity = new TileEntity
|
||||||
Math.Abs(t.Longitude - downloadedTile.CenterLongitude) < 0.0001 &&
|
|
||||||
t.ZoomLevel == downloadedTile.ZoomLevel);
|
|
||||||
|
|
||||||
if (existingTile != null)
|
|
||||||
{
|
{
|
||||||
reusedCount++;
|
Id = Guid.NewGuid(),
|
||||||
_logger.LogInformation("REUSED tile at ({Lat:F12}, {Lon:F12}) - matched DB tile ID {Id}", downloadedTile.CenterLatitude, downloadedTile.CenterLongitude, existingTile.Id);
|
ZoomLevel = downloadedTile.ZoomLevel,
|
||||||
result.Add(MapToMetadata(existingTile));
|
Latitude = downloadedTile.CenterLatitude,
|
||||||
}
|
Longitude = downloadedTile.CenterLongitude,
|
||||||
else
|
TileSizeMeters = downloadedTile.TileSizeMeters,
|
||||||
{
|
TileSizePixels = 256,
|
||||||
downloadedCount++;
|
ImageType = "jpg",
|
||||||
_logger.LogInformation("NEW tile needed at ({Lat:F12}, {Lon:F12}) - no match in DB", downloadedTile.CenterLatitude, downloadedTile.CenterLongitude);
|
MapsVersion = $"downloaded_{now:yyyy-MM-dd}",
|
||||||
|
Version = currentVersion,
|
||||||
|
FilePath = downloadedTile.FilePath,
|
||||||
|
CreatedAt = now,
|
||||||
|
UpdatedAt = now
|
||||||
|
};
|
||||||
|
|
||||||
var closestTile = existingTilesList
|
await _tileRepository.InsertAsync(tileEntity);
|
||||||
.Select(t => new {
|
_logger.LogInformation("Saved new tile {Id} at ({Lat:F12}, {Lon:F12}) version {Version}", tileEntity.Id, tileEntity.Latitude, tileEntity.Longitude, currentVersion);
|
||||||
Tile = t,
|
result.Add(MapToMetadata(tileEntity));
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
_logger.LogInformation("Tile processing summary: {Reused} reused, {Downloaded} new", reusedCount, downloadedCount);
|
||||||
|
|||||||
Reference in New Issue
Block a user