Files
annotations/Azaion.Common/Extensions/GeoUtils.cs
T
Alex Bezdieniezhnykh ca1682a86e add gps matcher service
2025-04-14 09:50:34 +03:00

39 lines
1.5 KiB
C#

namespace Azaion.Common.Extensions;
public static class GeoUtils
{
private const double EARTH_RADIUS = 6378137;
public static (int x, int y) WorldToTilePos(double lat, double lon, int zoom)
{
var latRad = lat * Math.PI / 180.0;
var n = Math.Pow(2.0, zoom);
var xTile = (int)Math.Floor((lon + 180.0) / 360.0 * n);
var yTile = (int)Math.Floor((1.0 - Math.Log(Math.Tan(latRad) + 1.0 / Math.Cos(latRad)) / Math.PI) / 2.0 * n);
return (xTile, yTile);
}
public static (double lat, double lon) TileToWorldPos(int x, int y, int zoom)
{
var n = Math.Pow(2.0, zoom);
var lonDeg = x / n * 360.0 - 180.0;
var latRad = Math.Atan(Math.Sinh(Math.PI * (1.0 - 2.0 * y / n)));
var latDeg = latRad * 180.0 / Math.PI;
return (latDeg, lonDeg);
}
public static (double minLat, double maxLat, double minLon, double maxLon) GetBoundingBox(double centerLat, double centerLon, double radiusM)
{
var latRad = centerLat * Math.PI / 180.0;
var latDiff = (radiusM / EARTH_RADIUS) * (180.0 / Math.PI);
var minLat = Math.Max(centerLat - latDiff, -90.0);
var maxLat = Math.Min(centerLat + latDiff, 90.0);
var lonDiff = (radiusM / (EARTH_RADIUS * Math.Cos(latRad))) * (180.0 / Math.PI);
var minLon = Math.Max(centerLon - lonDiff, -180.0);
var maxLon = Math.Min(centerLon + lonDiff, 180.0);
return (minLat, maxLat, minLon, maxLon);
}
}