File indexing completed on 2024-05-05 12:06:54
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Jens-Michael Hoffmann <jmho@c-xx.com> 0004 // 0005 0006 #include "DownloadRegionDialog.h" 0007 0008 #include <cmath> 0009 0010 #include <QDialogButtonBox> 0011 #include <QGroupBox> 0012 #include <QHBoxLayout> 0013 #include <QHideEvent> 0014 #include <QLabel> 0015 #include <QComboBox> 0016 #include <QPushButton> 0017 #include <QButtonGroup> 0018 #include <QRadioButton> 0019 #include <QShowEvent> 0020 #include <QVBoxLayout> 0021 #include <QSpinBox> 0022 #include <QScrollArea> 0023 #include <QSet> 0024 #include <QStandardItemModel> 0025 #include <QTimer> 0026 0027 #include "GeoDataLatLonAltBox.h" 0028 #include "MarbleDebug.h" 0029 #include "MarbleModel.h" 0030 #include "MarbleWidget.h" 0031 #include "LatLonBoxWidget.h" 0032 #include "TileLayer.h" 0033 #include "TextureLayer.h" 0034 #include "VectorTileLayer.h" 0035 #include "TileId.h" 0036 #include "TileCoordsPyramid.h" 0037 #include "TileLevelRangeWidget.h" 0038 #include "TileLoaderHelper.h" 0039 #include "routing/RoutingManager.h" 0040 #include "routing/RoutingModel.h" 0041 #include "GeoDataCoordinates.h" 0042 #include "GeoDataLineString.h" 0043 #include "DownloadRegion.h" 0044 #include "GeoSceneDocument.h" 0045 #include "GeoSceneMap.h" 0046 #include "Route.h" 0047 0048 namespace Marble 0049 { 0050 0051 int const maxTilesCount = 100000; 0052 int const minimumRouteOffset = 0; 0053 int const maximumRouteOffset = 10000; 0054 int averageTextureTileSize = 13; //The average size of a tile in kilobytes 0055 int averageVectorTileSize = 30; // The average size of a vector tile in kilobytes 0056 0057 class Q_DECL_HIDDEN DownloadRegionDialog::Private 0058 { 0059 public: 0060 Private( MarbleWidget *const widget, QDialog * const dialog ); 0061 QWidget * createSelectionMethodBox(); 0062 QLayout * createTilesCounter(); 0063 QWidget * createOkCancelButtonBox(); 0064 0065 bool hasRoute() const; 0066 bool hasTextureLayers() const; 0067 bool hasVectorLayers() const; 0068 QDialog * m_dialog; 0069 QLabel * m_layerLabel; 0070 QComboBox * m_layerComboBox; 0071 QButtonGroup * m_buttonGroup; 0072 QRadioButton * m_visibleRegionMethodButton; 0073 QRadioButton * m_specifiedRegionMethodButton; 0074 LatLonBoxWidget * m_latLonBoxWidget; 0075 TileLevelRangeWidget * m_tileLevelRangeWidget; 0076 QRadioButton *m_routeDownloadMethodButton; 0077 QLabel* m_routeOffsetLabel; 0078 QDoubleSpinBox *m_routeOffsetSpinBox; 0079 QLabel * m_tilesCountLabel; 0080 QLabel * m_tileSizeInfo; 0081 QPushButton * m_okButton; 0082 QPushButton * m_applyButton; 0083 TextureLayer const * m_textureLayer; 0084 VectorTileLayer const * m_vectorTileLayer; 0085 int m_visibleTileLevel; 0086 MarbleModel const*const m_model; 0087 MarbleWidget *const m_widget; 0088 SelectionMethod m_selectionMethod; 0089 GeoDataLatLonAltBox m_visibleRegion; 0090 RoutingModel *m_routingModel; 0091 DownloadRegion m_downloadRegion; 0092 TileType m_tileType; 0093 }; 0094 0095 DownloadRegionDialog::Private::Private( MarbleWidget * const widget, 0096 QDialog * const dialog ) 0097 : m_dialog( dialog ), 0098 m_layerLabel( nullptr ), 0099 m_layerComboBox( nullptr ), 0100 m_buttonGroup(nullptr), 0101 m_visibleRegionMethodButton( nullptr ), 0102 m_specifiedRegionMethodButton( nullptr ), 0103 m_latLonBoxWidget( new LatLonBoxWidget ), 0104 m_tileLevelRangeWidget( new TileLevelRangeWidget ), 0105 m_routeDownloadMethodButton( nullptr ), 0106 m_routeOffsetLabel( nullptr ), 0107 m_routeOffsetSpinBox( nullptr ), 0108 m_tilesCountLabel( nullptr ), 0109 m_tileSizeInfo( nullptr ), 0110 m_okButton( nullptr ), 0111 m_applyButton( nullptr ), 0112 m_textureLayer( widget->textureLayer() ), 0113 m_vectorTileLayer( widget->vectorTileLayer() ), 0114 m_visibleTileLevel( 0 ), 0115 m_model( widget->model() ), 0116 m_widget( widget ), 0117 m_selectionMethod( VisibleRegionMethod ), 0118 m_visibleRegion(), 0119 m_routingModel( widget->model()->routingManager()->routingModel() ) 0120 { 0121 m_latLonBoxWidget->setEnabled( false ); 0122 m_latLonBoxWidget->setLatLonBox( m_visibleRegion ); 0123 m_tileLevelRangeWidget->setDefaultLevel( m_visibleTileLevel ); 0124 m_downloadRegion.setMarbleModel( widget->model() ); 0125 } 0126 0127 0128 0129 QWidget * DownloadRegionDialog::Private::createSelectionMethodBox() 0130 { 0131 m_buttonGroup = new QButtonGroup(m_dialog); 0132 m_buttonGroup->setExclusive(true); 0133 m_visibleRegionMethodButton = new QRadioButton( tr( "Visible region" ) ); 0134 m_buttonGroup->addButton(m_visibleRegionMethodButton); 0135 m_specifiedRegionMethodButton = new QRadioButton( tr( "Specify region" ) ); 0136 m_buttonGroup->addButton(m_specifiedRegionMethodButton); 0137 m_routeDownloadMethodButton = new QRadioButton( tr( "Download Route" ) ); 0138 m_buttonGroup->addButton(m_routeDownloadMethodButton); 0139 m_routeDownloadMethodButton->setToolTip( tr( "Enabled when a route exists" ) ); 0140 m_routeDownloadMethodButton->setEnabled( hasRoute() ); 0141 m_routeDownloadMethodButton->setChecked( hasRoute() ); 0142 m_routeOffsetSpinBox = new QDoubleSpinBox(); 0143 m_routeOffsetSpinBox->setEnabled( hasRoute() ); 0144 m_routeOffsetSpinBox->setRange( minimumRouteOffset, maximumRouteOffset ); 0145 int defaultOffset = 500; 0146 m_routeOffsetSpinBox->setValue( defaultOffset ); 0147 m_routeOffsetSpinBox->setSingleStep( 100 ); 0148 m_routeOffsetSpinBox->setSuffix( " m" ); 0149 m_routeOffsetSpinBox->setDecimals( 0 ); 0150 m_routeOffsetSpinBox->setAlignment( Qt::AlignRight ); 0151 0152 m_routeOffsetLabel = new QLabel( tr( "Offset from route:" ) ); 0153 m_routeOffsetLabel->setAlignment( Qt::AlignHCenter ); 0154 0155 connect( m_buttonGroup, SIGNAL(buttonToggled(QAbstractButton*,bool)), 0156 m_dialog, SLOT(toggleSelectionMethod()) ); 0157 connect( m_routingModel, SIGNAL(modelReset()), m_dialog, SLOT(updateRouteDialog()) ); 0158 connect( m_routingModel, SIGNAL(rowsInserted(QModelIndex,int,int)), 0159 m_dialog, SLOT(updateRouteDialog()) ); 0160 connect( m_routingModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), 0161 m_dialog, SLOT(updateRouteDialog()) ); 0162 0163 QHBoxLayout *routeOffsetLayout = new QHBoxLayout; 0164 routeOffsetLayout->addWidget( m_routeOffsetLabel ); 0165 routeOffsetLayout->insertSpacing( 0, 25 ); 0166 routeOffsetLayout->addWidget( m_routeOffsetSpinBox ); 0167 0168 QVBoxLayout * const routeLayout = new QVBoxLayout; 0169 routeLayout->addWidget( m_routeDownloadMethodButton ); 0170 routeLayout->addLayout( routeOffsetLayout ); 0171 0172 QVBoxLayout * const layout = new QVBoxLayout; 0173 layout->addWidget( m_visibleRegionMethodButton ); 0174 layout->addLayout( routeLayout ); 0175 layout->addWidget( m_specifiedRegionMethodButton ); 0176 layout->addWidget( m_latLonBoxWidget ); 0177 0178 bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen; 0179 m_specifiedRegionMethodButton->setVisible( !smallScreen ); 0180 m_latLonBoxWidget->setVisible( !smallScreen ); 0181 0182 if ( smallScreen ) { 0183 QWidget * const selectionMethodWidget = new QWidget; 0184 selectionMethodWidget->setLayout( layout ); 0185 return selectionMethodWidget; 0186 } else { 0187 QGroupBox * const selectionMethodBox = new QGroupBox( tr( "Selection Method" ) ); 0188 selectionMethodBox->setLayout( layout ); 0189 return selectionMethodBox; 0190 } 0191 } 0192 0193 QLayout * DownloadRegionDialog::Private::createTilesCounter() 0194 { 0195 QLabel * const description = new QLabel( tr( "Number of tiles to download:" ) ); 0196 m_tilesCountLabel = new QLabel; 0197 m_tileSizeInfo = new QLabel; 0198 0199 QHBoxLayout * const tilesCountLayout = new QHBoxLayout; 0200 tilesCountLayout->addWidget( description ); 0201 tilesCountLayout->addWidget( m_tilesCountLabel ); 0202 //tilesCountLayout->insertSpacing( 0, 5 ); 0203 QVBoxLayout * const layout = new QVBoxLayout; 0204 layout->addLayout( tilesCountLayout ); 0205 layout->addWidget( m_tileSizeInfo ); 0206 return layout; 0207 } 0208 0209 QWidget * DownloadRegionDialog::Private::createOkCancelButtonBox() 0210 { 0211 QDialogButtonBox * const buttonBox = new QDialogButtonBox; 0212 m_okButton = buttonBox->addButton( QDialogButtonBox::Ok ); 0213 m_applyButton = buttonBox->addButton( QDialogButtonBox::Apply ); 0214 if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) { 0215 buttonBox->removeButton( m_applyButton ); 0216 m_applyButton->setVisible( false ); 0217 } 0218 buttonBox->addButton( QDialogButtonBox::Cancel ); 0219 connect( buttonBox, SIGNAL(accepted()), m_dialog, SLOT(accept()) ); 0220 connect( buttonBox, SIGNAL(rejected()), m_dialog, SLOT(reject()) ); 0221 connect( m_applyButton, SIGNAL(clicked()), m_dialog, SIGNAL(applied()) ); 0222 return buttonBox; 0223 } 0224 0225 bool DownloadRegionDialog::Private::hasRoute() const 0226 { 0227 return !m_routingModel->route().path().isEmpty(); 0228 } 0229 0230 bool DownloadRegionDialog::Private::hasTextureLayers() const 0231 { 0232 return m_model->mapTheme()->map()->hasTextureLayers(); 0233 } 0234 0235 bool DownloadRegionDialog::Private::hasVectorLayers() const 0236 { 0237 return m_model->mapTheme()->map()->hasVectorLayers(); 0238 } 0239 0240 DownloadRegionDialog::DownloadRegionDialog( MarbleWidget *const widget, QWidget * const parent, 0241 Qt::WindowFlags const f ) 0242 : QDialog( parent, f ), 0243 d( new Private( widget, this )) 0244 { 0245 setWindowTitle( tr( "Download Region" )); 0246 QVBoxLayout * const layout = new QVBoxLayout; 0247 d->m_layerLabel = new QLabel( tr( "Tile type to be downloaded:" )); 0248 d->m_layerComboBox = new QComboBox(); 0249 d->m_layerComboBox->addItem(tr("Texture tiles")); 0250 d->m_layerComboBox->addItem(tr("Vector tiles")); 0251 d->m_layerComboBox->setToolTip(tr("Allows selection between layer types that are visibly being rendered.")); 0252 updateTileLayer(); 0253 0254 layout->addWidget( d->m_layerLabel ); 0255 layout->addWidget( d->m_layerComboBox ); 0256 layout->addWidget( d->createSelectionMethodBox() ); 0257 layout->addWidget( d->m_tileLevelRangeWidget ); 0258 layout->addStretch(); 0259 layout->addLayout( d->createTilesCounter() ); 0260 0261 if ( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) { 0262 QWidget* widget = new QWidget( this ); 0263 widget->setLayout( layout ); 0264 QScrollArea* scrollArea = new QScrollArea( this ); 0265 scrollArea->setFrameShape( QFrame::NoFrame ); 0266 scrollArea->setWidget( widget ); 0267 QVBoxLayout * const mainLayout = new QVBoxLayout; 0268 mainLayout->addWidget( scrollArea ); 0269 mainLayout->addWidget( d->createOkCancelButtonBox() ); 0270 setLayout( mainLayout ); 0271 } else { 0272 layout->addWidget( d->createOkCancelButtonBox() ); 0273 setLayout( layout ); 0274 } 0275 0276 connect( d->m_layerComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), 0277 this, &DownloadRegionDialog::updateTileCount ); 0278 connect( d->m_latLonBoxWidget, &Marble::LatLonBoxWidget::valueChanged, 0279 this, &DownloadRegionDialog::updateTileCount ); 0280 connect( d->m_tileLevelRangeWidget, &TileLevelRangeWidget::topLevelChanged, 0281 this, &DownloadRegionDialog::updateTileCount ); 0282 connect( d->m_tileLevelRangeWidget, &TileLevelRangeWidget::bottomLevelChanged, 0283 this, &DownloadRegionDialog::updateTileCount ); 0284 connect( d->m_routeOffsetSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0285 this, &DownloadRegionDialog::updateTileCount ); 0286 connect( d->m_routeOffsetSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), 0287 this, &DownloadRegionDialog::setOffsetUnit ); 0288 connect( d->m_model, &MarbleModel::themeChanged, 0289 this, &DownloadRegionDialog::delayUpdateTileLayer); 0290 } 0291 0292 DownloadRegionDialog::~DownloadRegionDialog() 0293 { 0294 delete d; 0295 } 0296 0297 void DownloadRegionDialog::setAllowedTileLevelRange( int const minimumTileLevel, 0298 int const maximumTileLevel ) 0299 { 0300 d->m_tileLevelRangeWidget->setAllowedLevelRange( minimumTileLevel, maximumTileLevel ); 0301 } 0302 0303 void DownloadRegionDialog::setVisibleTileLevel( int const tileLevel ) 0304 { 0305 d->m_visibleTileLevel = tileLevel; 0306 d->m_tileLevelRangeWidget->setDefaultLevel( tileLevel ); 0307 d->m_downloadRegion.setVisibleTileLevel( tileLevel ); 0308 } 0309 0310 void DownloadRegionDialog::setSelectionMethod( SelectionMethod const selectionMethod ) 0311 { 0312 d->m_selectionMethod = selectionMethod; 0313 switch ( selectionMethod ) { 0314 case VisibleRegionMethod: 0315 d->m_visibleRegionMethodButton->setChecked( true ); 0316 d->m_routeOffsetLabel->setEnabled( false ); 0317 d->m_routeOffsetSpinBox->setEnabled( false ); 0318 d->m_latLonBoxWidget->setEnabled( false ); 0319 setSpecifiedLatLonAltBox( d->m_visibleRegion ); 0320 break; 0321 case SpecifiedRegionMethod: 0322 d->m_specifiedRegionMethodButton->setChecked( true ); 0323 d->m_routeOffsetLabel->setEnabled( false ); 0324 d->m_routeOffsetSpinBox->setEnabled( false ); 0325 d->m_latLonBoxWidget->setEnabled( true ); 0326 break; 0327 case RouteDownloadMethod: 0328 d->m_routeDownloadMethodButton->setChecked( true ); 0329 d->m_routeOffsetLabel->setEnabled( true ); 0330 d->m_routeOffsetSpinBox->setEnabled( true ); 0331 d->m_latLonBoxWidget->setEnabled( false ); 0332 } 0333 0334 updateTileCount(); 0335 } 0336 0337 QVector<TileCoordsPyramid> DownloadRegionDialog::region() const 0338 { 0339 if ( !d->hasTextureLayers() && !d->hasVectorLayers() ) { 0340 return QVector<TileCoordsPyramid>(); 0341 } 0342 0343 d->m_visibleTileLevel = (tileType() == TextureTileType && d->m_textureLayer->tileZoomLevel() != -1) 0344 ? d->m_textureLayer->tileZoomLevel() : d->m_vectorTileLayer->tileZoomLevel(); 0345 0346 const TileLayer * tileLayer = (tileType() == TextureTileType && d->m_textureLayer->layerCount() > 0) 0347 ? dynamic_cast<const TileLayer *>(d->m_textureLayer) 0348 : dynamic_cast<const TileLayer *>(d->m_vectorTileLayer); 0349 0350 d->m_downloadRegion.setTileLevelRange( d->m_tileLevelRangeWidget->topLevel(), 0351 d->m_tileLevelRangeWidget->bottomLevel() ); 0352 d->m_downloadRegion.setVisibleTileLevel( d->m_visibleTileLevel ); 0353 0354 // check whether "visible region" or "lat/lon region" is selection method 0355 GeoDataLatLonAltBox downloadRegion; 0356 switch ( d->m_selectionMethod ) { 0357 case VisibleRegionMethod: 0358 downloadRegion = d->m_visibleRegion; 0359 break; 0360 case SpecifiedRegionMethod: 0361 downloadRegion = GeoDataLatLonAltBox( d->m_latLonBoxWidget->latLonBox(), 0, 0 ); 0362 break; 0363 case RouteDownloadMethod: 0364 qreal offset = d->m_routeOffsetSpinBox->value(); 0365 if (d->m_routeOffsetSpinBox->suffix() == QLatin1String(" km")) { 0366 offset *= KM2METER; 0367 } 0368 const GeoDataLineString waypoints = d->m_model->routingManager()->routingModel()->route().path(); 0369 return d->m_downloadRegion.fromPath( tileLayer, offset, waypoints ); 0370 } 0371 0372 // For Mercator tiles limit the LatLonBox to the valid tile range. 0373 if (tileLayer->tileProjection()->type() == GeoSceneAbstractTileProjection::Mercator) { 0374 downloadRegion.setNorth(qMin(downloadRegion.north(), +1.4835)); 0375 downloadRegion.setSouth(qMax(downloadRegion.south(), -1.4835)); 0376 } 0377 0378 return d->m_downloadRegion.region( tileLayer, downloadRegion ); 0379 } 0380 0381 TileType DownloadRegionDialog::tileType() const 0382 { 0383 return d->m_layerComboBox->currentIndex() == 0 ? TextureTileType : VectorTileType; 0384 } 0385 0386 void DownloadRegionDialog::setSpecifiedLatLonAltBox( GeoDataLatLonAltBox const & region ) 0387 { 0388 d->m_latLonBoxWidget->setLatLonBox( region ); 0389 } 0390 0391 void DownloadRegionDialog::setVisibleLatLonAltBox( GeoDataLatLonAltBox const & region ) 0392 { 0393 d->m_visibleRegion = region; 0394 0395 // update lat/lon widget only if not active to prevent that users unintentionally loose 0396 // entered values 0397 if ( d->m_selectionMethod == VisibleRegionMethod ) { 0398 setSpecifiedLatLonAltBox( region ); 0399 } 0400 updateTileCount(); 0401 } 0402 0403 void DownloadRegionDialog::updateTileLayer() 0404 { 0405 updateTileType(); 0406 updateTileCount(); 0407 } 0408 0409 void DownloadRegionDialog::delayUpdateTileLayer() 0410 { 0411 QTimer::singleShot(500, this, &DownloadRegionDialog::updateTileLayer); 0412 } 0413 0414 void DownloadRegionDialog::hideEvent( QHideEvent * event ) 0415 { 0416 disconnect( d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)), 0417 this, SLOT(setVisibleLatLonAltBox(GeoDataLatLonAltBox)) ); 0418 disconnect( d->m_widget, SIGNAL(themeChanged(QString)), 0419 this, SLOT(delayUpdateTileLayer()) ); 0420 disconnect( d->m_widget, SIGNAL(propertyValueChanged(QString,bool)), 0421 this, SLOT(delayUpdateTileLayer()) ); 0422 0423 emit hidden(); 0424 event->accept(); 0425 } 0426 0427 void DownloadRegionDialog::showEvent( QShowEvent * event ) 0428 { 0429 connect( d->m_widget, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)), 0430 this, SLOT(setVisibleLatLonAltBox(GeoDataLatLonAltBox)) ); 0431 connect( d->m_widget, SIGNAL(themeChanged(QString)), 0432 this, SLOT(delayUpdateTileLayer()) ); 0433 connect( d->m_widget, SIGNAL(propertyValueChanged(QString,bool)), 0434 this, SLOT(delayUpdateTileLayer()) ); 0435 0436 setVisibleTileLevel(d->m_widget->tileZoomLevel()); 0437 0438 updateTileCount(); 0439 0440 emit shown(); 0441 event->accept(); 0442 } 0443 0444 void DownloadRegionDialog::toggleSelectionMethod() 0445 { 0446 if( d->m_specifiedRegionMethodButton->isChecked() ) { 0447 setSelectionMethod( SpecifiedRegionMethod ); 0448 } 0449 else if( d->m_routeDownloadMethodButton->isChecked() ) { 0450 setSelectionMethod( RouteDownloadMethod ); 0451 } 0452 else if( d->m_specifiedRegionMethodButton->isChecked() ) { 0453 setSelectionMethod( SpecifiedRegionMethod ); 0454 } 0455 } 0456 0457 void DownloadRegionDialog::updateTileType() 0458 { 0459 bool hasVisibleTextureLayers = d->hasTextureLayers() && d->m_textureLayer->layerCount() > 0; 0460 bool hasVisibleVectorLayers = d->hasVectorLayers() && d->m_vectorTileLayer->layerCount() > 0; 0461 0462 QStandardItemModel *model = qobject_cast<QStandardItemModel *>(d->m_layerComboBox->model()); 0463 Q_ASSERT(model != nullptr); 0464 QStandardItem *item = nullptr; 0465 item = model->item(0); 0466 item->setFlags(hasVisibleTextureLayers ? item->flags() | Qt::ItemIsEnabled 0467 : item->flags() & ~Qt::ItemIsEnabled); 0468 item = model->item(1); 0469 item->setFlags(hasVisibleVectorLayers ? item->flags() | Qt::ItemIsEnabled 0470 : item->flags() & ~Qt::ItemIsEnabled); 0471 0472 bool allTileTypesAvailable = hasVisibleTextureLayers && hasVisibleVectorLayers; 0473 0474 d->m_layerComboBox->setEnabled(allTileTypesAvailable); 0475 if (hasVisibleVectorLayers) { 0476 d->m_layerComboBox->setCurrentIndex(1); 0477 } 0478 else if (hasVisibleTextureLayers && !hasVisibleVectorLayers) { 0479 d->m_layerComboBox->setCurrentIndex(0); 0480 } 0481 } 0482 0483 void DownloadRegionDialog::updateTileCount() 0484 { 0485 if ( !isVisible() ) { 0486 return; 0487 } 0488 0489 qint64 tilesCount = 0; 0490 QString themeId( d->m_model->mapThemeId() ); 0491 QVector<TileCoordsPyramid> const pyramid = region(); 0492 Q_ASSERT( !pyramid.isEmpty() ); 0493 if( pyramid.size() == 1 ) { 0494 tilesCount = pyramid[0].tilesCount(); 0495 } 0496 else { 0497 for( int level = pyramid[0].bottomLevel(); level>= pyramid[0].topLevel(); --level ) { 0498 QSet<TileId> tileIdSet; 0499 for( int i = 0; i < pyramid.size(); ++i ) { 0500 QRect const coords = pyramid[i].coords( level ); 0501 int x1, y1, x2, y2; 0502 coords.getCoords( &x1, &y1, &x2, &y2 ); 0503 for ( int x = x1; x <= x2; ++x ) { 0504 for ( int y = y1; y <= y2; ++y ) { 0505 TileId const tileId( 0, level, x, y ); 0506 tileIdSet.insert( tileId ); 0507 } 0508 } 0509 } 0510 tilesCount += tileIdSet.count(); 0511 } 0512 } 0513 0514 qreal tileDownloadSize = 0; 0515 0516 if ( tilesCount > maxTilesCount ) { 0517 d->m_tileSizeInfo->setToolTip( QString() ); 0518 //~ singular There is a limit of %n tile to download. 0519 //~ plural There is a limit of %n tiles to download. 0520 d->m_tileSizeInfo->setText( tr( "There is a limit of %n tile(s) to download.", "", 0521 maxTilesCount ) ); 0522 } else { 0523 if (themeId == QLatin1String("earth/openstreetmap/openstreetmap.dgml") || 0524 themeId == QLatin1String("earth/openstreetmap/openseamap.dgml") || 0525 themeId == QLatin1String("earth/vectorosm/vectorosm.dgml") ) { 0526 0527 tileDownloadSize = tileType() == TextureTileType 0528 ? tilesCount * averageTextureTileSize 0529 : tilesCount * averageVectorTileSize; 0530 0531 d->m_tileSizeInfo->setToolTip( tr( "Approximate size of the tiles to be downloaded" ) ); 0532 0533 if( tileDownloadSize > 1024 ) { 0534 tileDownloadSize = tileDownloadSize / 1024; 0535 d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 MB" ).arg( ceil( tileDownloadSize ) ) ); 0536 } 0537 else { 0538 d->m_tileSizeInfo->setText( tr( "Estimated download size: %1 kB" ).arg( tileDownloadSize ) ); 0539 } 0540 } 0541 else { 0542 d->m_tileSizeInfo->setToolTip( QString() ); 0543 d->m_tileSizeInfo->clear(); 0544 } 0545 } 0546 0547 d->m_tilesCountLabel->setText( QString::number( tilesCount ) ); 0548 bool const tilesCountWithinLimits = tilesCount > 0 && tilesCount <= maxTilesCount; 0549 d->m_okButton->setEnabled( tilesCountWithinLimits ); 0550 d->m_applyButton->setEnabled( tilesCountWithinLimits ); 0551 } 0552 0553 void DownloadRegionDialog::updateRouteDialog() 0554 { 0555 d->m_routeDownloadMethodButton->setEnabled( d->hasRoute() ); 0556 d->m_routeDownloadMethodButton->setChecked( d->hasRoute() ); 0557 if( !d->hasRoute() ) { 0558 setSelectionMethod( VisibleRegionMethod ); 0559 } 0560 } 0561 0562 void DownloadRegionDialog::setOffsetUnit() 0563 { 0564 qreal offset = d->m_routeOffsetSpinBox->value(); 0565 0566 if( offset >= 1100 ) { 0567 d->m_routeOffsetSpinBox->setSuffix( " km" ); 0568 d->m_routeOffsetSpinBox->setRange( minimumRouteOffset * METER2KM, maximumRouteOffset * METER2KM ); 0569 d->m_routeOffsetSpinBox->setDecimals( 1 ); 0570 d->m_routeOffsetSpinBox->setValue( offset * METER2KM ); 0571 d->m_routeOffsetSpinBox->setSingleStep( 0.1 ); 0572 } 0573 else if (offset <= 1 && d->m_routeOffsetSpinBox->suffix() == QLatin1String(" km")) { 0574 d->m_routeOffsetSpinBox->setSuffix( " m" ); 0575 d->m_routeOffsetSpinBox->setRange( minimumRouteOffset, maximumRouteOffset ); 0576 d->m_routeOffsetSpinBox->setDecimals( 0 ); 0577 d->m_routeOffsetSpinBox->setValue( offset * KM2METER ); 0578 d->m_routeOffsetSpinBox->setSingleStep( 100 ); 0579 } 0580 } 0581 0582 } 0583 0584 #include "moc_DownloadRegionDialog.cpp"