diff --git a/src/apps/marble-maps/MarbleMaps.qrc b/src/apps/marble-maps/MarbleMaps.qrc
index 21cf9d878..1003c4aa3 100644
--- a/src/apps/marble-maps/MarbleMaps.qrc
+++ b/src/apps/marble-maps/MarbleMaps.qrc
@@ -1,72 +1,73 @@
AboutDialog.qml
FlatButton.qml
Completion.qml
MainScreen.qml
SearchResults.qml
SearchField.qml
Search.qml
CircularButton.qml
IconText.qml
PositionButton.qml
BoxedText.qml
ImageButton.qml
WaypointImage.qml
RoutingManager.qml
PlacemarkDialog.qml
SettingsDialog.qml
DeveloperDialog.qml
ProfileSelectorMenu.qml
FloatingMenuButton.qml
RouteEditor.qml
NavigationInfoBar.qml
NavigationManager.qml
PositionMarker.qml
Waypoint.qml
CurrentPosition.qml
../../../data/android/drawable-xxxhdpi/search.png
../../../data/android/drawable-xxxhdpi/gps_fixed.png
../../../data/android/drawable-xxxhdpi/gps_not_fixed.png
../../../data/android/drawable-xxxhdpi/backdrop.png
../../../data/android/drawable-xxxhdpi/border_shadow.png
../../../data/android/drawable-xxxhdpi/map.png
../../../data/android/drawable-xxxhdpi/waypoint.png
../../../data/android/drawable-xxxhdpi/up.png
../../../data/android/drawable-xxxhdpi/down.png
../../../data/android/drawable-xxxhdpi/delete.png
../../../data/android/drawable-xxxhdpi/delete_white.png
../../../data/android/drawable-xxxhdpi/ic_close_black_18dp.png
../../../data/android/drawable-xxxhdpi/busy_indicator.png
../../../data/android/drawable-xxxhdpi/navigation_blue.png
../../../data/svg/navigation_blue.svg
../../../data/android/drawable-xxxhdpi/circular_menu_backdrop.png
../../../data/android/drawable-xxxhdpi/ic_place.png
../../../data/android/drawable-xxxhdpi/ic_place_arrival.png
../../../data/android/drawable-xxxhdpi/ic_place_departure.png
../../../data/android/drawable-xxxhdpi/ic_place_unknown.png
../../../data/android/drawable-xxxhdpi/ic_place_via.png
../../../data/android/drawable-xxxhdpi/ic_add_black_48dp.png
material-icons/ic_local_gas_station_48px.svg
material-icons/ic_open_in_browser_48px.svg
material-icons/ic_volume_off_48px.svg
material-icons/ic_volume_up_48px.svg
material-icons/ic_directions_48px.svg
material-icons/ic_directions_bike_48px.svg
material-icons/ic_directions_car_48px.svg
material-icons/ic_directions_walk_48px.svg
material-icons/ic_navigation_48px.svg
material-icons/ic_access_time_48px.svg
+ material-icons/ic_accessible_black_48px.svg
material-icons/ic_place_black_48px.svg
material-icons/ic_star_24px.svg
material-icons/ic_star_border_24px.svg
material-icons/ic_label_48px.svg
konqi/konqi-app-dev.png
konqi/konqi-dev-qt.png
konqi/konqi-group.png
konqi/konqi-globe.png
konqi/konqi-books.png
RouteProfileRadioButton.qml
ScrollBar.qml
diff --git a/src/apps/marble-maps/PlacemarkDialog.qml b/src/apps/marble-maps/PlacemarkDialog.qml
index 567502c8f..bfb9b2e3a 100644
--- a/src/apps/marble-maps/PlacemarkDialog.qml
+++ b/src/apps/marble-maps/PlacemarkDialog.qml
@@ -1,163 +1,170 @@
//
// 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
}
IconText {
width: parent.width
visible: text.length > 0
text: placemark === null ? "" : placemark.description
}
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.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 518d9c7ab..f64cdd225 100644
--- a/src/lib/marble/declarative/Placemark.cpp
+++ b/src/lib/marble/declarative/Placemark.cpp
@@ -1,528 +1,557 @@
//
// 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();
updateTags();
emit coordinatesChanged();
emit nameChanged();
emit descriptionChanged();
emit addressChanged();
emit websiteChanged();
emit wikipediaChanged();
emit openingHoursChanged();
+ emit wheelchairInfoChanged();
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) {
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");
addTagValue(m_description, QStringLiteral("ele"), tr("%1 m"));
} 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::NaturalPeak) {
addTagValue(m_description, QStringLiteral("ele"), tr("%1 m"));
} 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::TouristWildernessHut) {
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::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"));
}
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(", "));
}
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"));
-
- addTagDescription(m_description, QStringLiteral("wheelchair"), QStringLiteral("yes"), tr("Wheelchair accessible"));
- addTagDescription(m_description, QStringLiteral("wheelchair"), QStringLiteral("no"), tr("Not wheelchair accessible"));
- addTagDescription(m_description, QStringLiteral("wheelchair"), QStringLiteral("limited"), tr("Limited wheelchair accessibility"));
}
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("Wheelchair access only"));
+
+ // 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;
+}
+
void Placemark::setName(const QString & name)
{
if (m_placemark.displayName() == 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);
}
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 a69d57f48..cd15391b6 100644
--- a/src/lib/marble/declarative/Placemark.h
+++ b/src/lib/marble/declarative/Placemark.h
@@ -1,95 +1,99 @@
//
// 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
#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(double longitude READ longitude NOTIFY coordinatesChanged)
Q_PROPERTY(double latitude READ latitude NOTIFY coordinatesChanged)
Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged)
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;
double longitude() const;
double latitude() const;
const QStringList & tags() const;
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 tagsChanged();
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;
QStringList m_tags;
};
}
QML_DECLARE_TYPE(Marble::Placemark)
#endif // MARBLE_DECLARATIVE_PLACEMARK_H