summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Nienhüser <nienhueser@kde.org>2016-07-17 15:06:54 (GMT)
committerDennis Nienhüser <nienhueser@kde.org>2016-07-18 19:01:36 (GMT)
commit43f3168e3ed8fb73d331cff3f6f2f7b022c9b095 (patch)
tree9d21c75d5a1da201fa6dbf2ff2e1582026277589
parent61c2384729acc6e1a5a39f3af3b8dcdd72024151 (diff)
Create placemarks with point geometry from non-trivial way nodes
Previously all nodes of the OSM file were examined (including those part of ways and polygons) and completely discarded if their tags did not result in a visual category or the visual category was a highway one. Now those nodes which are part of ways and polygons are removed early in case they are trivial (have just a coordinate and an id). This is fine because them being part of a way of polygon ensures all information is still available. Otherwise they are kept. This ensures that stale nodes (trivial but not referenced) are not discarded anymore. Parsing should be slightly faster also given that trivial nodes which are part of ways are not tried to be converted to a placemark anymore.
-rw-r--r--src/lib/marble/osm/OsmPlacemarkData.cpp15
-rw-r--r--src/lib/marble/osm/OsmPlacemarkData.h5
-rw-r--r--src/plugins/runner/osm/OsmNode.cpp8
-rw-r--r--src/plugins/runner/osm/OsmParser.cpp12
-rw-r--r--src/plugins/runner/osm/OsmRelation.cpp13
-rw-r--r--src/plugins/runner/osm/OsmRelation.h4
-rw-r--r--src/plugins/runner/osm/OsmWay.cpp4
-rw-r--r--src/plugins/runner/osm/OsmWay.h2
8 files changed, 48 insertions, 15 deletions
diff --git a/src/lib/marble/osm/OsmPlacemarkData.cpp b/src/lib/marble/osm/OsmPlacemarkData.cpp
index fd99e38..5d52cba 100644
--- a/src/lib/marble/osm/OsmPlacemarkData.cpp
+++ b/src/lib/marble/osm/OsmPlacemarkData.cpp
@@ -278,6 +278,21 @@ bool OsmPlacemarkData::isNull() const
return !m_id;
}
+bool OsmPlacemarkData::isEmpty() const
+{
+ return m_tags.isEmpty() &&
+ m_nodeReferences.isEmpty() &&
+ m_memberReferences.isEmpty() &&
+ m_relationReferences.isEmpty() &&
+ m_version.isEmpty() &&
+ m_changeset.isEmpty() &&
+ m_uid.isEmpty() &&
+ m_visible.isEmpty() &&
+ m_user.isEmpty() &&
+ m_timestamp.isEmpty() &&
+ m_action.isEmpty();
+}
+
OsmPlacemarkData OsmPlacemarkData::fromParserAttributes( const QXmlStreamAttributes &attributes )
{
OsmPlacemarkData osmData;
diff --git a/src/lib/marble/osm/OsmPlacemarkData.h b/src/lib/marble/osm/OsmPlacemarkData.h
index 25c7abc..f1c04a5 100644
--- a/src/lib/marble/osm/OsmPlacemarkData.h
+++ b/src/lib/marble/osm/OsmPlacemarkData.h
@@ -188,6 +188,11 @@ public:
bool isNull() const;
/**
+ * @brief isEmpty returns true if no attribute other than the id has been set
+ */
+ bool isEmpty() const;
+
+ /**
* @brief fromParserAttributes is a convenience function that parses all osm-related
* arguments of a tag
* @return an OsmPlacemarkData object containing all the necessary data
diff --git a/src/plugins/runner/osm/OsmNode.cpp b/src/plugins/runner/osm/OsmNode.cpp
index 8fd5f43..6bbffda 100644
--- a/src/plugins/runner/osm/OsmNode.cpp
+++ b/src/plugins/runner/osm/OsmNode.cpp
@@ -34,15 +34,15 @@ void OsmNode::setCoordinates(const GeoDataCoordinates &coordinates)
void OsmNode::create(GeoDataDocument *document) const
{
GeoDataFeature::GeoDataVisualCategory const category = OsmPresetLibrary::determineVisualCategory(m_osmData);
- if (category == GeoDataFeature::None ||
- (category >= GeoDataFeature::HighwaySteps && category <= GeoDataFeature::HighwayMotorway)) {
- return;
- }
GeoDataPlacemark* placemark = new GeoDataPlacemark;
placemark->setOsmData(m_osmData);
placemark->setCoordinate(m_coordinates);
+ if (category == GeoDataFeature::None) {
+ placemark->setVisible(false);
+ }
+
if ((category == GeoDataFeature::TransportCarShare || category == GeoDataFeature::MoneyAtm)
&& m_osmData.containsTagKey("operator")) {
placemark->setName(m_osmData.tagValue("operator"));
diff --git a/src/plugins/runner/osm/OsmParser.cpp b/src/plugins/runner/osm/OsmParser.cpp
index 994ad55..fb13aa2 100644
--- a/src/plugins/runner/osm/OsmParser.cpp
+++ b/src/plugins/runner/osm/OsmParser.cpp
@@ -193,16 +193,22 @@ GeoDataDocument *OsmParser::createDocument(OsmNodes &nodes, OsmWays &ways, OsmRe
backgroundStyle->setId( "background" );
document->addStyle( backgroundStyle );
- QSet<qint64> usedWays;
+ QSet<qint64> usedNodes, usedWays;
foreach(OsmRelation const &relation, relations) {
- relation.create(document, ways, nodes, usedWays);
+ relation.create(document, ways, nodes, usedNodes, usedWays);
}
foreach(qint64 id, usedWays) {
ways.remove(id);
}
foreach(OsmWay const &way, ways) {
- way.create(document, nodes);
+ way.create(document, nodes, usedNodes);
+ }
+
+ foreach(qint64 id, usedNodes) {
+ if (nodes[id].osmData().isEmpty()) {
+ nodes.remove(id);
+ }
}
foreach(OsmNode const &node, nodes) {
diff --git a/src/plugins/runner/osm/OsmRelation.cpp b/src/plugins/runner/osm/OsmRelation.cpp
index 3125ebc..2193899 100644
--- a/src/plugins/runner/osm/OsmRelation.cpp
+++ b/src/plugins/runner/osm/OsmRelation.cpp
@@ -48,7 +48,7 @@ void OsmRelation::addMember(qint64 reference, const QString &role, const QString
m_members << member;
}
-void OsmRelation::create(GeoDataDocument *document, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedWays) const
+void OsmRelation::create(GeoDataDocument *document, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedNodes, QSet<qint64> &usedWays) const
{
if (!m_osmData.containsTag("type", "multipolygon")) {
return;
@@ -58,7 +58,8 @@ void OsmRelation::create(GeoDataDocument *document, const OsmWays &ways, const O
QStringList const outerRoles = QStringList() << "outer" << "";
QSet<qint64> outerWays;
- QList<GeoDataLinearRing> outer = rings(outerRoles, ways, nodes, outerWays);
+ QSet<qint64> outerNodes;
+ QList<GeoDataLinearRing> outer = rings(outerRoles, ways, nodes, outerNodes, outerWays);
if (outer.isEmpty()) {
return;
} else if (outer.size() > 1) {
@@ -115,7 +116,7 @@ void OsmRelation::create(GeoDataDocument *document, const OsmWays &ways, const O
QStringList const innerRoles = QStringList() << "inner";
QSet<qint64> innerWays;
- QList<GeoDataLinearRing> inner = rings(innerRoles, ways, nodes, innerWays);
+ QList<GeoDataLinearRing> inner = rings(innerRoles, ways, nodes, usedNodes, innerWays);
foreach(qint64 wayId, innerWays) {
Q_ASSERT(ways.contains(wayId));
if (OsmPresetLibrary::determineVisualCategory(ways[wayId].osmData()) == GeoDataFeature::None) {
@@ -129,14 +130,16 @@ void OsmRelation::create(GeoDataDocument *document, const OsmWays &ways, const O
polygon->appendInnerBoundary(ring);
}
placemark->setGeometry(polygon);
+ usedNodes |= outerNodes;
OsmObjectManager::registerId( m_osmData.id() );
document->append(placemark);
}
-QList<GeoDataLinearRing> OsmRelation::rings(const QStringList &roles, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedWays) const
+QList<GeoDataLinearRing> OsmRelation::rings(const QStringList &roles, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedNodes, QSet<qint64> &usedWays) const
{
QSet<qint64> currentWays;
+ QSet<qint64> currentNodes;
QList<qint64> roleMembers;
foreach(const OsmMember &member, m_members) {
if (roles.contains(member.role)) {
@@ -193,6 +196,7 @@ QList<GeoDataLinearRing> OsmRelation::rings(const QStringList &roles, const OsmW
}
if ( id != lastReference ) {
ring << nodes[id].coordinates();
+ currentNodes << id;
}
}
lastReference = isReversed ? nextWay.references().first()
@@ -217,6 +221,7 @@ QList<GeoDataLinearRing> OsmRelation::rings(const QStringList &roles, const OsmW
}
usedWays |= currentWays;
+ usedNodes |= currentNodes;
return result;
}
diff --git a/src/plugins/runner/osm/OsmRelation.h b/src/plugins/runner/osm/OsmRelation.h
index b9dd1d7..ef3f75c 100644
--- a/src/plugins/runner/osm/OsmRelation.h
+++ b/src/plugins/runner/osm/OsmRelation.h
@@ -32,7 +32,7 @@ public:
const OsmPlacemarkData & osmData() const;
- void create(GeoDataDocument* document, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedWays) const;
+ void create(GeoDataDocument* document, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedNodes, QSet<qint64> &usedWays) const;
private:
struct OsmMember
@@ -44,7 +44,7 @@ private:
OsmMember();
};
- QList<GeoDataLinearRing> rings(const QStringList &roles, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedWays) const;
+ QList<GeoDataLinearRing> rings(const QStringList &roles, const OsmWays &ways, const OsmNodes &nodes, QSet<qint64> &usedNodes, QSet<qint64> &usedWays) const;
OsmPlacemarkData m_osmData;
QVector<OsmMember> m_members;
diff --git a/src/plugins/runner/osm/OsmWay.cpp b/src/plugins/runner/osm/OsmWay.cpp
index 4fc4c60..17b6ba6 100644
--- a/src/plugins/runner/osm/OsmWay.cpp
+++ b/src/plugins/runner/osm/OsmWay.cpp
@@ -22,7 +22,7 @@ namespace Marble {
QSet<QString> OsmWay::s_areaTags;
-void OsmWay::create(GeoDataDocument *document, const OsmNodes &nodes) const
+void OsmWay::create(GeoDataDocument *document, const OsmNodes &nodes, QSet<qint64> &usedNodes) const
{
bool const shouldRender =
!m_osmData.containsTagKey("area:highway") && // Not supported yet
@@ -57,6 +57,7 @@ void OsmWay::create(GeoDataDocument *document, const OsmNodes &nodes) const
OsmNode const & node = nodeIter.value();
placemark->osmData().addNodeReference(node.coordinates(), node.osmData());
linearRing->append(node.coordinates());
+ usedNodes << nodeId;
}
*linearRing = GeoDataLinearRing(linearRing->optimized());
@@ -74,6 +75,7 @@ void OsmWay::create(GeoDataDocument *document, const OsmNodes &nodes) const
OsmNode const & node = nodeIter.value();
placemark->osmData().addNodeReference(node.coordinates(), node.osmData());
lineString->append(node.coordinates());
+ usedNodes << nodeId;
}
*lineString = lineString->optimized();
diff --git a/src/plugins/runner/osm/OsmWay.h b/src/plugins/runner/osm/OsmWay.h
index 6646e94..d0b7e69 100644
--- a/src/plugins/runner/osm/OsmWay.h
+++ b/src/plugins/runner/osm/OsmWay.h
@@ -30,7 +30,7 @@ public:
const OsmPlacemarkData & osmData() const;
const QVector<qint64> &references() const;
- void create(GeoDataDocument* document, const OsmNodes &nodes) const;
+ void create(GeoDataDocument* document, const OsmNodes &nodes, QSet<qint64> &usedNodes) const;
private:
bool isArea() const;