24 class DownloadRegionPrivate
27 MarbleModel* m_marbleModel;
29 QPair<int,int> m_tileLevelRange;
31 int m_visibleTileLevel;
33 DownloadRegionPrivate();
35 int rad2PixelX( qreal
const lon,
const TextureLayer *textureLayer )
const;
37 int rad2PixelY( qreal
const lat,
const TextureLayer *textureLayer )
const;
40 DownloadRegionPrivate::DownloadRegionPrivate() : m_marbleModel( 0 ),
41 m_tileLevelRange( 0, 0 ), m_visibleTileLevel( 0 )
47 int DownloadRegionPrivate::rad2PixelX( qreal
const lon,
const TextureLayer *textureLayer )
const
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 ) ) );
55 int DownloadRegionPrivate::rad2PixelY( qreal
const lat,
const TextureLayer *textureLayer )
const
57 qreal
const globalHeight = textureLayer->tileSize().height()
58 * textureLayer->tileRowCount( m_visibleTileLevel );
59 qreal
const normGlobalHeight = globalHeight /
M_PI;
60 switch ( textureLayer->tileProjection() ) {
62 return static_cast<int>( globalHeight * 0.5 - lat * normGlobalHeight );
64 if ( fabs( lat ) < 1.4835 )
65 return static_cast<int>( globalHeight * 0.5 -
gdInv( lat ) * 0.5 * normGlobalHeight );
67 return static_cast<int>( globalHeight * 0.5 - 3.1309587 * 0.5 * normGlobalHeight );
69 return static_cast<int>( globalHeight * 0.5 + 3.1309587 * 0.5 * normGlobalHeight );
77 d( new DownloadRegionPrivate )
84 d->m_marbleModel = model;
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;
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 );
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;
118 int const tileWidth = textureLayer->
tileSize().width();
119 int const tileHeight = textureLayer->
tileSize().height();
120 mDebug() <<
"DownloadRegionDialog downloadRegion: tileSize:" << tileWidth << tileHeight;
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 );
127 mDebug() <<
"visible level pixel coords (level/x1/y1/x2/y2):" << d->m_visibleTileLevel
128 << visibleLevelX1 << visibleLevelY1 << visibleLevelX2 << visibleLevelY2;
130 int bottomLevelX1, bottomLevelY1, bottomLevelX2, bottomLevelY2;
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;
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;
148 bottomLevelX1 = visibleLevelX1;
149 bottomLevelY1 = visibleLevelY1;
150 bottomLevelX2 = visibleLevelX2;
151 bottomLevelY2 = visibleLevelY2;
153 mDebug() <<
"bottom level pixel coords (level/x1/y1/x2/y2):"
154 << d->m_tileLevelRange.second
155 << bottomLevelX1 << bottomLevelY1 << bottomLevelX2 << bottomLevelY2;
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;
167 QVector<TileCoordsPyramid> pyramid;
168 pyramid << coordsPyramid;
174 d->m_visibleTileLevel = tileLevel;
179 if ( !d->m_marbleModel ) {
180 return QVector<TileCoordsPyramid>();
183 RoutingModel* routingModel = d->m_marbleModel->routingManager()->routingModel();
184 if( routingModel->
rowCount() == 0 ) {
185 return QVector<TileCoordsPyramid>();
189 int const topLevel = d->m_tileLevelRange.first;
190 int const bottomLevel = d->m_tileLevelRange.second;
193 int const tileWidth = textureLayer->
tileSize().width();
194 int const tileHeight = textureLayer->
tileSize().height();
196 qreal radius = d->m_marbleModel->planetRadius();
197 QVector<TileCoordsPyramid> pyramid;
198 qreal radianOffset = offset / radius;
200 for(
int i = 1; i < waypoints.
size(); ++i ) {
203 qreal latCenter = position.
latitude();
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;
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 );
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 );
223 int bottomLevelTileX1 = 0;
224 int bottomLevelTileY1 = 0;
225 int bottomLevelTileX2 = 0;
226 int bottomLevelTileY2 = 0;
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;
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;
243 bottomLevelTileX1 = west;
244 bottomLevelTileY1 = north;
245 bottomLevelTileX2 = east;
246 bottomLevelTileY2 = south;
249 QRect waypointRegion;
251 waypointRegion.setCoords( bottomLevelTileX1/tileWidth, bottomLevelTileY1/tileHeight,
252 bottomLevelTileX2/tileWidth, bottomLevelTileY2/tileHeight );
254 pyramid << coordsPyramid;
262 #include "DownloadRegion.moc"
A 3d point representation.
qreal gdInv(qreal x)
This method is a fast Mac Laurin power series approximation of the.
void setMarbleModel(MarbleModel *model)
This file contains the headers for MarbleModel.
int size() const
Returns the number of nodes in a LineString.
const Route & route() const
int rowCount(const QModelIndex &parent=QModelIndex()) const
Overload of QAbstractListModel.
qreal latitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
qreal north(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the northern boundary of the bounding box.
qreal east(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the eastern boundary of the bounding box.
This file contains the headers for MarbleMap.
QVector< TileCoordsPyramid > region(const TextureLayer *textureLayer, const GeoDataLatLonAltBox ®ion) const
qint64 tilesCount() const
returns the number of tiles covered by one pyramid
A LineString that allows to store a contiguous set of line segments.
qreal longitude(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
qreal west(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the western boundary of the bounding box.
The data model (not based on QAbstractModel) for a MarbleWidget.
void setTileLevelRange(int const minimumTileLevel, int const maximumTileLevel)
qreal south(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the southern boundary of the bounding box.
void setBottomLevelCoords(QRect const &coords)
void setVisibleTileLevel(int const tileLevel)
QVector< TileCoordsPyramid > routeRegion(const TextureLayer *textureLayer, qreal offset) const
calculates the region to be downloaded around a route
const GeoDataLineString & path() const
QDebug mDebug()
a function to replace qDebug() in Marble library code
A class that defines a 3D bounding box for geographic data.
DownloadRegion(QObject *parent=0)