1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2006-2009 Torsten Rahn <tackat@kde.org>
4 // SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
5 // SPDX-FileCopyrightText: 2008 Carlos Licea <carlos.licea@kdemail.net>
6 // SPDX-FileCopyrightText: 2009 Jens-Michael Hoffmann <jensmh@gmx.de>
7 // SPDX-FileCopyrightText: 2010-2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
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:
CustomPaintLayer(MarbleMap * map)79 explicit CustomPaintLayer( MarbleMap *map )
80 : m_map( map )
81 {
82 }
83
renderPosition() const84 QStringList renderPosition() const override { return QStringList() << "USER_TOOLS"; }
85
render(GeoPainter * painter,ViewportParams * viewport,const QString & renderPos,GeoSceneLayer * layer)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
zValue() const98 qreal zValue() const override { return 1.0e6; }
99
renderState() const100 RenderState renderState() const override { return RenderState(QStringLiteral("Custom Map Paint")); }
101
runtimeTrace() const102 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
MarbleMapPrivate(MarbleMap * parent,MarbleModel * model)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
updateProperty(const QString & name,bool show)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
addPlugins()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
MarbleMap()316 MarbleMap::MarbleMap()
317 : d( new MarbleMapPrivate( this, new MarbleModel( this ) ) )
318 {
319 // nothing to do
320 }
321
MarbleMap(MarbleModel * model)322 MarbleMap::MarbleMap(MarbleModel *model)
323 : d( new MarbleMapPrivate( this, model ) )
324 {
325 d->m_modelIsOwned = false;
326 }
327
~MarbleMap()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
model() const345 MarbleModel *MarbleMap::model() const
346 {
347 return d->m_model;
348 }
349
viewport()350 ViewportParams *MarbleMap::viewport()
351 {
352 return &d->m_viewport;
353 }
354
viewport() const355 const ViewportParams *MarbleMap::viewport() const
356 {
357 return &d->m_viewport;
358 }
359
360
setMapQualityForViewContext(MapQuality quality,ViewContext viewContext)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
mapQuality(ViewContext viewContext) const369 MapQuality MarbleMap::mapQuality( ViewContext viewContext ) const
370 {
371 return d->m_viewParams.mapQuality( viewContext );
372 }
373
mapQuality() const374 MapQuality MarbleMap::mapQuality() const
375 {
376 return d->m_viewParams.mapQuality();
377 }
378
setViewContext(ViewContext viewContext)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
viewContext() const397 ViewContext MarbleMap::viewContext() const
398 {
399 return d->m_viewParams.viewContext();
400 }
401
402
setSize(int width,int height)403 void MarbleMap::setSize( int width, int height )
404 {
405 setSize( QSize( width, height ) );
406 }
407
setSize(const QSize & size)408 void MarbleMap::setSize( const QSize& size )
409 {
410 d->m_viewport.setSize( size );
411
412 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
413 }
414
size() const415 QSize MarbleMap::size() const
416 {
417 return QSize( d->m_viewport.width(), d->m_viewport.height() );
418 }
419
width() const420 int MarbleMap::width() const
421 {
422 return d->m_viewport.width();
423 }
424
height() const425 int MarbleMap::height() const
426 {
427 return d->m_viewport.height();
428 }
429
radius() const430 int MarbleMap::radius() const
431 {
432 return d->m_viewport.radius();
433 }
434
setRadius(int radius)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
preferredRadiusCeil(int radius) const448 int MarbleMap::preferredRadiusCeil(int radius) const
449 {
450 return d->m_textureLayer.preferredRadiusCeil( radius );
451 }
452
453
preferredRadiusFloor(int radius) const454 int MarbleMap::preferredRadiusFloor(int radius) const
455 {
456 return d->m_textureLayer.preferredRadiusFloor( radius );
457 }
458
459
tileZoomLevel() const460 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
centerLatitude() const467 qreal MarbleMap::centerLatitude() const
468 {
469 // Calculate translation of center point
470 const qreal centerLat = d->m_viewport.centerLatitude();
471
472 return centerLat * RAD2DEG;
473 }
474
hasFeatureAt(const QPoint & position) const475 bool MarbleMap::hasFeatureAt(const QPoint &position) const
476 {
477 return d->m_placemarkLayer.hasPlacemarkAt(position) || d->m_geometryLayer.hasFeatureAt(position, viewport());
478 }
479
centerLongitude() const480 qreal MarbleMap::centerLongitude() const
481 {
482 // Calculate translation of center point
483 const qreal centerLon = d->m_viewport.centerLongitude();
484
485 return centerLon * RAD2DEG;
486 }
487
minimumZoom() const488 int MarbleMap::minimumZoom() const
489 {
490 if ( d->m_model->mapTheme() )
491 return d->m_model->mapTheme()->head()->zoom()->minimum();
492
493 return 950;
494 }
495
maximumZoom() const496 int MarbleMap::maximumZoom() const
497 {
498 if ( d->m_model->mapTheme() )
499 return d->m_model->mapTheme()->head()->zoom()->maximum();
500
501 return 2100;
502 }
503
discreteZoom() const504 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
whichFeatureAt(const QPoint & curpos) const512 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
reload()517 void MarbleMap::reload()
518 {
519 d->m_textureLayer.reload();
520 d->m_vectorTileLayer.reload();
521 }
522
downloadRegion(QVector<TileCoordsPyramid> const & pyramid)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 }
563 tilesCount += tileIdSet.count();
564 }
565 // Needed for downloading unique tiles only. Much faster than if tiles for each level is downloaded separately
566
567 int const elapsedMs = t.elapsed();
568 mDebug() << "MarbleMap::downloadRegion:" << tilesCount << "tiles, " << elapsedMs << "ms";
569 }
570
highlightRouteRelation(qint64 osmId,bool enabled)571 void MarbleMap::highlightRouteRelation(qint64 osmId, bool enabled)
572 {
573 d->m_geometryLayer.highlightRouteRelation(osmId, enabled);
574 }
575
propertyValue(const QString & name) const576 bool MarbleMap::propertyValue( const QString& name ) const
577 {
578 bool value;
579 if ( d->m_model->mapTheme() ) {
580 d->m_model->mapTheme()->settings()->propertyValue( name, value );
581 }
582 else {
583 value = false;
584 mDebug() << "WARNING: Failed to access a map theme! Property: " << name;
585 }
586 return value;
587 }
588
showOverviewMap() const589 bool MarbleMap::showOverviewMap() const
590 {
591 return propertyValue(QStringLiteral("overviewmap"));
592 }
593
showScaleBar() const594 bool MarbleMap::showScaleBar() const
595 {
596 return propertyValue(QStringLiteral("scalebar"));
597 }
598
showCompass() const599 bool MarbleMap::showCompass() const
600 {
601 return propertyValue(QStringLiteral("compass"));
602 }
603
showGrid() const604 bool MarbleMap::showGrid() const
605 {
606 return propertyValue(QStringLiteral("coordinate-grid"));
607 }
608
showClouds() const609 bool MarbleMap::showClouds() const
610 {
611 return d->m_viewParams.showClouds();
612 }
613
showSunShading() const614 bool MarbleMap::showSunShading() const
615 {
616 return d->m_textureLayer.showSunShading();
617 }
618
showCityLights() const619 bool MarbleMap::showCityLights() const
620 {
621 return d->m_textureLayer.showCityLights();
622 }
623
isLockedToSubSolarPoint() const624 bool MarbleMap::isLockedToSubSolarPoint() const
625 {
626 return d->m_isLockedToSubSolarPoint;
627 }
628
isSubSolarPointIconVisible() const629 bool MarbleMap::isSubSolarPointIconVisible() const
630 {
631 return d->m_isSubSolarPointIconVisible;
632 }
633
showAtmosphere() const634 bool MarbleMap::showAtmosphere() const
635 {
636 return d->m_viewParams.showAtmosphere();
637 }
638
showCrosshairs() const639 bool MarbleMap::showCrosshairs() const
640 {
641 bool visible = false;
642
643 QList<RenderPlugin *> pluginList = renderPlugins();
644 QList<RenderPlugin *>::const_iterator i = pluginList.constBegin();
645 QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
646 for (; i != end; ++i ) {
647 if ((*i)->nameId() == QLatin1String("crosshairs")) {
648 visible = (*i)->visible();
649 }
650 }
651
652 return visible;
653 }
654
showPlaces() const655 bool MarbleMap::showPlaces() const
656 {
657 return propertyValue(QStringLiteral("places"));
658 }
659
showCities() const660 bool MarbleMap::showCities() const
661 {
662 return propertyValue(QStringLiteral("cities"));
663 }
664
showTerrain() const665 bool MarbleMap::showTerrain() const
666 {
667 return propertyValue(QStringLiteral("terrain"));
668 }
669
showOtherPlaces() const670 bool MarbleMap::showOtherPlaces() const
671 {
672 return propertyValue(QStringLiteral("otherplaces"));
673 }
674
showRelief() const675 bool MarbleMap::showRelief() const
676 {
677 return propertyValue(QStringLiteral("relief"));
678 }
679
showIceLayer() const680 bool MarbleMap::showIceLayer() const
681 {
682 return propertyValue(QStringLiteral("ice"));
683 }
684
showBorders() const685 bool MarbleMap::showBorders() const
686 {
687 return propertyValue(QStringLiteral("borders"));
688 }
689
showRivers() const690 bool MarbleMap::showRivers() const
691 {
692 return propertyValue(QStringLiteral("rivers"));
693 }
694
showLakes() const695 bool MarbleMap::showLakes() const
696 {
697 return propertyValue(QStringLiteral("lakes"));
698 }
699
showFrameRate() const700 bool MarbleMap::showFrameRate() const
701 {
702 return d->m_showFrameRate;
703 }
704
showBackground() const705 bool MarbleMap::showBackground() const
706 {
707 return d->m_layerManager.showBackground();
708 }
709
visibleRelationTypes() const710 GeoDataRelation::RelationTypes MarbleMap::visibleRelationTypes() const
711 {
712 return d->m_visibleRelationTypes;
713 }
714
volatileTileCacheLimit() const715 quint64 MarbleMap::volatileTileCacheLimit() const
716 {
717 return d->m_textureLayer.volatileCacheLimit();
718 }
719
720
rotateBy(qreal deltaLon,qreal deltaLat)721 void MarbleMap::rotateBy(qreal deltaLon, qreal deltaLat)
722 {
723 centerOn( d->m_viewport.centerLongitude() * RAD2DEG + deltaLon,
724 d->m_viewport.centerLatitude() * RAD2DEG + deltaLat );
725 }
726
727
centerOn(const qreal lon,const qreal lat)728 void MarbleMap::centerOn( const qreal lon, const qreal lat )
729 {
730 d->m_viewport.centerOn( lon * DEG2RAD, lat * DEG2RAD );
731
732 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
733 }
734
setCenterLatitude(qreal lat)735 void MarbleMap::setCenterLatitude( qreal lat )
736 {
737 centerOn( centerLongitude(), lat );
738 }
739
setCenterLongitude(qreal lon)740 void MarbleMap::setCenterLongitude( qreal lon )
741 {
742 centerOn( lon, centerLatitude() );
743 }
744
projection() const745 Projection MarbleMap::projection() const
746 {
747 return d->m_viewport.projection();
748 }
749
setProjection(Projection projection)750 void MarbleMap::setProjection( Projection projection )
751 {
752 if ( d->m_viewport.projection() == projection )
753 return;
754
755 emit projectionChanged( projection );
756
757 d->m_viewport.setProjection( projection );
758
759 d->m_textureLayer.setProjection( projection );
760
761 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
762 }
763
764
screenCoordinates(qreal lon,qreal lat,qreal & x,qreal & y) const765 bool MarbleMap::screenCoordinates( qreal lon, qreal lat,
766 qreal& x, qreal& y ) const
767 {
768 return d->m_viewport.screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, x, y );
769 }
770
geoCoordinates(int x,int y,qreal & lon,qreal & lat,GeoDataCoordinates::Unit unit) const771 bool MarbleMap::geoCoordinates( int x, int y,
772 qreal& lon, qreal& lat,
773 GeoDataCoordinates::Unit unit ) const
774 {
775 return d->m_viewport.geoCoordinates( x, y, lon, lat, unit );
776 }
777
setDocument(const QString & key)778 void MarbleMapPrivate::setDocument( const QString& key )
779 {
780 if ( !m_model->mapTheme() ) {
781 // Happens if no valid map theme is set or at application startup
782 // if a file is passed via command line parameters and the last
783 // map theme has not been loaded yet
784 /**
785 * @todo Do we need to queue the document and process it once a map
786 * theme becomes available?
787 */
788 return;
789 }
790
791 GeoDataDocument* doc = m_model->fileManager()->at( key );
792
793 for ( const GeoSceneLayer *layer: m_model->mapTheme()->map()->layers() ) {
794 if ( layer->backend() != dgml::dgmlValue_geodata
795 && layer->backend() != dgml::dgmlValue_vector )
796 continue;
797
798 // look for documents
799 for ( const GeoSceneAbstractDataset *dataset: layer->datasets() ) {
800 const GeoSceneGeodata *data = static_cast<const GeoSceneGeodata*>( dataset );
801 QString containername = data->sourceFile();
802 QString colorize = data->colorize();
803 if( key == containername ) {
804 if (colorize == QLatin1String("land")) {
805 m_textureLayer.addLandDocument( doc );
806 }
807 if (colorize == QLatin1String("sea")) {
808 m_textureLayer.addSeaDocument( doc );
809 }
810
811 // set visibility according to theme property
812 if( !data->property().isEmpty() ) {
813 bool value;
814 m_model->mapTheme()->settings()->propertyValue( data->property(), value );
815 doc->setVisible( value );
816 m_model->treeModel()->updateFeature( doc );
817 }
818 }
819 }
820 }
821 }
822
updateTileLevel()823 void MarbleMapPrivate::updateTileLevel()
824 {
825 auto const tileZoomLevel = q->tileZoomLevel();
826 m_geometryLayer.setTileLevel(tileZoomLevel);
827 m_placemarkLayer.setTileLevel(tileZoomLevel);
828 emit q->tileLevelChanged(tileZoomLevel);
829 }
830
831 // Used to be paintEvent()
paint(GeoPainter & painter,const QRect & dirtyRect)832 void MarbleMap::paint( GeoPainter &painter, const QRect &dirtyRect )
833 {
834 Q_UNUSED( dirtyRect );
835
836 if (d->m_showDebugPolygons ) {
837 if (viewContext() == Animation) {
838 painter.setDebugPolygonsLevel(1);
839 }
840 else {
841 painter.setDebugPolygonsLevel(2);
842 }
843 }
844 painter.setDebugBatchRender(d->m_showDebugBatchRender);
845
846 if ( !d->m_model->mapTheme() ) {
847 mDebug() << "No theme yet!";
848 d->m_marbleSplashLayer.render( &painter, &d->m_viewport );
849 return;
850 }
851
852 QElapsedTimer t;
853 t.start();
854
855 RenderStatus const oldRenderStatus = d->m_renderState.status();
856 d->m_layerManager.renderLayers( &painter, &d->m_viewport );
857 d->m_renderState = d->m_layerManager.renderState();
858 bool const parsing = d->m_model->fileManager()->pendingFiles() > 0;
859 d->m_renderState.addChild(RenderState(QStringLiteral("Files"), parsing ? WaitingForData : Complete));
860 RenderStatus const newRenderStatus = d->m_renderState.status();
861 if ( oldRenderStatus != newRenderStatus ) {
862 emit renderStatusChanged( newRenderStatus );
863 }
864 emit renderStateChanged( d->m_renderState );
865
866 if ( d->m_showFrameRate ) {
867 FpsLayer fpsPainter( &t );
868 fpsPainter.paint( &painter );
869 }
870
871 const qreal fps = 1000.0 / (qreal)( t.elapsed() );
872 emit framesPerSecond( fps );
873 }
874
customPaint(GeoPainter * painter)875 void MarbleMap::customPaint( GeoPainter *painter )
876 {
877 Q_UNUSED( painter );
878 }
879
mapThemeId() const880 QString MarbleMap::mapThemeId() const
881 {
882 return d->m_model->mapThemeId();
883 }
884
setMapThemeId(const QString & mapThemeId)885 void MarbleMap::setMapThemeId( const QString& mapThemeId )
886 {
887 d->m_model->setMapThemeId( mapThemeId );
888 }
889
updateMapTheme()890 void MarbleMapPrivate::updateMapTheme()
891 {
892 m_layerManager.removeLayer( &m_textureLayer );
893 // FIXME Find a better way to do this reset. Maybe connect to themeChanged SIGNAL?
894 m_vectorTileLayer.reset();
895 m_layerManager.removeLayer( &m_vectorTileLayer );
896 m_layerManager.removeLayer( &m_groundLayer );
897
898 QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)),
899 q, SLOT(updateProperty(QString,bool)) );
900 QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)),
901 m_model, SLOT(updateProperty(QString,bool)) );
902
903 q->setPropertyValue(QStringLiteral("clouds_data"), m_viewParams.showClouds());
904 m_groundLayer.setColor( m_model->mapTheme()->map()->backgroundColor() );
905
906 // Check whether there is a texture layer and vectortile layer available:
907 if ( m_model->mapTheme()->map()->hasTextureLayers() ) {
908 const GeoSceneSettings *const settings = m_model->mapTheme()->settings();
909 const GeoSceneGroup *const textureLayerSettings = settings ? settings->group( "Texture Layers" ) : nullptr;
910 const GeoSceneGroup *const vectorTileLayerSettings = settings ? settings->group( "VectorTile Layers" ) : nullptr;
911
912 bool textureLayersOk = true;
913 bool vectorTileLayersOk = true;
914
915 // textures will contain texture layers and
916 // vectorTiles vectortile layers
917 QVector<const GeoSceneTextureTileDataset *> textures;
918 QVector<const GeoSceneVectorTileDataset *> vectorTiles;
919
920 for( GeoSceneLayer* layer: m_model->mapTheme()->map()->layers() ){
921 if ( layer->backend() == dgml::dgmlValue_texture ){
922
923 for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) {
924 const GeoSceneTextureTileDataset *const texture = dynamic_cast<GeoSceneTextureTileDataset const *>( pos );
925 if ( !texture )
926 continue;
927
928 const QString sourceDir = texture->sourceDir();
929 const QString installMap = texture->installMap();
930 const QString role = layer->role();
931
932 // If the tiles aren't already there, put up a progress dialog
933 // while creating them.
934 if ( !TileLoader::baseTilesAvailable( *texture )
935 && !installMap.isEmpty() )
936 {
937 mDebug() << "Base tiles not available. Creating Tiles ... \n"
938 << "SourceDir: " << sourceDir << "InstallMap:" << installMap;
939
940 TileCreator *tileCreator = new TileCreator(
941 sourceDir,
942 installMap,
943 (role == QLatin1String("dem")) ? "true" : "false" );
944 tileCreator->setTileFormat( texture->fileFormat().toLower() );
945
946 QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr );
947 tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(),
948 m_model->mapTheme()->head()->description() );
949 tileCreatorDlg->exec();
950 if ( TileLoader::baseTilesAvailable( *texture ) ) {
951 mDebug() << "Base tiles for" << sourceDir << "successfully created.";
952 } else {
953 qWarning() << "Some or all base tiles for" << sourceDir << "could not be created.";
954 }
955
956 delete tileCreatorDlg;
957 }
958
959 if ( TileLoader::baseTilesAvailable( *texture ) ) {
960 textures.append( texture );
961 } else {
962 qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers.";
963 textureLayersOk = false;
964 }
965 }
966 }
967 else if ( layer->backend() == dgml::dgmlValue_vectortile ){
968
969 for ( const GeoSceneAbstractDataset *pos: layer->datasets() ) {
970 const GeoSceneVectorTileDataset *const vectorTile = dynamic_cast<GeoSceneVectorTileDataset const *>( pos );
971 if ( !vectorTile )
972 continue;
973
974 const QString sourceDir = vectorTile->sourceDir();
975 const QString installMap = vectorTile->installMap();
976 const QString role = layer->role();
977
978 // If the tiles aren't already there, put up a progress dialog
979 // while creating them.
980 if ( !TileLoader::baseTilesAvailable( *vectorTile )
981 && !installMap.isEmpty() )
982 {
983 mDebug() << "Base tiles not available. Creating Tiles ... \n"
984 << "SourceDir: " << sourceDir << "InstallMap:" << installMap;
985
986 TileCreator *tileCreator = new TileCreator(
987 sourceDir,
988 installMap,
989 (role == QLatin1String("dem")) ? "true" : "false" );
990 tileCreator->setTileFormat( vectorTile->fileFormat().toLower() );
991
992 QPointer<TileCreatorDialog> tileCreatorDlg = new TileCreatorDialog( tileCreator, nullptr );
993 tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(),
994 m_model->mapTheme()->head()->description() );
995 tileCreatorDlg->exec();
996 if ( TileLoader::baseTilesAvailable( *vectorTile ) ) {
997 qDebug() << "Base tiles for" << sourceDir << "successfully created.";
998 } else {
999 qDebug() << "Some or all base tiles for" << sourceDir << "could not be created.";
1000 }
1001
1002 delete tileCreatorDlg;
1003 }
1004
1005 if ( TileLoader::baseTilesAvailable( *vectorTile ) ) {
1006 vectorTiles.append( vectorTile );
1007 } else {
1008 qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers.";
1009 vectorTileLayersOk = false;
1010 }
1011 }
1012 }
1013 }
1014
1015 QString seafile, landfile;
1016 if( !m_model->mapTheme()->map()->filters().isEmpty() ) {
1017 const GeoSceneFilter *filter= m_model->mapTheme()->map()->filters().first();
1018
1019 if (filter->type() == QLatin1String("colorize")) {
1020 //no need to look up with MarbleDirs twice so they are left null for now
1021 QList<const GeoScenePalette*> palette = filter->palette();
1022 for (const GeoScenePalette *curPalette: palette ) {
1023
1024 if (curPalette->type() == QLatin1String("sea")) {
1025 seafile = MarbleDirs::path( curPalette->file() );
1026 } else if (curPalette->type() == QLatin1String("land")) {
1027 landfile = MarbleDirs::path( curPalette->file() );
1028 }
1029 }
1030 //look up locations if they are empty
1031 if( seafile.isEmpty() )
1032 seafile = MarbleDirs::path(QStringLiteral("seacolors.leg"));
1033 if( landfile.isEmpty() )
1034 landfile = MarbleDirs::path(QStringLiteral("landcolors.leg"));
1035 }
1036 }
1037
1038 m_textureLayer.setMapTheme( textures, textureLayerSettings, seafile, landfile );
1039 m_textureLayer.setProjection( m_viewport.projection() );
1040 m_textureLayer.setShowRelief( q->showRelief() );
1041
1042 m_vectorTileLayer.setMapTheme( vectorTiles, vectorTileLayerSettings );
1043
1044 if (m_textureLayer.textureLayerCount() == 0) {
1045 m_layerManager.addLayer( &m_groundLayer );
1046 }
1047
1048 if ( textureLayersOk )
1049 m_layerManager.addLayer( &m_textureLayer );
1050 if ( vectorTileLayersOk && !vectorTiles.isEmpty() )
1051 m_layerManager.addLayer( &m_vectorTileLayer );
1052 }
1053 else {
1054 m_layerManager.addLayer( &m_groundLayer );
1055 m_textureLayer.setMapTheme( QVector<const GeoSceneTextureTileDataset *>(), nullptr, "", "" );
1056 m_vectorTileLayer.setMapTheme( QVector<const GeoSceneVectorTileDataset *>(), nullptr );
1057 }
1058
1059 // earth
1060 m_placemarkLayer.setShowPlaces( q->showPlaces() );
1061
1062 m_placemarkLayer.setShowCities( q->showCities() );
1063 m_placemarkLayer.setShowTerrain( q->showTerrain() );
1064 m_placemarkLayer.setShowOtherPlaces( q->showOtherPlaces() );
1065 m_placemarkLayer.setShowLandingSites(q->propertyValue(QStringLiteral("landingsites")));
1066 m_placemarkLayer.setShowCraters(q->propertyValue(QStringLiteral("craters")));
1067 m_placemarkLayer.setShowMaria(q->propertyValue(QStringLiteral("maria")));
1068
1069 m_styleBuilder.setDefaultLabelColor(m_model->mapTheme()->map()->labelColor());
1070 m_placemarkLayer.requestStyleReset();
1071
1072 for (RenderPlugin *renderPlugin: m_renderPlugins) {
1073 bool propertyAvailable = false;
1074 m_model->mapTheme()->settings()->propertyAvailable( renderPlugin->nameId(), propertyAvailable );
1075 bool propertyValue = false;
1076 m_model->mapTheme()->settings()->propertyValue( renderPlugin->nameId(), propertyValue );
1077
1078 if ( propertyAvailable ) {
1079 renderPlugin->setVisible( propertyValue );
1080 }
1081 }
1082
1083 emit q->themeChanged( m_model->mapTheme()->head()->mapThemeId() );
1084 }
1085
setPropertyValue(const QString & name,bool value)1086 void MarbleMap::setPropertyValue( const QString& name, bool value )
1087 {
1088 mDebug() << "In MarbleMap the property " << name << "was set to " << value;
1089 if ( d->m_model->mapTheme() ) {
1090 d->m_model->mapTheme()->settings()->setPropertyValue( name, value );
1091 d->m_textureLayer.setNeedsUpdate();
1092 }
1093 else {
1094 mDebug() << "WARNING: Failed to access a map theme! Property: " << name;
1095 }
1096 if (d->m_textureLayer.textureLayerCount() == 0) {
1097 d->m_layerManager.addLayer( &d->m_groundLayer );
1098 }
1099 else {
1100 d->m_layerManager.removeLayer( &d->m_groundLayer );
1101 }
1102 }
1103
setShowOverviewMap(bool visible)1104 void MarbleMap::setShowOverviewMap( bool visible )
1105 {
1106 setPropertyValue(QStringLiteral("overviewmap"), visible);
1107 }
1108
setShowScaleBar(bool visible)1109 void MarbleMap::setShowScaleBar( bool visible )
1110 {
1111 setPropertyValue(QStringLiteral("scalebar"), visible);
1112 }
1113
setShowCompass(bool visible)1114 void MarbleMap::setShowCompass( bool visible )
1115 {
1116 setPropertyValue(QStringLiteral("compass"), visible);
1117 }
1118
setShowAtmosphere(bool visible)1119 void MarbleMap::setShowAtmosphere( bool visible )
1120 {
1121 for ( RenderPlugin *plugin: renderPlugins() ) {
1122 if (plugin->nameId() == QLatin1String("atmosphere")) {
1123 plugin->setVisible( visible );
1124 }
1125 }
1126
1127 d->m_viewParams.setShowAtmosphere( visible );
1128 }
1129
setShowCrosshairs(bool visible)1130 void MarbleMap::setShowCrosshairs( bool visible )
1131 {
1132 QList<RenderPlugin *> pluginList = renderPlugins();
1133 QList<RenderPlugin *>::const_iterator i = pluginList.constBegin();
1134 QList<RenderPlugin *>::const_iterator const end = pluginList.constEnd();
1135 for (; i != end; ++i ) {
1136 if ((*i)->nameId() == QLatin1String("crosshairs")) {
1137 (*i)->setVisible( visible );
1138 }
1139 }
1140 }
1141
setShowClouds(bool visible)1142 void MarbleMap::setShowClouds( bool visible )
1143 {
1144 d->m_viewParams.setShowClouds( visible );
1145
1146 setPropertyValue(QStringLiteral("clouds_data"), visible);
1147 }
1148
setShowSunShading(bool visible)1149 void MarbleMap::setShowSunShading( bool visible )
1150 {
1151 d->m_textureLayer.setShowSunShading( visible );
1152 }
1153
setShowCityLights(bool visible)1154 void MarbleMap::setShowCityLights( bool visible )
1155 {
1156 d->m_textureLayer.setShowCityLights( visible );
1157 setPropertyValue(QStringLiteral("citylights"), visible);
1158 }
1159
setLockToSubSolarPoint(bool visible)1160 void MarbleMap::setLockToSubSolarPoint( bool visible )
1161 {
1162 disconnect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)),
1163 this, SLOT(centerOn(qreal,qreal)) );
1164
1165 if( isLockedToSubSolarPoint() != visible ) {
1166 d->m_isLockedToSubSolarPoint = visible;
1167 }
1168
1169 if ( isLockedToSubSolarPoint() ) {
1170 connect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)),
1171 this, SLOT(centerOn(qreal,qreal)) );
1172
1173 centerOn( d->m_model->sunLocator()->getLon(), d->m_model->sunLocator()->getLat() );
1174 } else if ( visible ) {
1175 mDebug() << "Ignoring centering on sun, since the sun plugin is not loaded.";
1176 }
1177 }
1178
setSubSolarPointIconVisible(bool visible)1179 void MarbleMap::setSubSolarPointIconVisible( bool visible )
1180 {
1181 if ( isSubSolarPointIconVisible() != visible ) {
1182 d->m_isSubSolarPointIconVisible = visible;
1183 }
1184 }
1185
setShowTileId(bool visible)1186 void MarbleMap::setShowTileId( bool visible )
1187 {
1188 d->m_textureLayer.setShowTileId( visible );
1189 }
1190
setShowGrid(bool visible)1191 void MarbleMap::setShowGrid( bool visible )
1192 {
1193 setPropertyValue(QStringLiteral("coordinate-grid"), visible);
1194 }
1195
setShowPlaces(bool visible)1196 void MarbleMap::setShowPlaces( bool visible )
1197 {
1198 setPropertyValue(QStringLiteral("places"), visible);
1199 }
1200
setShowCities(bool visible)1201 void MarbleMap::setShowCities( bool visible )
1202 {
1203 setPropertyValue(QStringLiteral("cities"), visible);
1204 }
1205
setShowTerrain(bool visible)1206 void MarbleMap::setShowTerrain( bool visible )
1207 {
1208 setPropertyValue(QStringLiteral("terrain"), visible);
1209 }
1210
setShowOtherPlaces(bool visible)1211 void MarbleMap::setShowOtherPlaces( bool visible )
1212 {
1213 setPropertyValue(QStringLiteral("otherplaces"), visible);
1214 }
1215
setShowRelief(bool visible)1216 void MarbleMap::setShowRelief( bool visible )
1217 {
1218 setPropertyValue(QStringLiteral("relief"), visible);
1219 }
1220
setShowIceLayer(bool visible)1221 void MarbleMap::setShowIceLayer( bool visible )
1222 {
1223 setPropertyValue(QStringLiteral("ice"), visible);
1224 }
1225
setShowBorders(bool visible)1226 void MarbleMap::setShowBorders( bool visible )
1227 {
1228 setPropertyValue(QStringLiteral("borders"), visible);
1229 }
1230
setShowRivers(bool visible)1231 void MarbleMap::setShowRivers( bool visible )
1232 {
1233 setPropertyValue(QStringLiteral("rivers"), visible);
1234 }
1235
setShowLakes(bool visible)1236 void MarbleMap::setShowLakes( bool visible )
1237 {
1238 setPropertyValue(QStringLiteral("lakes"), visible);
1239 }
1240
setShowFrameRate(bool visible)1241 void MarbleMap::setShowFrameRate( bool visible )
1242 {
1243 d->m_showFrameRate = visible;
1244 }
1245
setShowRuntimeTrace(bool visible)1246 void MarbleMap::setShowRuntimeTrace( bool visible )
1247 {
1248 if (visible != d->m_layerManager.showRuntimeTrace()) {
1249 d->m_layerManager.setShowRuntimeTrace(visible);
1250 emit repaintNeeded();
1251 }
1252 }
1253
showRuntimeTrace() const1254 bool MarbleMap::showRuntimeTrace() const
1255 {
1256 return d->m_layerManager.showRuntimeTrace();
1257 }
1258
setShowDebugPolygons(bool visible)1259 void MarbleMap::setShowDebugPolygons( bool visible)
1260 {
1261 if (visible != d->m_showDebugPolygons) {
1262 d->m_showDebugPolygons = visible;
1263 emit repaintNeeded();
1264 }
1265 }
1266
showDebugPolygons() const1267 bool MarbleMap::showDebugPolygons() const
1268 {
1269 return d->m_showDebugPolygons;
1270 }
1271
setShowDebugBatchRender(bool visible)1272 void MarbleMap::setShowDebugBatchRender( bool visible)
1273 {
1274 qDebug() << Q_FUNC_INFO << visible;
1275 if (visible != d->m_showDebugBatchRender) {
1276 d->m_showDebugBatchRender = visible;
1277 emit repaintNeeded();
1278 }
1279 }
1280
showDebugBatchRender() const1281 bool MarbleMap::showDebugBatchRender() const
1282 {
1283 return d->m_showDebugBatchRender;
1284 }
1285
setShowDebugPlacemarks(bool visible)1286 void MarbleMap::setShowDebugPlacemarks( bool visible)
1287 {
1288 if (visible != d->m_placemarkLayer.isDebugModeEnabled()) {
1289 d->m_placemarkLayer.setDebugModeEnabled(visible);
1290 emit repaintNeeded();
1291 }
1292 }
1293
showDebugPlacemarks() const1294 bool MarbleMap::showDebugPlacemarks() const
1295 {
1296 return d->m_placemarkLayer.isDebugModeEnabled();
1297 }
1298
setLevelTagDebugModeEnabled(bool visible)1299 void MarbleMap::setLevelTagDebugModeEnabled(bool visible)
1300 {
1301 if (visible != d->m_geometryLayer.levelTagDebugModeEnabled()) {
1302 d->m_geometryLayer.setLevelTagDebugModeEnabled(visible);
1303 d->m_placemarkLayer.setLevelTagDebugModeEnabled(visible);
1304 emit repaintNeeded();
1305 }
1306 }
1307
levelTagDebugModeEnabled() const1308 bool MarbleMap::levelTagDebugModeEnabled() const
1309 {
1310 return d->m_geometryLayer.levelTagDebugModeEnabled() &&
1311 d->m_placemarkLayer.levelTagDebugModeEnabled();
1312 }
1313
setDebugLevelTag(int level)1314 void MarbleMap::setDebugLevelTag(int level)
1315 {
1316 d->m_geometryLayer.setDebugLevelTag(level);
1317 d->m_placemarkLayer.setDebugLevelTag(level);
1318 }
1319
debugLevelTag() const1320 int MarbleMap::debugLevelTag() const
1321 {
1322 return d->m_geometryLayer.debugLevelTag();
1323 }
1324
setShowBackground(bool visible)1325 void MarbleMap::setShowBackground( bool visible )
1326 {
1327 d->m_layerManager.setShowBackground( visible );
1328 }
1329
setVisibleRelationTypes(GeoDataRelation::RelationTypes relationTypes)1330 void MarbleMap::setVisibleRelationTypes(GeoDataRelation::RelationTypes relationTypes)
1331 {
1332 if (d->m_visibleRelationTypes != relationTypes) {
1333 d->m_visibleRelationTypes = relationTypes;
1334 d->m_geometryLayer.setVisibleRelationTypes(relationTypes);
1335 emit visibleRelationTypesChanged(d->m_visibleRelationTypes);
1336 }
1337 }
1338
notifyMouseClick(int x,int y)1339 void MarbleMap::notifyMouseClick( int x, int y )
1340 {
1341 qreal lon = 0;
1342 qreal lat = 0;
1343
1344 const bool valid = geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian );
1345
1346 if ( valid ) {
1347 emit mouseClickGeoPosition( lon, lat, GeoDataCoordinates::Radian );
1348 }
1349 }
1350
clearVolatileTileCache()1351 void MarbleMap::clearVolatileTileCache()
1352 {
1353 d->m_vectorTileLayer.reset();
1354 d->m_textureLayer.reset();
1355 mDebug() << "Cleared Volatile Cache!";
1356 }
1357
setVolatileTileCacheLimit(quint64 kilobytes)1358 void MarbleMap::setVolatileTileCacheLimit( quint64 kilobytes )
1359 {
1360 mDebug() << "kiloBytes" << kilobytes;
1361 d->m_textureLayer.setVolatileCacheLimit( kilobytes );
1362 }
1363
defaultAngleUnit() const1364 AngleUnit MarbleMap::defaultAngleUnit() const
1365 {
1366 if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::Decimal ) {
1367 return DecimalDegree;
1368 } else if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::UTM ) {
1369 return UTM;
1370 }
1371
1372 return DMSDegree;
1373 }
1374
setDefaultAngleUnit(AngleUnit angleUnit)1375 void MarbleMap::setDefaultAngleUnit( AngleUnit angleUnit )
1376 {
1377 if ( angleUnit == DecimalDegree ) {
1378 GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::Decimal );
1379 return;
1380 } else if ( angleUnit == UTM ) {
1381 GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::UTM );
1382 return;
1383 }
1384
1385 GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::DMS );
1386 }
1387
defaultFont() const1388 QFont MarbleMap::defaultFont() const
1389 {
1390 return d->m_styleBuilder.defaultFont();
1391 }
1392
setDefaultFont(const QFont & font)1393 void MarbleMap::setDefaultFont( const QFont& font )
1394 {
1395 d->m_styleBuilder.setDefaultFont(font);
1396 d->m_placemarkLayer.requestStyleReset();
1397 }
1398
renderPlugins() const1399 QList<RenderPlugin *> MarbleMap::renderPlugins() const
1400 {
1401 return d->m_renderPlugins;
1402 }
1403
floatItems() const1404 QList<AbstractFloatItem *> MarbleMap::floatItems() const
1405 {
1406 return d->m_floatItemsLayer.floatItems();
1407 }
1408
floatItem(const QString & nameId) const1409 AbstractFloatItem * MarbleMap::floatItem( const QString &nameId ) const
1410 {
1411 for ( AbstractFloatItem * floatItem: floatItems() ) {
1412 if ( floatItem && floatItem->nameId() == nameId ) {
1413 return floatItem;
1414 }
1415 }
1416
1417 return nullptr; // No item found
1418 }
1419
dataPlugins() const1420 QList<AbstractDataPlugin *> MarbleMap::dataPlugins() const
1421 {
1422 return d->m_layerManager.dataPlugins();
1423 }
1424
whichItemAt(const QPoint & curpos) const1425 QList<AbstractDataPluginItem *> MarbleMap::whichItemAt( const QPoint& curpos ) const
1426 {
1427 return d->m_layerManager.whichItemAt( curpos );
1428 }
1429
addLayer(LayerInterface * layer)1430 void MarbleMap::addLayer( LayerInterface *layer )
1431 {
1432 d->m_layerManager.addLayer(layer);
1433 }
1434
removeLayer(LayerInterface * layer)1435 void MarbleMap::removeLayer( LayerInterface *layer )
1436 {
1437 d->m_layerManager.removeLayer(layer);
1438 }
1439
renderStatus() const1440 RenderStatus MarbleMap::renderStatus() const
1441 {
1442 return d->m_layerManager.renderState().status();
1443 }
1444
renderState() const1445 RenderState MarbleMap::renderState() const
1446 {
1447 return d->m_layerManager.renderState();
1448 }
1449
addTextureLayer(GeoSceneTextureTileDataset * texture)1450 QString MarbleMap::addTextureLayer(GeoSceneTextureTileDataset *texture)
1451 {
1452 return textureLayer()->addTextureLayer(texture);
1453 }
1454
removeTextureLayer(const QString & key)1455 void MarbleMap::removeTextureLayer(const QString &key)
1456 {
1457 textureLayer()->removeTextureLayer(key);
1458 }
1459
1460 // this method will only temporarily "pollute" the MarbleModel class
textureLayer() const1461 TextureLayer *MarbleMap::textureLayer() const
1462 {
1463 return &d->m_textureLayer;
1464 }
1465
styleBuilder() const1466 const StyleBuilder* MarbleMap::styleBuilder() const
1467 {
1468 return &d->m_styleBuilder;
1469 }
1470
heading() const1471 qreal MarbleMap::heading() const
1472 {
1473 return d->m_viewport.heading() * RAD2DEG;
1474 }
1475
setHeading(qreal heading)1476 void MarbleMap::setHeading( qreal heading )
1477 {
1478 d->m_viewport.setHeading( heading * DEG2RAD );
1479 d->m_textureLayer.setNeedsUpdate();
1480
1481 emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() );
1482 }
1483
1484 }
1485
1486 #include "moc_MarbleMap.cpp"
1487