Marble

SphericalProjection.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
4// SPDX-FileCopyrightText: 2007-2014 Torsten Rahn <rahn@kde.org>
5// SPDX-FileCopyrightText: 2009 Patrick Spendrin <ps_ml@gmx.de>
6// SPDX-FileCopyrightText: 2012 Cezar Mocan <mocancezar@gmail.com>
7//
8
9// Local
10#include "SphericalProjection.h"
11
12// Marble
13#include "AzimuthalProjection_p.h"
14#include "GeoDataCoordinates.h"
15#include "GeoDataLineString.h"
16#include "MarbleGlobal.h"
17#include "ViewportParams.h"
18
19#include <QIcon>
20
21#define SAFE_DISTANCE
22
23namespace Marble
24{
25
26class SphericalProjectionPrivate : public AzimuthalProjectionPrivate
27{
28public:
29 explicit SphericalProjectionPrivate(SphericalProjection *parent);
30
31 Q_DECLARE_PUBLIC(SphericalProjection)
32};
33
35 : AzimuthalProjection(new SphericalProjectionPrivate(this))
36{
37 setMinLat(minValidLat());
38 setMaxLat(maxValidLat());
39}
40
41SphericalProjection::SphericalProjection(SphericalProjectionPrivate *dd)
43{
44 setMinLat(minValidLat());
45 setMaxLat(maxValidLat());
46}
47
48SphericalProjection::~SphericalProjection() = default;
49
50SphericalProjectionPrivate::SphericalProjectionPrivate(SphericalProjection *parent)
51 : AzimuthalProjectionPrivate(parent)
52{
53}
54
56{
57 return QObject::tr("Globe");
58}
59
61{
62 return QObject::tr(
63 "<p><b>Orthographic Projection</b> (\"orthogonal\")</p><p>Applications: A perspective projection that is used to display the hemisphere of a globe as "
64 "it appears from outer space.</p>");
65}
66
68{
69 return QIcon(QStringLiteral(":/icons/map-globe.png"));
70}
71
73 const ViewportParams *viewport,
74 qreal &x,
75 qreal &y,
76 bool &globeHidesPoint) const
77{
78 const qreal altitude = coordinates.altitude();
79 const qreal absoluteAltitude = altitude + EARTH_RADIUS;
80 Quaternion qpos = coordinates.quaternion();
81
82 qpos.rotateAroundAxis(viewport->planetAxisMatrix());
83
84 const qreal radius = viewport->radius();
85 const qreal pixelAltitude = (radius / EARTH_RADIUS * absoluteAltitude);
86 if (altitude < 10000) {
87 // Skip placemarks at the other side of the earth.
88 if (qpos.v[Q_Z] < 0) {
89 globeHidesPoint = true;
90 return false;
91 }
92 } else {
93 qreal earthCenteredX = pixelAltitude * qpos.v[Q_X];
94 qreal earthCenteredY = pixelAltitude * qpos.v[Q_Y];
95
96 // Don't draw high placemarks (e.g. satellites) that aren't visible.
97 if (qpos.v[Q_Z] < 0 && ((earthCenteredX * earthCenteredX + earthCenteredY * earthCenteredY) < radius * radius)) {
98 globeHidesPoint = true;
99 return false;
100 }
101 }
102
103 const qreal width = viewport->width();
104 const qreal height = viewport->height();
105
106 // Let (x, y) be the position on the screen of the placemark..
107 x = (width / 2 + pixelAltitude * qpos.v[Q_X]);
108 y = (height / 2 - pixelAltitude * qpos.v[Q_Y]);
109
110 // Skip placemarks that are outside the screen area
111 if (x < 0 || x >= width || y < 0 || y >= height) {
112 globeHidesPoint = false;
113 return false;
114 }
115
116 globeHidesPoint = false;
117 return true;
118}
119
121 const ViewportParams *viewport,
122 qreal *x,
123 qreal &y,
124 int &pointRepeatNum,
125 const QSizeF &size,
126 bool &globeHidesPoint) const
127{
128 pointRepeatNum = 0;
129 bool visible = screenCoordinates(coordinates, viewport, *x, y, globeHidesPoint);
130
131 // Skip placemarks that are outside the screen area
132 if (*x + size.width() / 2.0 < 0.0 || *x >= viewport->width() + size.width() / 2.0 || y + size.height() / 2.0 < 0.0
133 || y >= viewport->height() + size.height() / 2.0) {
134 globeHidesPoint = false;
135 return false;
136 }
137
138 // This projection doesn't have any repetitions,
139 // so the number of screen points referring to the geopoint is one.
140 pointRepeatNum = 1;
141 return visible;
142}
143
144bool SphericalProjection::geoCoordinates(const int x, const int y, const ViewportParams *viewport, qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit) const
145{
146 const qreal inverseRadius = 1.0 / (qreal)(viewport->radius());
147
148 const qreal qx = +(qreal)(x - viewport->width() / 2) * inverseRadius;
149 const qreal qy = -(qreal)(y - viewport->height() / 2) * inverseRadius;
150
151 if (1 <= qx * qx + qy * qy) {
152 return false;
153 }
154
155 const qreal qz = sqrt(1 - qx * qx - qy * qy);
156
157 Quaternion qpos(0.0, qx, qy, qz);
158 qpos.rotateAroundAxis(viewport->planetAxis());
159 qpos.getSpherical(lon, lat);
160
161 if (unit == GeoDataCoordinates::Degree) {
162 lon *= RAD2DEG;
163 lat *= RAD2DEG;
164 }
165
166 return true;
167}
168
169}
This file contains the headers for SphericalProjection.
This file contains the headers for ViewportParams.
virtual qreal maxValidLat() const
Returns the maximum (northern) latitude that is mathematically defined and reasonable.
virtual qreal minValidLat() const
Returns the minimum (southern) latitude that is mathematically defined and reasonable.
A base class for the Gnomonic and Orthographic (Globe) projections in Marble.
A 3d point representation.
qreal altitude() const
return the altitude of the Point in meters
Unit
enum used constructor to specify the units used
const Quaternion & quaternion() const
return a Quaternion with the used coordinates
QString description() const override
Returns a short user description of the projection that can be used in tooltips or dialogs.
SphericalProjection()
Construct a new SphericalProjection.
QString name() const override
Returns the user-visible name of the projection.
bool screenCoordinates(const GeoDataCoordinates &coordinates, const ViewportParams *params, qreal &x, qreal &y, bool &globeHidesPoint) const override
Get the screen coordinates corresponding to geographical coordinates in the map.
bool geoCoordinates(const int x, const int y, const ViewportParams *params, qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Degree) const override
Get the earth coordinates corresponding to a pixel in the map.
QIcon icon() const override
Returns an icon for the projection.
A public class that controls what is visible in the viewport of a Marble map.
Binds a QML item to a specific geodetic location in screen coordinates.
QString tr(const char *sourceText, const char *disambiguation, int n)
qreal height() const const
qreal width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.