CYCLUS
position.cc
Go to the documentation of this file.
1 #include <math.h>
2 #include <stdio.h>
3 #include <sstream>
4 
5 #include "position.h"
6 
7 namespace cyclus {
8 namespace toolkit {
9 
10 Position::Position() : latitude_(0), longitude_(0) {}
11 
12 Position::Position(double decimal_lat, double decimal_lon) {
13  LatCheck(decimal_lat);
14  LonCheck(decimal_lon);
15  latitude_ = SetPrecision(decimal_lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
16  longitude_ = SetPrecision(decimal_lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
17 }
18 
20 
21 double Position::latitude() const {
22  return SetPrecision(latitude_ / CYCLUS_DECIMAL_SECOND_MULTIPLIER, 6);
23 }
24 
25 double Position::longitude() const {
26  return SetPrecision(longitude_ / CYCLUS_DECIMAL_SECOND_MULTIPLIER, 6);
27 }
28 
29 void Position::latitude(double lat) {
30  LatCheck(lat);
31  latitude_ = SetPrecision(lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
32 }
33 
34 void Position::longitude(double lon) {
35  LonCheck(lon);
36  longitude_ = SetPrecision(lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
37 }
38 
39 void Position::set_position(double lat, double lon) {
40  LatCheck(lat);
41  LonCheck(lon);
42  latitude_ = SetPrecision(lat * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
43  longitude_ = SetPrecision(lon * CYCLUS_DECIMAL_SECOND_MULTIPLIER, 1);
44 }
45 
46 void Position::LatCheck(double lat) {
47  if (lat > 90 || lat < -90){
48  std::stringstream msg;
49  msg << "The provided latitude (" << lat
50  << ") is outside the acceptable range. "
51  << "[-90, 90]";
52  throw ValueError(msg.str());
53  }
54 }
55 
56 void Position::LonCheck(double lon) {
57  if (lon > 180 || lon < -180){
58  std::stringstream msg;
59  msg << "The provided longitude (" << lon
60  << ") is outside the acceptable range."
61  << "[-180, 180]";
62  throw ValueError(msg.str());
63  }
64 }
65 
66 double Position::Distance(Position target) const {
67  double earth_radius = 6372.8; // in kilometers (KM)
68  double curr_longitude = this->longitude() * M_PI / 180;
69  double curr_latitude = this->latitude() * M_PI / 180;
70  double tarlongitude = target.longitude() * M_PI / 180;
71  double tarlatitude = target.latitude() * M_PI / 180;
72  double dlong = tarlongitude - curr_longitude;
73  double dlat = tarlatitude - curr_latitude;
74 
75  double half_chord_length_sq =
76  pow(sin(dlat / 2), 2) +
77  pow(sin(dlong / 2), 2) * cos(curr_latitude) * cos(tarlatitude);
78 
79  double angular_distance =
80  2 * atan2(sqrt(half_chord_length_sq), sqrt(1 - half_chord_length_sq));
81  return earth_radius * angular_distance;
82 }
83 
85  std::stringstream lat_string;
86  std::stringstream lon_string;
87  double lat = this->latitude();
88  double lon = this->longitude();
89  switch (format) {
90  case StringFormat::DEGREES:
91  lat_string << ToStringHelperLat(format, lat);
92  lon_string << ToStringHelperLon(format, lon);
93  break;
94  case StringFormat::DEGREES_MINUTES:
95  lat_string << ToStringHelperLat(format, lat);
96  lon_string << ToStringHelperLon(format, lon);
97  break;
98  case StringFormat::DEGREES_MINUTES_SECONDS:
99  lat_string << ToStringHelperLat(format, lat);
100  lon_string << ToStringHelperLon(format, lon);
101  break;
102  }
103  return lat_string.str() + lon_string.str() + "/";
104 }
105 
106 double Position::SetPrecision(double value, double precision) const {
107  if (precision == 0) {
108  return floor(value);
109  }
110  return (floor((value * pow(10, precision) + 0.5)) / pow(10, precision));
111 }
112 
113 std::string Position::ToStringHelperLat(int mode, double lat) const {
114  std::stringstream lat_string;
115  double lat_int;
116  lat_string << ToStringHelper(lat);
117 
118  lat = modf(lat, &lat_int);
119  if (((int)lat_int) / 10 == 0) {
120  lat_string << "0";
121  }
122  switch (mode) {
123  case StringFormat::DEGREES:
124  lat_string << std::setprecision(7) << fabs(lat_int + lat);
125  break;
126  case StringFormat::DEGREES_MINUTES:
127  lat_string << abs((int)lat_int) << ToStringHelperDM(lat);
128  break;
129  case StringFormat::DEGREES_MINUTES_SECONDS:
130  lat_string << abs((int)lat_int) << ToStringHelperDMS(lat);
131  break;
132  }
133  return lat_string.str();
134 }
135 
136 std::string Position::ToStringHelperLon(int mode, double lon) const {
137  std::stringstream lon_string;
138  double lon_int;
139  lon_string << ToStringHelper(lon);
140  lon = modf(lon, &lon_int);
141  if (((int)lon_int) / 100 == 0) {
142  if (((int)lon_int) / 10 == 0) {
143  lon_string << "0";
144  }
145  lon_string << "0";
146  }
147  switch (mode) {
148  case StringFormat::DEGREES:
149  lon_string << std::setprecision(7) << fabs(lon_int + lon);
150  break;
151  case StringFormat::DEGREES_MINUTES:
152  lon_string << abs((int)lon_int) << ToStringHelperDM(lon);
153  break;
154  case StringFormat::DEGREES_MINUTES_SECONDS:
155  lon_string << abs((int)lon_int) << ToStringHelperDMS(lon);
156  break;
157  }
158  return lon_string.str();
159 }
160 
161 std::string Position::ToStringHelper(double value) const {
162  std::stringstream temp;
163  if (value > 0) {
164  temp << "+";
165  } else {
166  temp << "-";
167  }
168  return temp.str();
169 }
170 
171 std::string Position::ToStringHelperDM(double value) const {
172  std::stringstream temp;
173  value = fabs(value) * 60;
174  if (((int)fabs(value)) / 10 == 0) {
175  temp << "0";
176  }
177  temp << std::setprecision(5) << value;
178 
179  return temp.str();
180 }
181 
182 std::string Position::ToStringHelperDMS(double value) const {
183  std::stringstream temp;
184  double value_int;
185  value = fabs(value) * 60;
186  value = modf(value, &value_int);
187  if (((int)value_int) / 10 == 0) {
188  temp << "0";
189  }
190  temp << fabs(value_int);
191  value = value * 60;
192  if ((int)fabs(value) / 10 == 0) {
193  temp << "0";
194  }
195  temp << std::setprecision(1) << std::fixed << value;
196 
197  return temp.str();
198 }
199 
200 } // namespace toolkit
201 } // namespace cyclus
std::string ToString(Position::StringFormat format=StringFormat::DEGREES) const
Converts Position location into a string expression that follows ISO 6709 Annex H.
Definition: position.cc:84
~Position()
The default destructor for Position.
Definition: position.cc:19
Position()
The default constructor for Position.
Definition: position.cc:10
For values that are too big, too small, etc.
Definition: error.h:41
double latitude() const
Returns the current latitude.
Definition: position.cc:21
double longitude() const
Returns the current longitude.
Definition: position.cc:25
The Position class is a basic class that stores the geographic location of each agent in latitude and...
Definition: position.h:59
#define CYCLUS_DECIMAL_SECOND_MULTIPLIER
Definition: position.h:3
void set_position(double lat, double lon)
Sets a new latitude and longitude.
Definition: position.cc:39
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
Definition: agent.cc:14
double Distance(Position target) const
Returns the distance (in km) between this Position object and the target Position object...
Definition: position.cc:66