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,180 @@
|
|
1
|
+
/**
|
2
|
+
* \file Geohash.hpp
|
3
|
+
* \brief Header for GeographicLib::Geohash class
|
4
|
+
*
|
5
|
+
* Copyright (c) Charles Karney (2012-2015) <charles@karney.com> and licensed
|
6
|
+
* under the MIT/X11 License. For more information, see
|
7
|
+
* http://geographiclib.sourceforge.net/
|
8
|
+
**********************************************************************/
|
9
|
+
|
10
|
+
#if !defined(GEOGRAPHICLIB_GEOHASH_HPP)
|
11
|
+
#define GEOGRAPHICLIB_GEOHASH_HPP 1
|
12
|
+
|
13
|
+
#include <GeographicLib/Constants.hpp>
|
14
|
+
|
15
|
+
#if defined(_MSC_VER)
|
16
|
+
// Squelch warnings about dll vs string
|
17
|
+
# pragma warning (push)
|
18
|
+
# pragma warning (disable: 4251)
|
19
|
+
#endif
|
20
|
+
|
21
|
+
namespace GeographicLib {
|
22
|
+
|
23
|
+
/**
|
24
|
+
* \brief Conversions for geohashes
|
25
|
+
*
|
26
|
+
* Geohashes are described in
|
27
|
+
* - https://en.wikipedia.org/wiki/Geohash
|
28
|
+
* - http://geohash.org/
|
29
|
+
* .
|
30
|
+
* They provide a compact string representation of a particular geographic
|
31
|
+
* location (expressed as latitude and longitude), with the property that if
|
32
|
+
* trailing characters are dropped from the string the geographic location
|
33
|
+
* remains nearby. The classes Georef and GARS implement similar compact
|
34
|
+
* representations.
|
35
|
+
*
|
36
|
+
* Example of use:
|
37
|
+
* \include example-Geohash.cpp
|
38
|
+
**********************************************************************/
|
39
|
+
|
40
|
+
class GEOGRAPHICLIB_EXPORT Geohash {
|
41
|
+
private:
|
42
|
+
typedef Math::real real;
|
43
|
+
static const int maxlen_ = 18;
|
44
|
+
static const unsigned long long mask_ = 1ULL << 45;
|
45
|
+
static const std::string lcdigits_;
|
46
|
+
static const std::string ucdigits_;
|
47
|
+
Geohash(); // Disable constructor
|
48
|
+
|
49
|
+
public:
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Convert from geographic coordinates to a geohash.
|
53
|
+
*
|
54
|
+
* @param[in] lat latitude of point (degrees).
|
55
|
+
* @param[in] lon longitude of point (degrees).
|
56
|
+
* @param[in] len the length of the resulting geohash.
|
57
|
+
* @param[out] geohash the geohash.
|
58
|
+
* @exception GeographicErr if \e lat is not in [−90°,
|
59
|
+
* 90°].
|
60
|
+
* @exception std::bad_alloc if memory for \e geohash can't be allocated.
|
61
|
+
*
|
62
|
+
* Internally, \e len is first put in the range [0, 18]. (\e len = 18
|
63
|
+
* provides approximately 1μm precision.)
|
64
|
+
*
|
65
|
+
* If \e lat or \e lon is NaN, the returned geohash is "invalid".
|
66
|
+
**********************************************************************/
|
67
|
+
static void Forward(real lat, real lon, int len, std::string& geohash);
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Convert from a geohash to geographic coordinates.
|
71
|
+
*
|
72
|
+
* @param[in] geohash the geohash.
|
73
|
+
* @param[out] lat latitude of point (degrees).
|
74
|
+
* @param[out] lon longitude of point (degrees).
|
75
|
+
* @param[out] len the length of the geohash.
|
76
|
+
* @param[in] centerp if true (the default) return the center of the
|
77
|
+
* geohash location, otherwise return the south-west corner.
|
78
|
+
* @exception GeographicErr if \e geohash contains illegal characters.
|
79
|
+
*
|
80
|
+
* Only the first 18 characters for \e geohash are considered. (18
|
81
|
+
* characters provides approximately 1μm precision.) The case of the
|
82
|
+
* letters in \e geohash is ignored.
|
83
|
+
*
|
84
|
+
* If the first 3 characters of \e geohash are "inv", then \e lat and \e
|
85
|
+
* lon are set to NaN and \e len is unchanged. ("nan" is treated
|
86
|
+
* similarly.)
|
87
|
+
**********************************************************************/
|
88
|
+
static void Reverse(const std::string& geohash, real& lat, real& lon,
|
89
|
+
int& len, bool centerp = true);
|
90
|
+
|
91
|
+
/**
|
92
|
+
* The latitude resolution of a geohash.
|
93
|
+
*
|
94
|
+
* @param[in] len the length of the geohash.
|
95
|
+
* @return the latitude resolution (degrees).
|
96
|
+
*
|
97
|
+
* Internally, \e len is first put in the range [0, 18].
|
98
|
+
**********************************************************************/
|
99
|
+
static Math::real LatitudeResolution(int len) {
|
100
|
+
using std::pow;
|
101
|
+
len = (std::max)(0, (std::min)(int(maxlen_), len));
|
102
|
+
return 180 * pow(real(0.5), 5 * len / 2);
|
103
|
+
}
|
104
|
+
|
105
|
+
/**
|
106
|
+
* The longitude resolution of a geohash.
|
107
|
+
*
|
108
|
+
* @param[in] len the length of the geohash.
|
109
|
+
* @return the longitude resolution (degrees).
|
110
|
+
*
|
111
|
+
* Internally, \e len is first put in the range [0, 18].
|
112
|
+
**********************************************************************/
|
113
|
+
static Math::real LongitudeResolution(int len) {
|
114
|
+
using std::pow;
|
115
|
+
len = (std::max)(0, (std::min)(int(maxlen_), len));
|
116
|
+
return 360 * pow(real(0.5), 5 * len - 5 * len / 2);
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* The geohash length required to meet a given geographic resolution.
|
121
|
+
*
|
122
|
+
* @param[in] res the minimum of resolution in latitude and longitude
|
123
|
+
* (degrees).
|
124
|
+
* @return geohash length.
|
125
|
+
*
|
126
|
+
* The returned length is in the range [0, 18].
|
127
|
+
**********************************************************************/
|
128
|
+
static int GeohashLength(real res) {
|
129
|
+
using std::abs; res = abs(res);
|
130
|
+
for (int len = 0; len < maxlen_; ++len)
|
131
|
+
if (LongitudeResolution(len) <= res)
|
132
|
+
return len;
|
133
|
+
return maxlen_;
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* The geohash length required to meet a given geographic resolution.
|
138
|
+
*
|
139
|
+
* @param[in] latres the resolution in latitude (degrees).
|
140
|
+
* @param[in] lonres the resolution in longitude (degrees).
|
141
|
+
* @return geohash length.
|
142
|
+
*
|
143
|
+
* The returned length is in the range [0, 18].
|
144
|
+
**********************************************************************/
|
145
|
+
static int GeohashLength(real latres, real lonres) {
|
146
|
+
using std::abs;
|
147
|
+
latres = abs(latres);
|
148
|
+
lonres = abs(lonres);
|
149
|
+
for (int len = 0; len < maxlen_; ++len)
|
150
|
+
if (LatitudeResolution(len) <= latres &&
|
151
|
+
LongitudeResolution(len) <= lonres)
|
152
|
+
return len;
|
153
|
+
return maxlen_;
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* The decimal geographic precision required to match a given geohash
|
158
|
+
* length. This is the number of digits needed after decimal point in a
|
159
|
+
* decimal degrees representation.
|
160
|
+
*
|
161
|
+
* @param[in] len the length of the geohash.
|
162
|
+
* @return the decimal precision (may be negative).
|
163
|
+
*
|
164
|
+
* Internally, \e len is first put in the range [0, 18]. The returned
|
165
|
+
* decimal precision is in the range [−2, 12].
|
166
|
+
**********************************************************************/
|
167
|
+
static int DecimalPrecision(int len) {
|
168
|
+
using std::floor; using std::log;
|
169
|
+
return -int(floor(log(LatitudeResolution(len))/log(Math::real(10))));
|
170
|
+
}
|
171
|
+
|
172
|
+
};
|
173
|
+
|
174
|
+
} // namespace GeographicLib
|
175
|
+
|
176
|
+
#if defined(_MSC_VER)
|
177
|
+
# pragma warning (pop)
|
178
|
+
#endif
|
179
|
+
|
180
|
+
#endif // GEOGRAPHICLIB_GEOHASH_HPP
|
@@ -0,0 +1,472 @@
|
|
1
|
+
/**
|
2
|
+
* \file Geoid.hpp
|
3
|
+
* \brief Header for GeographicLib::Geoid class
|
4
|
+
*
|
5
|
+
* Copyright (c) Charles Karney (2009-2015) <charles@karney.com> and licensed
|
6
|
+
* under the MIT/X11 License. For more information, see
|
7
|
+
* http://geographiclib.sourceforge.net/
|
8
|
+
**********************************************************************/
|
9
|
+
|
10
|
+
#if !defined(GEOGRAPHICLIB_GEOID_HPP)
|
11
|
+
#define GEOGRAPHICLIB_GEOID_HPP 1
|
12
|
+
|
13
|
+
#include <vector>
|
14
|
+
#include <fstream>
|
15
|
+
#include <GeographicLib/Constants.hpp>
|
16
|
+
|
17
|
+
#if defined(_MSC_VER)
|
18
|
+
// Squelch warnings about dll vs vector and constant conditional expressions
|
19
|
+
# pragma warning (push)
|
20
|
+
# pragma warning (disable: 4251 4127)
|
21
|
+
#endif
|
22
|
+
|
23
|
+
#if !defined(GEOGRAPHICLIB_GEOID_PGM_PIXEL_WIDTH)
|
24
|
+
/**
|
25
|
+
* The size of the pixel data in the pgm data files for the geoids. 2 is the
|
26
|
+
* standard size corresponding to a maxval 2<sup>16</sup>−1. Setting it
|
27
|
+
* to 4 uses a maxval of 2<sup>32</sup>−1 and changes the extension for
|
28
|
+
* the data files from .pgm to .pgm4. Note that the format of these pgm4 files
|
29
|
+
* is a non-standard extension of the pgm format.
|
30
|
+
**********************************************************************/
|
31
|
+
# define GEOGRAPHICLIB_GEOID_PGM_PIXEL_WIDTH 2
|
32
|
+
#endif
|
33
|
+
|
34
|
+
namespace GeographicLib {
|
35
|
+
|
36
|
+
/**
|
37
|
+
* \brief Looking up the height of the geoid above the ellipsoid
|
38
|
+
*
|
39
|
+
* This class evaluates the height of one of the standard geoids, EGM84,
|
40
|
+
* EGM96, or EGM2008 by bilinear or cubic interpolation into a rectangular
|
41
|
+
* grid of data. These geoid models are documented in
|
42
|
+
* - EGM84:
|
43
|
+
* http://earth-info.nga.mil/GandG/wgs84/gravitymod/wgs84_180/wgs84_180.html
|
44
|
+
* - EGM96:
|
45
|
+
* http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm96/egm96.html
|
46
|
+
* - EGM2008:
|
47
|
+
* http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008
|
48
|
+
*
|
49
|
+
* The geoids are defined in terms of spherical harmonics. However in order
|
50
|
+
* to provide a quick and flexible method of evaluating the geoid heights,
|
51
|
+
* this class evaluates the height by interpolation into a grid of
|
52
|
+
* precomputed values.
|
53
|
+
*
|
54
|
+
* The height of the geoid above the ellipsoid, \e N, is sometimes called the
|
55
|
+
* geoid undulation. It can be used to convert a height above the ellipsoid,
|
56
|
+
* \e h, to the corresponding height above the geoid (the orthometric height,
|
57
|
+
* roughly the height above mean sea level), \e H, using the relations
|
58
|
+
*
|
59
|
+
* \e h = \e N + \e H;
|
60
|
+
* \e H = −\e N + \e h.
|
61
|
+
*
|
62
|
+
* See \ref geoid for details of how to install the data sets, the data
|
63
|
+
* format, estimates of the interpolation errors, and how to use caching.
|
64
|
+
*
|
65
|
+
* This class is typically \e not thread safe in that a single instantiation
|
66
|
+
* cannot be safely used by multiple threads because of the way the object
|
67
|
+
* reads the data set and because it maintains a single-cell cache. If
|
68
|
+
* multiple threads need to calculate geoid heights they should all construct
|
69
|
+
* thread-local instantiations. Alternatively, set the optional \e
|
70
|
+
* threadsafe parameter to true in the constructor. This causes the
|
71
|
+
* constructor to read all the data into memory and to turn off the
|
72
|
+
* single-cell caching which results in a Geoid object which \e is thread
|
73
|
+
* safe.
|
74
|
+
*
|
75
|
+
* Example of use:
|
76
|
+
* \include example-Geoid.cpp
|
77
|
+
*
|
78
|
+
* <a href="GeoidEval.1.html">GeoidEval</a> is a command-line utility
|
79
|
+
* providing access to the functionality of Geoid.
|
80
|
+
**********************************************************************/
|
81
|
+
|
82
|
+
class GEOGRAPHICLIB_EXPORT Geoid {
|
83
|
+
private:
|
84
|
+
typedef Math::real real;
|
85
|
+
#if GEOGRAPHICLIB_GEOID_PGM_PIXEL_WIDTH != 4
|
86
|
+
typedef unsigned short pixel_t;
|
87
|
+
static const unsigned pixel_size_ = 2;
|
88
|
+
static const unsigned pixel_max_ = 0xffffu;
|
89
|
+
#else
|
90
|
+
typedef unsigned pixel_t;
|
91
|
+
static const unsigned pixel_size_ = 4;
|
92
|
+
static const unsigned pixel_max_ = 0xffffffffu;
|
93
|
+
#endif
|
94
|
+
static const unsigned stencilsize_ = 12;
|
95
|
+
static const unsigned nterms_ = ((3 + 1) * (3 + 2))/2; // for a cubic fit
|
96
|
+
static const int c0_;
|
97
|
+
static const int c0n_;
|
98
|
+
static const int c0s_;
|
99
|
+
static const int c3_[stencilsize_ * nterms_];
|
100
|
+
static const int c3n_[stencilsize_ * nterms_];
|
101
|
+
static const int c3s_[stencilsize_ * nterms_];
|
102
|
+
|
103
|
+
std::string _name, _dir, _filename;
|
104
|
+
const bool _cubic;
|
105
|
+
const real _a, _e2, _degree, _eps;
|
106
|
+
mutable std::ifstream _file;
|
107
|
+
real _rlonres, _rlatres;
|
108
|
+
std::string _description, _datetime;
|
109
|
+
real _offset, _scale, _maxerror, _rmserror;
|
110
|
+
int _width, _height;
|
111
|
+
unsigned long long _datastart, _swidth;
|
112
|
+
bool _threadsafe;
|
113
|
+
// Area cache
|
114
|
+
mutable std::vector< std::vector<pixel_t> > _data;
|
115
|
+
mutable bool _cache;
|
116
|
+
// NE corner and extent of cache
|
117
|
+
mutable int _xoffset, _yoffset, _xsize, _ysize;
|
118
|
+
// Cell cache
|
119
|
+
mutable int _ix, _iy;
|
120
|
+
mutable real _v00, _v01, _v10, _v11;
|
121
|
+
mutable real _t[nterms_];
|
122
|
+
void filepos(int ix, int iy) const {
|
123
|
+
_file.seekg(
|
124
|
+
#if !(defined(__GNUC__) && __GNUC__ < 4)
|
125
|
+
// g++ 3.x doesn't know about the cast to streamoff.
|
126
|
+
std::ios::streamoff
|
127
|
+
#endif
|
128
|
+
(_datastart +
|
129
|
+
pixel_size_ * (unsigned(iy)*_swidth + unsigned(ix))));
|
130
|
+
}
|
131
|
+
real rawval(int ix, int iy) const {
|
132
|
+
if (ix < 0)
|
133
|
+
ix += _width;
|
134
|
+
else if (ix >= _width)
|
135
|
+
ix -= _width;
|
136
|
+
if (_cache && iy >= _yoffset && iy < _yoffset + _ysize &&
|
137
|
+
((ix >= _xoffset && ix < _xoffset + _xsize) ||
|
138
|
+
(ix + _width >= _xoffset && ix + _width < _xoffset + _xsize))) {
|
139
|
+
return real(_data[iy - _yoffset]
|
140
|
+
[ix >= _xoffset ? ix - _xoffset : ix + _width - _xoffset]);
|
141
|
+
} else {
|
142
|
+
if (iy < 0 || iy >= _height) {
|
143
|
+
iy = iy < 0 ? -iy : 2 * (_height - 1) - iy;
|
144
|
+
ix += (ix < _width/2 ? 1 : -1) * _width/2;
|
145
|
+
}
|
146
|
+
try {
|
147
|
+
filepos(ix, iy);
|
148
|
+
// initial values to suppress warnings in case get fails
|
149
|
+
char a = 0, b = 0;
|
150
|
+
_file.get(a);
|
151
|
+
_file.get(b);
|
152
|
+
unsigned r = ((unsigned char)(a) << 8) | (unsigned char)(b);
|
153
|
+
if (pixel_size_ == 4) {
|
154
|
+
_file.get(a);
|
155
|
+
_file.get(b);
|
156
|
+
r = (r << 16) | ((unsigned char)(a) << 8) | (unsigned char)(b);
|
157
|
+
}
|
158
|
+
return real(r);
|
159
|
+
}
|
160
|
+
catch (const std::exception& e) {
|
161
|
+
// throw GeographicErr("Error reading " + _filename + ": "
|
162
|
+
// + e.what());
|
163
|
+
// triggers complaints about the "binary '+'" under Visual Studio.
|
164
|
+
// So use '+=' instead.
|
165
|
+
std::string err("Error reading ");
|
166
|
+
err += _filename;
|
167
|
+
err += ": ";
|
168
|
+
err += e.what();
|
169
|
+
throw GeographicErr(err);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
real height(real lat, real lon) const;
|
174
|
+
Geoid(const Geoid&); // copy constructor not allowed
|
175
|
+
Geoid& operator=(const Geoid&); // copy assignment not allowed
|
176
|
+
public:
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Flags indicating conversions between heights above the geoid and heights
|
180
|
+
* above the ellipsoid.
|
181
|
+
**********************************************************************/
|
182
|
+
enum convertflag {
|
183
|
+
/**
|
184
|
+
* The multiplier for converting from heights above the geoid to heights
|
185
|
+
* above the ellipsoid.
|
186
|
+
**********************************************************************/
|
187
|
+
ELLIPSOIDTOGEOID = -1,
|
188
|
+
/**
|
189
|
+
* No conversion.
|
190
|
+
**********************************************************************/
|
191
|
+
NONE = 0,
|
192
|
+
/**
|
193
|
+
* The multiplier for converting from heights above the ellipsoid to
|
194
|
+
* heights above the geoid.
|
195
|
+
**********************************************************************/
|
196
|
+
GEOIDTOELLIPSOID = 1,
|
197
|
+
};
|
198
|
+
|
199
|
+
/** \name Setting up the geoid
|
200
|
+
**********************************************************************/
|
201
|
+
///@{
|
202
|
+
/**
|
203
|
+
* Construct a geoid.
|
204
|
+
*
|
205
|
+
* @param[in] name the name of the geoid.
|
206
|
+
* @param[in] path (optional) directory for data file.
|
207
|
+
* @param[in] cubic (optional) interpolation method; false means bilinear,
|
208
|
+
* true (the default) means cubic.
|
209
|
+
* @param[in] threadsafe (optional), if true, construct a thread safe
|
210
|
+
* object. The default is false
|
211
|
+
* @exception GeographicErr if the data file cannot be found, is
|
212
|
+
* unreadable, or is corrupt.
|
213
|
+
* @exception GeographicErr if \e threadsafe is true but the memory
|
214
|
+
* necessary for caching the data can't be allocated.
|
215
|
+
*
|
216
|
+
* The data file is formed by appending ".pgm" to the name. If \e path is
|
217
|
+
* specified (and is non-empty), then the file is loaded from directory, \e
|
218
|
+
* path. Otherwise the path is given by DefaultGeoidPath(). If the \e
|
219
|
+
* threadsafe parameter is true, the data set is read into memory, the data
|
220
|
+
* file is closed, and single-cell caching is turned off; this results in a
|
221
|
+
* Geoid object which \e is thread safe.
|
222
|
+
**********************************************************************/
|
223
|
+
explicit Geoid(const std::string& name, const std::string& path = "",
|
224
|
+
bool cubic = true, bool threadsafe = false);
|
225
|
+
|
226
|
+
/**
|
227
|
+
* Set up a cache.
|
228
|
+
*
|
229
|
+
* @param[in] south latitude (degrees) of the south edge of the cached area.
|
230
|
+
* @param[in] west longitude (degrees) of the west edge of the cached area.
|
231
|
+
* @param[in] north latitude (degrees) of the north edge of the cached area.
|
232
|
+
* @param[in] east longitude (degrees) of the east edge of the cached area.
|
233
|
+
* @exception GeographicErr if the memory necessary for caching the data
|
234
|
+
* can't be allocated (in this case, you will have no cache and can try
|
235
|
+
* again with a smaller area).
|
236
|
+
* @exception GeographicErr if there's a problem reading the data.
|
237
|
+
* @exception GeographicErr if this is called on a threadsafe Geoid.
|
238
|
+
*
|
239
|
+
* Cache the data for the specified "rectangular" area bounded by the
|
240
|
+
* parallels \e south and \e north and the meridians \e west and \e east.
|
241
|
+
* \e east is always interpreted as being east of \e west, if necessary by
|
242
|
+
* adding 360° to its value. \e south and \e north should be in
|
243
|
+
* the range [−90°, 90°].
|
244
|
+
**********************************************************************/
|
245
|
+
void CacheArea(real south, real west, real north, real east) const;
|
246
|
+
|
247
|
+
/**
|
248
|
+
* Cache all the data.
|
249
|
+
*
|
250
|
+
* @exception GeographicErr if the memory necessary for caching the data
|
251
|
+
* can't be allocated (in this case, you will have no cache and can try
|
252
|
+
* again with a smaller area).
|
253
|
+
* @exception GeographicErr if there's a problem reading the data.
|
254
|
+
* @exception GeographicErr if this is called on a threadsafe Geoid.
|
255
|
+
*
|
256
|
+
* On most computers, this is fast for data sets with grid resolution of 5'
|
257
|
+
* or coarser. For a 1' grid, the required RAM is 450MB; a 2.5' grid needs
|
258
|
+
* 72MB; and a 5' grid needs 18MB.
|
259
|
+
**********************************************************************/
|
260
|
+
void CacheAll() const { CacheArea(real(-90), real(0),
|
261
|
+
real(90), real(360)); }
|
262
|
+
|
263
|
+
/**
|
264
|
+
* Clear the cache. This never throws an error. (This does nothing with a
|
265
|
+
* thread safe Geoid.)
|
266
|
+
**********************************************************************/
|
267
|
+
void CacheClear() const;
|
268
|
+
|
269
|
+
///@}
|
270
|
+
|
271
|
+
/** \name Compute geoid heights
|
272
|
+
**********************************************************************/
|
273
|
+
///@{
|
274
|
+
/**
|
275
|
+
* Compute the geoid height at a point
|
276
|
+
*
|
277
|
+
* @param[in] lat latitude of the point (degrees).
|
278
|
+
* @param[in] lon longitude of the point (degrees).
|
279
|
+
* @exception GeographicErr if there's a problem reading the data; this
|
280
|
+
* never happens if (\e lat, \e lon) is within a successfully cached area.
|
281
|
+
* @return the height of the geoid above the ellipsoid (meters).
|
282
|
+
*
|
283
|
+
* The latitude should be in [−90°, 90°].
|
284
|
+
**********************************************************************/
|
285
|
+
Math::real operator()(real lat, real lon) const {
|
286
|
+
return height(lat, lon);
|
287
|
+
}
|
288
|
+
|
289
|
+
/**
|
290
|
+
* Convert a height above the geoid to a height above the ellipsoid and
|
291
|
+
* vice versa.
|
292
|
+
*
|
293
|
+
* @param[in] lat latitude of the point (degrees).
|
294
|
+
* @param[in] lon longitude of the point (degrees).
|
295
|
+
* @param[in] h height of the point (degrees).
|
296
|
+
* @param[in] d a Geoid::convertflag specifying the direction of the
|
297
|
+
* conversion; Geoid::GEOIDTOELLIPSOID means convert a height above the
|
298
|
+
* geoid to a height above the ellipsoid; Geoid::ELLIPSOIDTOGEOID means
|
299
|
+
* convert a height above the ellipsoid to a height above the geoid.
|
300
|
+
* @exception GeographicErr if there's a problem reading the data; this
|
301
|
+
* never happens if (\e lat, \e lon) is within a successfully cached area.
|
302
|
+
* @return converted height (meters).
|
303
|
+
**********************************************************************/
|
304
|
+
Math::real ConvertHeight(real lat, real lon, real h,
|
305
|
+
convertflag d) const {
|
306
|
+
return h + real(d) * height(lat, lon);
|
307
|
+
}
|
308
|
+
|
309
|
+
///@}
|
310
|
+
|
311
|
+
/** \name Inspector functions
|
312
|
+
**********************************************************************/
|
313
|
+
///@{
|
314
|
+
/**
|
315
|
+
* @return geoid description, if available, in the data file; if
|
316
|
+
* absent, return "NONE".
|
317
|
+
**********************************************************************/
|
318
|
+
const std::string& Description() const { return _description; }
|
319
|
+
|
320
|
+
/**
|
321
|
+
* @return date of the data file; if absent, return "UNKNOWN".
|
322
|
+
**********************************************************************/
|
323
|
+
const std::string& DateTime() const { return _datetime; }
|
324
|
+
|
325
|
+
/**
|
326
|
+
* @return full file name used to load the geoid data.
|
327
|
+
**********************************************************************/
|
328
|
+
const std::string& GeoidFile() const { return _filename; }
|
329
|
+
|
330
|
+
/**
|
331
|
+
* @return "name" used to load the geoid data (from the first argument of
|
332
|
+
* the constructor).
|
333
|
+
**********************************************************************/
|
334
|
+
const std::string& GeoidName() const { return _name; }
|
335
|
+
|
336
|
+
/**
|
337
|
+
* @return directory used to load the geoid data.
|
338
|
+
**********************************************************************/
|
339
|
+
const std::string& GeoidDirectory() const { return _dir; }
|
340
|
+
|
341
|
+
/**
|
342
|
+
* @return interpolation method ("cubic" or "bilinear").
|
343
|
+
**********************************************************************/
|
344
|
+
const std::string Interpolation() const
|
345
|
+
{ return std::string(_cubic ? "cubic" : "bilinear"); }
|
346
|
+
|
347
|
+
/**
|
348
|
+
* @return estimate of the maximum interpolation and quantization error
|
349
|
+
* (meters).
|
350
|
+
*
|
351
|
+
* This relies on the value being stored in the data file. If the value is
|
352
|
+
* absent, return −1.
|
353
|
+
**********************************************************************/
|
354
|
+
Math::real MaxError() const { return _maxerror; }
|
355
|
+
|
356
|
+
/**
|
357
|
+
* @return estimate of the RMS interpolation and quantization error
|
358
|
+
* (meters).
|
359
|
+
*
|
360
|
+
* This relies on the value being stored in the data file. If the value is
|
361
|
+
* absent, return −1.
|
362
|
+
**********************************************************************/
|
363
|
+
Math::real RMSError() const { return _rmserror; }
|
364
|
+
|
365
|
+
/**
|
366
|
+
* @return offset (meters).
|
367
|
+
*
|
368
|
+
* This in used in converting from the pixel values in the data file to
|
369
|
+
* geoid heights.
|
370
|
+
**********************************************************************/
|
371
|
+
Math::real Offset() const { return _offset; }
|
372
|
+
|
373
|
+
/**
|
374
|
+
* @return scale (meters).
|
375
|
+
*
|
376
|
+
* This in used in converting from the pixel values in the data file to
|
377
|
+
* geoid heights.
|
378
|
+
**********************************************************************/
|
379
|
+
Math::real Scale() const { return _scale; }
|
380
|
+
|
381
|
+
/**
|
382
|
+
* @return true if the object is constructed to be thread safe.
|
383
|
+
**********************************************************************/
|
384
|
+
bool ThreadSafe() const { return _threadsafe; }
|
385
|
+
|
386
|
+
/**
|
387
|
+
* @return true if a data cache is active.
|
388
|
+
**********************************************************************/
|
389
|
+
bool Cache() const { return _cache; }
|
390
|
+
|
391
|
+
/**
|
392
|
+
* @return west edge of the cached area; the cache includes this edge.
|
393
|
+
**********************************************************************/
|
394
|
+
Math::real CacheWest() const {
|
395
|
+
return _cache ? ((_xoffset + (_xsize == _width ? 0 : _cubic)
|
396
|
+
+ _width/2) % _width - _width/2) / _rlonres :
|
397
|
+
0;
|
398
|
+
}
|
399
|
+
|
400
|
+
/**
|
401
|
+
* @return east edge of the cached area; the cache excludes this edge.
|
402
|
+
**********************************************************************/
|
403
|
+
Math::real CacheEast() const {
|
404
|
+
return _cache ?
|
405
|
+
CacheWest() +
|
406
|
+
(_xsize - (_xsize == _width ? 0 : 1 + 2 * _cubic)) / _rlonres :
|
407
|
+
0;
|
408
|
+
}
|
409
|
+
|
410
|
+
/**
|
411
|
+
* @return north edge of the cached area; the cache includes this edge.
|
412
|
+
**********************************************************************/
|
413
|
+
Math::real CacheNorth() const {
|
414
|
+
return _cache ? 90 - (_yoffset + _cubic) / _rlatres : 0;
|
415
|
+
}
|
416
|
+
|
417
|
+
/**
|
418
|
+
* @return south edge of the cached area; the cache excludes this edge
|
419
|
+
* unless it's the south pole.
|
420
|
+
**********************************************************************/
|
421
|
+
Math::real CacheSouth() const {
|
422
|
+
return _cache ? 90 - ( _yoffset + _ysize - 1 - _cubic) / _rlatres : 0;
|
423
|
+
}
|
424
|
+
|
425
|
+
/**
|
426
|
+
* @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
|
427
|
+
*
|
428
|
+
* (The WGS84 value is returned because the supported geoid models are all
|
429
|
+
* based on this ellipsoid.)
|
430
|
+
**********************************************************************/
|
431
|
+
Math::real MajorRadius() const
|
432
|
+
{ return Constants::WGS84_a(); }
|
433
|
+
|
434
|
+
/**
|
435
|
+
* @return \e f the flattening of the WGS84 ellipsoid.
|
436
|
+
*
|
437
|
+
* (The WGS84 value is returned because the supported geoid models are all
|
438
|
+
* based on this ellipsoid.)
|
439
|
+
**********************************************************************/
|
440
|
+
Math::real Flattening() const { return Constants::WGS84_f(); }
|
441
|
+
///@}
|
442
|
+
|
443
|
+
/**
|
444
|
+
* @return the default path for geoid data files.
|
445
|
+
*
|
446
|
+
* This is the value of the environment variable GEOGRAPHICLIB_GEOID_PATH,
|
447
|
+
* if set; otherwise, it is $GEOGRAPHICLIB_DATA/geoids if the environment
|
448
|
+
* variable GEOGRAPHICLIB_DATA is set; otherwise, it is a compile-time
|
449
|
+
* default (/usr/local/share/GeographicLib/geoids on non-Windows systems
|
450
|
+
* and C:/ProgramData/GeographicLib/geoids on Windows systems).
|
451
|
+
**********************************************************************/
|
452
|
+
static std::string DefaultGeoidPath();
|
453
|
+
|
454
|
+
/**
|
455
|
+
* @return the default name for the geoid.
|
456
|
+
*
|
457
|
+
* This is the value of the environment variable GEOGRAPHICLIB_GEOID_NAME,
|
458
|
+
* if set; otherwise, it is "egm96-5". The Geoid class does not use this
|
459
|
+
* function; it is just provided as a convenience for a calling program
|
460
|
+
* when constructing a Geoid object.
|
461
|
+
**********************************************************************/
|
462
|
+
static std::string DefaultGeoidName();
|
463
|
+
|
464
|
+
};
|
465
|
+
|
466
|
+
} // namespace GeographicLib
|
467
|
+
|
468
|
+
#if defined(_MSC_VER)
|
469
|
+
# pragma warning (pop)
|
470
|
+
#endif
|
471
|
+
|
472
|
+
#endif // GEOGRAPHICLIB_GEOID_HPP
|