summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Maps/MapSpan.cs
diff options
context:
space:
mode:
authorJason Smith <jason.smith@xamarin.com>2016-03-22 13:02:25 -0700
committerJason Smith <jason.smith@xamarin.com>2016-03-22 16:13:41 -0700
commit17fdde66d94155fc62a034fa6658995bef6fd6e5 (patch)
treeb5e5073a2a7b15cdbe826faa5c763e270a505729 /Xamarin.Forms.Maps/MapSpan.cs
downloadxamarin-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.cs116
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