Marble

MarbleMap.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2006-2009 Torsten Rahn <[email protected]>
4 // SPDX-FileCopyrightText: 2007 Inge Wallin <[email protected]>
5 // SPDX-FileCopyrightText: 2008 Carlos Licea <[email protected]>
6 // SPDX-FileCopyrightText: 2009 Jens-Michael Hoffmann <[email protected]>
7 // SPDX-FileCopyrightText: 2010-2012 Bernhard Beschow <[email protected]>
8 //
9 
10 
11 // Own
12 #include "MarbleMap.h"
13 
14 // Posix
15 #include <cmath>
16 
17 // Qt
18 #include <QElapsedTimer>
19 #include <QtMath>
20 
21 // Marble
22 #include "layers/FloatItemsLayer.h"
23 #include "layers/FogLayer.h"
24 #include "layers/FpsLayer.h"
25 #include "layers/GeometryLayer.h"
26 #include "layers/GroundLayer.h"
27 #include "layers/MarbleSplashLayer.h"
28 #include "layers/PlacemarkLayer.h"
29 #include "layers/TextureLayer.h"
30 #include "layers/VectorTileLayer.h"
31 #include "AbstractFloatItem.h"
32 #include "DgmlAuxillaryDictionary.h"
33 #include "FileManager.h"
34 #include "GeoDataTreeModel.h"
35 #include "GeoPainter.h"
36 #include "GeoSceneDocument.h"
37 #include "GeoSceneFilter.h"
38 #include "GeoSceneGeodata.h"
39 #include "GeoSceneHead.h"
40 #include "GeoSceneLayer.h"
41 #include "GeoSceneMap.h"
42 #include "GeoScenePalette.h"
43 #include "GeoSceneSettings.h"
44 #include "GeoSceneVector.h"
45 #include "GeoSceneVectorTileDataset.h"
46 #include "GeoSceneTextureTileDataset.h"
47 #include "GeoSceneZoom.h"
48 #include "GeoDataDocument.h"
49 #include "GeoDataFeature.h"
50 #include "GeoDataStyle.h"
51 #include "GeoDataStyleMap.h"
52 #include "LayerManager.h"
53 #include "MapThemeManager.h"
54 #include "MarbleDebug.h"
55 #include "MarbleDirs.h"
56 #include "MarbleModel.h"
57 #include "PluginManager.h"
58 #include "RenderPlugin.h"
59 #include "StyleBuilder.h"
60 #include "SunLocator.h"
61 #include "TileId.h"
62 #include "TileCoordsPyramid.h"
63 #include "TileCreator.h"
64 #include "TileCreatorDialog.h"
65 #include "TileLoader.h"
66 #include "ViewParams.h"
67 #include "ViewportParams.h"
68 #include "RenderState.h"
69 #include "BookmarkManager.h"
70 
71 
72 namespace Marble
73 {
74 
75 
76 class MarbleMap::CustomPaintLayer : public LayerInterface
77 {
78 public:
79  explicit CustomPaintLayer( MarbleMap *map )
80  : m_map( map )
81  {
82  }
83 
84  QStringList renderPosition() const override { return QStringList() << "USER_TOOLS"; }
85 
86  bool render( GeoPainter *painter, ViewportParams *viewport,
87  const QString &renderPos, GeoSceneLayer *layer ) override
88  {
89  Q_UNUSED( viewport );
90  Q_UNUSED( renderPos );
91  Q_UNUSED( layer );
92 
93  m_map->customPaint( painter );
94 
95  return true;
96  }
97 
98  qreal zValue() const override { return 1.0e6; }
99 
100  RenderState renderState() const override { return RenderState(QStringLiteral("Custom Map Paint")); }
101 
102  QString runtimeTrace() const override { return QStringLiteral("CustomPaint"); }
103 
104 private:
105  MarbleMap *const m_map;
106 };
107 
108 
109 class MarbleMapPrivate
110 {
111  friend class MarbleWidget;
112 
113 public:
114  explicit MarbleMapPrivate( MarbleMap *parent, MarbleModel *model );
115 
116  void updateMapTheme();
117 
118  void updateProperty( const QString &, bool );
119 
120  void setDocument( const QString& key );
121 
122  void updateTileLevel();
123 
124  void addPlugins();
125 
126  MarbleMap *const q;
127 
128  // The model we are showing.
129  MarbleModel *const m_model;
130  bool m_modelIsOwned;
131 
132  // Parameters for the maps appearance.
133  ViewParams m_viewParams;
134  ViewportParams m_viewport;
135  bool m_showFrameRate;
136  bool m_showDebugPolygons;
137  bool m_showDebugBatchRender;
138  GeoDataRelation::RelationTypes m_visibleRelationTypes;
139  StyleBuilder m_styleBuilder;
140 
141  QList<RenderPlugin *> m_renderPlugins;
142 
143  LayerManager m_layerManager;
144  MarbleSplashLayer m_marbleSplashLayer;
145  MarbleMap::CustomPaintLayer m_customPaintLayer;
146  GeometryLayer m_geometryLayer;
147  FloatItemsLayer m_floatItemsLayer;
148  FogLayer m_fogLayer;
149  GroundLayer m_groundLayer;
150  TextureLayer m_textureLayer;
151  PlacemarkLayer m_placemarkLayer;
152  VectorTileLayer m_vectorTileLayer;
153 
154  bool m_isLockedToSubSolarPoint;
155  bool m_isSubSolarPointIconVisible;
156  RenderState m_renderState;
157 };
158 
159 MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) :
160  q( parent ),
161  m_model( model ),
162  m_viewParams(),
163  m_showFrameRate( false ),
164  m_showDebugPolygons( false ),
165  m_showDebugBatchRender( false ),
166  m_visibleRelationTypes(GeoDataRelation::RouteFerry),
167  m_styleBuilder(),
168  m_layerManager( parent ),
169  m_customPaintLayer( parent ),
170  m_geometryLayer(model->treeModel(), &m_styleBuilder),
171  m_floatItemsLayer(parent),
172  m_textureLayer( model->downloadManager(), model->pluginManager(), model->sunLocator(), model->groundOverlayModel() ),
173  m_placemarkLayer( model->placemarkModel(), model->placemarkSelectionModel(), model->clock(), &m_styleBuilder ),
174  m_vectorTileLayer( model->downloadManager(), model->pluginManager(), model->treeModel() ),
175  m_isLockedToSubSolarPoint( false ),
176  m_isSubSolarPointIconVisible( false )
177 {
178  m_layerManager.addLayer(&m_floatItemsLayer);
179  m_layerManager.addLayer( &m_fogLayer );
180  m_layerManager.addLayer( &m_groundLayer );
181  m_layerManager.addLayer( &m_geometryLayer );
182  m_layerManager.addLayer( &m_placemarkLayer );
183  m_layerManager.addLayer( &m_customPaintLayer );
184 
185  m_model->bookmarkManager()->setStyleBuilder(&m_styleBuilder);
186 
187  QObject::connect( m_model, SIGNAL(themeChanged(QString)),
188  parent, SLOT(updateMapTheme()) );
189  QObject::connect( m_model->fileManager(), SIGNAL(fileAdded(QString)),
190  parent, SLOT(setDocument(QString)) );
191 
192 
193  QObject::connect( &m_placemarkLayer, SIGNAL(repaintNeeded()),
194  parent, SIGNAL(repaintNeeded()));
195 
196  QObject::connect ( &m_layerManager, SIGNAL(pluginSettingsChanged()),
197  parent, SIGNAL(pluginSettingsChanged()) );
198  QObject::connect ( &m_layerManager, SIGNAL(repaintNeeded(QRegion)),
199  parent, SIGNAL(repaintNeeded(QRegion)) );
200  QObject::connect ( &m_layerManager, SIGNAL(renderPluginInitialized(RenderPlugin*)),
201  parent, SIGNAL(renderPluginInitialized(RenderPlugin*)) );
202  QObject::connect ( &m_layerManager, SIGNAL(visibilityChanged(QString,bool)),
203  parent, SLOT(setPropertyValue(QString,bool)) );
204 
205  QObject::connect( &m_geometryLayer, SIGNAL(repaintNeeded()),
206  parent, SIGNAL(repaintNeeded()));
207 
208  /*
209  * Slot handleHighlight finds all placemarks
210  * that contain the clicked point.
211  * The placemarks under the clicked position may
212  * have their styleUrl set to a style map which
213  * doesn't specify any highlight styleId. Such
214  * placemarks will be fletered out in GeoGraphicsScene
215  * and will not be highlighted.
216  */
217  QObject::connect( parent, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)),
218  &m_geometryLayer, SLOT(handleHighlight(qreal,qreal,GeoDataCoordinates::Unit)) );
219 
220  QObject::connect(&m_floatItemsLayer, SIGNAL(repaintNeeded(QRegion)),
221  parent, SIGNAL(repaintNeeded(QRegion)));
222  QObject::connect(&m_floatItemsLayer, SIGNAL(renderPluginInitialized(RenderPlugin*)),
223  parent, SIGNAL(renderPluginInitialized(RenderPlugin*)));
224  QObject::connect(&m_floatItemsLayer, SIGNAL(visibilityChanged(QString,bool)),
225  parent, SLOT(setPropertyValue(QString,bool)));
226  QObject::connect(&m_floatItemsLayer, SIGNAL(pluginSettingsChanged()),
227  parent, SIGNAL(pluginSettingsChanged()));
228 
229  QObject::connect( &m_textureLayer, SIGNAL(tileLevelChanged(int)),
230  parent, SLOT(updateTileLevel()) );
231  QObject::connect( &m_vectorTileLayer, SIGNAL(tileLevelChanged(int)),
232  parent, SLOT(updateTileLevel()) );
233  QObject::connect( parent, SIGNAL(radiusChanged(int)),
234  parent, SLOT(updateTileLevel()) );
235 
236  QObject::connect( &m_textureLayer, SIGNAL(repaintNeeded()),
237  parent, SIGNAL(repaintNeeded()) );
238  QObject::connect( parent, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)),
239  parent, SIGNAL(repaintNeeded()) );
240 
241  addPlugins();
242  QObject::connect(model->pluginManager(), SIGNAL(renderPluginsChanged()),
243  parent, SLOT(addPlugins()));
244 }
245 
246 void MarbleMapPrivate::updateProperty( const QString &name, bool show )
247 {
248  // earth
249  if (name == QLatin1String("places")) {
250  m_placemarkLayer.setShowPlaces( show );
251  } else if (name == QLatin1String("cities")) {
252  m_placemarkLayer.setShowCities( show );
253  } else if (name == QLatin1String("terrain")) {
254  m_placemarkLayer.setShowTerrain( show );
255  } else if (name == QLatin1String("otherplaces")) {
256  m_placemarkLayer.setShowOtherPlaces( show );
257  }
258 
259  // other planets
260  else if (name == QLatin1String("landingsites")) {
261  m_placemarkLayer.setShowLandingSites( show );
262  } else if (name == QLatin1String("craters")) {
263  m_placemarkLayer.setShowCraters( show );
264  } else if (name == QLatin1String("maria")) {
265  m_placemarkLayer.setShowMaria( show );
266  }
267 
268  else if (name == QLatin1String("relief")) {
269  m_textureLayer.setShowRelief( show );
270  }
271 
272  for(RenderPlugin *renderPlugin: m_renderPlugins) {
273  if ( name == renderPlugin->nameId() ) {
274  if ( renderPlugin->visible() == show ) {
275  break;
276  }
277 
278  renderPlugin->setVisible( show );
279 
280  break;
281  }
282  }
283 }
284 
285 void MarbleMapPrivate::addPlugins()
286 {
287  for (const RenderPlugin *factory: m_model->pluginManager()->renderPlugins()) {
288  bool alreadyCreated = false;
289  for(const RenderPlugin *existing: m_renderPlugins) {
290  if (existing->nameId() == factory->nameId()) {
291  alreadyCreated = true;
292  break;
293  }
294  }
295 
296  if (alreadyCreated) {
297  continue;
298  }
299 
300  RenderPlugin *const renderPlugin = factory->newInstance(m_model);
301  Q_ASSERT(renderPlugin && "Plugin must not return null when requesting a new instance.");
302  m_renderPlugins << renderPlugin;
303 
304  if (AbstractFloatItem *const floatItem = qobject_cast<AbstractFloatItem *>(renderPlugin)) {
305  m_floatItemsLayer.addFloatItem(floatItem);
306  }
307  else {
308  m_layerManager.addRenderPlugin(renderPlugin);
309  }
310  }
311 }
312 
313 // ----------------------------------------------------------------
314 
315 
317  : d( new MarbleMapPrivate( this, new MarbleModel( this ) ) )
318 {
319  // nothing to do
320 }
321 
323  : d( new MarbleMapPrivate( this, model ) )
324 {
325  d->m_modelIsOwned = false;
326 }
327 
328 MarbleMap::~MarbleMap()
329 {
330  MarbleModel *model = d->m_modelIsOwned ? d->m_model : nullptr;
331 
332  d->m_layerManager.removeLayer( &d->m_customPaintLayer );
333  d->m_layerManager.removeLayer( &d->m_geometryLayer );
334  d->m_layerManager.removeLayer(&d->m_floatItemsLayer);
335  d->m_layerManager.removeLayer( &d->m_fogLayer );
336  d->m_layerManager.removeLayer( &d->m_placemarkLayer );
337  d->m_layerManager.removeLayer( &d->m_textureLayer );
338  d->m_layerManager.removeLayer( &d->m_groundLayer );
339  qDeleteAll(d->m_renderPlugins);
340  delete d;
341 
342  delete model; // delete the model after private data
343 }
344 
346 {
347  return d->m_model;
348 }
349 
350 ViewportParams *MarbleMap::viewport()
351 {
352  return &d->m_viewport;
353 }
354 
355 const ViewportParams *MarbleMap::viewport() const
356 {
357  return &d->m_viewport;
358 }
359 
360 
361 void MarbleMap::setMapQualityForViewContext( MapQuality quality, ViewContext viewContext )
362 {
363  d->m_viewParams.setMapQualityForViewContext( quality, viewContext );
364 
365  // Update texture map during the repaint that follows:
366  d->m_textureLayer.setNeedsUpdate();
367 }
368 
369 MapQuality MarbleMap::mapQuality( ViewContext viewContext ) const
370 {
371  return d->m_viewParams.mapQuality( viewContext );
372 }
373 
375 {
376  return d->m_viewParams.mapQuality();
377 }
378 
379 void MarbleMap::setViewContext( ViewContext viewContext )
380 {
381  if ( d->m_viewParams.viewContext() == viewContext ) {
382  return;
383  }
384 
385  const MapQuality oldQuality = d->m_viewParams.mapQuality();
386  d->m_viewParams.setViewContext( viewContext );
387  emit viewContextChanged( viewContext );
388 
389  if ( d->m_viewParams.mapQuality() != oldQuality ) {
390  // Update texture map during the repaint that follows:
391  d->m_textureLayer.setNeedsUpdate();
392 
393  emit repaintNeeded();
394  }
395 }
396 
397 ViewContext MarbleMap::viewContext() const
398 {
399  return d->m_viewParams.viewContext();
400 }
401 
402 
403 void MarbleMap::setSize( int width, int height )
404 {
405  setSize( QSize( width, height ) );
406 }
407 
408 void MarbleMap::setSize( const QSize& size )
409 {
410  d->m_viewport.setSize( size );
411 
412  emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
413 }
414 
415 QSize MarbleMap::size() const
416 {
417  return QSize( d->m_viewport.width(), d->m_viewport.height() );
418 }
419 
420 int MarbleMap::width() const
421 {
422  return d->m_viewport.width();
423 }
424 
425 int MarbleMap::height() const
426 {
427  return d->m_viewport.height();
428 }
429 
430 int MarbleMap::radius() const
431 {
432  return d->m_viewport.radius();
433 }
434 
435 void MarbleMap::setRadius( int radius )
436 {
437  const int oldRadius = d->m_viewport.radius();
438 
439  d->m_viewport.setRadius( radius );
440 
441  if ( oldRadius != d->m_viewport.radius() ) {
442  emit radiusChanged( radius );
443  emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
444  }
445 }
446 
447 
448 int MarbleMap::preferredRadiusCeil(int radius) const
449 {
450  return d->m_textureLayer.preferredRadiusCeil( radius );
451 }
452 
453 
454 int MarbleMap::preferredRadiusFloor(int radius) const
455 {
456  return d->m_textureLayer.preferredRadiusFloor( radius );
457 }
458 
459 
460 int MarbleMap::tileZoomLevel() const
461 {
462  auto const tileZoomLevel = qMax(d->m_textureLayer.tileZoomLevel(), d->m_vectorTileLayer.tileZoomLevel());
463  return tileZoomLevel >= 0 ? tileZoomLevel : qMin<int>(qMax<int>(qLn(d->m_viewport.radius()*4/256)/qLn(2.0), 1), d->m_styleBuilder.maximumZoomLevel());
464 }
465 
466 
468 {
469  // Calculate translation of center point
470  const qreal centerLat = d->m_viewport.centerLatitude();
471 
472  return centerLat * RAD2DEG;
473 }
474 
475 bool MarbleMap::hasFeatureAt(const QPoint &position) const
476 {
477  return d->m_placemarkLayer.hasPlacemarkAt(position) || d->m_geometryLayer.hasFeatureAt(position, viewport());
478 }
479 
481 {
482  // Calculate translation of center point
483  const qreal centerLon = d->m_viewport.centerLongitude();
484 
485  return centerLon * RAD2DEG;
486 }
487 
489 {
490  if ( d->m_model->mapTheme() )
491  return d->m_model->mapTheme()->head()->zoom()->minimum();
492 
493  return 950;
494 }
495 
497 {
498  if ( d->m_model->mapTheme() )
499  return d->m_model->mapTheme()->head()->zoom()->maximum();
500 
501  return 2100;
502 }
503 
504 bool MarbleMap::discreteZoom() const
505 {
506  if ( d->m_model->mapTheme() )
507  return d->m_model->mapTheme()->head()->zoom()->discrete();
508 
509  return false;
510 }
511 
512 QVector<const GeoDataFeature*> MarbleMap::whichFeatureAt( const QPoint& curpos ) const
513 {
514  return d->m_placemarkLayer.whichPlacemarkAt( curpos ) + d->m_geometryLayer.whichFeatureAt( curpos, viewport() );
515 }
516 
518 {
519  d->m_textureLayer.reload();
520  d->m_vectorTileLayer.reload();
521 }
522 
523 void MarbleMap::downloadRegion( QVector<TileCoordsPyramid> const & pyramid )
524 {
525  Q_ASSERT( textureLayer() );
526  Q_ASSERT( !pyramid.isEmpty() );
527  QElapsedTimer t;
528  t.start();
529 
530  // When downloading a region (the author of these lines thinks) most users probably expect
531  // the download to begin with the low resolution tiles and then procede level-wise to
532  // higher resolution tiles. In order to achieve this, we start requesting downloads of
533  // high resolution tiles and request the low resolution tiles at the end because
534  // DownloadQueueSet (silly name) is implemented as stack.
535 
536 
537  int const first = 0;
538  int tilesCount = 0;
539 
540  for ( int level = pyramid[first].bottomLevel(); level >= pyramid[first].topLevel(); --level ) {
541  QSet<TileId> tileIdSet;
542  for( int i = 0; i < pyramid.size(); ++i ) {
543  QRect const coords = pyramid[i].coords( level );
544  mDebug() << "MarbleMap::downloadRegion level:" << level << "tile coords:" << coords;
545  int x1, y1, x2, y2;
546  coords.getCoords( &x1, &y1, &x2, &y2 );
547  for ( int x = x1; x <= x2; ++x ) {
548  for ( int y = y1; y <= y2; ++y ) {
549  TileId const stackedTileId( 0, level, x, y );
550  tileIdSet.insert( stackedTileId );
551  // FIXME: use lazy evaluation to not generate up to 100k tiles in one go
552  // this can take considerable time even on very fast systems
553  // in contrast generating the TileIds on the fly when they are needed
554  // does not seem to affect download speed.
555  }
556  }
557  }
558  QSetIterator<TileId> i( tileIdSet );
559  while( i.hasNext() ) {
560  TileId const tileId = i.next();
561  d->m_textureLayer.downloadStackedTile( tileId );
562  d->m_vectorTileLayer.downloadTile(tileId);
563  mDebug() << "TileDownload" << tileId;
564  }
565  tilesCount += tileIdSet.count();
566  }
567  // Needed for downloading unique tiles only. Much faster than if tiles for each level is downloaded separately
568 
569  int const elapsedMs = t.elapsed();
570  mDebug() << "MarbleMap::downloadRegion:" << tilesCount << "tiles, " << elapsedMs << "ms";
571 }
572 
573 void MarbleMap::highlightRouteRelation(qint64 osmId, bool enabled)
574 {
575  d->m_geometryLayer.highlightRouteRelation(osmId, enabled);
576 }
577 
578 bool MarbleMap::propertyValue( const QString& name ) const
579 {
580  bool value;
581  if ( d->m_model->mapTheme() ) {
582  d->m_model->mapTheme()->settings()->propertyValue( name, value );
583  }
584  else {
585  value = false;
586  mDebug() << "WARNING: Failed to access a map theme! Property: " << name;
587  }
588  return value;
589 }
590 
592 {
593  return propertyValue(QStringLiteral("overviewmap"));
594 }
595 
597 {
598  return propertyValue(QStringLiteral("scalebar"));
599 }
600 
602 {
603  return propertyValue(QStringLiteral("compass"));
604 }
605 
607 {
608  return propertyValue(QStringLiteral("coordinate-grid"));
609 }
610 
612 {
613  return d->m_viewParams.showClouds();
614 }
615 
617 {
618  return d->m_textureLayer.showSunShading();
619 }
620 
622 {
623  return d->m_textureLayer.showCityLights();
624 }
625 
627 {
628  return d->m_isLockedToSubSolarPoint;
629 }
630 
632 {
633  return d->m_isSubSolarPointIconVisible;
634 }
635 
637 {
638  return d->m_viewParams.showAtmosphere();
639 }
640 
642 {
643  bool visible = false;
644 
645  QList<RenderPlugin *> pluginList = renderPlugins();
647  QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
648  for (; i != end; ++i ) {
649  if ((*i)->nameId() == QLatin1String("crosshairs")) {
650  visible = (*i)->visible();
651  }
652  }
653 
654  return visible;
655 }
656 
658 {
659  return propertyValue(QStringLiteral("places"));
660 }
661 
663 {
664  return propertyValue(QStringLiteral("cities"));
665 }
666 
668 {
669  return propertyValue(QStringLiteral("terrain"));
670 }
671 
673 {
674  return propertyValue(QStringLiteral("otherplaces"));
675 }
676 
678 {
679  return propertyValue(QStringLiteral("relief"));
680 }
681 
683 {
684  return propertyValue(QStringLiteral("ice"));
685 }
686 
688 {
689  return propertyValue(QStringLiteral("borders"));
690 }
691 
693 {
694  return propertyValue(QStringLiteral("rivers"));
695 }
696 
698 {
699  return propertyValue(QStringLiteral("lakes"));
700 }
701 
703 {
704  return d->m_showFrameRate;
705 }
706 
707 bool MarbleMap::showBackground() const
708 {
709  return d->m_layerManager.showBackground();
710 }
711 
712 GeoDataRelation::RelationTypes MarbleMap::visibleRelationTypes() const
713 {
714  return d->m_visibleRelationTypes;
715 }
716 
718 {
719  return d->m_textureLayer.volatileCacheLimit();
720 }
721 
722 
723 void MarbleMap::rotateBy(qreal deltaLon, qreal deltaLat)
724 {
725  centerOn( d->m_viewport.centerLongitude() * RAD2DEG + deltaLon,
726  d->m_viewport.centerLatitude() * RAD2DEG + deltaLat );
727 }
728 
729 
730 void MarbleMap::centerOn( const qreal lon, const qreal lat )
731 {
732  d->m_viewport.centerOn( lon * DEG2RAD, lat * DEG2RAD );
733 
734  emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
735 }
736 
738 {
739  centerOn( centerLongitude(), lat );
740 }
741 
743 {
744  centerOn( lon, centerLatitude() );
745 }
746 
748 {
749  return d->m_viewport.projection();
750 }
751 
753 {
754  if ( d->m_viewport.projection() == projection )
755  return;
756 
757  emit projectionChanged( projection );
758 
759  d->m_viewport.setProjection( projection );
760 
761  d->m_textureLayer.setProjection( projection );
762 
763  emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
764 }
765 
766 
767 bool MarbleMap::screenCoordinates( qreal lon, qreal lat,
768  qreal& x, qreal& y ) const
769 {
770  return d->m_viewport.screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, x, y );
771 }
772 
773 bool MarbleMap::geoCoordinates( int x, int y,
774  qreal& lon, qreal& lat,
775  GeoDataCoordinates::Unit unit ) const
776 {
777  return d->m_viewport.geoCoordinates( x, y, lon, lat, unit );
778 }
779 
780 void MarbleMapPrivate::setDocument( const QString& key )
781 {
782  if ( !m_model->mapTheme() ) {
783  // Happens if no valid map theme is set or at application startup
784  // if a file is passed via command line parameters and the last
785  // map theme has not been loaded yet
786  /**
787  * @todo Do we need to queue the document and process it once a map
788  * theme becomes available?
789  */
790  return;
791  }
792 
793  GeoDataDocument* doc = m_model->fileManager()->at( key );
794 
795  for ( const GeoSceneLayer *layer: m_model->mapTheme()->map()->layers() ) {
796  if ( layer->backend() != dgml::dgmlValue_geodata
797  && layer->backend() != dgml::dgmlValue_vector )
798  continue;
799 
800  // look for documents
801  for ( const GeoSceneAbstractDataset *dataset: layer->datasets() ) {
802  const GeoSceneGeodata *data = static_cast<const GeoSceneGeodata*>( dataset );
803  QString containername = data->sourceFile();
804  QString colorize = data->colorize();
805  if( key == containername ) {
806  if (colorize == QLatin1String("land")) {
807  m_textureLayer.addLandDocument( doc );
808  }
809  if (colorize == QLatin1String("sea")) {
810  m_textureLayer.addSeaDocument( doc );
811  }
812 
813  // set visibility according to theme property
814  if( !data->property().isEmpty() ) {
815  bool value;
816  m_model->mapTheme()->settings()->propertyValue( data->property(), value );
817  doc->setVisible( value );
818  m_model->treeModel()->updateFeature( doc );
819  }
820  }
821  }
822  }
823 }
824 
825 void MarbleMapPrivate::updateTileLevel()
826 {
827  auto const tileZoomLevel = q->tileZoomLevel();
828  m_geometryLayer.setTileLevel(tileZoomLevel);
829  m_placemarkLayer.setTileLevel(tileZoomLevel);
830  emit q->tileLevelChanged(tileZoomLevel);
831 }
832 
833 // Used to be paintEvent()
834 void MarbleMap::paint( GeoPainter &painter, const QRect &dirtyRect )
835 {
836  Q_UNUSED( dirtyRect );
837 
838  if (d->m_showDebugPolygons ) {
839  if (viewContext() == Animation) {
840  painter.setDebugPolygonsLevel(1);
841  }
842  else {
843  painter.setDebugPolygonsLevel(2);
844  }
845  }
846  painter.setDebugBatchRender(d->m_showDebugBatchRender);
847 
848  if ( !d->m_model->mapTheme() ) {
849  mDebug() << "No theme yet!";
850  d->m_marbleSplashLayer.render( &painter, &d->m_viewport );
851  return;
852  }
853 
854  QElapsedTimer t;
855  t.start();
856 
857  RenderStatus const oldRenderStatus = d->m_renderState.status();
858  d->m_layerManager.renderLayers( &painter, &d->m_viewport );
859  d->m_renderState = d->m_layerManager.renderState();
860  bool const parsing = d->m_model->fileManager()->pendingFiles() > 0;
861  d->m_renderState.addChild(RenderState(QStringLiteral("Files"), parsing ? WaitingForData : Complete));
862  RenderStatus const newRenderStatus = d->m_renderState.status();
863  if ( oldRenderStatus != newRenderStatus ) {
864  emit renderStatusChanged( newRenderStatus );
865  }
866  emit renderStateChanged( d->m_renderState );
867 
868  if ( d->m_showFrameRate ) {
869  FpsLayer fpsPainter( &t );
870  fpsPainter.paint( &painter );
871  }
872 
873  const qreal fps = 1000.0 / (qreal)( t.elapsed() );
874  emit framesPerSecond( fps );
875 }
876 
878 {
879  Q_UNUSED( painter );
880 }
881 
883 {
884  return d->m_model->mapThemeId();
885 }
886 
887 void MarbleMap::setMapThemeId( const QString& mapThemeId )
888 {
889  d->m_model->setMapThemeId( mapThemeId );
890 }
891 
892 void MarbleMapPrivate::updateMapTheme()
893 {
894  m_layerManager.removeLayer( &m_textureLayer );
895  // FIXME Find a better way to do this reset. Maybe connect to themeChanged SIGNAL?
896  m_vectorTileLayer.reset();
897  m_layerManager.removeLayer( &m_vectorTileLayer );
898  m_layerManager.removeLayer( &m_groundLayer );
899 
900  QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)),
901  q, SLOT(updateProperty(QString,bool)) );
902  QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)),
903  m_model, SLOT(updateProperty(QString,bool)) );
904 
905  q->setPropertyValue(QStringLiteral("clouds_data"), m_viewParams.showClouds());
906 
907  QColor backgroundColor = m_styleBuilder.effectColor(m_model->mapTheme()->map()->backgroundColor());
908  m_groundLayer.setColor(backgroundColor);
909 
910  // Check whether there is a texture layer and vectortile layer available:
911  if ( m_model->mapTheme()->map()->hasTextureLayers() ) {
912  const GeoSceneSettings *const settings = m_model->mapTheme()->settings();
913  const GeoSceneGroup *const textureLayerSettings = settings ? settings->group( "Texture Layers" ) : nullptr;
914  const GeoSceneGroup *const vectorTileLayerSettings = settings ? settings->group( "VectorTile Layers" ) : nullptr;
915 
916  bool textureLayersOk = true;
917  bool vectorTileLayersOk = true;
918 
919  // textures will contain texture layers and
920  // vectorTiles vectortile layers
923 
924  for( GeoSceneLayer* layer: m_model->mapTheme()->map()->layers() ){
925  if ( layer->backend() == dgml::dgmlValue_texture ){
926 
927  for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) {
928  const GeoSceneTextureTileDataset *const texture = dynamic_cast<GeoSceneTextureTileDataset const *>( pos );
929  if ( !texture )
930  continue;
931 
932  const QString sourceDir = texture->sourceDir();
933  const QString installMap = texture->installMap();
934  const QString role = layer->role();
935 
936  // If the tiles aren't already there, put up a progress dialog
937  // while creating them.
938  if ( !TileLoader::baseTilesAvailable( *texture )
939  && !installMap.isEmpty() )
940  {
941  mDebug() << "Base tiles not available. Creating Tiles ... \n"
942  << "SourceDir: " << sourceDir << "InstallMap:" << installMap;
943 
944  TileCreator *tileCreator = new TileCreator(
945  sourceDir,
946  installMap,
947  (role == QLatin1String("dem")) ? "true" : "false" );
948  tileCreator->setTileFormat( texture->fileFormat().toLower() );
949 
950  QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr );
951  tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(),
952  m_model->mapTheme()->head()->description() );
953  tileCreatorDlg->exec();
954  if ( TileLoader::baseTilesAvailable( *texture ) ) {
955  mDebug() << "Base tiles for" << sourceDir << "successfully created.";
956  } else {
957  qWarning() << "Some or all base tiles for" << sourceDir << "could not be created.";
958  }
959 
960  delete tileCreatorDlg;
961  }
962 
963  if ( TileLoader::baseTilesAvailable( *texture ) ) {
964  textures.append( texture );
965  } else {
966  qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers.";
967  textureLayersOk = false;
968  }
969  }
970  }
971  else if ( layer->backend() == dgml::dgmlValue_vectortile ){
972 
973  for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) {
974  const GeoSceneVectorTileDataset *const vectorTile = dynamic_cast<GeoSceneVectorTileDataset const *>( pos );
975  if ( !vectorTile )
976  continue;
977 
978  const QString sourceDir = vectorTile->sourceDir();
979  const QString installMap = vectorTile->installMap();
980  const QString role = layer->role();
981 
982  // If the tiles aren't already there, put up a progress dialog
983  // while creating them.
984  if ( !TileLoader::baseTilesAvailable( *vectorTile )
985  && !installMap.isEmpty() )
986  {
987  mDebug() << "Base tiles not available. Creating Tiles ... \n"
988  << "SourceDir: " << sourceDir << "InstallMap:" << installMap;
989 
990  TileCreator *tileCreator = new TileCreator(
991  sourceDir,
992  installMap,
993  (role == QLatin1String("dem")) ? "true" : "false" );
994  tileCreator->setTileFormat( vectorTile->fileFormat().toLower() );
995 
996  QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr );
997  tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(),
998  m_model->mapTheme()->head()->description() );
999  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();
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 
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 
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 
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 
1278 {
1279  qDebug() << Q_FUNC_INFO << 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 
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 
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 {
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 ) {
1384  return;
1385  } else if ( angleUnit == UTM ) {
1386  GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::UTM );
1387  return;
1388  }
1389 
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 
1405 {
1406  return d->m_renderPlugins;
1407 }
1408 
1409 QList<AbstractFloatItem *> MarbleMap::floatItems() const
1410 {
1411  return d->m_floatItemsLayer.floatItems();
1412 }
1413 
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 
1426 {
1427  return d->m_layerManager.dataPlugins();
1428 }
1429 
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 
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"
@ DecimalDegree
Degrees in decimal notation.
Definition: MarbleGlobal.h:59
ViewContext
This enum is used to choose context in which map quality gets used.
Definition: MarbleGlobal.h:66
bool geoCoordinates(int x, int y, qreal &lon, qreal &lat, GeoDataCoordinates::Unit=GeoDataCoordinates::Degree) const
Get the earth coordinates corresponding to a pixel in the map.
Definition: MarbleMap.cpp:773
QString addTextureLayer(GeoSceneTextureTileDataset *texture)
Adds a texture sublayer.
Definition: MarbleMap.cpp:1455
void setShowCityLights(bool visible)
Set whether city lights instead of night shadow are visible.
Definition: MarbleMap.cpp:1159
bool isEmpty() const const
The abstract class that creates a renderable item.
Definition: RenderPlugin.h:38
bool isLockedToSubSolarPoint() const
Return whether the globe is locked to the sub solar point.
Definition: MarbleMap.cpp:626
bool showRivers() const
Return whether the rivers are visible.
Definition: MarbleMap.cpp:692
MapQuality mapQuality() const
Return the current map quality.
Definition: MarbleMap.cpp:374
void setCenterLatitude(qreal lat)
Set the latitude for the center point.
Definition: MarbleMap.cpp:737
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
void notifyMouseClick(int x, int y)
used to notify about the position of the mouse click
Definition: MarbleMap.cpp:1344
void setShowSunShading(bool visible)
Set whether the night shadow is visible.
Definition: MarbleMap.cpp:1154
void removeLayer(LayerInterface *layer)
Remove a layer from being included in rendering.
Definition: MarbleMap.cpp:1440
void setShowClouds(bool visible)
Set whether the cloud cover is visible.
Definition: MarbleMap.cpp:1147
void setShowOtherPlaces(bool visible)
Set whether the other places overlay is visible.
Definition: MarbleMap.cpp:1216
Projection projection() const
Get the Projection used for the map.
Definition: MarbleMap.cpp:747
int count() const const
qreal centerLongitude() const
Return the longitude of the center point.
Definition: MarbleMap.cpp:480
void centerOn(const qreal lon, const qreal lat)
Center the view on a geographical point.
Definition: MarbleMap.cpp:730
void setVolatileTileCacheLimit(quint64 kiloBytes)
Set the limit of the volatile (in RAM) tile cache.
Definition: MarbleMap.cpp:1363
void setShowTerrain(bool visible)
Set whether the terrain place mark overlay is visible.
Definition: MarbleMap.cpp:1211
@ Animation
animated view (e.g. while rotating the globe)
Definition: MarbleGlobal.h:68
void append(const T &value)
void setLevelTagDebugModeEnabled(bool visible)
Set whether to enter the debug mode for level tags.
Definition: MarbleMap.cpp:1304
MarbleMap()
Construct a new MarbleMap.
Definition: MarbleMap.cpp:316
static GeoDataCoordinates::Notation defaultNotation()
return Notation of string representation
virtual void customPaint(GeoPainter *painter)
Enables custom drawing onto the MarbleMap straight after.
Definition: MarbleMap.cpp:877
void setShowGrid(bool visible)
Set whether the coordinate grid overlay is visible.
Definition: MarbleMap.cpp:1196
bool showCityLights() const
Return whether the city lights are shown instead of the night shadow.
Definition: MarbleMap.cpp:621
void setShowTileId(bool visible)
Set whether the is tile is visible NOTE: This is part of the transitional debug API and might be subj...
Definition: MarbleMap.cpp:1191
bool isSubSolarPointIconVisible() const
Return whether the sun icon is shown in the sub solar point.
Definition: MarbleMap.cpp:631
QList::const_iterator constBegin() const const
bool showFrameRate() const
Return whether the frame rate gets displayed.
Definition: MarbleMap.cpp:702
@ DMS
"Sexagesimal DMS" notation (base-60)
@ UTM
UTM.
Definition: MarbleGlobal.h:60
void setShowCrosshairs(bool visible)
Set whether the crosshairs are visible.
Definition: MarbleMap.cpp:1135
void rotateBy(qreal deltaLon, qreal deltaLat)
Rotate the view by the two angles phi and theta.
Definition: MarbleMap.cpp:723
The abstract class for float item plugins.
Layer of a GeoScene document.
Definition: GeoSceneLayer.h:28
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setShowDebugPlacemarks(bool visible)
Set whether to enter the debug mode for placemark drawing.
Definition: MarbleMap.cpp:1291
bool hasFeatureAt(const QPoint &) const
Definition: MarbleMap.cpp:475
void setShowLakes(bool visible)
Set whether the lakes are visible.
Definition: MarbleMap.cpp:1241
bool showAtmosphere() const
Return whether the atmospheric glow is visible.
Definition: MarbleMap.cpp:636
bool showGrid() const
Return whether the coordinate grid is visible.
Definition: MarbleMap.cpp:606
Group inside the settings of a GeoScene document.
Definition: GeoSceneGroup.h:25
bool showClouds() const
Return whether the cloud cover is visible.
Definition: MarbleMap.cpp:611
QList< RenderPlugin * > renderPlugins() const
Returns a list of all RenderPlugins in the model, this includes float items.
Definition: MarbleMap.cpp:1404
QList< AbstractDataPluginItem * > whichItemAt(const QPoint &curpos) const
Returns all widgets of dataPlugins on the position curpos.
Definition: MarbleMap.cpp:1430
A public class that controls what is visible in the viewport of a Marble map.
bool showTerrain() const
Return whether the terrain place marks are visible.
Definition: MarbleMap.cpp:667
int radius() const
Return the radius of the globe in pixels.
Definition: MarbleMap.cpp:430
bool screenCoordinates(qreal lon, qreal lat, qreal &x, qreal &y) const
Get the screen coordinates corresponding to geographical coordinates in the map.
Definition: MarbleMap.cpp:767
bool showCompass() const
Return whether the compass bar is visible.
Definition: MarbleMap.cpp:601
const StyleBuilder * styleBuilder() const
Definition: MarbleMap.cpp:1476
bool showLakes() const
Return whether the lakes are visible.
Definition: MarbleMap.cpp:697
void visibleLatLonAltBoxChanged(const GeoDataLatLonAltBox &visibleLatLonAltBox)
This signal is emitted when the visible region of the map changes.
void getCoords(int *x1, int *y1, int *x2, int *y2) const const
bool isEmpty() const const
@ Decimal
"Decimal" notation (base-10)
void setShowIceLayer(bool visible)
Set whether the ice layer is visible.
Definition: MarbleMap.cpp:1226
void removeTextureLayer(const QString &key)
Removes a texture sublayer.
Definition: MarbleMap.cpp:1460
QString mapThemeId() const
Get the ID of the current map theme To ensure that a unique identifier is being used the theme does N...
Definition: MarbleMap.cpp:882
MapQuality
This enum is used to choose the map quality shown in the view.
Definition: MarbleGlobal.h:74
void renderStatusChanged(RenderStatus status)
Emitted when the layer rendering status has changed.
void setShowPlaces(bool visible)
Set whether the place mark overlay is visible.
Definition: MarbleMap.cpp:1201
QFuture< void > filter(Sequence &sequence, KeepFunctor filterFunction)
void setPropertyValue(const QString &name, bool value)
Sets the value of a map theme property.
Definition: MarbleMap.cpp:1090
bool showCities() const
Return whether the city place marks are visible.
Definition: MarbleMap.cpp:662
Binds a QML item to a specific geodetic location in screen coordinates.
@ DMSDegree
Degrees in DMS notation.
Definition: MarbleGlobal.h:58
void setRadius(int radius)
Set the radius of the globe in pixels.
Definition: MarbleMap.cpp:435
static void setDefaultNotation(GeoDataCoordinates::Notation notation)
set the Notation of the string representation
Contents used inside a layer.
AbstractFloatItem * floatItem(const QString &nameId) const
Returns a list of all FloatItems in the model.
Definition: MarbleMap.cpp:1414
qint64 elapsed() const const
bool showPlaces() const
Return whether the place marks are visible.
Definition: MarbleMap.cpp:657
Settings of a GeoScene document.
A painter that allows to draw geometric primitives on the map.
Definition: GeoPainter.h:88
bool showCrosshairs() const
Return whether the crosshairs are visible.
Definition: MarbleMap.cpp:641
void setShowAtmosphere(bool visible)
Set whether the atmospheric glow is visible.
Definition: MarbleMap.cpp:1124
bool propertyValue(const QString &name) const
Return the property value by name.
Definition: MarbleMap.cpp:578
void setShowScaleBar(bool visible)
Set whether the scale bar overlay is visible.
Definition: MarbleMap.cpp:1114
void setShowRivers(bool visible)
Set whether the rivers are visible.
Definition: MarbleMap.cpp:1236
Projection
This enum is used to choose the projection shown in the view.
Definition: MarbleGlobal.h:41
void setLockToSubSolarPoint(bool visible)
Set the globe locked to the sub solar point.
Definition: MarbleMap.cpp:1165
@ Complete
All data is there and up to date.
Definition: MarbleGlobal.h:181
AngleUnit
This enum is used to choose the unit chosen to measure angles.
Definition: MarbleGlobal.h:57
void addLayer(LayerInterface *layer)
Add a layer to be included in rendering.
Definition: MarbleMap.cpp:1435
void setShowCities(bool visible)
Set whether the city place mark overlay is visible.
Definition: MarbleMap.cpp:1206
void setShowFrameRate(bool visible)
Set whether the frame rate gets shown.
Definition: MarbleMap.cpp:1246
void setProjection(Projection projection)
Set the Projection used for the map.
Definition: MarbleMap.cpp:752
QList::const_iterator constEnd() const const
void setCenterLongitude(qreal lon)
Set the longitude for the center point.
Definition: MarbleMap.cpp:742
void repaintNeeded(const QRegion &dirtyRegion=QRegion())
This signal is emitted when the repaint of the view was requested.
int minimumZoom() const
return the minimum zoom value for the current map theme.
Definition: MarbleMap.cpp:488
Unit
enum used constructor to specify the units used
qreal centerLatitude() const
Return the latitude of the center point.
Definition: MarbleMap.cpp:467
bool showScaleBar() const
Return whether the scale bar is visible.
Definition: MarbleMap.cpp:596
void setShowDebugBatchRender(bool visible)
Set whether to enter the debug mode for visualizing batch rendering.
Definition: MarbleMap.cpp:1277
bool showSunShading() const
Return whether the night shadow is visible.
Definition: MarbleMap.cpp:616
void reload()
Reload the currently displayed map by reloading texture tiles from the Internet.
Definition: MarbleMap.cpp:517
void setShowBorders(bool visible)
Set whether the borders visible.
Definition: MarbleMap.cpp:1231
MarbleModel * model() const
Return the model that this view shows.
Definition: MarbleMap.cpp:345
QList< AbstractDataPlugin * > dataPlugins() const
Returns a list of all DataPlugins on the layer.
Definition: MarbleMap.cpp:1425
void setShowOverviewMap(bool visible)
Set whether the overview map overlay is visible.
Definition: MarbleMap.cpp:1109
@ WaitingForData
Rendering is based on no or partial data, more data was requested (e.g. pending network queries)
Definition: MarbleGlobal.h:183
QSet::iterator insert(const T &value)
int size() const const
quint64 volatileTileCacheLimit() const
Returns the limit in kilobytes of the volatile (in RAM) tile cache.
Definition: MarbleMap.cpp:717
void paint(GeoPainter &painter, const QRect &dirtyRect)
Paint the map using a give painter.
Definition: MarbleMap.cpp:834
void setShowRelief(bool visible)
Set whether the relief is visible.
Definition: MarbleMap.cpp:1221
bool showOverviewMap() const
Return whether the overview map is visible.
Definition: MarbleMap.cpp:591
void setSubSolarPointIconVisible(bool visible)
Set whether the sun icon is shown in the sub solar point.
Definition: MarbleMap.cpp:1184
void setShowCompass(bool visible)
Set whether the compass overlay is visible.
Definition: MarbleMap.cpp:1119
bool showRelief() const
Return whether the relief is visible.
Definition: MarbleMap.cpp:677
void setShowDebugPolygons(bool visible)
Set whether to enter the debug mode for polygon node drawing.
Definition: MarbleMap.cpp:1264
int maximumZoom() const
return the minimum zoom value for the current map theme.
Definition: MarbleMap.cpp:496
bool showOtherPlaces() const
Return whether other places are visible.
Definition: MarbleMap.cpp:672
QFuture< void > map(Sequence &sequence, MapFunctor function)
const GeoSceneGroup * group(const QString &name) const
Get a group from the settings.
bool showBorders() const
Return whether the borders are visible.
Definition: MarbleMap.cpp:687
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:86
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
bool showIceLayer() const
Return whether the ice layer is visible.
Definition: MarbleMap.cpp:682
void setMapThemeId(const QString &maptheme)
Set a new map theme.
Definition: MarbleMap.cpp:887
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Oct 3 2023 04:09:48 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.