Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
Add GeographyUtils class and Distance.BetweenPoints method
Browse files Browse the repository at this point in the history
  • Loading branch information
jcmanke committed Sep 5, 2019
1 parent 604720e commit 26decfa
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 55 deletions.
29 changes: 1 addition & 28 deletions Xamarin.Forms.Controls/GalleryPages/MapElementsGallery.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,39 +92,12 @@ void MapClicked(object sender, MapClickedEventArgs e)
}
else
{
_circle.Radius = CalculateDistance(_circle.Center, e.Position);
_circle.Radius = Distance.BetweenPositions(_circle.Center, e.Position);
}
break;
}
}

Distance CalculateDistance(Position position1, Position position2)
{
const double EarthRadiusKm = 6371;

var latitude1 = DegreeToRadian(position1.Latitude);
var longitude1 = DegreeToRadian(position1.Longitude);

var latitude2 = DegreeToRadian(position2.Latitude);
var longitude2 = DegreeToRadian(position2.Longitude);

var distance = Math.Sin((latitude2 - latitude1) / 2.0);
distance *= distance;

var intermediate = Math.Sin((longitude2 - longitude1) / 2.0);
intermediate *= intermediate;

distance = distance + Math.Cos(latitude1) * Math.Cos(latitude2) * intermediate;
distance = 2 * EarthRadiusKm * Math.Atan2(Math.Sqrt(distance), Math.Sqrt(1 - distance));

return Distance.FromKilometers(distance);
}

double DegreeToRadian(double degree)
{
return degree * Math.PI / 180.0;
}

void PickerSelectionChanged(object sender, EventArgs e)
{
Enum.TryParse((string)ElementPicker.SelectedItem, out _selectedType);
Expand Down
36 changes: 12 additions & 24 deletions Xamarin.Forms.Maps.UWP/MapRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ protected Geopath PositionsToGeopath(IList<Position> positions)
{
return new Geopath(new[]
{
new BasicGeoposition(),
new BasicGeoposition(),
});
}
}
Expand Down Expand Up @@ -347,38 +347,26 @@ protected virtual MapPolygon LoadCircle(Circle circle)

Geopath GenerateCirclePath(Circle circle)
{
const double EarthRadiusKm = 6371;

var positions = new List<Position>();
double latitude = DegreesToRadians(circle.Center.Latitude);
double longitude = DegreesToRadians(circle.Center.Longitude);
double distance = circle.Radius.Kilometers / EarthRadiusKm;
double centerLatitude = circle.Center.Latitude.ToRadians();
double centerLongitude = circle.Center.Longitude.ToRadians();
double distance = circle.Radius.Kilometers / GeographyUtils.EarthRadiusKm;

for (int angle = 0; angle <= 360; angle++)
{
double angleInRadians = DegreesToRadians(angle);
double latitudeInRadians = Math.Asin(Math.Sin(latitude) * Math.Cos(distance) +
Math.Cos(latitude) * Math.Sin(distance) * Math.Cos(angleInRadians));
double longitudeInRadians =
longitude + Math.Atan2(Math.Sin(angleInRadians) * Math.Sin(distance) * Math.Cos(latitude),
Math.Cos(distance) - Math.Sin(latitude) * Math.Sin(latitudeInRadians));
double angleInRadians = ((double)angle).ToRadians();
double latitude = Math.Asin(Math.Sin(centerLatitude) * Math.Cos(distance) +
Math.Cos(centerLatitude) * Math.Sin(distance) * Math.Cos(angleInRadians));
double longitude = centerLongitude +
Math.Atan2(Math.Sin(angleInRadians) * Math.Sin(distance) * Math.Cos(centerLatitude),
Math.Cos(distance) - Math.Sin(centerLatitude) * Math.Sin(latitude));

positions.Add(new Position(RadiansToDegrees(latitudeInRadians), RadiansToDegrees(longitudeInRadians)));
positions.Add(new Position(latitude.ToDegrees(), longitude.ToDegrees()));
}

return PositionsToGeopath(positions);
}

double DegreesToRadians(double degrees)
{
return degrees * Math.PI / 180.0;
}

double RadiansToDegrees(double radians)
{
return radians / Math.PI * 180.0;
}

void OnCirclePropertyChanged(Circle circle, PropertyChangedEventArgs e)
{
var mapPolygon = (MapPolygon)circle.MapElementId;
Expand All @@ -401,7 +389,7 @@ void OnCirclePropertyChanged(Circle circle, PropertyChangedEventArgs e)
mapPolygon.FillColor = circle.FillColor.ToWindowsColor();
}
else if (e.PropertyName == Circle.CenterProperty.PropertyName ||
e.PropertyName == Circle.RadiusProperty.PropertyName)
e.PropertyName == Circle.RadiusProperty.PropertyName)
{
mapPolygon.Path = GenerateCirclePath(circle);
}
Expand Down
23 changes: 22 additions & 1 deletion Xamarin.Forms.Maps/Distance.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System;
using System.Diagnostics;

namespace Xamarin.Forms.Maps
{
Expand Down Expand Up @@ -48,6 +49,26 @@ public static Distance FromKilometers(double kilometers)
return new Distance(kilometers * MetersPerKilometer);
}

public static Distance BetweenPositions(Position position1, Position position2)
{
var latitude1 = position1.Latitude.ToRadians();
var longitude1 = position1.Longitude.ToRadians();

var latitude2 = position2.Latitude.ToRadians();
var longitude2 = position2.Longitude.ToRadians();

var distance = Math.Sin((latitude2 - latitude1) / 2.0);
distance *= distance;

var intermediate = Math.Sin((longitude2 - longitude1) / 2.0);
intermediate *= intermediate;

distance = distance + Math.Cos(latitude1) * Math.Cos(latitude2) * intermediate;
distance = 2 * GeographyUtils.EarthRadiusKm * Math.Atan2(Math.Sqrt(distance), Math.Sqrt(1 - distance));

return FromKilometers(distance);
}

public bool Equals(Distance other)
{
return Meters.Equals(other.Meters);
Expand Down
19 changes: 19 additions & 0 deletions Xamarin.Forms.Maps/GeographyUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace Xamarin.Forms.Maps
{
public static class GeographyUtils
{
public const double EarthRadiusKm = 6371;

public static double ToRadians(this double degrees)
{
return degrees * Math.PI / 180.0;
}

public static double ToDegrees(this double radians)
{
return radians / Math.PI * 180.0;
}
}
}
3 changes: 1 addition & 2 deletions Xamarin.Forms.Maps/MapSpan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ namespace Xamarin.Forms.Maps
{
public sealed class MapSpan
{
const double EarthRadiusKm = 6371;
const double EarthCircumferenceKm = EarthRadiusKm * 2 * Math.PI;
const double EarthCircumferenceKm = GeographyUtils.EarthRadiusKm * 2 * Math.PI;
const double MinimumRangeDegrees = 0.001 / EarthCircumferenceKm * 360; // 1 meter

public MapSpan(Position center, double latitudeDegrees, double longitudeDegrees)
Expand Down

0 comments on commit 26decfa

Please sign in to comment.