mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 12:26:30 +00:00
switcher dataset explorer
lat lon -> geopoint correct location for gps if small keypoints number
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
namespace Azaion.Common.Extensions;
|
||||
using Azaion.Common.DTO;
|
||||
|
||||
namespace Azaion.Common.Extensions;
|
||||
|
||||
public static class GeoUtils
|
||||
{
|
||||
@@ -13,26 +15,71 @@ public static class GeoUtils
|
||||
return (xTile, yTile);
|
||||
}
|
||||
|
||||
public static (double lat, double lon) TileToWorldPos(int x, int y, int zoom)
|
||||
public static double ToRadians(double degrees) => degrees * Math.PI / 180.0;
|
||||
public static double ToDegrees(double radians) => radians * 180.0 / Math.PI;
|
||||
|
||||
public static Direction DirectionTo(this GeoPoint p1, GeoPoint p2)
|
||||
{
|
||||
var lat1Rad = ToRadians(p1.Lat);
|
||||
var lat2Rad = ToRadians(p2.Lat);
|
||||
var dLon = ToRadians(p2.Lon - p1.Lon);
|
||||
var dLat = ToRadians(p2.Lat - p1.Lat);
|
||||
|
||||
var a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
|
||||
Math.Cos(lat1Rad) * Math.Cos(lat2Rad) *
|
||||
Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
|
||||
var c = 2 * Math.Asin(Math.Sqrt(a));
|
||||
var distance = EARTH_RADIUS * c;
|
||||
|
||||
var y = Math.Sin(dLon) * Math.Cos(lat2Rad);
|
||||
var x = Math.Cos(lat1Rad) * Math.Sin(lat2Rad) -
|
||||
Math.Sin(lat1Rad) * Math.Cos(lat2Rad) * Math.Cos(dLon);
|
||||
var azimuthRadians = Math.Atan2(y, x);
|
||||
var azimuth = (ToDegrees(azimuthRadians) + 360) % 360;
|
||||
|
||||
return new Direction
|
||||
{
|
||||
Distance = distance,
|
||||
Azimuth = azimuth
|
||||
};
|
||||
}
|
||||
|
||||
public static GeoPoint GoDirection(this GeoPoint startPoint, Direction direction)
|
||||
{
|
||||
var angularDistance = direction.Distance / EARTH_RADIUS;
|
||||
var azimuthRadians = ToRadians(direction.Azimuth);
|
||||
var startLatRad = ToRadians(startPoint.Lat);
|
||||
var startLonRad = ToRadians(startPoint.Lon);
|
||||
|
||||
var destLatRad = Math.Asin(Math.Sin(startLatRad) * Math.Cos(angularDistance) +
|
||||
Math.Cos(startLatRad) * Math.Sin(angularDistance) * Math.Cos(azimuthRadians));
|
||||
|
||||
var destLonRad = startLonRad + Math.Atan2(Math.Sin(azimuthRadians) * Math.Sin(angularDistance) * Math.Cos(startLatRad),
|
||||
Math.Cos(angularDistance) - Math.Sin(startLatRad) * Math.Sin(destLatRad));
|
||||
|
||||
return new GeoPoint(ToDegrees(destLatRad), ToDegrees(destLonRad));
|
||||
}
|
||||
|
||||
public static GeoPoint 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);
|
||||
return new GeoPoint(latDeg, lonDeg);
|
||||
}
|
||||
|
||||
public static (double minLat, double maxLat, double minLon, double maxLon) GetBoundingBox(double centerLat, double centerLon, double radiusM)
|
||||
public static (double minLat, double maxLat, double minLon, double maxLon) GetBoundingBox(GeoPoint centerGeoPoint, double radiusM)
|
||||
{
|
||||
var latRad = centerLat * Math.PI / 180.0;
|
||||
var latRad = centerGeoPoint.Lat * 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 minLat = Math.Max(centerGeoPoint.Lat - latDiff, -90.0);
|
||||
var maxLat = Math.Min(centerGeoPoint.Lat + 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);
|
||||
var minLon = Math.Max(centerGeoPoint.Lon - lonDiff, -180.0);
|
||||
var maxLon = Math.Min(centerGeoPoint.Lon + lonDiff, 180.0);
|
||||
|
||||
return (minLat, maxLat, minLon, maxLon);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user