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 @@ -25,6 +25,7 @@ PlacemarkFilter.cpp ShpCoastlineProcessor.cpp LineStringProcessor.cpp + NodeReducer.cpp ) add_definitions( -DMAKE_MARBLE_LIB ) diff --git a/tools/osm-simplify/NodeReducer.h b/tools/osm-simplify/NodeReducer.h new file mode 100644 --- /dev/null +++ b/tools/osm-simplify/NodeReducer.h @@ -0,0 +1,28 @@ +// +// 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_NODEREDUCER_H +#define MARBLE_NODEREDUCER_H + +#include "PlacemarkFilter.h" +#include "GeoDataLineString.h" + +class NodeReducer : public PlacemarkFilter{ +public: + NodeReducer(GeoDataDocument* document, int zoomLevel); + virtual void process(); +private: + GeoDataLineString* reduce(GeoDataLineString* lineString); + static qreal resolutionForLevel(int level); + qreal m_resolution; + qint64 m_count; +}; + +#endif \ No newline at end of file diff --git a/tools/osm-simplify/NodeReducer.cpp b/tools/osm-simplify/NodeReducer.cpp new file mode 100644 --- /dev/null +++ b/tools/osm-simplify/NodeReducer.cpp @@ -0,0 +1,163 @@ +// +// 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 "BaseClipper.h" +#include "GeoDataPlacemark.h" +#include "GeoDataTypes.h" +#include "GeoDataLineString.h" +#include "GeoDataCoordinates.h" +#include "MarbleMath.h" +#include "NodeReducer.h" + +#include +#include + +NodeReducer::NodeReducer(GeoDataDocument* document, int zoomLevel) : + PlacemarkFilter(document) +{ + m_resolution = resolutionForLevel(zoomLevel); + m_count = 0; +} + +void NodeReducer::process() +{ + foreach (GeoDataObject* object, m_objects) { + + GeoDataPlacemark* placemark = static_cast(object); + + if(placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType){ + GeoDataLineString* prevLine = static_cast(placemark->geometry()); + GeoDataLineString* reducedLine = reduce(prevLine); + placemark->setGeometry(reducedLine); + } + + else if(placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLinearRingType){ + GeoDataLinearRing* prevRing = static_cast(placemark->geometry()); + GeoDataLinearRing* reducedRing = static_cast(reduce(prevRing)); + placemark->setGeometry(reducedRing); + } + + else if(placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType){ + GeoDataPolygon* reducedPolygon = new GeoDataPolygon; + GeoDataPolygon* prevPolygon = static_cast(placemark->geometry()); + GeoDataLinearRing* prevRing = &(prevPolygon->outerBoundary()); + GeoDataLinearRing* reducedRing = static_cast(reduce(prevRing)); + reducedPolygon->setOuterBoundary(*reducedRing); + QVector& innerBoundaries = prevPolygon->innerBoundaries(); + for(int i = 0; i < innerBoundaries.size(); i++){ + prevRing = &innerBoundaries[i]; + reducedRing = static_cast(reduce(prevRing)); + reducedPolygon->appendInnerBoundary(*reducedRing); + } + placemark->setGeometry(reducedPolygon); + } + } + qDebug()<<"Total nodes reduced: "<size(); + + GeoDataLineString* reducedLine; + if(lineString->nodeType() == GeoDataTypes::GeoDataLineStringType){ + if(prevSize < 2){ + reducedLine = new GeoDataLineString(*lineString); + return reducedLine; + } + else{ + reducedLine = new GeoDataLineString; + } + } + else if(lineString->nodeType() == GeoDataTypes::GeoDataLinearRingType){ + if(prevSize < 2){ + reducedLine = new GeoDataLinearRing(*lineString); + return reducedLine; + } + reducedLine = new GeoDataLinearRing; + } + + + QVector::iterator itCoords = lineString->begin(); + GeoDataCoordinates currentCoords = *itCoords; + reducedLine->append(*itCoords); + ++itCoords; + for(; itCoords != (lineString->end() - 1); ++itCoords){ + if(distanceSphere( currentCoords, *itCoords ) >= m_resolution){ + currentCoords = *itCoords; + reducedLine->append(*itCoords); + } + } + reducedLine->append(*itCoords); + + qint64 reducedSize = reducedLine->size(); + m_count += (prevSize - reducedSize); + return reducedLine; + //qDebug()<<"Nodes reduced "<<(prevSize - reducedSize)<"), + QCoreApplication::translate("main", "Cuts into tiles based on the zoom level passed using -z."), + //QCoreApplication::translate("main", "number") + }, + + { + {"n", "node-reduce"}, + QCoreApplication::translate("main", "Reduces the number of nodes for a given way based on zoom level"), + }, + + { + {"z", "zoom-level"}, + QCoreApplication::translate("main", "Zoom level according to which OSM information has to be processed."), QCoreApplication::translate("main", "number") }, @@ -120,8 +132,17 @@ QString inputFileName = args.at(0); bool debug = parser.isSet("debug"); bool mute = parser.isSet("mute"); - unsigned int zoomLevel = parser.value("cut-to-tiles").toInt(); - QString outputFileName = parser.value("output"); + unsigned int zoomLevel = parser.value("zoom-level").toInt(); + qDebug()<<"Zoom level is "<