17 #include <QAbstractItemModel>
18 #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 "GeoDataPlacemark.h"
39 #include "GeoDataPoint.h"
40 #include "GeoDataStyle.h"
41 #include "GeoDataStyleMap.h"
42 #include "GeoDataTrack.h"
43 #include "GeoDataLineStyle.h"
44 #include "GeoDataPolyStyle.h"
45 #include "GeoDataTypes.h"
47 #include "DgmlAuxillaryDictionary.h"
48 #include "MarbleClock.h"
49 #include "FileStoragePolicy.h"
50 #include "FileStorageWatcher.h"
51 #include "PositionTracking.h"
52 #include "HttpDownloadManager.h"
53 #include "MarbleDirs.h"
54 #include "FileManager.h"
55 #include "GeoDataTreeModel.h"
56 #include "PlacemarkPositionProviderPlugin.h"
58 #include "PlanetFactory.h"
59 #include "PluginManager.h"
60 #include "StoragePolicy.h"
61 #include "SunLocator.h"
62 #include "TileCreator.h"
63 #include "TileCreatorDialog.h"
64 #include "TileLoader.h"
65 #include "routing/RoutingManager.h"
66 #include "RouteSimulationPositionProviderPlugin.h"
67 #include "BookmarkManager.h"
68 #include "ElevationModel.h"
73 class 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 ),
83 m_mapTheme( nullptr ),
84 m_storagePolicy( MarbleDirs::localPath() ),
85 m_downloadManager( &m_storagePolicy ),
86 m_storageWatcher( MarbleDirs::localPath() ),
89 m_placemarkProxyModel(),
90 m_placemarkSelectionModel( nullptr ),
91 m_fileManager( &m_treeModel, &m_pluginManager ),
92 m_positionTracking( &m_treeModel ),
93 m_trackedPlacemark( nullptr ),
94 m_bookmarkManager( &m_treeModel ),
95 m_routingManager( nullptr ),
97 m_workOffline( false ),
98 m_elevationModel( &m_downloadManager, &m_pluginManager )
100 m_descendantProxy.setSourceModel( &m_treeModel );
102 m_placemarkProxyModel.setFilterFixedString( GeoDataTypes::GeoDataPlacemarkType );
103 m_placemarkProxyModel.setFilterKeyColumn( 1 );
104 m_placemarkProxyModel.setSourceModel( &m_descendantProxy );
105 m_placemarkSelectionModel.setModel(&m_placemarkProxyModel);
107 m_groundOverlayProxyModel.setFilterFixedString( GeoDataTypes::GeoDataGroundOverlayType );
108 m_groundOverlayProxyModel.setFilterKeyColumn( 1 );
109 m_groundOverlayProxyModel.setSourceModel( &m_descendantProxy );
112 ~MarbleModelPrivate()
123 void assignFillColors(
const QString &filePath );
124 void assignFillColors(GeoDataDocument *doc,
const GeoSceneGeodata &data)
const;
126 void addHighlightStyle(GeoDataDocument *doc)
const;
131 SunLocator m_sunLocator;
133 PluginManager m_pluginManager;
136 GeoDataCoordinates m_homePoint;
140 GeoSceneDocument *m_mapTheme;
142 FileStoragePolicy m_storagePolicy;
143 HttpDownloadManager m_downloadManager;
146 FileStorageWatcher m_storageWatcher;
149 GeoDataTreeModel m_treeModel;
157 FileManager m_fileManager;
160 PositionTracking m_positionTracking;
162 const GeoDataPlacemark *m_trackedPlacemark;
164 BookmarkManager m_bookmarkManager;
165 RoutingManager *m_routingManager;
170 ElevationModel m_elevationModel;
175 d( new MarbleModelPrivate() )
178 connect( &d->m_storagePolicy, SIGNAL(cleared()),
179 &d->m_storageWatcher, SLOT(resetCurrentSize()) );
180 connect( &d->m_storagePolicy, SIGNAL(sizeChanged(qint64)),
181 &d->m_storageWatcher, SLOT(addToCurrentSize(qint64)) );
184 this, SLOT(assignFillColors(
QString)) );
188 connect(&d->m_clock, SIGNAL(timeChanged()),
189 &d->m_sunLocator, SLOT(update()) );
191 d->m_pluginManager.addPositionProviderPlugin(
new PlacemarkPositionProviderPlugin(
this,
this));
192 d->m_pluginManager.addPositionProviderPlugin(
new RouteSimulationPositionProviderPlugin(
this,
this));
195 MarbleModel::~MarbleModel()
199 mDebug() <<
"Model deleted:" <<
this;
204 return &d->m_bookmarkManager;
207 QString MarbleModel::mapThemeId()
const
212 mapThemeId = d->m_mapTheme->head()->mapThemeId();
217 GeoSceneDocument *MarbleModel::mapTheme()
219 return d->m_mapTheme;
222 const GeoSceneDocument *MarbleModel::mapTheme()
const
224 return d->m_mapTheme;
238 if ( !mapThemeId.
isEmpty() && mapThemeId == this->mapThemeId() )
242 setMapTheme( mapTheme );
250 if ( d->m_mapTheme ){
251 qWarning() <<
"Selected theme doesn't work, so we stick to the previous one";
256 QString defaultTheme =
"earth/srtm/srtm.dgml";
257 qWarning() <<
"Falling back to default theme:" << defaultTheme;
263 qWarning() <<
"Couldn't find a valid DGML map.";
269 if ( d->m_mapTheme ) {
270 for ( GeoSceneLayer *layer: d->m_mapTheme->map()->layers() ) {
271 if ( layer->backend() != dgml::dgmlValue_geodata
272 && layer->backend() != dgml::dgmlValue_vector )
276 for ( GeoSceneAbstractDataset *dataset: layer->datasets() ) {
277 GeoSceneGeodata *data =
dynamic_cast<GeoSceneGeodata*
>( dataset );
279 currentDatasets << *data;
284 delete d->m_mapTheme;
285 d->m_mapTheme = mapTheme;
287 addDownloadPolicies( d->m_mapTheme );
290 mDebug() <<
"DGML2 Name : " << d->m_mapTheme->head()->name();
307 qreal
const radiusAttributeValue = d->m_mapTheme->head()->radius();
308 if( d->m_mapTheme->head()->target().toLower() != d->m_planet.id() || radiusAttributeValue != d->m_planet.radius() ) {
309 mDebug() <<
"Changing Planet";
311 if ( radiusAttributeValue > 0.0 ) {
312 d->m_planet.setRadius( radiusAttributeValue );
314 sunLocator()->setPlanet( &d->m_planet );
322 for ( GeoSceneLayer *layer: d->m_mapTheme->map()->layers() ) {
323 if ( layer->backend() != dgml::dgmlValue_geodata
324 && layer->backend() != dgml::dgmlValue_vector )
328 for (
const GeoSceneAbstractDataset *dataset: layer->datasets() ) {
329 const GeoSceneGeodata *data =
dynamic_cast<const GeoSceneGeodata*
>( dataset );
332 GeoDataDocument *doc =
nullptr;
333 for (
int i = 0; i < currentDatasets.
size(); ++i ) {
334 if ( currentDatasets[i] == *data ) {
344 if ( currentDatasets[i].sourceFile() == data->sourceFile() ) {
345 doc = d->m_fileManager.at(data->sourceFile());
354 d->assignFillColors(doc, *data);
357 const QString filename = data->sourceFile();
358 const QString property = data->property();
359 const QPen pen = data->pen();
360 const QBrush brush = data->brush();
361 GeoDataStyle::Ptr style;
362 const int renderOrder = data->renderOrder();
372 if ( data->colors().isEmpty() ) {
373 GeoDataLineStyle lineStyle( pen.
color() );
374 lineStyle.setPenStyle( pen.
style() );
375 lineStyle.setWidth( pen.
width() );
376 GeoDataPolyStyle polyStyle( brush.
color() );
377 polyStyle.setFill(
true );
378 style = GeoDataStyle::Ptr(
new GeoDataStyle);
379 style->setLineStyle( lineStyle );
380 style->setPolyStyle( polyStyle );
381 style->setId(QStringLiteral(
"default"));
384 fileList << filename;
387 renderOrderList << renderOrder;
392 for(
const GeoSceneGeodata &data: currentDatasets) {
393 d->m_fileManager.removeFile( data.sourceFile() );
396 for (
int i = 0 ; i < fileList.
size(); ++i ) {
397 d->m_fileManager.addFile( fileList.
at(i), propertyList.
at(i), styleList.
at(i), MapDocument, renderOrderList.
at(i) );
400 mDebug() <<
"THEME CHANGED: ***" << mapTheme->head()->mapThemeId();
404 void MarbleModelPrivate::addHighlightStyle(GeoDataDocument *doc)
const
411 QColor highlightBrushColor = m_mapTheme->map()->highlightBrushColor();
412 QColor highlightPenColor = m_mapTheme->map()->highlightPenColor();
414 GeoDataStyle::Ptr highlightStyle(
new GeoDataStyle);
415 highlightStyle->setId(QStringLiteral(
"highlight"));
417 if ( highlightBrushColor.
isValid() ) {
418 GeoDataPolyStyle highlightPolyStyle;
419 highlightPolyStyle.setColor( highlightBrushColor );
420 highlightPolyStyle.setFill(
true );
421 highlightStyle->setPolyStyle( highlightPolyStyle );
423 if ( highlightPenColor.
isValid() ) {
424 GeoDataLineStyle highlightLineStyle( highlightPenColor );
425 highlightStyle->setLineStyle( highlightLineStyle );
427 if ( highlightBrushColor.
isValid()
428 || highlightPenColor.
isValid() )
430 GeoDataStyleMap styleMap = doc->styleMap(QStringLiteral(
"default-map"));
431 styleMap.insert(QStringLiteral(
"highlight"),
QLatin1Char(
'#') + highlightStyle->id());
432 doc->addStyle( highlightStyle );
433 doc->addStyleMap( styleMap );
440 d->m_homePoint.geoCoordinates( lon, lat, GeoDataCoordinates::Degree );
441 zoom = d->m_homeZoom;
447 d->m_homeZoom = zoom;
453 d->m_homePoint = homePoint;
454 d->m_homeZoom = zoom;
460 return &d->m_downloadManager;
465 return &d->m_downloadManager;
471 return &d->m_treeModel;
476 return &d->m_treeModel;
481 return &d->m_placemarkProxyModel;
486 return &d->m_placemarkProxyModel;
491 return &d->m_groundOverlayProxyModel;
496 return &d->m_groundOverlayProxyModel;
501 return &d->m_placemarkSelectionModel;
504 PositionTracking *MarbleModel::positionTracking()
const
506 return &d->m_positionTracking;
509 FileManager *MarbleModel::fileManager()
511 return &d->m_fileManager;
514 qreal MarbleModel::planetRadius()
const
516 return d->m_planet.radius();
519 QString MarbleModel::planetName()
const
521 return d->m_planet.name();
524 QString MarbleModel::planetId()
const
526 return d->m_planet.id();
529 MarbleClock *MarbleModel::clock()
534 const MarbleClock *MarbleModel::clock()
const
539 SunLocator *MarbleModel::sunLocator()
541 return &d->m_sunLocator;
544 const SunLocator *MarbleModel::sunLocator()
const
546 return &d->m_sunLocator;
551 return d->m_storageWatcher.cacheLimit() / 1024;
554 void MarbleModel::clearPersistentTileCache()
556 d->m_storagePolicy.clearCache();
559 if ( d->m_mapTheme->map()->hasTextureLayers() || d->m_mapTheme->map()->hasVectorLayers() ) {
565 QString themeID = d->m_mapTheme->head()->theme();
568 static_cast<const GeoSceneLayer*
>( d->m_mapTheme->map()->layer( themeID ) );
569 const GeoSceneTileDataset *texture =
570 static_cast<const GeoSceneTileDataset*
>( layer->groundDataset() );
572 QString sourceDir = texture->sourceDir();
573 QString installMap = texture->installMap();
574 QString role = d->m_mapTheme->map()->layer( themeID )->role();
576 if ( !TileLoader::baseTilesAvailable( *texture )
579 mDebug() <<
"Base tiles not available. Creating Tiles ... \n"
580 <<
"SourceDir: " << sourceDir <<
"InstallMap:" << installMap;
583 TileCreator *tileCreator =
new TileCreator(
587 tileCreator->setTileFormat( texture->fileFormat().toLower() );
590 tileCreatorDlg->setSummary( d->m_mapTheme->head()->name(),
591 d->m_mapTheme->head()->description() );
592 tileCreatorDlg->exec();
593 qDebug(
"Tile creation completed");
594 delete tileCreatorDlg;
601 d->m_storageWatcher.setCacheLimit( kiloBytes * 1024 );
605 if( !d->m_storageWatcher.isRunning() )
610 d->m_storageWatcher.quit();
617 d->m_trackedPlacemark = placemark;
623 return d->m_trackedPlacemark;
628 return &d->m_pluginManager;
631 PluginManager* MarbleModel::pluginManager()
633 return &d->m_pluginManager;
650 const QString themeId = mapTheme->head()->theme();
655 const GeoSceneTileDataset *
const texture =
static_cast<const GeoSceneTileDataset*
>( layer->groundDataset() );
662 for (; pos != end; ++pos ) {
663 d->m_downloadManager.addDownloadPolicy( **pos );
667 RoutingManager* MarbleModel::routingManager()
669 return d->m_routingManager;
672 const RoutingManager* MarbleModel::routingManager()
const
674 return d->m_routingManager;
677 void MarbleModel::setClockDateTime(
const QDateTime& datetime )
679 d->m_clock.setDateTime( datetime );
682 QDateTime MarbleModel::clockDateTime()
const
684 return d->m_clock.dateTime();
687 int MarbleModel::clockSpeed()
const
689 return d->m_clock.speed();
692 void MarbleModel::setClockSpeed(
int speed )
694 d->m_clock.setSpeed( speed );
697 void MarbleModel::setClockTimezone(
int timeInSec )
699 d->m_clock.setTimezone( timeInSec );
702 int MarbleModel::clockTimezone()
const
704 return d->m_clock.timezone();
715 d->m_legend = legend;
720 d->m_fileManager.addFile( filename, filename,
GeoDataStyle::Ptr(), UserDocument, 0,
true );
725 d->m_fileManager.addData( key, data, UserDocument );
730 d->m_fileManager.removeFile( fileName );
733 void MarbleModel::updateProperty(
const QString &property,
bool value )
735 for(
GeoDataFeature *feature: d->m_treeModel.rootDocument()->featureList()) {
736 if (
auto document = geodata_cast<GeoDataDocument>(feature)) {
738 document->setVisible( value );
739 d->m_treeModel.updateFeature( document );
745 void MarbleModelPrivate::assignFillColors(
const QString &filePath)
747 const GeoSceneGeodata *data =
nullptr;
749 for (
auto layer : m_mapTheme->map()->layers()) {
750 if (layer->backend() != dgml::dgmlValue_geodata
751 && layer->backend() != dgml::dgmlValue_vector) {
755 for (
auto dataset: layer->datasets()) {
756 auto sceneData =
dynamic_cast<const GeoSceneGeodata *
>(dataset);
757 if (sceneData !=
nullptr && sceneData->sourceFile() == filePath) {
768 if (data ==
nullptr) {
772 GeoDataDocument *doc = m_fileManager.at(filePath);
775 assignFillColors(doc, *data);
778 void MarbleModelPrivate::assignFillColors(GeoDataDocument *doc,
const GeoSceneGeodata &data)
const
780 addHighlightStyle( doc );
782 const QPen pen = data.pen();
783 const QBrush brush = data.brush();
785 GeoDataLineStyle lineStyle( pen.
color() );
786 lineStyle.setPenStyle( pen.
style() );
787 lineStyle.setWidth( pen.
width() );
790 const qreal alpha = data.alpha();
791 for (
auto feature : *doc) {
792 auto placemark = geodata_cast<GeoDataPlacemark>(feature);
793 if (placemark ==
nullptr) {
797 GeoDataStyle::Ptr style(
new GeoDataStyle);
798 style->setId(QStringLiteral(
"normal"));
799 style->setLineStyle( lineStyle );
800 quint8 colorIndex = placemark->style()->polyStyle().colorIndex();
801 GeoDataPolyStyle polyStyle;
803 polyStyle.setColorIndex( colorIndex );
806 Q_ASSERT( colors.
size() );
807 if (colorIndex > colors.
size() || (colorIndex - 1) < 0) {
811 color = colors[colorIndex-1];
814 polyStyle.setColor( color );
815 polyStyle.setFill(
true );
816 style->setPolyStyle( polyStyle );
817 placemark->setStyle( style );
821 GeoDataStyle::Ptr style(
new GeoDataStyle);
822 GeoDataPolyStyle polyStyle( brush.
color() );
823 polyStyle.setFill(
true );
824 style->setLineStyle( lineStyle );
825 style->setPolyStyle( polyStyle );
826 style->setId(QStringLiteral(
"default"));
827 GeoDataStyleMap styleMap;
828 styleMap.setId(QStringLiteral(
"default-map"));
829 styleMap.insert(QStringLiteral(
"normal"),
QLatin1Char(
'#') + style->id());
830 doc->addStyle( style );
831 doc->addStyleMap( styleMap );
835 for (
auto feature : *doc) {
836 auto placemark = geodata_cast<GeoDataPlacemark>(feature);
837 if (placemark ==
nullptr) {
841 if (geodata_cast<GeoDataTrack>(placemark->geometry()) ||
842 geodata_cast<GeoDataPoint>(placemark->geometry())) {
846 placemark->setStyleUrl(styleUrl);
851 bool MarbleModel::workOffline()
const
853 return d->m_workOffline;
856 void MarbleModel::setWorkOffline(
bool workOffline )
858 if ( d->m_workOffline != workOffline ) {
861 d->m_workOffline = workOffline;
862 emit workOfflineChanged();
866 ElevationModel* MarbleModel::elevationModel()
868 return &d->m_elevationModel;
871 const ElevationModel* MarbleModel::elevationModel()
const
873 return &d->m_elevationModel;
878 #include "moc_MarbleModel.cpp"