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)
106 m_placemarkSelectionModel.
setModel(&m_placemarkProxyModel);
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;
158 FileManager m_fileManager;
161 PositionTracking m_positionTracking;
163 const GeoDataPlacemark *m_trackedPlacemark;
165 BookmarkManager m_bookmarkManager;
166 RoutingManager *m_routingManager;
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()));
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.";
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);
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();
398void MarbleModelPrivate::addHighlightStyle(GeoDataDocument *doc)
const
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;
477 return &d->m_placemarkProxyModel;
482 return &d->m_groundOverlayProxyModel;
487 return &d->m_groundOverlayProxyModel;
492 return &d->m_placemarkSelectionModel;
495PositionTracking *MarbleModel::positionTracking()
const
497 return &d->m_positionTracking;
500FileManager *MarbleModel::fileManager()
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) {
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);
647RoutingManager *MarbleModel::routingManager()
649 return d->m_routingManager;
652const RoutingManager *MarbleModel::routingManager()
const
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();
695 d->m_legend = legend;
705 d->m_fileManager.
addData(key, data, UserDocument);
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();
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);
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...
void addFile(const QString &fileName, const QString &property, const GeoDataStyle::Ptr &style, DocumentRole role, int renderOrder=0, bool recenter=false)
Loads a new file into the manager.
void removeFile(const QString &fileName)
removes an existing file from the manager
void addData(const QString &name, const QString &data, DocumentRole role)
add Data containing KML code as string
QList< GeoDataFeature * > featureList() const
A convenience function that returns all features in this container.
A 3d point representation.
void geoCoordinates(qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit) const
use this function to get the longitude and latitude with one call - use the unit parameter to switch ...
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.
qreal radius() const
Planet radius, 0.0 if unknown.
Layer of a GeoScene document.
bool hasVectorLayers() const
Checks for valid layers that contain vector data.
QList< GeoSceneLayer * > layers() const
Return all layers.
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.
void setSourceModel(QAbstractItemModel *model) override
Sets the source model of the proxy.
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.
void addPositionProviderPlugin(const PositionProviderPlugin *plugin)
Add a PositionProviderPlugin manually to the list of known 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)
void setModel(QAbstractItemModel *model)
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)
QVariant property(const char *name) const const
QColor color() const const
Qt::PenStyle style() const const
void setFilterKeyColumn(int column)
void setFilterFixedString(const QString &pattern)
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QString toLower() const const
bool isRunning() const const
void start(Priority priority)