2018-05-29 00:17:20 +02:00
|
|
|
#include "ellipsoid.h"
|
|
|
|
#include "krovak.h"
|
|
|
|
|
|
|
|
Krovak::Krovak(const Ellipsoid *ellipsoid, double standardParallel,
|
|
|
|
double azimuth, double scale, double centerLatitude, double longitudeOrigin,
|
2018-05-29 21:54:25 +02:00
|
|
|
double falseEasting, double falseNorthing)
|
2018-05-29 00:17:20 +02:00
|
|
|
{
|
|
|
|
double phiC = deg2rad(centerLatitude);
|
|
|
|
double sinPhiC = sin(phiC);
|
|
|
|
double sinPhiC2 = sinPhiC * sinPhiC;
|
|
|
|
double cosPhiC = cos(phiC);
|
|
|
|
double cosPhiC2 = cosPhiC * cosPhiC;
|
|
|
|
double cosPhiC4 = cosPhiC2 * cosPhiC2;
|
|
|
|
double alphaC = deg2rad(azimuth);
|
|
|
|
|
|
|
|
_phiP = deg2rad(standardParallel);
|
|
|
|
_e = sqrt(ellipsoid->es());
|
2020-01-23 23:19:32 +01:00
|
|
|
_a = ellipsoid->radius() * sqrt(1.0 - ellipsoid->es())
|
2018-05-29 00:17:20 +02:00
|
|
|
/ (1.0 - ellipsoid->es() * sinPhiC2);
|
2020-01-23 23:19:32 +01:00
|
|
|
_b = sqrt(1.0 + (ellipsoid->es() * cosPhiC4 / (1.0 - ellipsoid->es())));
|
|
|
|
double gamma0 = asin(sinPhiC / _b);
|
2018-05-29 00:17:20 +02:00
|
|
|
_t0 = tan(M_PI_4 + gamma0 / 2.0) * pow((1.0 + _e * sinPhiC) /
|
2020-01-23 23:19:32 +01:00
|
|
|
(1.0 - _e * sinPhiC), _e*_b / 2.0) / pow(tan(M_PI_4 + phiC/2.0), _b);
|
2018-05-29 00:17:20 +02:00
|
|
|
_n = sin(_phiP);
|
2020-01-23 23:19:32 +01:00
|
|
|
_r0 = scale * _a / tan(_phiP);
|
|
|
|
_fe = falseEasting;
|
|
|
|
_fn = falseNorthing;
|
2018-05-29 00:17:20 +02:00
|
|
|
_cosAlphaC = cos(alphaC);
|
|
|
|
_sinAlphaC = sin(alphaC);
|
|
|
|
_lambda0 = deg2rad(longitudeOrigin);
|
|
|
|
}
|
|
|
|
|
|
|
|
PointD Krovak::ll2xy(const Coordinates &c) const
|
|
|
|
{
|
|
|
|
double phi = deg2rad(c.lat());
|
|
|
|
double lambda = deg2rad(c.lon());
|
2018-05-29 21:54:25 +02:00
|
|
|
double eSinPhi = _e * sin(phi);
|
2020-01-23 23:19:32 +01:00
|
|
|
double U = 2.0 * (atan(_t0 * pow(tan(phi/2.0 + M_PI_4), _b)
|
|
|
|
/ pow((1.0 + eSinPhi) / (1.0 - eSinPhi), _e * _b/2.0)) - M_PI_4);
|
2018-05-29 21:54:25 +02:00
|
|
|
double cosU = cos(U);
|
2020-01-23 23:19:32 +01:00
|
|
|
double V = _b * (_lambda0 - lambda);
|
2018-05-29 21:54:25 +02:00
|
|
|
double T = asin(_cosAlphaC * sin(U) + _sinAlphaC * cosU * cos(V));
|
|
|
|
double D = asin(cosU * sin(V) / cos(T));
|
2018-05-29 00:17:20 +02:00
|
|
|
double theta = _n * D;
|
2018-05-29 21:54:25 +02:00
|
|
|
double r = _r0 * pow(tan(M_PI_4 + _phiP/2.0), _n)
|
2018-05-29 00:17:20 +02:00
|
|
|
/ pow(tan(T/2.0 + M_PI_4), _n);
|
|
|
|
|
2020-01-23 23:19:32 +01:00
|
|
|
return PointD(r * sin(theta) + _fe, r * cos(theta) + _fn);
|
2018-05-29 00:17:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Coordinates Krovak::xy2ll(const PointD &p) const
|
|
|
|
{
|
2020-01-23 23:19:32 +01:00
|
|
|
double Xp = p.y() - _fn;
|
|
|
|
double Yp = p.x() - _fe;
|
2018-05-29 00:17:20 +02:00
|
|
|
double Xp2 = Xp * Xp;
|
|
|
|
double Yp2 = Yp * Yp;
|
|
|
|
double r = sqrt(Xp2 + Yp2);
|
|
|
|
double theta = atan(Yp / Xp);
|
|
|
|
double D = theta / sin(_phiP);
|
|
|
|
double T = 2.0 * (atan(pow(_r0 / r, 1.0/_n) * tan(M_PI_4 + _phiP/2.0))
|
|
|
|
- M_PI_4);
|
|
|
|
double U = asin(_cosAlphaC * sin(T) - _sinAlphaC * cos(T) * cos(D));
|
|
|
|
double V = asin(cos(T) * sin(D) / cos(U));
|
|
|
|
double phi = U;
|
|
|
|
for (int i = 0; i < 3; i++)
|
2020-01-23 23:19:32 +01:00
|
|
|
phi = 2.0 * (atan(pow(_t0, -1.0/_b) * pow(tan(U/2.0 + M_PI_4), 1.0/_b)
|
2018-05-29 00:17:20 +02:00
|
|
|
* pow((1.0 + _e * sin(phi))/(1.0 - _e * sin(phi)), _e/2.0)) - M_PI_4);
|
|
|
|
|
2020-01-23 23:19:32 +01:00
|
|
|
return Coordinates(rad2deg(_lambda0 - V/_b), rad2deg(phi));
|
2018-05-29 00:17:20 +02:00
|
|
|
}
|