Marble

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

KDE's Doxygen guidelines are available online.