summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Stanciu <[email protected]>2015-07-19 17:41:59 +0300
committerMarius Stanciu <[email protected]>2015-07-19 17:41:59 +0300
commit987be5fa157ddac8d6dd3bd08ba5647c785ff7f1 (patch)
tree16960852dc4214e0d196d10232694d4686d69646
parent32946954065268cebae3e23f330700ff58d33d10 (diff)
Modifying the osm handlers to store OsmPlacemarkData
REVIEW: 124233
-rw-r--r--src/plugins/runner/osm/OsmParser.cpp27
-rw-r--r--src/plugins/runner/osm/OsmParser.h27
-rw-r--r--src/plugins/runner/osm/handlers/OsmElementDictionary.cpp9
-rw-r--r--src/plugins/runner/osm/handlers/OsmElementDictionary.h7
-rw-r--r--src/plugins/runner/osm/handlers/OsmMemberTagHandler.cpp199
-rw-r--r--src/plugins/runner/osm/handlers/OsmNdTagHandler.cpp34
-rw-r--r--src/plugins/runner/osm/handlers/OsmNodeTagHandler.cpp27
-rw-r--r--src/plugins/runner/osm/handlers/OsmRelationTagHandler.cpp20
-rw-r--r--src/plugins/runner/osm/handlers/OsmTagTagHandler.cpp75
-rw-r--r--src/plugins/runner/osm/handlers/OsmTagTagHandler.h4
-rw-r--r--src/plugins/runner/osm/handlers/OsmWayTagHandler.cpp20
11 files changed, 299 insertions, 150 deletions
diff --git a/src/plugins/runner/osm/OsmParser.cpp b/src/plugins/runner/osm/OsmParser.cpp
index 7ad467b..c9b63b0 100644
--- a/src/plugins/runner/osm/OsmParser.cpp
+++ b/src/plugins/runner/osm/OsmParser.cpp
@@ -12,6 +12,7 @@
#include "OsmParser.h"
#include "OsmElementDictionary.h"
+#include "osm/OsmPlacemarkData.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPoint.h"
@@ -63,32 +64,32 @@ OsmParser::~OsmParser()
qDeleteAll( m_nodes );
}
-void OsmParser::setNode( quint64 id, GeoDataPoint *point )
+void OsmParser::setNode( qint64 id, GeoDataPoint *point )
{
m_nodes[id] = point;
}
-GeoDataPoint *OsmParser::node( quint64 id )
+GeoDataPoint *OsmParser::node( qint64 id )
{
return m_nodes.value( id );
}
-void OsmParser::setWay( quint64 id, GeoDataLineString *way )
+void OsmParser::setWay( qint64 id, GeoDataLineString *way )
{
m_ways[id] = way;
}
-GeoDataLineString *OsmParser::way( quint64 id )
+GeoDataLineString *OsmParser::way( qint64 id )
{
return m_ways.value( id );
}
-void OsmParser::setPolygon( quint64 id, GeoDataPolygon *polygon )
+void OsmParser::setPolygon( qint64 id, GeoDataPolygon *polygon )
{
m_polygons[id] = polygon;
}
-GeoDataPolygon *OsmParser::polygon( quint64 id )
+GeoDataPolygon *OsmParser::polygon( qint64 id )
{
return m_polygons.value( id );
}
@@ -103,6 +104,20 @@ void OsmParser::addDummyPlacemark( GeoDataPlacemark *placemark )
m_dummyPlacemarks << placemark;
}
+OsmPlacemarkData OsmParser::osmAttributeData() const
+{
+ OsmPlacemarkData osmData;
+ osmData.setId( attribute( "id" ).toLongLong() );
+ osmData.setVersion( attribute( "version" ) );
+ osmData.setChangeset( attribute( "changeset" ) );
+ osmData.setUser( attribute( "user" ) );
+ osmData.setUid( attribute( "uid" ) );
+ osmData.setVisible( attribute( "visible" ) );
+ osmData.setTimestamp( attribute( "timestamp" ) );
+ osmData.setAction( attribute( "action" ) );
+ return osmData;
+}
+
bool OsmParser::isValidRootElement()
{
return isValidElement(osm::osmTag_osm);
diff --git a/src/plugins/runner/osm/OsmParser.h b/src/plugins/runner/osm/OsmParser.h
index 4436680..141f4f6 100644
--- a/src/plugins/runner/osm/OsmParser.h
+++ b/src/plugins/runner/osm/OsmParser.h
@@ -14,6 +14,7 @@
#define OSMPARSER_H
#include "GeoParser.h"
+#include "GeoDataCoordinates.h"
#include <QColor>
#include <QList>
@@ -26,6 +27,7 @@ class GeoDataLineString;
class GeoDataPlacemark;
class GeoDataPoint;
class GeoDataPolygon;
+class OsmPlacemarkData;
class OsmParser : public GeoParser
{
@@ -33,18 +35,25 @@ public:
OsmParser();
virtual ~OsmParser();
- void setNode( quint64 id, GeoDataPoint *point );
- GeoDataPoint *node( quint64 id );
+ void setNode( qint64 id, GeoDataPoint *point );
+ GeoDataPoint *node( qint64 id );
- void setWay( quint64 id, GeoDataLineString *way );
- GeoDataLineString *way( quint64 id );
+ void setWay( qint64 id, GeoDataLineString *way );
+ GeoDataLineString *way( qint64 id );
- void setPolygon( quint64 id, GeoDataPolygon *polygon );
- GeoDataPolygon *polygon( quint64 id );
+ void setPolygon( qint64 id, GeoDataPolygon *polygon );
+ GeoDataPolygon *polygon( qint64 id );
bool tagNeedArea( const QString &keyValue ) const;
void addDummyPlacemark( GeoDataPlacemark *placemark );
+ /**
+ * @brief osmAttributeData is a convenience function that parses all osm-related
+ * arguments of a tag
+ * @return an OsmPlacemarkData object containing all the necessary data
+ */
+ OsmPlacemarkData osmAttributeData() const;
+
static const QColor backgroundColor;
private:
@@ -53,9 +62,9 @@ private:
virtual GeoDocument* createDocument() const;
- QMap<quint64, GeoDataPoint *> m_nodes;
- QMap<quint64, GeoDataPolygon *> m_polygons;
- QMap<quint64, GeoDataLineString *> m_ways;
+ QMap<qint64, GeoDataPoint *> m_nodes;
+ QMap<qint64, GeoDataPolygon *> m_polygons;
+ QMap<qint64, GeoDataLineString *> m_ways;
QSet<QString> m_areaTags;
QList<GeoDataPlacemark *> m_dummyPlacemarks;
};
diff --git a/src/plugins/runner/osm/handlers/OsmElementDictionary.cpp b/src/plugins/runner/osm/handlers/OsmElementDictionary.cpp
index f493e7b..6781a3f 100644
--- a/src/plugins/runner/osm/handlers/OsmElementDictionary.cpp
+++ b/src/plugins/runner/osm/handlers/OsmElementDictionary.cpp
@@ -13,9 +13,16 @@ namespace Marble
namespace osm
{
-// OSM data primitives and what do they represent
+// OSM data primitives and what they represent
// http://wiki.openstreetmap.org/wiki/Elements
+const char* osmTag_version06 = "0.6";
+// KML to OSM translators
+const char* osmTranslate_document = "document";
+const char* osmTranslate_feature = "feature";
+const char* osmTranslate_placemark = "placemark";
+
+// OSM writers
const char* osmTag_osm = "osm";
const char* osmTag_bound = "bound";
const char* osmTag_bounds = "bounds";
diff --git a/src/plugins/runner/osm/handlers/OsmElementDictionary.h b/src/plugins/runner/osm/handlers/OsmElementDictionary.h
index 44a993c..7c12fdf 100644
--- a/src/plugins/runner/osm/handlers/OsmElementDictionary.h
+++ b/src/plugins/runner/osm/handlers/OsmElementDictionary.h
@@ -16,6 +16,13 @@ namespace Marble
{
namespace osm
{
+
+extern const char* osmTag_version06;
+
+extern const char* osmTranslate_document;
+extern const char* osmTranslate_feature;
+extern const char* osmTranslate_placemark;
+
extern const char* osmTag_osm;
extern const char* osmTag_bound;
extern const char* osmTag_bounds;
diff --git a/src/plugins/runner/osm/handlers/OsmMemberTagHandler.cpp b/src/plugins/runner/osm/handlers/OsmMemberTagHandler.cpp
index 8fdfaae..2e1c9b7 100644
--- a/src/plugins/runner/osm/handlers/OsmMemberTagHandler.cpp
+++ b/src/plugins/runner/osm/handlers/OsmMemberTagHandler.cpp
@@ -10,13 +10,17 @@
Copyright 2012 Ander Pijoan <[email protected]>
*/
-#include "OsmMemberTagHandler.h"
+#include <QHash>
+#include "OsmMemberTagHandler.h"
#include "OsmParser.h"
#include "OsmElementDictionary.h"
#include "GeoDataParser.h"
#include "GeoDataPolygon.h"
+#include "GeoDataExtendedData.h"
+#include "GeoDataPlacemark.h"
+#include "osm/OsmPlacemarkData.h"
#include "MarbleDebug.h"
@@ -27,7 +31,7 @@ namespace osm
{
static GeoTagHandlerRegistrar osmMemberTagHandler( GeoParser::QualifiedName( osmTag_member, "" ),
- new OsmMemberTagHandler() );
+ new OsmMemberTagHandler() );
GeoNode* OsmMemberTagHandler::parse( GeoParser &geoParser ) const
{
@@ -40,119 +44,129 @@ GeoNode* OsmMemberTagHandler::parse( GeoParser &geoParser ) const
Q_ASSERT( parser.isStartElement() );
GeoStackItem parentItem = parser.parentElement();
+ qint64 id = parser.attribute( "ref" ).toLongLong();
- if ( parentItem.represents( osmTag_relation ) )
- {
- // Never heard of a type different from "way" but
- // maybe it should be checked
+ if ( parentItem.represents( osmTag_relation ) ) {
- if (parser.attribute( "type" ) == "way")
- {
- // Outer poligons (sometimes the role is empty)
+ // Currently, only polygons can be parsed
+ // TODO: parse non-polygon relations
+ GeoDataPolygon *polygon = parentItem.nodeAs<GeoDataPolygon>();
+ Q_ASSERT( polygon );
+ GeoDataPlacemark *polygonPlacemark = dynamic_cast<GeoDataPlacemark*>( polygon->parent() );
+ Q_ASSERT( polygonPlacemark );
+
+ // Getting the polygon's osmData
+ OsmPlacemarkData &polygonOsmData = polygonPlacemark->osmData();
+
+ // Polygons only have way members
+ if ( parser.attribute( "type" ) == "way" ) {
+
+ // With the id we get the way geometry
+ GeoDataLineString *line = parser.way( id );
+ if ( !line ) {
+ qWarning()<< QString( "Malformed relation %1: No way with id %2 exists" )
+ .arg( QString::number( polygonOsmData.id() ) ).arg( id );
+ return 0;
+ }
+
+ GeoDataPlacemark *linePlacemark = dynamic_cast<GeoDataPlacemark*>( line->parent() );
+ Q_ASSERT( linePlacemark );
+
+ // Getting the line's osmData
+ OsmPlacemarkData &lineOsmData = linePlacemark->osmData();
+
+ // Outer polygons (sometimes the role is empty)
if (parser.attribute( "role" ) == "outer" || parser.attribute( "role" ).isEmpty() )
{
+ // Some of the ways that build the relation
+ // might be in opposite directions
+ // so the final linearRing would be wrong.
+ // It is needed to seek in the linearRing
+ // to know if the new way should be added
+ // at the beginning or end and in which order.
+ // Also the shared node (which will be in both
+ // geometries) has to be removed to avoid having
+ // it repeated.
+ GeoDataLinearRing envelope = polygon->outerBoundary();
+
+ // Case 0: envelope is empty
+ if ( envelope.isEmpty() )
+ {
+ envelope = *line;
+ }
- GeoDataPolygon *polygon = parentItem.nodeAs<GeoDataPolygon>();
- Q_ASSERT( polygon );
- quint64 id = parser.attribute( "ref" ).toULongLong();
-
- // With the id we get the way geometry
- if ( GeoDataLineString *line = parser.way( id ) )
+ // Case 1: line.first = envelope.first
+ else if ( line->first() == envelope.first() )
{
- // Some of the ways that build the relation
- // might be in opposite directions
- // so the final linearRing would be wrong.
- // It is needed to seek in the linearRing
- // to know if the new way should be added
- // at the beginning or end and in which order.
- // Also the shared node (which will be in both
- // geometries) has to be removed to avoid having
- // it repeated.
-
- GeoDataLinearRing envelope = polygon->outerBoundary();
-
- // Case 0: envelope is empty
- if ( envelope.isEmpty() )
- {
- envelope = *line;
- }
+ GeoDataLinearRing temp = GeoDataLinearRing( envelope.tessellationFlags() );
- // Case 1: line.first = envelope.first
- else if ( line->first() == envelope.first() )
+ // Invert envelopes direction
+ for (int x = envelope.size()-1; x > -1; x--)
{
- GeoDataLinearRing temp = GeoDataLinearRing( envelope.tessellationFlags() );
-
- // Invert envelopes direction
- for (int x = envelope.size()-1; x > -1; x--)
- {
- temp.append( GeoDataCoordinates ( envelope.at(x) ) );
- }
- envelope = temp;
-
- // Now its the same as case 2
- // envelope-last not to repeat the shared node
- envelope.remove( envelope.size() - 1 );
- envelope << *line;
+ temp.append( GeoDataCoordinates ( envelope.at(x) ) );
}
+ envelope = temp;
+
+ // Now its the same as case 2
+ // envelope-last not to repeat the shared node
+ envelope.remove( envelope.size() - 1 );
+ envelope << *line;
+ }
- // Case 2: line.first = envelope.last
- else if (line->first() == envelope.last() )
+ // Case 2: line.first = envelope.last
+ else if (line->first() == envelope.last() )
+ {
+ // envelope-last not to repeat the shared node
+ envelope.remove( envelope.size() - 1 );
+ envelope << *line;
+ }
+
+ // Case 3: line.last = envelope.first
+ else if (line->last() == envelope.first() )
+ {
+ GeoDataLinearRing temp = GeoDataLinearRing( envelope.tessellationFlags() );
+
+ // Invert envelopes direction
+ for (int x = envelope.size()-1; x > -1; x--)
{
- // envelope-last not to repeat the shared node
- envelope.remove( envelope.size() - 1 );
- envelope << *line;
+ temp.append( GeoDataCoordinates ( envelope.at(x) ) );
}
+ envelope = temp;
- // Case 3: line.last = envelope.first
- else if (line->last() == envelope.first() )
+ // Now its the same as case 4
+ // size-2 not to repeat the shared node
+ for (int x = line->size()-2; x > -1; x--)
{
- GeoDataLinearRing temp = GeoDataLinearRing( envelope.tessellationFlags() );
-
- // Invert envelopes direction
- for (int x = envelope.size()-1; x > -1; x--)
- {
- temp.append( GeoDataCoordinates ( envelope.at(x) ) );
- }
- envelope = temp;
-
- // Now its the same as case 4
- // size-2 not to repeat the shared node
- for (int x = line->size()-2; x > -1; x--)
- {
- envelope.append( GeoDataCoordinates ( line->at(x) ) );
- }
+ envelope.append( GeoDataCoordinates ( line->at(x) ) );
}
+ }
- // Case 4: line.last = envelope.last
- else if (line->last() == envelope.last() )
+ // Case 4: line.last = envelope.last
+ else if (line->last() == envelope.last() )
+ {
+ // size-2 not to repeat the shared node
+ for (int x = line->size()-2; x > -1; x--)
{
- // size-2 not to repeat the shared node
- for (int x = line->size()-2; x > -1; x--)
- {
- envelope.append( GeoDataCoordinates ( line->at(x) ) );
- }
+ envelope.append( GeoDataCoordinates ( line->at(x) ) );
}
-
- // Update the outer boundary
- polygon->setOuterBoundary( envelope );
}
- }
+ // Update the outer boundary
+ polygon->setOuterBoundary( envelope );
+ // Inserting the outerBoundary's osmData in the polygon osmData's reference hash map
+ const GeoDataLinearRing &outerBoundary = polygon->outerBoundary();
+ polygonOsmData.addReference( &outerBoundary, lineOsmData );
+ }
// Inner poligons
- if (parser.attribute( "role" ) == "inner")
+ else if ( parser.attribute( "role" ) == "inner" )
{
- GeoDataPolygon *polygon = parentItem.nodeAs<GeoDataPolygon>();
- Q_ASSERT( polygon );
- quint64 id = parser.attribute( "ref" ).toULongLong();
+ polygon->appendInnerBoundary( GeoDataLinearRing( *line ) );
- // With the id we get the way geometry
- if ( GeoDataLineString *line = parser.way( id ) )
- {
- polygon->appendInnerBoundary( GeoDataLinearRing( *line ) );
- }
+ // Inserting the innerBoundary's osmData in the polygon osmData's reference hash map
+ const GeoDataLinearRing &innerBoundary = polygon->innerBoundaries().last();
+ polygonOsmData.addReference( &innerBoundary, lineOsmData );
}
}
-
else if (parser.attribute( "type" ) == "relation")
{
// Never seen this case
@@ -169,7 +183,7 @@ GeoNode* OsmMemberTagHandler::parse( GeoParser &geoParser ) const
{
GeoDataPolygon *polygon = parentItem.nodeAs<GeoDataPolygon>();
Q_ASSERT( polygon );
- quint64 id = parser.attribute( "ref" ).toULongLong();
+ id = parser.attribute( "ref" ).toLongLong();
// With the id we get the relation geometry
if ( GeoDataPolygon *p = parser.polygon( id ) )
@@ -178,10 +192,7 @@ GeoNode* OsmMemberTagHandler::parse( GeoParser &geoParser ) const
}
}
}
-
- return 0;
}
-
return 0;
}
diff --git a/src/plugins/runner/osm/handlers/OsmNdTagHandler.cpp b/src/plugins/runner/osm/handlers/OsmNdTagHandler.cpp
index 3183560..df102d0 100644
--- a/src/plugins/runner/osm/handlers/OsmNdTagHandler.cpp
+++ b/src/plugins/runner/osm/handlers/OsmNdTagHandler.cpp
@@ -6,16 +6,25 @@
// the source code.
//
// Copyright 2011 Konstantin Oblaukhov <[email protected]>
+// Copyright 2015 Marius-Valeriu Stanciu <[email protected]>
//
-#include "OsmNdTagHandler.h"
+#include <QHash>
+#include <QVariant>
+#include <QThread>
+#include "OsmNdTagHandler.h"
#include "OsmElementDictionary.h"
#include "OsmParser.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLineString.h"
#include "GeoDataPoint.h"
+#include "GeoDataPlacemark.h"
+#include "GeoDataExtendedData.h"
+#include "GeoDataData.h"
+#include "GeoDataTypes.h"
+#include "osm/OsmPlacemarkData.h"
namespace Marble
{
@@ -24,7 +33,7 @@ namespace osm
{
static GeoTagHandlerRegistrar osmNdTagHandler( GeoParser::QualifiedName( osmTag_nd, "" ),
- new OsmNdTagHandler() );
+ new OsmNdTagHandler() );
GeoNode* OsmNdTagHandler::parse( GeoParser &geoParser ) const
{
@@ -39,9 +48,26 @@ GeoNode* OsmNdTagHandler::parse( GeoParser &geoParser ) const
{
GeoDataLineString *s = parentItem.nodeAs<GeoDataLineString>();
Q_ASSERT( s );
- quint64 id = parser.attribute( "ref" ).toULongLong();
+ qint64 id = parser.attribute( "ref" ).toLongLong();
+
if ( GeoDataPoint *p = parser.node( id ) ) {
- s->append( GeoDataCoordinates( p->coordinates().longitude(), p->coordinates().latitude() ) );
+
+ const GeoDataCoordinates coordinates = p->coordinates();
+ s->append( coordinates );
+
+ GeoDataPlacemark *nodePlacemark = dynamic_cast<GeoDataPlacemark *> ( p->parent() );
+ GeoDataPlacemark *wayPlacemark = dynamic_cast<GeoDataPlacemark *> ( s->parent() );
+ Q_ASSERT( nodePlacemark );
+ Q_ASSERT( wayPlacemark );
+
+ // Getting the node's osmData
+ OsmPlacemarkData &nodeOsmData = nodePlacemark->osmData();
+
+ // Getting the line's osmData
+ OsmPlacemarkData &wayOsmData = wayPlacemark->osmData();
+
+ // Inserting the point's osmData in the line osmData's reference hash map
+ wayOsmData.addReference( coordinates, nodeOsmData );
}
return 0;
diff --git a/src/plugins/runner/osm/handlers/OsmNodeTagHandler.cpp b/src/plugins/runner/osm/handlers/OsmNodeTagHandler.cpp
index e8dc85f..ed84e0b 100644
--- a/src/plugins/runner/osm/handlers/OsmNodeTagHandler.cpp
+++ b/src/plugins/runner/osm/handlers/OsmNodeTagHandler.cpp
@@ -6,15 +6,24 @@
// the source code.
//
// Copyright 2011 Konstantin Oblaukhov <[email protected]>
+// Copyright 2015 Marius-Valeriu Stanciu <[email protected]>
//
+// Self
#include "OsmNodeTagHandler.h"
+// Osm plugin
#include "OsmElementDictionary.h"
#include "OsmParser.h"
+// Marble
#include "GeoDataCoordinates.h"
#include "GeoDataPoint.h"
+#include "GeoDataPlacemark.h"
+#include "GeoDataExtendedData.h"
+#include "GeoDataGeometry.h"
+#include "GeoDataData.h"
+#include "osm/OsmPlacemarkData.h"
namespace Marble
{
@@ -35,9 +44,25 @@ GeoNode* OsmNodeTagHandler::parse( GeoParser &geoParser ) const
qreal lon = parser.attribute( "lon" ).toDouble();
qreal lat = parser.attribute( "lat" ).toDouble();
+ qint64 id = parser.attribute( "id" ).toLongLong();
+ GeoDataPlacemark *placemark = new GeoDataPlacemark();
GeoDataPoint *point = new GeoDataPoint( lon, lat, 0, GeoDataCoordinates::Degree );
- parser.setNode( parser.attribute( "id" ).toULongLong(), point );
+ point->setParent( placemark );
+ placemark->setZoomLevel( 18 ); // Not really sure it's the right thing?
+
+ // Saving osm server generated data
+ OsmPlacemarkData osmData = parser.osmAttributeData();
+ GeoDataExtendedData extendedData;
+ extendedData.addValue( GeoDataData( OsmPlacemarkData::osmHashKey(), QVariant::fromValue( osmData ) ) );
+ placemark->setExtendedData( extendedData );
+ parser.addDummyPlacemark( placemark );
+
+ // Initially, it is not visible. If a tag is found, this will change.
+ placemark->setVisible( false );
+
+ // Adding the node to the parser's hash ( in case we need to ref it )
+ parser.setNode( id, point );
return point;
}
diff --git a/src/plugins/runner/osm/handlers/OsmRelationTagHandler.cpp b/src/plugins/runner/osm/handlers/OsmRelationTagHandler.cpp
index 5d900ba..99df5e5 100644
--- a/src/plugins/runner/osm/handlers/OsmRelationTagHandler.cpp
+++ b/src/plugins/runner/osm/handlers/OsmRelationTagHandler.cpp
@@ -10,15 +10,23 @@
Copyright 2012 Ander Pijoan <[email protected]>
*/
+// Self
#include "OsmRelationTagHandler.h"
+// Qt
+#include <QVariant>
+
+// Osm plugin
#include "OsmParser.h"
#include "OsmElementDictionary.h"
+// Marble
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataParser.h"
#include "GeoDataPolygon.h"
+#include "osm/OsmPlacemarkData.h"
+#include "GeoDataExtendedData.h"
namespace Marble
{
@@ -44,13 +52,21 @@ GeoNode* OsmRelationTagHandler::parse( GeoParser &geoParser ) const
GeoDataPolygon *polygon = new GeoDataPolygon();
GeoDataPlacemark *placemark = new GeoDataPlacemark();
placemark->setGeometry( polygon );
+ qint64 id = parser.attribute( "id" ).toLongLong();
+
+
+ // Saving osm server generated data
+ OsmPlacemarkData osmData = parser.osmAttributeData();
+ GeoDataExtendedData extendedData;
+ extendedData.addValue( GeoDataData( OsmPlacemarkData::osmHashKey(), QVariant::fromValue( osmData ) ) );
+ placemark->setExtendedData( extendedData );
- // In the beginning visibility = false. Afterwards when it parses
+ // At the beginning visibility = false. Afterwards when parsing
// the tags for the placemark it will decide if it should be displayed or not
placemark->setVisible( false );
doc->append( placemark );
- parser.setPolygon( parser.attribute( "id" ).toULongLong(), polygon );
+ parser.setPolygon( id, polygon );
return polygon;
}
diff --git a/src/plugins/runner/osm/handlers/OsmTagTagHandler.cpp b/src/plugins/runner/osm/handlers/OsmTagTagHandler.cpp
index deaf32e..d3fd2f2 100644
--- a/src/plugins/runner/osm/handlers/OsmTagTagHandler.cpp
+++ b/src/plugins/runner/osm/handlers/OsmTagTagHandler.cpp
@@ -18,6 +18,8 @@
#include "GeoDataParser.h"
#include "GeoDataLineString.h"
#include "GeoDataStyle.h"
+#include "GeoDataExtendedData.h"
+#include "osm/OsmPlacemarkData.h"
#include "MarbleDebug.h"
@@ -27,7 +29,7 @@ namespace Marble
namespace osm
{
static GeoTagHandlerRegistrar osmTagTagHandler( GeoParser::QualifiedName( osmTag_tag, "" ),
- new OsmTagTagHandler() );
+ new OsmTagTagHandler() );
static QStringList tagBlackList = QStringList() << "created_by";
@@ -43,6 +45,7 @@ GeoNode* OsmTagTagHandler::parse( GeoParser &geoParser ) const
QString key = parser.attribute( "k" );
QString value = parser.attribute( "v" );
+
if ( tagBlackList.contains( key ) )
return 0;
@@ -51,36 +54,45 @@ GeoNode* OsmTagTagHandler::parse( GeoParser &geoParser ) const
return 0;
GeoDataGeometry *placemarkGeometry = geometry;
-
+
//If node geometry is part of multigeometry -> go up to placemark geometry.
while( dynamic_cast<GeoDataMultiGeometry*>(placemarkGeometry->parent()) )
placemarkGeometry = dynamic_cast<GeoDataMultiGeometry*>(placemarkGeometry->parent());
-
GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>(placemarkGeometry->parent());
+ Q_ASSERT( placemark );
- if ( key == "name" )
- {
- if ( !placemark )
- {
- if ( parentItem.represents( osmTag_node ) )
- placemark = createPOI( doc, geometry );
- else
+ // Getting the placemark's osm data
+ OsmPlacemarkData &osmData = placemark->osmData();
+
+ // Inserting the tag into the placemark's tag hash
+ osmData.addTag( key, value );
+
+ if ( key == "name" ) {
+ // If placemark is not in the document, add it.
+ if ( !placemark->parent() ) {
+ if ( parentItem.represents( osmTag_node ) ) {
+ placemark = createPOI( doc, geometry, placemark->extendedData() );
+ }
+ else if ( parentItem.represents( osmTag_way ) ) {
+ doc->append( placemark );
+ }
+ else {
return 0;
+ }
}
placemark->setName( value );
return 0;
}
// Ways or relations can represent closed areas such as buildings
- if ( parentItem.represents( osmTag_way ) || parentItem.represents( osmTag_relation ) )
- {
- Q_ASSERT( placemark );
-
+ if ( parentItem.represents( osmTag_way ) || parentItem.represents( osmTag_relation ) ) {
if( !dynamic_cast<GeoDataPolygon*>( geometry ) && parser.tagNeedArea( key + '=' + value ) ) {
//Convert area ways or relations to polygons
GeoDataLineString *polyline = dynamic_cast<GeoDataLineString *>( geometry );
Q_ASSERT( polyline );
- doc->remove( doc->childPosition( placemark ) );
+ if ( placemark->parent() ) {
+ doc->remove( doc->childPosition( placemark ) );
+ }
parser.addDummyPlacemark( placemark );
placemark = new GeoDataPlacemark( *placemark );
GeoDataPolygon *polygon = new GeoDataPolygon;
@@ -103,9 +115,10 @@ GeoNode* OsmTagTagHandler::parse( GeoParser &geoParser ) const
//Placemark is an accepted POI
if ( poiCategory )
{
- if ( !placemark )
- placemark = createPOI( doc, geometry );
-
+ // If placemark is not in the document, add it.
+ if ( !placemark->parent() ) {
+ placemark = createPOI( doc, geometry, placemark->extendedData() );
+ }
placemark->setVisible( true );
}
}
@@ -113,10 +126,9 @@ GeoNode* OsmTagTagHandler::parse( GeoParser &geoParser ) const
if ( placemark )
{
GeoDataFeature::GeoDataVisualCategory category;
-
if ( ( category = GeoDataFeature::OsmVisualCategory( key + '=' + value ) ) )
{
- if( placemark->visualCategory() != GeoDataFeature::Default
+ if( placemark->visualCategory() != GeoDataFeature::Default
&& placemark->visualCategory() != GeoDataFeature::Building )
{
GeoDataPlacemark* newPlacemark = new GeoDataPlacemark( *placemark );
@@ -156,17 +168,22 @@ GeoNode* OsmTagTagHandler::parse( GeoParser &geoParser ) const
return 0;
}
-GeoDataPlacemark* OsmTagTagHandler::createPOI( GeoDataDocument* doc, GeoDataGeometry* geometry )
+GeoDataPlacemark* OsmTagTagHandler::createPOI( GeoDataDocument* doc, GeoDataGeometry *geometry, const GeoDataExtendedData &extendedData )
{
GeoDataPoint *point = dynamic_cast<GeoDataPoint *>( geometry );
- Q_ASSERT( point );
- GeoDataPlacemark *placemark = new GeoDataPlacemark();
- placemark->setGeometry( new GeoDataPoint( *point ) );
- point->setParent( placemark );
- placemark->setVisible( false );
- placemark->setZoomLevel( 18 );
- doc->append( placemark );
- return placemark;
+
+ if ( !point ) {
+ return 0;
+ }
+
+ GeoDataPlacemark *newPlacemark = new GeoDataPlacemark();
+ newPlacemark->setGeometry( new GeoDataPoint( *point ) );
+ newPlacemark->setExtendedData( extendedData );
+ point->setParent( newPlacemark );
+ newPlacemark->setVisible( false );
+ newPlacemark->setZoomLevel( 18 );
+ doc->append( newPlacemark );
+ return newPlacemark;
}
}
diff --git a/src/plugins/runner/osm/handlers/OsmTagTagHandler.h b/src/plugins/runner/osm/handlers/OsmTagTagHandler.h
index d4749da..9bf9e0c 100644
--- a/src/plugins/runner/osm/handlers/OsmTagTagHandler.h
+++ b/src/plugins/runner/osm/handlers/OsmTagTagHandler.h
@@ -17,6 +17,7 @@ namespace Marble
class GeoDataGeometry;
class GeoDataPlacemark;
class GeoDataDocument;
+class GeoDataExtendedData;
namespace osm
{
@@ -25,9 +26,8 @@ class OsmTagTagHandler : public GeoTagHandler
{
public:
virtual GeoNode* parse( GeoParser& ) const;
-
private:
- static GeoDataPlacemark *createPOI( GeoDataDocument *doc, GeoDataGeometry *geometry );
+ static GeoDataPlacemark* createPOI( GeoDataDocument* doc, GeoDataGeometry* geometry, const GeoDataExtendedData &data );
};
}
diff --git a/src/plugins/runner/osm/handlers/OsmWayTagHandler.cpp b/src/plugins/runner/osm/handlers/OsmWayTagHandler.cpp
index df15102..b70fc78 100644
--- a/src/plugins/runner/osm/handlers/OsmWayTagHandler.cpp
+++ b/src/plugins/runner/osm/handlers/OsmWayTagHandler.cpp
@@ -8,15 +8,24 @@
// Copyright 2011 Konstantin Oblaukhov <[email protected]>
//
+// Self
#include "OsmWayTagHandler.h"
+// Qt
+#include <QVariant>
+
+// Osm plugin
#include "OsmParser.h"
#include "OsmElementDictionary.h"
+// Marble
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataParser.h"
#include "GeoDataLineString.h"
+#include "GeoDataExtendedData.h"
+#include "GeoDataData.h"
+#include "osm/OsmPlacemarkData.h"
namespace Marble
{
@@ -42,13 +51,20 @@ GeoNode* OsmWayTagHandler::parse( GeoParser &geoParser ) const
GeoDataLineString *polyline = new GeoDataLineString();
GeoDataPlacemark *placemark = new GeoDataPlacemark();
placemark->setGeometry( polyline );
+ qint64 id = parser.attribute( "id" ).toLongLong();
+
+ // Saving osm server generated data
+ OsmPlacemarkData osmData = parser.osmAttributeData();
+ GeoDataExtendedData extendedData;
+ extendedData.addValue( GeoDataData( OsmPlacemarkData::osmHashKey(), QVariant::fromValue( osmData ) ) );
+ placemark->setExtendedData( extendedData );
// At the beginning visibility = false. Afterwards when parsing
// the tags for the placemark it will decide if it should be displayed or not
placemark->setVisible( false );
- doc->append( placemark );
- parser.setWay( parser.attribute( "id" ).toULongLong(), polyline );
+ // Adding the way to the parser's hash ( in case we need to ref it )
+ parser.setWay( id, polyline );
return polyline;
}