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 "ViewportParams.h"
14#include "GeoDataPoint.h"
15#include "GeoDataLineString.h"
16#include "GeoDataCoordinates.h"
17#include "MarbleGlobal.h"
18#include "AzimuthalProjection_p.h"
19
20#include <QIcon>
21#include <qmath.h>
22
23#define SAFE_DISTANCE
24
25namespace Marble
26{
27
28class AzimuthalEquidistantProjectionPrivate : public AzimuthalProjectionPrivate
29{
30 public:
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()
51{
52}
53
55{
56 return QObject::tr( "Azimuthal Equidistant" );
57}
58
60{
61 return QObject::tr( "<p><b>Azimuthal Equidistant Projection</b> (\"fish eye\")</p><p>Applications: Display of seismic and radio data and for use in digital 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, qreal &y, bool &globeHidesPoint ) const
82{
83 const qreal lambda = coordinates.longitude();
84 const qreal phi = coordinates.latitude();
85 const qreal lambdaPrime = viewport->centerLongitude();
86 const qreal phi1 = viewport->centerLatitude();
87
88 qreal cosC = qSin( phi1 ) * qSin( phi ) + qCos( phi1 ) * qCos( phi ) * qCos( lambda - lambdaPrime );
89 // Prevent division by zero
90 if (cosC <= 0) {
91 globeHidesPoint = true;
92 return false;
93 }
94
95 qreal c = qAcos(cosC);
96
97 qreal k = cosC == 1 ? 1 : c / qSin( c );
98
99 // Let (x, y) be the position on the screen of the placemark..
100 x = ( qCos( phi ) * qSin( lambda - lambdaPrime ) ) * k;
101 y = ( qCos( phi1 ) * qSin( phi ) - qSin( phi1 ) * qCos( phi ) * qCos( lambda - lambdaPrime ) ) * k;
102
103 x *= 2 * viewport->radius() / M_PI;
104 y *= 2 * viewport->radius() / M_PI;
105
106 const qint64 radius = clippingRadius() * viewport->radius();
107
108 if (x*x + y*y > radius * radius) {
109 globeHidesPoint = true;
110 return false;
111 }
112
113 globeHidesPoint = false;
114
115 x += viewport->width() / 2;
116 y = viewport->height() / 2 - y;
117
118 // Skip placemarks that are outside the screen area
119 return !(x < 0 || x >= viewport->width() || y < 0 || y >= viewport->height());
120}
121
123 const ViewportParams *viewport,
124 qreal *x, qreal &y,
125 int &pointRepeatNum,
126 const QSizeF& size,
127 bool &globeHidesPoint ) const
128{
129 pointRepeatNum = 0;
130 globeHidesPoint = false;
131
132 bool visible = screenCoordinates( coordinates, viewport, *x, y, globeHidesPoint );
133
134 // Skip placemarks that are outside the screen area
135 if ( *x + size.width() / 2.0 < 0.0 || *x >= viewport->width() + size.width() / 2.0
136 || y + size.height() / 2.0 < 0.0 || y >= viewport->height() + size.height() / 2.0 )
137 {
138 return false;
139 }
140
141 // This projection doesn't have any repetitions,
142 // so the number of screen points referring to the geopoint is one.
143 pointRepeatNum = 1;
144 return visible;
145}
146
147
149 const ViewportParams *viewport,
150 qreal& lon, qreal& lat,
151 GeoDataCoordinates::Unit unit ) const
152{
153 const qint64 radius = viewport->radius();
154 // Calculate how many degrees are being represented per pixel.
155 const qreal rad2Pixel = ( 2 * radius ) / M_PI;
156 const qreal centerLon = viewport->centerLongitude();
157 const qreal centerLat = viewport->centerLatitude();
158 const qreal rx = ( - viewport->width() / 2 + x ) / rad2Pixel;
159 const qreal ry = ( viewport->height() / 2 - y ) / rad2Pixel;
160 const qreal c = qMax( qSqrt( rx*rx + ry*ry ), qreal(0.0001) ); // ensure we don't divide by zero
161 const qreal sinc = qSin(c);
162
163 lon = centerLon + qAtan2( rx*sinc , ( c*qCos( centerLat )*qCos( c ) - ry*qSin( centerLat )*sinc ) );
164
165 while ( lon < -M_PI ) lon += 2 * M_PI;
166 while ( lon > M_PI ) lon -= 2 * M_PI;
167
168 lat = qAsin( qCos(c)*qSin(centerLat) + (ry*sinc*qCos(centerLat))/c );
169
170 if ( unit == GeoDataCoordinates::Degree ) {
171 lon *= RAD2DEG;
172 lat *= RAD2DEG;
173 }
174
175 return true;
176}
177
178}
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.
qreal longitude(GeoDataCoordinates::Unit unit) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
Unit
enum used constructor to specify the units used
qreal latitude(GeoDataCoordinates::Unit unit) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
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 Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.