PageRenderTime 35ms CodeModel.GetById 22ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/Main/src/DynamicDataDisplay.Maps/Degree.cs

#
C# | 218 lines | 175 code | 41 blank | 2 comment | 19 complexity | fae43f3f01bde2780d9126c2da99efc8 MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Text;
  5using System.Globalization;
  6
  7namespace Microsoft.Research.DynamicDataDisplay.Charts.Maps
  8{
  9	public struct Degree : IComparable, IComparable<Degree>, IEquatable<Degree>
 10	{
 11		private readonly CoordinateType coordinateType;
 12		public CoordinateType CoordinateType
 13		{
 14			get { return coordinateType; }
 15		}
 16
 17		private readonly double value;
 18		public double TotalDegrees
 19		{
 20			get { return value; }
 21		}
 22
 23		public Degree(double totalDegrees)
 24		{
 25			if (Double.IsNaN(totalDegrees))
 26				throw new ArgumentException("Value cannot be NaN.", "totalDegrees");
 27			if (Math.Abs(totalDegrees) >= Int32.MaxValue)
 28				throw new ArgumentOutOfRangeException("totalDegrees", "Value cannot be greater than Int32.MaxValue.");
 29
 30			this.value = totalDegrees;
 31			coordinateType = CoordinateType.Latitude;
 32		}
 33
 34		public Degree(int degrees, int minutes, double seconds, CoordinateType coordinateType)
 35			: this(degrees + minutes / 60.0 + seconds / 3600.0)
 36		{
 37			if (Math.Abs(minutes) >= 60)
 38				throw new ArgumentOutOfRangeException("minutes");
 39			if (Math.Abs(seconds) >= 60.0)
 40				throw new ArgumentOutOfRangeException("seconds");
 41
 42			this.coordinateType = coordinateType;
 43		}
 44
 45		public Degree(double value, CoordinateType coodinateType)
 46			: this(value)
 47		{
 48			this.coordinateType = coodinateType;
 49		}
 50
 51		public static Degree CreateLatitude(int degrees, int minutes)
 52		{
 53			return Degree.CreateLatitude(degrees, minutes, 0);
 54		}
 55
 56		public static Degree CreateLongitude(int degrees, int minutes)
 57		{
 58			return Degree.CreateLongitude(degrees, minutes, 0);
 59		}
 60
 61		public static Degree CreateLatitude(int degrees, int minutes, double seconds)
 62		{
 63			int sign = Math.Sign(degrees);
 64			return new Degree(degrees, sign * minutes, sign * seconds, CoordinateType.Latitude);
 65		}
 66
 67		public static Degree CreateLongitude(int degrees, int minutes, double seconds)
 68		{
 69			int sign = Math.Sign(degrees);
 70			return new Degree(degrees, sign * minutes, sign * seconds, CoordinateType.Longitude);
 71		}
 72
 73		public static Degree CreateLatitude(double value)
 74		{
 75			return new Degree(value, CoordinateType.Latitude);
 76		}
 77
 78		public static Degree CreateLongitude(double value)
 79		{
 80			return new Degree(value, CoordinateType.Longitude);
 81		}
 82
 83		public int Degrees
 84		{
 85			get { return (int)Math.Sign(value) * (int)Math.Floor(Math.Abs(value)); }
 86		}
 87
 88		public int Minutes
 89		{
 90			get { return (int)Math.Floor(TotalMinutes); }
 91		}
 92
 93		public double TotalMinutes
 94		{
 95			get
 96			{
 97				double abs = Math.Abs(value);
 98				double frac = abs - Math.Floor(abs);
 99				return frac * 60;
100			}
101		}
102
103		public int Seconds
104		{
105			get
106			{
107				return (int)Math.Floor(TotalSeconds);
108			}
109		}
110
111		public double TotalSeconds
112		{
113			get
114			{
115				double mins = TotalMinutes;
116				double frac = mins - Math.Floor(mins);
117				return frac * 60;
118			}
119		}
120
121		#region IComparable Members
122
123		public int CompareTo(object obj)
124		{
125			if (obj == null)
126				return 1;
127			if (!(obj is Degree))
128				throw new ArgumentException("Argument must be Degree.", "obj");
129			double otherValue = ((Degree)obj).value;
130
131			return value.CompareTo(otherValue);
132		}
133
134		#endregion
135
136		#region IComparable<Degree> Members
137
138		public int CompareTo(Degree other)
139		{
140			return value.CompareTo(other.value);
141		}
142
143		#endregion
144
145		#region Operators
146
147		public static Degree operator -(Degree degree)
148		{
149			return new Degree(-degree.value);
150		}
151
152		public static bool operator ==(Degree left, Degree right)
153		{
154			return left.value == right.value;
155		}
156
157		public static bool operator !=(Degree left, Degree right)
158		{
159			return left.value != right.value;
160		}
161
162		#endregion
163
164		#region IEquatable<Degree> Members
165
166		public override bool Equals(object obj)
167		{
168			return (obj is Degree) && (((Degree)obj).value == value);
169		}
170
171		public override int GetHashCode()
172		{
173			return value.GetHashCode();
174		}
175
176		public bool Equals(Degree other)
177		{
178			return value == other.value;
179		}
180
181		#endregion
182
183		public override string ToString()
184		{
185			return ToString("{0}° {1:0#}' {2:00.00}\" {3}");
186		}
187
188		public string ToString(string format)
189		{
190			if (String.IsNullOrEmpty(format))
191				throw new ArgumentException("Format string cannot be null or empty.", "format");
192
193			string typeStr = CreateTypeString();
194			string str = String.Format(format, Math.Abs(Degrees), Minutes, TotalSeconds, typeStr);
195			return str;
196		}
197
198		private string CreateTypeString()
199		{
200			CultureInfo culture = CultureInfo.CurrentCulture;
201
202			// russian language
203			if (culture.TwoLetterISOLanguageName == "ru")
204			{
205				if (coordinateType == CoordinateType.Latitude)
206					return value >= 0 ? "с.ш." : "ю.ш.";
207				else
208					return value >= 0 ? "в.д." : "з.д.";
209			}
210
211			// other languages - taking English translation
212			if (coordinateType == CoordinateType.Latitude)
213				return value >= 0 ? "N" : "S";
214			else
215				return value >= 0 ? "E" : "W";
216		}
217	}
218}