using GpsCardGatewayPosition.Model.GatewayEntity; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GpsCardGatewayPosition.Common { public class GeoUtils { private const decimal A = 6370996.81m; private const double EARTH_RADIUS = 6378137;//赤道半径(单位m) /// /// 点是否在矩形区域中 /// /// /// /// public static bool IsPointInRect(Point pt, Bounds rect) { var e = rect.SW; var h = rect.NE; return (pt.Lng >= e.Lng && pt.Lng <= h.Lng && pt.Lat >= e.Lat && pt.Lat <= h.Lat); } /// /// 点是否在圆形区域中 /// /// /// /// public static bool IsPointInCircle(Point pt, Circle circle) { var i = circle.Center; var g = circle.Radius; var f = GetDistance(pt, i); return f <= g; } /// /// 获取形状的矩形范围 /// /// /// public static Bounds GetBound(IList pts) { if (pts.Count == 0) return new Bounds(new Point(0, 0), new Point(0, 0)); ; decimal minLat = pts[0].Lat, minLng = pts[0].Lng, maxLat = pts[0].Lat, maxLng = pts[0].Lng; foreach (var pt in pts) { minLat = Math.Min(minLat, pt.Lat); minLng = Math.Min(minLng, pt.Lng); maxLat = Math.Max(maxLat, pt.Lat); maxLng = Math.Max(maxLng, pt.Lng); } return new Bounds(new Point(minLng, minLat), new Point(maxLng, maxLat)); } /// /// 经纬度测距算法 /// /// /// /// /// /// 单位 米 public static double GetDistance2(double lon1, double lat1, double lon2, double lat2) { double radLat1 = rad(lat1); double radLat2 = rad(lat2); double a = radLat1 - radLat2; double b = rad(lon1) - rad(lon2); double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))); s = s * EARTH_RADIUS; return s; } /// /// 转化为弧度(rad) /// /// 经度或纬度 /// 弧度 private static double rad(double d) { return d * Math.PI / 180.0; } /// /// 计算两点的距离 单位:米 /// /// /// /// public static decimal GetDistance(Point j, Point h) { j.Lng = ValidLng(j.Lng, -180, 180); j.Lat = ValidLat(j.Lat, -74, 74); h.Lng = ValidLng(h.Lng, -180, 180); h.Lat = ValidLat(h.Lat, -74, 74); decimal f, e, i, g; f = DegreeToRad(j.Lng); i = DegreeToRad(j.Lat); e = DegreeToRad(h.Lng); g = DegreeToRad(h.Lat); return Convert.ToDecimal((double)A * Math.Acos((Math.Sin((double)i) * Math.Sin((double)g) + Math.Cos((double)i) * Math.Cos((double)g) * Math.Cos((double)e - (double)f)))); } private static decimal DegreeToRad(decimal d) { return Convert.ToDecimal(Math.PI * (double)d / 180); } private static decimal RadToDegree(decimal d) { return Convert.ToDecimal((180 * (double)d) / Math.PI); } private static decimal ValidLng(decimal lng, decimal min, decimal max) { while (lng > max) { lng -= max - min; } while (lng < min) { lng += max - min; } return lng; } private static decimal ValidLat(decimal lat, decimal min, decimal max) { lat = Math.Max(lat, min); lat = Math.Min(lat, max); return lat; } } }