Guest User

Untitled

a guest
Dec 11th, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.31 KB | None | 0 0
  1. #region Camera focus method
  2. private static void OnCustomPinsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
  3. {
  4. CustomMap customMap = ((CustomMap)bindable);
  5.  
  6. if (customMap.CameraFocusParameter == CameraFocusReference.OnPins)
  7. {
  8. List<Position> PositionPins = new List<Position>();
  9. bool onlyOnePointPresent;
  10.  
  11. foreach (CustomPin pin in (newValue as List<CustomPin>))
  12. {
  13. PositionPins.Add(pin.Position);
  14. }
  15. Position CentralPosition = GetCentralPosition(PositionPins);
  16. if (PositionPins.Count > 1)
  17. {
  18. Position[] FarestPoints = GetTwoFarestPointsOfCenterPointReference(PositionPins, CentralPosition);
  19. customMap.CameraFocus = GetPositionAndZoomLevelForCameraAboutPositions(FarestPoints);
  20. onlyOnePointPresent = false;
  21. }
  22. else
  23. {
  24. customMap.CameraFocus = new CameraFocusData() { Position = CentralPosition };
  25. onlyOnePointPresent = true;
  26. }
  27. customMap.MoveToRegion(MapSpan.FromCenterAndRadius(customMap.CameraFocus.Position,
  28. (!onlyOnePointPresent) ? (customMap.CameraFocus.Distance) : (new Distance(5))));
  29. }
  30. }
  31. public static Position GetCentralPosition(List<Position> positions)
  32. {
  33. if (positions.Count == 1)
  34. {
  35. foreach (Position pos in positions)
  36. {
  37. return (pos);
  38. }
  39. }
  40.  
  41. double lat = 0;
  42. double lng = 0;
  43.  
  44. foreach (var pos in positions)
  45. {
  46. lat += pos.Latitude;
  47. lng += pos.Longitude;
  48. }
  49.  
  50. var total = positions.Count;
  51.  
  52. lat = lat / total;
  53. lng = lng / total;
  54.  
  55. return new Position(lat, lng);
  56. }
  57. public class DataCalc
  58. {
  59. public Position Pos { get; set; }
  60. public double Distance { get; set; }
  61. }
  62. public static Position[] GetTwoFarestPointsOfCenterPointReference(List<Position> farestPosition, Position centerPosition)
  63. {
  64. Position[] FarestPos = new Position[2];
  65. List<DataCalc> dataCalc = new List<DataCalc>();
  66.  
  67. Debug.WriteLine("So the center is on [{0}]/[{1}]", centerPosition.Latitude, centerPosition.Longitude);
  68.  
  69. foreach (Position pos in farestPosition)
  70. {
  71. dataCalc.Add(new DataCalc()
  72. {
  73. Pos = pos,
  74. Distance = Math.Sqrt(Math.Pow(pos.Latitude - centerPosition.Latitude, 2) + Math.Pow(pos.Longitude - centerPosition.Longitude, 2))
  75. });
  76. }
  77.  
  78. DataCalc First = new DataCalc() { Distance = 0 };
  79. foreach (DataCalc dc in dataCalc)
  80. {
  81. if (dc.Distance > First.Distance)
  82. {
  83. First = dc;
  84. }
  85. }
  86. Debug.WriteLine("The farest one is on [{0}]/[{1}]", First.Pos.Latitude, First.Pos.Longitude);
  87.  
  88. DataCalc Second = new DataCalc() { Distance = 0 };
  89. foreach (DataCalc dc in dataCalc)
  90. {
  91. if (dc.Distance > Second.Distance
  92. && (dc.Pos.Latitude != First.Pos.Latitude && dc.Pos.Longitude != First.Pos.Longitude))
  93. {
  94. Second = dc;
  95. }
  96. }
  97. Debug.WriteLine("the second is on [{0}]/[{1}]", Second.Pos.Latitude, Second.Pos.Longitude);
  98.  
  99. FarestPos[0] = First.Pos;
  100. FarestPos[1] = Second.Pos;
  101.  
  102. return (FarestPos);
  103. }
  104. public class CameraFocusData
  105. {
  106. public Position Position { get; set; }
  107. public Distance Distance { get; set; }
  108. }
  109.  
  110. //HAVERSINE
  111. public static CameraFocusData GetPositionAndZoomLevelForCameraAboutPositions(Position[] FarestPoints)
  112. {
  113. double earthRadius = 6371000; //metros
  114.  
  115. Position pos1 = FarestPoints[0];
  116. Position pos2 = FarestPoints[1];
  117.  
  118. double latitud1Radianes = pos1.Latitude * (Math.PI / 180.0);
  119. double latitud2Radianes = pos2.Latitude * (Math.PI / 180.0);
  120. double longitud1Radianes = pos2.Longitude * (Math.PI / 180.0);
  121. double longitud2Radianes = pos2.Longitude * (Math.PI / 180.0);
  122.  
  123. double deltaLatitud = (pos2.Latitude - pos1.Latitude) * (Math.PI / 180.0);
  124. double deltaLongitud = (pos2.Longitude - pos1.Longitude) * (Math.PI / 180.0);
  125.  
  126. double sum1 = Math.Sin(deltaLatitud / 2) * Math.Sin(deltaLatitud / 2);
  127. double sum2 = Math.Cos(latitud1Radianes) * Math.Cos(latitud2Radianes) * Math.Sin(deltaLongitud / 2) * Math.Sin(deltaLongitud / 2);
  128.  
  129. var a = sum1 + sum2;
  130. var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
  131.  
  132. var distance = earthRadius * c;
  133.  
  134. /* lt is deltaLatitud
  135. * lng is deltaLongitud*/
  136. var Bx = Math.Cos(latitud2Radianes) * Math.Cos(deltaLongitud);
  137. var By = Math.Cos(latitud2Radianes) * Math.Sin(deltaLongitud);
  138. var lt = Math.Atan2(Math.Sin(latitud1Radianes) + Math.Sin(latitud2Radianes),
  139. Math.Sqrt((Math.Cos(latitud1Radianes) + Bx) * (Math.Cos(latitud2Radianes) + Bx) + By * By));//Latitud del punto medio
  140. var lng = longitud1Radianes + Math.Atan2(By, Math.Cos(longitud1Radianes) + Bx);//Longitud del punto medio
  141.  
  142. Debug.WriteLine("the final pos of the camera is on [{0}]/[{1}]", lt, lng);
  143.  
  144. return (new CameraFocusData() { Position = new Position(lt, lng), Distance = new Distance(distance + 0.2) });
  145. }
  146. #endregion
  147.  
  148. public static readonly BindableProperty CustomPinsProperty =
  149. BindableProperty.Create(nameof(CustomPins), typeof(IList<CustomPin>), typeof(CustomMap), null,
  150. propertyChanged: OnCustomPinsPropertyChanged);
  151.  
  152. #region Camera focus definition
  153. public class CameraFocusData
  154. {
  155. public Position Position { get; set; }
  156. public Distance Distance { get; set; }
  157. }
  158. private static void OnCustomPinsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
  159. {
  160. CustomMap customMap = ((CustomMap)bindable);
  161.  
  162. if (customMap.CameraFocusParameter == CameraFocusReference.OnPins)
  163. {
  164. List<double> latitudes = new List<double>();
  165. List<double> longitudes = new List<double>();
  166.  
  167. foreach (CustomPin pin in (newValue as List<CustomPin>))
  168. {
  169. latitudes.Add(pin.Position.Latitude);
  170. longitudes.Add(pin.Position.Longitude);
  171. }
  172.  
  173. double lowestLat = latitudes.Min();
  174. double highestLat = latitudes.Max();
  175. double lowestLong = longitudes.Min();
  176. double highestLong = longitudes.Max();
  177. double finalLat = (lowestLat + highestLat) / 2;
  178. double finalLong = (lowestLong + highestLong) / 2;
  179.  
  180. double distance = DistanceCalculation.GeoCodeCalc.CalcDistance(lowestLat, lowestLong, highestLat, highestLong, DistanceCalculation.GeoCodeCalcMeasurement.Kilometers);
  181.  
  182. customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(finalLat, finalLong), Distance.FromKilometers(distance * 0.7)));
  183. }
  184. }
  185. private class DistanceCalculation
  186. {
  187. public static class GeoCodeCalc
  188. {
  189. public const double EarthRadiusInMiles = 3956.0;
  190. public const double EarthRadiusInKilometers = 6367.0;
  191.  
  192. public static double ToRadian(double val) { return val * (Math.PI / 180); }
  193. public static double DiffRadian(double val1, double val2) { return ToRadian(val2) - ToRadian(val1); }
  194.  
  195. public static double CalcDistance(double lat1, double lng1, double lat2, double lng2)
  196. {
  197. return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles);
  198. }
  199.  
  200. public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m)
  201. {
  202. double radius = GeoCodeCalc.EarthRadiusInMiles;
  203.  
  204. if (m == GeoCodeCalcMeasurement.Kilometers) { radius = GeoCodeCalc.EarthRadiusInKilometers; }
  205. return radius * 2 * Math.Asin(Math.Min(1, Math.Sqrt((Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0)))));
  206. }
  207. }
  208.  
  209. public enum GeoCodeCalcMeasurement : int
  210. {
  211. Miles = 0,
  212. Kilometers = 1
  213. }
  214. }
  215. #endregion
Add Comment
Please, Sign In to add comment