diff --git a/src/apps/marble-maps/PlacemarkDialog.qml b/src/apps/marble-maps/PlacemarkDialog.qml index 4295bd41b..e7f75b4c8 100644 --- a/src/apps/marble-maps/PlacemarkDialog.qml +++ b/src/apps/marble-maps/PlacemarkDialog.qml @@ -1,187 +1,193 @@ // // 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.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 text: placemark === null ? "" : placemark.amenity } + IconText { + width: parent.width + visible: text.length > 0 + text: placemark === null ? "" : placemark.shop + } + 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/declarative/Placemark.cpp b/src/lib/marble/declarative/Placemark.cpp index 222135446..4f2939e1c 100644 --- a/src/lib/marble/declarative/Placemark.cpp +++ b/src/lib/marble/declarative/Placemark.cpp @@ -1,288 +1,303 @@ // // 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(); m_amenity = QString(); + m_shop = QString(); emit coordinatesChanged(); emit nameChanged(); emit descriptionChanged(); emit addressChanged(); emit websiteChanged(); emit wikipediaChanged(); emit openingHoursChanged(); emit elevationChanged(); emit amenityChanged(); + emit shopChanged(); 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; } QString Placemark::amenity() const { if (!m_amenity.isEmpty()){ return m_amenity; } OsmPlacemarkData data = m_placemark.osmData(); + if (data.containsTagKey("amenity") && !data.tagValue("amenity").isEmpty()){ + QString amenity = data.tagValue("amenity"); + amenity[0] = amenity[0].toUpper(); + m_amenity = amenity; + } + + return m_amenity; +} + +QString Placemark::shop() const +{ + if (!m_shop.isEmpty()){ + return m_shop; + } + + OsmPlacemarkData data = m_placemark.osmData(); + if (data.containsTagKey("shop") && !data.tagValue("shop").isEmpty()){ QString shop = data.tagValue("shop"); shop[0] = shop[0].toUpper(); if (shop == "Clothes" && data.containsTagKey("clothes") && !data.tagValue("clothes").isEmpty()){ QString clothes = data.tagValue("clothes"); clothes[0] = clothes[0].toUpper(); - m_amenity = "Shop : " + shop + " (" + clothes + ")"; + m_shop = "Shop : " + shop + " (" + clothes + ")"; } else if (shop == "Clothes" && data.containsTagKey("designation") && !data.tagValue("designation").isEmpty()){ QString designation = data.tagValue("designation"); designation[0] = designation[0].toUpper(); - m_amenity = "Shop : " + shop + " (" + designation + ")"; + m_shop = "Shop : " + shop + " (" + designation + ")"; } else { - m_amenity = "Shop : " + shop; + m_shop = "Shop : " + shop; } - } else if (data.containsTagKey("amenity") && !data.tagValue("amenity").isEmpty()){ - QString amenity = data.tagValue("amenity"); - amenity[0] = amenity[0].toUpper(); - m_amenity = amenity; } - return m_amenity; + return m_shop; } 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 79efbfc7f..97236ff03 100644 --- a/src/lib/marble/declarative/Placemark.h +++ b/src/lib/marble/declarative/Placemark.h @@ -1,102 +1,106 @@ // // 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 elevation READ elevation NOTIFY elevationChanged) Q_PROPERTY(QString amenity READ amenity NOTIFY amenityChanged) + Q_PROPERTY(QString shop READ shop NOTIFY shopChanged) 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; QString amenity() const; + QString shop() 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(); void amenityChanged(); + void shopChanged(); 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; mutable QString m_amenity; + mutable QString m_shop; }; } QML_DECLARE_TYPE(Marble::Placemark) #endif // MARBLE_DECLARATIVE_PLACEMARK_H