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

marble

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