Marble

AzimuthalEquidistantProjection.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 "AzimuthalEquidistantProjection.h"
8#include "AbstractProjection_p.h"
9
10#include "MarbleDebug.h"
11
12// Marble
13#include "AzimuthalProjection_p.h"
14#include "GeoDataCoordinates.h"
15#include "GeoDataLineString.h"
16#include "GeoDataPoint.h"
17#include "MarbleGlobal.h"
18#include "ViewportParams.h"
19
20#include <QIcon>
21#include <qmath.h>
22
23#define SAFE_DISTANCE
24
25namespace Marble
26{
27
28class AzimuthalEquidistantProjectionPrivate : public AzimuthalProjectionPrivate
29{
30public:
31 explicit AzimuthalEquidistantProjectionPrivate(AzimuthalEquidistantProjection *parent);
32
33 Q_DECLARE_PUBLIC(AzimuthalEquidistantProjection)
34};
35
37 : AzimuthalProjection(new AzimuthalEquidistantProjectionPrivate(this))
38{
39 setMinLat(minValidLat());
40 setMaxLat(maxValidLat());
41}
42
43AzimuthalEquidistantProjection::AzimuthalEquidistantProjection(AzimuthalEquidistantProjectionPrivate *dd)
45{
46 setMinLat(minValidLat());
47 setMaxLat(maxValidLat());
48}
49
50AzimuthalEquidistantProjection::~AzimuthalEquidistantProjection() = default;
51
53{
54 return QObject::tr("Azimuthal Equidistant");
55}
56
58{
59 return QObject::tr(
60 "<p><b>Azimuthal Equidistant Projection</b> (\"fish eye\")</p><p>Applications: Display of seismic and radio data and for use in digital "
61 "planetariums.</p>");
62}
63
65{
66 return QIcon(QStringLiteral(":/icons/map-globe.png"));
67}
68
69AzimuthalEquidistantProjectionPrivate::AzimuthalEquidistantProjectionPrivate(AzimuthalEquidistantProjection *parent)
70 : AzimuthalProjectionPrivate(parent)
71{
72}
73
74qreal AzimuthalEquidistantProjection::clippingRadius() const
75{
76 return 1;
77}
78
80 const ViewportParams *viewport,
81 qreal &x,
82 qreal &y,
83 bool &globeHidesPoint) const
84{
85 const qreal lambda = coordinates.longitude();
86 const qreal phi = coordinates.latitude();
87 const qreal lambdaPrime = viewport->centerLongitude();
88 const qreal phi1 = viewport->centerLatitude();
89
90 qreal cosC = qSin(phi1) * qSin(phi) + qCos(phi1) * qCos(phi) * qCos(lambda - lambdaPrime);
91 // Prevent division by zero
92 if (cosC <= 0) {
93 globeHidesPoint = true;
94 return false;
95 }
96
97 qreal c = qAcos(cosC);
98
99 qreal k = cosC == 1 ? 1 : c / qSin(c);
100
101 // Let (x, y) be the position on the screen of the placemark..
102 x = (qCos(phi) * qSin(lambda - lambdaPrime)) * k;
103 y = (qCos(phi1) * qSin(phi) - qSin(phi1) * qCos(phi) * qCos(lambda - lambdaPrime)) * k;
104
105 x *= 2 * viewport->radius() / M_PI;
106 y *= 2 * viewport->radius() / M_PI;
107
108 const qint64 radius = clippingRadius() * viewport->radius();
109
110 if (x * x + y * y > radius * radius) {
111 globeHidesPoint = true;
112 return false;
113 }
114
115 globeHidesPoint = false;
116
117 x += viewport->width() / 2;
118 y = viewport->height() / 2 - y;
119
120 // Skip placemarks that are outside the screen area
121 return !(x < 0 || x >= viewport->width() || y < 0 || y >= viewport->height());
122}
123
125 const ViewportParams *viewport,
126 qreal *x,
127 qreal &y,
128 int &pointRepeatNum,
129 const QSizeF &size,
130 bool &globeHidesPoint) const
131{
132 pointRepeatNum = 0;
133 globeHidesPoint = false;
134
135 bool visible = screenCoordinates(coordinates, viewport, *x, y, globeHidesPoint);
136
137 // Skip placemarks that are outside the screen area
138 if (*x + size.width() / 2.0 < 0.0 || *x >= viewport->width() + size.width() / 2.0 || y + size.height() / 2.0 < 0.0
139 || y >= viewport->height() + size.height() / 2.0) {
140 return false;
141 }
142
143 // This projection doesn't have any repetitions,
144 // so the number of screen points referring to the geopoint is one.
145 pointRepeatNum = 1;
146 return visible;
147}
148
150 const int y,
151 const ViewportParams *viewport,
152 qreal &lon,
153 qreal &lat,
154 GeoDataCoordinates::Unit unit) const
155{
156 const qint64 radius = viewport->radius();
157 // Calculate how many degrees are being represented per pixel.
158 const qreal rad2Pixel = (2 * radius) / M_PI;
159 const qreal centerLon = viewport->centerLongitude();
160 const qreal centerLat = viewport->centerLatitude();
161 const qreal rx = (-viewport->width() / 2 + x) / rad2Pixel;
162 const qreal ry = (viewport->height() / 2 - y) / rad2Pixel;
163 const qreal c = qMax(qSqrt(rx * rx + ry * ry), qreal(0.0001)); // ensure we don't divide by zero
164 const qreal sinc = qSin(c);
165
166 lon = centerLon + qAtan2(rx * sinc, (c * qCos(centerLat) * qCos(c) - ry * qSin(centerLat) * sinc));
167
168 while (lon < -M_PI)
169 lon += 2 * M_PI;
170 while (lon > M_PI)
171 lon -= 2 * M_PI;
172
173 lat = qAsin(qCos(c) * qSin(centerLat) + (ry * sinc * qCos(centerLat)) / c);
174
175 if (unit == GeoDataCoordinates::Degree) {
176 lon *= RAD2DEG;
177 lat *= RAD2DEG;
178 }
179
180 return true;
181}
182
183}
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 class to implement the spherical projection used by the "Globe" view.
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.
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.
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.
AzimuthalEquidistantProjection()
Construct a new AzimuthalEquidistantProjection.
QString name() const override
Returns the user-visible name of the projection.
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
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.