Marble

Placemark.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2011 Dennis Nienhüser <nienhueser@kde.org>
4//
5
6#include "Placemark.h"
7
8#ifdef HAVE_QT5_POSITIONING
9#include <GeoDataExtendedData.h>
10#include <QGeoAddress>
11#endif // HAVE_QT5_POSITIONING
12
13#include <osm/OsmPlacemarkData.h>
14#include "GeoDataStyle.h"
15#include "GeoDataIconStyle.h"
16#include "GeoDataDocument.h"
17
18namespace Marble {
19
21 QObject( parent )
22{
23 // nothing to do
24}
25
26void Placemark::setGeoDataPlacemark( const Marble::GeoDataPlacemark &placemark )
27{
28 m_placemark = placemark;
29 m_address = QString();
30 m_description = QString();
31 m_website = QString();
32 m_wikipedia = QString();
33 m_openingHours = QString();
34 m_wheelchairInfo = QString();
35 m_wifiAvailable = QString();
36 m_phone = QString();
37 updateTags();
38 updateRelations(placemark);
39 emit coordinatesChanged();
40 emit nameChanged();
41 emit descriptionChanged();
42 emit addressChanged();
43 emit websiteChanged();
44 emit wikipediaChanged();
45 emit openingHoursChanged();
46 emit wheelchairInfoChanged();
47 emit wifiAvailabilityChanged();
48 emit phoneChanged();
49 emit tagsChanged();
50}
51
52Marble::GeoDataPlacemark & Placemark::placemark()
53{
54 return m_placemark;
55}
56
57const GeoDataPlacemark &Placemark::placemark() const
58{
59 return m_placemark;
60}
61
62QString Placemark::name() const
63{
64 return m_placemark.displayName();
65}
66
67QString Placemark::description() const
68{
69 if (m_description.isEmpty()) {
70 auto const category = m_placemark.visualCategory();
71 m_description = m_placemark.categoryName();
72
73 if (category == GeoDataPlacemark::AccomodationHotel || category == GeoDataPlacemark::FoodRestaurant) {
74 QString const stars = m_placemark.osmData().tagValue(QStringLiteral("stars"));
75 if (!stars.isEmpty()) {
76 bool hasStars;
77 int const numStars = stars.mid(0, 1).toInt(&hasStars);
78 if (hasStars) {
79 m_description += QString(' ') + QString("★").repeated(numStars) + stars.mid(1);
80 } else {
81 addTagValue(m_description, QStringLiteral("stars"));
82 }
83 }
84 addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
85 }
86
87 if ((category >= GeoDataPlacemark::AccomodationHostel &&
88 category <= GeoDataPlacemark::AccomodationGuestHouse) ||
89 category == GeoDataPlacemark::HealthHospital) {
90 int const rooms = m_placemark.osmData().tagValue(QStringLiteral("rooms")).toInt();
91 if (rooms > 0) {
92 //~ singular %n room
93 //~ plural %n rooms
94 addTagValue(m_description, QStringLiteral("rooms"), tr("%n rooms", nullptr, rooms));
95 }
96 int const beds = m_placemark.osmData().tagValue(QStringLiteral("beds")).toInt();
97 if (beds > 0) {
98 //~ singular %n bed
99 //~ plural %n beds
100 addTagValue(m_description, QStringLiteral("beds"), tr("%n beds", nullptr, beds));
101 }
102 }
103
104 if (category == GeoDataPlacemark::TransportParking || category == GeoDataPlacemark::TransportBicycleParking || category == GeoDataPlacemark::TransportMotorcycleParking) {
105 addTagValue(m_description, QStringLiteral("capacity"), tr("%1 parking spaces"));
106 addTagValue(m_description, QStringLiteral("maxstay"), tr("Maximum parking time %1"));
107 }
108
109 if (category >= GeoDataPlacemark::FoodBar && category <= GeoDataPlacemark::FoodRestaurant) {
110 if (category != GeoDataPlacemark::FoodRestaurant) {
111 addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
112 } else {
113 // Do nothing, already added in stars section above
114 }
115 addTagValue(m_description, "cuisine");
116 addTagValue(m_description, "brewery");
117 addTagDescription(m_description, "self_service", "yes", "Self Service");
118 addTagDescription(m_description, "takeaway", "yes", "Take Away");
119 addTagDescription(m_description, "outdoor_seating", "yes", "Outdoor Seating");
120 addTagDescription(m_description, "ice_cream", "yes", "Ice Cream");
121 addTagDescription(m_description, "smoking", "dedicated", "Smoking (dedicated)");
122 addTagDescription(m_description, "smoking", "yes", "Smoking allowed");
123 addTagDescription(m_description, "smoking", "separated", "Smoking (separated)");
124 addTagDescription(m_description, "smoking", "isolated", "Smoking (isolated)");
125 addTagDescription(m_description, "smoking", "no", "No smoking");
126 addTagDescription(m_description, "smoking", "outside", "Smoking (outside)");
127 addTagDescription(m_description, "smoking:outside", "yes", "Smoking (outside)");
128 addTagDescription(m_description, "smoking:outside", "separated", "Smoking (outside separated)");
129 addTagDescription(m_description, "smoking:outside", "no", "No smoking outside");
130 } else if (category >= GeoDataPlacemark::ShopBeverages && category <= GeoDataPlacemark::Shop) {
131 addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
132 addTagValue(m_description, "clothes");
133 addTagValue(m_description, "designation");
134 if (category == GeoDataPlacemark::ShopButcher) {
135 addTagValue(m_description, "butcher");
136 } else if (category == GeoDataPlacemark::ShopCopy) {
137 addTagDescription(m_description, QStringLiteral("service:computer"), QStringLiteral("yes"), tr("Computers available", "A copy shop provides computers for customer use"));
138 addTagDescription(m_description, QStringLiteral("service:computer"), QStringLiteral("no"), tr("No computers available", "A copy shop does not provide computers for customer use"));
139 addTagDescription(m_description, QStringLiteral("service:copy"), QStringLiteral("yes"), tr("Photocopying service", "A copy shop provides photocopying service"));
140 addTagDescription(m_description, QStringLiteral("service:copy"), QStringLiteral("no"), tr("No photocopying service", "A copy shop does not provide photocopying service"));
141 addTagDescription(m_description, QStringLiteral("service:scan"), QStringLiteral("yes"), tr("Digital scanning", "A copy shop provides a service for scanning documents into digital files"));
142 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"));
143 addTagDescription(m_description, QStringLiteral("service:fax"), QStringLiteral("yes"), tr("Fax service", "A copy shop provides a service to send documents through fax"));
144 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"));
145 addTagDescription(m_description, QStringLiteral("service:phone"), QStringLiteral("yes"), tr("Phone service", "A copy shop provides a paid service to make phone calls"));
146 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"));
147 addTagDescription(m_description, QStringLiteral("service:print"), QStringLiteral("yes"), tr("Digital printing", "A copy shop provides services to print paper documents from digital files"));
148 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"));
149 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"));
150 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"));
151 addTagDescription(m_description, QStringLiteral("service:prepress"), QStringLiteral("yes"), tr("Press printing assistance", "A copy shop provides help with preparing special printing techniques"));
152 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"));
153 addTagDescription(m_description, QStringLiteral("service:self"), QStringLiteral("yes"), tr("Self service", "A copy shop provides individual copy machines for self-service"));
154 addTagDescription(m_description, QStringLiteral("service:self"), QStringLiteral("no"), tr(" No self service", "A copy shop does not provide individual machines for self-service"));
155 } else if (category == GeoDataPlacemark::ShopDeli) {
156 addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("yes"), tr("Sells organic food", "A deli that sells organic food"));
157 addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("no"), tr("Does not sell organic food", "A deli that does not sell organic food"));
158 addTagDescription(m_description, QStringLiteral("organic"), QStringLiteral("only"), tr("Only sells organic food", "A deli that only sells organic food"));
159
160 addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("yes"), tr("Sells gluten free food", "A deli that sells gluten free food"));
161 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"));
162 addTagDescription(m_description, QStringLiteral("diet:gluten_free"), QStringLiteral("only"), tr("Only sells gluten free food", "A deli that only sells gluten free food"));
163
164 addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("yes"), tr("Sells lactose free food", "A deli that sells lactose free food"));
165 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"));
166 addTagDescription(m_description, QStringLiteral("diet:lactose_free"), QStringLiteral("only"), tr("Only sells lactose free food", "A deli that only sells lactose free food"));
167 } else if (category == GeoDataPlacemark::ShopTobacco) {
168 addTagDescription(m_description, QStringLiteral("lottery"), QStringLiteral("yes"), tr("Sells lottery tickets", "A tobacco shop that also sells lottery tickets"));
169 addTagDescription(m_description, QStringLiteral("stamps"), QStringLiteral("yes"), tr("Sells revenue stamps", "A tobacco shop that also sells revenue stamps"));
170 addTagDescription(m_description, QStringLiteral("salt"), QStringLiteral("yes"), tr("Sells salt", "A tobacco shop that also sells salt"));
171 }
172 } else if (category == GeoDataPlacemark::TransportBusStop) {
173 addTagValue(m_description, "network");
174 addTagValue(m_description, "operator");
175 addTagValue(m_description, "ref");
176 } else if (category == GeoDataPlacemark::TransportCarShare) {
177 addTagValue(m_description, "network");
178 addTagValue(m_description, "operator");
179 } else if (category == GeoDataPlacemark::TransportRentalBicycle ||
180 category == GeoDataPlacemark::TransportRentalCar ||
181 category == GeoDataPlacemark::TransportRentalSki) {
182 addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
183
184 } else if (category == GeoDataPlacemark::TransportFuel) {
185 addFirstTagValueOf(m_description, QStringList() << "brand" << "operator");
186 addTagDescription(m_description, "fuel:diesel", "yes", tr("Diesel"));
187 addTagDescription(m_description, "fuel:biodiesel", "yes", tr("Biodiesel"));
188 addTagDescription(m_description, "fuel:octane_91", "yes", tr("Octane 91"));
189 addTagDescription(m_description, "fuel:octane_95", "yes", tr("Octane 95"));
190 addTagDescription(m_description, "fuel:octane_98", "yes", tr("Octane 98"));
191 addTagDescription(m_description, "fuel:octane_100", "yes", tr("Octane 100"));
192 addTagDescription(m_description, "fuel:e10", "yes", tr("E10"));
193 addTagDescription(m_description, "fuel:lpg", "yes", tr("LPG"));
194 } else if (category == GeoDataPlacemark::NaturalTree) {
195 addTagValue(m_description, "species:en");
196 addTagValue(m_description, "genus:en");
197 addTagValue(m_description, "leaf_type");
198 } else if (category == GeoDataPlacemark::NaturalCave){
199 addTagValue(m_description, "cave:ref");
200 } else if (category == GeoDataPlacemark::AmenityRecycling) {
201 addTagDescription(m_description, QStringLiteral("recycling:batteries"), "yes", tr("Batteries"));
202 addTagDescription(m_description, QStringLiteral("recycling:clothes"), "yes", tr("Clothes"));
203 addTagDescription(m_description, QStringLiteral("recycling:glass"), "yes", tr("Glass"));
204 addTagDescription(m_description, QStringLiteral("recycling:glass_bottles"), "yes", tr("Glass bottles"));
205 addTagDescription(m_description, QStringLiteral("recycling:green_waste"), "yes", tr("Green waste"));
206 addTagDescription(m_description, QStringLiteral("recycling:garden_waste"), "yes", tr("Garden waste"));
207 addTagDescription(m_description, QStringLiteral("recycling:electrical_items"), "yes", tr("Electrical items"));
208 addTagDescription(m_description, QStringLiteral("recycling:metal"), "yes", tr("Metal"));
209 addTagDescription(m_description, QStringLiteral("recycling:mobile_phones"), "yes", tr("Mobile phones"));
210 addTagDescription(m_description, QStringLiteral("recycling:newspaper"), "yes", tr("Newspaper"));
211 addTagDescription(m_description, QStringLiteral("recycling:paint"), "yes", tr("Paint"));
212 addTagDescription(m_description, QStringLiteral("recycling:paper"), "yes", tr("Paper"));
213 addTagDescription(m_description, QStringLiteral("recycling:paper_packaging"), "yes", tr("Paper packaging"));
214 addTagDescription(m_description, QStringLiteral("recycling:PET"), "yes", tr("PET"));
215 addTagDescription(m_description, QStringLiteral("recycling:plastic"), "yes", tr("Plastic"));
216 addTagDescription(m_description, QStringLiteral("recycling:plastic_bags"), "yes", tr("Plastic bags"));
217 addTagDescription(m_description, QStringLiteral("recycling:plastic_bottles"), "yes", tr("Plastic bottles"));
218 addTagDescription(m_description, QStringLiteral("recycling:plastic_packaging"), "yes", tr("Plastic packaging"));
219 addTagDescription(m_description, QStringLiteral("recycling:polyester"), "yes", tr("Polyester"));
220 addTagDescription(m_description, QStringLiteral("recycling:tyres"), "yes", tr("Tyres"));
221 addTagDescription(m_description, QStringLiteral("recycling:waste"), "yes", tr("Waste"));
222 addTagDescription(m_description, QStringLiteral("recycling:white_goods"), "yes", tr("White goods"));
223 addTagDescription(m_description, QStringLiteral("recycling:wood"), "yes", tr("Wood"));
224 } else if (category == GeoDataPlacemark::NaturalVolcano) {
225 addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("active"), tr("Active", "An active volcano"));
226 addTagDescription(m_description, QStringLiteral("volcano:status"), QStringLiteral("dormant"), tr("Dormant", "A dormant volcano that will erupt at some point in the future."));
227 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."));
228 addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("stratovolcano"), tr("Stratovolcano"));
229 addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("shield"), tr("Shield volcano"));
230 addTagDescription(m_description, QStringLiteral("volcano:type"), QStringLiteral("scoria"), tr("Scoria cone", "A scoria cone volcano."));
231 } else if (category == GeoDataPlacemark::HealthDoctors) {
232 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("alternative"), tr("Alternative medicine"));
233 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("audiologist"), tr("Audiologist"));
234 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("blood_bank"), tr("Blood bank"));
235 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("blood_donation"), tr("Blood donation"));
236 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("centre"), tr("Medical center"));
237 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("clinic"), tr("Clinic"));
238 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("dentist"), tr("Dentist"));
239 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("doctor"), tr("Medical practitioner"));
240 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("hospital"), tr("Hospital"));
241 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("midwife"), tr("Midwife"));
242 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("optometrist"), tr("Optometrist"));
243 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("physiotherapist"), tr("Physiotherapist"));
244 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("podiatrist"), tr("Podiatrist"));
245 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("psychotherapist"), tr("Psychotherapist"));
246 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("rehabilitation"), tr("Rehabilitation"));
247 addTagDescription(m_description, QStringLiteral("healthcare"), QStringLiteral("speech_therapist"), tr("Speech therapist"));
248 addTagValue(m_description, QStringLiteral("healthcare:speciality"));
249 } else if (category == GeoDataPlacemark::AmenityBench) {
250 int const seats = m_placemark.osmData().tagValue(QStringLiteral("seats")).toInt();
251 if (seats > 0) {
252 //~ singular %n seat
253 //~ plural %n seats
254 addTagValue(m_description, QStringLiteral("seats"), tr("%n seats", "number of seats a bench provides", seats));
255 }
256 addTagValue(m_description, QStringLiteral("material"));
257 addTagDescription(m_description, QStringLiteral("backrest"), QStringLiteral("yes"), tr("Has backrest", "A bench provides a backrest to lean against"));
258 addTagDescription(m_description, QStringLiteral("backrest"), QStringLiteral("no"), tr("No backrest", "A bench provides no backrest to lean against"));
259 } else if (category == GeoDataPlacemark::AmenityWasteBasket) {
260 addTagValue(m_description, QStringLiteral("waste"));
261 } else if (category == GeoDataPlacemark::TransportSpeedCamera) {
262 addTagValue(m_description, QStringLiteral("maxspeed"), tr("%1 km/h"));
263 addTagValue(m_description, "ref");
264 } else if (category == GeoDataPlacemark::TransportParking) {
265 addTagDescription(m_description, QStringLiteral("supervised"), QStringLiteral("yes"), tr("Is supervised", "Parking spaces are supervised by guards"));
266 addTagDescription(m_description, QStringLiteral("supervised"), QStringLiteral("no"), tr("Not supervised", "Parking spaces are not supervised by guards"));
267
268 int const disabledSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:disabled")).toInt();
269 if (disabledSpaces > 0) {
270 addTagValue(m_description, QStringLiteral("capacity:disabled"), tr("%1 disabled spaces", "Parking spaces"));
271 }
272 int const womenSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:women")).toInt();
273 if (womenSpaces > 0) {
274 addTagValue(m_description, QStringLiteral("capacity:women"), tr("%1 women spaces", "Parking spaces"));
275 }
276 int const parentSpaces = m_placemark.osmData().tagValue(QStringLiteral("capacity:parent")).toInt();
277 if (parentSpaces > 0) {
278 addTagValue(m_description, QStringLiteral("capacity:parent"), tr("%1 parent and child spaces", "Parking spaces"));
279 }
280 int const electricChargers = m_placemark.osmData().tagValue(QStringLiteral("capacity:charging")).toInt();
281 if (electricChargers > 0) {
282 addTagValue(m_description, QStringLiteral("capacity:charging"), tr("%1 spaces with electric chargers", "Parking spaces"));
283 }
284 } else if (category == GeoDataPlacemark::TransportBicycleParking) {
285 addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("outdoor"), tr("Has outdoor surveillance", "A parking space has outdoor surveillance"));
286 addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("indoor"), tr("Has indoor surveillance", "A parking space has indoor surveillance"));
287 addTagDescription(m_description, QStringLiteral("surveillance"), QStringLiteral("public"), tr("Has public surveillance", "A parking space has public surveillance"));
288 } else if (category == GeoDataPlacemark::TourismWildernessHut) {
289 addTagDescription(m_description, QStringLiteral("shower"), QStringLiteral("yes"), tr("Has shower", "A hut provides showers inside or aside"));
290 addTagDescription(m_description, QStringLiteral("shower"), QStringLiteral("no"), tr("Has no shower", "A hut does not provide showers inside or aside"));
291 addTagDescription(m_description, QStringLiteral("mattress"), QStringLiteral("yes"), tr("Has mattress", "A hut provides mattress"));
292 addTagDescription(m_description, QStringLiteral("mattress"), QStringLiteral("no"), tr("Has no mattress", "A hut does not provide mattress"));
293 addTagDescription(m_description, QStringLiteral("drinking_water"), QStringLiteral("yes"), tr("Has water", "Water is available inside or aside"));
294 addTagDescription(m_description, QStringLiteral("drinking_water"), QStringLiteral("no"), tr("Has no water", "Water is not available inside nor aside"));
295 addTagDescription(m_description, QStringLiteral("toilets"), QStringLiteral("yes"), tr("Has toilets", "A hut provides toilets"));
296 addTagDescription(m_description, QStringLiteral("toilets"), QStringLiteral("no"), tr("Has no toilets", "A hut does not provide toilets"));
297 addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("yes"), tr("Reservation is possible"));
298 addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("no"), tr("No reservation possible"));
299 addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("required"), tr("Reservation is required"));
300 addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("recommended"), tr("Reservation is recommended", "You should make reservation"));
301 addTagDescription(m_description, QStringLiteral("reservation"), QStringLiteral("members_only"), tr("Only for members", "Reservation is only possible for members of the organisation running the hut"));
302 } else if (category == GeoDataPlacemark::TourismArtwork) {
303 addTagValue(m_description, QStringLiteral("artist_name"), tr("By %1"));
304 } else if (category == GeoDataPlacemark::AmenityChargingStation) {
305 addTagValue(m_description, QStringLiteral("capacity"), tr("%1 vehicles"));
306 addTagValue(m_description, QStringLiteral("amperage"), tr("%1 ampere"));
307 addTagValue(m_description, QStringLiteral("voltage"), tr("%1 volt"));
308
309 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_blue"), tr("%1 blue CEE sockets"));
310 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_16a"), tr("%1 red CEE sockets (16 A)"));
311 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_32a"), tr("%1 red CEE sockets (32 A)"));
312 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_64a"), tr("%1 red CEE sockets (64 A)"));
313 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("cee_red_125a"), tr("%1 red CEE sockets (125 A)"));
314 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_5_15"), tr("%1 NEMA-5-15P plugs"));
315 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("typeb"), tr("%1 NEMA-5-15P plugs"));
316 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_5_20"), tr("%1 NEMA-5-20P plugs"));
317 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_14_30"), tr("%1 NEMA 14-30 sockets"));
318 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("nema_14_50"), tr("%1 NEMA 14-50 sockets"));
319 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("schuko"), tr("%1 Schuko sockets"));
320 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("bs1363"), tr("%1 BS 1363 sockets"));
321 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type1"), tr("%1 Type 1 plugs"));
322 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type1_combo"), tr("%1 Type 1 combo plugs"));
323 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type2"), tr("%1 Type 2 sockets"));
324 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type2_combo"), tr("%1 Type 2 combo sockets"));
325 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("type3"), tr("%1 Type 3 sockets"));
326 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("chademo"), tr("%1 CHAdeMO plugs"));
327 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("magne_charge"), tr("%1 Magne Charge plugs"));
328 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_standard"), tr("%1 Tesla standard plugs"));
329 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_supercharger"), tr("%1 Tesla standard plugs (Supercharger)"));
330 addTagDescription(m_description, QStringLiteral("socket"), QStringLiteral("tesla_roadster"), tr("%1 Tesla roadster plugs"));
331 } else if (category == GeoDataPlacemark::AmenityCarWash) {
332 addTagValue(m_description, QStringLiteral("maxwidth"), tr("Maximum vehicle width: %1"));
333 addTagValue(m_description, QStringLiteral("maxheight"), tr("Maximum vehicle height: %1"));
334
335 addTagDescription(m_description, QStringLiteral("self_service"), QStringLiteral("yes"), tr("Self-service"));
336 addTagDescription(m_description, QStringLiteral("self_service"), QStringLiteral("no"), tr("No self-service"));
337 addTagDescription(m_description, QStringLiteral("automated"), QStringLiteral("yes"), tr("Automated"));
338 addTagDescription(m_description, QStringLiteral("automated"), QStringLiteral("no"), tr("Manual"));
339 } else if (category == GeoDataPlacemark::AmenitySocialFacility) {
340 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("group_home"), tr("Group home"));
341 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("nursing_home"), tr("Nursing home"));
342 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"));
343 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("day_care"), tr("Nursing services on a daily basis"));
344 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("shelter"), tr("Shelter"));
345 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("ambulatory_care"), tr("Ambulatory care"));
346 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("outreach"), tr("Social welfare services"));
347 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("workshop"), tr("Employment and workshops for offenders and people with disabilities"));
348 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("food_bank"), tr("Pre-packaged food for free or below market price"));
349 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("soup_kitchen"), tr("Prepared meals for free or below market price"));
350 addTagDescription(m_description, QStringLiteral("social_facility"), QStringLiteral("dairy_kitchen"), tr("Free dairy food (subject to local regulations)"));
351
352 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("abused"), tr("For abused"));
353 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("child"), tr("For children"));
354 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("disabled"), tr("For people with physical disabilities"));
355 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("diseased"), tr("For those who suffer of a disease"));
356 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("drug_addicted"), tr("For drug-addicted"));
357 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("homeless"), tr("For homeless"));
358 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("juvenile"), tr("For juvenile"));
359 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("mental_health"), tr("For those with mental/psychological problems"));
360 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("migrant"), tr("For migrants"));
361 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("orphan"), tr("For orphans"));
362 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("senior"), tr("For elder people"));
363 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("underprivileged"), tr("For poor or disadvantaged people"));
364 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("unemployed"), tr("For unemployed"));
365 addTagDescription(m_description, QStringLiteral("social_facility:for"), QStringLiteral("victim"), tr("For victims of crimes"));
366 } else if (category == GeoDataPlacemark::HistoricMemorial) {
367 addTagValue(m_description, QStringLiteral("inscription"), tr("Inscription: %1"));
368 } else if (category >= GeoDataPlacemark::AerialwayCableCar && category <= GeoDataPlacemark::AerialwayGoods) {
369 addTagValue(m_description, QStringLiteral("occupancy"), tr("%1 places per carriage"));
370 addTagValue(m_description, QStringLiteral("capacity"), tr("%1 people per hour"));
371 addTagValue(m_description, QStringLiteral("duration"), tr("%1 minutes"));
372
373 addTagDescription(m_description, QStringLiteral("bubble"), QStringLiteral("yes"), tr("Has weather protection", "A carriage is protected from the weather"));
374 addTagDescription(m_description, QStringLiteral("bubble"), QStringLiteral("no"), tr("No weather protection", "A carriage is not protected from the weather"));
375 addTagDescription(m_description, QStringLiteral("heating"), QStringLiteral("yes"), tr("Is heated", "A carriage is heated"));
376 addTagDescription(m_description, QStringLiteral("heating"), QStringLiteral("no"), tr("Not heated", "A carriage is not heated"));
377 addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("yes"), tr("Bicycle transportation possible", "Bicycles can be transported"));
378 addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("summer"), tr("Bicycle transportation only in summer", "Bicycles can only be transported in summer"));
379 addTagDescription(m_description, QStringLiteral("bicycle"), QStringLiteral("no"), tr("Bicycle transportation impossible", "Bicyles cannot be transported"));
380 } else if (category >= GeoDataPlacemark::PisteDownhill && category <= GeoDataPlacemark::PisteSkiJump) {
381 addTagDescription(m_description, QStringLiteral("lit"), QStringLiteral("yes"), tr("Lit at night"));
382 addTagDescription(m_description, QStringLiteral("piste:lit"), QStringLiteral("yes"), tr("Lit in winter"));
383 addTagDescription(m_description, QStringLiteral("gladed"), QStringLiteral("yes"), tr("Contains trees", "A ski piste with trees (gladed)"));
384 addTagDescription(m_description, QStringLiteral("patrolled"), QStringLiteral("no"), tr("Not patrolled"));
385
386 addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic"), tr("Groomed for classic style nordic or downhill skiing"));
387 addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("mogul"), tr("Mogul piste"));
388 addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("skating"), tr("Groomed for free style or skating"));
389 addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic;skating"), tr("Groomed for classic and free style skiing"));
390 addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("classic+skating"), tr("Groomed for classic and free style skiing"));
391 addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("scooter"), tr("Groomed by a smaller snowmobile"));
392 addTagDescription(m_description, QStringLiteral("piste:grooming"), QStringLiteral("backcountry"), tr("Unmarked piste (backcountry touring)"));
393 }
394
395 if (category == GeoDataPlacemark::TransportBicycleParking || category == GeoDataPlacemark::TransportMotorcycleParking) {
396 addTagDescription(m_description, QStringLiteral("covered"), QStringLiteral("yes"), tr("Is covered", "A parking space is covered"));
397 addTagDescription(m_description, QStringLiteral("covered"), QStringLiteral("no"), tr("Not covered", "A parking space is not covered"));
398 }
399
400 if (category == GeoDataPlacemark::AmenityRecycling || category == GeoDataPlacemark::AmenityPostBox) {
401 addTagValue(m_description, QStringLiteral("collection_times"), tr("Collection times %1"), QStringLiteral(", "));
402 }
403
404 if (category == GeoDataPlacemark::AerialwayStation) {
405 addTagDescription(m_description, "aerialway:access", "entry", tr("Entry", "Entry station of an aerialway"));
406 addTagDescription(m_description, "aerialway:access", "exit", tr("Exit", "Exit station of an aerialway"));
407 addTagDescription(m_description, "aerialway:access", "both", tr("Entry and exit", "Entry and exit station of an aerialway"));
408 addTagDescription(m_description, "aerialway:access", "no", tr("No entry or exit", "Transit only station of an aerialway"));
409 addTagDescription(m_description, "aerialway:summer:access", "entry", tr("Entry during summer", "Entry station of an aerialway during summer"));
410 addTagDescription(m_description, "aerialway:summer:access", "exit", tr("Exit during summer", "Exit station of an aerialway during summer"));
411 addTagDescription(m_description, "aerialway:summer:access", "both", tr("Entry and exit during summer", "Entry and exit station of an aerialway during summer"));
412 addTagDescription(m_description, "aerialway:summer:access", "no", tr("No entry or exit during summer", "Transit only station of an aerialway during summer"));
413 }
414
415 if (category != GeoDataPlacemark::AerialwayStation) {
416 addTagValue(m_description, QStringLiteral("ele"), tr("Elevation: %1 m"));
417 }
418
419 addTagDescription(m_description, "access", "customers", tr("Customers only"));
420 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"));
421 addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("private"), tr("Private", "Only with permission of the owner on an individual basis."));
422 addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("permissive"), tr("Open to general traffic", "Open to general traffic but permission can be revoked by the owner"));
423 addTagDescription(m_description, QStringLiteral("access"), QStringLiteral("no"), tr("No access", "No access for the general public"));
424
425
426 addTagDescription(m_description, QStringLiteral("fee"), QStringLiteral("no"), tr("no fee"));
427 addTagValue(m_description, QStringLiteral("description"));
428 addTagValue(m_description, QStringLiteral("old_name"), tr("formerly <i>%1</i>"));
429
430 const int level = m_placemark.osmData().tagValue(QStringLiteral("level")).toInt();
431 if (level > 2) {
432 addTagValue(m_description, QStringLiteral("level"), tr("Floor %1", "Positive floor level"));
433 } else if (level < -2) {
434 addTagValue(m_description, QStringLiteral("level"), tr("Basement %1", "Negative floor level"));
435 } else {
436 addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("2"), tr("Floor 2", "Floor level 2, two levels above ground level"));
437 addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("1"), tr("Floor 1", "Floor level 1, one level above ground level"));
438 addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("0"), tr("Ground floor", "Floor level 0"));
439 addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("-1"), tr("Basement 1", "Floor level -1, one level below ground level"));
440 addTagDescription(m_description, QStringLiteral("level"), QStringLiteral("-2"), tr("Basement 2", "Floor level -2, two levels below ground level"));
441 }
442 }
443
444 return m_description;
445}
446
447QString Placemark::address() const
448{
449 if (m_address.isEmpty()) {
450 m_address = addressFromOsmData();
451 }
452 return m_address;
453}
454
455QString Placemark::website() const
456{
457 if (!m_website.isEmpty()) {
458 return m_website;
459 }
460 auto const tags = QStringList() << "website" << "contact:website" << "facebook" << "contact:facebook" << "url";
461 for(const QString &tag: tags) {
462 QString const value = m_placemark.osmData().tagValue(tag);
463 if (!value.isEmpty()) {
464 QUrl url = QUrl(value);
465 if (url.isValid()) {
466 if (url.scheme().isEmpty()) {
467 m_website = QStringLiteral("http://%1").arg(value);
468 } else {
469 m_website = value;
470 }
471 if (!m_website.isEmpty()) {
472 return m_website;
473 }
474 }
475 }
476 }
477
478 return m_website;
479}
480
481QString Placemark::wikipedia() const
482{
483 if (!m_wikipedia.isEmpty()) {
484 return m_wikipedia;
485 }
486
487 // TODO: also support "wikipedia:lang=page title" tags
488 const QString wikipedia = m_placemark.osmData().tagValue("wikipedia");
489 if (!wikipedia.isEmpty()) {
490 // full URL?
491 if (wikipedia.startsWith(QLatin1String("http://")) ||
492 wikipedia.startsWith(QLatin1String("https://"))) {
493 m_wikipedia = wikipedia;
494 } else {
495 // match "(lang:)human readable title"
496 QRegularExpression re("^(?:([a-z]{2,}):)?(.*)$");
497 QRegularExpressionMatch match = re.match(wikipedia);
498 QString lang = match.captured(1);
499 if (lang.isEmpty()) {
500 lang = QStringLiteral("en");
501 }
502 const QString title = QString::fromLatin1(QUrl::toPercentEncoding(match.captured(2)));
503
504 m_wikipedia = QLatin1String("https://") + lang + QLatin1String(".wikipedia.org/wiki/") + title;
505 }
506 }
507
508 return m_wikipedia;
509}
510
511QString Placemark::openingHours() const
512{
513 if (!m_openingHours.isEmpty()) {
514 return m_openingHours;
515 }
516
517 addTagValue(m_openingHours, "opening_hours");
518 return m_openingHours;
519}
520
521QString Placemark::coordinates() const
522{
524}
525
526QString Placemark::wheelchairInfo() const
527{
528 if (!m_wheelchairInfo.isEmpty())
529 return m_wheelchairInfo;
530
531 addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("yes"), tr("Wheelchair accessible"));
532 addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("no"), tr("Wheelchair inaccessible"));
533 addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("limited"), tr("Limited wheelchair accessibility"));
534 addTagDescription(m_wheelchairInfo, QStringLiteral("wheelchair"), QStringLiteral("designated"), tr("Designated wheelchair access"));
535
536 // Check if there is localized description
537 auto const & osmData = m_placemark.osmData();
538 QStringList const uiLanguages = QLocale::system().uiLanguages();
539 const QString tag = QLatin1String("wheelchair:description:");
540 for (const QString &uiLanguage: uiLanguages) {
541 for (auto tagIter = osmData.tagsBegin(), end = osmData.tagsEnd(); tagIter != end; ++tagIter) {
542 if (tagIter.key().startsWith(tag)) {
543 QStringRef const tagLanguage = tagIter.key().midRef(tag.length());
544 if (tagLanguage == uiLanguage) {
545 append(m_wheelchairInfo, tagIter.value());
546 return m_wheelchairInfo;
547 }
548 }
549 }
550 }
551
552 addTagValue(m_wheelchairInfo, "wheelchair:description");
553
554 return m_wheelchairInfo;
555}
556
557QString Placemark::wifiAvailable() const
558{
559 if (!m_wifiAvailable.isEmpty()) {
560 return m_wifiAvailable;
561 }
562
563 const auto& osmData = m_placemark.osmData();
564 addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("no"), tr("No public Internet access", "This location does not provide public Internet access"));
565 addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("yes"), tr("Public Internet access available", "This location provides an unknown type of public Internet access."));
566
567 if (osmData.containsTag(QStringLiteral("internet_access:fee"), QStringLiteral("yes"))) {
568 addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Charged public wifi available", "Public wireless Internet access is available here for a fee."));
569 } else if (osmData.containsTag(QStringLiteral("internet_access:fee"), QStringLiteral("no"))) {
570 addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Free public wifi available", "Public wireless Internet access is available here for no cost."));
571 } else {
572 addTagDescription(m_wifiAvailable, QStringLiteral("internet_access"), QStringLiteral("wlan"), tr("Public wifi available", "Public wireless Internet access is available here."));
573 }
574
575 if (m_wifiAvailable.isEmpty()) {
576 addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("no"), tr("No public wifi", "Public wifi is not available here."));
577 addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("yes"), tr("Public wifi available", "Public wireless Internet is available here."));
578 addTagDescription(m_wifiAvailable, QStringLiteral("wifi"), QStringLiteral("free"), tr("Free public wifi available", "Public wireless Internet is available here for no cost."));
579 }
580
581 return m_wifiAvailable;
582}
583
584QString Placemark::phone() const
585{
586 if (!m_phone.isEmpty()) {
587 return m_phone;
588 }
589
590 addTagValue(m_phone, "phone");
591 return m_phone;
592}
593
594void Placemark::setName(const QString & name)
595{
596 if (m_placemark.displayName() == name) {
597 return;
598 }
599
600 m_placemark.setName(name);
601 emit nameChanged();
602}
603
604RouteRelationModel* Placemark::routeRelationModel()
605{
606 return &m_relationModel;
607}
608
609double Placemark::longitude() const
610{
611 return m_placemark.coordinate().longitude(GeoDataCoordinates::Degree);
612}
613
614double Placemark::latitude() const
615{
616 return m_placemark.coordinate().latitude(GeoDataCoordinates::Degree);
617}
618
619const QStringList &Placemark::tags() const
620{
621 return m_tags;
622}
623
624bool Placemark::addTagValue(QString &target, const QString &key, const QString &format, const QString& separator) const
625{
626 auto const & osmData = m_placemark.osmData();
627 QString const value = osmData.tagValue(key);
628 if (!value.isEmpty()) {
629 QString description = format.isEmpty() ? value : format.arg(value);
630 description.replace(QLatin1Char(';'), separator);
631 append(target, description);
632 return true;
633 }
634 return false;
635}
636
637void Placemark::addFirstTagValueOf(QString &target, const QStringList &keys) const
638{
639 for (auto const &key: keys) {
640 if (addTagValue(target, key)) {
641 return;
642 }
643 }
644}
645
646void Placemark::addTagDescription(QString &target, const QString &key, const QString &value, const QString &description) const
647{
648 auto const & osmData = m_placemark.osmData();
649 if (osmData.containsTag(key, value)) {
650 append(target, description);
651 }
652}
653
654void Placemark::append(QString &target, const QString &value)
655{
656 if (!target.isEmpty()) {
657 target += QStringLiteral(" · "); // non-latin1
658 }
659 target += value;
660}
661
662QString Placemark::addressFromOsmData() const
663{
664#ifdef HAVE_QT5_POSITIONING
665 QGeoAddress address;
666 OsmPlacemarkData const data = m_placemark.osmData();
667 address.setCountry(data.tagValue("addr:country"));
668 address.setState(data.tagValue("addr:state"));
669 address.setCity(data.tagValue("addr:city"));
670 address.setDistrict(data.tagValue("district"));
671 address.setPostalCode(data.tagValue("addr:postcode"));
672 QString const street = data.tagValue("addr:street");
673 QString const houseNumber = data.tagValue("addr:housenumber");
674 address.setStreet(formatStreet(street, houseNumber));
675 return address.text().replace("<br/>", ", ");
676#else
677 return QString();
678#endif
679}
680
681QString Placemark::formatStreet(const QString &street, const QString &houseNumber)
682{
683 return houseNumber.isEmpty() ? street : tr("%1 %2",
684 "House number (first argument) and street name (second argument) in an address").arg(houseNumber).arg(street).trimmed();
685}
686
687void Placemark::updateTags()
688{
689 m_tags.clear();
690 QString const tag = QStringLiteral("%1 = %2");
691 for (auto iter = m_placemark.osmData().tagsBegin(), end = m_placemark.osmData().tagsEnd(); iter != end; ++iter) {
692 m_tags << tag.arg(iter.key()).arg(iter.value());
693 }
694}
695
696void Placemark::updateRelations(const Marble::GeoDataPlacemark &placemark)
697{
698 if (const auto document = (placemark.parent() ? geodata_cast<GeoDataDocument>(placemark.parent()) : nullptr)) {
702 auto const & osmData = placemark.osmData();
703 placemarkIds << osmData.oid();
704 bool searchRelations = true;
705 for (auto feature: document->featureList()) {
706 if (const auto relation = geodata_cast<GeoDataRelation>(feature)) {
707 allRelations << relation;
708 if (relation->memberIds().contains(osmData.oid())) {
709 relevantRelations << relation;
710 auto const isRoute = relation->osmData().tagValue(QStringLiteral("type")) == QStringLiteral("route");
712 }
713 }
714 }
715 if (searchRelations) {
716 for (auto feature: document->featureList()) {
717 if (const auto relation = geodata_cast<GeoDataRelation>(feature)) {
718 if (relevantRelations.contains(relation) &&
719 relation->osmData().containsTag(QStringLiteral("type"), QStringLiteral("public_transport")) &&
720 relation->osmData().containsTag(QStringLiteral("public_transport"), QStringLiteral("stop_area"))) {
721 for (auto iter = relation->osmData().relationReferencesBegin(), end = relation->osmData().relationReferencesEnd();
722 iter != end; ++iter) {
723 if (iter.value() == QStringLiteral("stop") || iter.value() == QStringLiteral("platform")) {
724 placemarkIds << iter.key().id;
725 }
726 }
727 }
728 }
729 }
730 }
731 for (auto relation: allRelations) {
732 if (relation->containsAnyOf(placemarkIds)) {
733 relevantRelations << relation;
734 }
735 }
736 m_relationModel.setRelations(relevantRelations);
737 }
738}
739
740}
741
742#include "moc_Placemark.cpp"
@ Decimal
"Decimal" notation (base-10)
qreal longitude(GeoDataCoordinates::Unit unit) const
retrieves the longitude of the GeoDataCoordinates object use the unit parameter to switch between Rad...
qreal latitude(GeoDataCoordinates::Unit unit) const
retrieves the latitude of the GeoDataCoordinates object use the unit parameter to switch between Radi...
QString toString() const
return a string representation of the coordinate this is a convenience function which uses the defaul...
void setName(const QString &value)
Set a new name for this feature.
const GeoDataObject * parent() const
Provides the parent of the object in GeoDataContainers.
a class representing a point of interest on the map
GeoDataVisualCategory visualCategory() const
Return the symbol index of the placemark.
OsmPlacemarkData & osmData()
Quick, safe accessor to the placemark's OsmPlacemarkData stored within it's ExtendedData.
GeoDataCoordinates coordinate(const QDateTime &dateTime=QDateTime(), bool *iconAtCoordinates=nullptr) const
Return the coordinates of the placemark at time dateTime as a GeoDataCoordinates.
QString displayName() const
displays the name of a place in the locale language of the user
QHash< QString, QString >::const_iterator tagsBegin() const
iterators for the tags hash.
QString tagValue(const QString &key) const
tagValue returns the value of the tag that has key as key or an empty qstring if there is no such tag
Placemark(QObject *parent=nullptr)
Constructor.
Definition Placemark.cpp:20
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
PostalAddress address(const QVariant &location)
QStringView level(QStringView ifopt)
Category category(StandardShortcut id)
const QList< QKeySequence > & end()
Binds a QML item to a specific geodetic location in screen coordinates.
void clear()
QLocale system()
QStringList uiLanguages() const const
T qobject_cast(QObject *object)
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
qsizetype length() const const
QString repeated(qsizetype times) const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
int toInt(bool *ok, int base) const const
QString trimmed() const const
bool isValid() const const
QString scheme() const const
QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude, const QByteArray &include)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jun 14 2024 11:54:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.