1
#include "Maps/Projection.h"
2
#include "Maps/TrackPoint.h"
9
#include <ggl/projections/parameters.hpp>
10
#include <ggl/projections/factory.hpp>
13
#define EQUATORIALRADIUS 6378137.0
14
#define POLARRADIUS 6356752.0
15
//#define PROJ_RATIO ((double(INT_MAX)/M_PI) / EQUATORIALRADIUS)
21
class ProjectionPrivate
24
ProjProjection *theWGS84Proj;
25
QRectF ProjectedViewport;
26
int ProjectionRevision;
30
: ProjectionRevision(0)
37
Projection::Projection(void)
38
: theProj(0), p(new ProjectionPrivate)
41
p->theWGS84Proj = Projection::getProjection("+proj=longlat +ellps=WGS84 +datum=WGS84");
42
setProjectionType(M_PREFS->getProjectionType());
46
Projection::~Projection(void)
54
#include "ggl/projections/impl/pj_transform.hpp"
55
void Projection::projTransform(ProjProjection *srcdefn,
56
ProjProjection *dstdefn,
57
long point_count, int point_offset, double *x, double *y, double *z )
59
ggl::projection::detail::pj_transform(srcdefn, dstdefn, point_count, point_offset, x, y, z);
62
void Projection::projTransformFromWGS84(long point_count, int point_offset, double *x, double *y, double *z )
64
ggl::projection::detail::pj_transform(p->theWGS84Proj, theProj, point_count, point_offset, x, y, z);
67
void Projection::projTransformToWGS84(long point_count, int point_offset, double *x, double *y, double *z )
69
ggl::projection::detail::pj_transform(theProj, p->theWGS84Proj, point_count, point_offset, x, y, z);
72
QPointF Projection::projProject(const Coord & Map) const
75
point_ll_deg in(longitude<>(intToAng(Map.lon())), latitude<>(intToAng(Map.lat())));
78
theProj->forward(in, out);
80
return QPointF(out.x(), out.y());
82
return QPointF(0., 0.);
86
Coord Projection::projInverse(const QPointF & pProj) const
89
point_2d in(pProj.x(), pProj.y());
92
theProj->inverse(in, out);
94
return Coord(angToInt(out.lat()), angToInt(out.lon()));
100
bool Projection::projIsLatLong()
102
return (theProj->params().is_latlong > 0);
105
QRectF Projection::getProjectedViewport(CoordBox& Viewport, QRect& screen)
109
double x = intToRad(Viewport.topLeft().lon());
110
double y = intToRad(Viewport.topLeft().lat());
111
projTransformFromWGS84(1, 0, &x, &y, NULL);
112
if (theProj->params().is_latlong)
113
tl = QPointF(radToAng(x), radToAng(y));
117
x = intToRad(Viewport.bottomRight().lon());
118
y = intToRad(Viewport.bottomRight().lat());
119
projTransformFromWGS84(1, 0, &x, &y, NULL);
120
if (theProj->params().is_latlong)
121
br = QPointF(radToAng(x), radToAng(y));
125
QRectF pViewport = QRectF(tl, br);
127
QPointF pCenter(pViewport.center());
130
//wv = (pViewport.width() / Viewport.londiff()) * ((double)screen.width() / Viewport.londiff());
131
//hv = (pViewport.height() / Viewport.latdiff()) * ((double)screen.height() / Viewport.latdiff());
133
double Aspect = (double)screen.width() / screen.height();
134
double pAspect = fabs(pViewport.width() / pViewport.height());
136
if (pAspect > Aspect) {
137
wv = fabs(pViewport.width());
138
hv = fabs(pViewport.height() * pAspect / Aspect);
140
wv = fabs(pViewport.width() * Aspect / pAspect);
141
hv = fabs(pViewport.height());
144
pViewport = QRectF((pCenter.x() - wv/2), (pCenter.y() + hv/2), wv, -hv);
153
ProjProjection * Projection::getProjection(QString projString)
155
ggl::projection::factory<ggl::point_ll_deg, ggl::point_2d> fac;
156
ggl::projection::parameters par;
157
ggl::projection::projection<ggl::point_ll_deg, ggl::point_2d> *theProj;
160
par = ggl::projection::init(std::string(QString("%1 +over").arg(projString).toLatin1().data()));
161
theProj = fac.create_new(par);
163
par = ggl::projection::init(std::string(QString("%1 +over").arg(M_PREFS->getProjection("mercator").projection).toLatin1().data()));
164
theProj = fac.create_new(par);
166
qDebug() << "Unable to set projection : " << projString;
171
par = ggl::projection::init(std::string(QString("%1 +over").arg(M_PREFS->getProjection("mercator").projection).toLatin1().data()));
172
theProj = fac.create_new(par);
177
bool Projection::setProjectionType(ProjectionType aProjectionType)
180
p->ProjectionRevision++;
182
theProj = getProjection(M_PREFS->getProjection(aProjectionType).projection);
186
return (theProj != NULL);
192
double Projection::latAnglePerM() const
194
double LengthOfOneDegreeLat = EQUATORIALRADIUS * M_PI / 180;
195
return 1 / LengthOfOneDegreeLat;
198
double Projection::lonAnglePerM(double Lat) const
200
double LengthOfOneDegreeLat = EQUATORIALRADIUS * M_PI / 180;
201
double LengthOfOneDegreeLon = LengthOfOneDegreeLat * fabs(cos(Lat));
202
return 1 / LengthOfOneDegreeLon;
205
QPointF Projection::project(const Coord & Map) const
208
return projProject(Map);
210
return QPoint(qRound(Map.lon()), qRound(Map.lat()));
214
QPointF Projection::project(TrackPoint* aNode) const
217
if (aNode && aNode->projectionRevision() == p->ProjectionRevision)
218
return aNode->projection();
220
QPointF pt = projProject(aNode->position());
222
aNode->setProjectionRevision(p->ProjectionRevision);
223
aNode->setProjection(pt);
227
return project(aNode->position());
231
Coord Projection::inverse(const QPointF & Screen) const
234
return projInverse(QPointF(Screen.x(), Screen.y()));
236
return Coord(qRound(Screen.y()),
241
int Projection::projectionRevision() const
243
return p->ProjectionRevision;