No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

GeoUtils.cs 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using GpsCardGatewayPosition.Model.GatewayEntity;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace GpsCardGatewayPosition.Common
  8. {
  9. public class GeoUtils
  10. {
  11. private const decimal A = 6370996.81m;
  12. private const double EARTH_RADIUS = 6378137;//赤道半径(单位m)
  13. /// <summary>
  14. /// 点是否在矩形区域中
  15. /// </summary>
  16. /// <param name="pt"></param>
  17. /// <param name="rect"></param>
  18. /// <returns></returns>
  19. public static bool IsPointInRect(Point pt, Bounds rect)
  20. {
  21. var e = rect.SW;
  22. var h = rect.NE;
  23. return (pt.Lng >= e.Lng && pt.Lng <= h.Lng && pt.Lat >= e.Lat && pt.Lat <= h.Lat);
  24. }
  25. /// <summary>
  26. /// 点是否在圆形区域中
  27. /// </summary>
  28. /// <param name="pt"></param>
  29. /// <param name="circle"></param>
  30. /// <returns></returns>
  31. public static bool IsPointInCircle(Point pt, Circle circle)
  32. {
  33. var i = circle.Center;
  34. var g = circle.Radius;
  35. var f = GetDistance(pt, i);
  36. return f <= g;
  37. }
  38. /// <summary>
  39. /// 获取形状的矩形范围
  40. /// </summary>
  41. /// <param name="pts"></param>
  42. /// <returns></returns>
  43. public static Bounds GetBound(IList<Point> pts)
  44. {
  45. if (pts.Count == 0)
  46. return new Bounds(new Point(0, 0), new Point(0, 0)); ;
  47. decimal minLat = pts[0].Lat, minLng = pts[0].Lng, maxLat = pts[0].Lat, maxLng = pts[0].Lng;
  48. foreach (var pt in pts)
  49. {
  50. minLat = Math.Min(minLat, pt.Lat);
  51. minLng = Math.Min(minLng, pt.Lng);
  52. maxLat = Math.Max(maxLat, pt.Lat);
  53. maxLng = Math.Max(maxLng, pt.Lng);
  54. }
  55. return new Bounds(new Point(minLng, minLat), new Point(maxLng, maxLat));
  56. }
  57. /// <summary>
  58. /// 经纬度测距算法
  59. /// </summary>
  60. /// <param name="lon1"></param>
  61. /// <param name="lat1"></param>
  62. /// <param name="lon2"></param>
  63. /// <param name="lat2"></param>
  64. /// <returns>单位 米</returns>
  65. public static double GetDistance2(double lon1, double lat1, double lon2, double lat2)
  66. {
  67. double radLat1 = rad(lat1);
  68. double radLat2 = rad(lat2);
  69. double a = radLat1 - radLat2;
  70. double b = rad(lon1) - rad(lon2);
  71. 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)));
  72. s = s * EARTH_RADIUS;
  73. return s;
  74. }
  75. /// <summary>
  76. /// 转化为弧度(rad)
  77. /// </summary>
  78. /// <param name="d">经度或纬度</param>
  79. /// <returns>弧度</returns>
  80. private static double rad(double d)
  81. {
  82. return d * Math.PI / 180.0;
  83. }
  84. /// <summary>
  85. /// 计算两点的距离 单位:米
  86. /// </summary>
  87. /// <param name="j"></param>
  88. /// <param name="h"></param>
  89. /// <returns></returns>
  90. public static decimal GetDistance(Point j, Point h)
  91. {
  92. j.Lng = ValidLng(j.Lng, -180, 180);
  93. j.Lat = ValidLat(j.Lat, -74, 74);
  94. h.Lng = ValidLng(h.Lng, -180, 180);
  95. h.Lat = ValidLat(h.Lat, -74, 74);
  96. decimal f, e, i, g;
  97. f = DegreeToRad(j.Lng);
  98. i = DegreeToRad(j.Lat);
  99. e = DegreeToRad(h.Lng);
  100. g = DegreeToRad(h.Lat);
  101. 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))));
  102. }
  103. private static decimal DegreeToRad(decimal d)
  104. {
  105. return Convert.ToDecimal(Math.PI * (double)d / 180);
  106. }
  107. private static decimal RadToDegree(decimal d)
  108. {
  109. return Convert.ToDecimal((180 * (double)d) / Math.PI);
  110. }
  111. private static decimal ValidLng(decimal lng, decimal min, decimal max)
  112. {
  113. while (lng > max)
  114. {
  115. lng -= max - min;
  116. }
  117. while (lng < min)
  118. {
  119. lng += max - min;
  120. }
  121. return lng;
  122. }
  123. private static decimal ValidLat(decimal lat, decimal min, decimal max)
  124. {
  125. lat = Math.Max(lat, min);
  126. lat = Math.Min(lat, max);
  127. return lat;
  128. }
  129. }
  130. }