1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2015 Dennis Nienhüser <nienhueser@kde.org>
4 //
5 
6 #include <OsmNode.h>
7 
8 #include "osm/OsmObjectManager.h"
9 #include <GeoDataStyle.h>
10 #include <GeoDataIconStyle.h>
11 #include <GeoDataDocument.h>
12 #include <MarbleDirs.h>
13 #include <StyleBuilder.h>
14 
15 #include <QXmlStreamAttributes>
16 
17 namespace Marble {
18 
parseCoordinates(const QXmlStreamAttributes & attributes)19 void OsmNode::parseCoordinates(const QXmlStreamAttributes &attributes)
20 {
21     qreal const lon = attributes.value(QLatin1String("lon")).toDouble();
22     qreal const lat = attributes.value(QLatin1String("lat")).toDouble();
23     setCoordinates(GeoDataCoordinates(lon, lat, 0, GeoDataCoordinates::Degree));
24 }
25 
setCoordinates(const GeoDataCoordinates & coordinates)26 void OsmNode::setCoordinates(const GeoDataCoordinates &coordinates)
27 {
28     m_coordinates = coordinates;
29 }
30 
create() const31 GeoDataPlacemark *OsmNode::create() const
32 {
33     GeoDataPlacemark::GeoDataVisualCategory const category = StyleBuilder::determineVisualCategory(m_osmData);
34 
35     if (category == GeoDataPlacemark::None && m_osmData.isEmpty()) {
36         return nullptr;
37     }
38 
39     GeoDataPlacemark* placemark = new GeoDataPlacemark;
40     placemark->setOsmData(m_osmData);
41     auto coordinates = m_coordinates;
42     coordinates.setAltitude(m_osmData.tagValue("ele").toDouble());
43     placemark->setCoordinate(coordinates);
44 
45     QHash<QString, QString>::const_iterator tagIter;
46     if ((category == GeoDataPlacemark::TransportCarShare || category == GeoDataPlacemark::MoneyAtm)
47             && (tagIter = m_osmData.findTag(QStringLiteral("operator"))) != m_osmData.tagsEnd()) {
48         placemark->setName(tagIter.value());
49     } else {
50         placemark->setName(m_osmData.tagValue(QStringLiteral("name")));
51     }
52     if (category == GeoDataPlacemark::AerialwayStation && coordinates.altitude() != 0.0) {
53         if (placemark->name().isEmpty()) {
54             placemark->setName(QStringLiteral("%1 m").arg(coordinates.altitude()));
55         } else {
56             placemark->setName(QStringLiteral("%1 (%2 m)").arg(placemark->name()).arg(coordinates.altitude()));
57         }
58     }
59     if (placemark->name().isEmpty()) {
60         placemark->setName(m_osmData.tagValue(QStringLiteral("ref")));
61     }
62     placemark->setVisualCategory(category);
63     placemark->setZoomLevel(StyleBuilder::minimumZoomLevel(category));
64     placemark->setPopularity(StyleBuilder::popularity(placemark));
65 
66     if (category >= GeoDataPlacemark::PlaceCity && category <= GeoDataPlacemark::PlaceVillageNationalCapital) {
67         int const population = m_osmData.tagValue(QStringLiteral("population")).toInt();
68         placemark->setPopulation(qMax(0, population));
69         if (population > 0) {
70             placemark->setZoomLevel(populationIndex(population));
71             placemark->setPopularity(population);
72         }
73     }
74 
75     if (m_osmData.containsTagKey(QLatin1String("marbleZoomLevel"))) {
76         int const zoomLevel = m_osmData.tagValue(QLatin1String("marbleZoomLevel")).toInt();
77         placemark->setZoomLevel(zoomLevel);
78     }
79 
80     OsmObjectManager::registerId(m_osmData.id());
81     return placemark;
82 }
83 
populationIndex(qint64 population) const84 int OsmNode::populationIndex(qint64 population) const
85 {
86     int popidx = 3;
87 
88     if ( population < 2500 )        popidx=10;
89     else if ( population < 5000)    popidx=9;
90     else if ( population < 25000)   popidx=8;
91     else if ( population < 75000)   popidx=7;
92     else if ( population < 250000)  popidx=6;
93     else if ( population < 750000)  popidx=5;
94     else if ( population < 2500000) popidx=4;
95 
96     return popidx;
97 }
98 
coordinates() const99 const GeoDataCoordinates &OsmNode::coordinates() const
100 {
101     return m_coordinates;
102 }
103 
osmData()104 OsmPlacemarkData &OsmNode::osmData()
105 {
106     return m_osmData;
107 }
108 
osmData() const109 const OsmPlacemarkData &OsmNode::osmData() const
110 {
111     return m_osmData;
112 }
113 
114 }
115