geographiclib 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +12 -0
- data/LICENSE +24 -0
- data/ext/geographiclib/Accumulator.cpp +23 -0
- data/ext/geographiclib/AlbersEqualArea.cpp +445 -0
- data/ext/geographiclib/AzimuthalEquidistant.cpp +41 -0
- data/ext/geographiclib/CassiniSoldner.cpp +89 -0
- data/ext/geographiclib/CircularEngine.cpp +96 -0
- data/ext/geographiclib/DMS.cpp +381 -0
- data/ext/geographiclib/Ellipsoid.cpp +125 -0
- data/ext/geographiclib/EllipticFunction.cpp +512 -0
- data/ext/geographiclib/GARS.cpp +122 -0
- data/ext/geographiclib/GeoCoords.cpp +175 -0
- data/ext/geographiclib/Geocentric.cpp +172 -0
- data/ext/geographiclib/Geodesic.cpp +1908 -0
- data/ext/geographiclib/GeodesicExact.cpp +927 -0
- data/ext/geographiclib/GeodesicExactC4.cpp +7879 -0
- data/ext/geographiclib/GeodesicLine.cpp +321 -0
- data/ext/geographiclib/GeodesicLineExact.cpp +289 -0
- data/ext/geographiclib/GeographicLib/Accumulator.hpp +184 -0
- data/ext/geographiclib/GeographicLib/AlbersEqualArea.hpp +312 -0
- data/ext/geographiclib/GeographicLib/AzimuthalEquidistant.hpp +139 -0
- data/ext/geographiclib/GeographicLib/CassiniSoldner.hpp +204 -0
- data/ext/geographiclib/GeographicLib/CircularEngine.hpp +195 -0
- data/ext/geographiclib/GeographicLib/Config.h +12 -0
- data/ext/geographiclib/GeographicLib/Constants.hpp +387 -0
- data/ext/geographiclib/GeographicLib/DMS.hpp +370 -0
- data/ext/geographiclib/GeographicLib/Ellipsoid.hpp +534 -0
- data/ext/geographiclib/GeographicLib/EllipticFunction.hpp +692 -0
- data/ext/geographiclib/GeographicLib/GARS.hpp +143 -0
- data/ext/geographiclib/GeographicLib/GeoCoords.hpp +544 -0
- data/ext/geographiclib/GeographicLib/Geocentric.hpp +267 -0
- data/ext/geographiclib/GeographicLib/Geodesic.hpp +970 -0
- data/ext/geographiclib/GeographicLib/GeodesicExact.hpp +862 -0
- data/ext/geographiclib/GeographicLib/GeodesicLine.hpp +701 -0
- data/ext/geographiclib/GeographicLib/GeodesicLineExact.hpp +667 -0
- data/ext/geographiclib/GeographicLib/Geohash.hpp +180 -0
- data/ext/geographiclib/GeographicLib/Geoid.hpp +472 -0
- data/ext/geographiclib/GeographicLib/Georef.hpp +160 -0
- data/ext/geographiclib/GeographicLib/Gnomonic.hpp +206 -0
- data/ext/geographiclib/GeographicLib/GravityCircle.hpp +301 -0
- data/ext/geographiclib/GeographicLib/GravityModel.hpp +520 -0
- data/ext/geographiclib/GeographicLib/LambertConformalConic.hpp +313 -0
- data/ext/geographiclib/GeographicLib/LocalCartesian.hpp +236 -0
- data/ext/geographiclib/GeographicLib/MGRS.hpp +355 -0
- data/ext/geographiclib/GeographicLib/MagneticCircle.hpp +178 -0
- data/ext/geographiclib/GeographicLib/MagneticModel.hpp +347 -0
- data/ext/geographiclib/GeographicLib/Math.hpp +920 -0
- data/ext/geographiclib/GeographicLib/NormalGravity.hpp +350 -0
- data/ext/geographiclib/GeographicLib/OSGB.hpp +249 -0
- data/ext/geographiclib/GeographicLib/PolarStereographic.hpp +150 -0
- data/ext/geographiclib/GeographicLib/PolygonArea.hpp +288 -0
- data/ext/geographiclib/GeographicLib/Rhumb.hpp +589 -0
- data/ext/geographiclib/GeographicLib/SphericalEngine.hpp +376 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic.hpp +354 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic1.hpp +281 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic2.hpp +315 -0
- data/ext/geographiclib/GeographicLib/TransverseMercator.hpp +196 -0
- data/ext/geographiclib/GeographicLib/TransverseMercatorExact.hpp +254 -0
- data/ext/geographiclib/GeographicLib/UTMUPS.hpp +421 -0
- data/ext/geographiclib/GeographicLib/Utility.hpp +612 -0
- data/ext/geographiclib/Geohash.cpp +102 -0
- data/ext/geographiclib/Geoid.cpp +509 -0
- data/ext/geographiclib/Georef.cpp +135 -0
- data/ext/geographiclib/Gnomonic.cpp +85 -0
- data/ext/geographiclib/GravityCircle.cpp +129 -0
- data/ext/geographiclib/GravityModel.cpp +360 -0
- data/ext/geographiclib/LambertConformalConic.cpp +456 -0
- data/ext/geographiclib/LocalCartesian.cpp +62 -0
- data/ext/geographiclib/MGRS.cpp +461 -0
- data/ext/geographiclib/MagneticCircle.cpp +52 -0
- data/ext/geographiclib/MagneticModel.cpp +269 -0
- data/ext/geographiclib/Math.cpp +63 -0
- data/ext/geographiclib/NormalGravity.cpp +262 -0
- data/ext/geographiclib/OSGB.cpp +167 -0
- data/ext/geographiclib/PolarStereographic.cpp +108 -0
- data/ext/geographiclib/PolygonArea.cpp +204 -0
- data/ext/geographiclib/Rhumb.cpp +383 -0
- data/ext/geographiclib/SphericalEngine.cpp +477 -0
- data/ext/geographiclib/TransverseMercator.cpp +603 -0
- data/ext/geographiclib/TransverseMercatorExact.cpp +464 -0
- data/ext/geographiclib/UTMUPS.cpp +296 -0
- data/ext/geographiclib/Utility.cpp +61 -0
- data/ext/geographiclib/extconf.rb +3 -0
- data/ext/geographiclib/geographiclib.cpp +62 -0
- data/lib/geographiclib.rb +20 -0
- metadata +140 -0
@@ -0,0 +1,296 @@
|
|
1
|
+
/**
|
2
|
+
* \file UTMUPS.cpp
|
3
|
+
* \brief Implementation for GeographicLib::UTMUPS class
|
4
|
+
*
|
5
|
+
* Copyright (c) Charles Karney (2008-2015) <charles@karney.com> and licensed
|
6
|
+
* under the MIT/X11 License. For more information, see
|
7
|
+
* http://geographiclib.sourceforge.net/
|
8
|
+
**********************************************************************/
|
9
|
+
|
10
|
+
#include <GeographicLib/UTMUPS.hpp>
|
11
|
+
#include <GeographicLib/MGRS.hpp>
|
12
|
+
#include <GeographicLib/PolarStereographic.hpp>
|
13
|
+
#include <GeographicLib/TransverseMercator.hpp>
|
14
|
+
#include <GeographicLib/Utility.hpp>
|
15
|
+
|
16
|
+
namespace GeographicLib {
|
17
|
+
|
18
|
+
using namespace std;
|
19
|
+
|
20
|
+
const int UTMUPS::falseeasting_[4] =
|
21
|
+
{ MGRS::upseasting_ * MGRS::tile_, MGRS::upseasting_ * MGRS::tile_,
|
22
|
+
MGRS::utmeasting_ * MGRS::tile_, MGRS::utmeasting_ * MGRS::tile_ };
|
23
|
+
const int UTMUPS::falsenorthing_[4] =
|
24
|
+
{ MGRS::upseasting_ * MGRS::tile_, MGRS::upseasting_ * MGRS::tile_,
|
25
|
+
MGRS::maxutmSrow_ * MGRS::tile_, MGRS::minutmNrow_ * MGRS::tile_ };
|
26
|
+
const int UTMUPS::mineasting_[4] =
|
27
|
+
{ MGRS::minupsSind_ * MGRS::tile_, MGRS::minupsNind_ * MGRS::tile_,
|
28
|
+
MGRS::minutmcol_ * MGRS::tile_, MGRS::minutmcol_ * MGRS::tile_ };
|
29
|
+
const int UTMUPS::maxeasting_[4] =
|
30
|
+
{ MGRS::maxupsSind_ * MGRS::tile_, MGRS::maxupsNind_ * MGRS::tile_,
|
31
|
+
MGRS::maxutmcol_ * MGRS::tile_, MGRS::maxutmcol_ * MGRS::tile_ };
|
32
|
+
const int UTMUPS::minnorthing_[4] =
|
33
|
+
{ MGRS::minupsSind_ * MGRS::tile_, MGRS::minupsNind_ * MGRS::tile_,
|
34
|
+
MGRS::minutmSrow_ * MGRS::tile_,
|
35
|
+
(MGRS::minutmNrow_ + MGRS::minutmSrow_ - MGRS::maxutmSrow_)
|
36
|
+
* MGRS::tile_ };
|
37
|
+
const int UTMUPS::maxnorthing_[4] =
|
38
|
+
{ MGRS::maxupsSind_ * MGRS::tile_, MGRS::maxupsNind_ * MGRS::tile_,
|
39
|
+
(MGRS::maxutmSrow_ + MGRS::maxutmNrow_ - MGRS::minutmNrow_) * MGRS::tile_,
|
40
|
+
MGRS::maxutmNrow_ * MGRS::tile_ };
|
41
|
+
|
42
|
+
int UTMUPS::StandardZone(real lat, real lon, int setzone) {
|
43
|
+
if (!(setzone >= MINPSEUDOZONE && setzone <= MAXZONE))
|
44
|
+
throw GeographicErr("Illegal zone requested " + Utility::str(setzone));
|
45
|
+
if (setzone >= MINZONE || setzone == INVALID)
|
46
|
+
return setzone;
|
47
|
+
if (Math::isnan(lat) || Math::isnan(lon)) // Check if lat or lon is a NaN
|
48
|
+
return INVALID;
|
49
|
+
if (setzone == UTM || (lat >= -80 && lat < 84)) {
|
50
|
+
int ilon = int(floor(fmod(lon, real(360))));
|
51
|
+
if (ilon >= 180)
|
52
|
+
ilon -= 360;
|
53
|
+
else if (ilon < -180)
|
54
|
+
ilon += 360;
|
55
|
+
int zone = (ilon + 186)/6;
|
56
|
+
int band = MGRS::LatitudeBand(lat);
|
57
|
+
if (band == 7 && zone == 31 && ilon >= 3)
|
58
|
+
zone = 32;
|
59
|
+
else if (band == 9 && ilon >= 0 && ilon < 42)
|
60
|
+
zone = 2 * ((ilon + 183)/12) + 1;
|
61
|
+
return zone;
|
62
|
+
} else
|
63
|
+
return UPS;
|
64
|
+
}
|
65
|
+
|
66
|
+
void UTMUPS::Forward(real lat, real lon,
|
67
|
+
int& zone, bool& northp, real& x, real& y,
|
68
|
+
real& gamma, real& k,
|
69
|
+
int setzone, bool mgrslimits) {
|
70
|
+
if (abs(lat) > 90)
|
71
|
+
throw GeographicErr("Latitude " + Utility::str(lat)
|
72
|
+
+ "d not in [-90d, 90d]");
|
73
|
+
bool northp1 = lat >= 0;
|
74
|
+
int zone1 = StandardZone(lat, lon, setzone);
|
75
|
+
if (zone1 == INVALID) {
|
76
|
+
zone = zone1;
|
77
|
+
northp = northp1;
|
78
|
+
x = y = gamma = k = Math::NaN();
|
79
|
+
return;
|
80
|
+
}
|
81
|
+
real x1, y1, gamma1, k1;
|
82
|
+
bool utmp = zone1 != UPS;
|
83
|
+
if (utmp) {
|
84
|
+
real
|
85
|
+
lon0 = CentralMeridian(zone1),
|
86
|
+
dlon = lon - lon0;
|
87
|
+
dlon = abs(dlon - 360 * floor((dlon + 180)/360));
|
88
|
+
if (!(dlon <= 60))
|
89
|
+
// Check isn't really necessary because CheckCoords catches this case.
|
90
|
+
// But this allows a more meaningful error message to be given.
|
91
|
+
throw GeographicErr("Longitude " + Utility::str(lon)
|
92
|
+
+ "d more than 60d from center of UTM zone "
|
93
|
+
+ Utility::str(zone1));
|
94
|
+
TransverseMercator::UTM().Forward(lon0, lat, lon, x1, y1, gamma1, k1);
|
95
|
+
} else {
|
96
|
+
if (abs(lat) < 70)
|
97
|
+
// Check isn't really necessary ... (see above).
|
98
|
+
throw GeographicErr("Latitude " + Utility::str(lat)
|
99
|
+
+ "d more than 20d from "
|
100
|
+
+ (northp1 ? "N" : "S") + " pole");
|
101
|
+
PolarStereographic::UPS().Forward(northp1, lat, lon, x1, y1, gamma1, k1);
|
102
|
+
}
|
103
|
+
int ind = (utmp ? 2 : 0) + (northp1 ? 1 : 0);
|
104
|
+
x1 += falseeasting_[ind];
|
105
|
+
y1 += falsenorthing_[ind];
|
106
|
+
if (! CheckCoords(zone1 != UPS, northp1, x1, y1, mgrslimits, false) )
|
107
|
+
throw GeographicErr("Latitude " + Utility::str(lat)
|
108
|
+
+ ", longitude " + Utility::str(lon)
|
109
|
+
+ " out of legal range for "
|
110
|
+
+ (utmp ? "UTM zone " + Utility::str(zone1) : "UPS"));
|
111
|
+
zone = zone1;
|
112
|
+
northp = northp1;
|
113
|
+
x = x1;
|
114
|
+
y = y1;
|
115
|
+
gamma = gamma1;
|
116
|
+
k = k1;
|
117
|
+
}
|
118
|
+
|
119
|
+
void UTMUPS::Reverse(int zone, bool northp, real x, real y,
|
120
|
+
real& lat, real& lon, real& gamma, real& k,
|
121
|
+
bool mgrslimits) {
|
122
|
+
if (zone == INVALID || Math::isnan(x) || Math::isnan(y)) {
|
123
|
+
lat = lon = gamma = k = Math::NaN();
|
124
|
+
return;
|
125
|
+
}
|
126
|
+
if (!(zone >= MINZONE && zone <= MAXZONE))
|
127
|
+
throw GeographicErr("Zone " + Utility::str(zone)
|
128
|
+
+ " not in range [0, 60]");
|
129
|
+
bool utmp = zone != UPS;
|
130
|
+
CheckCoords(utmp, northp, x, y, mgrslimits);
|
131
|
+
int ind = (utmp ? 2 : 0) + (northp ? 1 : 0);
|
132
|
+
x -= falseeasting_[ind];
|
133
|
+
y -= falsenorthing_[ind];
|
134
|
+
if (utmp)
|
135
|
+
TransverseMercator::UTM().Reverse(CentralMeridian(zone),
|
136
|
+
x, y, lat, lon, gamma, k);
|
137
|
+
else
|
138
|
+
PolarStereographic::UPS().Reverse(northp, x, y, lat, lon, gamma, k);
|
139
|
+
}
|
140
|
+
|
141
|
+
bool UTMUPS::CheckCoords(bool utmp, bool northp, real x, real y,
|
142
|
+
bool mgrslimits, bool throwp) {
|
143
|
+
// Limits are all multiples of 100km and are all closed on the both ends.
|
144
|
+
// Failure tests are such that NaNs succeed.
|
145
|
+
real slop = mgrslimits ? 0 : MGRS::tile_;
|
146
|
+
int ind = (utmp ? 2 : 0) + (northp ? 1 : 0);
|
147
|
+
if (x < mineasting_[ind] - slop || x > maxeasting_[ind] + slop) {
|
148
|
+
if (!throwp) return false;
|
149
|
+
throw GeographicErr("Easting " + Utility::str(x/1000) + "km not in "
|
150
|
+
+ (mgrslimits ? "MGRS/" : "")
|
151
|
+
+ (utmp ? "UTM" : "UPS") + " range for "
|
152
|
+
+ (northp ? "N" : "S" ) + " hemisphere ["
|
153
|
+
+ Utility::str((mineasting_[ind] - slop)/1000)
|
154
|
+
+ "km, "
|
155
|
+
+ Utility::str((maxeasting_[ind] + slop)/1000)
|
156
|
+
+ "km]");
|
157
|
+
}
|
158
|
+
if (y < minnorthing_[ind] - slop || y > maxnorthing_[ind] + slop) {
|
159
|
+
if (!throwp) return false;
|
160
|
+
throw GeographicErr("Northing " + Utility::str(y/1000) + "km not in "
|
161
|
+
+ (mgrslimits ? "MGRS/" : "")
|
162
|
+
+ (utmp ? "UTM" : "UPS") + " range for "
|
163
|
+
+ (northp ? "N" : "S" ) + " hemisphere ["
|
164
|
+
+ Utility::str((minnorthing_[ind] - slop)/1000)
|
165
|
+
+ "km, "
|
166
|
+
+ Utility::str((maxnorthing_[ind] + slop)/1000)
|
167
|
+
+ "km]");
|
168
|
+
}
|
169
|
+
return true;
|
170
|
+
}
|
171
|
+
|
172
|
+
void UTMUPS::Transfer(int zonein, bool northpin, real xin, real yin,
|
173
|
+
int zoneout, bool northpout, real& xout, real& yout,
|
174
|
+
int& zone) {
|
175
|
+
bool northp = northpin;
|
176
|
+
if (zonein != zoneout) {
|
177
|
+
// Determine lat, lon
|
178
|
+
real lat, lon;
|
179
|
+
GeographicLib::UTMUPS::Reverse(zonein, northpin, xin, yin, lat, lon);
|
180
|
+
// Try converting to zoneout
|
181
|
+
real x, y;
|
182
|
+
int zone1;
|
183
|
+
GeographicLib::UTMUPS::Forward(lat, lon, zone1, northp, x, y,
|
184
|
+
zoneout == UTMUPS::MATCH
|
185
|
+
? zonein : zoneout);
|
186
|
+
if (zone1 == 0 && northp != northpout)
|
187
|
+
throw GeographicErr
|
188
|
+
("Attempt to transfer UPS coordinates between hemispheres");
|
189
|
+
zone = zone1;
|
190
|
+
xout = x;
|
191
|
+
yout = y;
|
192
|
+
} else {
|
193
|
+
if (zoneout == 0 && northp != northpout)
|
194
|
+
throw GeographicErr
|
195
|
+
("Attempt to transfer UPS coordinates between hemispheres");
|
196
|
+
zone = zoneout;
|
197
|
+
xout = xin;
|
198
|
+
yout = yin;
|
199
|
+
}
|
200
|
+
if (northp != northpout)
|
201
|
+
// Can't get here if UPS
|
202
|
+
yout += (northpout ? -1 : 1) * MGRS::utmNshift_;
|
203
|
+
return;
|
204
|
+
}
|
205
|
+
|
206
|
+
void UTMUPS::DecodeZone(const std::string& zonestr, int& zone, bool& northp) {
|
207
|
+
unsigned zlen = unsigned(zonestr.size());
|
208
|
+
if (zlen == 0)
|
209
|
+
throw GeographicErr("Empty zone specification");
|
210
|
+
// Longest zone spec is 32north, 42south, invalid = 7
|
211
|
+
if (zlen > 7)
|
212
|
+
throw GeographicErr("More than 7 characters in zone specification "
|
213
|
+
+ zonestr);
|
214
|
+
|
215
|
+
const char* c = zonestr.c_str();
|
216
|
+
char* q;
|
217
|
+
int zone1 = strtol(c, &q, 10);
|
218
|
+
// if (zone1 == 0) zone1 = UPS; (not necessary)
|
219
|
+
|
220
|
+
if (zone1 == UPS) {
|
221
|
+
if (!(q == c))
|
222
|
+
// Don't allow 0n as an alternative to n for UPS coordinates
|
223
|
+
throw GeographicErr("Illegal zone 0 in " + zonestr +
|
224
|
+
", use just the hemisphere for UPS");
|
225
|
+
} else if (!(zone1 >= MINUTMZONE && zone1 <= MAXUTMZONE))
|
226
|
+
throw GeographicErr("Zone " + Utility::str(zone1)
|
227
|
+
+ " not in range [1, 60]");
|
228
|
+
else if (!isdigit(zonestr[0]))
|
229
|
+
throw GeographicErr("Must use unsigned number for zone "
|
230
|
+
+ Utility::str(zone1));
|
231
|
+
else if (q - c > 2)
|
232
|
+
throw GeographicErr("More than 2 digits use to specify zone "
|
233
|
+
+ Utility::str(zone1));
|
234
|
+
|
235
|
+
string hemi = zonestr.substr(q - c);
|
236
|
+
transform(hemi.begin(), hemi.end(), hemi.begin(), (int(*)(int))tolower);
|
237
|
+
if (q == c && (hemi == "inv" || hemi == "invalid")) {
|
238
|
+
zone = INVALID;
|
239
|
+
northp = false;
|
240
|
+
return;
|
241
|
+
}
|
242
|
+
bool northp1 = hemi == "north" || hemi == "n";
|
243
|
+
if (!(northp1 || hemi == "south" || hemi == "s"))
|
244
|
+
throw GeographicErr(string("Illegal hemisphere ") + hemi + " in "
|
245
|
+
+ zonestr + ", specify north or south");
|
246
|
+
zone = zone1;
|
247
|
+
northp = northp1;
|
248
|
+
}
|
249
|
+
|
250
|
+
std::string UTMUPS::EncodeZone(int zone, bool northp, bool abbrev) {
|
251
|
+
if (zone == INVALID)
|
252
|
+
return string(abbrev ? "inv" : "invalid");
|
253
|
+
if (!(zone >= MINZONE && zone <= MAXZONE))
|
254
|
+
throw GeographicErr("Zone " + Utility::str(zone)
|
255
|
+
+ " not in range [0, 60]");
|
256
|
+
ostringstream os;
|
257
|
+
if (zone != UPS)
|
258
|
+
os << setfill('0') << setw(2) << zone;
|
259
|
+
if (abbrev)
|
260
|
+
os << (northp ? 'n' : 's');
|
261
|
+
else
|
262
|
+
os << (northp ? "north" : "south");
|
263
|
+
return os.str();
|
264
|
+
}
|
265
|
+
|
266
|
+
void UTMUPS::DecodeEPSG(int epsg, int& zone, bool& northp) {
|
267
|
+
northp = false;
|
268
|
+
if (epsg >= epsg01N && epsg <= epsg60N) {
|
269
|
+
zone = (epsg - epsg01N) + MINUTMZONE;
|
270
|
+
northp = true;
|
271
|
+
} else if (epsg == epsgN) {
|
272
|
+
zone = UPS;
|
273
|
+
northp = true;
|
274
|
+
} else if (epsg >= epsg01S && epsg <= epsg60S) {
|
275
|
+
zone = (epsg - epsg01S) + MINUTMZONE;
|
276
|
+
} else if (epsg == epsgS) {
|
277
|
+
zone = UPS;
|
278
|
+
} else {
|
279
|
+
zone = INVALID;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
int UTMUPS::EncodeEPSG(int zone, bool northp) {
|
284
|
+
int epsg = -1;
|
285
|
+
if (zone == UPS)
|
286
|
+
epsg = epsgS;
|
287
|
+
else if (zone >= MINUTMZONE && zone <= MAXUTMZONE)
|
288
|
+
epsg = (zone - MINUTMZONE) + epsg01S;
|
289
|
+
if (epsg >= 0 && northp)
|
290
|
+
epsg += epsgN - epsgS;
|
291
|
+
return epsg;
|
292
|
+
}
|
293
|
+
|
294
|
+
Math::real UTMUPS::UTMShift() { return real(MGRS::utmNshift_); }
|
295
|
+
|
296
|
+
} // namespace GeographicLib
|
@@ -0,0 +1,61 @@
|
|
1
|
+
/**
|
2
|
+
* \file Utility.cpp
|
3
|
+
* \brief Implementation for GeographicLib::Utility class
|
4
|
+
*
|
5
|
+
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed under
|
6
|
+
* the MIT/X11 License. For more information, see
|
7
|
+
* http://geographiclib.sourceforge.net/
|
8
|
+
**********************************************************************/
|
9
|
+
|
10
|
+
#include <cstdlib>
|
11
|
+
#include <GeographicLib/Utility.hpp>
|
12
|
+
|
13
|
+
#if defined(_MSC_VER)
|
14
|
+
// Squelch warnings about unsafe use of getenv
|
15
|
+
# pragma warning (disable: 4996)
|
16
|
+
#endif
|
17
|
+
|
18
|
+
namespace GeographicLib {
|
19
|
+
|
20
|
+
using namespace std;
|
21
|
+
|
22
|
+
bool Utility::ParseLine(const std::string& line,
|
23
|
+
std::string& key, std::string& val) {
|
24
|
+
const char* spaces = " \t\n\v\f\r";
|
25
|
+
string::size_type n0 = line.find_first_not_of(spaces);
|
26
|
+
if (n0 == string::npos)
|
27
|
+
return false; // Blank line
|
28
|
+
string::size_type n1 = line.find_first_of('#', n0);
|
29
|
+
if (n0 == n1)
|
30
|
+
return false; // Only a comment
|
31
|
+
val = line.substr(n0, n1 == string::npos ? n1 : n1 - n0);
|
32
|
+
n0 = val.find_first_of(spaces);
|
33
|
+
key = val.substr(0, n0);
|
34
|
+
if (n0 == string::npos) {
|
35
|
+
val = "";
|
36
|
+
return true;
|
37
|
+
}
|
38
|
+
n0 = val.find_first_not_of(spaces, n0);
|
39
|
+
if (n0 == string::npos) {
|
40
|
+
val = "";
|
41
|
+
return true;
|
42
|
+
}
|
43
|
+
n1 = val.find_last_not_of(spaces);
|
44
|
+
val = val.substr(n0, n1 + 1 - n0);
|
45
|
+
return true;
|
46
|
+
}
|
47
|
+
|
48
|
+
int Utility::set_digits(int ndigits) {
|
49
|
+
#if GEOGRAPHICLIB_PRECISION == 5
|
50
|
+
if (ndigits <= 0) {
|
51
|
+
char* digitenv = getenv("GEOGRAPHICLIB_DIGITS");
|
52
|
+
if (digitenv)
|
53
|
+
ndigits = strtol(digitenv, NULL, 0);
|
54
|
+
if (ndigits <= 0)
|
55
|
+
ndigits = 256;
|
56
|
+
}
|
57
|
+
#endif
|
58
|
+
return Math::set_digits(ndigits);
|
59
|
+
}
|
60
|
+
|
61
|
+
} // namespace GeographicLib
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <GeographicLib/Constants.hpp>
|
3
|
+
#include <GeographicLib/Geodesic.hpp>
|
4
|
+
|
5
|
+
static VALUE geographiclib_geodesic_direct(VALUE self, VALUE a, VALUE f, VALUE vlat1, VALUE vlon1, VALUE vazi1, VALUE arcmode, VALUE vs12_a12)
|
6
|
+
{
|
7
|
+
GeographicLib::Geodesic g(NUM2DBL(a), NUM2DBL(f));
|
8
|
+
GeographicLib::Math::real lat1, lon1, s12_a12, lat2, lon2, s12, azi1, azi2, m12, M12, M21, S12;
|
9
|
+
lat1 = NUM2DBL(vlat1);
|
10
|
+
lon1 = NUM2DBL(vlon1);
|
11
|
+
azi1 = NUM2DBL(vazi1);
|
12
|
+
s12_a12 = NUM2DBL(vs12_a12);
|
13
|
+
g.GenDirect(lat1, lon1, azi1, arcmode, s12_a12, GeographicLib::Geodesic::ALL, lat2, lon2, azi2, s12, m12, M12, M21, S12);
|
14
|
+
VALUE r = rb_hash_new();
|
15
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lat1")), DBL2NUM(lat1));
|
16
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lon1")), DBL2NUM(lon1));
|
17
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lat2")), DBL2NUM(lat2));
|
18
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lon2")), DBL2NUM(lon2));
|
19
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("s12")), DBL2NUM(s12));
|
20
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("azi1")), DBL2NUM(azi1));
|
21
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("azi2")), DBL2NUM(azi2));
|
22
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("m12")), DBL2NUM(m12));
|
23
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("M12")), DBL2NUM(M12));
|
24
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("M21")), DBL2NUM(M21));
|
25
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("S12")), DBL2NUM(S12));
|
26
|
+
return r;
|
27
|
+
}
|
28
|
+
|
29
|
+
static VALUE geographiclib_geodesic_inverse(VALUE self, VALUE a, VALUE f, VALUE vlat1, VALUE vlon1, VALUE vlat2, VALUE vlon2)
|
30
|
+
{
|
31
|
+
GeographicLib::Geodesic g(NUM2DBL(a), NUM2DBL(f));
|
32
|
+
GeographicLib::Math::real lat1, lon1, lat2, lon2, s12, azi1, azi2, m12, M12, M21, S12;
|
33
|
+
lat1 = NUM2DBL(vlat1);
|
34
|
+
lon1 = NUM2DBL(vlon1);
|
35
|
+
lat2 = NUM2DBL(vlat2);
|
36
|
+
lon2 = NUM2DBL(vlon2);
|
37
|
+
g.GenInverse(lat1, lon1, lat2, lon2, GeographicLib::Geodesic::ALL, s12, azi1, azi2, m12, M12, M21, S12);
|
38
|
+
VALUE r = rb_hash_new();
|
39
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lat1")), DBL2NUM(lat1));
|
40
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lon1")), DBL2NUM(lon1));
|
41
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lat2")), DBL2NUM(lat2));
|
42
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("lon2")), DBL2NUM(lon2));
|
43
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("s12")), DBL2NUM(s12));
|
44
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("azi1")), DBL2NUM(azi1));
|
45
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("azi2")), DBL2NUM(azi2));
|
46
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("m12")), DBL2NUM(m12));
|
47
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("M12")), DBL2NUM(M12));
|
48
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("M21")), DBL2NUM(M21));
|
49
|
+
rb_hash_aset(r, rb_id2sym(rb_intern_const("S12")), DBL2NUM(S12));
|
50
|
+
return r;
|
51
|
+
}
|
52
|
+
|
53
|
+
extern "C" void Init_geographiclib(void)
|
54
|
+
{
|
55
|
+
VALUE geographiclib = rb_define_module("GeographicLib");
|
56
|
+
VALUE constants = rb_define_module_under(geographiclib, "Constants");
|
57
|
+
rb_define_const(constants, "WGS84_a", DBL2NUM(GeographicLib::Constants::WGS84_a()));
|
58
|
+
rb_define_const(constants, "WGS84_f", DBL2NUM(GeographicLib::Constants::WGS84_f()));
|
59
|
+
VALUE geodesic = rb_define_class_under(geographiclib, "Geodesic", rb_cObject);
|
60
|
+
rb_define_singleton_method(geodesic, "direct", (VALUE (*)(...)) geographiclib_geodesic_direct, 7);
|
61
|
+
rb_define_singleton_method(geodesic, "inverse", (VALUE (*)(...)) geographiclib_geodesic_inverse, 6);
|
62
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'geographiclib/geographiclib'
|
2
|
+
|
3
|
+
module GeographicLib
|
4
|
+
class Geodesic
|
5
|
+
def initialize a, f
|
6
|
+
@a = a
|
7
|
+
@f = f
|
8
|
+
end
|
9
|
+
|
10
|
+
def direct lat1, lon1, azi1, arcmode, s12_a12
|
11
|
+
Geodesic.direct @a, @f, lat1, lon1, azi1, !!arcmode, s12_a12
|
12
|
+
end
|
13
|
+
|
14
|
+
def inverse lat1, lon1, lat2, lon2
|
15
|
+
Geodesic.inverse @a, @f, lat1, lon1, lat2, lon2
|
16
|
+
end
|
17
|
+
|
18
|
+
WGS84 = Geodesic.new Constants::WGS84_a, Constants::WGS84_f
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: geographiclib
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charles Karney <charles@karney.com>
|
8
|
+
- Francesco Paolo Lovergine <frankie@debian.org> (autoconfiscation)
|
9
|
+
- Mathieu Peyréga <mathieu.peyrega@gmail.com> (help with gravity models)
|
10
|
+
- Andrew MacIntyre <Andrew.MacIntyre@acma.gov.au> (python/setup.py)
|
11
|
+
- Skip Breidbach <skip@waywally.com> (maven support for Java)
|
12
|
+
- Scott Heiman <mrmtdew2@outlook.com> (.NET wrappers + C# examples)
|
13
|
+
- Chris Bennight <chris@bennight.com> (deploying Java library)
|
14
|
+
- Sebastian Mattheis <Sebastian.Mattheis@bmw.de> (gnomonic projection in Java)
|
15
|
+
- Yurij Mikhalevich <0@39.yt> (node.js port)
|
16
|
+
- Phil Miller <phillip.miller@sri.com> (putting tests into python/setup.py)
|
17
|
+
- Jonathan Takahashi <jtakahashi@gmail.com> (boost-python sample)
|
18
|
+
- Lukas Joeressen <lukas@joeressen.net> (Ruby wrapper)
|
19
|
+
autorequire:
|
20
|
+
bindir: bin
|
21
|
+
cert_chain: []
|
22
|
+
date: 2016-02-28 00:00:00.000000000 Z
|
23
|
+
dependencies: []
|
24
|
+
description: A wrapper for GeograpicLib.
|
25
|
+
email: "—"
|
26
|
+
executables: []
|
27
|
+
extensions:
|
28
|
+
- ext/geographiclib/extconf.rb
|
29
|
+
extra_rdoc_files: []
|
30
|
+
files:
|
31
|
+
- AUTHORS
|
32
|
+
- LICENSE
|
33
|
+
- ext/geographiclib/Accumulator.cpp
|
34
|
+
- ext/geographiclib/AlbersEqualArea.cpp
|
35
|
+
- ext/geographiclib/AzimuthalEquidistant.cpp
|
36
|
+
- ext/geographiclib/CassiniSoldner.cpp
|
37
|
+
- ext/geographiclib/CircularEngine.cpp
|
38
|
+
- ext/geographiclib/DMS.cpp
|
39
|
+
- ext/geographiclib/Ellipsoid.cpp
|
40
|
+
- ext/geographiclib/EllipticFunction.cpp
|
41
|
+
- ext/geographiclib/GARS.cpp
|
42
|
+
- ext/geographiclib/GeoCoords.cpp
|
43
|
+
- ext/geographiclib/Geocentric.cpp
|
44
|
+
- ext/geographiclib/Geodesic.cpp
|
45
|
+
- ext/geographiclib/GeodesicExact.cpp
|
46
|
+
- ext/geographiclib/GeodesicExactC4.cpp
|
47
|
+
- ext/geographiclib/GeodesicLine.cpp
|
48
|
+
- ext/geographiclib/GeodesicLineExact.cpp
|
49
|
+
- ext/geographiclib/GeographicLib/Accumulator.hpp
|
50
|
+
- ext/geographiclib/GeographicLib/AlbersEqualArea.hpp
|
51
|
+
- ext/geographiclib/GeographicLib/AzimuthalEquidistant.hpp
|
52
|
+
- ext/geographiclib/GeographicLib/CassiniSoldner.hpp
|
53
|
+
- ext/geographiclib/GeographicLib/CircularEngine.hpp
|
54
|
+
- ext/geographiclib/GeographicLib/Config.h
|
55
|
+
- ext/geographiclib/GeographicLib/Constants.hpp
|
56
|
+
- ext/geographiclib/GeographicLib/DMS.hpp
|
57
|
+
- ext/geographiclib/GeographicLib/Ellipsoid.hpp
|
58
|
+
- ext/geographiclib/GeographicLib/EllipticFunction.hpp
|
59
|
+
- ext/geographiclib/GeographicLib/GARS.hpp
|
60
|
+
- ext/geographiclib/GeographicLib/GeoCoords.hpp
|
61
|
+
- ext/geographiclib/GeographicLib/Geocentric.hpp
|
62
|
+
- ext/geographiclib/GeographicLib/Geodesic.hpp
|
63
|
+
- ext/geographiclib/GeographicLib/GeodesicExact.hpp
|
64
|
+
- ext/geographiclib/GeographicLib/GeodesicLine.hpp
|
65
|
+
- ext/geographiclib/GeographicLib/GeodesicLineExact.hpp
|
66
|
+
- ext/geographiclib/GeographicLib/Geohash.hpp
|
67
|
+
- ext/geographiclib/GeographicLib/Geoid.hpp
|
68
|
+
- ext/geographiclib/GeographicLib/Georef.hpp
|
69
|
+
- ext/geographiclib/GeographicLib/Gnomonic.hpp
|
70
|
+
- ext/geographiclib/GeographicLib/GravityCircle.hpp
|
71
|
+
- ext/geographiclib/GeographicLib/GravityModel.hpp
|
72
|
+
- ext/geographiclib/GeographicLib/LambertConformalConic.hpp
|
73
|
+
- ext/geographiclib/GeographicLib/LocalCartesian.hpp
|
74
|
+
- ext/geographiclib/GeographicLib/MGRS.hpp
|
75
|
+
- ext/geographiclib/GeographicLib/MagneticCircle.hpp
|
76
|
+
- ext/geographiclib/GeographicLib/MagneticModel.hpp
|
77
|
+
- ext/geographiclib/GeographicLib/Math.hpp
|
78
|
+
- ext/geographiclib/GeographicLib/NormalGravity.hpp
|
79
|
+
- ext/geographiclib/GeographicLib/OSGB.hpp
|
80
|
+
- ext/geographiclib/GeographicLib/PolarStereographic.hpp
|
81
|
+
- ext/geographiclib/GeographicLib/PolygonArea.hpp
|
82
|
+
- ext/geographiclib/GeographicLib/Rhumb.hpp
|
83
|
+
- ext/geographiclib/GeographicLib/SphericalEngine.hpp
|
84
|
+
- ext/geographiclib/GeographicLib/SphericalHarmonic.hpp
|
85
|
+
- ext/geographiclib/GeographicLib/SphericalHarmonic1.hpp
|
86
|
+
- ext/geographiclib/GeographicLib/SphericalHarmonic2.hpp
|
87
|
+
- ext/geographiclib/GeographicLib/TransverseMercator.hpp
|
88
|
+
- ext/geographiclib/GeographicLib/TransverseMercatorExact.hpp
|
89
|
+
- ext/geographiclib/GeographicLib/UTMUPS.hpp
|
90
|
+
- ext/geographiclib/GeographicLib/Utility.hpp
|
91
|
+
- ext/geographiclib/Geohash.cpp
|
92
|
+
- ext/geographiclib/Geoid.cpp
|
93
|
+
- ext/geographiclib/Georef.cpp
|
94
|
+
- ext/geographiclib/Gnomonic.cpp
|
95
|
+
- ext/geographiclib/GravityCircle.cpp
|
96
|
+
- ext/geographiclib/GravityModel.cpp
|
97
|
+
- ext/geographiclib/LambertConformalConic.cpp
|
98
|
+
- ext/geographiclib/LocalCartesian.cpp
|
99
|
+
- ext/geographiclib/MGRS.cpp
|
100
|
+
- ext/geographiclib/MagneticCircle.cpp
|
101
|
+
- ext/geographiclib/MagneticModel.cpp
|
102
|
+
- ext/geographiclib/Math.cpp
|
103
|
+
- ext/geographiclib/NormalGravity.cpp
|
104
|
+
- ext/geographiclib/OSGB.cpp
|
105
|
+
- ext/geographiclib/PolarStereographic.cpp
|
106
|
+
- ext/geographiclib/PolygonArea.cpp
|
107
|
+
- ext/geographiclib/Rhumb.cpp
|
108
|
+
- ext/geographiclib/SphericalEngine.cpp
|
109
|
+
- ext/geographiclib/TransverseMercator.cpp
|
110
|
+
- ext/geographiclib/TransverseMercatorExact.cpp
|
111
|
+
- ext/geographiclib/UTMUPS.cpp
|
112
|
+
- ext/geographiclib/Utility.cpp
|
113
|
+
- ext/geographiclib/extconf.rb
|
114
|
+
- ext/geographiclib/geographiclib.cpp
|
115
|
+
- lib/geographiclib.rb
|
116
|
+
homepage: https://github.com/kext/ruby-geographiclib
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.5.1
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: GeograpicLib
|
140
|
+
test_files: []
|