diff options
author | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 13:02:25 -0700 |
---|---|---|
committer | Jason Smith <jason.smith@xamarin.com> | 2016-03-22 16:13:41 -0700 |
commit | 17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch) | |
tree | b5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Maps/MapSpan.cs | |
download | xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.gz xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.tar.bz2 xamarin-forms-17fdde66d94155fc62a034fa6658995bef6fd6e5.zip |
Initial import
Diffstat (limited to 'Xamarin.Forms.Maps/MapSpan.cs')
-rw-r--r-- | Xamarin.Forms.Maps/MapSpan.cs | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/Xamarin.Forms.Maps/MapSpan.cs b/Xamarin.Forms.Maps/MapSpan.cs new file mode 100644 index 00000000..883e630f --- /dev/null +++ b/Xamarin.Forms.Maps/MapSpan.cs @@ -0,0 +1,116 @@ +using System; + +namespace Xamarin.Forms.Maps +{ + public sealed class MapSpan + { + const double EarthRadiusKm = 6371; + const double EarthCircumferenceKm = EarthRadiusKm * 2 * Math.PI; + const double MinimumRangeDegrees = 0.001 / EarthCircumferenceKm * 360; // 1 meter + + public MapSpan(Position center, double latitudeDegrees, double longitudeDegrees) + { + Center = center; + LatitudeDegrees = Math.Min(Math.Max(latitudeDegrees, MinimumRangeDegrees), 90.0); + LongitudeDegrees = Math.Min(Math.Max(longitudeDegrees, MinimumRangeDegrees), 180.0); + } + + public Position Center { get; } + + public double LatitudeDegrees { get; } + + public double LongitudeDegrees { get; } + + public Distance Radius + { + get + { + double latKm = LatitudeDegreesToKm(LatitudeDegrees); + double longKm = LongitudeDegreesToKm(Center, LongitudeDegrees); + return new Distance(1000 * Math.Min(latKm, longKm) / 2); + } + } + + public MapSpan ClampLatitude(double north, double south) + { + north = Math.Min(Math.Max(north, 0), 90); + south = Math.Max(Math.Min(south, 0), -90); + double lat = Math.Max(Math.Min(Center.Latitude, north), south); + double maxDLat = Math.Min(north - lat, -south + lat) * 2; + return new MapSpan(new Position(lat, Center.Longitude), Math.Min(LatitudeDegrees, maxDLat), LongitudeDegrees); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) + return false; + if (ReferenceEquals(this, obj)) + return true; + return obj is MapSpan && Equals((MapSpan)obj); + } + + public static MapSpan FromCenterAndRadius(Position center, Distance radius) + { + return new MapSpan(center, 2 * DistanceToLatitudeDegrees(radius), 2 * DistanceToLongitudeDegrees(center, radius)); + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = Center.GetHashCode(); + hashCode = (hashCode * 397) ^ LongitudeDegrees.GetHashCode(); + hashCode = (hashCode * 397) ^ LatitudeDegrees.GetHashCode(); + return hashCode; + } + } + + public static bool operator ==(MapSpan left, MapSpan right) + { + return Equals(left, right); + } + + public static bool operator !=(MapSpan left, MapSpan right) + { + return !Equals(left, right); + } + + public MapSpan WithZoom(double zoomFactor) + { + double maxDLat = Math.Min(90 - Center.Latitude, 90 + Center.Latitude) * 2; + return new MapSpan(Center, Math.Min(LatitudeDegrees / zoomFactor, maxDLat), LongitudeDegrees / zoomFactor); + } + + static double DistanceToLatitudeDegrees(Distance distance) + { + return distance.Kilometers / EarthCircumferenceKm * 360; + } + + static double DistanceToLongitudeDegrees(Position position, Distance distance) + { + double latCircumference = LatitudeCircumferenceKm(position); + return distance.Kilometers / latCircumference * 360; + } + + bool Equals(MapSpan other) + { + return Center.Equals(other.Center) && LongitudeDegrees.Equals(other.LongitudeDegrees) && LatitudeDegrees.Equals(other.LatitudeDegrees); + } + + static double LatitudeCircumferenceKm(Position position) + { + return EarthCircumferenceKm * Math.Cos(position.Latitude * Math.PI / 180.0); + } + + static double LatitudeDegreesToKm(double latitudeDegrees) + { + return EarthCircumferenceKm * latitudeDegrees / 360; + } + + static double LongitudeDegreesToKm(Position position, double longitudeDegrees) + { + double latCircumference = LatitudeCircumferenceKm(position); + return latCircumference * longitudeDegrees / 360; + } + } +}
\ No newline at end of file |