Marble

StereographicProjection.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2014 Torsten Rahn <rahn@kde.org>
4//
5
6// Local
7#include "StereographicProjection.h"
8
9// Marble
10#include "AzimuthalProjection_p.h"
11#include "GeoDataCoordinates.h"
12#include "GeoDataLineString.h"
13#include "MarbleGlobal.h"
14#include "ViewportParams.h"
15
16#include <QIcon>
17#include <qmath.h>
18
19#define SAFE_DISTANCE
20
21namespace Marble
22{
23
24class StereographicProjectionPrivate : public AzimuthalProjectionPrivate
25{
26public:
27 explicit StereographicProjectionPrivate(StereographicProjection *parent);
28
29 Q_DECLARE_PUBLIC(StereographicProjection)
30};
31
33 : AzimuthalProjection(new StereographicProjectionPrivate(this))
34{
35 setMinLat(minValidLat());
36 setMaxLat(maxValidLat());
37}
38
39StereographicProjection::StereographicProjection(StereographicProjectionPrivate *dd)
41{
42 setMinLat(minValidLat());
43 setMaxLat(maxValidLat());
44}
45
46StereographicProjection::~StereographicProjection() = default;
47
48StereographicProjectionPrivate::StereographicProjectionPrivate(StereographicProjection *parent)
49 : AzimuthalProjectionPrivate(parent)
50{
51}
52
54{
55 return QObject::tr("Stereographic");
56}
57
59{
60 return QObject::tr(
61 "<p><b>Stereographic Projection</b> (\"orthogonal\")</p><p>Applications: Used for planetary cartography, geology and panorama photography.</p>");
62}
63
65{
66 return QIcon(QStringLiteral(":/icons/map-globe.png"));
67}
68
69qreal StereographicProjection::clippingRadius() const
70{
71 return 1;
72}
73
75 const ViewportParams *viewport,
76 qreal &x,
77 qreal &y,
78 bool &globeHidesPoint) const
79{
80 const qreal lambda = coordinates.longitude();
81 const qreal phi = coordinates.latitude();
82 const qreal lambdaPrime = viewport->centerLongitude();
83 const qreal phi1 = viewport->centerLatitude();
84
85 qreal cosC = qSin(phi1) * qSin(phi) + qCos(phi1) * qCos(phi) * qCos(lambda - lambdaPrime);
86 // Prevent division by zero
87 if (cosC <= 0) {
88 globeHidesPoint = true;
89 return false;
90 }
91
92 qreal k = 1 / (1 + cosC);
93
94 // Let (x, y) be the position on the screen of the placemark..
95 x = (qCos(phi) * qSin(lambda - lambdaPrime)) * k;
96 y = (qCos(phi1) * qSin(phi) - qSin(phi1) * qCos(phi) * qCos(lambda - lambdaPrime)) * k;
97
98 x *= viewport->radius();
99 y *= viewport->radius();
100
101 const qint64 radius = clippingRadius() * viewport->radius();
102
103 if (x * x + y * y > radius * radius) {
104 globeHidesPoint = true;
105 return false;
106 }
107
108 globeHidesPoint = false;
109
110 x += viewport->width() / 2;
111 y = viewport->height() / 2 - y;
112
113 // Skip placemarks that are outside the screen area
114 return !(x < 0 || x >= viewport->width() || y < 0 || y >= viewport->height());
115}
116
118 const ViewportParams *viewport,
119 qreal *x,
120 qreal &y,
121 int &pointRepeatNum,
122 const QSizeF &size,
123 bool &globeHidesPoint) const
124{
125 pointRepeatNum = 0;
126 globeHidesPoint = false;
127
128 bool visible = screenCoordinates(coordinates, viewport, *x, y, globeHidesPoint);
129
130 // Skip placemarks that are outside the screen area
131 if (*x + size.width() / 2.0 < 0.0 || *x >= viewport->width() + size.width() / 2.0 || y + size.height() / 2.0 < 0.0
132 || y >= viewport->height() + size.height() / 2.0) {
133 return false;
134 }
135
136 // This projection doesn't have any repetitions,
137 // so the number of screen points referring to the geopoint is one.
138 pointRepeatNum = 1;
139 return visible;
140}
141
142bool StereographicProjection::geoCoordinates(const int x, const int y, const ViewportParams *viewport, qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit)
143 const
144{
145 const qint64 radius = viewport->radius();
146 // Calculate how many degrees are being represented per pixel.
147 const qreal centerLon = viewport->centerLongitude();
148 const qreal centerLat = viewport->centerLatitude();
149 const qreal rx = (-viewport->width() / 2 + x);
150 const qreal ry = (viewport->height() / 2 - y);
151 const qreal p = qMax(qSqrt(rx * rx + ry * ry), qreal(0.0001)); // ensure we don't divide by zero
152 const qreal c = 2 * qAtan2(p, radius);
153 const qreal sinc = qSin(c);
154
155 lon = centerLon + qAtan2(rx * sinc, (p * qCos(centerLat) * qCos(c) - ry * qSin(centerLat) * sinc));
156
157 while (lon < -M_PI)
158 lon += 2 * M_PI;
159 while (lon > M_PI)
160 lon -= 2 * M_PI;
161
162 lat = qAsin(qCos(c) * qSin(centerLat) + (ry * sinc * qCos(centerLat)) / p);
163
164 if (unit == GeoDataCoordinates::Degree) {
165 lon *= RAD2DEG;
166 lat *= RAD2DEG;
167 }
168
169 return true;
170}
171
172}
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.
Unit
enum used constructor to specify the units used
QString name() const override
Returns the user-visible name of the projection.
StereographicProjection()
Construct a new StereographicProjection.
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.
QString description() const override
Returns a short user description of the projection that can be used in tooltips or dialogs.
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 Mon Nov 18 2024 12:15:46 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.