diff --git a/src/apps/marble-maps/PlacemarkDialog.qml b/src/apps/marble-maps/PlacemarkDialog.qml index 904484bd7..f91e7f0bd 100644 --- a/src/apps/marble-maps/PlacemarkDialog.qml +++ b/src/apps/marble-maps/PlacemarkDialog.qml @@ -1,175 +1,181 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2015 Dennis Nienhüser // import QtQuick 2.3 import QtQuick.Controls 1.3 import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 import org.kde.edu.marble 0.20 Item { id: root property var placemark: null property bool condensed: true property string actionIconSource: routeEditor.currentProfileIcon property alias map: bookmarks.map height: placemark === null ? 0 : Screen.pixelDensity * 6 + infoLayout.height function addToRoute() { ensureRouteHasDeparture() routing.addViaByPlacemarkAtIndex(routing.waypointCount(), placemark) routing.clearSearchResultPlacemarks() placemark = null itemStack.state = "routing" } onPlacemarkChanged: { if (placemark) { bookmarkButton.bookmark = bookmarks.isBookmark(placemark.longitude, placemark.latitude) itemStack.state = "place" } else { condensed = true itemStack.state = "" } } SystemPalette { id: palette colorGroup: SystemPalette.Active } Rectangle { anchors.fill: parent color: palette.base } MouseArea { anchors.fill: parent onClicked: { condensed = !condensed } } Bookmarks { id: bookmarks } Column { id: infoLayout anchors { top: parent.top left: parent.left right: bookmarkButton.left margins: Screen.pixelDensity * 2 } IconText { id: name width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.name maximumLineCount: 2 font.pointSize: 20 } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.description maximumLineCount: condensed ? 4 : undefined } + IconText { + width: parent.width + visible: placemark != null && placemark.elevation != "" + text: placemark === null ? "" : ("Elevation : " + placemark.elevation + " m") + } + IconText { width: parent.width visible: text.length > 0 && (!condensed || name.text === "") text: placemark === null ? "" : placemark.address maximumLineCount: 4 } IconText { width: parent.width visible: url.length > 0 property string url: placemark === null ? "" : placemark.website text: "" + url + "" icon: "qrc:/material/browser.svg" maximumLineCount: 4 } IconText { width: parent.width visible: url.length > 0 property string url: placemark === null ? "" : placemark.wikipedia text: "Wikipedia" icon: "qrc:/material/browser.svg" maximumLineCount: 4 } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.fuelDetails icon: "qrc:/material/gas_station.svg" } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.openingHours icon: "qrc:/material/access_time.svg" } IconText { width: parent.width visible: text.length > 0 && (!condensed || name.text === "") text: placemark === null ? "" : placemark.coordinates icon: "qrc:/material/place.svg" } } Image { id: bookmarkButton anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: Screen.pixelDensity * 2 visible: root.height > 0 property bool bookmark: false width: Screen.pixelDensity * 6 height: width sourceSize.height: height sourceSize.width: width source: bookmark ? "qrc:/material/star.svg" : "qrc:/material/star_border.svg" MouseArea { id: touchArea anchors.fill: parent onClicked: { if (bookmarkButton.bookmark) { bookmarks.removeBookmark(root.placemark.longitude, root.placemark.latitude) } else { bookmarks.addBookmark(root.placemark, "Default") } bookmarkButton.bookmark = !bookmarkButton.bookmark } } } function ensureRouteHasDeparture() { if (routing.routeRequestModel.count === 0) { if (marbleMaps.positionAvailable) { routing.addViaByPlacemark(marbleMaps.currentPosition) } } } } diff --git a/src/lib/marble/MarbleWidgetPopupMenu.cpp b/src/lib/marble/MarbleWidgetPopupMenu.cpp index a51844d53..f031c0ba7 100644 --- a/src/lib/marble/MarbleWidgetPopupMenu.cpp +++ b/src/lib/marble/MarbleWidgetPopupMenu.cpp @@ -1,872 +1,894 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2007 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2012 Illya Kovalevskyy // Copyright 2014 Gábor Péterffy // // Self #include "MarbleWidgetPopupMenu.h" // Marble #include "AbstractDataPluginItem.h" #include "AbstractFloatItem.h" #include "MarbleAboutDialog.h" #include "MarbleDirs.h" #include "MarbleWidget.h" #include "MarbleModel.h" #include "GeoDataExtendedData.h" #include "GeoDataFolder.h" #include "GeoDataPlacemark.h" #include "GeoDataSnippet.h" #include "GeoDataStyle.h" #include "GeoDataIconStyle.h" #include "GeoDataTypes.h" #include "GeoDataPhotoOverlay.h" #include "GeoSceneDocument.h" #include "GeoSceneHead.h" #include "MarbleClock.h" #include "MarbleDebug.h" #include "PopupLayer.h" #include "Planet.h" #include "routing/RoutingManager.h" #include "routing/RoutingLayer.h" #include "routing/RouteRequest.h" #include "EditBookmarkDialog.h" #include "BookmarkManager.h" #include "ReverseGeocodingRunnerManager.h" #include "TemplateDocument.h" #include "OsmPlacemarkData.h" #include "StyleBuilder.h" // Qt #include #include #include #include #include #include #include #include namespace Marble { /* TRANSLATOR Marble::MarbleWidgetPopupMenu */ class Q_DECL_HIDDEN MarbleWidgetPopupMenu::Private { public: const MarbleModel *const m_model; MarbleWidget *const m_widget; QVector m_featurelist; QList m_itemList; QMenu m_lmbMenu; QMenu m_rmbMenu; QAction *m_infoDialogAction; QAction *m_directionsFromHereAction; QAction *m_directionsToHereAction; QAction *const m_copyCoordinateAction; QAction *m_rmbExtensionPoint; ReverseGeocodingRunnerManager m_runnerManager; QPoint m_mousePosition; public: Private( MarbleWidget *widget, const MarbleModel *model, MarbleWidgetPopupMenu* parent ); QMenu* createInfoBoxMenu(); /** * Returns the geo coordinates of the mouse pointer at the last right button menu. * You must not pass 0 as coordinates parameter. The result indicates whether the * coordinates are valid, which will be true if the right button menu was opened at least once. */ GeoDataCoordinates mouseCoordinates( QAction* dataContainer ) const; static QString filterEmptyShortDescription( const QString &description ); void setupDialogOsm( PopupLayer *popup, const GeoDataPlacemark* placemark ); void setupDialogSatellite( const GeoDataPlacemark *placemark ); static void setupDialogCity( PopupLayer *popup, const GeoDataPlacemark *placemark ); static void setupDialogNation( PopupLayer *popup, const GeoDataPlacemark *placemark ); static void setupDialogGeoPlaces( PopupLayer *popup, const GeoDataPlacemark *placemark ); static void setupDialogSkyPlaces( PopupLayer *popup, const GeoDataPlacemark *placemark ); static void setupDialogPhotoOverlay( PopupLayer *popup, const GeoDataPhotoOverlay *overlay); }; MarbleWidgetPopupMenu::Private::Private( MarbleWidget *widget, const MarbleModel *model, MarbleWidgetPopupMenu* parent ) : m_model(model), m_widget(widget), m_lmbMenu( m_widget ), m_rmbMenu( m_widget ), m_directionsFromHereAction( 0 ), m_directionsToHereAction( 0 ), m_copyCoordinateAction( new QAction( QIcon(":/icons/copy-coordinates.png"), tr("Copy Coordinates"), parent ) ), m_rmbExtensionPoint( 0 ), m_runnerManager( model ) { // Property actions (Left mouse button) m_infoDialogAction = new QAction( parent ); m_infoDialogAction->setData( 0 ); // Tool actions (Right mouse button) m_directionsFromHereAction = new QAction( tr( "Directions &from here" ), parent ); m_directionsToHereAction = new QAction( tr( "Directions &to here" ), parent ); RouteRequest* request = m_widget->model()->routingManager()->routeRequest(); if ( request ) { m_directionsFromHereAction->setIcon( QIcon( request->pixmap( 0, 16 ) ) ); int const lastIndex = qMax( 1, request->size()-1 ); m_directionsToHereAction->setIcon( QIcon( request->pixmap( lastIndex, 16 ) ) ); } QAction* addBookmark = new QAction( QIcon(":/icons/bookmark-new.png"), tr( "Add &Bookmark" ), parent ); QAction* fullscreenAction = new QAction( tr( "&Full Screen Mode" ), parent ); fullscreenAction->setCheckable( true ); QAction* aboutDialogAction = new QAction( QIcon(":/icons/marble.png"), tr( "&About" ), parent ); QMenu* infoBoxMenu = createInfoBoxMenu(); const bool smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen; if ( !smallScreen ) { m_rmbExtensionPoint = m_rmbMenu.addSeparator(); } m_rmbMenu.addAction( m_directionsFromHereAction ); m_rmbMenu.addAction( m_directionsToHereAction ); m_rmbMenu.addSeparator(); m_rmbMenu.addAction( addBookmark ); if ( !smallScreen ) { m_rmbMenu.addAction( m_copyCoordinateAction ); } m_rmbMenu.addAction( QIcon(":/icons/addressbook-details.png"), tr( "&Address Details" ), parent, SLOT(startReverseGeocoding()) ); m_rmbMenu.addSeparator(); m_rmbMenu.addMenu( infoBoxMenu ); if ( !smallScreen ) { m_rmbMenu.addAction( aboutDialogAction ); } else { m_rmbMenu.addAction( fullscreenAction ); } parent->connect( &m_lmbMenu, SIGNAL(aboutToHide()), SLOT(resetMenu()) ); parent->connect( m_directionsFromHereAction, SIGNAL(triggered()), SLOT(directionsFromHere()) ); parent->connect( m_directionsToHereAction, SIGNAL(triggered()), SLOT(directionsToHere()) ); parent->connect( addBookmark, SIGNAL(triggered()), SLOT(addBookmark()) ); parent->connect( aboutDialogAction, SIGNAL(triggered()), SLOT(slotAboutDialog()) ); parent->connect( m_copyCoordinateAction, SIGNAL(triggered()), SLOT(slotCopyCoordinates()) ); parent->connect( m_infoDialogAction, SIGNAL(triggered()), SLOT(slotInfoDialog()) ); parent->connect( fullscreenAction, SIGNAL(triggered(bool)), parent, SLOT(toggleFullscreen(bool)) ); parent->connect( &m_runnerManager, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)), parent, SLOT(showAddressInformation(GeoDataCoordinates,GeoDataPlacemark)) ); } QString MarbleWidgetPopupMenu::Private::filterEmptyShortDescription(const QString &description) { if(description.isEmpty()) return tr("No description available."); return description; } void MarbleWidgetPopupMenu::Private::setupDialogOsm( PopupLayer *popup, const GeoDataPlacemark *placemark ) { const GeoDataCoordinates location = placemark->coordinate(); popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/osm.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } QString description = descriptionFile.readAll(); OsmPlacemarkData data = placemark->osmData(); if (!data.containsTagKey("addr:street") && !data.containsTagKey("addr:housenumber")){ description = description.replace("
%postcode%", "%postcode%"); } TemplateDocument doc(description); if (data.containsTagKey("name")){ doc["name"] = data.tagValue("name"); } else { doc["name"] = ""; } + if (data.containsTagKey("natural")){ + QString natural = data.tagValue("natural"); + if (!natural.isEmpty()){ + natural[0] = natural[0].toUpper(); + if (natural == "Peak" && data.containsTagKey("ele")){ + doc["details"] = natural + " - " + data.tagValue("ele") + " m"; + } else { + doc["details"] = natural; + } + } + } else { + doc["detailsVisibility"] = "none"; + } + if (data.containsTagKey("shop")){ QString shop = data.tagValue("shop"); - shop[0] = shop[0].toUpper(); - doc["amenity"] = "Shop - " + shop; + if (!shop.isEmpty()){ + shop[0] = shop[0].toUpper(); + doc["amenity"] = "Shop - " + shop; + } } else if (data.containsTagKey("amenity")){ QString amenity = data.tagValue("amenity"); - amenity[0] = amenity[0].toUpper(); - doc["amenity"] = amenity; + if (!amenity.isEmpty()){ + amenity[0] = amenity[0].toUpper(); + doc["amenity"] = amenity; + } } else { doc["amenityVisibility"] = "none"; } if (data.containsTagKey("cuisine")){ QString cuisine = data.tagValue("cuisine"); - cuisine[0] = cuisine[0].toUpper(); - doc["cuisine"] = cuisine; + if (!cuisine.isEmpty()){ + cuisine[0] = cuisine[0].toUpper(); + doc["cuisine"] = cuisine; + } } else { doc["cuisineVisibility"] = "none"; } if (data.containsTagKey("opening_hours")){ doc["openinghours"] = data.tagValue("opening_hours"); } else { doc["openinghoursVisibility"] = "none"; } bool hasAddressData = false; foreach(const QString &tag, QStringList() << "addr:street" << "addr:housenumber" << "addr:postcode" << "addr:city") { if (data.containsTagKey(tag)){ hasAddressData = true; break; } } bool hasWebsiteData = false; foreach(const QString &tag, QStringList() << "website" << "contact:website" << "facebook" << "contact:facebook" << "url") { if (data.containsTagKey(tag)){ hasWebsiteData = true; break; } } bool hasPhoneData = data.containsTagKey("phone"); bool hasContactsData = hasAddressData || hasPhoneData || hasWebsiteData; if (hasContactsData){ if (hasAddressData){ foreach (const QString tag, QStringList() << "addr:street" << "addr:housenumber" << "addr:postcode" << "addr:city") { if (data.containsTagKey(tag)){ doc[tag.split("addr:")[1]] = data.tagValue(tag); } else { doc[tag.split("addr:")[1]] = ""; } } } else { doc["addressVisibility"] = "none"; } if (hasPhoneData){ doc["phone"] = data.tagValue("phone"); } else { doc["phoneVisibility"] = "none"; } if (hasWebsiteData){ foreach(const QString tag, QStringList() << "website" << "contact:website" << "facebook" << "contact:facebook" << "url") { if (data.containsTagKey(tag)){ doc["website"] = data.tagValue(tag); break; } } } else { doc["websiteVisibility"] = "none"; } } else { doc["contactVisibility"] = "none"; } - if (data.containsTagKey("wheelchair") || data.containsTagKey("internet_access") || data.containsTagKey("smoking")){ + bool hasFacilitiesData = data.containsTagKey("wheelchair") || data.containsTagKey("internet_access") || data.containsTagKey("smoking"); + + if (hasFacilitiesData){ if (data.containsTagKey("wheelchair")){ doc["wheelchair"] = data.tagValue("wheelchair"); } else { doc["wheelchairVisibility"] = "none"; } if (data.containsTagKey("internet_access")){ doc["internetaccess"] = data.tagValue("internet_access"); } else { doc["internetVisibility"] = "none"; } if (data.containsTagKey("smoking")){ doc["smoking"] = data.tagValue("smoking"); } else { doc["smokingVisibility"] = "none"; } } else { doc["facilitiesVisibility"] = "none"; } const QString flagPath = m_widget->styleBuilder()->createStyle(StyleParameters(placemark))->iconStyle().iconPath(); doc["flag"] = flagPath; popup->setContent(doc.finalText()); } void MarbleWidgetPopupMenu::Private::setupDialogSatellite( const GeoDataPlacemark *placemark ) { PopupLayer *const popup = m_widget->popupLayer(); const GeoDataCoordinates location = placemark->coordinate(m_widget->model()->clockDateTime()); popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); const QString description = placemark->description(); TemplateDocument doc(description); doc["altitude"] = QString::number(location.altitude(), 'f', 2); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); popup->setContent(doc.finalText()); } void MarbleWidgetPopupMenu::Private::setupDialogCity( PopupLayer *popup, const GeoDataPlacemark *placemark ) { const GeoDataCoordinates location = placemark->coordinate(); popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/city.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = placemark->name(); QString roleString; const QString role = placemark->role(); if(role=="PPLC") { roleString = tr("National Capital"); } else if(role=="PPL") { roleString = tr("City"); } else if(role=="PPLA") { roleString = tr("State Capital"); } else if(role=="PPLA2") { roleString = tr("County Capital"); } else if(role=="PPLA3" || role=="PPLA4" ) { roleString = tr("Capital"); } else if(role=="PPLF" || role=="PPLG" || role=="PPLL" || role=="PPLQ" || role=="PPLR" || role=="PPLS" || role=="PPLW" ) { roleString = tr("Village"); } doc["category"] = roleString; doc["shortDescription"] = filterEmptyShortDescription(placemark->description()); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); doc["elevation"] = QString::number(location.altitude(), 'f', 2); doc["population"] = QString::number(placemark->population()); doc["country"] = placemark->countryCode(); doc["state"] = placemark->state(); QString dst = QString( "%1" ).arg( ( placemark->extendedData().value("gmt").value().toInt() + placemark->extendedData().value("dst").value().toInt() ) / ( double ) 100, 0, 'f', 1 ); // There is an issue about UTC. // It's possible to variants (e.g.): // +1.0 and -1.0, but dst does not have + an the start if(dst.startsWith('-')) { doc["timezone"] = dst; } else { doc["timezone"] = '+'+dst; } const QString flagPath = MarbleDirs::path( QString("flags/flag_%1.svg").arg(placemark->countryCode().toLower())); doc["flag"] = flagPath; popup->setContent(doc.finalText()); } void MarbleWidgetPopupMenu::Private::setupDialogNation( PopupLayer *popup, const GeoDataPlacemark *index) { const GeoDataCoordinates location = index->coordinate(); popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/nation.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); doc["shortDescription"] = filterEmptyShortDescription(index->description()); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); doc["elevation"] = QString::number(location.altitude(), 'f', 2); doc["population"] = QString::number(index->population()); doc["area"] = QString::number(index->area(), 'f', 2); const QString flagPath = MarbleDirs::path(QString("flags/flag_%1.svg").arg(index->countryCode().toLower()) ); doc["flag"] = flagPath; popup->setContent(doc.finalText()); } void MarbleWidgetPopupMenu::Private::setupDialogGeoPlaces( PopupLayer *popup, const GeoDataPlacemark *index) { const GeoDataCoordinates location = index->coordinate(); popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/geoplace.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); doc["elevation"] = QString::number(location.altitude(), 'f', 2); doc["shortDescription"] = filterEmptyShortDescription(index->description()); popup->setContent(doc.finalText()); } void MarbleWidgetPopupMenu::Private::setupDialogSkyPlaces( PopupLayer *popup, const GeoDataPlacemark *index) { const GeoDataCoordinates location = index->coordinate(); popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/skyplace.html"); if (!descriptionFile.open(QIODevice::ReadOnly)) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); doc["latitude"] = GeoDataCoordinates::latToString( location.latitude(), GeoDataCoordinates::Astro, GeoDataCoordinates::Radian, -1, 'f'); doc["longitude"] = GeoDataCoordinates::lonToString( location.longitude(), GeoDataCoordinates::Astro, GeoDataCoordinates::Radian, -1, 'f'); doc["shortDescription"] = filterEmptyShortDescription(index->description()); popup->setContent(doc.finalText()); } void MarbleWidgetPopupMenu::Private::setupDialogPhotoOverlay( PopupLayer *popup, const GeoDataPhotoOverlay *index ) { const GeoDataCoordinates location = index->point().coordinates(); popup->setCoordinates(location, Qt::AlignRight | Qt::AlignVCenter); QFile descriptionFile(":/marble/webpopup/photooverlay.html"); if ( !descriptionFile.open(QIODevice::ReadOnly) ) { return; } const QString description = descriptionFile.readAll(); TemplateDocument doc(description); doc["name"] = index->name(); doc["latitude"] = location.latToString(); doc["longitude"] = location.lonToString(); doc["elevation"] = QString::number(location.altitude(), 'f', 2); doc["shortDescription"] = filterEmptyShortDescription(index->description()); doc["source"] = index->absoluteIconFile(); doc["width"] = QString::number(200); doc["height"] = QString::number(100); QString const basePath = index->resolvePath("."); QUrl const baseUrl = basePath != "." ? QUrl::fromLocalFile( basePath + "/" ) : QUrl(); popup->setContent(doc.finalText(), baseUrl ); } MarbleWidgetPopupMenu::MarbleWidgetPopupMenu(MarbleWidget *widget, const MarbleModel *model) : QObject(widget), d( new Private( widget, model, this ) ) { // nothing to do } MarbleWidgetPopupMenu::~MarbleWidgetPopupMenu() { delete d; } QMenu* MarbleWidgetPopupMenu::Private::createInfoBoxMenu() { QMenu* menu = new QMenu( tr( "&Info Boxes" ) ); QList floatItemList = m_widget->floatItems(); QList::const_iterator iter = floatItemList.constBegin(); QList::const_iterator const end = floatItemList.constEnd(); for (; iter != end; ++iter ) { menu->addAction( (*iter)->action() ); } return menu; } void MarbleWidgetPopupMenu::showLmbMenu( int xpos, int ypos ) { bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen; if ( smallScreen ) { showRmbMenu( xpos, ypos ); return; } d->m_mousePosition.setX(xpos); d->m_mousePosition.setY(ypos); const QPoint curpos = QPoint( xpos, ypos ); d->m_featurelist = d->m_widget->whichFeatureAt( curpos ); int actionidx = 1; QVector::const_iterator it = d->m_featurelist.constBegin(); QVector::const_iterator const itEnd = d->m_featurelist.constEnd(); for (; it != itEnd; ++it ) { QString name = (*it)->name(); QPixmap icon = QPixmap::fromImage( ( *it)->style()->iconStyle().icon() ); d->m_infoDialogAction->setData( actionidx ); d->m_infoDialogAction->setText( name ); d->m_infoDialogAction->setIcon( icon ); // Insert as first action in the menu QAction *firstAction = 0; if( !d->m_lmbMenu.actions().isEmpty() ) { firstAction = d->m_lmbMenu.actions().first(); } d->m_lmbMenu.insertAction( firstAction, d->m_infoDialogAction ); actionidx++; } d->m_itemList = d->m_widget->whichItemAt( curpos ); QList::const_iterator itW = d->m_itemList.constBegin(); QList::const_iterator const itWEnd = d->m_itemList.constEnd(); for (; itW != itWEnd; ++itW ) { foreach ( QAction* action, (*itW)->actions() ) { d->m_lmbMenu.addAction( action ); } } switch ( d->m_lmbMenu.actions().size() ) { case 0: // nothing to do, ignore break; case 1: // one action? perform immediately d->m_lmbMenu.actions().first()->activate( QAction::Trigger ); d->m_lmbMenu.clear(); break; default: d->m_lmbMenu.popup( d->m_widget->mapToGlobal( curpos ) ); } } void MarbleWidgetPopupMenu::showRmbMenu( int xpos, int ypos ) { qreal lon, lat; const bool visible = d->m_widget->geoCoordinates( xpos, ypos, lon, lat, GeoDataCoordinates::Radian ); if ( !visible ) return; d->m_mousePosition.setX(xpos); d->m_mousePosition.setY(ypos); QPoint curpos = QPoint( xpos, ypos ); d->m_copyCoordinateAction->setData( curpos ); bool const showDirectionButtons = d->m_widget->routingLayer() && d->m_widget->routingLayer()->isInteractive(); d->m_directionsFromHereAction->setVisible( showDirectionButtons ); d->m_directionsToHereAction->setVisible( showDirectionButtons ); RouteRequest* request = d->m_widget->model()->routingManager()->routeRequest(); if ( request ) { int const lastIndex = qMax( 1, request->size()-1 ); d->m_directionsToHereAction->setIcon( QIcon( request->pixmap( lastIndex, 16 ) ) ); } d->m_rmbMenu.popup( d->m_widget->mapToGlobal( curpos ) ); } void MarbleWidgetPopupMenu::resetMenu() { d->m_lmbMenu.clear(); } void MarbleWidgetPopupMenu::slotInfoDialog() { QAction *action = qobject_cast( sender() ); if ( action == 0 ) { mDebug() << "Warning: slotInfoDialog should be called by a QAction signal"; return; } int actionidx = action->data().toInt(); if ( actionidx > 0 ) { const GeoDataPlacemark *placemark = dynamic_cast(d->m_featurelist.at( actionidx -1 )); const GeoDataPhotoOverlay *overlay = dynamic_cast(d->m_featurelist.at( actionidx - 1 )); PopupLayer* popup = d->m_widget->popupLayer(); bool isSatellite = false; bool isCity = false; bool isNation = false; OsmPlacemarkData data = placemark->osmData(); bool hasOsmData = false; QStringList recognizedTags; recognizedTags << "name" << "amenity" << "cuisine" << "opening_hours"; recognizedTags << "addr:street" << "addr:housenumber" << "addr:postcode"; recognizedTags << "addr:city" << "phone" << "wheelchair" << "internet_access"; recognizedTags << "smoking" << "website" << "contact:website" << "facebook"; recognizedTags << "contact:facebook" << "url"; foreach(const QString &tag, recognizedTags) { if (data.containsTagKey(tag)) { hasOsmData = true; break; } } if ( placemark ) { isSatellite = (placemark->visualCategory() == GeoDataFeature::Satellite); isCity = (placemark->visualCategory() >= GeoDataFeature::SmallCity && placemark->visualCategory() <= GeoDataFeature::LargeNationCapital); isNation = (placemark->visualCategory() == GeoDataFeature::Nation); } bool isSky = false; if ( d->m_widget->model()->mapTheme() ) { isSky = d->m_widget->model()->mapTheme()->head()->target() == "sky"; } popup->setSize(QSizeF(400, 400)); if (hasOsmData){ d->setupDialogOsm( popup, placemark ); } else if (isSatellite) { d->setupDialogSatellite( placemark ); } else if (isCity) { Private::setupDialogCity( popup, placemark ); } else if (isNation) { Private::setupDialogNation( popup, placemark ); } else if (isSky) { Private::setupDialogSkyPlaces( popup, placemark ); } else if ( overlay ) { Private::setupDialogPhotoOverlay( popup, overlay ); } else if ( placemark && placemark->role().isEmpty() ) { popup->setContent( placemark->description() ); } else if ( placemark ) { Private::setupDialogGeoPlaces( popup, placemark ); } if ( placemark ) { if ( placemark->style() == 0 ) { popup->setBackgroundColor(QColor(Qt::white)); popup->setTextColor(QColor(Qt::black)); return; } if ( placemark->style()->balloonStyle().displayMode() == GeoDataBalloonStyle::Hide ) { popup->setVisible(false); return; } QString content = placemark->style()->balloonStyle().text(); if (content.length() > 0) { content = content.replace("$[name]", placemark->name(), Qt::CaseInsensitive); content = content.replace("$[description]", placemark->description(), Qt::CaseInsensitive); content = content.replace("$[address]", placemark->address(), Qt::CaseInsensitive); // @TODO: implement the line calculation, so that snippet().maxLines actually has effect. content = content.replace("$[snippet]", placemark->snippet().text(), Qt::CaseInsensitive); content = content.replace("$[id]", placemark->id(), Qt::CaseInsensitive); QString const basePath = placemark->resolvePath("."); QUrl const baseUrl = basePath != "." ? QUrl::fromLocalFile( basePath + "/" ) : QUrl(); popup->setContent(content, baseUrl ); } popup->setBackgroundColor(placemark->style()->balloonStyle().backgroundColor()); popup->setTextColor(placemark->style()->balloonStyle().textColor()); } popup->popup(); } } void MarbleWidgetPopupMenu::slotCopyCoordinates() { const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction ); if ( coordinates.isValid() ) { const qreal longitude_degrees = coordinates.longitude(GeoDataCoordinates::Degree); const qreal latitude_degrees = coordinates.latitude(GeoDataCoordinates::Degree); // importing this representation into Marble does not show anything, // but Merkaartor shows the point const QString kmlRepresentation = QString::fromLatin1( "\n" "\n" "\n" " \n" // " \n" " \n" " %1,%2\n" " \n" " \n" "\n" "\n" ).arg(longitude_degrees, 0, 'f', 10).arg(latitude_degrees, 0, 'f', 10); // importing this data into Marble and Merkaartor works const QString gpxRepresentation = QString::fromLatin1( "\n" "\n" " \n" // " %3\n" // " \n" // " %4\n" " \n" "\n" ).arg(latitude_degrees, 0, 'f', 10).arg(longitude_degrees, 0, 'f', 10); QString positionString = coordinates.toString(); QMimeData * const myMimeData = new QMimeData(); myMimeData->setText(positionString); myMimeData->setData(QLatin1String("application/vnd.google-earth.kml+xml"), kmlRepresentation.toUtf8()); myMimeData->setData(QLatin1String("application/gpx+xml"), gpxRepresentation.toUtf8()); QClipboard * const clipboard = QApplication::clipboard(); clipboard->setMimeData(myMimeData); } } void MarbleWidgetPopupMenu::slotAboutDialog() { QPointer dialog = new MarbleAboutDialog( d->m_widget ); dialog->exec(); delete dialog; } void MarbleWidgetPopupMenu::addAction( Qt::MouseButton button, QAction* action ) { if ( button == Qt::RightButton ) { d->m_rmbMenu.insertAction( d->m_rmbExtensionPoint, action ); } else { d->m_lmbMenu.addAction( action ); } } void MarbleWidgetPopupMenu::directionsFromHere() { RouteRequest* request = d->m_widget->model()->routingManager()->routeRequest(); if ( request ) { const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction ); if ( coordinates.isValid() ) { if ( request->size() > 0 ) { request->setPosition( 0, coordinates ); } else { request->append( coordinates ); } d->m_widget->model()->routingManager()->retrieveRoute(); } } } void MarbleWidgetPopupMenu::directionsToHere() { RouteRequest* request = d->m_widget->model()->routingManager()->routeRequest(); if ( request ) { const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction ); if ( coordinates.isValid() ) { if ( request->size() > 1 ) { request->setPosition( request->size()-1, coordinates ); } else { request->append( coordinates ); } d->m_widget->model()->routingManager()->retrieveRoute(); } } } GeoDataCoordinates MarbleWidgetPopupMenu::Private::mouseCoordinates( QAction* dataContainer ) const { if ( !dataContainer ) { return GeoDataCoordinates(); } if ( !m_featurelist.isEmpty() && m_featurelist.first()->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) { const GeoDataPlacemark * placemark = static_cast( m_featurelist.first() ); return placemark->coordinate( m_model->clock()->dateTime() ); } else { QPoint p = dataContainer->data().toPoint(); qreal lat( 0.0 ), lon( 0.0 ); const bool valid = m_widget->geoCoordinates( p.x(), p.y(), lon, lat, GeoDataCoordinates::Radian ); if ( valid ) { return GeoDataCoordinates( lon, lat ); } } return GeoDataCoordinates(); } void MarbleWidgetPopupMenu::startReverseGeocoding() { const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction ); if ( coordinates.isValid() ) { d->m_runnerManager.reverseGeocoding( coordinates ); } } void MarbleWidgetPopupMenu::showAddressInformation(const GeoDataCoordinates &, const GeoDataPlacemark &placemark) { QString text = placemark.address(); if ( !text.isEmpty() ) { QMessageBox::information( d->m_widget, tr( "Address Details" ), text, QMessageBox::Ok ); } } void MarbleWidgetPopupMenu::addBookmark() { const GeoDataCoordinates coordinates = d->mouseCoordinates( d->m_copyCoordinateAction ); if ( coordinates.isValid() ) { QPointer dialog = new EditBookmarkDialog( d->m_widget->model()->bookmarkManager(), d->m_widget ); dialog->setMarbleWidget( d->m_widget ); dialog->setCoordinates( coordinates ); dialog->setRange( d->m_widget->lookAt().range() ); dialog->setReverseGeocodeName(); if ( dialog->exec() == QDialog::Accepted ) { d->m_widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() ); } delete dialog; } } void MarbleWidgetPopupMenu::toggleFullscreen( bool enabled ) { QWidget* parent = d->m_widget; for ( ; parent->parentWidget(); parent = parent->parentWidget() ) { // nothing to do } if ( enabled ) { parent->setWindowState( parent->windowState() | Qt::WindowFullScreen ); } else { parent->setWindowState( parent->windowState() & ~Qt::WindowFullScreen ); } } QPoint MarbleWidgetPopupMenu::mousePosition() const { return d->m_mousePosition; } } #include "moc_MarbleWidgetPopupMenu.cpp" diff --git a/src/lib/marble/declarative/Placemark.cpp b/src/lib/marble/declarative/Placemark.cpp index 608c9634d..73a492477 100644 --- a/src/lib/marble/declarative/Placemark.cpp +++ b/src/lib/marble/declarative/Placemark.cpp @@ -1,238 +1,255 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2011 Dennis Nienhüser // #include "Placemark.h" #ifdef HAVE_QT5_POSITIONING #include #include #endif // HAVE_QT5_POSITIONING #include #include "GeoDataStyle.h" #include "GeoDataIconStyle.h" namespace Marble { Placemark::Placemark(QObject *parent ) : QObject( parent ) { // nothing to do } void Placemark::setGeoDataPlacemark( const Marble::GeoDataPlacemark &placemark ) { m_placemark = placemark; m_address = QString(); m_description = QString(); m_website = QString(); m_wikipedia = QString(); m_fuelDetails = QString(); m_openingHours = QString(); + m_elevation = QString(); emit coordinatesChanged(); emit nameChanged(); emit descriptionChanged(); emit addressChanged(); emit websiteChanged(); emit wikipediaChanged(); emit openingHoursChanged(); + emit elevationChanged(); if (m_placemark.visualCategory() == GeoDataFeature::TransportFuel) { emit fuelDetailsChanged(); } } Marble::GeoDataPlacemark & Placemark::placemark() { return m_placemark; } const GeoDataPlacemark &Placemark::placemark() const { return m_placemark; } QString Placemark::name() const { return m_placemark.name(); } QString Placemark::description() const { if (m_description.isEmpty()) { auto const category = m_placemark.visualCategory(); m_description = m_placemark.categoryName(); if (category >= GeoDataFeature::FoodBar && category <= GeoDataFeature::FoodRestaurant) { addTagValue(m_description, "brand"); addTagValue(m_description, "cuisine"); addTagDescription(m_description, "self_service", "yes", "Self Service"); addTagDescription(m_description, "takeaway", "yes", "Take Away"); addTagDescription(m_description, "outdoor_seating", "yes", "Outdoor Seating"); addTagDescription(m_description, "ice_cream", "yes", "Ice Cream"); addTagDescription(m_description, "smoking", "dedicated", "Smoking (dedicated)"); addTagDescription(m_description, "smoking", "yes", "Smoking allowed"); addTagDescription(m_description, "smoking", "separated", "Smoking (separated)"); addTagDescription(m_description, "smoking", "isolated", "Smoking (isolated)"); addTagDescription(m_description, "smoking", "no", "No smoking"); addTagDescription(m_description, "smoking", "outside", "Smoking (outside)"); addTagDescription(m_description, "smoking:outside", "yes", "Smoking (outside)"); addTagDescription(m_description, "smoking:outside", "separated", "Smoking (outside separated)"); addTagDescription(m_description, "smoking:outside", "no", "No smoking outside"); } else if (category >= GeoDataFeature::ShopBeverages && category <= GeoDataFeature::Shop) { addTagValue(m_description, "operator"); } else if (category == GeoDataFeature::TransportBusStop) { addTagValue(m_description, "network"); addTagValue(m_description, "operator"); addTagValue(m_description, "ref"); } else if (category == GeoDataFeature::TransportCarShare) { addTagValue(m_description, "network"); addTagValue(m_description, "operator"); } else if (category == GeoDataFeature::TransportFuel) { addTagValue(m_description, "brand"); addTagValue(m_description, "operator"); } else if (category == GeoDataFeature::NaturalTree) { addTagValue(m_description, "species:en"); addTagValue(m_description, "genus:en"); addTagValue(m_description, "leaf_type"); } } return m_description; } QString Placemark::address() const { if (m_address.isEmpty()) { m_address = addressFromOsmData(); } return m_address; } QString Placemark::fuelDetails() const { if (m_fuelDetails.isEmpty() && m_placemark.visualCategory() == GeoDataFeature::TransportFuel) { addTagDescription(m_fuelDetails, "fuel:diesel", "yes", tr("Diesel")); addTagDescription(m_fuelDetails, "fuel:octane_91", "yes", tr("Octane 91")); addTagDescription(m_fuelDetails, "fuel:octane_95", "yes", tr("Octane 95")); addTagDescription(m_fuelDetails, "fuel:octane_98", "yes", tr("Octane 98")); addTagDescription(m_fuelDetails, "fuel:e10", "yes", tr("E10")); addTagDescription(m_fuelDetails, "fuel:lpg", "yes", tr("LPG")); } return m_fuelDetails; } QString Placemark::website() const { if (!m_website.isEmpty()) { return m_website; } foreach(const QString &tag, QStringList() << "website" << "contact:website" << "facebook" << "contact:facebook" << "url") { m_website = m_placemark.osmData().tagValue(tag); if (!m_website.isEmpty()) { return m_website; } } return m_website; } QString Placemark::wikipedia() const { if (!m_wikipedia.isEmpty()) { return m_wikipedia; } m_wikipedia = m_placemark.osmData().tagValue("wikipedia"); return m_wikipedia; } QString Placemark::openingHours() const { if (!m_openingHours.isEmpty()) { return m_openingHours; } addTagValue(m_openingHours, "opening_hours"); return m_openingHours; } QString Placemark::coordinates() const { return m_placemark.coordinate().toString(GeoDataCoordinates::Decimal).trimmed(); } +QString Placemark::elevation() const +{ + if (!m_elevation.isEmpty()){ + return m_elevation; + } + + OsmPlacemarkData data = m_placemark.osmData(); + + if (data.containsTagKey("ele")) { + m_elevation = data.tagValue("ele"); + } + + return m_elevation; +} + void Placemark::setName(const QString & name) { if (m_placemark.name() == name) { return; } m_placemark.setName(name); emit nameChanged(); } double Placemark::longitude() const { return m_placemark.coordinate().longitude(GeoDataCoordinates::Degree); } double Placemark::latitude() const { return m_placemark.coordinate().latitude(GeoDataCoordinates::Degree); } void Placemark::addTagValue(QString &target, const QString &key) const { auto const & osmData = m_placemark.osmData(); QString const value = osmData.tagValue(key); QString description = value; description.replace(';', " · "); addTagDescription(target, key, value, description); } void Placemark::addTagDescription(QString &target, const QString &key, const QString &value, const QString &description) const { auto const & osmData = m_placemark.osmData(); if (osmData.containsTag(key, value)) { if (!target.isEmpty()) { target += " · "; } target += description; } } QString Placemark::addressFromOsmData() const { #ifdef HAVE_QT5_POSITIONING QGeoAddress address; OsmPlacemarkData const data = m_placemark.osmData(); address.setCountry(data.tagValue("addr:country")); address.setState(data.tagValue("addr:state")); address.setCity(data.tagValue("addr:city")); address.setDistrict(data.tagValue("district")); address.setPostalCode(data.tagValue("addr:postcode")); QString const street = data.tagValue("addr:street"); QString const houseNumber = data.tagValue("addr:housenumber"); address.setStreet(formatStreet(street, houseNumber)); return address.text().replace("
", ", "); #else return QString(); #endif } QString Placemark::formatStreet(const QString &street, const QString &houseNumber) const { return houseNumber.isEmpty() ? street : tr("%1 %2", "House number (first argument) and street name (second argument) in an address").arg(houseNumber).arg(street).trimmed(); } } #include "moc_Placemark.cpp" diff --git a/src/lib/marble/declarative/Placemark.h b/src/lib/marble/declarative/Placemark.h index 22bfafd6f..d988ee835 100644 --- a/src/lib/marble/declarative/Placemark.h +++ b/src/lib/marble/declarative/Placemark.h @@ -1,94 +1,98 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2012 Dennis Nienhüser // #ifndef MARBLE_DECLARATIVE_PLACEMARK_H #define MARBLE_DECLARATIVE_PLACEMARK_H #include "Coordinate.h" #include "GeoDataPlacemark.h" #include "GeoDataFeature.h" #include #include namespace Marble { /** * Wraps a GeoDataPlacemark for QML access */ class Placemark : public QObject { Q_OBJECT - Q_PROPERTY( QString name WRITE setName READ name NOTIFY nameChanged ) - Q_PROPERTY( QString description READ description NOTIFY descriptionChanged ) - Q_PROPERTY( QString address READ address NOTIFY addressChanged ) - Q_PROPERTY( QString website READ website NOTIFY websiteChanged ) - Q_PROPERTY( QString wikipedia READ wikipedia NOTIFY wikipediaChanged ) - Q_PROPERTY( QString fuelDetails READ fuelDetails NOTIFY fuelDetailsChanged ) - Q_PROPERTY( QString openingHours READ openingHours NOTIFY openingHoursChanged ) - Q_PROPERTY( QString coordinates READ coordinates NOTIFY coordinatesChanged ) + Q_PROPERTY(QString name WRITE setName READ name NOTIFY nameChanged) + Q_PROPERTY(QString description READ description NOTIFY descriptionChanged) + Q_PROPERTY(QString address READ address NOTIFY addressChanged) + Q_PROPERTY(QString website READ website NOTIFY websiteChanged) + Q_PROPERTY(QString wikipedia READ wikipedia NOTIFY wikipediaChanged) + Q_PROPERTY(QString fuelDetails READ fuelDetails NOTIFY fuelDetailsChanged) + Q_PROPERTY(QString openingHours READ openingHours NOTIFY openingHoursChanged) + Q_PROPERTY(QString coordinates READ coordinates NOTIFY coordinatesChanged) + Q_PROPERTY(QString elevation READ elevation NOTIFY elevationChanged) Q_PROPERTY(double longitude READ longitude NOTIFY coordinatesChanged) Q_PROPERTY(double latitude READ latitude NOTIFY coordinatesChanged) public: /** Constructor */ explicit Placemark( QObject *parent = 0 ); void setGeoDataPlacemark( const Marble::GeoDataPlacemark &placemark ); Marble::GeoDataPlacemark & placemark(); const Marble::GeoDataPlacemark & placemark() const; QString name() const; QString description() const; QString address() const; QString website() const; QString wikipedia() const; QString fuelDetails() const; QString openingHours() const; QString coordinates() const; + QString elevation() const; double longitude() const; double latitude() const; public Q_SLOTS: void setName(const QString &name); Q_SIGNALS: void nameChanged(); void coordinatesChanged(); void descriptionChanged(); void addressChanged(); void websiteChanged(); void wikipediaChanged(); void fuelDetailsChanged(); void openingHoursChanged(); + void elevationChanged(); private: void addTagValue(QString &target, const QString &key) const; void addTagDescription(QString &target, const QString &key, const QString &value, const QString &description) const; QString addressFromOsmData() const; QString formatStreet(const QString &street, const QString &houseNumber) const; Marble::GeoDataPlacemark m_placemark; mutable QString m_address; // mutable to allow lazy calculation in the getter mutable QString m_description; mutable QString m_fuelDetails; mutable QString m_website; mutable QString m_wikipedia; mutable QString m_openingHours; + mutable QString m_elevation; }; } QML_DECLARE_TYPE(Marble::Placemark) #endif // MARBLE_DECLARATIVE_PLACEMARK_H diff --git a/src/lib/marble/webpopup/osm.html b/src/lib/marble/webpopup/osm.html index cfa377381..d44e228d8 100644 --- a/src/lib/marble/webpopup/osm.html +++ b/src/lib/marble/webpopup/osm.html @@ -1,101 +1,103 @@ Place information %!{bootstrap}%

%name%

-

%amenity%

- -

%cuisine%

- +

%details%

+

%cuisine%

Opening Hours: %openinghours%

Contact
Address:%street% %housenumber%
%postcode% %city%
Phone:%phone%
Website:%website%

Popular Facilities
Wheelchair access%wheelchair%
Internet%internetaccess%
Smoking%smoking%

Copyright: © OpenStreetMap Contributors

diff --git a/src/plugins/runner/osm/OsmNode.cpp b/src/plugins/runner/osm/OsmNode.cpp index a88277d6b..e6d5f8382 100644 --- a/src/plugins/runner/osm/OsmNode.cpp +++ b/src/plugins/runner/osm/OsmNode.cpp @@ -1,116 +1,109 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2015 Dennis Nienhüser // #include #include "osm/OsmPresetLibrary.h" #include "osm/OsmObjectManager.h" #include #include #include #include namespace Marble { void OsmNode::parseCoordinates(const QXmlStreamAttributes &attributes) { qreal const lon = attributes.value( "lon" ).toDouble(); qreal const lat = attributes.value( "lat" ).toDouble(); setCoordinates(GeoDataCoordinates(lon, lat, 0, GeoDataCoordinates::Degree)); } void OsmNode::setCoordinates(const GeoDataCoordinates &coordinates) { m_coordinates = coordinates; } void OsmNode::create(GeoDataDocument *document) const { GeoDataFeature::GeoDataVisualCategory const category = OsmPresetLibrary::determineVisualCategory(m_osmData); if (category == GeoDataFeature::None) { return; } GeoDataPlacemark* placemark = new GeoDataPlacemark; placemark->setOsmData(m_osmData); placemark->setCoordinate(m_coordinates); if ((category == GeoDataFeature::TransportCarShare || category == GeoDataFeature::MoneyAtm) && m_osmData.containsTagKey("operator")) { placemark->setName(m_osmData.tagValue("operator")); } else { placemark->setName(m_osmData.tagValue("name")); } placemark->setVisualCategory(category); placemark->setStyle( GeoDataStyle::Ptr() ); placemark->setZoomLevel( 18 ); if (category >= GeoDataFeature::PlaceCity && category <= GeoDataFeature::PlaceVillage) { int const population = m_osmData.tagValue("population").toInt(); placemark->setPopulation(qMax(0, population)); if (population > 0) { placemark->setZoomLevel(populationIndex(population)); placemark->setPopularity(population); } else { switch (category) { case GeoDataFeature::PlaceCity: placemark->setZoomLevel(9); break; case GeoDataFeature::PlaceSuburb: placemark->setZoomLevel(13); break; case GeoDataFeature::PlaceHamlet: placemark->setZoomLevel(15); break; case GeoDataFeature::PlaceLocality: placemark->setZoomLevel(15); break; case GeoDataFeature::PlaceTown: placemark->setZoomLevel(11); break; case GeoDataFeature::PlaceVillage: placemark->setZoomLevel(13); break; default: placemark->setZoomLevel(10); break; } } - } else if (category == GeoDataFeature::NaturalPeak) { - placemark->setZoomLevel(11); - bool isInteger = false; - int const elevation = m_osmData.tagValue("ele").toInt(&isInteger); - if (isInteger) { - placemark->setName(QString("%1 (%2 m)").arg(placemark->name()).arg(elevation)); - } } OsmObjectManager::registerId(m_osmData.id()); document->append(placemark); } int OsmNode::populationIndex(qint64 population) const { int popidx = 3; if ( population < 2500 ) popidx=10; else if ( population < 5000) popidx=9; else if ( population < 25000) popidx=8; else if ( population < 75000) popidx=7; else if ( population < 250000) popidx=6; else if ( population < 750000) popidx=5; else if ( population < 2500000) popidx=4; return popidx; } const GeoDataCoordinates &OsmNode::coordinates() const { return m_coordinates; } OsmPlacemarkData &OsmNode::osmData() { return m_osmData; } const OsmPlacemarkData &OsmNode::osmData() const { return m_osmData; } }