summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshat Tandon <akshat.tandon@research.iiit.ac.in>2016-07-16 00:39:05 (GMT)
committerAkshat Tandon <akshat.tandon@research.iiit.ac.in>2016-07-19 14:04:44 (GMT)
commit9c6b3d0e42da0438a54798fda192034f6694ba72 (patch)
tree37b28c342ea9bdfca60643018a9949fc2ab73ad6
parent43f3168e3ed8fb73d331cff3f6f2f7b022c9b095 (diff)
Added way-concatenating module to osm-simplify.
Reviewers: nienhueser, rahn Differential Revision: https://phabricator.kde.org/D2128
-rw-r--r--src/lib/marble/geodata/data/GeoDataLineString.cpp11
-rw-r--r--src/lib/marble/geodata/data/GeoDataLineString.h4
-rw-r--r--tools/osm-simplify/BaseFilter.cpp10
-rw-r--r--tools/osm-simplify/BaseFilter.h3
-rw-r--r--tools/osm-simplify/CMakeLists.txt3
-rw-r--r--tools/osm-simplify/TagsFilter.cpp95
-rw-r--r--tools/osm-simplify/TagsFilter.h37
-rw-r--r--tools/osm-simplify/WayChunk.cpp129
-rw-r--r--tools/osm-simplify/WayChunk.h60
-rw-r--r--tools/osm-simplify/WayConcatenator.cpp344
-rw-r--r--tools/osm-simplify/WayConcatenator.h45
-rw-r--r--tools/osm-simplify/main.cpp48
12 files changed, 788 insertions, 1 deletions
diff --git a/src/lib/marble/geodata/data/GeoDataLineString.cpp b/src/lib/marble/geodata/data/GeoDataLineString.cpp
index e18e546..c70808a 100644
--- a/src/lib/marble/geodata/data/GeoDataLineString.cpp
+++ b/src/lib/marble/geodata/data/GeoDataLineString.cpp
@@ -522,6 +522,17 @@ void GeoDataLineString::setTessellationFlags( TessellationFlags f )
p()->m_tessellationFlags = f;
}
+void GeoDataLineString::reverse()
+{
+ GeoDataGeometry::detach();
+ GeoDataLineStringPrivate* d = p();
+ delete d->m_rangeCorrected;
+ d->m_rangeCorrected = 0;
+ d->m_dirtyRange = true;
+ d->m_dirtyBox = true;
+ std::reverse(begin(), end());
+}
+
GeoDataLineString GeoDataLineString::toNormalized() const
{
GeoDataLineString normalizedLineString;
diff --git a/src/lib/marble/geodata/data/GeoDataLineString.h b/src/lib/marble/geodata/data/GeoDataLineString.h
index 5973c16..54eacf6 100644
--- a/src/lib/marble/geodata/data/GeoDataLineString.h
+++ b/src/lib/marble/geodata/data/GeoDataLineString.h
@@ -136,6 +136,10 @@ class GEODATA_EXPORT GeoDataLineString : public GeoDataGeometry
*/
void setTessellationFlags( TessellationFlags f );
+/*!
+ \brief Reverses the LineString.
+*/
+ void reverse();
/*!
\brief Returns the smallest latLonAltBox that contains the LineString.
diff --git a/tools/osm-simplify/BaseFilter.cpp b/tools/osm-simplify/BaseFilter.cpp
index bfe6f73..7649c19 100644
--- a/tools/osm-simplify/BaseFilter.cpp
+++ b/tools/osm-simplify/BaseFilter.cpp
@@ -29,3 +29,13 @@ BaseFilter::~BaseFilter()
{
}
+
+QList<GeoDataObject*>::const_iterator BaseFilter::objectsBegin() const
+{
+ return m_objects.begin();
+}
+
+QList<GeoDataObject*>::const_iterator BaseFilter::objectsEnd() const
+{
+ return m_objects.end();
+}
diff --git a/tools/osm-simplify/BaseFilter.h b/tools/osm-simplify/BaseFilter.h
index 9c361f4..3e3ce7d 100644
--- a/tools/osm-simplify/BaseFilter.h
+++ b/tools/osm-simplify/BaseFilter.h
@@ -28,6 +28,9 @@ public:
virtual void process() = 0;
+ QList<GeoDataObject*>::const_iterator objectsBegin() const;
+ QList<GeoDataObject*>::const_iterator objectsEnd() const;
+
protected:
GeoDataDocument* m_document;
QList<GeoDataObject*> m_objects;
diff --git a/tools/osm-simplify/CMakeLists.txt b/tools/osm-simplify/CMakeLists.txt
index cc43b28..4220eb7 100644
--- a/tools/osm-simplify/CMakeLists.txt
+++ b/tools/osm-simplify/CMakeLists.txt
@@ -27,6 +27,9 @@ BaseFilter.cpp
LineStringProcessor.cpp
TinyPlanetProcessor.cpp
NodeReducer.cpp
+ TagsFilter.cpp
+ WayConcatenator.cpp
+WayChunk.cpp
)
add_definitions( -DMAKE_MARBLE_LIB )
diff --git a/tools/osm-simplify/TagsFilter.cpp b/tools/osm-simplify/TagsFilter.cpp
new file mode 100644
index 0000000..5024924
--- /dev/null
+++ b/tools/osm-simplify/TagsFilter.cpp
@@ -0,0 +1,95 @@
+//
+// 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 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
+//
+
+#include <QString>
+#include <QStringList>
+
+#include "PlacemarkFilter.h"
+#include "TagsFilter.h"
+#include "GeoDataObject.h"
+#include "GeoDataDocument.h"
+#include "OsmPlacemarkData.h"
+#include "GeoDataPlacemark.h"
+
+namespace Marble{
+
+TagsFilter::TagsFilter(GeoDataDocument *document, const QStringList &tagsList, bool andFlag ) : PlacemarkFilter(document)
+{
+ int total=0, tagCount=0;
+ // qDebug()<<"Entered tagFilter";
+ QList<GeoDataObject*> previousObjects(m_objects);
+ m_objects.clear();
+ foreach (GeoDataObject *object, previousObjects) {
+ ++total;
+ GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(object);
+ bool flag = andFlag;
+ QStringList::const_iterator itr = tagsList.begin();
+ for (; itr != tagsList.end(); ++itr) {
+ QStringList currentTag = (*itr).split('=');
+ QString currentKey;
+ QString currentValue;
+ if (currentTag.size() != 2) {
+ qDebug()<< "Invalid tag : "<< currentTag<<" ,rejecting it"<<endl;
+ continue;
+ } else {
+ currentKey = currentTag[0].trimmed();
+ currentValue = currentTag[1].trimmed();
+ }
+ bool contains;
+ if (currentValue == "*") {
+ contains = placemark->osmData().containsTagKey(currentKey);
+ } else {
+ contains = placemark->osmData().containsTag(currentKey, currentValue);
+ }
+ if (!contains) {
+ if (andFlag) {
+ flag = false;
+ break;
+ }
+ } else {
+ if (!andFlag) {
+ flag = true;
+ break;
+ }
+ }
+ }
+ if (flag) {
+ ++tagCount;
+ // qDebug()<<"Contained tag";
+ m_objects.append(object);
+ // qDebug()<<"ID "<<placemark->osmData().id();
+ } else {
+ m_rejectedObjects.append(object);
+ }
+
+ }
+ // qDebug()<<"Done TagFiltering";
+ // qDebug()<<"Total"<<total;
+ // qDebug()<<"TagCount"<<tagcon;
+ // qDebug()<<"Is and : "<<andFlag;
+}
+
+void TagsFilter::process()
+{
+ //does nothing
+}
+
+}
+
+
+QList<GeoDataObject*>::const_iterator TagsFilter::rejectedObjectsBegin() const
+{
+ return m_rejectedObjects.begin();
+}
+
+QList<GeoDataObject*>::const_iterator TagsFilter::rejectedObjectsEnd() const
+{
+ return m_rejectedObjects.end();
+}
diff --git a/tools/osm-simplify/TagsFilter.h b/tools/osm-simplify/TagsFilter.h
new file mode 100644
index 0000000..9e2bf3f
--- /dev/null
+++ b/tools/osm-simplify/TagsFilter.h
@@ -0,0 +1,37 @@
+//
+// 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 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
+//
+
+
+#ifndef MARBLE_TAGSFILTER_H
+#define MARBLE_TAGSFILTER_H
+
+#include "PlacemarkFilter.h"
+#include <QMap>
+#include <QString>
+
+
+namespace Marble{
+
+class GeoDataDocument;
+
+class TagsFilter : public PlacemarkFilter
+{
+public:
+ //Filters placemarks which have tags in the hash
+ TagsFilter(GeoDataDocument* document, const QStringList& tagsList, bool andFlag = false);
+ virtual void process();
+ QList<GeoDataObject*>::const_iterator rejectedObjectsBegin() const;
+ QList<GeoDataObject*>::const_iterator rejectedObjectsEnd() const;
+private:
+ QList<GeoDataObject*> m_rejectedObjects;
+};
+
+}
+#endif
diff --git a/tools/osm-simplify/WayChunk.cpp b/tools/osm-simplify/WayChunk.cpp
new file mode 100644
index 0000000..dd9f77b
--- /dev/null
+++ b/tools/osm-simplify/WayChunk.cpp
@@ -0,0 +1,129 @@
+//
+// 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 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
+//
+
+#include <QList>
+#include <QVector>
+#include <QDebug>
+
+#include "WayChunk.h"
+#include "GeoDataCoordinates.h"
+#include "GeoDataFeature.h"
+#include "GeoDataPlacemark.h"
+#include "GeoDataLineString.h"
+#include "OsmPlacemarkData.h"
+
+namespace Marble
+{
+
+WayChunk::WayChunk(GeoDataPlacemark *placemark, qint64 first, qint64 last)
+{
+ m_wayList.append(placemark);
+ m_first = first;
+ m_last = last;
+ m_visualCategory = placemark->visualCategory();
+}
+
+WayChunk::~WayChunk()
+{
+
+}
+
+qint64 WayChunk::first() const
+{
+ return m_first;
+}
+
+qint64 WayChunk::last() const
+{
+ return m_last;
+}
+
+void WayChunk::append(GeoDataPlacemark *placemark, qint64 last)
+{
+ m_wayList.append(placemark);
+ m_last = last;
+
+}
+
+void WayChunk::prepend(GeoDataPlacemark *placemark, qint64 first)
+{
+ m_wayList.prepend(placemark);
+ m_first = first;
+
+}
+
+void WayChunk::append(WayChunk *chunk)
+{
+ m_wayList << chunk->m_wayList;
+ m_last = chunk->last();
+}
+
+GeoDataPlacemark* WayChunk::merge()
+{
+ Q_ASSERT(!m_wayList.isEmpty());
+
+ GeoDataPlacemark *placemark = new GeoDataPlacemark(*(m_wayList.first()));
+ GeoDataLineString *line = static_cast<GeoDataLineString*>(placemark->geometry());
+ QList<GeoDataPlacemark*>::iterator itr = m_wayList.begin();
+ QList<GeoDataPlacemark*>::iterator itrEnd = m_wayList.end();
+ ++itr;
+ for (; itr != itrEnd; ++itr) {
+ GeoDataLineString *currentLine = static_cast<GeoDataLineString*>( (*itr)->geometry() );
+ currentLine->remove(0);
+ (*line) << *currentLine;
+ }
+ //qDebug()<<"Merging placemark";
+ return placemark;
+}
+
+void WayChunk::reverse()
+{
+ std::reverse(m_wayList.begin(), m_wayList.end());
+ QList<GeoDataPlacemark*>::iterator itr = m_wayList.begin();
+ for (; itr != m_wayList.end(); ++itr) {
+ GeoDataPlacemark *placemark = *itr;
+ GeoDataLineString *line = static_cast<GeoDataLineString*>(placemark->geometry());
+ line->reverse();
+ }
+ qSwap(m_first, m_last);
+}
+
+qint64 WayChunk::id() const
+{
+ return m_wayList.first()->osmData().id();
+}
+
+void WayChunk::printIds() const
+{
+ QList<GeoDataPlacemark*>::const_iterator itr = m_wayList.begin();
+ qDebug()<<"IDs of placemarks in chunk";
+ for (; itr != m_wayList.end(); ++itr) {
+ qDebug()<<"Id :- "<<(*itr)->osmData().id();
+ }
+}
+
+int WayChunk::size() const
+{
+ return m_wayList.size();
+}
+
+bool WayChunk::concatPossible(GeoDataPlacemark *placemark) const
+{
+ GeoDataFeature::GeoDataVisualCategory category = placemark->visualCategory();
+ return (category == m_visualCategory);
+}
+
+GeoDataFeature::GeoDataVisualCategory WayChunk::visualCategory() const
+{
+ return m_visualCategory;
+}
+
+
+}
diff --git a/tools/osm-simplify/WayChunk.h b/tools/osm-simplify/WayChunk.h
new file mode 100644
index 0000000..1423c7a
--- /dev/null
+++ b/tools/osm-simplify/WayChunk.h
@@ -0,0 +1,60 @@
+//
+// 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 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
+//
+
+#ifndef MARBLE_WAYCHUNK_H
+#define MARBLE_WAYCHUNK_H
+
+#include <QList>
+
+#include "GeoDataFeature.h"
+#include "GeoDataLineString.h"
+
+
+namespace Marble
+{
+
+class GeoDataPlacemark;
+
+class WayChunk
+{
+public:
+ WayChunk(GeoDataPlacemark *placemark, qint64 first, qint64 last );
+ ~WayChunk();
+ void append(GeoDataPlacemark *placemark, qint64 last);
+ void append(WayChunk *chunk);
+ void prepend(GeoDataPlacemark *placemark, qint64 first);
+
+ /*
+ * Creates a new placemark object by concatenating all the linsetrings which exist in the WayChunk
+ * Caller has the responsibility of deleting the object.
+ */
+ GeoDataPlacemark* merge();
+
+ qint64 first() const;
+ qint64 last() const;
+ void reverse();
+ qint64 id() const;
+ void printIds() const;
+ int size() const;
+ bool concatPossible(GeoDataPlacemark *placemark) const;
+ GeoDataFeature::GeoDataVisualCategory visualCategory() const;
+
+private:
+ QList<GeoDataPlacemark*> m_wayList;
+ qint64 m_first;
+ qint64 m_last;
+ GeoDataFeature::GeoDataVisualCategory m_visualCategory;
+
+};
+
+}
+
+#endif
+
diff --git a/tools/osm-simplify/WayConcatenator.cpp b/tools/osm-simplify/WayConcatenator.cpp
new file mode 100644
index 0000000..df1671f
--- /dev/null
+++ b/tools/osm-simplify/WayConcatenator.cpp
@@ -0,0 +1,344 @@
+//
+// 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 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
+//
+
+#include <QList>
+#include <QHash>
+
+#include "GeoDataPlacemark.h"
+#include "GeoDataDocument.h"
+#include "GeoDataObject.h"
+#include "OsmPlacemarkData.h"
+#include "StyleBuilder.h"
+
+#include "WayConcatenator.h"
+#include "WayChunk.h"
+#include "TagsFilter.h"
+
+namespace Marble
+{
+
+WayConcatenator::WayConcatenator(GeoDataDocument *document, const QStringList &tagsList, bool andFlag) : TagsFilter(document, tagsList, andFlag)
+{
+ // qDebug()<< "Entered WayConcatenator";
+}
+
+WayConcatenator::~WayConcatenator()
+{
+ QVector<WayChunk*>::iterator itr = m_chunks.begin();
+ for (; itr != m_chunks.end(); ++itr) {
+ delete *itr;
+ }
+}
+
+void WayConcatenator::process()
+{
+ qint64 count = 0;
+ qint64 chunkCount = 0;
+ qint64 newCount = 0;
+ qint64 placemarkCount = 0;
+
+ // qDebug()<<"** Number of TagFiletered placemarks "<< m_objects.size();
+ foreach (GeoDataObject *object, m_objects) {
+ GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(object);
+
+ qDebug()<<" ";
+ ++placemarkCount;
+ // qDebug()<<"No."<<plcCount;
+ if (placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType) {
+ qDebug()<<"-- Placemark ID : "<<placemark->osmData().id()<<" visualCategory: "<<StyleBuilder::visualCategoryName(placemark->visualCategory());
+ GeoDataLineString *line = static_cast<GeoDataLineString*>(placemark->geometry());
+ qint64 firstId = placemark->osmData().nodeReference(line->first()).id();
+ qint64 lastId = placemark->osmData().nodeReference(line->last()).id();
+
+ bool containsFirst = m_hash.contains(firstId);
+ bool containsLast = m_hash.contains(lastId);
+
+ if (!containsFirst && !containsLast) {
+ qDebug()<<"No coords matched, creating a new chunk";
+ createWayChunk(placemark, firstId, lastId);
+ ++count;
+ ++chunkCount;
+ } else if (containsFirst && !containsLast) {
+ qDebug()<<"First coord matched";
+ WayChunk *chunk = getWayChunk(placemark, firstId);
+ if (chunk != nullptr) {
+ // qDebug()<< "First* Chunk found, concatenating to it";
+ concatFirst(placemark, chunk);
+ } else {
+ // qDebug()<<"";
+ qDebug()<< "First* No possible chunk found, creating a new chunk";
+ qDebug()<<"FirstId"<<firstId;
+ qDebug()<<"lastId"<<lastId;
+ // qDebug()<<"";
+ createWayChunk(placemark, firstId, lastId);
+ ++chunkCount;
+ ++newCount;
+ }
+ ++count;
+ } else if (!containsFirst && containsLast) {
+ qDebug()<<"Last coord matched";
+ WayChunk *chunk = getWayChunk(placemark, lastId);
+ if (chunk != nullptr) {
+ // qDebug()<< "Last* Chunk found, concatenating to it";
+ concatLast(placemark, chunk);
+ } else {
+ // qDebug()<<"";
+ qDebug()<< "Last* No possible chunk found, creating a new chunk";
+ qDebug()<<"FirstId"<<firstId;
+ qDebug()<<"lastId"<<lastId;
+ // qDebug()<<"";
+ createWayChunk(placemark, firstId, lastId);
+ ++chunkCount;
+ ++newCount;
+ }
+ ++count;
+ } else if (containsFirst && containsLast) {
+ qDebug()<<"Both coord matched";
+ WayChunk *chunk = getWayChunk(placemark, firstId);
+ WayChunk *otherChunk = getWayChunk(placemark, lastId);
+
+ if (chunk != nullptr && otherChunk != nullptr) {
+ // qDebug()<< "Both* Both chunks found, concatenating to it";
+ if(chunk == otherChunk){
+ qDebug()<<"#### Both the chunks are same, directly adding to the list of placemarks";
+ m_placemarks.append(*placemark);
+ } else {
+ concatBoth(placemark, chunk, otherChunk);
+ ++count;
+ }
+ } else if(chunk != nullptr && otherChunk == nullptr) {
+ // qDebug()<< "Both* First chunk found, concatenating to it";
+ concatFirst(placemark, chunk);
+ ++count;
+ } else if(chunk == nullptr && otherChunk != nullptr) {
+ // qDebug()<< "Both* Last chunk found, concatenating to it";
+ concatLast(placemark, otherChunk);
+ ++count;
+ } else {
+ // qDebug()<<"";
+ qDebug()<< "Both* No possible chunk found, creating a new chunk";
+ qDebug()<<"FirstId"<<firstId;
+ qDebug()<<"lastId"<<lastId;
+ // qDebug()<<"";
+ createWayChunk(placemark, firstId, lastId);
+ ++chunkCount;
+ ++newCount;
+ ++count;
+ }
+
+ }
+
+ // if(flag){
+ // qDebug()<<" Concat not possible";
+ // m_placemarks.append(*placemark);
+ // }
+ } else{
+ m_placemarks.append(*placemark);
+ }
+ }
+
+ addRejectedPlacemarks();
+ addWayChunks();
+ modifyDocument();
+
+ qDebug()<<"####################################";
+ qDebug()<<"Total OSM ways concatenated: "<<count;
+ qDebug()<<"* Counted no. of chunks: "<<chunkCount;
+ qDebug()<<"* Chunks formed due to no match"<<newCount;
+ // qDebug()<<"Total reverses required: "<<rvr;
+
+}
+
+void WayConcatenator::addRejectedPlacemarks()
+{
+ QList<GeoDataObject*>::const_iterator itr = rejectedObjectsBegin();
+ QList<GeoDataObject*>::const_iterator endItr = rejectedObjectsEnd();
+ for (; itr != endItr; ++itr) {
+ GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(*itr);
+ m_placemarks.append(*placemark);
+ }
+}
+
+void WayConcatenator::addWayChunks()
+{
+ qint64 totalSize = 0;
+ QSet<WayChunk*> chunkSet;
+ // QList<WayChunk*> chunkList = m_hash.values();
+ // QList<WayChunk*>::iterator cItr = chunkList.begin();
+ // qDebug()<<"* Chunk list size = "<<chunkList.size();
+
+ QVector<WayChunk*>::iterator itr = m_chunks.begin();
+ for (; itr != m_chunks.end(); ++itr) {
+ if (!chunkSet.contains(*itr)) {
+ chunkSet.insert(*itr);
+ GeoDataPlacemark* placemark = (*itr)->merge();
+ if (placemark) {
+ m_placemarks.append(*placemark);
+ totalSize += (*itr)->size();
+ qDebug()<<"Chunk:";
+ (*itr)->printIds();
+ qDebug()<<"Size of this chunk"<<(*itr)->size();
+ qDebug()<<"Merged";
+ qDebug()<<" ";
+ delete placemark;
+ }
+ }
+ }
+ qDebug()<<"*** Total number of ways merged"<<totalSize;
+ qDebug()<<"******* m_chunks vector size"<<m_chunks.size();
+ // qDebug()<< "Entered 1";
+}
+
+void WayConcatenator::modifyDocument()
+{
+ m_document->clear();
+ QList<GeoDataPlacemark>::iterator itr;
+ itr = m_placemarks.begin();
+ for (; itr != m_placemarks.end(); ++itr) {
+ GeoDataPlacemark *placemark = new GeoDataPlacemark(*itr);
+ m_document->append(placemark);
+ }
+}
+
+void WayConcatenator::createWayChunk(GeoDataPlacemark *placemark, qint64 firstId, qint64 lastId)
+{
+ WayChunk *chunk = new WayChunk(placemark, firstId, lastId);
+ m_hash.insert(firstId, chunk);
+ if (firstId != lastId) {
+ m_hash.insert(lastId, chunk);
+ }
+ m_chunks.append(chunk);
+}
+
+WayChunk* WayConcatenator::getWayChunk(GeoDataPlacemark *placemark, qint64 matchId)
+{
+ qDebug()<<"Searching for a compatible WayChunk";
+ qDebug()<<"Visual category for placemark"<<StyleBuilder::visualCategoryName(placemark->visualCategory());
+
+ QHash<qint64, WayChunk*>::iterator matchItr = m_hash.find(matchId);
+ while (matchItr != m_hash.end() && matchItr.key() == matchId) {
+ WayChunk *chunk = matchItr.value();
+ qDebug()<<" * Chunk ID: "<<chunk->id()<<" Visual category for chunk"<<StyleBuilder::visualCategoryName(chunk->visualCategory());
+ if (chunk->concatPossible(placemark)) {
+ qDebug()<<"Match found";
+ return chunk;
+ }
+ ++matchItr;
+ }
+ qDebug()<<"### No Chunk found, returning nullptr";
+ return nullptr;
+}
+
+void WayConcatenator::concatFirst(GeoDataPlacemark *placemark, WayChunk *chunk)
+{
+ qDebug()<<"First coord matched";
+ qDebug()<<"Matched with: ";
+ chunk->printIds();
+
+ GeoDataLineString *line = static_cast<GeoDataLineString*>(placemark->geometry());
+ qint64 firstId = placemark->osmData().nodeReference(line->first()).id();
+ qint64 lastId = placemark->osmData().nodeReference(line->last()).id();
+
+ if (chunk->first() != chunk->last()) {
+ int chunksRemoved = m_hash.remove(firstId, chunk);
+ Q_ASSERT(chunksRemoved == 1);
+ }
+ m_hash.insert(lastId, chunk);
+
+ if (firstId == chunk->last()) {
+ //First node matches with an existing last node
+ qDebug()<<"Appended chunk";
+ chunk->append(placemark, lastId);
+ } else {
+ //First node matches with an existing first node
+ //Reverse the GeoDataLineString of the placemark
+ line->reverse();
+ chunk->prepend(placemark, lastId);
+ qDebug()<<"Reversed line and then prepended";
+ }
+
+}
+
+void WayConcatenator::concatLast(GeoDataPlacemark *placemark, WayChunk *chunk)
+{
+ qDebug()<<"Last coord matched";
+ qDebug()<<"Matched with: ";
+ chunk->printIds();
+
+ GeoDataLineString *line = static_cast<GeoDataLineString*>(placemark->geometry());
+ qint64 firstId = placemark->osmData().nodeReference(line->first()).id();
+ qint64 lastId = placemark->osmData().nodeReference(line->last()).id();
+
+ if (chunk->first() != chunk->last()) {
+ int chunksRemoved = m_hash.remove(lastId, chunk);
+ Q_ASSERT(chunksRemoved == 1);
+ }
+ m_hash.insert(firstId, chunk);
+
+ if (lastId == chunk->first()) {
+ qDebug()<<"Prepended chunk";
+ chunk->prepend(placemark, firstId);
+ } else {
+ line->reverse();
+ chunk->append(placemark, firstId);
+ qDebug()<<"Reversed line and then appended";
+ }
+
+}
+
+void WayConcatenator::concatBoth(GeoDataPlacemark *placemark, WayChunk *chunk, WayChunk *otherChunk)
+{
+
+ qDebug()<<" Concat possible";
+ qDebug()<<"Inserting in the middle";
+ qDebug()<<"Matched first coord with: ";
+ chunk->printIds();
+ qDebug()<<"Matched last coord with";
+ otherChunk->printIds();
+
+ GeoDataLineString *line = static_cast<GeoDataLineString*>(placemark->geometry());
+ qint64 firstId = placemark->osmData().nodeReference(line->first()).id();
+ qint64 lastId = placemark->osmData().nodeReference(line->last()).id();
+
+ int chunksRemoved;
+ if (chunk->first() != chunk->last()) {
+ chunksRemoved = m_hash.remove(firstId, chunk);
+ Q_ASSERT(chunksRemoved == 1);
+ }
+
+ if (firstId == chunk->first()) {
+ chunk->reverse();
+ }
+
+ chunk->append(placemark, lastId);
+
+ if (lastId == otherChunk->last()) {
+ qDebug()<<" otherChunk reversed";
+ otherChunk->reverse();
+ }
+ chunk->append(otherChunk);
+
+ chunksRemoved = m_hash.remove(otherChunk->first(), otherChunk);
+ Q_ASSERT(chunksRemoved == 1);
+
+ if (otherChunk->first() != otherChunk->last()) {
+ chunksRemoved = m_hash.remove(otherChunk->last(), otherChunk);
+ Q_ASSERT(chunksRemoved == 1);
+ }
+
+ m_hash.insert(otherChunk->last(), chunk);
+
+ m_chunks.removeOne(otherChunk);
+
+}
+
+
+
+}
diff --git a/tools/osm-simplify/WayConcatenator.h b/tools/osm-simplify/WayConcatenator.h
new file mode 100644
index 0000000..394f150
--- /dev/null
+++ b/tools/osm-simplify/WayConcatenator.h
@@ -0,0 +1,45 @@
+//
+// 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 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
+//
+
+#ifndef MARBLE_WAYCONCATENATOR_H
+#define MARBLE_WAYCONCATENATOR_H
+
+#include "PlacemarkFilter.h"
+#include "TagsFilter.h"
+
+namespace Marble
+{
+class WayChunk;
+
+class WayConcatenator : public TagsFilter
+{
+public:
+ WayConcatenator(GeoDataDocument *document, const QStringList &tagsList, bool andFlag = false);
+ virtual void process();
+ ~WayConcatenator();
+private:
+ QMultiHash<qint64, WayChunk*> m_hash;
+ QVector<WayChunk*> m_chunks;
+ QList<GeoDataPlacemark> m_placemarks;
+ void createWayChunk(GeoDataPlacemark *placemark, qint64 firstId, qint64 lastId);
+ WayChunk* getWayChunk(GeoDataPlacemark *placemark, qint64 matchId);
+ void concatFirst(GeoDataPlacemark *placemark, WayChunk *chunk);
+ void concatLast(GeoDataPlacemark *placemark, WayChunk *chunk);
+ void concatBoth(GeoDataPlacemark *placemark, WayChunk *chunk, WayChunk *otherChunk);
+ void addRejectedPlacemarks();
+ void addWayChunks();
+ void modifyDocument();
+};
+
+}
+
+#endif
+
+
diff --git a/tools/osm-simplify/main.cpp b/tools/osm-simplify/main.cpp
index 3c34d3e..e365f2f 100644
--- a/tools/osm-simplify/main.cpp
+++ b/tools/osm-simplify/main.cpp
@@ -26,6 +26,7 @@
#include "ShpCoastlineProcessor.h"
#include "TinyPlanetProcessor.h"
#include "NodeReducer.h"
+#include "WayConcatenator.h"
using namespace Marble;
@@ -133,6 +134,22 @@ int main(int argc, char *argv[])
},
{
+ {"t", "tags-filter"},
+ QCoreApplication::translate("main", "Tag key-value pairs which are to be be considered"),
+ QCoreApplication::translate("main", "k1=v1,k2=v2...")
+ },
+
+ {
+ {"and", "tags-and"},
+ QCoreApplication::translate("main", "For a feature to be considered for processing it must contain all the specified using tags-filter"),
+ },
+
+ {
+ {"w", "concat-ways"},
+ QCoreApplication::translate("main", "Concatenates the ways which are specified using tags-filter"),
+ },
+
+ {
{"o", "output"},
QCoreApplication::translate("main", "Generates an output .osmfile based on other flags. If the cut-to-tiles flag is set, then this needs to be a directory."),
QCoreApplication::translate("main", "output_file.osm")
@@ -389,8 +406,37 @@ int main(int argc, char *argv[])
}
}
- } else {
+ } else if(parser.isSet("tags-filter") && parser.isSet("concat-ways")){
+
+
+ //Parses the tags given at command line and makes a Hash of key-value pairs
+ qDebug()<<" Parsed tf value: "<<parser.value("tags-filter")<<endl;
+ QStringList tagsList = parser.value("tags-filter").split(',');
+ //Filters and considers only those placemarks which have all the key-value pairs given at command line
+
+ WayConcatenator concatenator(map, tagsList, parser.isSet("tags-and"));
+ concatenator.process();
+
+ qDebug()<<"Concatenation done, writing results to the file";
+
+ QFile outputFile(outputName);
+ GeoWriter writer;
+ writer.setDocumentType("0.6");
+
+ outputFile.open( QIODevice::WriteOnly );
+ if ( !writer.write( &outputFile, map ) ) {
+ qDebug() << "Could not write the file " << outputName;
+ return 4;
+ }else{
+ qDebug()<<"File written";
+ }
+
+
}
+ else {
+ }
+
+ delete map;
return 0;