Geographical position and calculation using latitude/longitude. Most of this comes from http://www.movable-type.co.uk/scripts/latlong.html
GeoPosition.cpp@0:8b049ccf57cb, 2011-04-27 (annotated)
- Committer:
- shimniok
- Date:
- Wed Apr 27 17:58:09 2011 +0000
- Revision:
- 0:8b049ccf57cb
Initial release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shimniok | 0:8b049ccf57cb | 1 | #include "GeoPosition.h" |
shimniok | 0:8b049ccf57cb | 2 | #include <math.h> |
shimniok | 0:8b049ccf57cb | 3 | |
shimniok | 0:8b049ccf57cb | 4 | // Earth's mean radius in meters |
shimniok | 0:8b049ccf57cb | 5 | #define EARTHRADIUS 6371000.0 |
shimniok | 0:8b049ccf57cb | 6 | |
shimniok | 0:8b049ccf57cb | 7 | GeoPosition::GeoPosition(): _R(EARTHRADIUS), _latitude(0.0), _longitude(0.0) |
shimniok | 0:8b049ccf57cb | 8 | { |
shimniok | 0:8b049ccf57cb | 9 | } |
shimniok | 0:8b049ccf57cb | 10 | |
shimniok | 0:8b049ccf57cb | 11 | GeoPosition::GeoPosition(double latitude, double longitude): _R(EARTHRADIUS), _latitude(latitude), _longitude(longitude) |
shimniok | 0:8b049ccf57cb | 12 | { |
shimniok | 0:8b049ccf57cb | 13 | } |
shimniok | 0:8b049ccf57cb | 14 | |
shimniok | 0:8b049ccf57cb | 15 | /* |
shimniok | 0:8b049ccf57cb | 16 | double GeoPosition::easting() |
shimniok | 0:8b049ccf57cb | 17 | { |
shimniok | 0:8b049ccf57cb | 18 | } |
shimniok | 0:8b049ccf57cb | 19 | |
shimniok | 0:8b049ccf57cb | 20 | double GeoPosition::northing() |
shimniok | 0:8b049ccf57cb | 21 | { |
shimniok | 0:8b049ccf57cb | 22 | } |
shimniok | 0:8b049ccf57cb | 23 | */ |
shimniok | 0:8b049ccf57cb | 24 | |
shimniok | 0:8b049ccf57cb | 25 | double GeoPosition::latitude() |
shimniok | 0:8b049ccf57cb | 26 | { |
shimniok | 0:8b049ccf57cb | 27 | return _latitude; |
shimniok | 0:8b049ccf57cb | 28 | } |
shimniok | 0:8b049ccf57cb | 29 | |
shimniok | 0:8b049ccf57cb | 30 | double GeoPosition::longitude() |
shimniok | 0:8b049ccf57cb | 31 | { |
shimniok | 0:8b049ccf57cb | 32 | return _longitude; |
shimniok | 0:8b049ccf57cb | 33 | } |
shimniok | 0:8b049ccf57cb | 34 | |
shimniok | 0:8b049ccf57cb | 35 | void GeoPosition::set(double latitude, double longitude) |
shimniok | 0:8b049ccf57cb | 36 | { |
shimniok | 0:8b049ccf57cb | 37 | _latitude = latitude; |
shimniok | 0:8b049ccf57cb | 38 | _longitude = longitude; |
shimniok | 0:8b049ccf57cb | 39 | } |
shimniok | 0:8b049ccf57cb | 40 | |
shimniok | 0:8b049ccf57cb | 41 | void GeoPosition::set(GeoPosition pos) |
shimniok | 0:8b049ccf57cb | 42 | { |
shimniok | 0:8b049ccf57cb | 43 | _latitude = pos.latitude(); |
shimniok | 0:8b049ccf57cb | 44 | _longitude = pos.longitude(); |
shimniok | 0:8b049ccf57cb | 45 | } |
shimniok | 0:8b049ccf57cb | 46 | |
shimniok | 0:8b049ccf57cb | 47 | /* |
shimniok | 0:8b049ccf57cb | 48 | void GeoPosition::set(UTM coord) |
shimniok | 0:8b049ccf57cb | 49 | { |
shimniok | 0:8b049ccf57cb | 50 | } |
shimniok | 0:8b049ccf57cb | 51 | */ |
shimniok | 0:8b049ccf57cb | 52 | |
shimniok | 0:8b049ccf57cb | 53 | void GeoPosition::move(float course, float distance) |
shimniok | 0:8b049ccf57cb | 54 | { |
shimniok | 0:8b049ccf57cb | 55 | double d = distance / _R; |
shimniok | 0:8b049ccf57cb | 56 | double c = radians(course); |
shimniok | 0:8b049ccf57cb | 57 | double rlat1 = radians(_latitude); |
shimniok | 0:8b049ccf57cb | 58 | double rlon1 = radians(_longitude); |
shimniok | 0:8b049ccf57cb | 59 | |
shimniok | 0:8b049ccf57cb | 60 | double rlat2 = asin(sin(rlat1)*cos(d) + cos(rlat1)*sin(d)*cos(c)); |
shimniok | 0:8b049ccf57cb | 61 | double rlon2 = rlon1 + atan2(sin(c)*sin(d)*cos(rlat1), cos(d)-sin(rlat1)*sin(rlat2)); |
shimniok | 0:8b049ccf57cb | 62 | |
shimniok | 0:8b049ccf57cb | 63 | _latitude = degrees(rlat2); |
shimniok | 0:8b049ccf57cb | 64 | _longitude = degrees(rlon2); |
shimniok | 0:8b049ccf57cb | 65 | |
shimniok | 0:8b049ccf57cb | 66 | // bring back within the range -180 to +180 |
shimniok | 0:8b049ccf57cb | 67 | while (_longitude < -180.0) _longitude += 360.0; |
shimniok | 0:8b049ccf57cb | 68 | while (_longitude > 180.0) _longitude -= 360.0; |
shimniok | 0:8b049ccf57cb | 69 | } |
shimniok | 0:8b049ccf57cb | 70 | |
shimniok | 0:8b049ccf57cb | 71 | /* |
shimniok | 0:8b049ccf57cb | 72 | void GeoPosition::move(Direction toWhere) |
shimniok | 0:8b049ccf57cb | 73 | { |
shimniok | 0:8b049ccf57cb | 74 | } |
shimniok | 0:8b049ccf57cb | 75 | |
shimniok | 0:8b049ccf57cb | 76 | Direction GeoPosition::direction(GeoPosition startingPoint) |
shimniok | 0:8b049ccf57cb | 77 | { |
shimniok | 0:8b049ccf57cb | 78 | } |
shimniok | 0:8b049ccf57cb | 79 | */ |
shimniok | 0:8b049ccf57cb | 80 | |
shimniok | 0:8b049ccf57cb | 81 | float GeoPosition::bearing(GeoPosition from) |
shimniok | 0:8b049ccf57cb | 82 | { |
shimniok | 0:8b049ccf57cb | 83 | double lat1 = radians(from.latitude()); |
shimniok | 0:8b049ccf57cb | 84 | double lon1 = radians(from.longitude()); |
shimniok | 0:8b049ccf57cb | 85 | double lat2 = radians(_latitude); |
shimniok | 0:8b049ccf57cb | 86 | double lon2 = radians(_longitude); |
shimniok | 0:8b049ccf57cb | 87 | double dLon = lon2 - lon1; |
shimniok | 0:8b049ccf57cb | 88 | |
shimniok | 0:8b049ccf57cb | 89 | double y = sin(dLon) * cos(lat2); |
shimniok | 0:8b049ccf57cb | 90 | double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon); |
shimniok | 0:8b049ccf57cb | 91 | |
shimniok | 0:8b049ccf57cb | 92 | return degrees(atan2(y, x)); |
shimniok | 0:8b049ccf57cb | 93 | } |
shimniok | 0:8b049ccf57cb | 94 | |
shimniok | 0:8b049ccf57cb | 95 | /* |
shimniok | 0:8b049ccf57cb | 96 | float GeoPosition::bearing(LatLong startingPoint) |
shimniok | 0:8b049ccf57cb | 97 | { |
shimniok | 0:8b049ccf57cb | 98 | } |
shimniok | 0:8b049ccf57cb | 99 | |
shimniok | 0:8b049ccf57cb | 100 | float GeoPosition::bearing(UTM startingPoint) |
shimniok | 0:8b049ccf57cb | 101 | { |
shimniok | 0:8b049ccf57cb | 102 | } |
shimniok | 0:8b049ccf57cb | 103 | */ |
shimniok | 0:8b049ccf57cb | 104 | |
shimniok | 0:8b049ccf57cb | 105 | float GeoPosition::distance(GeoPosition from) |
shimniok | 0:8b049ccf57cb | 106 | { |
shimniok | 0:8b049ccf57cb | 107 | double lat1 = radians(from.latitude()); |
shimniok | 0:8b049ccf57cb | 108 | double lon1 = radians(from.longitude()); |
shimniok | 0:8b049ccf57cb | 109 | double lat2 = radians(_latitude); |
shimniok | 0:8b049ccf57cb | 110 | double lon2 = radians(_longitude); |
shimniok | 0:8b049ccf57cb | 111 | double dLat = lat2 - lat1; |
shimniok | 0:8b049ccf57cb | 112 | double dLon = lon2 - lon1; |
shimniok | 0:8b049ccf57cb | 113 | |
shimniok | 0:8b049ccf57cb | 114 | double a = sin(dLat/2.0) * sin(dLat/2.0) + |
shimniok | 0:8b049ccf57cb | 115 | cos(lat1) * cos(lat2) * |
shimniok | 0:8b049ccf57cb | 116 | sin(dLon/2.0) * sin(dLon/2.0); |
shimniok | 0:8b049ccf57cb | 117 | double c = 2.0 * atan2(sqrt(a), sqrt(1-a)); |
shimniok | 0:8b049ccf57cb | 118 | |
shimniok | 0:8b049ccf57cb | 119 | return _R * c; |
shimniok | 0:8b049ccf57cb | 120 | } |
shimniok | 0:8b049ccf57cb | 121 | |
shimniok | 0:8b049ccf57cb | 122 | /* |
shimniok | 0:8b049ccf57cb | 123 | float GeoPosition::distance(LatLong startingPoint) |
shimniok | 0:8b049ccf57cb | 124 | { |
shimniok | 0:8b049ccf57cb | 125 | } |
shimniok | 0:8b049ccf57cb | 126 | |
shimniok | 0:8b049ccf57cb | 127 | float GeoPosition::distance(UTM startingPoint) |
shimniok | 0:8b049ccf57cb | 128 | { |
shimniok | 0:8b049ccf57cb | 129 | } |
shimniok | 0:8b049ccf57cb | 130 | */ |
shimniok | 0:8b049ccf57cb | 131 | |
shimniok | 0:8b049ccf57cb | 132 | void GeoPosition::setTimestamp(int time) { |
shimniok | 0:8b049ccf57cb | 133 | _time = time; |
shimniok | 0:8b049ccf57cb | 134 | } |
shimniok | 0:8b049ccf57cb | 135 | |
shimniok | 0:8b049ccf57cb | 136 | int GeoPosition::getTimestamp(void) { |
shimniok | 0:8b049ccf57cb | 137 | return _time; |
shimniok | 0:8b049ccf57cb | 138 | } |
shimniok | 0:8b049ccf57cb | 139 | |
shimniok | 0:8b049ccf57cb | 140 | |
shimniok | 0:8b049ccf57cb | 141 |