Some custom map providers will not provide a maps for the entire world , but rather to a small area. While there is a command line option to start marble to point to a location , it is not a feasible solution when requesting a non technical person to start with command line options (In addition to the need for asking a person to put files a directory) Reproducible: Always Steps to Reproduce: 1. take a dgml with a custom server that does not support world wide tiles 2. choose dgml in marble Actual Results: no easy way to set the center location in the dgml. Expected Results: an option to set center location in the dgml file. From 79afd8a250b40ae76de950708a991c07b8a58853 Mon Sep 17 00:00:00 2001 From: boris <boris@bugs.local> Date: Sat, 30 Jan 2016 13:17:09 +0200 Subject: [PATCH] lonlat from dgml When loading a dgml file , a feature needed to center the map on a specific location. usecase : big boss need to see a map that will start on a custom tile server (which only show the city). it is hard enough for an IT/dev person to ask him to download and unpack a theme file, asking him to run something from command line is asking for trouble. --- src/apps/marble-kde/KdeMainWindow.cpp | 18 ++++++++ src/apps/marble-kde/KdeMainWindow.h | 1 + src/apps/marble-qt/QtMainWindow.cpp | 22 +++++++++- src/apps/marble-qt/QtMainWindow.h | 1 + src/lib/marble/geodata/CMakeLists.txt | 2 + .../geodata/handlers/dgml/DgmlCenterTagHandler.cpp | 48 ++++++++++++++++++++++ .../geodata/handlers/dgml/DgmlCenterTagHandler.h | 41 ++++++++++++++++++ .../handlers/dgml/DgmlElementDictionary.cpp | 1 + .../geodata/handlers/dgml/DgmlElementDictionary.h | 1 + src/lib/marble/geodata/scene/GeoSceneMap.cpp | 22 ++++++++++ src/lib/marble/geodata/scene/GeoSceneMap.h | 13 +++++- 11 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.cpp create mode 100644 src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.h diff --git a/src/apps/marble-kde/KdeMainWindow.cpp b/src/apps/marble-kde/KdeMainWindow.cpp index c4fd3b1..932acf8 100644 --- a/src/apps/marble-kde/KdeMainWindow.cpp +++ b/src/apps/marble-kde/KdeMainWindow.cpp @@ -71,6 +71,9 @@ MainWindow::MainWindow( const QString& marbleDataPath, QWidget *parent ) connect( marbleWidget(), SIGNAL(themeChanged(QString)), this, SLOT(setMapTitle())); + connect( marbleWidget(), SIGNAL(themeChanged(QString)), + this, SLOT(updateCenterFromTheme())); + } MainWindow::~MainWindow() @@ -97,6 +100,21 @@ void MainWindow::setMapTitle() } } +void MainWindow::updateCenterFromTheme() +{ + //A scene provider may provide only a subset of the globe, use scene properties read from a dgml as a starting point + GeoSceneDocument * theme = m_controlView->marbleModel()->mapTheme(); + if (theme) { + const GeoSceneMap* map = theme->map(); + if (map) { + const QVariantList lonLat = map->center(); + if (! lonLat.empty()) { + m_controlView->marbleWidget()->centerOn( lonLat.at(0).toDouble(), lonLat.at(1).toDouble() ); + } + } + } +} + void MainWindow::changeViewSize( QAction* action ) { mDebug()<<size(); diff --git a/src/apps/marble-kde/KdeMainWindow.h b/src/apps/marble-kde/KdeMainWindow.h index b961c6f..f0e45ac 100644 --- a/src/apps/marble-kde/KdeMainWindow.h +++ b/src/apps/marble-kde/KdeMainWindow.h @@ -41,6 +41,7 @@ class MainWindow : public KXmlGuiWindow public slots: void setMapTitle(); void changeViewSize( QAction* ); + void updateCenterFromTheme(); protected: void closeEvent( QCloseEvent *event ); diff --git a/src/apps/marble-qt/QtMainWindow.cpp b/src/apps/marble-qt/QtMainWindow.cpp index a0491a3..1535afc 100644 --- a/src/apps/marble-qt/QtMainWindow.cpp +++ b/src/apps/marble-qt/QtMainWindow.cpp @@ -65,6 +65,8 @@ #include "NewBookmarkFolderDialog.h" #include "GeoSceneDocument.h" #include "GeoSceneHead.h" +#include "GeoSceneMap.h" + #include "GeoDataCoordinates.h" #include "GeoDataDocument.h" #include "GeoDataFolder.h" @@ -219,6 +221,9 @@ MainWindow::MainWindow(const QString& marbleDataPath, const QVariantMap& cmdLine this, SLOT(updateMapEditButtonVisibility(QString)) ); connect(m_controlView->marbleModel(), SIGNAL(themeChanged(QString)), this, SLOT(updateApplicationTitle(QString))); + connect(m_controlView->marbleModel(), SIGNAL(themeChanged(QString)), + this, SLOT(updateCenterFromTheme())); + connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) ); connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) ); @@ -1626,6 +1631,22 @@ void MainWindow::updateApplicationTitle(const QString&) } } +void MainWindow::updateCenterFromTheme() +{ + //A scene provider may provide only a subset of the globe, use scene properties read from a dgml as a starting point + GeoSceneDocument * theme = m_controlView->marbleModel()->mapTheme(); + if (theme) { + const GeoSceneMap* map = theme->map(); + if (map) { + const QVariantList lonLat = map->center(); + if (! lonLat.empty()) { + qDebug() << __FUNCTION__ << " lonlat:" << QString::number(lonLat.at(0).toDouble()) << "," << QString::number(lonLat.at(1).toDouble()) ; + m_controlView->marbleWidget()->centerOn( lonLat.at(0).toDouble(), lonLat.at(1).toDouble() ); + } + } + } +} + void MainWindow::showMapWizard() { QPointer<MapWizard> mapWizard = new MapWizard(); @@ -1686,5 +1707,4 @@ void MainWindow::changeViewSize( QAction* action ) m_savedSize.setHeight( -1 ); } } - #include "moc_QtMainWindow.cpp" diff --git a/src/apps/marble-qt/QtMainWindow.h b/src/apps/marble-qt/QtMainWindow.h index ff82641..430edb8 100644 --- a/src/apps/marble-qt/QtMainWindow.h +++ b/src/apps/marble-qt/QtMainWindow.h @@ -85,6 +85,7 @@ private Q_SLOTS: void changeRecordingState(); void updateApplicationTitle(const QString&); + void updateCenterFromTheme(); // File Menu void openFile(); diff --git a/src/lib/marble/geodata/CMakeLists.txt b/src/lib/marble/geodata/CMakeLists.txt index fe0a919..20e73a1 100644 --- a/src/lib/marble/geodata/CMakeLists.txt +++ b/src/lib/marble/geodata/CMakeLists.txt @@ -143,6 +143,7 @@ SET ( geodata_handlers_dgml_SRCS geodata/handlers/dgml/DgmlThemeTagHandler.h geodata/handlers/dgml/DgmlSettingsTagHandler.h geodata/handlers/dgml/DgmlDescriptionTagHandler.h + geodata/handlers/dgml/DgmlCenterTagHandler.h geodata/handlers/dgml/DgmlBrushTagHandler.cpp geodata/handlers/dgml/DgmlSectionTagHandler.h geodata/handlers/dgml/DgmlTextureTagHandler.h @@ -162,6 +163,7 @@ SET ( geodata_handlers_dgml_SRCS geodata/handlers/dgml/DgmlTileSizeTagHandler.cpp geodata/handlers/dgml/DgmlTextureTagHandler.cpp geodata/handlers/dgml/DgmlPenTagHandler.cpp + geodata/handlers/dgml/DgmlCenterTagHandler.cpp geodata/handlers/dgml/DgmlDescriptionTagHandler.cpp geodata/handlers/dgml/DgmlElementDictionary.h geodata/handlers/dgml/DgmlIconTagHandler.cpp diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.cpp new file mode 100644 index 0000000..8289709 --- /dev/null +++ b/src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.cpp @@ -0,0 +1,48 @@ +/* + Copyright (C) 2015 Boris Shtrasman + + This file is part of the KDE project + + This library is free software you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "DgmlCenterTagHandler.h" + +#include "DgmlElementDictionary.h" +#include "GeoParser.h" +#include "GeoSceneMap.h" + +namespace Marble +{ +namespace dgml +{ +DGML_DEFINE_TAG_HANDLER(Center) + +GeoNode* DgmlCenterTagHandler::parse(GeoParser& parser) const +{ + // Check whether the tag is valid + Q_ASSERT(parser.isStartElement() && parser.isValidElement(dgmlTag_Center)); + + // Checking for parent item + GeoStackItem parentItem = parser.parentElement(); + if (parentItem.represents(dgmlTag_Map)) + parentItem.nodeAs<GeoSceneMap>()->setCenter( parser.readElementText().trimmed() ); + + return 0; +} + +} +} diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.h b/src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.h new file mode 100644 index 0000000..1605a74 --- /dev/null +++ b/src/lib/marble/geodata/handlers/dgml/DgmlCenterTagHandler.h @@ -0,0 +1,41 @@ +/* + Copyright (C) 2015 Boris Shtrasman + + This file is part of the KDE project + + This library is free software you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef MARBLE_DGML_CENTERTAGHANDLER_H +#define MARBLE_DGML_CENTERTAGHANDLER_H + +#include "GeoTagHandler.h" + +namespace Marble +{ +namespace dgml +{ + +class DgmlCenterTagHandler : public GeoTagHandler +{ +public: + virtual GeoNode* parse(GeoParser&) const; +}; + +} +} + +#endif diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.cpp b/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.cpp index 96d26e3..0a83b71 100644 --- a/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.cpp +++ b/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.cpp @@ -34,6 +34,7 @@ const char* dgmlTag_Available = "available"; const char* dgmlTag_Blending = "blending"; const char* dgmlTag_Brush = "brush"; const char* dgmlTag_Color = "color"; +const char* dgmlTag_Center = "center"; const char* dgmlTag_CustomPlugin = "customplugin"; const char* dgmlTag_Dem = "dem"; const char* dgmlTag_Description = "description"; diff --git a/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.h b/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.h index b08c3c3..1fedaf1 100644 --- a/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.h +++ b/src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.h @@ -36,6 +36,7 @@ namespace dgml extern const char* dgmlTag_Available; extern const char* dgmlTag_Blending; extern const char* dgmlTag_Brush; + extern const char* dgmlTag_Center; extern const char* dgmlTag_Color; extern const char* dgmlTag_CustomPlugin; extern const char* dgmlTag_Dem; diff --git a/src/lib/marble/geodata/scene/GeoSceneMap.cpp b/src/lib/marble/geodata/scene/GeoSceneMap.cpp index 9b4966e..7c49508 100644 --- a/src/lib/marble/geodata/scene/GeoSceneMap.cpp +++ b/src/lib/marble/geodata/scene/GeoSceneMap.cpp @@ -26,6 +26,8 @@ #include "GeoSceneFilter.h" #include "DgmlAuxillaryDictionary.h" +#include <GeoDataCoordinates.h> + namespace Marble { @@ -50,6 +52,8 @@ class GeoSceneMapPrivate return GeoSceneTypes::GeoSceneMapType; } + QVariantList m_center; + /// The vector holding all the sections in the legend. /// (We want to preserve the order and don't care /// much about speed here), so we don't use a hash @@ -166,6 +170,24 @@ void GeoSceneMap::addFilter( GeoSceneFilter* filter ) } } +QVariantList GeoSceneMap::center() const +{ + return d->m_center; +} + +void GeoSceneMap::setCenter(const QString & coordinatesString) +{ + bool success = false; + const GeoDataCoordinates coordinates = GeoDataCoordinates::fromString(coordinatesString, success); + + if ( success ) { + QVariantList lonLat; + lonLat << QVariant( coordinates.longitude(GeoDataCoordinates::Degree) ) + << QVariant( coordinates.latitude(GeoDataCoordinates::Degree) ); + d->m_center = lonLat; + } +} + GeoSceneFilter* GeoSceneMap::filter( const QString& name ) { GeoSceneFilter* filter = 0; diff --git a/src/lib/marble/geodata/scene/GeoSceneMap.h b/src/lib/marble/geodata/scene/GeoSceneMap.h index 42db5b4..f01b387 100644 --- a/src/lib/marble/geodata/scene/GeoSceneMap.h +++ b/src/lib/marble/geodata/scene/GeoSceneMap.h @@ -25,6 +25,7 @@ #include <QColor> #include <QString> #include <QVector> +#include <QVariant> #include <geodata_export.h> @@ -64,7 +65,17 @@ class GEODATA_EXPORT GeoSceneMap : public GeoNode * @param section The new layer */ void addLayer( GeoSceneLayer* ); - + /** + * @ brief Set starting center with lon lat cooredinates + * used if a scene downloadUrl do not handle elements in other locations + */ + void setCenter(const QString & coordinateString); + /** + * @breif Get starting center with cooredinates + * used if a scene downloadUrl do not handle elements in other locations + * return A QVariantList of lon lat as specified in the dgml + */ + QVariantList center() const; /** * @brief Return a layer by its name * @param name The name of the layer -- 2.7.0
Created attachment 96928 [details] [PATCH] lonlat from dgml
Sorry, this nice patch got completely "drowned" and remained undiscovered in our bug database. A better place for submission would have been Gitlab at https://invent.kde.org/education/marble/-/merge_requests Thanks for the contribution - this is indeed a feature that I had planned since long to get implemented. I will review this and will add this (likely with modifications) to our codebase. Thanks a lot!
My need for this patch arises from the usecase of creating WMS-based dgml-themes. Many WMS services just cover a particular geodetic bounding box (and many are only meant as an overlay to be used for "groundlayers"). Now there are two issues in this context which I currently consider: - Ideally instead of "centerOn" I'd like to rather see "setViewLatLon(Alt)Box()" which would also steer the zoomlevel to ensure that a particular region gets centered and fully displayed. The case where the map should only be centered could be accomplished by using the same API with a boundingbox that has no size (and is a point). - In the implementation of the patch the centering is done whenever the map theme changes if the map theme specifies a center-point. I'm not sure whether this is a good approach. During application startup we have the option to either center on the "home position" or to recall zoom level and center point last time when Marble was quit. Also we usually don't change the view when a map theme is changed. I see several other usecases where one might want a different behavior: - The centerOn/setViewLatLonAltBox would only get applied the first time the map theme gets invoked (however that is impossible to detect at the moment). - The centerOn/setViewLatLonAltBox would only get applied if the current point that Marble focuses on is not in the valid boundingbox specified for the map theme. - Or as this patch does we always enforce centerOn/setViewLatLonAltBox whenever the map theme is invoked. Of course we could add an option that would override this behavior (globally or restricted to this map theme) but that would make things increasingly complex. Tough choice :-)
Another finding: Marble already has void MarbleAbstractPresenter::centerOn(const GeoDataLatLonBox &box, bool animated) implemented which is available in MarbleWidget and which tries to approximate the setViewLatLon(Alt)Box() behavior mentioned before. The implementation of this method is not ideal (see https://bugs.kde.org/show_bug.cgi?id=461569) but should work well enough for a start.
Git commit a4aa19db604e1c233982b20e1ab886df76839094 by Torsten Rahn. Committed on 24/04/2023 at 11:55. Pushed by rahn into branch 'master'. Patch by Boris Shhtrasman: - dgml is missing an option center the map (lonlat) In order to integrate this with MapWizard's WMS support I changed the behavior by - centering on the geodetic boundingbox instead of a geodetic point - only center when the map theme is changed if the current view points outside the boundingbox of the map theme. M +35 -0 src/apps/marble-kde/KdeMainWindow.cpp M +1 -0 src/apps/marble-kde/KdeMainWindow.h M +35 -1 src/apps/marble-qt/QtMainWindow.cpp M +1 -0 src/apps/marble-qt/QtMainWindow.h M +12 -0 src/lib/marble/MapWizard.cpp M +36 -0 src/lib/marble/OwsServiceManager.cpp M +1 -0 src/lib/marble/OwsServiceManager.h M +2 -0 src/lib/marble/geodata/CMakeLists.txt M +1 -1 src/lib/marble/geodata/data/GeoDataCoordinates.h M +1 -0 src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.cpp M +1 -0 src/lib/marble/geodata/handlers/dgml/DgmlElementDictionary.h M +31 -0 src/lib/marble/geodata/scene/GeoSceneMap.cpp M +12 -1 src/lib/marble/geodata/scene/GeoSceneMap.h M +16 -1 src/lib/marble/geodata/writers/dgml/DgmlMapTagWriter.cpp https://invent.kde.org/education/marble/commit/a4aa19db604e1c233982b20e1ab886df76839094
Hello Boris, sorry, but for the lack of your realname I had looked up your name on the Internet and copied your name over from https://kdepim-bugs.kde.narkive.com/9IhS4B3v/akonadi-bug-339393-new-akonadi-fail-to-fetch-imap-folder-content-with-over-100mib-of-messages where this typo was unfortunately included. Again sorry, and also sorry that this took so long. I had been basically on parental leave during the last few years (with a great wife and two marbleous kids). Your patch has made the WMS improvements that I'm looking into a whole lot more enjoyable. Thanks for that! :-)
Thank you a lot, sorry for that link as well. I need to see how that had happened in the first place :) On Tuesday, 25 April 2023 20:38:53 IDT Torsten Rahn wrote: > https://bugs.kde.org/show_bug.cgi?id=358779 > > --- Comment #6 from Torsten Rahn <rahn@kde.org> --- > Hello Boris, > > sorry, but for the lack of your realname I had looked up your name on the > Internet and copied your name over from > https://kdepim-bugs.kde.narkive.com/9IhS4B3v/akonadi-bug-339393-new-akonadi-fail-to-fetch-imap-folder-content-with-over-100mib-of-messages > where this typo was unfortunately included. > > Again sorry, and also sorry that this took so long. I had been basically on > parental leave during the last few years (with a great wife and two marbleous > kids). > > Your patch has made the WMS improvements that I'm looking into a whole lot more > enjoyable. Thanks for that! :-) > >