1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-07 07:13:21 +02:00
GPXSee/src/ellipsoid.cpp

93 lines
2.3 KiB
C++
Raw Normal View History

#include <cmath>
#include <QString>
#include "wgs84.h"
#include "ellipsoid.h"
#define INTERNATIONAL_RADIUS 6378388.0
#define INTERNATIONAL_FLATTENING (1.0/297.0)
#define KRASSOVSKY_RADIUS 6378245.0
#define KRASSOVSKY_FLATTENING (1.0/298.3)
#define BESSEL_RADIUS 6377397.155
#define BESSEL_FLATTENING (1.0/299.1528128)
#define GRS80_RADIUS 6378137.0
#define GRS80_FLATTENING (1.0/298.257222101)
#define WGS70_RADIUS 6378135.0
#define WGS70_FLATTENING (1.0/298.26)
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif // M_PI_2
#ifndef M_PI_4
#define M_PI_4 0.78539816339744830962
#endif // M_PI_4
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
typedef struct {
const char *name;
double radius;
double flattening;
} Entry;
static Entry list[] = {
{"S42", KRASSOVSKY_RADIUS, KRASSOVSKY_FLATTENING},
{"Pulkovo 1942", KRASSOVSKY_RADIUS, KRASSOVSKY_FLATTENING},
{"European 1950", INTERNATIONAL_RADIUS, INTERNATIONAL_FLATTENING},
{"European 1979", INTERNATIONAL_RADIUS, INTERNATIONAL_FLATTENING},
{"NZGD1949", INTERNATIONAL_RADIUS, INTERNATIONAL_FLATTENING},
{"NAD27", BESSEL_RADIUS, BESSEL_FLATTENING},
{"NAD83", GRS80_RADIUS, GRS80_FLATTENING},
{"WGS 72", WGS70_RADIUS, WGS70_FLATTENING}
};
Ellipsoid::Ellipsoid()
{
_radius = WGS84_RADIUS;
_flattening = WGS84_FLATTENING;
}
Ellipsoid::Ellipsoid(const QString &datum)
{
for (size_t i = 0; i < ARRAY_SIZE(list); i++) {
if (datum.startsWith(list[i].name)) {
_radius = list[i].radius;
_flattening = list[i].flattening;
return;
}
}
_radius = WGS84_RADIUS;
_flattening = WGS84_FLATTENING;
}
double Ellipsoid::q(double b) const
{
double e = sqrt(_flattening * (2. - _flattening));
double esb = e * sin(b);
return log(tan(M_PI_4 + b / 2.) * pow((1. - esb) / (1. + esb), e / 2.));
}
double Ellipsoid::iq(double q) const
{
double e = sqrt(_flattening * (2. - _flattening));
double b0 = 0.;
double b = 2. * atan(exp(q)) - M_PI_2;
do {
b0 = b;
double esb = e * sin(b);
b = 2. * atan(exp(q) * pow((1. - esb) / (1. + esb), -e / 2.)) - M_PI_2;
} while (fabs(b - b0) > 1e-10);
return b;
}
double Ellipsoid::nradius(double phi) const
{
double sin_phi = sin(phi);
return (_radius / sqrt(1. - (_flattening * (2. - _flattening)) * sin_phi
* sin_phi));
}