电子围栏推送服务
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

179 rindas
5.4KB

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