15#include <QAbstractItemModel>
17#include <QItemSelectionModel>
19#include <QSortFilterProxyModel>
20#include <QTextDocument>
22#include "kdescendantsproxymodel.h"
24#include "MapThemeManager.h"
25#include "MarbleDebug.h"
27#include "GeoSceneDocument.h"
28#include "GeoSceneGeodata.h"
29#include "GeoSceneHead.h"
30#include "GeoSceneLayer.h"
31#include "GeoSceneMap.h"
32#include "GeoScenePalette.h"
33#include "GeoSceneTileDataset.h"
34#include "GeoSceneVector.h"
36#include "GeoDataDocument.h"
37#include "GeoDataFeature.h"
38#include "GeoDataLineStyle.h"
39#include "GeoDataPlacemark.h"
40#include "GeoDataPoint.h"
41#include "GeoDataPolyStyle.h"
42#include "GeoDataStyle.h"
43#include "GeoDataStyleMap.h"
44#include "GeoDataTrack.h"
45#include "GeoDataTypes.h"
47#include "BookmarkManager.h"
48#include "DgmlAuxillaryDictionary.h"
49#include "ElevationModel.h"
50#include "FileManager.h"
51#include "FileStoragePolicy.h"
52#include "FileStorageWatcher.h"
53#include "GeoDataTreeModel.h"
54#include "HttpDownloadManager.h"
55#include "MarbleClock.h"
56#include "MarbleDirs.h"
57#include "PlacemarkPositionProviderPlugin.h"
59#include "PlanetFactory.h"
60#include "PluginManager.h"
61#include "PositionTracking.h"
62#include "RouteSimulationPositionProviderPlugin.h"
63#include "StoragePolicy.h"
64#include "SunLocator.h"
65#include "TileCreator.h"
66#include "TileCreatorDialog.h"
67#include "TileLoader.h"
68#include "routing/RoutingManager.h"
73class MarbleModelPrivate
78 , m_planet(PlanetFactory::construct(QStringLiteral(
"earth")))
79 , m_sunLocator(&m_clock, &m_planet)
81 , m_homePoint(-9.4, 54.8, 0.0, GeoDataCoordinates::Degree)
85 , m_storagePolicy(MarbleDirs::localPath())
86 , m_downloadManager(&m_storagePolicy)
87 , m_storageWatcher(MarbleDirs::localPath())
90 , m_placemarkProxyModel()
91 , m_placemarkSelectionModel(nullptr)
92 , m_fileManager(&m_treeModel, &m_pluginManager)
93 , m_positionTracking(&m_treeModel)
94 , m_trackedPlacemark(nullptr)
95 , m_bookmarkManager(&m_treeModel)
96 , m_routingManager(nullptr)
98 , m_workOffline(false)
99 , m_elevationModel(&m_downloadManager, &m_pluginManager)
101 m_descendantProxy.setSourceModel(&m_treeModel);
103 m_placemarkProxyModel.setFilterFixedString(
QString::fromLatin1(GeoDataTypes::GeoDataPlacemarkType));
104 m_placemarkProxyModel.setFilterKeyColumn(1);
105 m_placemarkProxyModel.setSourceModel(&m_descendantProxy);
106 m_placemarkSelectionModel.setModel(&m_placemarkProxyModel);
108 m_groundOverlayProxyModel.setFilterFixedString(
QString::fromLatin1(GeoDataTypes::GeoDataGroundOverlayType));
109 m_groundOverlayProxyModel.setFilterKeyColumn(1);
110 m_groundOverlayProxyModel.setSourceModel(&m_descendantProxy);
113 ~MarbleModelPrivate()
124 void assignFillColors(
const QString &filePath);
125 void assignFillColors(GeoDataDocument *doc,
const GeoSceneGeodata &data)
const;
127 void addHighlightStyle(GeoDataDocument *doc)
const;
132 SunLocator m_sunLocator;
134 PluginManager m_pluginManager;
137 GeoDataCoordinates m_homePoint;
141 GeoSceneDocument *m_mapTheme;
143 FileStoragePolicy m_storagePolicy;
144 HttpDownloadManager m_downloadManager;
147 FileStorageWatcher m_storageWatcher;
150 GeoDataTreeModel m_treeModel;
151 KDescendantsProxyModel m_descendantProxy;
152 QSortFilterProxyModel m_placemarkProxyModel;
153 QSortFilterProxyModel m_groundOverlayProxyModel;
156 QItemSelectionModel m_placemarkSelectionModel;
158 FileManager m_fileManager;
161 PositionTracking m_positionTracking;
163 const GeoDataPlacemark *m_trackedPlacemark;
165 BookmarkManager m_bookmarkManager;
166 RoutingManager *m_routingManager;
167 QTextDocument *m_legend;
171 ElevationModel m_elevationModel;
176 , d(new MarbleModelPrivate())
179 connect(&d->m_storagePolicy, SIGNAL(cleared()), &d->m_storageWatcher, SLOT(resetCurrentSize()));
180 connect(&d->m_storagePolicy, SIGNAL(sizeChanged(qint64)), &d->m_storageWatcher, SLOT(addToCurrentSize(qint64)));
186 connect(&d->m_clock, SIGNAL(timeChanged()), &d->m_sunLocator, SLOT(update()));
188 d->m_pluginManager.addPositionProviderPlugin(
new PlacemarkPositionProviderPlugin(
this,
this));
189 d->m_pluginManager.addPositionProviderPlugin(
new RouteSimulationPositionProviderPlugin(
this,
this));
192MarbleModel::~MarbleModel()
196 mDebug() <<
"Model deleted:" <<
this;
201 return &d->m_bookmarkManager;
209 mapThemeId = d->m_mapTheme->head()->mapThemeId();
216 return d->m_mapTheme;
219const GeoSceneDocument *MarbleModel::mapTheme()
const
221 return d->m_mapTheme;
235 if (!mapThemeId.isEmpty() && mapThemeId == this->mapThemeId())
239 setMapTheme(mapTheme);
248 qWarning() <<
"Selected theme doesn't work, so we stick to the previous one";
253 QString defaultTheme = QStringLiteral(
"earth/srtm/srtm.dgml");
254 qWarning() <<
"Falling back to default theme:" << defaultTheme;
260 qWarning() <<
"Couldn't find a valid DGML map.";
265 QList<GeoSceneGeodata> currentDatasets;
267 for (GeoSceneLayer *layer : d->m_mapTheme->map()->layers()) {
272 for (GeoSceneAbstractDataset *dataset : layer->datasets()) {
273 auto data =
dynamic_cast<GeoSceneGeodata *
>(dataset);
275 currentDatasets << *data;
280 delete d->m_mapTheme;
281 d->m_mapTheme = mapTheme;
283 addDownloadPolicies(d->m_mapTheme);
286 mDebug() <<
"DGML2 Name : " << d->m_mapTheme->head()->name();
303 qreal
const radiusAttributeValue = d->m_mapTheme->head()->radius();
304 if (d->m_mapTheme->head()->target().toLower() != d->m_planet.id() || radiusAttributeValue != d->m_planet.radius()) {
305 mDebug() <<
"Changing Planet";
307 if (radiusAttributeValue > 0.0) {
308 d->m_planet.setRadius(radiusAttributeValue);
310 sunLocator()->setPlanet(&d->m_planet);
313 QStringList fileList;
314 QStringList propertyList;
315 QList<GeoDataStyle::Ptr> styleList;
316 QList<int> renderOrderList;
318 for (GeoSceneLayer *layer : d->m_mapTheme->map()->layers()) {
323 for (
const GeoSceneAbstractDataset *dataset : layer->datasets()) {
324 const auto data =
dynamic_cast<const GeoSceneGeodata *
>(dataset);
327 GeoDataDocument *doc =
nullptr;
328 for (
int i = 0; i < currentDatasets.
size(); ++i) {
329 if (currentDatasets[i] == *data) {
339 if (currentDatasets[i].sourceFile() == data->sourceFile()) {
340 doc = d->m_fileManager.at(data->sourceFile());
349 d->assignFillColors(doc, *data);
351 const QString filename = data->sourceFile();
352 const QString
property = data->property();
353 const QPen pen = data->pen();
354 const QBrush brush = data->brush();
355 GeoDataStyle::Ptr style;
356 const int renderOrder = data->renderOrder();
366 if (data->colors().isEmpty()) {
367 GeoDataLineStyle lineStyle(pen.
color());
368 lineStyle.setPenStyle(pen.
style());
369 lineStyle.setWidth(pen.
width());
370 GeoDataPolyStyle polyStyle(brush.
color());
371 polyStyle.setFill(
true);
372 style = GeoDataStyle::Ptr(
new GeoDataStyle);
373 style->setLineStyle(lineStyle);
374 style->setPolyStyle(polyStyle);
375 style->setId(QStringLiteral(
"default"));
378 fileList << filename;
381 renderOrderList << renderOrder;
386 for (
const GeoSceneGeodata &data : std::as_const(currentDatasets)) {
387 d->m_fileManager.removeFile(data.sourceFile());
390 for (
int i = 0; i < fileList.
size(); ++i) {
391 d->m_fileManager.addFile(fileList.
at(i), propertyList.
at(i), styleList.
at(i), MapDocument, renderOrderList.
at(i));
394 mDebug() <<
"THEME CHANGED: ***" << mapTheme->head()->mapThemeId();
405 QColor highlightBrushColor = m_mapTheme->map()->highlightBrushColor();
406 QColor highlightPenColor = m_mapTheme->map()->highlightPenColor();
408 GeoDataStyle::Ptr highlightStyle(
new GeoDataStyle);
409 highlightStyle->setId(QStringLiteral(
"highlight"));
411 if (highlightBrushColor.
isValid()) {
412 GeoDataPolyStyle highlightPolyStyle;
413 highlightPolyStyle.setColor(highlightBrushColor);
414 highlightPolyStyle.setFill(
true);
415 highlightStyle->setPolyStyle(highlightPolyStyle);
417 if (highlightPenColor.
isValid()) {
418 GeoDataLineStyle highlightLineStyle(highlightPenColor);
419 highlightStyle->setLineStyle(highlightLineStyle);
421 if (highlightBrushColor.
isValid() || highlightPenColor.
isValid()) {
422 GeoDataStyleMap styleMap = doc->styleMap(QStringLiteral(
"default-map"));
423 styleMap.insert(QStringLiteral(
"highlight"), QLatin1Char(
'#') + highlightStyle->id());
424 doc->addStyle(highlightStyle);
425 doc->addStyleMap(styleMap);
432 d->m_homePoint.geoCoordinates(lon, lat, GeoDataCoordinates::Degree);
433 zoom = d->m_homeZoom;
439 d->m_homeZoom = zoom;
445 d->m_homePoint = homePoint;
446 d->m_homeZoom = zoom;
452 return &d->m_downloadManager;
457 return &d->m_downloadManager;
462 return &d->m_treeModel;
467 return &d->m_treeModel;
472 return &d->m_placemarkProxyModel;
475const QAbstractItemModel *MarbleModel::placemarkModel()
const
477 return &d->m_placemarkProxyModel;
480QAbstractItemModel *MarbleModel::groundOverlayModel()
482 return &d->m_groundOverlayProxyModel;
485const QAbstractItemModel *MarbleModel::groundOverlayModel()
const
487 return &d->m_groundOverlayProxyModel;
490QItemSelectionModel *MarbleModel::placemarkSelectionModel()
492 return &d->m_placemarkSelectionModel;
495PositionTracking *MarbleModel::positionTracking()
const
497 return &d->m_positionTracking;
502 return &d->m_fileManager;
505qreal MarbleModel::planetRadius()
const
507 return d->m_planet.radius();
510QString MarbleModel::planetName()
const
512 return d->m_planet.name();
515QString MarbleModel::planetId()
const
517 return d->m_planet.id();
520MarbleClock *MarbleModel::clock()
525const MarbleClock *MarbleModel::clock()
const
530SunLocator *MarbleModel::sunLocator()
532 return &d->m_sunLocator;
535const SunLocator *MarbleModel::sunLocator()
const
537 return &d->m_sunLocator;
542 return d->m_storageWatcher.cacheLimit() / 1024;
545void MarbleModel::clearPersistentTileCache()
547 d->m_storagePolicy.clearCache();
556 QString themeID = d->m_mapTheme->head()->theme();
558 const auto layer =
static_cast<const GeoSceneLayer *
>(d->m_mapTheme->map()->layer(themeID));
559 const auto texture =
static_cast<const GeoSceneTileDataset *
>(layer->groundDataset());
561 QString sourceDir = texture->sourceDir();
562 QString installMap = texture->installMap();
563 QString role = d->m_mapTheme->map()->
layer(themeID)->role();
565 if (!TileLoader::baseTilesAvailable(*texture) && !installMap.
isEmpty()) {
566 mDebug() <<
"Base tiles not available. Creating Tiles ... \n"
567 <<
"SourceDir: " << sourceDir <<
"InstallMap:" << installMap;
570 auto tileCreator =
new TileCreator(sourceDir, installMap, (role ==
QLatin1StringView(
"dem")) ? QStringLiteral(
"true") : QStringLiteral(
"false"));
571 tileCreator->setTileFormat(texture->fileFormat().toLower());
574 tileCreatorDlg->setSummary(d->m_mapTheme->head()->name(), d->m_mapTheme->head()->description());
575 tileCreatorDlg->exec();
576 qDebug(
"Tile creation completed");
577 delete tileCreatorDlg;
584 d->m_storageWatcher.setCacheLimit(kiloBytes * 1024);
586 if (kiloBytes != 0) {
587 if (!d->m_storageWatcher.isRunning())
590 d->m_storageWatcher.quit();
597 d->m_trackedPlacemark = placemark;
603 return d->m_trackedPlacemark;
608 return &d->m_pluginManager;
611PluginManager *MarbleModel::pluginManager()
613 return &d->m_pluginManager;
630 const QString themeId = mapTheme->head()->theme();
631 auto const *layer =
static_cast<const GeoSceneLayer *
>(mapTheme->map()->layer(themeId));
635 auto const *texture =
static_cast<const GeoSceneTileDataset *
>(layer->groundDataset());
642 for (; pos != end; ++pos) {
643 d->m_downloadManager.addDownloadPolicy(**pos);
649 return d->m_routingManager;
654 return d->m_routingManager;
657void MarbleModel::setClockDateTime(
const QDateTime &datetime)
659 d->m_clock.setDateTime(datetime);
662QDateTime MarbleModel::clockDateTime()
const
664 return d->m_clock.dateTime();
667int MarbleModel::clockSpeed()
const
669 return d->m_clock.speed();
672void MarbleModel::setClockSpeed(
int speed)
674 d->m_clock.setSpeed(speed);
677void MarbleModel::setClockTimezone(
int timeInSec)
679 d->m_clock.setTimezone(timeInSec);
682int MarbleModel::clockTimezone()
const
684 return d->m_clock.timezone();
687QTextDocument *MarbleModel::legend()
695 d->m_legend = legend;
700 d->m_fileManager.addFile(filename, filename, GeoDataStyle::Ptr(), UserDocument, 0,
true);
705 d->m_fileManager.addData(key, data, UserDocument);
710 d->m_fileManager.removeFile(fileName);
713void MarbleModel::updateProperty(
const QString &property,
bool value)
718 document->setVisible(value);
719 d->m_treeModel.updateFeature(document);
725void MarbleModelPrivate::assignFillColors(
const QString &filePath)
727 const GeoSceneGeodata *data =
nullptr;
729 for (
auto layer : m_mapTheme->map()->layers()) {
734 for (
auto dataset : layer->datasets()) {
735 auto sceneData =
dynamic_cast<const GeoSceneGeodata *
>(dataset);
736 if (sceneData !=
nullptr && sceneData->sourceFile() == filePath) {
747 if (data ==
nullptr) {
751 GeoDataDocument *doc = m_fileManager.at(filePath);
754 assignFillColors(doc, *data);
757void MarbleModelPrivate::assignFillColors(
GeoDataDocument *doc,
const GeoSceneGeodata &data)
const
759 addHighlightStyle(doc);
761 const QPen pen = data.pen();
762 const QBrush brush = data.brush();
763 const QList<QColor> colors = data.colors();
764 GeoDataLineStyle lineStyle(pen.
color());
765 lineStyle.setPenStyle(pen.
style());
766 lineStyle.setWidth(pen.
width());
769 const qreal alpha = data.alpha();
770 for (
auto feature : *doc) {
772 if (placemark ==
nullptr) {
776 GeoDataStyle::Ptr style(
new GeoDataStyle);
777 style->setId(QStringLiteral(
"normal"));
778 style->setLineStyle(lineStyle);
779 quint8 colorIndex = placemark->style()->polyStyle().colorIndex();
780 GeoDataPolyStyle polyStyle;
782 polyStyle.setColorIndex(colorIndex);
785 Q_ASSERT(colors.
size());
786 if (colorIndex > colors.
size() || (colorIndex - 1) < 0) {
789 color = colors[colorIndex - 1];
792 polyStyle.setColor(color);
793 polyStyle.setFill(
true);
794 style->setPolyStyle(polyStyle);
795 placemark->setStyle(style);
798 GeoDataStyle::Ptr style(
new GeoDataStyle);
799 GeoDataPolyStyle polyStyle(brush.
color());
800 polyStyle.setFill(
true);
801 style->setLineStyle(lineStyle);
802 style->setPolyStyle(polyStyle);
803 style->setId(QStringLiteral(
"default"));
804 GeoDataStyleMap styleMap;
805 styleMap.setId(QStringLiteral(
"default-map"));
806 styleMap.insert(QStringLiteral(
"normal"), QLatin1Char(
'#') + style->id());
807 doc->addStyle(style);
808 doc->addStyleMap(styleMap);
810 const QString styleUrl = QLatin1Char(
'#') + styleMap.id();
812 for (
auto feature : *doc) {
814 if (placemark ==
nullptr) {
822 placemark->setStyleUrl(styleUrl);
827bool MarbleModel::workOffline()
const
829 return d->m_workOffline;
832void MarbleModel::setWorkOffline(
bool workOffline)
834 if (d->m_workOffline != workOffline) {
837 d->m_workOffline = workOffline;
838 Q_EMIT workOfflineChanged();
842ElevationModel *MarbleModel::elevationModel()
844 return &d->m_elevationModel;
847const ElevationModel *MarbleModel::elevationModel()
const
849 return &d->m_elevationModel;
854#include "moc_MarbleModel.cpp"
This file contains the headers for MarbleModel.
This class is responsible for loading the book mark objects from the files and various book mark oper...
This class is responsible for loading the different files into Geodata model.
QList< GeoDataFeature * > featureList() const
A convenience function that returns all features in this container.
A 3d point representation.
A container for Features, Styles and in the future Schemas.
A base class for all geodata features.
a class representing a point of interest on the map
The representation of GeoData in a model This class represents all available data given by kml-data f...
A container for features parsed from the DGML file.
Layer of a GeoScene document.
bool hasVectorLayers() const
Checks for valid layers that contain vector data.
GeoSceneLayer * layer(const QString &name)
Return a layer by its name.
bool hasTextureLayers() const
Checks for valid layers that contain texture data.
This class manages scheduled downloads.
void setDownloadEnabled(const bool enable)
Switches loading on/off, useful for offline mode.
static GeoSceneDocument * loadMapTheme(const QString &mapThemeStringID)
Returns the map theme as a GeoSceneDocument object.
BookmarkManager * bookmarkManager()
return instance of BookmarkManager
void trackedPlacemarkChanged(const GeoDataPlacemark *placemark)
Emitted when the placemark tracked by this model has changed.
void addGeoDataFile(const QString &filename)
Handle file loading into the treeModel.
HttpDownloadManager * downloadManager()
Return the downloadmanager to load missing tiles.
const Planet * planet() const
Returns the planet object for the current map.
quint64 persistentTileCacheLimit() const
Returns the limit in kilobytes of the persistent (on hard disc) tile cache.
void homeChanged(const GeoDataCoordinates &newHomePoint)
Emitted when the home location is changed.
void themeChanged(const QString &mapTheme)
Signal that the map theme has changed, and to which theme.
void setPersistentTileCacheLimit(quint64 kiloBytes)
Set the limit of the persistent (on hard disc) tile cache.
void removeGeoData(const QString &key)
Remove the file or raw data from the treeModel.
const GeoDataPlacemark * trackedPlacemark() const
Returns the placemark being tracked by this model or 0 if no placemark is currently tracked.
void setTrackedPlacemark(const GeoDataPlacemark *placemark)
Change the placemark tracked by this model.
void addGeoDataString(const QString &data, const QString &key=QLatin1String("data"))
Handle raw data loading into the treeModel.
void home(qreal &lon, qreal &lat, int &zoom) const
get the home point
void setHome(qreal lon, qreal lat, int zoom=1050)
Set the home point.
void setMapThemeId(const QString &mapThemeId)
Set a new map theme to use.
void setLegend(QTextDocument *document)
Uses the given text document as the new content of the legend Any previous legend content is overwrit...
MarbleModel(QObject *parent=nullptr)
Construct a new MarbleModel.
GeoDataTreeModel * treeModel()
Return the list of Placemarks as a QAbstractItemModel *.
static Planet construct(const QString &id)
Creates the planet with the given ID, or one with default values if ID is not among planetList()
The class that handles Marble's plugins.
Delegates data retrieval and model updates to the appropriate routing provider.
Binds a QML item to a specific geodetic location in screen coordinates.
T * geodata_cast(GeoDataObject *node)
Returns the given node cast to type T if the node was instantiated as type T; otherwise returns 0.
const QColor & color() const const
bool isValid() const const
void setAlphaF(float alpha)
const_reference at(qsizetype i) const const
const_iterator constBegin() const const
const_iterator constEnd() const const
bool isEmpty() const const
void removeAt(qsizetype i)
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * parent() const const
QVariant property(const char *name) const const
QColor color() const const
Qt::PenStyle style() const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const