Marble

LambertAzimuthalProjection.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 "LambertAzimuthalProjection.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 LambertAzimuthalProjectionPrivate : public AzimuthalProjectionPrivate
25{
26public:
27 explicit LambertAzimuthalProjectionPrivate(LambertAzimuthalProjection *parent);
28
29 Q_DECLARE_PUBLIC(LambertAzimuthalProjection)
30};
31
33 : AzimuthalProjection(new LambertAzimuthalProjectionPrivate(this))
34{
35 setMinLat(minValidLat());
36 setMaxLat(maxValidLat());
37}
38
39LambertAzimuthalProjection::LambertAzimuthalProjection(LambertAzimuthalProjectionPrivate *dd)
41{
42 setMinLat(minValidLat());
43 setMaxLat(maxValidLat());
44}
45
46LambertAzimuthalProjection::~LambertAzimuthalProjection() = default;
47
48LambertAzimuthalProjectionPrivate::LambertAzimuthalProjectionPrivate(LambertAzimuthalProjection *parent)
49 : AzimuthalProjectionPrivate(parent)
50{
51}
52
54{
55 return QObject::tr("Lambert Azimuthal Equal-Area");
56}
57
59{
60 return QObject::tr("<p><b>Lambert Azimuthal Equal-Area Projection</b></p><p>Applications: Used in structural geology to plot directional data.</p>");
61}
62
64{
65 return QIcon(QStringLiteral(":/icons/map-globe.png"));
66}
67
68qreal LambertAzimuthalProjection::clippingRadius() const
69{
70 return 1;
71}
72
74 const ViewportParams *viewport,
75 qreal &x,
76 qreal &y,
77 bool &globeHidesPoint) const
78{
79 const qreal lambda = coordinates.longitude();
80 const qreal phi = coordinates.latitude();
81 const qreal lambdaPrime = viewport->centerLongitude();
82 const qreal phi1 = viewport->centerLatitude();
83
84 qreal cosC = qSin(phi1) * qSin(phi) + qCos(phi1) * qCos(phi) * qCos(lambda - lambdaPrime);
85 // Prevent division by zero
86 if (cosC <= 0) {
87 globeHidesPoint = true;
88 return false;
89 }
90
91 qreal k = qSqrt(2 / (1 + cosC));
92
93 // Let (x, y) be the position on the screen of the placemark..
94 x = (qCos(phi) * qSin(lambda - lambdaPrime)) * k;
95 y = (qCos(phi1) * qSin(phi) - qSin(phi1) * qCos(phi) * qCos(lambda - lambdaPrime)) * k;
96
97 x *= viewport->radius() / qSqrt(2);
98 y *= viewport->radius() / qSqrt(2);
99
100 const qint64 radius = clippingRadius() * viewport->radius();
101
102 if (x * x + y * y > radius * radius) {
103 globeHidesPoint = true;
104 return false;
105 }
106
107 globeHidesPoint = false;
108
109 x += viewport->width() / 2;
110 y = viewport->height() / 2 - y;
111
112 // Skip placemarks that are outside the screen area
113 return !(x < 0 || x >= viewport->width() || y < 0 || y >= viewport->height());
114}
115
117 const ViewportParams *viewport,
118 qreal *x,
119 qreal &y,
120 int &pointRepeatNum,
121 const QSizeF &size,
122 bool &globeHidesPoint) const
123{
124 pointRepeatNum = 0;
125 globeHidesPoint = false;
126
127 bool visible = screenCoordinates(coordinates, viewport, *x, y, globeHidesPoint);
128
129 // Skip placemarks that are outside the screen area
130 if (*x + size.width() / 2.0 < 0.0 || *x >= viewport->width() + size.width() / 2.0 || y + size.height() / 2.0 < 0.0
131 || y >= viewport->height() + size.height() / 2.0) {
132 return false;
133 }
134
135 // This projection doesn't have any repetitions,
136 // so the number of screen points referring to the geopoint is one.
137 pointRepeatNum = 1;
138 return visible;
139}
140
141bool LambertAzimuthalProjection::geoCoordinates(const int x, const int y, const ViewportParams *viewport, qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit)
142 const
143{
144 const qint64 radius = viewport->radius();
145 // Calculate how many degrees are being represented per pixel.
146 const qreal centerLon = viewport->centerLongitude();
147 const qreal centerLat = viewport->centerLatitude();
148 const qreal rx = (-viewport->width() / 2 + x);
149 const qreal ry = (viewport->height() / 2 - y);
150 const qreal p = qMax(qSqrt(rx * rx + ry * ry), qreal(0.0001)); // ensure we don't divide by zero
151
152 // exclude area too far away from map, as it may cause undefined arcsin result
153 if (p > (qSqrt(2) * radius)) {
154 return false;
155 }
156 const qreal c = 2 * qAsin(p / (qSqrt(2) * radius));
157 const qreal sinc = qSin(c);
158
159 lon = centerLon + qAtan2(rx * sinc, (p * qCos(centerLat) * qCos(c) - ry * qSin(centerLat) * sinc));
160
161 while (lon < -M_PI)
162 lon += 2 * M_PI;
163 while (lon > M_PI)
164 lon -= 2 * M_PI;
165
166 lat = qAsin(qCos(c) * qSin(centerLat) + (ry * sinc * qCos(centerLat)) / p);
167
168 if (unit == GeoDataCoordinates::Degree) {
169 lon *= RAD2DEG;
170 lat *= RAD2DEG;
171 }
172
173 return true;
174}
175
176}
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.
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.
QString description() const override
Returns a short user description of the projection that can be used in tooltips or dialogs.
QIcon icon() const override
Returns an icon for the projection.
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.
LambertAzimuthalProjection()
Construct a new LambertAzimuthalProjection.
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 Fri Nov 8 2024 12:02:44 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.