File indexing completed on 2024-04-28 07:37:59
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2006-2009 Torsten Rahn <tackat@kde.org> 0004 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org> 0005 // SPDX-FileCopyrightText: 2008 Carlos Licea <carlos.licea@kdemail.net> 0006 // SPDX-FileCopyrightText: 2009 Jens-Michael Hoffmann <jensmh@gmx.de> 0007 // SPDX-FileCopyrightText: 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de> 0008 // 0009 0010 0011 // Own 0012 #include "MarbleMap.h" 0013 0014 // Posix 0015 #include <cmath> 0016 0017 // Qt 0018 #include <QElapsedTimer> 0019 #include <QtMath> 0020 0021 // Marble 0022 #include "layers/FloatItemsLayer.h" 0023 #include "layers/FogLayer.h" 0024 #include "layers/FpsLayer.h" 0025 #include "layers/GeometryLayer.h" 0026 #include "layers/GroundLayer.h" 0027 #include "layers/MarbleSplashLayer.h" 0028 #include "layers/PlacemarkLayer.h" 0029 #include "layers/TextureLayer.h" 0030 #include "layers/VectorTileLayer.h" 0031 #include "AbstractFloatItem.h" 0032 #include "DgmlAuxillaryDictionary.h" 0033 #include "FileManager.h" 0034 #include "GeoDataTreeModel.h" 0035 #include "GeoPainter.h" 0036 #include "GeoSceneDocument.h" 0037 #include "GeoSceneFilter.h" 0038 #include "GeoSceneGeodata.h" 0039 #include "GeoSceneHead.h" 0040 #include "GeoSceneLayer.h" 0041 #include "GeoSceneMap.h" 0042 #include "GeoScenePalette.h" 0043 #include "GeoSceneSettings.h" 0044 #include "GeoSceneVector.h" 0045 #include "GeoSceneVectorTileDataset.h" 0046 #include "GeoSceneTextureTileDataset.h" 0047 #include "GeoSceneZoom.h" 0048 #include "GeoDataDocument.h" 0049 #include "GeoDataFeature.h" 0050 #include "GeoDataStyle.h" 0051 #include "GeoDataStyleMap.h" 0052 #include "LayerManager.h" 0053 #include "MapThemeManager.h" 0054 #include "MarbleDebug.h" 0055 #include "MarbleDirs.h" 0056 #include "MarbleModel.h" 0057 #include "PluginManager.h" 0058 #include "RenderPlugin.h" 0059 #include "StyleBuilder.h" 0060 #include "SunLocator.h" 0061 #include "TileId.h" 0062 #include "TileCoordsPyramid.h" 0063 #include "TileCreator.h" 0064 #include "TileCreatorDialog.h" 0065 #include "TileLoader.h" 0066 #include "ViewParams.h" 0067 #include "ViewportParams.h" 0068 #include "RenderState.h" 0069 #include "BookmarkManager.h" 0070 0071 0072 namespace Marble 0073 { 0074 0075 0076 class MarbleMap::CustomPaintLayer : public LayerInterface 0077 { 0078 public: 0079 explicit CustomPaintLayer( MarbleMap *map ) 0080 : m_map( map ) 0081 { 0082 } 0083 0084 QStringList renderPosition() const override { return QStringList() << "USER_TOOLS"; } 0085 0086 bool render( GeoPainter *painter, ViewportParams *viewport, 0087 const QString &renderPos, GeoSceneLayer *layer ) override 0088 { 0089 Q_UNUSED( viewport ); 0090 Q_UNUSED( renderPos ); 0091 Q_UNUSED( layer ); 0092 0093 m_map->customPaint( painter ); 0094 0095 return true; 0096 } 0097 0098 qreal zValue() const override { return 1.0e6; } 0099 0100 RenderState renderState() const override { return RenderState(QStringLiteral("Custom Map Paint")); } 0101 0102 QString runtimeTrace() const override { return QStringLiteral("CustomPaint"); } 0103 0104 private: 0105 MarbleMap *const m_map; 0106 }; 0107 0108 0109 class MarbleMapPrivate 0110 { 0111 friend class MarbleWidget; 0112 0113 public: 0114 explicit MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ); 0115 0116 void updateMapTheme(); 0117 0118 void updateProperty( const QString &, bool ); 0119 0120 void setDocument( const QString& key ); 0121 0122 void updateTileLevel(); 0123 0124 void addPlugins(); 0125 0126 MarbleMap *const q; 0127 0128 // The model we are showing. 0129 MarbleModel *const m_model; 0130 bool m_modelIsOwned; 0131 0132 // Parameters for the maps appearance. 0133 ViewParams m_viewParams; 0134 ViewportParams m_viewport; 0135 bool m_showFrameRate; 0136 bool m_showDebugPolygons; 0137 bool m_showDebugBatchRender; 0138 GeoDataRelation::RelationTypes m_visibleRelationTypes; 0139 StyleBuilder m_styleBuilder; 0140 0141 QList<RenderPlugin *> m_renderPlugins; 0142 0143 LayerManager m_layerManager; 0144 MarbleSplashLayer m_marbleSplashLayer; 0145 MarbleMap::CustomPaintLayer m_customPaintLayer; 0146 GeometryLayer m_geometryLayer; 0147 FloatItemsLayer m_floatItemsLayer; 0148 FogLayer m_fogLayer; 0149 GroundLayer m_groundLayer; 0150 TextureLayer m_textureLayer; 0151 PlacemarkLayer m_placemarkLayer; 0152 VectorTileLayer m_vectorTileLayer; 0153 0154 bool m_isLockedToSubSolarPoint; 0155 bool m_isSubSolarPointIconVisible; 0156 RenderState m_renderState; 0157 }; 0158 0159 MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) : 0160 q( parent ), 0161 m_model( model ), 0162 m_viewParams(), 0163 m_showFrameRate( false ), 0164 m_showDebugPolygons( false ), 0165 m_showDebugBatchRender( false ), 0166 m_visibleRelationTypes(GeoDataRelation::RouteFerry), 0167 m_styleBuilder(), 0168 m_layerManager( parent ), 0169 m_customPaintLayer( parent ), 0170 m_geometryLayer(model->treeModel(), &m_styleBuilder), 0171 m_floatItemsLayer(parent), 0172 m_textureLayer( model->downloadManager(), model->pluginManager(), model->sunLocator(), model->groundOverlayModel() ), 0173 m_placemarkLayer( model->placemarkModel(), model->placemarkSelectionModel(), model->clock(), &m_styleBuilder ), 0174 m_vectorTileLayer( model->downloadManager(), model->pluginManager(), model->treeModel() ), 0175 m_isLockedToSubSolarPoint( false ), 0176 m_isSubSolarPointIconVisible( false ) 0177 { 0178 m_layerManager.addLayer(&m_floatItemsLayer); 0179 m_layerManager.addLayer( &m_fogLayer ); 0180 m_layerManager.addLayer( &m_groundLayer ); 0181 m_layerManager.addLayer( &m_geometryLayer ); 0182 m_layerManager.addLayer( &m_placemarkLayer ); 0183 m_layerManager.addLayer( &m_customPaintLayer ); 0184 0185 m_model->bookmarkManager()->setStyleBuilder(&m_styleBuilder); 0186 0187 QObject::connect( m_model, SIGNAL(themeChanged(QString)), 0188 parent, SLOT(updateMapTheme()) ); 0189 QObject::connect( m_model->fileManager(), SIGNAL(fileAdded(QString)), 0190 parent, SLOT(setDocument(QString)) ); 0191 0192 0193 QObject::connect( &m_placemarkLayer, SIGNAL(repaintNeeded()), 0194 parent, SIGNAL(repaintNeeded())); 0195 0196 QObject::connect ( &m_layerManager, SIGNAL(pluginSettingsChanged()), 0197 parent, SIGNAL(pluginSettingsChanged()) ); 0198 QObject::connect ( &m_layerManager, SIGNAL(repaintNeeded(QRegion)), 0199 parent, SIGNAL(repaintNeeded(QRegion)) ); 0200 QObject::connect ( &m_layerManager, SIGNAL(renderPluginInitialized(RenderPlugin*)), 0201 parent, SIGNAL(renderPluginInitialized(RenderPlugin*)) ); 0202 QObject::connect ( &m_layerManager, SIGNAL(visibilityChanged(QString,bool)), 0203 parent, SLOT(setPropertyValue(QString,bool)) ); 0204 0205 QObject::connect( &m_geometryLayer, SIGNAL(repaintNeeded()), 0206 parent, SIGNAL(repaintNeeded())); 0207 0208 /* 0209 * Slot handleHighlight finds all placemarks 0210 * that contain the clicked point. 0211 * The placemarks under the clicked position may 0212 * have their styleUrl set to a style map which 0213 * doesn't specify any highlight styleId. Such 0214 * placemarks will be fletered out in GeoGraphicsScene 0215 * and will not be highlighted. 0216 */ 0217 QObject::connect( parent, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)), 0218 &m_geometryLayer, SLOT(handleHighlight(qreal,qreal,GeoDataCoordinates::Unit)) ); 0219 0220 QObject::connect(&m_floatItemsLayer, SIGNAL(repaintNeeded(QRegion)), 0221 parent, SIGNAL(repaintNeeded(QRegion))); 0222 QObject::connect(&m_floatItemsLayer, SIGNAL(renderPluginInitialized(RenderPlugin*)), 0223 parent, SIGNAL(renderPluginInitialized(RenderPlugin*))); 0224 QObject::connect(&m_floatItemsLayer, SIGNAL(visibilityChanged(QString,bool)), 0225 parent, SLOT(setPropertyValue(QString,bool))); 0226 QObject::connect(&m_floatItemsLayer, SIGNAL(pluginSettingsChanged()), 0227 parent, SIGNAL(pluginSettingsChanged())); 0228 0229 QObject::connect( &m_textureLayer, SIGNAL(tileLevelChanged(int)), 0230 parent, SLOT(updateTileLevel()) ); 0231 QObject::connect( &m_vectorTileLayer, SIGNAL(tileLevelChanged(int)), 0232 parent, SLOT(updateTileLevel()) ); 0233 QObject::connect( parent, SIGNAL(radiusChanged(int)), 0234 parent, SLOT(updateTileLevel()) ); 0235 0236 QObject::connect( &m_textureLayer, SIGNAL(repaintNeeded()), 0237 parent, SIGNAL(repaintNeeded()) ); 0238 QObject::connect( parent, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)), 0239 parent, SIGNAL(repaintNeeded()) ); 0240 0241 addPlugins(); 0242 QObject::connect(model->pluginManager(), SIGNAL(renderPluginsChanged()), 0243 parent, SLOT(addPlugins())); 0244 } 0245 0246 void MarbleMapPrivate::updateProperty( const QString &name, bool show ) 0247 { 0248 // earth 0249 if (name == QLatin1String("places")) { 0250 m_placemarkLayer.setShowPlaces( show ); 0251 } else if (name == QLatin1String("cities")) { 0252 m_placemarkLayer.setShowCities( show ); 0253 } else if (name == QLatin1String("terrain")) { 0254 m_placemarkLayer.setShowTerrain( show ); 0255 } else if (name == QLatin1String("otherplaces")) { 0256 m_placemarkLayer.setShowOtherPlaces( show ); 0257 } 0258 0259 // other planets 0260 else if (name == QLatin1String("landingsites")) { 0261 m_placemarkLayer.setShowLandingSites( show ); 0262 } else if (name == QLatin1String("craters")) { 0263 m_placemarkLayer.setShowCraters( show ); 0264 } else if (name == QLatin1String("maria")) { 0265 m_placemarkLayer.setShowMaria( show ); 0266 } 0267 0268 else if (name == QLatin1String("relief")) { 0269 m_textureLayer.setShowRelief( show ); 0270 } 0271 0272 for(RenderPlugin *renderPlugin: m_renderPlugins) { 0273 if ( name == renderPlugin->nameId() ) { 0274 if ( renderPlugin->visible() == show ) { 0275 break; 0276 } 0277 0278 renderPlugin->setVisible( show ); 0279 0280 break; 0281 } 0282 } 0283 } 0284 0285 void MarbleMapPrivate::addPlugins() 0286 { 0287 for (const RenderPlugin *factory: m_model->pluginManager()->renderPlugins()) { 0288 bool alreadyCreated = false; 0289 for(const RenderPlugin *existing: m_renderPlugins) { 0290 if (existing->nameId() == factory->nameId()) { 0291 alreadyCreated = true; 0292 break; 0293 } 0294 } 0295 0296 if (alreadyCreated) { 0297 continue; 0298 } 0299 0300 RenderPlugin *const renderPlugin = factory->newInstance(m_model); 0301 Q_ASSERT(renderPlugin && "Plugin must not return null when requesting a new instance."); 0302 m_renderPlugins << renderPlugin; 0303 0304 if (AbstractFloatItem *const floatItem = qobject_cast<AbstractFloatItem *>(renderPlugin)) { 0305 m_floatItemsLayer.addFloatItem(floatItem); 0306 } 0307 else { 0308 m_layerManager.addRenderPlugin(renderPlugin); 0309 } 0310 } 0311 } 0312 0313 // ---------------------------------------------------------------- 0314 0315 0316 MarbleMap::MarbleMap() 0317 : d( new MarbleMapPrivate( this, new MarbleModel( this ) ) ) 0318 { 0319 // nothing to do 0320 } 0321 0322 MarbleMap::MarbleMap(MarbleModel *model) 0323 : d( new MarbleMapPrivate( this, model ) ) 0324 { 0325 d->m_modelIsOwned = false; 0326 } 0327 0328 MarbleMap::~MarbleMap() 0329 { 0330 MarbleModel *model = d->m_modelIsOwned ? d->m_model : nullptr; 0331 0332 d->m_layerManager.removeLayer( &d->m_customPaintLayer ); 0333 d->m_layerManager.removeLayer( &d->m_geometryLayer ); 0334 d->m_layerManager.removeLayer(&d->m_floatItemsLayer); 0335 d->m_layerManager.removeLayer( &d->m_fogLayer ); 0336 d->m_layerManager.removeLayer( &d->m_placemarkLayer ); 0337 d->m_layerManager.removeLayer( &d->m_textureLayer ); 0338 d->m_layerManager.removeLayer( &d->m_groundLayer ); 0339 qDeleteAll(d->m_renderPlugins); 0340 delete d; 0341 0342 delete model; // delete the model after private data 0343 } 0344 0345 MarbleModel *MarbleMap::model() const 0346 { 0347 return d->m_model; 0348 } 0349 0350 ViewportParams *MarbleMap::viewport() 0351 { 0352 return &d->m_viewport; 0353 } 0354 0355 const ViewportParams *MarbleMap::viewport() const 0356 { 0357 return &d->m_viewport; 0358 } 0359 0360 0361 void MarbleMap::setMapQualityForViewContext( MapQuality quality, ViewContext viewContext ) 0362 { 0363 d->m_viewParams.setMapQualityForViewContext( quality, viewContext ); 0364 0365 // Update texture map during the repaint that follows: 0366 d->m_textureLayer.setNeedsUpdate(); 0367 } 0368 0369 MapQuality MarbleMap::mapQuality( ViewContext viewContext ) const 0370 { 0371 return d->m_viewParams.mapQuality( viewContext ); 0372 } 0373 0374 MapQuality MarbleMap::mapQuality() const 0375 { 0376 return d->m_viewParams.mapQuality(); 0377 } 0378 0379 void MarbleMap::setViewContext( ViewContext viewContext ) 0380 { 0381 if ( d->m_viewParams.viewContext() == viewContext ) { 0382 return; 0383 } 0384 0385 const MapQuality oldQuality = d->m_viewParams.mapQuality(); 0386 d->m_viewParams.setViewContext( viewContext ); 0387 emit viewContextChanged( viewContext ); 0388 0389 if ( d->m_viewParams.mapQuality() != oldQuality ) { 0390 // Update texture map during the repaint that follows: 0391 d->m_textureLayer.setNeedsUpdate(); 0392 0393 emit repaintNeeded(); 0394 } 0395 } 0396 0397 ViewContext MarbleMap::viewContext() const 0398 { 0399 return d->m_viewParams.viewContext(); 0400 } 0401 0402 0403 void MarbleMap::setSize( int width, int height ) 0404 { 0405 setSize( QSize( width, height ) ); 0406 } 0407 0408 void MarbleMap::setSize( const QSize& size ) 0409 { 0410 d->m_viewport.setSize( size ); 0411 0412 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); 0413 } 0414 0415 QSize MarbleMap::size() const 0416 { 0417 return QSize( d->m_viewport.width(), d->m_viewport.height() ); 0418 } 0419 0420 int MarbleMap::width() const 0421 { 0422 return d->m_viewport.width(); 0423 } 0424 0425 int MarbleMap::height() const 0426 { 0427 return d->m_viewport.height(); 0428 } 0429 0430 int MarbleMap::radius() const 0431 { 0432 return d->m_viewport.radius(); 0433 } 0434 0435 void MarbleMap::setRadius( int radius ) 0436 { 0437 const int oldRadius = d->m_viewport.radius(); 0438 0439 d->m_viewport.setRadius( radius ); 0440 0441 if ( oldRadius != d->m_viewport.radius() ) { 0442 emit radiusChanged( radius ); 0443 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); 0444 } 0445 } 0446 0447 0448 int MarbleMap::preferredRadiusCeil(int radius) const 0449 { 0450 return d->m_textureLayer.preferredRadiusCeil( radius ); 0451 } 0452 0453 0454 int MarbleMap::preferredRadiusFloor(int radius) const 0455 { 0456 return d->m_textureLayer.preferredRadiusFloor( radius ); 0457 } 0458 0459 0460 int MarbleMap::tileZoomLevel() const 0461 { 0462 auto const tileZoomLevel = qMax(d->m_textureLayer.tileZoomLevel(), d->m_vectorTileLayer.tileZoomLevel()); 0463 return tileZoomLevel >= 0 ? tileZoomLevel : qMin<int>(qMax<int>(qLn(d->m_viewport.radius()*4/256)/qLn(2.0), 1), d->m_styleBuilder.maximumZoomLevel()); 0464 } 0465 0466 0467 qreal MarbleMap::centerLatitude() const 0468 { 0469 // Calculate translation of center point 0470 const qreal centerLat = d->m_viewport.centerLatitude(); 0471 0472 return centerLat * RAD2DEG; 0473 } 0474 0475 bool MarbleMap::hasFeatureAt(const QPoint &position) const 0476 { 0477 return d->m_placemarkLayer.hasPlacemarkAt(position) || d->m_geometryLayer.hasFeatureAt(position, viewport()); 0478 } 0479 0480 qreal MarbleMap::centerLongitude() const 0481 { 0482 // Calculate translation of center point 0483 const qreal centerLon = d->m_viewport.centerLongitude(); 0484 0485 return centerLon * RAD2DEG; 0486 } 0487 0488 int MarbleMap::minimumZoom() const 0489 { 0490 if ( d->m_model->mapTheme() ) 0491 return d->m_model->mapTheme()->head()->zoom()->minimum(); 0492 0493 return 950; 0494 } 0495 0496 int MarbleMap::maximumZoom() const 0497 { 0498 if ( d->m_model->mapTheme() ) 0499 return d->m_model->mapTheme()->head()->zoom()->maximum(); 0500 0501 return 2100; 0502 } 0503 0504 bool MarbleMap::discreteZoom() const 0505 { 0506 if ( d->m_model->mapTheme() ) 0507 return d->m_model->mapTheme()->head()->zoom()->discrete(); 0508 0509 return false; 0510 } 0511 0512 QVector<const GeoDataFeature*> MarbleMap::whichFeatureAt( const QPoint& curpos ) const 0513 { 0514 return d->m_placemarkLayer.whichPlacemarkAt( curpos ) + d->m_geometryLayer.whichFeatureAt( curpos, viewport() ); 0515 } 0516 0517 void MarbleMap::reload() 0518 { 0519 d->m_textureLayer.reload(); 0520 d->m_vectorTileLayer.reload(); 0521 } 0522 0523 void MarbleMap::downloadRegion( QVector<TileCoordsPyramid> const & pyramid ) 0524 { 0525 Q_ASSERT( textureLayer() ); 0526 Q_ASSERT( !pyramid.isEmpty() ); 0527 QElapsedTimer t; 0528 t.start(); 0529 0530 // When downloading a region (the author of these lines thinks) most users probably expect 0531 // the download to begin with the low resolution tiles and then procede level-wise to 0532 // higher resolution tiles. In order to achieve this, we start requesting downloads of 0533 // high resolution tiles and request the low resolution tiles at the end because 0534 // DownloadQueueSet (silly name) is implemented as stack. 0535 0536 0537 int const first = 0; 0538 int tilesCount = 0; 0539 0540 for ( int level = pyramid[first].bottomLevel(); level >= pyramid[first].topLevel(); --level ) { 0541 QSet<TileId> tileIdSet; 0542 for( int i = 0; i < pyramid.size(); ++i ) { 0543 QRect const coords = pyramid[i].coords( level ); 0544 mDebug() << "MarbleMap::downloadRegion level:" << level << "tile coords:" << coords; 0545 int x1, y1, x2, y2; 0546 coords.getCoords( &x1, &y1, &x2, &y2 ); 0547 for ( int x = x1; x <= x2; ++x ) { 0548 for ( int y = y1; y <= y2; ++y ) { 0549 TileId const stackedTileId( 0, level, x, y ); 0550 tileIdSet.insert( stackedTileId ); 0551 // FIXME: use lazy evaluation to not generate up to 100k tiles in one go 0552 // this can take considerable time even on very fast systems 0553 // in contrast generating the TileIds on the fly when they are needed 0554 // does not seem to affect download speed. 0555 } 0556 } 0557 } 0558 QSetIterator<TileId> i( tileIdSet ); 0559 while( i.hasNext() ) { 0560 TileId const tileId = i.next(); 0561 d->m_textureLayer.downloadStackedTile( tileId ); 0562 d->m_vectorTileLayer.downloadTile(tileId); 0563 mDebug() << "TileDownload" << tileId; 0564 } 0565 tilesCount += tileIdSet.count(); 0566 } 0567 // Needed for downloading unique tiles only. Much faster than if tiles for each level is downloaded separately 0568 0569 int const elapsedMs = t.elapsed(); 0570 mDebug() << "MarbleMap::downloadRegion:" << tilesCount << "tiles, " << elapsedMs << "ms"; 0571 } 0572 0573 void MarbleMap::highlightRouteRelation(qint64 osmId, bool enabled) 0574 { 0575 d->m_geometryLayer.highlightRouteRelation(osmId, enabled); 0576 } 0577 0578 bool MarbleMap::propertyValue( const QString& name ) const 0579 { 0580 bool value; 0581 if ( d->m_model->mapTheme() ) { 0582 d->m_model->mapTheme()->settings()->propertyValue( name, value ); 0583 } 0584 else { 0585 value = false; 0586 mDebug() << "WARNING: Failed to access a map theme! Property: " << name; 0587 } 0588 return value; 0589 } 0590 0591 bool MarbleMap::showOverviewMap() const 0592 { 0593 return propertyValue(QStringLiteral("overviewmap")); 0594 } 0595 0596 bool MarbleMap::showScaleBar() const 0597 { 0598 return propertyValue(QStringLiteral("scalebar")); 0599 } 0600 0601 bool MarbleMap::showCompass() const 0602 { 0603 return propertyValue(QStringLiteral("compass")); 0604 } 0605 0606 bool MarbleMap::showGrid() const 0607 { 0608 return propertyValue(QStringLiteral("coordinate-grid")); 0609 } 0610 0611 bool MarbleMap::showClouds() const 0612 { 0613 return d->m_viewParams.showClouds(); 0614 } 0615 0616 bool MarbleMap::showSunShading() const 0617 { 0618 return d->m_textureLayer.showSunShading(); 0619 } 0620 0621 bool MarbleMap::showCityLights() const 0622 { 0623 return d->m_textureLayer.showCityLights(); 0624 } 0625 0626 bool MarbleMap::isLockedToSubSolarPoint() const 0627 { 0628 return d->m_isLockedToSubSolarPoint; 0629 } 0630 0631 bool MarbleMap::isSubSolarPointIconVisible() const 0632 { 0633 return d->m_isSubSolarPointIconVisible; 0634 } 0635 0636 bool MarbleMap::showAtmosphere() const 0637 { 0638 return d->m_viewParams.showAtmosphere(); 0639 } 0640 0641 bool MarbleMap::showCrosshairs() const 0642 { 0643 bool visible = false; 0644 0645 QList<RenderPlugin *> pluginList = renderPlugins(); 0646 QList<RenderPlugin *>::const_iterator i = pluginList.constBegin(); 0647 QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd(); 0648 for (; i != end; ++i ) { 0649 if ((*i)->nameId() == QLatin1String("crosshairs")) { 0650 visible = (*i)->visible(); 0651 } 0652 } 0653 0654 return visible; 0655 } 0656 0657 bool MarbleMap::showPlaces() const 0658 { 0659 return propertyValue(QStringLiteral("places")); 0660 } 0661 0662 bool MarbleMap::showCities() const 0663 { 0664 return propertyValue(QStringLiteral("cities")); 0665 } 0666 0667 bool MarbleMap::showTerrain() const 0668 { 0669 return propertyValue(QStringLiteral("terrain")); 0670 } 0671 0672 bool MarbleMap::showOtherPlaces() const 0673 { 0674 return propertyValue(QStringLiteral("otherplaces")); 0675 } 0676 0677 bool MarbleMap::showRelief() const 0678 { 0679 return propertyValue(QStringLiteral("relief")); 0680 } 0681 0682 bool MarbleMap::showIceLayer() const 0683 { 0684 return propertyValue(QStringLiteral("ice")); 0685 } 0686 0687 bool MarbleMap::showBorders() const 0688 { 0689 return propertyValue(QStringLiteral("borders")); 0690 } 0691 0692 bool MarbleMap::showRivers() const 0693 { 0694 return propertyValue(QStringLiteral("rivers")); 0695 } 0696 0697 bool MarbleMap::showLakes() const 0698 { 0699 return propertyValue(QStringLiteral("lakes")); 0700 } 0701 0702 bool MarbleMap::showFrameRate() const 0703 { 0704 return d->m_showFrameRate; 0705 } 0706 0707 bool MarbleMap::showBackground() const 0708 { 0709 return d->m_layerManager.showBackground(); 0710 } 0711 0712 GeoDataRelation::RelationTypes MarbleMap::visibleRelationTypes() const 0713 { 0714 return d->m_visibleRelationTypes; 0715 } 0716 0717 quint64 MarbleMap::volatileTileCacheLimit() const 0718 { 0719 return d->m_textureLayer.volatileCacheLimit(); 0720 } 0721 0722 0723 void MarbleMap::rotateBy(qreal deltaLon, qreal deltaLat) 0724 { 0725 centerOn( d->m_viewport.centerLongitude() * RAD2DEG + deltaLon, 0726 d->m_viewport.centerLatitude() * RAD2DEG + deltaLat ); 0727 } 0728 0729 0730 void MarbleMap::centerOn( const qreal lon, const qreal lat ) 0731 { 0732 d->m_viewport.centerOn( lon * DEG2RAD, lat * DEG2RAD ); 0733 0734 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); 0735 } 0736 0737 void MarbleMap::setCenterLatitude( qreal lat ) 0738 { 0739 centerOn( centerLongitude(), lat ); 0740 } 0741 0742 void MarbleMap::setCenterLongitude( qreal lon ) 0743 { 0744 centerOn( lon, centerLatitude() ); 0745 } 0746 0747 Projection MarbleMap::projection() const 0748 { 0749 return d->m_viewport.projection(); 0750 } 0751 0752 void MarbleMap::setProjection( Projection projection ) 0753 { 0754 if ( d->m_viewport.projection() == projection ) 0755 return; 0756 0757 emit projectionChanged( projection ); 0758 0759 d->m_viewport.setProjection( projection ); 0760 0761 d->m_textureLayer.setProjection( projection ); 0762 0763 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); 0764 } 0765 0766 0767 bool MarbleMap::screenCoordinates( qreal lon, qreal lat, 0768 qreal& x, qreal& y ) const 0769 { 0770 return d->m_viewport.screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, x, y ); 0771 } 0772 0773 bool MarbleMap::geoCoordinates( int x, int y, 0774 qreal& lon, qreal& lat, 0775 GeoDataCoordinates::Unit unit ) const 0776 { 0777 return d->m_viewport.geoCoordinates( x, y, lon, lat, unit ); 0778 } 0779 0780 void MarbleMapPrivate::setDocument( const QString& key ) 0781 { 0782 if ( !m_model->mapTheme() ) { 0783 // Happens if no valid map theme is set or at application startup 0784 // if a file is passed via command line parameters and the last 0785 // map theme has not been loaded yet 0786 /** 0787 * @todo Do we need to queue the document and process it once a map 0788 * theme becomes available? 0789 */ 0790 return; 0791 } 0792 0793 GeoDataDocument* doc = m_model->fileManager()->at( key ); 0794 0795 for ( const GeoSceneLayer *layer: m_model->mapTheme()->map()->layers() ) { 0796 if ( layer->backend() != dgml::dgmlValue_geodata 0797 && layer->backend() != dgml::dgmlValue_vector ) 0798 continue; 0799 0800 // look for documents 0801 for ( const GeoSceneAbstractDataset *dataset: layer->datasets() ) { 0802 const GeoSceneGeodata *data = static_cast<const GeoSceneGeodata*>( dataset ); 0803 QString containername = data->sourceFile(); 0804 QString colorize = data->colorize(); 0805 if( key == containername ) { 0806 if (colorize == QLatin1String("land")) { 0807 m_textureLayer.addLandDocument( doc ); 0808 } 0809 if (colorize == QLatin1String("sea")) { 0810 m_textureLayer.addSeaDocument( doc ); 0811 } 0812 0813 // set visibility according to theme property 0814 if( !data->property().isEmpty() ) { 0815 bool value; 0816 m_model->mapTheme()->settings()->propertyValue( data->property(), value ); 0817 doc->setVisible( value ); 0818 m_model->treeModel()->updateFeature( doc ); 0819 } 0820 } 0821 } 0822 } 0823 } 0824 0825 void MarbleMapPrivate::updateTileLevel() 0826 { 0827 auto const tileZoomLevel = q->tileZoomLevel(); 0828 m_geometryLayer.setTileLevel(tileZoomLevel); 0829 m_placemarkLayer.setTileLevel(tileZoomLevel); 0830 emit q->tileLevelChanged(tileZoomLevel); 0831 } 0832 0833 // Used to be paintEvent() 0834 void MarbleMap::paint( GeoPainter &painter, const QRect &dirtyRect ) 0835 { 0836 Q_UNUSED( dirtyRect ); 0837 0838 if (d->m_showDebugPolygons ) { 0839 if (viewContext() == Animation) { 0840 painter.setDebugPolygonsLevel(1); 0841 } 0842 else { 0843 painter.setDebugPolygonsLevel(2); 0844 } 0845 } 0846 painter.setDebugBatchRender(d->m_showDebugBatchRender); 0847 0848 if ( !d->m_model->mapTheme() ) { 0849 mDebug() << "No theme yet!"; 0850 d->m_marbleSplashLayer.render( &painter, &d->m_viewport ); 0851 return; 0852 } 0853 0854 QElapsedTimer t; 0855 t.start(); 0856 0857 RenderStatus const oldRenderStatus = d->m_renderState.status(); 0858 d->m_layerManager.renderLayers( &painter, &d->m_viewport ); 0859 d->m_renderState = d->m_layerManager.renderState(); 0860 bool const parsing = d->m_model->fileManager()->pendingFiles() > 0; 0861 d->m_renderState.addChild(RenderState(QStringLiteral("Files"), parsing ? WaitingForData : Complete)); 0862 RenderStatus const newRenderStatus = d->m_renderState.status(); 0863 if ( oldRenderStatus != newRenderStatus ) { 0864 emit renderStatusChanged( newRenderStatus ); 0865 } 0866 emit renderStateChanged( d->m_renderState ); 0867 0868 if ( d->m_showFrameRate ) { 0869 FpsLayer fpsPainter( &t ); 0870 fpsPainter.paint( &painter ); 0871 } 0872 0873 const qreal fps = 1000.0 / (qreal)( t.elapsed() ); 0874 emit framesPerSecond( fps ); 0875 } 0876 0877 void MarbleMap::customPaint( GeoPainter *painter ) 0878 { 0879 Q_UNUSED( painter ); 0880 } 0881 0882 QString MarbleMap::mapThemeId() const 0883 { 0884 return d->m_model->mapThemeId(); 0885 } 0886 0887 void MarbleMap::setMapThemeId( const QString& mapThemeId ) 0888 { 0889 d->m_model->setMapThemeId( mapThemeId ); 0890 } 0891 0892 void MarbleMapPrivate::updateMapTheme() 0893 { 0894 m_layerManager.removeLayer( &m_textureLayer ); 0895 // FIXME Find a better way to do this reset. Maybe connect to themeChanged SIGNAL? 0896 m_vectorTileLayer.reset(); 0897 m_layerManager.removeLayer( &m_vectorTileLayer ); 0898 m_layerManager.removeLayer( &m_groundLayer ); 0899 0900 QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)), 0901 q, SLOT(updateProperty(QString,bool)) ); 0902 QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)), 0903 m_model, SLOT(updateProperty(QString,bool)) ); 0904 0905 q->setPropertyValue(QStringLiteral("clouds_data"), m_viewParams.showClouds()); 0906 0907 QColor backgroundColor = m_styleBuilder.effectColor(m_model->mapTheme()->map()->backgroundColor()); 0908 m_groundLayer.setColor(backgroundColor); 0909 0910 // Check whether there is a texture layer and vectortile layer available: 0911 if ( m_model->mapTheme()->map()->hasTextureLayers() ) { 0912 const GeoSceneSettings *const settings = m_model->mapTheme()->settings(); 0913 const GeoSceneGroup *const textureLayerSettings = settings ? settings->group( "Texture Layers" ) : nullptr; 0914 const GeoSceneGroup *const vectorTileLayerSettings = settings ? settings->group( "VectorTile Layers" ) : nullptr; 0915 0916 bool textureLayersOk = true; 0917 bool vectorTileLayersOk = true; 0918 0919 // textures will contain texture layers and 0920 // vectorTiles vectortile layers 0921 QVector<const GeoSceneTextureTileDataset *> textures; 0922 QVector<const GeoSceneVectorTileDataset *> vectorTiles; 0923 0924 for( GeoSceneLayer* layer: m_model->mapTheme()->map()->layers() ){ 0925 if ( layer->backend() == dgml::dgmlValue_texture ){ 0926 0927 for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) { 0928 const GeoSceneTextureTileDataset *const texture = dynamic_cast<GeoSceneTextureTileDataset const *>( pos ); 0929 if ( !texture ) 0930 continue; 0931 0932 const QString sourceDir = texture->sourceDir(); 0933 const QString installMap = texture->installMap(); 0934 const QString role = layer->role(); 0935 0936 // If the tiles aren't already there, put up a progress dialog 0937 // while creating them. 0938 if ( !TileLoader::baseTilesAvailable( *texture ) 0939 && !installMap.isEmpty() ) 0940 { 0941 mDebug() << "Base tiles not available. Creating Tiles ... \n" 0942 << "SourceDir: " << sourceDir << "InstallMap:" << installMap; 0943 0944 TileCreator *tileCreator = new TileCreator( 0945 sourceDir, 0946 installMap, 0947 (role == QLatin1String("dem")) ? "true" : "false" ); 0948 tileCreator->setTileFormat( texture->fileFormat().toLower() ); 0949 0950 QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr ); 0951 tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(), 0952 m_model->mapTheme()->head()->description() ); 0953 tileCreatorDlg->exec(); 0954 if ( TileLoader::baseTilesAvailable( *texture ) ) { 0955 mDebug() << "Base tiles for" << sourceDir << "successfully created."; 0956 } else { 0957 qWarning() << "Some or all base tiles for" << sourceDir << "could not be created."; 0958 } 0959 0960 delete tileCreatorDlg; 0961 } 0962 0963 if ( TileLoader::baseTilesAvailable( *texture ) ) { 0964 textures.append( texture ); 0965 } else { 0966 qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers."; 0967 textureLayersOk = false; 0968 } 0969 } 0970 } 0971 else if ( layer->backend() == dgml::dgmlValue_vectortile ){ 0972 0973 for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) { 0974 const GeoSceneVectorTileDataset *const vectorTile = dynamic_cast<GeoSceneVectorTileDataset const *>( pos ); 0975 if ( !vectorTile ) 0976 continue; 0977 0978 const QString sourceDir = vectorTile->sourceDir(); 0979 const QString installMap = vectorTile->installMap(); 0980 const QString role = layer->role(); 0981 0982 // If the tiles aren't already there, put up a progress dialog 0983 // while creating them. 0984 if ( !TileLoader::baseTilesAvailable( *vectorTile ) 0985 && !installMap.isEmpty() ) 0986 { 0987 mDebug() << "Base tiles not available. Creating Tiles ... \n" 0988 << "SourceDir: " << sourceDir << "InstallMap:" << installMap; 0989 0990 TileCreator *tileCreator = new TileCreator( 0991 sourceDir, 0992 installMap, 0993 (role == QLatin1String("dem")) ? "true" : "false" ); 0994 tileCreator->setTileFormat( vectorTile->fileFormat().toLower() ); 0995 0996 QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr ); 0997 tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(), 0998 m_model->mapTheme()->head()->description() ); 0999 tileCreatorDlg->exec(); 1000 if ( TileLoader::baseTilesAvailable( *vectorTile ) ) { 1001 qDebug() << "Base tiles for" << sourceDir << "successfully created."; 1002 } else { 1003 qDebug() << "Some or all base tiles for" << sourceDir << "could not be created."; 1004 } 1005 1006 delete tileCreatorDlg; 1007 } 1008 1009 if ( TileLoader::baseTilesAvailable( *vectorTile ) ) { 1010 vectorTiles.append( vectorTile ); 1011 } else { 1012 qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers."; 1013 vectorTileLayersOk = false; 1014 } 1015 } 1016 } 1017 } 1018 1019 QString seafile, landfile; 1020 if( !m_model->mapTheme()->map()->filters().isEmpty() ) { 1021 const GeoSceneFilter *filter= m_model->mapTheme()->map()->filters().first(); 1022 1023 if (filter->type() == QLatin1String("colorize")) { 1024 //no need to look up with MarbleDirs twice so they are left null for now 1025 QList<const GeoScenePalette*> palette = filter->palette(); 1026 for (const GeoScenePalette *curPalette: palette ) { 1027 1028 if (curPalette->type() == QLatin1String("sea")) { 1029 seafile = MarbleDirs::path( curPalette->file() ); 1030 } else if (curPalette->type() == QLatin1String("land")) { 1031 landfile = MarbleDirs::path( curPalette->file() ); 1032 } 1033 } 1034 //look up locations if they are empty 1035 if( seafile.isEmpty() ) 1036 seafile = MarbleDirs::path(QStringLiteral("seacolors.leg")); 1037 if( landfile.isEmpty() ) 1038 landfile = MarbleDirs::path(QStringLiteral("landcolors.leg")); 1039 } 1040 } 1041 1042 m_textureLayer.setMapTheme( textures, textureLayerSettings, seafile, landfile ); 1043 m_textureLayer.setProjection( m_viewport.projection() ); 1044 m_textureLayer.setShowRelief( q->showRelief() ); 1045 1046 m_vectorTileLayer.setMapTheme( vectorTiles, vectorTileLayerSettings ); 1047 1048 if (m_textureLayer.layerCount() == 0) { 1049 m_layerManager.addLayer( &m_groundLayer ); 1050 } 1051 1052 if ( textureLayersOk ) 1053 m_layerManager.addLayer( &m_textureLayer ); 1054 if ( vectorTileLayersOk && !vectorTiles.isEmpty() ) 1055 m_layerManager.addLayer( &m_vectorTileLayer ); 1056 } 1057 else { 1058 m_layerManager.addLayer( &m_groundLayer ); 1059 m_textureLayer.setMapTheme( QVector<const GeoSceneTextureTileDataset *>(), nullptr, "", "" ); 1060 m_vectorTileLayer.setMapTheme( QVector<const GeoSceneVectorTileDataset *>(), nullptr ); 1061 } 1062 1063 // earth 1064 m_placemarkLayer.setShowPlaces( q->showPlaces() ); 1065 1066 m_placemarkLayer.setShowCities( q->showCities() ); 1067 m_placemarkLayer.setShowTerrain( q->showTerrain() ); 1068 m_placemarkLayer.setShowOtherPlaces( q->showOtherPlaces() ); 1069 m_placemarkLayer.setShowLandingSites(q->propertyValue(QStringLiteral("landingsites"))); 1070 m_placemarkLayer.setShowCraters(q->propertyValue(QStringLiteral("craters"))); 1071 m_placemarkLayer.setShowMaria(q->propertyValue(QStringLiteral("maria"))); 1072 1073 m_styleBuilder.setDefaultLabelColor(m_model->mapTheme()->map()->labelColor()); 1074 m_placemarkLayer.requestStyleReset(); 1075 1076 for (RenderPlugin *renderPlugin: m_renderPlugins) { 1077 bool propertyAvailable = false; 1078 m_model->mapTheme()->settings()->propertyAvailable( renderPlugin->nameId(), propertyAvailable ); 1079 bool propertyValue = false; 1080 m_model->mapTheme()->settings()->propertyValue( renderPlugin->nameId(), propertyValue ); 1081 1082 if ( propertyAvailable ) { 1083 renderPlugin->setVisible( propertyValue ); 1084 } 1085 } 1086 1087 emit q->themeChanged( m_model->mapTheme()->head()->mapThemeId() ); 1088 } 1089 1090 void MarbleMap::setPropertyValue( const QString& name, bool value ) 1091 { 1092 mDebug() << "In MarbleMap the property " << name << "was set to " << value; 1093 if ( d->m_model->mapTheme() ) { 1094 d->m_model->mapTheme()->settings()->setPropertyValue( name, value ); 1095 d->m_textureLayer.setNeedsUpdate(); 1096 emit propertyValueChanged(name, value); 1097 } 1098 else { 1099 mDebug() << "WARNING: Failed to access a map theme! Property: " << name; 1100 } 1101 if (d->m_textureLayer.layerCount() == 0) { 1102 d->m_layerManager.addLayer( &d->m_groundLayer ); 1103 } 1104 else { 1105 d->m_layerManager.removeLayer( &d->m_groundLayer ); 1106 } 1107 } 1108 1109 void MarbleMap::setShowOverviewMap( bool visible ) 1110 { 1111 setPropertyValue(QStringLiteral("overviewmap"), visible); 1112 } 1113 1114 void MarbleMap::setShowScaleBar( bool visible ) 1115 { 1116 setPropertyValue(QStringLiteral("scalebar"), visible); 1117 } 1118 1119 void MarbleMap::setShowCompass( bool visible ) 1120 { 1121 setPropertyValue(QStringLiteral("compass"), visible); 1122 } 1123 1124 void MarbleMap::setShowAtmosphere( bool visible ) 1125 { 1126 for ( RenderPlugin *plugin: renderPlugins() ) { 1127 if (plugin->nameId() == QLatin1String("atmosphere")) { 1128 plugin->setVisible( visible ); 1129 } 1130 } 1131 1132 d->m_viewParams.setShowAtmosphere( visible ); 1133 } 1134 1135 void MarbleMap::setShowCrosshairs( bool visible ) 1136 { 1137 QList<RenderPlugin *> pluginList = renderPlugins(); 1138 QList<RenderPlugin *>::const_iterator i = pluginList.constBegin(); 1139 QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd(); 1140 for (; i != end; ++i ) { 1141 if ((*i)->nameId() == QLatin1String("crosshairs")) { 1142 (*i)->setVisible( visible ); 1143 } 1144 } 1145 } 1146 1147 void MarbleMap::setShowClouds( bool visible ) 1148 { 1149 d->m_viewParams.setShowClouds( visible ); 1150 1151 setPropertyValue(QStringLiteral("clouds_data"), visible); 1152 } 1153 1154 void MarbleMap::setShowSunShading( bool visible ) 1155 { 1156 d->m_textureLayer.setShowSunShading( visible ); 1157 } 1158 1159 void MarbleMap::setShowCityLights( bool visible ) 1160 { 1161 d->m_textureLayer.setShowCityLights( visible ); 1162 setPropertyValue(QStringLiteral("citylights"), visible); 1163 } 1164 1165 void MarbleMap::setLockToSubSolarPoint( bool visible ) 1166 { 1167 disconnect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)), 1168 this, SLOT(centerOn(qreal,qreal)) ); 1169 1170 if( isLockedToSubSolarPoint() != visible ) { 1171 d->m_isLockedToSubSolarPoint = visible; 1172 } 1173 1174 if ( isLockedToSubSolarPoint() ) { 1175 connect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)), 1176 this, SLOT(centerOn(qreal,qreal)) ); 1177 1178 centerOn( d->m_model->sunLocator()->getLon(), d->m_model->sunLocator()->getLat() ); 1179 } else if ( visible ) { 1180 mDebug() << "Ignoring centering on sun, since the sun plugin is not loaded."; 1181 } 1182 } 1183 1184 void MarbleMap::setSubSolarPointIconVisible( bool visible ) 1185 { 1186 if ( isSubSolarPointIconVisible() != visible ) { 1187 d->m_isSubSolarPointIconVisible = visible; 1188 } 1189 } 1190 1191 void MarbleMap::setShowTileId( bool visible ) 1192 { 1193 d->m_textureLayer.setShowTileId( visible ); 1194 } 1195 1196 void MarbleMap::setShowGrid( bool visible ) 1197 { 1198 setPropertyValue(QStringLiteral("coordinate-grid"), visible); 1199 } 1200 1201 void MarbleMap::setShowPlaces( bool visible ) 1202 { 1203 setPropertyValue(QStringLiteral("places"), visible); 1204 } 1205 1206 void MarbleMap::setShowCities( bool visible ) 1207 { 1208 setPropertyValue(QStringLiteral("cities"), visible); 1209 } 1210 1211 void MarbleMap::setShowTerrain( bool visible ) 1212 { 1213 setPropertyValue(QStringLiteral("terrain"), visible); 1214 } 1215 1216 void MarbleMap::setShowOtherPlaces( bool visible ) 1217 { 1218 setPropertyValue(QStringLiteral("otherplaces"), visible); 1219 } 1220 1221 void MarbleMap::setShowRelief( bool visible ) 1222 { 1223 setPropertyValue(QStringLiteral("relief"), visible); 1224 } 1225 1226 void MarbleMap::setShowIceLayer( bool visible ) 1227 { 1228 setPropertyValue(QStringLiteral("ice"), visible); 1229 } 1230 1231 void MarbleMap::setShowBorders( bool visible ) 1232 { 1233 setPropertyValue(QStringLiteral("borders"), visible); 1234 } 1235 1236 void MarbleMap::setShowRivers( bool visible ) 1237 { 1238 setPropertyValue(QStringLiteral("rivers"), visible); 1239 } 1240 1241 void MarbleMap::setShowLakes( bool visible ) 1242 { 1243 setPropertyValue(QStringLiteral("lakes"), visible); 1244 } 1245 1246 void MarbleMap::setShowFrameRate( bool visible ) 1247 { 1248 d->m_showFrameRate = visible; 1249 } 1250 1251 void MarbleMap::setShowRuntimeTrace( bool visible ) 1252 { 1253 if (visible != d->m_layerManager.showRuntimeTrace()) { 1254 d->m_layerManager.setShowRuntimeTrace(visible); 1255 emit repaintNeeded(); 1256 } 1257 } 1258 1259 bool MarbleMap::showRuntimeTrace() const 1260 { 1261 return d->m_layerManager.showRuntimeTrace(); 1262 } 1263 1264 void MarbleMap::setShowDebugPolygons( bool visible) 1265 { 1266 if (visible != d->m_showDebugPolygons) { 1267 d->m_showDebugPolygons = visible; 1268 emit repaintNeeded(); 1269 } 1270 } 1271 1272 bool MarbleMap::showDebugPolygons() const 1273 { 1274 return d->m_showDebugPolygons; 1275 } 1276 1277 void MarbleMap::setShowDebugBatchRender( bool visible) 1278 { 1279 qDebug() << visible; 1280 if (visible != d->m_showDebugBatchRender) { 1281 d->m_showDebugBatchRender = visible; 1282 emit repaintNeeded(); 1283 } 1284 } 1285 1286 bool MarbleMap::showDebugBatchRender() const 1287 { 1288 return d->m_showDebugBatchRender; 1289 } 1290 1291 void MarbleMap::setShowDebugPlacemarks( bool visible) 1292 { 1293 if (visible != d->m_placemarkLayer.isDebugModeEnabled()) { 1294 d->m_placemarkLayer.setDebugModeEnabled(visible); 1295 emit repaintNeeded(); 1296 } 1297 } 1298 1299 bool MarbleMap::showDebugPlacemarks() const 1300 { 1301 return d->m_placemarkLayer.isDebugModeEnabled(); 1302 } 1303 1304 void MarbleMap::setLevelTagDebugModeEnabled(bool visible) 1305 { 1306 if (visible != d->m_geometryLayer.levelTagDebugModeEnabled()) { 1307 d->m_geometryLayer.setLevelTagDebugModeEnabled(visible); 1308 d->m_placemarkLayer.setLevelTagDebugModeEnabled(visible); 1309 emit repaintNeeded(); 1310 } 1311 } 1312 1313 bool MarbleMap::levelTagDebugModeEnabled() const 1314 { 1315 return d->m_geometryLayer.levelTagDebugModeEnabled() && 1316 d->m_placemarkLayer.levelTagDebugModeEnabled(); 1317 } 1318 1319 void MarbleMap::setDebugLevelTag(int level) 1320 { 1321 d->m_geometryLayer.setDebugLevelTag(level); 1322 d->m_placemarkLayer.setDebugLevelTag(level); 1323 } 1324 1325 int MarbleMap::debugLevelTag() const 1326 { 1327 return d->m_geometryLayer.debugLevelTag(); 1328 } 1329 1330 void MarbleMap::setShowBackground( bool visible ) 1331 { 1332 d->m_layerManager.setShowBackground( visible ); 1333 } 1334 1335 void MarbleMap::setVisibleRelationTypes(GeoDataRelation::RelationTypes relationTypes) 1336 { 1337 if (d->m_visibleRelationTypes != relationTypes) { 1338 d->m_visibleRelationTypes = relationTypes; 1339 d->m_geometryLayer.setVisibleRelationTypes(relationTypes); 1340 emit visibleRelationTypesChanged(d->m_visibleRelationTypes); 1341 } 1342 } 1343 1344 void MarbleMap::notifyMouseClick( int x, int y ) 1345 { 1346 qreal lon = 0; 1347 qreal lat = 0; 1348 1349 const bool valid = geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian ); 1350 1351 if ( valid ) { 1352 emit mouseClickGeoPosition( lon, lat, GeoDataCoordinates::Radian ); 1353 } 1354 } 1355 1356 void MarbleMap::clearVolatileTileCache() 1357 { 1358 d->m_vectorTileLayer.reset(); 1359 d->m_textureLayer.reset(); 1360 mDebug() << "Cleared Volatile Cache!"; 1361 } 1362 1363 void MarbleMap::setVolatileTileCacheLimit( quint64 kilobytes ) 1364 { 1365 mDebug() << "kiloBytes" << kilobytes; 1366 d->m_textureLayer.setVolatileCacheLimit( kilobytes ); 1367 } 1368 1369 AngleUnit MarbleMap::defaultAngleUnit() const 1370 { 1371 if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::Decimal ) { 1372 return DecimalDegree; 1373 } else if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::UTM ) { 1374 return UTM; 1375 } 1376 1377 return DMSDegree; 1378 } 1379 1380 void MarbleMap::setDefaultAngleUnit( AngleUnit angleUnit ) 1381 { 1382 if ( angleUnit == DecimalDegree ) { 1383 GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::Decimal ); 1384 return; 1385 } else if ( angleUnit == UTM ) { 1386 GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::UTM ); 1387 return; 1388 } 1389 1390 GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::DMS ); 1391 } 1392 1393 QFont MarbleMap::defaultFont() const 1394 { 1395 return d->m_styleBuilder.defaultFont(); 1396 } 1397 1398 void MarbleMap::setDefaultFont( const QFont& font ) 1399 { 1400 d->m_styleBuilder.setDefaultFont(font); 1401 d->m_placemarkLayer.requestStyleReset(); 1402 } 1403 1404 QList<RenderPlugin *> MarbleMap::renderPlugins() const 1405 { 1406 return d->m_renderPlugins; 1407 } 1408 1409 QList<AbstractFloatItem *> MarbleMap::floatItems() const 1410 { 1411 return d->m_floatItemsLayer.floatItems(); 1412 } 1413 1414 AbstractFloatItem * MarbleMap::floatItem( const QString &nameId ) const 1415 { 1416 for ( AbstractFloatItem * floatItem: floatItems() ) { 1417 if ( floatItem && floatItem->nameId() == nameId ) { 1418 return floatItem; 1419 } 1420 } 1421 1422 return nullptr; // No item found 1423 } 1424 1425 QList<AbstractDataPlugin *> MarbleMap::dataPlugins() const 1426 { 1427 return d->m_layerManager.dataPlugins(); 1428 } 1429 1430 QList<AbstractDataPluginItem *> MarbleMap::whichItemAt( const QPoint& curpos ) const 1431 { 1432 return d->m_layerManager.whichItemAt( curpos ); 1433 } 1434 1435 void MarbleMap::addLayer( LayerInterface *layer ) 1436 { 1437 d->m_layerManager.addLayer(layer); 1438 } 1439 1440 void MarbleMap::removeLayer( LayerInterface *layer ) 1441 { 1442 d->m_layerManager.removeLayer(layer); 1443 } 1444 1445 RenderStatus MarbleMap::renderStatus() const 1446 { 1447 return d->m_layerManager.renderState().status(); 1448 } 1449 1450 RenderState MarbleMap::renderState() const 1451 { 1452 return d->m_layerManager.renderState(); 1453 } 1454 1455 QString MarbleMap::addTextureLayer(GeoSceneTextureTileDataset *texture) 1456 { 1457 return textureLayer()->addTextureLayer(texture); 1458 } 1459 1460 void MarbleMap::removeTextureLayer(const QString &key) 1461 { 1462 textureLayer()->removeTextureLayer(key); 1463 } 1464 1465 // this method will only temporarily "pollute" the MarbleModel class 1466 TextureLayer *MarbleMap::textureLayer() const 1467 { 1468 return &d->m_textureLayer; 1469 } 1470 1471 VectorTileLayer *MarbleMap::vectorTileLayer() const 1472 { 1473 return &d->m_vectorTileLayer; 1474 } 1475 1476 const StyleBuilder* MarbleMap::styleBuilder() const 1477 { 1478 return &d->m_styleBuilder; 1479 } 1480 1481 qreal MarbleMap::heading() const 1482 { 1483 return d->m_viewport.heading() * RAD2DEG; 1484 } 1485 1486 void MarbleMap::setHeading( qreal heading ) 1487 { 1488 d->m_viewport.setHeading( heading * DEG2RAD ); 1489 d->m_textureLayer.setNeedsUpdate(); 1490 1491 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); 1492 } 1493 1494 } 1495 1496 #include "moc_MarbleMap.cpp"