mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-23 14:31:15 +00:00
275ee1b554
- Introduced new TileProvision settings in appsettings.json, including MaxTilesPerBatch and ProgressEmitIntervalSeconds. - Configured TileProvisionConfig in Program.cs to bind the new settings. - Added gRPC service for RouteTileDelivery in Program.cs to handle tile delivery requests. - Updated SatelliteProvider.Api.csproj to include Grpc.AspNetCore package and added protobuf file for tile provision. - Enhanced AuthenticationServiceCollectionExtensions to handle JWT token extraction from the Authorization header. - Registered additional services in RouteManagementServiceCollectionExtensions for tile processing. These changes enhance the API's capability to manage tile provisioning and delivery efficiently.
117 lines
3.9 KiB
C#
117 lines
3.9 KiB
C#
using Microsoft.Extensions.Options;
|
|
using SatelliteProvider.Common.Configs;
|
|
using SatelliteProvider.Common.DTO;
|
|
using SatelliteProvider.Common.Utils;
|
|
|
|
namespace SatelliteProvider.Services.RouteManagement.TileProvision;
|
|
|
|
public sealed class RouteTileExpander
|
|
{
|
|
private readonly RoutePointGraphBuilder _pointGraphBuilder;
|
|
private readonly GeofenceGridCalculator _geofenceGridCalculator;
|
|
|
|
public RouteTileExpander(
|
|
RoutePointGraphBuilder pointGraphBuilder,
|
|
GeofenceGridCalculator geofenceGridCalculator)
|
|
{
|
|
_pointGraphBuilder = pointGraphBuilder;
|
|
_geofenceGridCalculator = geofenceGridCalculator;
|
|
}
|
|
|
|
public IReadOnlyList<RouteTileCandidate> Expand(
|
|
IReadOnlyList<(double Lat, double Lon)> waypoints,
|
|
double regionSizeMeters,
|
|
int zoom,
|
|
IReadOnlyList<IReadOnlyList<(double Lat, double Lon)>> geofenceVertices,
|
|
bool includeGeofenceTiles)
|
|
{
|
|
if (waypoints.Count < 2)
|
|
{
|
|
throw new ArgumentException("Route must have at least 2 waypoints", nameof(waypoints));
|
|
}
|
|
|
|
if (regionSizeMeters <= 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException(nameof(regionSizeMeters), "Region size must be positive");
|
|
}
|
|
|
|
var routePoints = waypoints
|
|
.Select(w => new RoutePoint { Latitude = w.Lat, Longitude = w.Lon })
|
|
.ToList();
|
|
var graph = _pointGraphBuilder.Build(routePoints);
|
|
|
|
var tiles = new Dictionary<(int Z, int X, int Y), uint>();
|
|
|
|
for (var priority = 0; priority < graph.Points.Count; priority++)
|
|
{
|
|
var point = graph.Points[priority];
|
|
AddCorridorTiles(
|
|
tiles,
|
|
new GeoPoint(point.Latitude, point.Longitude),
|
|
regionSizeMeters,
|
|
zoom,
|
|
(uint)priority);
|
|
}
|
|
|
|
if (includeGeofenceTiles)
|
|
{
|
|
var geofencePriority = (uint)graph.Points.Count;
|
|
foreach (var vertices in geofenceVertices)
|
|
{
|
|
if (vertices.Count < 3)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var minLat = vertices.Min(v => v.Lat);
|
|
var maxLat = vertices.Max(v => v.Lat);
|
|
var minLon = vertices.Min(v => v.Lon);
|
|
var maxLon = vertices.Max(v => v.Lon);
|
|
|
|
var northWest = new GeoPoint(maxLat, minLon);
|
|
var southEast = new GeoPoint(minLat, maxLon);
|
|
var centers = _geofenceGridCalculator.GenerateRegions(northWest, southEast, regionSizeMeters);
|
|
|
|
foreach (var center in centers)
|
|
{
|
|
AddCorridorTiles(tiles, center, regionSizeMeters, zoom, geofencePriority);
|
|
}
|
|
|
|
geofencePriority++;
|
|
}
|
|
}
|
|
|
|
return tiles
|
|
.OrderBy(t => t.Value)
|
|
.ThenBy(t => t.Key.Y)
|
|
.ThenBy(t => t.Key.X)
|
|
.Select(t => new RouteTileCandidate(t.Key.Z, t.Key.X, t.Key.Y, t.Value))
|
|
.ToList();
|
|
}
|
|
|
|
private static void AddCorridorTiles(
|
|
Dictionary<(int Z, int X, int Y), uint> tiles,
|
|
GeoPoint center,
|
|
double regionSizeMeters,
|
|
int zoom,
|
|
uint routePriority)
|
|
{
|
|
var radiusMeters = regionSizeMeters / 2.0;
|
|
var (latMin, latMax, lonMin, lonMax) = GeoUtils.GetBoundingBox(center, radiusMeters);
|
|
var (xMin, yMin) = GeoUtils.WorldToTilePos(new GeoPoint(latMax, lonMin), zoom);
|
|
var (xMax, yMax) = GeoUtils.WorldToTilePos(new GeoPoint(latMin, lonMax), zoom);
|
|
|
|
for (var y = yMin; y <= yMax; y++)
|
|
{
|
|
for (var x = xMin; x <= xMax; x++)
|
|
{
|
|
var key = (zoom, x, y);
|
|
if (!tiles.TryGetValue(key, out var existing) || routePriority < existing)
|
|
{
|
|
tiles[key] = routePriority;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|