Commit fb23fabe authored by Dennis Nienhüser's avatar Dennis Nienhüser

Write ways and relations in order, no duplicate ways.

parent 606c6aa2
......@@ -17,8 +17,6 @@ set( osm_writers_SRCS
)
set( osm_translators_SRCS
translators/OsmDocumentTagTranslator.cpp
translators/OsmPlacemarkTagTranslator.cpp
translators/OsmFeatureTagTranslator.cpp
)
set( osm_SRCS
......
......@@ -25,7 +25,7 @@
#include "GeoDataTypes.h"
#include "osm/OsmPlacemarkData.h"
#include "osm/OsmObjectManager.h"
#include "OsmRelationTagWriter.h"
namespace Marble
{
......@@ -35,32 +35,34 @@ static GeoTagWriterRegistrar s_writerDocument( GeoTagWriter::QualifiedName( GeoD
new OsmDocumentTagTranslator() );
bool OsmDocumentTagTranslator::writeMid( const GeoNode *node, GeoWriter& writer ) const
bool OsmDocumentTagTranslator::write( const GeoNode *node, GeoWriter& writer ) const
{
const GeoDataDocument *document = static_cast<const GeoDataDocument*>(node);
// Creating separate lists, to improve efficiency
QList<const GeoDataObject*> polylines, polygons;
QList<OsmBound> bounds;
typedef QPair<const GeoDataPolygon*, OsmPlacemarkData > OsmPolygon;
typedef QPair<const GeoDataLineString*, OsmPlacemarkData > OsmLineString;
QList<OsmPlacemarkData> nodes;
QList<OsmLineString> ways;
QList<OsmPolygon> polygons;
// Writing all the component nodes ( points, nodes of polylines, nodes of polygons )
foreach ( GeoDataPlacemark* placemark, document->placemarkList() ) {
foreach (GeoDataPlacemark* placemark, document->placemarkList()) {
// If the placemark's osmData is not complete, it is initialized by the OsmObjectManager
OsmObjectManager::initializeOsmData( placemark );
const OsmPlacemarkData osmData = placemark->osmData();
if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPointType ) {
nodes << osmData;
writeElement( placemark, writer );
}
else if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType ||
placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLinearRingType ) {
// Writing all the lineString nodes directly from the hash, as order is irrelevant
} else if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType ) {
const GeoDataLineString* lineString = static_cast<const GeoDataLineString*>( placemark->geometry() );
nodes << osmData;
polylines.append( placemark );
}
else if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType ) {
ways << OsmLineString(lineString, osmData);
} else if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLinearRingType ) {
const GeoDataLinearRing* linearRing = static_cast<const GeoDataLinearRing*>( placemark->geometry() );
nodes << osmData;
ways << OsmLineString(linearRing, osmData);
} else if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType ) {
const GeoDataPolygon *polygon = static_cast<const GeoDataPolygon*>( placemark->geometry() );
int index = -1;
......@@ -68,44 +70,38 @@ bool OsmDocumentTagTranslator::writeMid( const GeoNode *node, GeoWriter& writer
const GeoDataLinearRing &outerRing = polygon->outerBoundary();
const OsmPlacemarkData outerRingOsmData = osmData.memberReference( index );
nodes << outerRingOsmData;
bounds.append( OsmBound( &outerRing, outerRingOsmData ) );
ways << OsmLineString(&outerRing, outerRingOsmData);
// Writing all nodes for each innerRing
foreach ( const GeoDataLinearRing &innerRing, polygon->innerBoundaries() ) {
++index;
const OsmPlacemarkData innerRingOsmData = osmData.memberReference( index );
nodes << innerRingOsmData;
bounds.append( OsmBound( &innerRing, innerRingOsmData ) );
ways << OsmLineString(&innerRing, innerRingOsmData);
}
polygons.append( placemark );
polygons.append(OsmPolygon(polygon, osmData));
}
}
OsmNodeTagWriter::writeAllNodes(nodes, writer);
// Writing the ways
foreach ( const GeoDataObject* polyline, polylines ) {
writeElement( polyline, writer );
}
// Writing the bounds ( innerBounds and outerBounds, part of polygons )
foreach ( const OsmBound & bound, bounds ) {
OsmWayTagWriter::writeWay( *bound.first, bound.second, writer );
qSort(ways.begin(), ways.end(), [] (const OsmLineString &a, const OsmLineString &b) { return a.second.id() < b.second.id(); });
qint64 lastId = 0;
foreach(const OsmLineString &way, ways) {
if (way.second.id() != lastId) {
OsmWayTagWriter::writeWay(*way.first, way.second, writer);
lastId = way.second.id();
}
}
// Writing polygons
foreach ( const GeoDataObject* polygon, polygons ) {
writeElement( polygon, writer );
qSort(polygons.begin(), polygons.end(), [] (const OsmPolygon &a, const OsmPolygon &b) { return a.second.id() < b.second.id(); });
foreach (const OsmPolygon& polygon, polygons) {
OsmRelationTagWriter::writeMultipolygon(*polygon.first, polygon.second, writer );
}
return true;
}
OsmDocumentTagTranslator::OsmDocumentTagTranslator():
OsmFeatureTagTranslator() {
//nothing to do
}
}
......@@ -12,7 +12,6 @@
#define MARBLE_OSMDOCUMENTTAGTRANSLATOR_H
#include "GeoTagWriter.h"
#include "OsmFeatureTagTranslator.h"
namespace Marble
{
......@@ -33,17 +32,10 @@ namespace Marble
class GeoDataLineString;
class OsmPlacemarkData;
class OsmDocumentTagTranslator : public OsmFeatureTagTranslator
class OsmDocumentTagTranslator : public GeoTagWriter
{
public:
OsmDocumentTagTranslator();
protected:
virtual bool writeMid( const GeoNode *node, GeoWriter& writer ) const;
private:
typedef QPair<const GeoDataLineString*, OsmPlacemarkData > OsmBound;
bool write( const GeoNode *node, GeoWriter& writer ) const;
};
}
......
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
//
#include "OsmFeatureTagTranslator.h"
namespace Marble
{
OsmFeatureTagTranslator::OsmFeatureTagTranslator() {
//nothing to do
}
bool OsmFeatureTagTranslator::write( const Marble::GeoNode *node, GeoWriter &writer ) const
{
// Write identifiers
bool const result = writeMid( node, writer );
return result;
}
}
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
//
#ifndef MARBLE_OSMFEATURETAGTRANSLATOR_H
#define MARBLE_OSMFEATURETAGTRANSLATOR_H
#include "GeoTagWriter.h"
#include <QString>
namespace Marble
{
// No registration needed for this class, as it is abstract.
class OsmFeatureTagTranslator: public GeoTagWriter
{
public:
explicit OsmFeatureTagTranslator();
bool write( const GeoNode *node, GeoWriter& writer ) const;
protected:
virtual bool writeMid( const GeoNode *node, GeoWriter& writer ) const = 0;
};
}
#endif
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
//
//Self
#include "OsmPlacemarkTagTranslator.h"
//Marble
#include "OsmNodeTagWriter.h"
#include "OsmWayTagWriter.h"
#include "OsmRelationTagWriter.h"
#include "OsmElementDictionary.h"
#include "GeoDataPoint.h"
#include "GeoDataCoordinates.h"
#include "GeoDataLineString.h"
#include "GeoDataPolygon.h"
#include "GeoDataPlacemark.h"
#include "GeoDataGeometry.h"
#include "GeoWriter.h"
#include "GeoDataTypes.h"
#include "osm/OsmPlacemarkData.h"
#include "osm/OsmObjectManager.h"
namespace Marble
{
static GeoTagWriterRegistrar s_writerPlacemark( GeoTagWriter::QualifiedName( GeoDataTypes::GeoDataPlacemarkType,
osm::osmTag_version06 ), new OsmPlacemarkTagTranslator() );
OsmPlacemarkTagTranslator::OsmPlacemarkTagTranslator():
OsmFeatureTagTranslator() {
//nothing to do
}
bool OsmPlacemarkTagTranslator::writeMid( const GeoNode *node, GeoWriter& writer ) const
{
const GeoDataPlacemark *placemark = static_cast<const GeoDataPlacemark*>( node );
const OsmPlacemarkData &osmData = placemark->osmData();
if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType ) {
const GeoDataLineString* lineString = static_cast<const GeoDataLineString*>( placemark->geometry() );
OsmWayTagWriter::writeWay( *lineString, osmData, writer );
}
else if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLinearRingType ) {
const GeoDataLinearRing* linearRing = static_cast<const GeoDataLinearRing*>( placemark->geometry() );
OsmWayTagWriter::writeWay( *linearRing, osmData, writer );
}
else if ( placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType ) {
const GeoDataPolygon* polygon = static_cast<const GeoDataPolygon*>( placemark->geometry() );
OsmRelationTagWriter::writeMultipolygon( *polygon, osmData, writer );
}
return true;
}
}
//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
//
#ifndef MARBLE_OSMPLACEMARKTAGTRANSLATOR_H
#define MARBLE_OSMPLACEMARKTAGTRANSLATOR_H
#include "GeoTagWriter.h"
#include "OsmFeatureTagTranslator.h"
namespace Marble
{
class OsmPlacemarkTagTranslator : public OsmFeatureTagTranslator
{
public:
OsmPlacemarkTagTranslator();
protected:
virtual bool writeMid( const GeoNode *node, GeoWriter& writer ) const;
};
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment