|
- 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)
-
- /// <summary>
- /// 点是否在矩形区域中
- /// </summary>
- /// <param name="pt"></param>
- /// <param name="rect"></param>
- /// <returns></returns>
- 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);
- }
- /// <summary>
- /// 点是否在圆形区域中
- /// </summary>
- /// <param name="pt"></param>
- /// <param name="circle"></param>
- /// <returns></returns>
- public static bool IsPointInCircle(Point pt, Circle circle)
- {
- var i = circle.Center;
- var g = circle.Radius;
- var f = GetDistance(pt, i);
- return f <= g;
- }
-
- /// <summary>
- /// 获取形状的矩形范围
- /// </summary>
- /// <param name="pts"></param>
- /// <returns></returns>
- public static Bounds GetBound(IList<Point> 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));
- }
-
- /// <summary>
- /// 经纬度测距算法
- /// </summary>
- /// <param name="lon1"></param>
- /// <param name="lat1"></param>
- /// <param name="lon2"></param>
- /// <param name="lat2"></param>
- /// <returns>单位 米</returns>
- 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;
- }
-
- /// <summary>
- /// 转化为弧度(rad)
- /// </summary>
- /// <param name="d">经度或纬度</param>
- /// <returns>弧度</returns>
- private static double rad(double d)
- {
- return d * Math.PI / 180.0;
- }
-
-
- /// <summary>
- /// 计算两点的距离 单位:米
- /// </summary>
- /// <param name="j"></param>
- /// <param name="h"></param>
- /// <returns></returns>
- 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;
- }
- }
- }
|