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,162 @@ +// +// 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() +{ + GeoDataPlacemark* placemark; + GeoDataLineString* reducedLine; + GeoDataLineString* prevLine; + GeoDataLinearRing* prevRing; + GeoDataLinearRing* reducedRing; + GeoDataPolygon *prevPolygon; + GeoDataPolygon *reducedPolygon; + + foreach (GeoDataObject* object, m_objects) { + placemark = static_cast(object); + + if(placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType){ + prevLine = static_cast(placemark->geometry()); + reducedLine = reduce(prevLine); + if(reducedLine != prevLine) + placemark->setGeometry(reducedLine); + } + + else if(placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLinearRingType){ + prevRing = static_cast(placemark->geometry()); + reducedRing = static_cast(reduce(prevRing)); + if(reducedRing != prevRing) + placemark->setGeometry(reducedRing); + } + + else if(placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType){ + reducedPolygon = new GeoDataPolygon; + prevPolygon = static_cast(placemark->geometry()); + prevRing = &(prevPolygon->outerBoundary()); + 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(); + if(prevSize < 2) + return lineString; + GeoDataLineString* reducedLine; + if(lineString->nodeType() == GeoDataTypes::GeoDataLineStringType){ + reducedLine = new GeoDataLineString; + } + else if(lineString->nodeType() == GeoDataTypes::GeoDataLinearRingType){ + 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") }, @@ -121,8 +133,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 "<