/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
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}