diff --git a/src/lib/marble/geodata/data/GeoDataLineString.h b/src/lib/marble/geodata/data/GeoDataLineString.h --- a/src/lib/marble/geodata/data/GeoDataLineString.h +++ b/src/lib/marble/geodata/data/GeoDataLineString.h @@ -136,6 +136,10 @@ */ void setTessellationFlags( TessellationFlags f ); +/*! + \brief Reverses the LineString. +*/ + void reverse(); /*! \brief Returns the smallest latLonAltBox that contains the LineString. diff --git a/src/lib/marble/geodata/data/GeoDataLineString.cpp b/src/lib/marble/geodata/data/GeoDataLineString.cpp --- a/src/lib/marble/geodata/data/GeoDataLineString.cpp +++ b/src/lib/marble/geodata/data/GeoDataLineString.cpp @@ -522,6 +522,11 @@ p()->m_tessellationFlags = f; } +void GeoDataLineString::reverse() +{ + std::reverse(begin(), end()); +} + GeoDataLineString GeoDataLineString::toNormalized() const { GeoDataLineString normalizedLineString; diff --git a/tools/osm-simplify/BaseFilter.h b/tools/osm-simplify/BaseFilter.h --- a/tools/osm-simplify/BaseFilter.h +++ b/tools/osm-simplify/BaseFilter.h @@ -28,6 +28,9 @@ virtual void process() = 0; + QList::const_iterator objsBegin() const; + QList::const_iterator objsEnd() const; + protected: GeoDataDocument* m_document; QList m_objects; diff --git a/tools/osm-simplify/BaseFilter.cpp b/tools/osm-simplify/BaseFilter.cpp --- a/tools/osm-simplify/BaseFilter.cpp +++ b/tools/osm-simplify/BaseFilter.cpp @@ -29,3 +29,11 @@ { } + +QList::const_iterator BaseFilter::objsBegin() const{ + return m_objects.begin(); +} + +QList::const_iterator BaseFilter::objsEnd() const{ + return m_objects.end(); +} diff --git a/tools/osm-simplify/CMakeLists.txt b/tools/osm-simplify/CMakeLists.txt --- a/tools/osm-simplify/CMakeLists.txt +++ b/tools/osm-simplify/CMakeLists.txt @@ -27,6 +27,9 @@ LineStringProcessor.cpp TinyPlanetProcessor.cpp NodeReducer.cpp + TagsFilter.cpp + WayConcatenator.cpp +WayChunk.cpp ) add_definitions( -DMAKE_MARBLE_LIB ) diff --git a/tools/osm-simplify/TagsFilter.h b/tools/osm-simplify/TagsFilter.h new file mode 100644 --- /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 +// + + +#ifndef MARBLE_TAGSFILTER_H +#define MARBLE_TAGSFILTER_H + +#include "PlacemarkFilter.h" +#include +#include + + +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::const_iterator rejectedObjsBegin() const; + QList::const_iterator rejectedObjsEnd() const; +private: + QList m_rejectedObjs; +}; + +} +#endif diff --git a/tools/osm-simplify/TagsFilter.cpp b/tools/osm-simplify/TagsFilter.cpp new file mode 100644 --- /dev/null +++ b/tools/osm-simplify/TagsFilter.cpp @@ -0,0 +1,99 @@ +// +// 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 +// + +#include +#include + +#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, tagcon=0; + QStringList tempTag; + QString tempKey; + QString tempValue; + // qDebug()<<"Entered tagFilter"; + GeoDataPlacemark* placemark; + QList prevObjects(m_objects); + QStringList::const_iterator itr; + m_objects.clear(); + bool flag = true; + bool contains; + foreach(GeoDataObject* object, prevObjects){ + total++; + placemark = static_cast(object); + andFlag = flag; + itr = tagsList.begin(); + for(; itr != tagsList.end(); itr++){ + tempTag = (*itr).split('='); + + if(tempTag.size() != 2){ + qDebug()<< "Invalid tag : "<< tempTag<<" ,rejecting it"<osmData().containsTagKey(tempKey); + }else{ + contains = placemark->osmData().containsTag(tempKey, tempValue); + } + if(!contains){ + if(andFlag){ + flag = false; + break; + } + }else{ + if(!andFlag){ + flag = true; + break; + } + } + } + if(flag){ + tagcon++; + // qDebug()<<"Contained tag"; + m_objects.append(object); + // qDebug()<<"ID "<osmData().id(); + }else{ + m_rejectedObjs.append(object); + } + + } + // qDebug()<<"Done TagFiltering"; + // qDebug()<<"Total"<::const_iterator TagsFilter::rejectedObjsBegin() const{ + return m_rejectedObjs.begin(); +} + +QList::const_iterator TagsFilter::rejectedObjsEnd() const{ + return m_rejectedObjs.end(); +} diff --git a/tools/osm-simplify/WayChunk.h b/tools/osm-simplify/WayChunk.h new file mode 100644 --- /dev/null +++ b/tools/osm-simplify/WayChunk.h @@ -0,0 +1,56 @@ +// +// 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 +// + +#ifndef MARBLE_WAYCHUNK_H +#define MARBLE_WAYCHUNK_H + +#include + +#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, qint64 last); + void prepend(GeoDataPlacemark* placemark, qint64 first); + void prepend(WayChunk* chunk, qint64 first); + GeoDataPlacemark* merge(); + qint64 first() const; + qint64 last() const; + void reverse(); + qint64 id() const; + void printIds() const; + qint64 size() const; + // static void reverseLine(GeoDataLineString* line); + bool concatPossible(GeoDataPlacemark* placemark) const; + GeoDataFeature::GeoDataVisualCategory visualCategory(); + +private: + QList m_wayList; + qint64 m_first; + qint64 m_last; + GeoDataFeature::GeoDataVisualCategory m_visualCategory; + +}; + +} + +#endif + diff --git a/tools/osm-simplify/WayChunk.cpp b/tools/osm-simplify/WayChunk.cpp new file mode 100644 --- /dev/null +++ b/tools/osm-simplify/WayChunk.cpp @@ -0,0 +1,183 @@ +// +// 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 +// + +#include +#include +#include + +#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, qint64 last){ + QList::iterator itr = chunk->m_wayList.begin(); + QList::iterator itrEnd = chunk->m_wayList.end(); + for(; itr != itrEnd; itr++){ + m_wayList.append(*itr); + } + m_last = last; +} + +void WayChunk::prepend(WayChunk* chunk, qint64 first){ + QList::iterator itr = m_wayList.begin(); + QList::iterator itrEnd = m_wayList.end(); + for(; itr != itrEnd; itr++){ + chunk->m_wayList.append(*itr); + } + m_first = first; + m_wayList = chunk->m_wayList; +} + +GeoDataPlacemark* WayChunk::merge(){ + if(m_wayList.isEmpty()){ + qDebug()<<"Merge empty"; + return NULL; + } + if(m_wayList.size() == 1){ + qDebug()<<"* Merge size 1"; + return m_wayList.first(); + } + QList::iterator itr = m_wayList.begin(); + itr++; + QList::iterator itrEnd = m_wayList.end(); + GeoDataPlacemark* placemark = new GeoDataPlacemark(*(m_wayList.first())); + GeoDataLineString* line = static_cast(placemark->geometry()); + for(; itr != itrEnd; itr++){ + GeoDataLineString* tempLine = static_cast( (*itr)->geometry() ); + tempLine->remove(0); + (*line) << *tempLine; + } + //qDebug()<<"Merging placemark"; + return placemark; +} + +void WayChunk::reverse(){ + std::reverse(m_wayList.begin(), m_wayList.end()); + QList::iterator itr = m_wayList.begin(); + GeoDataPlacemark* placemark; + GeoDataLineString* line; + for(; itr != m_wayList.end(); itr++){ + placemark = *itr; + line = static_cast(placemark->geometry()); + line->reverse(); + } + qint64 temp; + temp = m_first; + m_first = m_last; + m_last = temp; +} + +// void WayChunk::reverseLine(GeoDataLineString* line){ +// qint64 lineSize = line->size(); +// QVector coordsVector; +// for(qint64 i = 0; i < lineSize; i++){ +// coordsVector.append(line->at(i)); +// } +// line->clear(); +// for(qint64 i = lineSize - 1; i >= 0; i--){ +// line->append(coordsVector[i]); +// } + +// } + +qint64 WayChunk::id() const{ + return m_wayList.first()->osmData().id(); +} + +void WayChunk::printIds() const{ + QList::const_iterator itr = m_wayList.begin(); + qDebug()<<"IDs of placemarks in chunk"; + for(; itr != m_wayList.end(); itr++){ + qDebug()<<"Id :- "<<(*itr)->osmData().id(); + + } + +} + +qint64 WayChunk::size() const{ + return m_wayList.size(); +} + +bool WayChunk::concatPossible(GeoDataPlacemark* placemark) const{ + GeoDataFeature::GeoDataVisualCategory category = placemark->visualCategory(); + bool flag = (category == m_visualCategory); + + // if(category <= GeoDataFeature::HighwayMotorway && m_visualCategory <= GeoDataFeature::HighwayMotorway){ + // if(category >= GeoDataFeature::HighwayTertiaryLink && m_visualCategory >= GeoDataFeature::HighwayTertiaryLink){ + // if(category == GeoDataFeature::HighwayTertiaryLink && m_visualCategory == GeoDataFeature::HighwayTertiary) + // flag = true; + // else if (m_visualCategory == GeoDataFeature::HighwayTertiaryLink && category == GeoDataFeature::HighwayTertiary) + // flag = true; + // else if(category == GeoDataFeature::HighwaySecondaryLink && m_visualCategory == GeoDataFeature::HighwaySecondary) + // flag = true; + // else if(m_visualCategory == GeoDataFeature::HighwaySecondaryLink && category == GeoDataFeature::HighwaySecondary) + // flag = true; + // else if(category == GeoDataFeature::HighwayPrimaryLink && m_visualCategory == GeoDataFeature::HighwayPrimary) + // flag = true; + // else if(m_visualCategory == GeoDataFeature::HighwayPrimaryLink && category == GeoDataFeature::HighwayPrimary) + // flag = true; + // else if(category == GeoDataFeature::HighwayTrunkLink && m_visualCategory == GeoDataFeature::HighwayTrunk) + // flag = true; + // else if(m_visualCategory == GeoDataFeature::HighwayTrunkLink && category == GeoDataFeature::HighwayTrunk) + // flag = true; + // else if(category == GeoDataFeature::HighwayMotorwayLink && m_visualCategory == GeoDataFeature::HighwayMotorway) + // flag = true; + // else if(m_visualCategory == GeoDataFeature::HighwayMotorwayLink && category == GeoDataFeature::HighwayMotorway) + // flag = true; + // } + // } + + return flag; + +} + +GeoDataFeature::GeoDataVisualCategory WayChunk::visualCategory(){ + return m_visualCategory; +} + + +} diff --git a/tools/osm-simplify/WayConcatenator.h b/tools/osm-simplify/WayConcatenator.h new file mode 100644 --- /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 +// + +#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 m_hash; + QVector m_chunks; + QList 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/WayConcatenator.cpp b/tools/osm-simplify/WayConcatenator.cpp new file mode 100644 --- /dev/null +++ b/tools/osm-simplify/WayConcatenator.cpp @@ -0,0 +1,335 @@ +// +// 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 +// + +#include +#include + +#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(){ + +} + +void WayConcatenator::process(){ + qint64 count = 0; + qint64 chunkCount = 0; + qint64 nc = 0; + qint64 plcCount = 0; + + // qDebug()<<"** Number of TagFiletered placemarks "<< m_objects.size(); + foreach(GeoDataObject* object, m_objects){ + GeoDataPlacemark* placemark = static_cast(object); + + qDebug()<<" "; + plcCount++; + // qDebug()<<"No."<geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType){ + qDebug()<<"-- Placemark ID : "<osmData().id()<<" visualCategory: "<visualCategory()); + GeoDataLineString* line = static_cast(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 != NULL){ + // qDebug()<< "First* Chunk found, concatenating to it"; + concatFirst(placemark, chunk); + }else{ + // qDebug()<<""; + qDebug()<< "First* No possible chunk found, creating a new chunk"; + qDebug()<<"FirstId"<::const_iterator itr = rejectedObjsBegin(); + QList::const_iterator endItr = rejectedObjsEnd(); + for(; itr != endItr; itr++){ + GeoDataPlacemark* placemark = static_cast(*itr); + m_placemarks.append(*placemark); + } + +} + +void WayConcatenator::addWayChunks(){ + qint64 totSize = 0; + QSet chunkSet; + // QList chunkList = m_hash.values(); + // QList::iterator cItr = chunkList.begin(); + // qDebug()<<"* Chunk list size = "<::iterator cItr = m_chunks.begin(); + for(; cItr != m_chunks.end(); cItr++){ + if(!chunkSet.contains(*cItr)) + { + chunkSet.insert(*cItr); + GeoDataPlacemark* placemark = (*cItr)->merge(); + if(placemark){ + m_placemarks.append(*placemark); + totSize += (*cItr)->size(); + qDebug()<<"Chunk:"; + (*cItr)->printIds(); + qDebug()<<"Size of this chunk"<<(*cItr)->size(); + qDebug()<<"Merged"; + qDebug()<<" "; + } + } + } + qDebug()<<"*** Total number of ways merged"<clear(); + QList::iterator pItr; + pItr = m_placemarks.begin(); + for(; pItr != m_placemarks.end(); pItr++){ + GeoDataPlacemark* placemark = new GeoDataPlacemark(*pItr); + 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); + m_hash.insert(lastId, chunk); + m_chunks.append(chunk); +} + +WayChunk* WayConcatenator::getWayChunk(GeoDataPlacemark* placemark, qint64 matchId){ + QHash::iterator matchItr = m_hash.find(matchId); + qDebug()<<"Searching for a compatible WayChunk"; + qDebug()<<"Visual category for placemark"<visualCategory()); + while(matchItr != m_hash.end() && matchItr.key() == matchId){ + WayChunk* chunk = matchItr.value(); + qDebug()<<" * Chunk ID: "<id()<<" Visual category for chunk"<visualCategory()); + if(chunk->concatPossible(placemark)){ + qDebug()<<"Match found"; + return chunk; + } + matchItr++; + } + qDebug()<<"### No Chunk found, returning NULL"; + return NULL; +} + +void WayConcatenator::concatFirst(GeoDataPlacemark* placemark, WayChunk* chunk){ + qDebug()<<"First coord matched"; + qDebug()<<"Matched with: "; + chunk->printIds(); + + GeoDataLineString* line = static_cast(placemark->geometry()); + qint64 firstId = placemark->osmData().nodeReference(line->first()).id(); + qint64 lastId = placemark->osmData().nodeReference(line->last()).id(); + + 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"; + } + m_hash.insert(lastId, chunk); + int p = m_hash.remove(firstId, chunk); + if(p != 1) + qDebug()<<" ######### Error, not possible"; +} + +void WayConcatenator::concatLast(GeoDataPlacemark* placemark, WayChunk* chunk){ + qDebug()<<"Last coord matched"; + qDebug()<<"Matched with: "; + chunk->printIds(); + + GeoDataLineString* line = static_cast(placemark->geometry()); + qint64 firstId = placemark->osmData().nodeReference(line->first()).id(); + qint64 lastId = placemark->osmData().nodeReference(line->last()).id(); + + if(lastId == chunk->first()){ + qDebug()<<"Prepended chunk"; + chunk->prepend(placemark, firstId); + } + else{ + line->reverse(); + chunk->append(placemark, firstId); + qDebug()<<"Reversed line and then appended"; + // rvr++; + } + m_hash.insert(firstId, chunk); + int p = m_hash.remove(lastId, chunk); + if(p != 1) + qDebug()<<" ######### Error, not possible"; +} + +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(placemark->geometry()); + qint64 firstId = placemark->osmData().nodeReference(line->first()).id(); + qint64 lastId = placemark->osmData().nodeReference(line->last()).id(); + + if (firstId == chunk->first()){ + chunk->reverse(); + } + int p = m_hash.remove(firstId, chunk); + chunk->append(placemark, lastId); + if(p != 1) + qDebug()<<" ######### Error, not possible"; + + if(lastId == otherChunk->last()){ + otherChunk->reverse(); + } + chunk->append(otherChunk, otherChunk->last()); + + p = m_hash.remove(otherChunk->first(), otherChunk); + if(p != 1) + qDebug()<<" ######### Error, not possible"; + + p = m_hash.remove(otherChunk->last(), otherChunk); + if(p != 1) + qDebug()<<" ######### Error, not possible"; + + m_hash.insert(otherChunk->last(), chunk); + + m_chunks.removeOne(otherChunk); + // else if(firstId == chunk->last() && lastId == otherChunk->first()){ + // qDebug()<<"Reverse it"; + // rvr++; + // } + +} + + + +} \ No newline at end of file diff --git a/tools/osm-simplify/main.cpp b/tools/osm-simplify/main.cpp --- 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 @@ }, { + {"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,7 +406,34 @@ } } - } 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: "<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"; + } + delete concatenator; + + } + else { }