PageRenderTime 36ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

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

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