• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
  • projections
EquirectProjection.cpp
Go to the documentation of this file.
1 //
2 // This file is part of the Marble Virtual Globe.
3 //
4 // This program is free software licensed under the GNU LGPL. You can
5 // find a copy of this license in LICENSE.txt in the top directory of
6 // the source code.
7 //
8 // Copyright 2007-2012 Torsten Rahn <rahn@kde.org>
9 // Copyright 2007-2008 Inge Wallin <ingwa@kde.org>
10 //
11 
12 
13 // Local
14 #include "EquirectProjection.h"
15 
16 // Marble
17 #include "ViewportParams.h"
18 
19 #include "MarbleDebug.h"
20 
21 using namespace Marble;
22 
23 
24 EquirectProjection::EquirectProjection()
25  : CylindricalProjection()
26 {
27  setMinLat( minValidLat() );
28  setMaxLat( maxValidLat() );
29 }
30 
31 EquirectProjection::~EquirectProjection()
32 {
33 }
34 
35 qreal EquirectProjection::maxValidLat() const
36 {
37  return +90.0 * DEG2RAD;
38 }
39 
40 qreal EquirectProjection::minValidLat() const
41 {
42  return -90.0 * DEG2RAD;
43 }
44 
45 bool EquirectProjection::screenCoordinates( const GeoDataCoordinates &geopoint,
46  const ViewportParams *viewport,
47  qreal &x, qreal &y, bool &globeHidesPoint ) const
48 {
49  globeHidesPoint = false;
50 
51  // Convenience variables
52  int radius = viewport->radius();
53  int width = viewport->width();
54  int height = viewport->height();
55 
56  qreal lon;
57  qreal lat;
58  qreal rad2Pixel = 2.0 * viewport->radius() / M_PI;
59 
60  const qreal centerLon = viewport->centerLongitude();
61  const qreal centerLat = viewport->centerLatitude();
62 
63  geopoint.geoCoordinates( lon, lat );
64 
65  // Let (x, y) be the position on the screen of the geopoint.
66  x = ((qreal)(viewport->width()) / 2.0 + rad2Pixel * (lon - centerLon));
67  y = ((qreal)(viewport->height()) / 2.0 - rad2Pixel * (lat - centerLat));
68 
69  // Return true if the calculated point is inside the screen area,
70  // otherwise return false.
71  return ( ( 0 <= y && y < height )
72  && ( ( 0 <= x && x < width )
73  || ( 0 <= x - 4 * radius && x - 4 * radius < width )
74  || ( 0 <= x + 4 * radius && x + 4 * radius < width ) ) );
75 }
76 
77 bool EquirectProjection::screenCoordinates( const GeoDataCoordinates &coordinates,
78  const ViewportParams *viewport,
79  qreal *x, qreal &y,
80  int &pointRepeatNum,
81  const QSizeF& size,
82  bool &globeHidesPoint ) const
83 {
84  pointRepeatNum = 0;
85  // On flat projections the observer's view onto the point won't be
86  // obscured by the target planet itself.
87  globeHidesPoint = false;
88 
89  // Convenience variables
90  int radius = viewport->radius();
91  qreal width = (qreal)(viewport->width());
92  qreal height = (qreal)(viewport->height());
93 
94  // Let (itX, y) be the first guess for one possible position on screen.
95  qreal itX;
96  screenCoordinates( coordinates, viewport, itX, y);
97 
98  // Make sure that the requested point is within the visible y range:
99  if ( 0 <= y + size.height() / 2.0 && y < height + size.height() / 2.0 ) {
100  // For the repetition case the same geopoint gets displayed on
101  // the map many times.across the longitude.
102 
103  int xRepeatDistance = 4 * radius;
104 
105  // Finding the leftmost positive x value
106  if ( itX + size.width() > xRepeatDistance ) {
107  const int repeatNum = (int)( ( itX + size.width() ) / xRepeatDistance );
108  itX = itX - repeatNum * xRepeatDistance;
109  }
110  if ( itX + size.width() / 2.0 < 0 ) {
111  itX += xRepeatDistance;
112  }
113  // The requested point is out of the visible x range:
114  if ( itX > width + size.width() / 2.0 ) {
115  return false;
116  }
117 
118  // Now iterate through all visible x screen coordinates for the point
119  // from left to right.
120  int itNum = 0;
121  while ( itX - size.width() / 2.0 < width ) {
122  *x = itX;
123  ++x;
124  ++itNum;
125  itX += xRepeatDistance;
126  }
127 
128  pointRepeatNum = itNum;
129 
130  return true;
131  }
132 
133  // The requested point is out of the visible y range.
134  return false;
135 }
136 
137 
138 bool EquirectProjection::geoCoordinates( const int x, const int y,
139  const ViewportParams *viewport,
140  qreal& lon, qreal& lat,
141  GeoDataCoordinates::Unit unit ) const
142 {
143  const int radius = viewport->radius();
144  const qreal pixel2Rad = M_PI / (2.0 * radius);
145 
146  // Get the Lat and Lon of the center point of the screen.
147  const qreal centerLon = viewport->centerLongitude();
148  const qreal centerLat = viewport->centerLatitude();
149 
150  {
151  const int halfImageWidth = viewport->width() / 2;
152  const int xPixels = x - halfImageWidth;
153 
154  lon = + xPixels * pixel2Rad + centerLon;
155 
156  while ( lon > M_PI ) lon -= 2.0 * M_PI;
157  while ( lon < -M_PI ) lon += 2.0 * M_PI;
158 
159  if ( unit == GeoDataCoordinates::Degree ) {
160  lon *= RAD2DEG;
161  }
162  }
163 
164  {
165  // Get yTop and yBottom, the limits of the map on the screen.
166  const int halfImageHeight = viewport->height() / 2;
167  const int yCenterOffset = (int)( centerLat * (qreal)(2 * radius) / M_PI);
168  const int yTop = halfImageHeight - radius + yCenterOffset;
169  const int yBottom = yTop + 2 * radius;
170 
171  // Return here if the y coordinate is outside the map
172  if ( yTop <= y && y < yBottom ) {
173  const int yPixels = y - halfImageHeight;
174  lat = - yPixels * pixel2Rad + centerLat;
175 
176  if ( unit == GeoDataCoordinates::Degree ) {
177  lat *= RAD2DEG;
178  }
179 
180  return true;
181  }
182  }
183 
184  return false;
185 }
186 
187 GeoDataLatLonAltBox EquirectProjection::latLonAltBox( const QRect& screenRect,
188  const ViewportParams *viewport ) const
189 {
190  qreal west;
191  qreal north = 90*DEG2RAD;
192  geoCoordinates( screenRect.left(), screenRect.top(), viewport, west, north, GeoDataCoordinates::Radian );
193 
194  qreal east;
195  qreal south = -90*DEG2RAD;
196  geoCoordinates( screenRect.right(), screenRect.bottom(), viewport, east, south, GeoDataCoordinates::Radian );
197 
198  // For the case where the whole viewport gets covered there is a
199  // pretty dirty and generic detection algorithm:
200  GeoDataLatLonAltBox latLonAltBox;
201  latLonAltBox.setNorth( north, GeoDataCoordinates::Radian );
202  latLonAltBox.setSouth( south, GeoDataCoordinates::Radian );
203  latLonAltBox.setWest( west, GeoDataCoordinates::Radian );
204  latLonAltBox.setEast( east, GeoDataCoordinates::Radian );
205  latLonAltBox.setMinAltitude( -100000000.0 );
206  latLonAltBox.setMaxAltitude( 100000000000000.0 );
207 
208  // Convenience variables
209  int radius = viewport->radius();
210  int width = viewport->width();
211 
212  // The remaining algorithm should be pretty generic for all kinds of
213  // flat projections:
214 
215  int xRepeatDistance = 4 * radius;
216  if ( width >= xRepeatDistance ) {
217  latLonAltBox.setWest( -M_PI );
218  latLonAltBox.setEast( +M_PI );
219  }
220 
221  // Now we need to check whether maxLat (e.g. the north pole) gets displayed
222  // inside the viewport.
223 
224  // We need a point on the screen at maxLat that definitely gets displayed:
225  qreal averageLongitude = latLonAltBox.east();
226 
227  GeoDataCoordinates maxLatPoint( averageLongitude, maxLat(), 0.0, GeoDataCoordinates::Radian );
228  GeoDataCoordinates minLatPoint( averageLongitude, minLat(), 0.0, GeoDataCoordinates::Radian );
229 
230  qreal dummyX, dummyY; // not needed
231 
232  if ( screenCoordinates( maxLatPoint, viewport, dummyX, dummyY ) ) {
233  latLonAltBox.setEast( +M_PI );
234  latLonAltBox.setWest( -M_PI );
235  }
236  if ( screenCoordinates( minLatPoint, viewport, dummyX, dummyY ) ) {
237  latLonAltBox.setEast( +M_PI );
238  latLonAltBox.setWest( -M_PI );
239  }
240 
241  return latLonAltBox;
242 }
243 
244 
245 bool EquirectProjection::mapCoversViewport( const ViewportParams *viewport ) const
246 {
247  // Convenience variables
248  int radius = viewport->radius();
249  //int width = viewport->width();
250  int height = viewport->height();
251  int halfImageHeight = viewport->height() / 2;
252 
253  // Get the Lat and Lon of the center point of the screen.
254  const qreal centerLat = viewport->centerLatitude();
255 
256  // Calculate how many pixel are being represented per radians.
257  const float rad2Pixel = (qreal)( 2 * radius )/M_PI;
258 
259  // Get yTop and yBottom, the limits of the map on the screen.
260  int yCenterOffset = (int)( centerLat * rad2Pixel );
261  int yTop = halfImageHeight - radius + yCenterOffset;
262  int yBottom = yTop + 2 * radius;
263 
264  if ( yTop >= 0 || yBottom < height )
265  return false;
266 
267  return true;
268 }
Marble::GeoDataCoordinates::Unit
Unit
enum used constructor to specify the units used
Definition: GeoDataCoordinates.h:64
Marble::RAD2DEG
const qreal RAD2DEG
Definition: MarbleGlobal.h:220
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::GeoDataCoordinates::Radian
Definition: GeoDataCoordinates.h:65
Marble::GeoDataLatLonBox::setNorth
void setNorth(const qreal north, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian)
Definition: GeoDataLatLonBox.cpp:101
Marble::EquirectProjection::screenCoordinates
bool screenCoordinates(const GeoDataCoordinates &coordinates, const ViewportParams *params, qreal &x, qreal &y, bool &globeHidesPoint) const
Get the screen coordinates corresponding to geographical coordinates in the map.
Definition: EquirectProjection.cpp:45
QRect::right
int right() const
Marble::EquirectProjection::EquirectProjection
EquirectProjection()
Construct a new EquirectProjection.
Definition: EquirectProjection.cpp:24
Marble::AbstractProjection::maxLat
qreal maxLat() const
Definition: AbstractProjection.cpp:54
MarbleDebug.h
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
Marble::ViewportParams::height
int height() const
Definition: ViewportParams.cpp:255
QRect
Marble::CylindricalProjection
A base class for the Equirectangular and Mercator projections in Marble.
Definition: CylindricalProjection.h:33
Marble::GeoDataCoordinates::geoCoordinates
void geoCoordinates(qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
use this function to get the longitude and latitude with one call - use the unit parameter to switch ...
Definition: GeoDataCoordinates.cpp:715
Marble::AbstractProjection::setMaxLat
void setMaxLat(qreal maxLat)
Definition: AbstractProjection.cpp:60
Marble::ViewportParams::width
int width() const
Definition: ViewportParams.cpp:250
QRect::top
int top() const
QRect::left
int left() const
Marble::radius
static qreal radius(qreal zoom)
Definition: thumbnailer.cpp:99
EquirectProjection.h
This file contains the headers for EquirectProjection.
Marble::DEG2RAD
const qreal DEG2RAD
Definition: MarbleGlobal.h:219
Marble::ViewportParams
A public class that controls what is visible in the viewport of a Marble map.
Definition: ViewportParams.h:44
ViewportParams.h
This file contains the headers for ViewportParams.
Marble::ViewportParams::centerLatitude
qreal centerLatitude() const
Definition: ViewportParams.cpp:294
Marble::EquirectProjection::maxValidLat
virtual qreal maxValidLat() const
Definition: EquirectProjection.cpp:35
QSizeF
Marble::EquirectProjection::geoCoordinates
bool geoCoordinates(const int x, const int y, const ViewportParams *params, qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Degree) const
Get the earth coordinates corresponding to a pixel in the map.
Definition: EquirectProjection.cpp:138
Marble::ViewportParams::radius
int radius() const
Definition: ViewportParams.cpp:195
Marble::EquirectProjection::latLonAltBox
GeoDataLatLonAltBox latLonAltBox(const QRect &screenRect, const ViewportParams *viewport) const
Definition: EquirectProjection.cpp:187
Marble::ViewportParams::centerLongitude
qreal centerLongitude() const
Definition: ViewportParams.cpp:289
QRect::bottom
int bottom() const
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
QSizeF::height
qreal height() const
Marble::EquirectProjection::mapCoversViewport
bool mapCoversViewport(const ViewportParams *viewport) const
Definition: EquirectProjection.cpp:245
Marble::EquirectProjection::~EquirectProjection
virtual ~EquirectProjection()
Definition: EquirectProjection.cpp:31
Marble::AbstractProjection::minLat
qreal minLat() const
Definition: AbstractProjection.cpp:76
Marble::GeoDataLatLonAltBox
A class that defines a 3D bounding box for geographic data.
Definition: GeoDataLatLonAltBox.h:49
Marble::AbstractProjection::setMinLat
void setMinLat(qreal minLat)
Definition: AbstractProjection.cpp:82
QSizeF::width
qreal width() const
Marble::EquirectProjection::minValidLat
virtual qreal minValidLat() const
Definition: EquirectProjection.cpp:40
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:39 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal