geographiclib 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|