diff --git a/src/apps/marble-maps/PlacemarkDialog.qml b/src/apps/marble-maps/PlacemarkDialog.qml index 81d306483..516a01f6b 100644 --- a/src/apps/marble-maps/PlacemarkDialog.qml +++ b/src/apps/marble-maps/PlacemarkDialog.qml @@ -1,185 +1,201 @@ // // 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.Controls 2.0 import org.kde.marble 0.20 Item { id: root property var placemark: null property variant map property alias showOsmTags: tagsView.visible height: placemark === null ? 0 : Screen.pixelDensity * 4 + (infoLayout.height > bookmarkButton.height ? infoLayout.height : bookmarkButton.height) onPlacemarkChanged: { if (placemark) { bookmarkButton.bookmark = bookmarks.isBookmark(placemark.longitude, placemark.latitude) } } SystemPalette { id: palette colorGroup: SystemPalette.Active } Rectangle { anchors.fill: parent color: palette.base } Bookmarks { id: bookmarks } onMapChanged: bookmarks.map = root.map 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 } - ListView { - model: placemark ? placemark.relationModel : undefined - header: Text { text: "Appears in these relations:" } - width: parent.width - height: 150 - delegate: Text { text: name } - } - IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.description } + ListView { + model: placemark ? placemark.routeRelationModel : undefined + width: parent.width + height: Math.min(Screen.pixelDensity * 25, contentHeight) + clip: true + delegate: Row { + spacing: Screen.pixelDensity * 1 + Image { + source: "file:/" + iconSource + height: text.height + width: height + sourceSize.height: height + sourceSize.width: width + fillMode: Image.PreserveAspectFit + } + Text { + id: text + font.pointSize: 14 + text: display + } + } + ScrollBar.vertical: ScrollBar {} + } + IconText { width: parent.width visible: text.length > 0 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 onLinkActivated: Qt.openUrlExternally(link) } IconText { width: parent.width visible: url.length > 0 property string url: placemark === null ? "" : placemark.wikipedia text: "Wikipedia" icon: "qrc:/material/browser.svg" maximumLineCount: 4 onLinkActivated: Qt.openUrlExternally(link) } 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 text: placemark === null ? "" : placemark.wheelchairInfo icon: "qrc:/material/wheelchair.svg" } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.wifiAvailable icon: "qrc:/material/wlan-available.svg" } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : "" + placemark.coordinates + "" icon: "qrc:/material/place.svg" linkColor: palette.text onLinkActivated: marbleMaps.centerOnCoordinates(placemark.longitude, placemark.latitude) } ListView { id: tagsView visible: false width: parent.width height: Math.min(contentHeight, Screen.pixelDensity * 24) clip: true model: placemark ? placemark.tags : undefined delegate: IconText { width: tagsView.width; icon: "qrc:/material/label.svg" text: modelData } ScrollBar.vertical: ScrollBar {} } } Image { id: bookmarkButton anchors.right: parent.right anchors.top: parent.top 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 } } } } diff --git a/src/lib/marble/declarative/Placemark.cpp b/src/lib/marble/declarative/Placemark.cpp index b9f2bcd95..65509bfd7 100644 --- a/src/lib/marble/declarative/Placemark.cpp +++ b/src/lib/marble/declarative/Placemark.cpp @@ -1,692 +1,691 @@ // // 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_openingHours = QString(); m_wheelchairInfo = QString(); m_wifiAvailable = QString(); updateTags(); emit coordinatesChanged(); emit nameChanged(); emit descriptionChanged(); emit addressChanged(); emit websiteChanged(); emit wikipediaChanged(); emit openingHoursChanged(); emit wheelchairInfoChanged(); emit wifiAvailabilityChanged(); emit tagsChanged(); } Marble::GeoDataPlacemark & Placemark::placemark() { return m_placemark; } const GeoDataPlacemark &Placemark::placemark() const { return m_placemark; } QString Placemark::name() const { return m_placemark.displayName(); } QString Placemark::description() const { if (m_description.isEmpty()) { auto const category = m_placemark.visualCategory(); m_description = m_placemark.categoryName(); if (category == GeoDataPlacemark::AccomodationHotel || category == GeoDataPlacemark::FoodRestaurant) { QString const stars = m_placemark.osmData().tagValue(QStringLiteral("stars")); if (!stars.isEmpty()) { bool hasStars; int const numStars = stars.mid(0, 1).toInt(&hasStars); if (hasStars) { m_description += QString(' ') + QString("★").repeated(numStars) + stars.mid(1); } else { addTagValue(m_description, QStringLiteral("stars")); } } addFirstTagValueOf(m_description, QStringList() << "brand" << "operator"); } if ((category >= GeoDataPlacemark::AccomodationHostel && category <= GeoDataPlacemark::AccomodationGuestHouse) || category == GeoDataPlacemark::HealthHospital) { int const rooms = m_placemark.osmData().tagValue(QStringLiteral("rooms")).toInt(); if (rooms > 0) { //~ singular %n room //~ plural %n rooms addTagValue(m_description, QStringLiteral("rooms"), tr("%n rooms", 0, rooms)); } int const beds = m_placemark.osmData().tagValue(QStringLiteral("beds")).toInt(); if (beds > 0) { //~ singular %n bed //~ plural %n beds addTagValue(m_description, QStringLiteral("beds"), tr("%n beds", 0, beds)); } } if (category == GeoDataPlacemark::TransportParking || category == GeoDataPlacemark::TransportBicycleParking || category == GeoDataPlacemark::TransportMotorcycleParking) { addTagValue(m_description, QStringLiteral("capacity"), tr("%1 parking spaces")); addTagValue(m_description, QStringLiteral("maxstay"), tr("Maximum parking time %1")); } if (category >= GeoDataPlacemark::FoodBar && category <= GeoDataPlacemark::FoodRestaurant) { if (category != GeoDataPlacemark::FoodRestaurant) { addFirstTagValueOf(m_description, QStringList() << "brand" << "operator"); } else { // Do nothing, already added in stars section above } addTagValue(m_description, "cuisine"); addTagValue(m_description, "brewery"); 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 >= GeoDataPlacemark::ShopBeverages && category <= GeoDataPlacemark::Shop) { addFirstTagValueOf(m_description, QStringList() << "brand" << "operator"); addTagValue(m_description, "clothes"); addTagValue(m_description, "designation"); if (category == GeoDataPlacemark::ShopButcher) { addTagValue(m_description, "butcher"); } else if (category == GeoDataPlacemark::ShopCopy) { addTagDescription(m_description, QStringLiteral("service:computer"), QStringLiteral("yes"), tr("Computers available", "A copy shop provides computers for customer use")); addTagDescription(m_description, QStringLiteral("service:computer"), QStringLiteral("no"), tr("No computers available", "A copy shop does not provide computers for customer use")); addTagDescription(m_description, QStringLiteral("service:copy"), QStringLiteral("yes"), tr("Photocopying service", "A copy shop provides photocopying service")); addTagDescription(m_description, QStringLiteral("service:copy"), QStringLiteral("no"), tr("No photocopying service", "A copy shop does not provide photocopying service")); addTagDescription(m_description, QStringLiteral("service:scan"), QStringLiteral("yes"), tr("Digital scanning", "A copy shop provides a service for scanning documents into digital files")); addTagDescription(m_description, QStringLiteral("service:scan"), QStringLiteral("no"), tr("No digital scanning", "A copy shop does not provide a service for scanning documents into digital files")); addTagDescription(m_description, QStringLiteral("service:fax"), QStringLiteral("yes"), tr("Fax service", "A copy shop provides a service to send documents through fax")); addTagDescription(m_description, QStringLiteral("service:fax"), QStringLiteral("no"), tr("No fax service", "A copy shop does not provide a service to send documents through fax")); addTagDescription(m_description, QStringLiteral("service:phone"), QStringLiteral("yes"), tr("Phone service", "A copy shop provides a paid service to make phone calls")); addTagDescription(m_description, QStringLiteral("service:phone"), QStringLiteral("no"), tr("No phone service", "A copy shop does not provide a paid service to make phone calls")); addTagDescription(m_description, QStringLiteral("service:print"), QStringLiteral("yes"), tr("Digital printing", "A copy shop provides services to print paper documents from digital files")); addTagDescription(m_description, QStringLiteral("service:print"), QStringLiteral("no"), tr("No digital printing", "A copy shop does not provide services to print paper documents from digital files")); addTagDescription(m_description, QStringLiteral("service:press"), QStringLiteral("yes"), tr("Press printing service", "A copy shop provides a professional service to print a large number of copies of a document")); addTagDescription(m_description, QStringLiteral("service:press"), QStringLiteral("no"), tr("No press printing service", "A copy shop does not provide a professional service to print a large number of copies of a document")); addTagDescription(m_description, QStringLiteral("service:prepress"), QStringLiteral("yes"), tr("Press printing assistance", "A copy shop provides help with preparing special printing techniques")); addTagDescription(m_description, QStringLiteral("service:prepress"), QStringLiteral("no"), tr("No press printing assistance", "A copy shop does not provide help with preparing special printing techniques")); addTagDescription(m_description, QStringLiteral("service:self"), QStringLiteral("yes"), tr("Self service", "A copy shop provides individual copy machines for self-service")); addTagDescription(m_description, QStringLiteral("service:self"), QStringLiteral("no"), tr(" No self service", "A copy shop does not provide individual machines for self-service")); } else if (category == GeoDataPlacemark::ShopDeli) { addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("yes"), tr("Sells organic food", "A deli that sells organic food")); addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("no"), tr("Does not sell organic food", "A deli that does not sell organic food")); addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("only"), tr("Only sells organic food", "A deli that only sells organic food")); addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("yes"), tr("Sells gluten free food", "A deli that sells gluten free food")); addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("no"), tr("Does not sell gluten free food", "A deli that does not sell gluten free food")); addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("only"), tr("Only sells gluten free food", "A deli that only sells gluten free food")); addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("yes"), tr("Sells lactose free food", "A deli that sells lactose free food")); addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("no"), tr("Does not sell lactose free food", "A deli that does not sell lactose free food")); addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("only"), tr("Only sells lactose free food", "A deli that only sells lactose free food")); } else if (category == GeoDataPlacemark::ShopTobacco) { addTagDescription(m_description, QStringLiteral("lottery"), QStringLiteral("yes"), tr("Sells lottery tickets", "A tobacco shop that also sells lottery tickets")); addTagDescription(m_description, QStringLiteral("stamps"), QStringLiteral("yes"), tr("Sells revenue stamps", "A tobacco shop that also sells revenue stamps")); addTagDescription(m_description, QStringLiteral("salt"), QStringLiteral("yes"), tr("Sells salt", "A tobacco shop that also sells salt")); } } else if (category == GeoDataPlacemark::TransportBusStop) { addTagValue(m_description, "network"); addTagValue(m_description, "operator"); addTagValue(m_description, "ref"); } else if (category == GeoDataPlacemark::TransportCarShare) { addTagValue(m_description, "network"); addTagValue(m_description, "operator"); } else if (category == GeoDataPlacemark::TransportRentalBicycle || category == GeoDataPlacemark::TransportRentalCar || category == GeoDataPlacemark::TransportRentalSki) { addFirstTagValueOf(m_description, QStringList() << "brand" << "operator"); } else if (category == GeoDataPlacemark::TransportFuel) { addFirstTagValueOf(m_description, QStringList() << "brand" << "operator"); addTagDescription(m_description, "fuel:diesel", "yes", tr("Diesel")); addTagDescription(m_description, "fuel:biodiesel", "yes", tr("Biodiesel")); addTagDescription(m_description, "fuel:octane_91", "yes", tr("Octane 91")); addTagDescription(m_description, "fuel:octane_95", "yes", tr("Octane 95")); addTagDescription(m_description, "fuel:octane_98", "yes", tr("Octane 98")); addTagDescription(m_description, "fuel:octane_100", "yes", tr("Octane 100")); addTagDescription(m_description, "fuel:e10", "yes", tr("E10")); addTagDescription(m_description, "fuel:lpg", "yes", tr("LPG")); } else if (category == GeoDataPlacemark::NaturalTree) { addTagValue(m_description, "species:en"); addTagValue(m_description, "genus:en"); addTagValue(m_description, "leaf_type"); } else if (category == GeoDataPlacemark::NaturalCave){ addTagValue(m_description, "cave:ref"); } else if (category == GeoDataPlacemark::AmenityRecycling) { addTagDescription(m_description, QStringLiteral("recycling:batteries"), "yes", tr("Batteries")); addTagDescription(m_description, QStringLiteral("recycling:clothes"), "yes", tr("Clothes")); addTagDescription(m_description, QStringLiteral("recycling:glass"), "yes", tr("Glass")); addTagDescription(m_description, QStringLiteral("recycling:glass_bottles"), "yes", tr("Glass bottles")); addTagDescription(m_description, QStringLiteral("recycling:green_waste"), "yes", tr("Green waste")); addTagDescription(m_description, QStringLiteral("recycling:garden_waste"), "yes", tr("Garden waste")); addTagDescription(m_description, QStringLiteral("recycling:electrical_items"), "yes", tr("Electrical items")); addTagDescription(m_description, QStringLiteral("recycling:metal"), "yes", tr("Metal")); addTagDescription(m_description, QStringLiteral("recycling:mobile_phones"), "yes", tr("Mobile phones")); addTagDescription(m_description, QStringLiteral("recycling:newspaper"), "yes", tr("Newspaper")); addTagDescription(m_description, QStringLiteral("recycling:paint"), "yes", tr("Paint")); addTagDescription(m_description, QStringLiteral("recycling:paper"), "yes", tr("Paper")); addTagDescription(m_description, QStringLiteral("recycling:paper_packaging"), "yes", tr("Paper packaging")); addTagDescription(m_description, QStringLiteral("recycling:PET"), "yes", tr("PET")); addTagDescription(m_description, QStringLiteral("recycling:plastic"), "yes", tr("Plastic")); addTagDescription(m_description, QStringLiteral("recycling:plastic_bags"), "yes", tr("Plastic bags")); addTagDescription(m_description, QStringLiteral("recycling:plastic_bottles"), "yes", tr("Plastic bottles")); addTagDescription(m_description, QStringLiteral("recycling:plastic_packaging"), "yes", tr("Plastic packaging")); addTagDescription(m_description, QStringLiteral("recycling:polyester"), "yes", tr("Polyester")); addTagDescription(m_description, QStringLiteral("recycling:tyres"), "yes", tr("Tyres")); addTagDescription(m_description, QStringLiteral("recycling:waste"), "yes", tr("Waste")); addTagDescription(m_description, QStringLiteral("recycling:white_goods"), "yes", tr("White goods")); addTagDescription(m_description, QStringLiteral("recycling:wood"), "yes", tr("Wood")); } else if (category == GeoDataPlacemark::NaturalVolcano) { addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("active"), tr("Active", "An active volcano")); addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("dormant"), tr("Dormant", "A dormant volcano that will erupt at some point in the future.")); addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("extinct"), tr("Extinct", "A volcano considered extinct, it has not erupted within the last 10000 years and likely never will again.")); addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("stratovolcano"), tr("Stratovolcano")); addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("shield"), tr("Shield volcano")); addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("scoria"), tr("Scoria cone", "A scoria cone volcano.")); } else if (category == GeoDataPlacemark::HealthDoctors) { addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("alternative"), tr("Alternative medicine")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("audiologist"), tr("Audiologist")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("blood_bank"), tr("Blood bank")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("blood_donation"), tr("Blood donation")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("centre"), tr("Medical center")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("clinic"), tr("Clinic")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("dentist"), tr("Dentist")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("doctor"), tr("Medical practitioner")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("hospital"), tr("Hospital")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("midwife"), tr("Midwife")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("optometrist"), tr("Optometrist")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("physiotherapist"), tr("Physiotherapist")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("podiatrist"), tr("Podiatrist")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("psychotherapist"), tr("Psychotherapist")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("rehabilitation"), tr("Rehabilitation")); addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("speech_therapist"), tr("Speech therapist")); addTagValue(m_description, QStringLiteral("healthcare:speciality")); } else if (category == GeoDataPlacemark::AmenityBench) { int const seats = m_placemark.osmData().tagValue(QStringLiteral("seats")).toInt(); if (seats > 0) { //~ singular %n seat //~ plural %n seats addTagValue(m_description, QStringLiteral("seats"), tr("%n seats", "number of seats a bench provides", seats)); } addTagValue(m_description, QStringLiteral("material")); addTagDescription(m_description, QStringLiteral("backrest"), QStringLiteral("yes"), tr("Has backrest", "A bench provides a backrest to lean against")); addTagDescription(m_description, QStringLiteral("backrest"), QStringLiteral("no"), tr("No backrest", "A bench provides no backrest to lean against")); } else if (category == GeoDataPlacemark::AmenityWasteBasket) { addTagValue(m_description, QStringLiteral("waste")); } else if (category == GeoDataPlacemark::TransportSpeedCamera) { addTagValue(m_description, QStringLiteral("maxspeed"), tr("%1 km/h")); addTagValue(m_description, "ref"); } else if (category == GeoDataPlacemark::TransportParking) { addTagDescription(m_description, QStringLiteral("supervised"), QStringLiteral("yes"), tr("Is supervised", "Parking spaces are supervised by guards")); addTagDescription(m_description, QStringLiteral("supervised"), QStringLiteral("no"), tr("Not supervised", "Parking spaces are not supervised by guards")); int const disabledSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:disabled")).toInt(); if (disabledSpaces > 0) { addTagValue(m_description, QStringLiteral("capacity:disabled"), tr("%1 disabled spaces", "Parking spaces")); } int const womenSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:women")).toInt(); if (womenSpaces > 0) { addTagValue(m_description, QStringLiteral("capacity:women"), tr("%1 women spaces", "Parking spaces")); } int const parentSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:parent")).toInt(); if (parentSpaces > 0) { addTagValue(m_description, QStringLiteral("capacity:parent"), tr("%1 parent and child spaces", "Parking spaces")); } int const electricChargers = m_placemark.osmData().tagValue(QStringLiteral("capacity:charging")).toInt(); if (electricChargers > 0) { addTagValue(m_description, QStringLiteral("capacity:charging"), tr("%1 spaces with electric chargers", "Parking spaces")); } } else if (category == GeoDataPlacemark::TransportBicycleParking) { addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("outdoor"), tr("Has outdoor surveillance", "A parking space has outdoor surveillance")); addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("indoor"), tr("Has indoor surveillance", "A parking space has indoor surveillance")); addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("public"), tr("Has public surveillance", "A parking space has public surveillance")); } else if (category == GeoDataPlacemark::TourismWildernessHut) { addTagDescription(m_description, QStringLiteral("shower"), QStringLiteral("yes"), tr("Has shower", "A hut provides showers inside or aside")); addTagDescription(m_description, QStringLiteral("shower"), QStringLiteral("no"), tr("Has no shower", "A hut does not provide showers inside or aside")); addTagDescription(m_description, QStringLiteral("mattress"), QStringLiteral("yes"), tr("Has mattress", "A hut provides mattress")); addTagDescription(m_description, QStringLiteral("mattress"), QStringLiteral("no"), tr("Has no mattress", "A hut does not provide mattress")); addTagDescription(m_description, QStringLiteral("drinking_water"), QStringLiteral("yes"), tr("Has water", "Water is available inside or aside")); addTagDescription(m_description, QStringLiteral("drinking_water"), QStringLiteral("no"), tr("Has no water", "Water is not available inside nor aside")); addTagDescription(m_description, QStringLiteral("toilets"), QStringLiteral("yes"), tr("Has toilets", "A hut provides toilets")); addTagDescription(m_description, QStringLiteral("toilets"), QStringLiteral("no"), tr("Has no toilets", "A hut does not provide toilets")); addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("yes"), tr("Reservation is possible")); addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("no"), tr("No reservation possible")); addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("required"), tr("Reservation is required")); addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("recommended"), tr("Reservation is recommended", "You should make reservation")); addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("members_only"), tr("Only for members", "Reservation is only possible for members of the organisation running the hut")); } else if (category == GeoDataPlacemark::TourismArtwork) { addTagValue(m_description, QStringLiteral("artist_name"), tr("By %1")); } else if (category == GeoDataPlacemark::AmenityChargingStation) { addTagValue(m_description, QStringLiteral("capacity"), tr("%1 vehicles")); addTagValue(m_description, QStringLiteral("amperage"), tr("%1 ampere")); addTagValue(m_description, QStringLiteral("voltage"), tr("%1 volt")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_blue"), tr("%1 blue CEE sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_16a"), tr("%1 red CEE sockets (16 A)")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_32a"), tr("%1 red CEE sockets (32 A)")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_64a"), tr("%1 red CEE sockets (64 A)")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_125a"), tr("%1 red CEE sockets (125 A)")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_5_15"), tr("%1 NEMA-5-15P plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("typeb"), tr("%1 NEMA-5-15P plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_5_20"), tr("%1 NEMA-5-20P plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_14_30"), tr("%1 NEMA 14-30 sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_14_50"), tr("%1 NEMA 14-50 sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("schuko"), tr("%1 Schuko sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("bs1363"), tr("%1 BS 1363 sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type1"), tr("%1 Type 1 plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type1_combo"), tr("%1 Type 1 combo plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type2"), tr("%1 Type 2 sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type2_combo"), tr("%1 Type 2 combo sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type3"), tr("%1 Type 3 sockets")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("chademo"), tr("%1 CHAdeMO plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("magne_charge"), tr("%1 Magne Charge plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_standard"), tr("%1 Tesla standard plugs")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_supercharger"), tr("%1 Tesla standard plugs (Supercharger)")); addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_roadster"), tr("%1 Tesla roadster plugs")); } else if (category == GeoDataPlacemark::AmenityCarWash) { addTagValue(m_description, QStringLiteral("maxwidth"), tr("Maximum vehicle width: %1")); addTagValue(m_description, QStringLiteral("maxheight"), tr("Maximum vehicle height: %1")); addTagDescription(m_description, QStringLiteral("self_service"), QStringLiteral("yes"), tr("Self-service")); addTagDescription(m_description, QStringLiteral("self_service"), QStringLiteral("no"), tr("No self-service")); addTagDescription(m_description, QStringLiteral("automated"), QStringLiteral("yes"), tr("Automated")); addTagDescription(m_description, QStringLiteral("automated"), QStringLiteral("no"), tr("Manual")); } else if (category == GeoDataPlacemark::AmenitySocialFacility) { addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("group_home"), tr("Group home")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("nursing_home"), tr("Nursing home")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("assisted_living"), tr("Assisted living", "Like group home but for more independent people, e.g. who have flats")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("day_care"), tr("Nursing services on a daily basis")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("shelter"), tr("Shelter")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("ambulatory_care"), tr("Ambulatory care")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("outreach"), tr("Social welfare services")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("workshop"), tr("Employment and workshops for offenders and people with disabilities")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("food_bank"), tr("Pre-packaged food for free or below market price")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("soup_kitchen"), tr("Prepared meals for free or below market price")); addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("dairy_kitchen"), tr("Free dairy food (subject to local regulations)")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("abused"), tr("For abused")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("child"), tr("For children")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("disabled"), tr("For people with physical disabilities")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("diseased"), tr("For those who suffer of a disease")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("drug_addicted"), tr("For drug-addicted")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("homeless"), tr("For homeless")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("juvenile"), tr("For juvenile")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("mental_health"), tr("For those with mental/psychological problems")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("migrant"), tr("For migrants")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("orphan"), tr("For orphans")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("senior"), tr("For elder people")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("underprivileged"), tr("For poor or disadvantaged people")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("unemployed"), tr("For unemployed")); addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("victim"), tr("For victims of crimes")); } else if (category == GeoDataPlacemark::HistoricMemorial) { addTagValue(m_description, QStringLiteral("inscription"), tr("Inscription: %1")); } else if (category >= GeoDataPlacemark::AerialwayCableCar && category <= GeoDataPlacemark::AerialwayGoods) { addTagValue(m_description, QStringLiteral("occupancy"), tr("%1 places per carriage")); addTagValue(m_description, QStringLiteral("capacity"), tr("%1 people per hour")); addTagValue(m_description, QStringLiteral("duration"), tr("%1 minutes")); addTagDescription(m_description, QStringLiteral("bubble"), QStringLiteral("yes"), tr("Has weather protection", "A carriage is protected from the weather")); addTagDescription(m_description, QStringLiteral("bubble"), QStringLiteral("no"), tr("No weather protection", "A carriage is not protected from the weather")); addTagDescription(m_description, QStringLiteral("heating"), QStringLiteral("yes"), tr("Is heated", "A carriage is heated")); addTagDescription(m_description, QStringLiteral("heating"), QStringLiteral("no"), tr("Not heated", "A carriage is not heated")); addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("yes"), tr("Bicycle transportation possible", "Bicycles can be transported")); addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("summer"), tr("Bicycle transportation only in summer", "Bicycles can only be transported in summer")); addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("no"), tr("Bicycle transportation impossible", "Bicyles cannot be transported")); } else if (category >= GeoDataPlacemark::PisteDownhill && category <= GeoDataPlacemark::PisteSkiJump) { addTagDescription(m_description, QStringLiteral("lit"), QStringLiteral("yes"), tr("Lit at night")); addTagDescription(m_description, QStringLiteral("piste:lit"), QStringLiteral("yes"), tr("Lit in winter")); addTagDescription(m_description, QStringLiteral("gladed"), QStringLiteral("yes"), tr("Contains trees", "A ski piste with trees (gladed)")); addTagDescription(m_description, QStringLiteral("patrolled"), QStringLiteral("no"), tr("Not patrolled")); addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic"), tr("Groomed for classic style nordic or downhill skiing")); addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("mogul"), tr("Mogul piste")); addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("skating"), tr("Groomed for free style or skating")); addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic;skating"), tr("Groomed for classic and free style skiing")); addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic+skating"), tr("Groomed for classic and free style skiing")); addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("scooter"), tr("Groomed by a smaller snowmobile")); addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("backcountry"), tr("Unmarked piste (backcountry touring)")); } if (category == GeoDataPlacemark::TransportBicycleParking || category == GeoDataPlacemark::TransportMotorcycleParking) { addTagDescription(m_description, QStringLiteral("covered"), QStringLiteral("yes"), tr("Is covered", "A parking space is covered")); addTagDescription(m_description, QStringLiteral("covered"), QStringLiteral("no"), tr("Not covered", "A parking space is not covered")); } if (category == GeoDataPlacemark::AmenityRecycling || category == GeoDataPlacemark::AmenityPostBox) { addTagValue(m_description, QStringLiteral("collection_times"), tr("Collection times %1"), QStringLiteral(", ")); } if (category == GeoDataPlacemark::AerialwayStation) { addTagDescription(m_description, "aerialway:access", "entry", tr("Entry", "Entry station of an aerialway")); addTagDescription(m_description, "aerialway:access", "exit", tr("Exit", "Exit station of an aerialway")); addTagDescription(m_description, "aerialway:access", "both", tr("Entry and exit", "Entry and exit station of an aerialway")); addTagDescription(m_description, "aerialway:access", "no", tr("No entry or exit", "Transit only station of an aerialway")); addTagDescription(m_description, "aerialway:summer:access", "entry", tr("Entry during summer", "Entry station of an aerialway during summer")); addTagDescription(m_description, "aerialway:summer:access", "exit", tr("Exit during summer", "Exit station of an aerialway during summer")); addTagDescription(m_description, "aerialway:summer:access", "both", tr("Entry and exit during summer", "Entry and exit station of an aerialway during summer")); addTagDescription(m_description, "aerialway:summer:access", "no", tr("No entry or exit during summer", "Transit only station of an aerialway during summer")); } addTagValue(m_description, QStringLiteral("ele"), tr("Elevation: %1 m")); addTagDescription(m_description, "access", "customers", tr("Customers only")); addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("yes"), tr("Accessible by anyone", "The public has an official, legally-enshrined right of access; i.e., it's a right of way")); addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("private"), tr("Private", "Only with permission of the owner on an individual basis.")); addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("permissive"), tr("Open to general traffic", "Open to general traffic but permission can be revoked by the owner")); addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("no"), tr("No access", "No access for the general public")); addTagDescription(m_description, QStringLiteral("fee"), QStringLiteral("no"), tr("no fee")); addTagValue(m_description, QStringLiteral("description")); addTagValue(m_description, QStringLiteral("old_name"), tr("formerly %1")); const int level = m_placemark.osmData().tagValue(QStringLiteral("level")).toInt(); if (level > 2) { addTagValue(m_description, QStringLiteral("level"), tr("Floor %1", "Positive floor level")); } else if (level < -2) { addTagValue(m_description, QStringLiteral("level"), tr("Basement %1", "Negative floor level")); } else { addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("2"), tr("Floor 2", "Floor level 2, two levels above ground level")); addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("1"), tr("Floor 1", "Floor level 1, one level above ground level")); addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("0"), tr("Ground floor", "Floor level 0")); addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("-1"), tr("Basement 1", "Floor level -1, one level below ground level")); addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("-2"), tr("Basement 2", "Floor level -2, two levels below ground level")); } } return m_description; } QString Placemark::address() const { if (m_address.isEmpty()) { m_address = addressFromOsmData(); } return m_address; } QString Placemark::website() const { if (!m_website.isEmpty()) { return m_website; } foreach(const QString &tag, QStringList() << "website" << "contact:website" << "facebook" << "contact:facebook" << "url") { QString const value = m_placemark.osmData().tagValue(tag); if (!value.isEmpty()) { QUrl url = QUrl(value); if (url.isValid()) { if (url.scheme().isEmpty()) { m_website = QStringLiteral("http://%1").arg(value); } else { m_website = value; } if (!m_website.isEmpty()) { return m_website; } } } } return m_website; } QString Placemark::wikipedia() const { if (!m_wikipedia.isEmpty()) { return m_wikipedia; } // TODO: also support "wikipedia:lang=page title" tags const QString wikipedia = m_placemark.osmData().tagValue("wikipedia"); if (!wikipedia.isEmpty()) { // full URL? if (wikipedia.startsWith(QLatin1String("http://")) || wikipedia.startsWith(QLatin1String("https://"))) { m_wikipedia = wikipedia; } else { // match "(lang:)human readable title" QRegularExpression re("^(?:([a-z]{2,}):)?(.*)$"); QRegularExpressionMatch match = re.match(wikipedia); QString lang = match.captured(1); if (lang.isEmpty()) { lang = QStringLiteral("en"); } const QString title = QString::fromLatin1(QUrl::toPercentEncoding(match.captured(2))); m_wikipedia = QLatin1String("https://") + lang + QLatin1String(".wikipedia.org/wiki/") + title; } } 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::wheelchairInfo() const { if (!m_wheelchairInfo.isEmpty()) return m_wheelchairInfo; addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("yes"), tr("Wheelchair accessible")); addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("no"), tr("Wheelchair inaccessible")); addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("limited"), tr("Limited wheelchair accessibility")); addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("designated"), tr("Designated wheelchair access")); // Check if there is localized description auto const & osmData = m_placemark.osmData(); QStringList const uiLanguages = QLocale::system().uiLanguages(); const QString tag = QLatin1String("wheelchair:description:"); foreach (const QString &uiLanguage, uiLanguages) { for (auto tagIter = osmData.tagsBegin(), end = osmData.tagsEnd(); tagIter != end; ++tagIter) { if (tagIter.key().startsWith(tag)) { QStringRef const tagLanguage = tagIter.key().midRef(tag.length()); if (tagLanguage == uiLanguage) { append(m_wheelchairInfo, tagIter.value()); return m_wheelchairInfo; } } } } addTagValue(m_wheelchairInfo, "wheelchair:description"); return m_wheelchairInfo; } QString Placemark::wifiAvailable() const { if (!m_wifiAvailable.isEmpty()) { return m_wifiAvailable; } const auto& osmData = m_placemark.osmData(); addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("no"), tr("No public Internet access", "This location does not provide public Internet access")); addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("yes"), tr("Public Internet access available", "This location provides an unknown type of public Internet access.")); if (osmData.containsTag(QStringLiteral("internet_access:fee"), QStringLiteral("yes"))) { addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Charged public wifi available", "Public wireless Internet access is available here for a fee.")); } else if (osmData.containsTag(QStringLiteral("internet_access:fee"), QStringLiteral("no"))) { addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Free public wifi available", "Public wireless Internet access is available here for no cost.")); } else { addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Public wifi available", "Public wireless Internet access is available here.")); } if (m_wifiAvailable.isEmpty()) { addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("no"), tr("No public wifi", "Public wifi is not available here.")); addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("yes"), tr("Public wifi available", "Public wireless Internet is available here.")); addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("free"), tr("Free public wifi available", "Public wireless Internet is available here for no cost.")); } return m_wifiAvailable; } void Placemark::setName(const QString & name) { if (m_placemark.displayName() == name) { return; } m_placemark.setName(name); emit nameChanged(); } void Placemark::setRelations(const QVector &relations) { m_relationModel.setRelations(relations); - emit relationModelChanged(); } -RouteRelationModel* Placemark::relationModel() +RouteRelationModel* Placemark::routeRelationModel() { return &m_relationModel; } double Placemark::longitude() const { return m_placemark.coordinate().longitude(GeoDataCoordinates::Degree); } double Placemark::latitude() const { return m_placemark.coordinate().latitude(GeoDataCoordinates::Degree); } const QStringList &Placemark::tags() const { return m_tags; } bool Placemark::addTagValue(QString &target, const QString &key, const QString &format, const QString separator) const { auto const & osmData = m_placemark.osmData(); QString const value = osmData.tagValue(key); if (!value.isEmpty()) { QString description = format.isEmpty() ? value : format.arg(value); description.replace(QLatin1Char(';'), separator); append(target, description); return true; } return false; } void Placemark::addFirstTagValueOf(QString &target, const QStringList &keys) const { for (auto const &key: keys) { if (addTagValue(target, key)) { return; } } } 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)) { append(target, description); } } void Placemark::append(QString &target, const QString &value) const { if (!target.isEmpty()) { target += QStringLiteral(" · "); // non-latin1 } target += value; } 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(); } void Placemark::updateTags() { m_tags.clear(); QString const tag = QStringLiteral("%1 = %2"); for (auto iter = m_placemark.osmData().tagsBegin(), end = m_placemark.osmData().tagsEnd(); iter != end; ++iter) { m_tags << tag.arg(iter.key()).arg(iter.value()); } } } #include "moc_Placemark.cpp" diff --git a/src/lib/marble/declarative/Placemark.h b/src/lib/marble/declarative/Placemark.h index b1079c081..451a8fdda 100644 --- a/src/lib/marble/declarative/Placemark.h +++ b/src/lib/marble/declarative/Placemark.h @@ -1,113 +1,113 @@ // // 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 "GeoDataPlacemark.h" #include "RouteRelationModel.h" #include #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 openingHours READ openingHours NOTIFY openingHoursChanged) Q_PROPERTY(QString coordinates READ coordinates NOTIFY coordinatesChanged) Q_PROPERTY(QString wheelchairInfo READ wheelchairInfo NOTIFY wheelchairInfoChanged) Q_PROPERTY(QString wifiAvailable READ wifiAvailable NOTIFY wifiAvailabilityChanged) Q_PROPERTY(double longitude READ longitude NOTIFY coordinatesChanged) Q_PROPERTY(double latitude READ latitude NOTIFY coordinatesChanged) Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged) - Q_PROPERTY(RouteRelationModel* relationModel READ relationModel NOTIFY relationModelChanged) + Q_PROPERTY(RouteRelationModel* routeRelationModel READ routeRelationModel CONSTANT) 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 openingHours() const; QString coordinates() const; QString wheelchairInfo() const; QString wifiAvailable() const; double longitude() const; double latitude() const; const QStringList & tags() const; void setRelations(const QVector &relations); - RouteRelationModel* relationModel(); + RouteRelationModel* routeRelationModel(); public Q_SLOTS: void setName(const QString &name); Q_SIGNALS: void nameChanged(); void coordinatesChanged(); void descriptionChanged(); void addressChanged(); void websiteChanged(); void wikipediaChanged(); void openingHoursChanged(); void wheelchairInfoChanged(); void wifiAvailabilityChanged(); void tagsChanged(); - void relationModelChanged(); + void routeRelationModelChanged(); private: bool addTagValue(QString &target, const QString &key, const QString &format=QString(), const QString separator = QStringLiteral(" · ")) const; void addFirstTagValueOf(QString &target, const QStringList &keys) const; void addTagDescription(QString &target, const QString &key, const QString &value, const QString &description) const; void append(QString &target, const QString &value) const; QString addressFromOsmData() const; QString formatStreet(const QString &street, const QString &houseNumber) const; void updateTags(); Marble::GeoDataPlacemark m_placemark; mutable QString m_address; // mutable to allow lazy calculation in the getter mutable QString m_description; mutable QString m_website; mutable QString m_wikipedia; mutable QString m_openingHours; mutable QString m_wheelchairInfo; mutable QString m_wifiAvailable; QStringList m_tags; RouteRelationModel m_relationModel; }; } QML_DECLARE_TYPE(Marble::Placemark) #endif // MARBLE_DECLARATIVE_PLACEMARK_H diff --git a/src/lib/marble/declarative/RouteRelationModel.cpp b/src/lib/marble/declarative/RouteRelationModel.cpp index 641d2b712..1d20ed448 100644 --- a/src/lib/marble/declarative/RouteRelationModel.cpp +++ b/src/lib/marble/declarative/RouteRelationModel.cpp @@ -1,52 +1,95 @@ // // 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 2017 Sergey Popov // #include "RouteRelationModel.h" -namespace Marble { +#include "MarbleDirs.h" + +namespace Marble +{ RouteRelationModel::RouteRelationModel(QObject *parent) : QAbstractListModel(parent) { // nothing to do } -void RouteRelationModel::setRelations(const QVector &relations) +void RouteRelationModel::setRelations(const QVector &relations) { - beginRemoveRows(QModelIndex(), 0, m_relations.count() - 1); - m_relations.clear(); - endRemoveRows(); - - beginInsertRows(QModelIndex(), 0, relations.count() - 1); - m_relations = relations; - endInsertRows(); + if (!m_relations.isEmpty()) { + beginRemoveRows(QModelIndex(), 0, m_relations.count() - 1); + m_relations.clear(); + endRemoveRows(); + } + + if (!relations.isEmpty()) { + beginInsertRows(QModelIndex(), 0, relations.count() - 1); + m_relations.reserve(relations.size()); + std::copy_if(relations.begin(), relations.end(), std::back_inserter(m_relations), + [](const GeoDataRelation * relation) { + return relation->relationType() >= GeoDataRelation::RouteRoad && relation->relationType() <= GeoDataRelation::RouteSled; + }); + std::sort(m_relations.begin(), m_relations.end(), + [](const GeoDataRelation * a, const GeoDataRelation * b) { + return a->relationType() < b->relationType(); + }); + endInsertRows(); + } } int RouteRelationModel::rowCount(const QModelIndex & parent) const { - Q_UNUSED(parent); - return m_relations.count(); + return parent.isValid() ? 0 : m_relations.count(); } QVariant RouteRelationModel::data(const QModelIndex & index, int role) const { - if (!index.isValid() || index.row() < 0 || index.row() >= m_relations.count()) + if (!index.isValid() || index.row() < 0 || index.row() >= m_relations.count()) { return QVariant(); - - return m_relations.at(index.row())->name(); + } + + if (role == Qt::DisplayRole) { + return m_relations.at(index.row())->name(); + } else if (role == IconSource) { + switch (m_relations.at(index.row())->relationType()) { + case GeoDataRelation::RouteRoad: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_bike_48px.svg")); + case GeoDataRelation::RouteDetour: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_car_48px.svg")); + case GeoDataRelation::RouteFerry: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_boat_48px.svg")); + case GeoDataRelation::RouteTrain: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_railway_48px.svg")); + case GeoDataRelation::RouteSubway: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_subway_48px.svg")); + case GeoDataRelation::RouteTram: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_tram_48px.svg")); + case GeoDataRelation::RouteBus: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_bus_48px.svg")); + case GeoDataRelation::RouteTrolleyBus: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_bus_48px.svg")); + case GeoDataRelation::RouteBicycle: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_bike_48px.svg")); + case GeoDataRelation::RouteMountainbike: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_bike_48px.svg")); + case GeoDataRelation::RouteFoot: return MarbleDirs::path(QStringLiteral("svg/material/maps/ic_directions_walk_48px.svg")); + case GeoDataRelation::RouteHiking: return MarbleDirs::path(QStringLiteral("svg/thenounproject/204712-hiker.svg")); + case GeoDataRelation::RouteHorse: return MarbleDirs::path(QStringLiteral("svg/thenounproject/78374-horse-riding.svg")); + case GeoDataRelation::RouteInlineSkates: return MarbleDirs::path(QStringLiteral("svg/thenounproject/101965-inline-skater.svg")); + case GeoDataRelation::RouteSkiDownhill: return MarbleDirs::path(QStringLiteral("svg/thenounproject/2412-skiing-downhill.svg")); + case GeoDataRelation::RouteSkiNordic: return MarbleDirs::path(QStringLiteral("svg/thenounproject/30231-skiing-cross-country.svg")); + case GeoDataRelation::RouteSkitour: return MarbleDirs::path(QStringLiteral("svg/thenounproject/29366-skitour.svg")); + case GeoDataRelation::RouteSled: return MarbleDirs::path(QStringLiteral("svg/thenounproject/365217-sled.svg")); + case GeoDataRelation::UnknownType: return QVariant(QString()); + } + } + + return QVariant(); } -QHash RouteRelationModel::roleNames() const { +QHash RouteRelationModel::roleNames() const +{ QHash roles; - roles[RelationName] = "name"; + roles[Qt::DisplayRole] = "display"; + roles[IconSource] = "iconSource"; return roles; } } diff --git a/src/lib/marble/declarative/RouteRelationModel.h b/src/lib/marble/declarative/RouteRelationModel.h index 59e6dfd14..0fade10c4 100644 --- a/src/lib/marble/declarative/RouteRelationModel.h +++ b/src/lib/marble/declarative/RouteRelationModel.h @@ -1,46 +1,47 @@ // // 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 2017 Sergey Popov // #ifndef MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H #define MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H #include #include #include "GeoDataRelation.h" namespace Marble { class RouteRelationModel : public QAbstractListModel { Q_OBJECT + public: - enum RelationRoles { - RelationName = Qt::UserRole + 1 + enum RouteRelationRoles { + IconSource = Qt::UserRole + 1 }; RouteRelationModel(QObject* parent = 0); void setRelations(const QVector &relations); - int rowCount(const QModelIndex & parent = QModelIndex()) const; + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; - QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; - protected: QHash roleNames() const; - + private: QVector m_relations; }; } #endif // ROUTERELATIONMODEL