• 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
DownloadRegion.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 2012 Dennis Nienhüser <earthwings@gentoo.org>
9 //
10 
11 #include "DownloadRegion.h"
12 
13 #include "MarbleModel.h"
14 #include "MarbleMap.h"
15 #include "MarbleMath.h"
16 #include "MarbleDebug.h"
17 #include "TextureLayer.h"
18 #include "GeoDataLatLonAltBox.h"
19 #include "GeoDataLineString.h"
20 
21 namespace Marble {
22 
23 class DownloadRegionPrivate
24 {
25 public:
26  MarbleModel* m_marbleModel;
27 
28  QPair<int,int> m_tileLevelRange;
29 
30  int m_visibleTileLevel;
31 
32  DownloadRegionPrivate();
33 
34  int rad2PixelX( qreal const lon, const TextureLayer *textureLayer ) const;
35 
36  int rad2PixelY( qreal const lat, const TextureLayer *textureLayer ) const;
37 };
38 
39 DownloadRegionPrivate::DownloadRegionPrivate() : m_marbleModel( 0 ),
40  m_tileLevelRange( 0, 0 ), m_visibleTileLevel( 0 )
41 {
42  // nothing to do
43 }
44 
45 // copied from AbstractScanlineTextureMapper and slightly adjusted
46 int DownloadRegionPrivate::rad2PixelX( qreal const lon, const TextureLayer *textureLayer ) const
47 {
48  qreal const globalWidth = textureLayer->tileSize().width()
49  * textureLayer->tileColumnCount( m_visibleTileLevel );
50  return static_cast<int>( globalWidth * 0.5 + lon * ( globalWidth / ( 2.0 * M_PI ) ) );
51 }
52 
53 // copied from AbstractScanlineTextureMapper and slightly adjusted
54 int DownloadRegionPrivate::rad2PixelY( qreal const lat, const TextureLayer *textureLayer ) const
55 {
56  qreal const globalHeight = textureLayer->tileSize().height()
57  * textureLayer->tileRowCount( m_visibleTileLevel );
58  qreal const normGlobalHeight = globalHeight / M_PI;
59  switch ( textureLayer->tileProjection() ) {
60  case GeoSceneTiled::Equirectangular:
61  return static_cast<int>( globalHeight * 0.5 - lat * normGlobalHeight );
62  case GeoSceneTiled::Mercator:
63  if ( fabs( lat ) < 1.4835 )
64  return static_cast<int>( globalHeight * 0.5 - gdInv( lat ) * 0.5 * normGlobalHeight );
65  if ( lat >= +1.4835 )
66  return static_cast<int>( globalHeight * 0.5 - 3.1309587 * 0.5 * normGlobalHeight );
67  if ( lat <= -1.4835 )
68  return static_cast<int>( globalHeight * 0.5 + 3.1309587 * 0.5 * normGlobalHeight );
69  }
70 
71  // Dummy value to avoid a warning.
72  return 0;
73 }
74 
75 DownloadRegion::DownloadRegion( QObject* parent ) : QObject( parent ),
76  d( new DownloadRegionPrivate )
77 {
78  // nothing to do
79 }
80 
81 void DownloadRegion::setMarbleModel( MarbleModel* model )
82 {
83  d->m_marbleModel = model;
84 }
85 
86 DownloadRegion::~DownloadRegion()
87 {
88  delete d;
89 }
90 
91 void DownloadRegion::setTileLevelRange( const int minimumTileLevel, const int maximumTileLevel )
92 {
93  Q_ASSERT( minimumTileLevel >= 0 );
94  Q_ASSERT( maximumTileLevel >= 0 );
95  Q_ASSERT( minimumTileLevel <= maximumTileLevel );
96  d->m_tileLevelRange.first = minimumTileLevel;
97  d->m_tileLevelRange.second = maximumTileLevel;
98 }
99 
100 QVector<TileCoordsPyramid> DownloadRegion::region( const TextureLayer *textureLayer, const GeoDataLatLonAltBox &downloadRegion ) const
101 {
102  Q_ASSERT( textureLayer );
103  int const westX = d->rad2PixelX( downloadRegion.west(), textureLayer );
104  int const northY = d->rad2PixelY( downloadRegion.north(), textureLayer );
105  int const eastX = d->rad2PixelX( downloadRegion.east(), textureLayer );
106  int const southY = d->rad2PixelY( downloadRegion.south(), textureLayer );
107 
108  // FIXME: remove this stuff
109  mDebug() << "DownloadRegionDialog downloadRegion:"
110  << "north:" << downloadRegion.north()
111  << "south:" << downloadRegion.south()
112  << "east:" << downloadRegion.east()
113  << "west:" << downloadRegion.west();
114  mDebug() << "north/west (x/y):" << westX << northY;
115  mDebug() << "south/east (x/y):" << eastX << southY;
116 
117  int const tileWidth = textureLayer->tileSize().width();
118  int const tileHeight = textureLayer->tileSize().height();
119  mDebug() << "DownloadRegionDialog downloadRegion: tileSize:" << tileWidth << tileHeight;
120 
121  int const visibleLevelX1 = qMin( westX, eastX );
122  int const visibleLevelY1 = qMin( northY, southY );
123  int const visibleLevelX2 = qMax( westX, eastX );
124  int const visibleLevelY2 = qMax( northY, southY );
125 
126  mDebug() << "visible level pixel coords (level/x1/y1/x2/y2):" << d->m_visibleTileLevel
127  << visibleLevelX1 << visibleLevelY1 << visibleLevelX2 << visibleLevelY2;
128 
129  int bottomLevelX1, bottomLevelY1, bottomLevelX2, bottomLevelY2;
130  // the pixel coords calculated above are referring to the visible tile level,
131  // if the bottom level is a different level, we have to take it into account
132  if ( d->m_visibleTileLevel > d->m_tileLevelRange.second ) {
133  int const deltaLevel = d->m_visibleTileLevel - d->m_tileLevelRange.second;
134  bottomLevelX1 = visibleLevelX1 >> deltaLevel;
135  bottomLevelY1 = visibleLevelY1 >> deltaLevel;
136  bottomLevelX2 = visibleLevelX2 >> deltaLevel;
137  bottomLevelY2 = visibleLevelY2 >> deltaLevel;
138  }
139  else if ( d->m_visibleTileLevel < d->m_tileLevelRange.second ) {
140  int const deltaLevel = d->m_tileLevelRange.second - d->m_visibleTileLevel;
141  bottomLevelX1 = visibleLevelX1 << deltaLevel;
142  bottomLevelY1 = visibleLevelY1 << deltaLevel;
143  bottomLevelX2 = visibleLevelX2 << deltaLevel;
144  bottomLevelY2 = visibleLevelY2 << deltaLevel;
145  }
146  else {
147  bottomLevelX1 = visibleLevelX1;
148  bottomLevelY1 = visibleLevelY1;
149  bottomLevelX2 = visibleLevelX2;
150  bottomLevelY2 = visibleLevelY2;
151  }
152  mDebug() << "bottom level pixel coords (level/x1/y1/x2/y2):"
153  << d->m_tileLevelRange.second
154  << bottomLevelX1 << bottomLevelY1 << bottomLevelX2 << bottomLevelY2;
155 
156  TileCoordsPyramid coordsPyramid( d->m_tileLevelRange.first, d->m_tileLevelRange.second );
157  QRect bottomLevelTileCoords;
158  bottomLevelTileCoords.setCoords
159  ( bottomLevelX1 / tileWidth,
160  bottomLevelY1 / tileHeight,
161  bottomLevelX2 / tileWidth + ( bottomLevelX2 % tileWidth > 0 ? 1 : 0 ),
162  bottomLevelY2 / tileHeight + ( bottomLevelY2 % tileHeight > 0 ? 1 : 0 ));
163  mDebug() << "bottom level tile coords: (x1/y1/size):" << bottomLevelTileCoords;
164  coordsPyramid.setBottomLevelCoords( bottomLevelTileCoords );
165  mDebug() << "tiles count:" << coordsPyramid.tilesCount( );
166  QVector<TileCoordsPyramid> pyramid;
167  pyramid << coordsPyramid;
168  return pyramid;
169 }
170 
171 void DownloadRegion::setVisibleTileLevel(const int tileLevel)
172 {
173  d->m_visibleTileLevel = tileLevel;
174 }
175 
176 QVector<TileCoordsPyramid> DownloadRegion::fromPath( const TextureLayer *textureLayer, qreal offset, const GeoDataLineString &waypoints ) const
177 {
178  if ( !d->m_marbleModel ) {
179  return QVector<TileCoordsPyramid>();
180  }
181 
182  int const topLevel = d->m_tileLevelRange.first;
183  int const bottomLevel = d->m_tileLevelRange.second;
184  TileCoordsPyramid coordsPyramid( topLevel, bottomLevel );
185 
186  int const tileWidth = textureLayer->tileSize().width();
187  int const tileHeight = textureLayer->tileSize().height();
188 
189  qreal radius = d->m_marbleModel->planetRadius();
190  QVector<TileCoordsPyramid> pyramid;
191  qreal radianOffset = offset / radius;
192 
193  for( int i = 1; i < waypoints.size(); ++i ) {
194  GeoDataCoordinates position = waypoints[i];
195  qreal lonCenter = position.longitude();
196  qreal latCenter = position.latitude();
197 
198  // coordinates of the of the vertices of the square(topleft and bottomright) at an offset distance from the waypoint
199  qreal latNorth = asin( sin( latCenter ) * cos( radianOffset ) + cos( latCenter ) * sin( radianOffset ) * cos( 7*M_PI/4 ) );
200  qreal dlonWest = atan2( sin( 7*M_PI/4 ) * sin( radianOffset ) * cos( latCenter ), cos( radianOffset ) - sin( latCenter ) * sin( latNorth ) );
201  qreal lonWest = fmod( lonCenter - dlonWest + M_PI, 2*M_PI ) - M_PI;
202  qreal latSouth = asin( sin( latCenter ) * cos( radianOffset ) + cos( latCenter ) * sin( radianOffset ) * cos( 3*M_PI/4 ) );
203  qreal dlonEast = atan2( sin( 3*M_PI/4 ) * sin( radianOffset ) * cos( latCenter ), cos( radianOffset ) - sin( latCenter ) * sin( latSouth ) );
204  qreal lonEast = fmod( lonCenter - dlonEast+M_PI, 2*M_PI ) - M_PI;
205 
206  int const northY = d->rad2PixelY( latNorth, textureLayer );
207  int const southY = d->rad2PixelY( latSouth, textureLayer );
208  int const eastX = d->rad2PixelX( lonEast, textureLayer );
209  int const westX = d->rad2PixelX( lonWest, textureLayer );
210 
211  int const west = qMin( westX, eastX );
212  int const north = qMin( northY, southY );
213  int const east = qMax( westX, eastX );
214  int const south = qMax( northY, southY );
215 
216  int bottomLevelTileX1 = 0;
217  int bottomLevelTileY1 = 0;
218  int bottomLevelTileX2 = 0;
219  int bottomLevelTileY2 = 0;
220 
221  if ( d->m_visibleTileLevel > d->m_tileLevelRange.second ) {
222  int const deltaLevel = d->m_visibleTileLevel - d->m_tileLevelRange.second;
223  bottomLevelTileX1 = west >> deltaLevel;
224  bottomLevelTileY1 = north >> deltaLevel;
225  bottomLevelTileX2 = east >> deltaLevel;
226  bottomLevelTileY2 = south >> deltaLevel;
227  }
228  else if ( d->m_visibleTileLevel < bottomLevel ) {
229  int const deltaLevel = bottomLevel - d->m_visibleTileLevel;
230  bottomLevelTileX1 = west << deltaLevel;
231  bottomLevelTileY1 = north << deltaLevel;
232  bottomLevelTileX2 = east << deltaLevel;
233  bottomLevelTileY2 = south << deltaLevel;
234  }
235  else {
236  bottomLevelTileX1 = west;
237  bottomLevelTileY1 = north;
238  bottomLevelTileX2 = east;
239  bottomLevelTileY2 = south;
240  }
241 
242  QRect waypointRegion;
243  //square region around the waypoint
244  waypointRegion.setCoords( bottomLevelTileX1/tileWidth, bottomLevelTileY1/tileHeight,
245  bottomLevelTileX2/tileWidth, bottomLevelTileY2/tileHeight );
246  coordsPyramid.setBottomLevelCoords( waypointRegion );
247  pyramid << coordsPyramid;
248  }
249 
250  return pyramid;
251 }
252 
253 }
254 
255 #include "DownloadRegion.moc"
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
Marble::GeoSceneTiled::Equirectangular
Definition: GeoSceneTiled.h:47
Marble::gdInv
qreal gdInv(qreal x)
This method is a fast Mac Laurin power series approximation of the.
Definition: MarbleMath.h:96
QSize::width
int width() const
MarbleMath.h
Marble::DownloadRegion::~DownloadRegion
~DownloadRegion()
Definition: DownloadRegion.cpp:86
Marble::DownloadRegion::setMarbleModel
void setMarbleModel(MarbleModel *model)
Definition: DownloadRegion.cpp:81
MarbleModel.h
This file contains the headers for MarbleModel.
Marble::GeoDataLineString::size
int size() const
Returns the number of nodes in a LineString.
Definition: GeoDataLineString.cpp:138
Marble::GeoDataCoordinates::latitude
qreal latitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
Definition: GeoDataCoordinates.cpp:751
MarbleDebug.h
Marble::GeoDataLatLonBox::north
qreal north(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the northern boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:93
Marble::GeoDataLatLonBox::east
qreal east(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the eastern boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:135
TextureLayer.h
QRect
Marble::TileCoordsPyramid
Definition: TileCoordsPyramid.h:23
MarbleMap.h
This file contains the headers for MarbleMap.
Marble::DownloadRegion::region
QVector< TileCoordsPyramid > region(const TextureLayer *textureLayer, const GeoDataLatLonAltBox &region) const
Definition: DownloadRegion.cpp:100
QObject
QRect::setCoords
void setCoords(int x1, int y1, int x2, int y2)
Marble::radius
static qreal radius(qreal zoom)
Definition: thumbnailer.cpp:99
Marble::DownloadRegion::fromPath
QVector< TileCoordsPyramid > fromPath(const TextureLayer *textureLayer, qreal offset, const GeoDataLineString &path) const
calculates the region to be downloaded around a path
Definition: DownloadRegion.cpp:176
Marble::TextureLayer
Definition: TextureLayer.h:38
GeoDataLineString.h
Marble::TileCoordsPyramid::tilesCount
qint64 tilesCount() const
returns the number of tiles covered by one pyramid
Definition: TileCoordsPyramid.cpp:97
Marble::GeoDataLineString
A LineString that allows to store a contiguous set of line segments.
Definition: GeoDataLineString.h:75
QPair< int, int >
Marble::GeoDataCoordinates::longitude
qreal longitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
Definition: GeoDataCoordinates.cpp:739
Marble::GeoSceneTiled::Mercator
Definition: GeoSceneTiled.h:47
Marble::GeoDataLatLonBox::west
qreal west(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the western boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:156
Marble::MarbleModel
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:97
QVector
Marble::DownloadRegion::setTileLevelRange
void setTileLevelRange(int const minimumTileLevel, int const maximumTileLevel)
Definition: DownloadRegion.cpp:91
GeoDataLatLonAltBox.h
Marble::GeoDataLatLonBox::south
qreal south(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the southern boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:114
QSize::height
int height() const
Marble::TileCoordsPyramid::setBottomLevelCoords
void setBottomLevelCoords(QRect const &coords)
Definition: TileCoordsPyramid.cpp:77
Marble::DownloadRegion::setVisibleTileLevel
void setVisibleTileLevel(int const tileLevel)
Definition: DownloadRegion.cpp:171
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
DownloadRegion.h
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:36
Marble::TextureLayer::tileSize
QSize tileSize() const
Definition: TextureLayer.cpp:468
Marble::GeoDataLatLonAltBox
A class that defines a 3D bounding box for geographic data.
Definition: GeoDataLatLonAltBox.h:49
Marble::DownloadRegion::DownloadRegion
DownloadRegion(QObject *parent=0)
Definition: DownloadRegion.cpp:75
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:38 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