diff --git a/code/Makefile b/code/Makefile index bc8dea9..be7cd75 100644 --- a/code/Makefile +++ b/code/Makefile @@ -76,6 +76,7 @@ PROMINENCE_OBJS = \ $(OUTDIR)/island_tree.o \ $(OUTDIR)/kml_writer.o \ $(OUTDIR)/kml_writer_2.o \ + $(OUTDIR)/text_writer.o \ $(OUTDIR)/latlng.o \ $(OUTDIR)/line_tree.o \ $(OUTDIR)/peakbagger_collection.o \ @@ -96,6 +97,7 @@ MERGE_DIVIDE_TREES_OBJS = \ $(OUTDIR)/island_tree.o \ $(OUTDIR)/kml_writer.o \ $(OUTDIR)/kml_writer_2.o \ + $(OUTDIR)/text_writer.o \ $(OUTDIR)/latlng.o \ $(OUTDIR)/line_tree.o \ $(OUTDIR)/merge_divide_trees.o \ @@ -119,6 +121,7 @@ DEM_METRICS_OBJS = \ $(OUTDIR)/isolation_results.o \ $(OUTDIR)/kml_writer.o \ $(OUTDIR)/kml_writer_2.o \ + $(OUTDIR)/text_writer.o \ $(OUTDIR)/latlng.o \ $(OUTDIR)/line_tree.o \ $(OUTDIR)/peakbagger_point.o \ diff --git a/code/dem_metrics.cpp b/code/dem_metrics.cpp index 57ac910..a813835 100644 --- a/code/dem_metrics.cpp +++ b/code/dem_metrics.cpp @@ -176,6 +176,15 @@ int main(int argc, char** argv) { fprintf(file, "%s", divideTree->getAsKmlWithPopups().c_str()); fclose(file); + file = fopen((demName + "-divide_tree_pruned_" + std::to_string(int(minProminence)) + + ".txt").c_str(), "wb"); + if (file == nullptr) { + delete tile; + return -1; + } + fprintf(file, "%s", divideTree->getAsText().c_str()); + fclose(file); + // Build new island tree on pruned divide tree to get final prominence values IslandTree prunedIslandTree(*divideTree); prunedIslandTree.build(); diff --git a/code/divide_tree.cpp b/code/divide_tree.cpp index 3ca7153..4f12bd6 100644 --- a/code/divide_tree.cpp +++ b/code/divide_tree.cpp @@ -28,6 +28,7 @@ #include "island_tree.h" #include "kml_writer.h" #include "kml_writer_2.h" +#include "text_writer.h" #include "line_tree.h" #include "util.h" @@ -1068,3 +1069,109 @@ std::string DivideTree::getAsKmlWithPopups() const return writer.finish(); } + +string DivideTree::getAsText() const { + TextWriter writer(mCoordinateSystem); + + int index; + + // Peaks + writer.startFolder("Peaks", mPeaks.size()); + index = 0; + for (const Peak &peak : mPeaks) { + writer.addPeak(peak, std::to_string(index)); + index += 1; + } + writer.endFolder(); + + unsigned int numPromSaddles = 0; + unsigned int numBasinSaddles = 0; + for (const Saddle &saddle : mSaddles) { + switch (saddle.type) { + case Saddle::Type::PROM: + numPromSaddles++; + break; + case Saddle::Type::BASIN: + numBasinSaddles++; + break; + } + } + + + // Prom saddles + writer.startFolder("PromSaddles", numPromSaddles); + std::vector promSaddleId(mSaddles.size(), -1); + index = 0; + int idSaddle = 0; + for (const Saddle &saddle : mSaddles) { + if (saddle.type == Saddle::Type::PROM) { + promSaddleId[index] = idSaddle; + writer.addPromSaddle(saddle, std::to_string(idSaddle)); + idSaddle += 1; + } + index += 1; + } + writer.endFolder(); + + // Basin saddles + writer.startFolder("BasinSaddles", numBasinSaddles); + std::vector basinSaddleId(mSaddles.size(), -1); + index = 0; + idSaddle = 0; + for (const Saddle &saddle : mSaddles) { + if (saddle.type == Saddle::Type::BASIN) { + basinSaddleId[index] = idSaddle; + writer.addBasinSaddle(saddle, std::to_string(index)); + idSaddle += 1; + } + index += 1; + } + writer.endFolder(); + + + // Runoffs + writer.startFolder("Runoffs", mRunoffs.size()); + index = 0; + for (const Runoff &runoff : mRunoffs) { + writer.addRunoff(runoff, std::to_string(index)); + index += 1; + } + writer.endFolder(); + + + // Graph edges + int numEdges = 0; + for (const Node &node : mNodes) { + if (node.saddleId != Node::Null && node.saddleId >= 0 && promSaddleId[node.saddleId] >= 0) { + numEdges++; + } + } + writer.startFolder("Edges", numEdges); + index = 0; + for (const Node &node : mNodes) { + if (node.saddleId != Node::Null && node.saddleId >= 0 && promSaddleId[node.saddleId] >= 0) { + writer.addGraphEdge(getPeak(index), getPeak(node.parentId), getSaddle(node.saddleId), + std::to_string(index), std::to_string(node.parentId), + std::to_string(promSaddleId[node.saddleId])); + } + index += 1; + } + + // Runoff edges + int numRunoffEdges = 0; + for (int i = 0; i < (int)mRunoffEdges.size(); ++i) { + if (mRunoffEdges[i] != Node::Null) { + numRunoffEdges++; + } + } + writer.startFolder("RunoffEdges", numRunoffEdges); + for (int i = 0; i < (int)mRunoffEdges.size(); ++i) { + if (mRunoffEdges[i] != Node::Null) { + writer.addRunoffEdge(getPeak(mRunoffEdges[i]), mRunoffs[i], std::to_string(mRunoffEdges[i]), std::to_string(i)); + } + } + writer.endFolder(); + + return writer.finish(); +} + diff --git a/code/divide_tree.h b/code/divide_tree.h index 250aa2d..04b5de8 100644 --- a/code/divide_tree.h +++ b/code/divide_tree.h @@ -105,6 +105,7 @@ class DivideTree { std::string getAsKml() const; std::string getAsKmlWithPopups() const; + std::string getAsText() const; const CoordinateSystem &coordinateSystem() const; const std::vector &peaks() const; diff --git a/code/makefile.win b/code/makefile.win index ed5aba0..1bdfa87 100644 --- a/code/makefile.win +++ b/code/makefile.win @@ -86,6 +86,7 @@ PROMINENCE_OBJS = \ $(OUTDIR)/island_tree.obj \ $(OUTDIR)/kml_writer.obj \ $(OUTDIR)/kml_writer_2.obj \ + $(OUTDIR)/text_writer.obj \ $(OUTDIR)/latlng.obj \ $(OUTDIR)/line_tree.obj \ $(OUTDIR)/peakbagger_collection.obj \ @@ -106,6 +107,7 @@ MERGE_DIVIDE_TREES_OBJS = \ $(OUTDIR)/island_tree.obj \ $(OUTDIR)/kml_writer.obj \ $(OUTDIR)/kml_writer_2.obj \ + $(OUTDIR)/text_writer.obj \ $(OUTDIR)/latlng.obj \ $(OUTDIR)/line_tree.obj \ $(OUTDIR)/merge_divide_trees.obj \ @@ -129,6 +131,7 @@ DEM_METRICS_OBJS = \ $(OUTDIR)/isolation_results.obj \ $(OUTDIR)/kml_writer.obj \ $(OUTDIR)/kml_writer_2.obj \ + $(OUTDIR)/text_writer.obj \ $(OUTDIR)/latlng.obj \ $(OUTDIR)/line_tree.obj \ $(OUTDIR)/peakbagger_point.obj \ diff --git a/code/text_writer.cpp b/code/text_writer.cpp new file mode 100644 index 0000000..8bc94bd --- /dev/null +++ b/code/text_writer.cpp @@ -0,0 +1,96 @@ +/* + * Oscar Argudo: adapted from Andrew Kirmse kml_writer.cpp + */ + +#include "text_writer.h" + +using std::string; + +TextWriter::TextWriter(const CoordinateSystem &coords) + : mCoords(coords) { +} + +void TextWriter::startFolder(const std::string &name, unsigned int numElements) { + mTxt += name + " " + std::to_string(numElements) + "\n"; +} + +void TextWriter::endFolder() { +} + +void TextWriter::addPeak(const Peak &peak, const std::string &name) { + LatLng peakpos = mCoords.getLatLng(peak.location); + mTxt += name + " "; + mTxt += std::to_string(peakpos.longitude()); + mTxt += " "; + mTxt += std::to_string(peakpos.latitude()); + mTxt += " "; + mTxt += std::to_string(peak.elevation); + mTxt += " "; + mTxt += std::to_string(peak.location.x()); + mTxt += " "; + mTxt += std::to_string(peak.location.y()); + mTxt += "\n"; +} + +void TextWriter::addPromSaddle(const Saddle &saddle, const std::string &name) { + addSaddle(saddle, "#saddle", name); +} + +void TextWriter::addBasinSaddle(const Saddle &saddle, const std::string &name) { + addSaddle(saddle, "#basinsaddle", name); +} + +void TextWriter::addSaddle(const Saddle &saddle, const char *styleUrl, const string &name) { + LatLng saddlepos = mCoords.getLatLng(saddle.location); + mTxt += name + " "; + mTxt += std::to_string(saddlepos.longitude()); + mTxt += " "; + mTxt += std::to_string(saddlepos.latitude()); + mTxt += " "; + mTxt += std::to_string(saddle.elevation); + mTxt += " "; + mTxt += std::to_string(saddle.location.x()); + mTxt += " "; + mTxt += std::to_string(saddle.location.y()); + mTxt += "\n"; +} + +void TextWriter::addRunoff(const Runoff &runoff, const std::string &name) { + LatLng pos = mCoords.getLatLng(runoff.location); + mTxt += name + " "; + mTxt += std::to_string(pos.longitude()); + mTxt += " "; + mTxt += std::to_string(pos.latitude()); + mTxt += " "; + mTxt += std::to_string(runoff.elevation); + mTxt += " "; + mTxt += std::to_string(runoff.location.x()); + mTxt += " "; + mTxt += std::to_string(runoff.location.y()); + mTxt += "\n"; +} + +void TextWriter::addGraphEdge(const Peak &peak1, const Peak &peak2, const Saddle &saddle, + const std::string& peakName, const std::string& parentName, const std::string& saddleName) { + LatLng peak1pos = mCoords.getLatLng(peak1.location); + LatLng saddlepos = mCoords.getLatLng(saddle.location); + LatLng peak2pos = mCoords.getLatLng(peak2.location); + + mTxt += peakName + " " + parentName + " " + saddleName + "\n"; +} + +void TextWriter::addRunoffEdge(const Peak &peak, const Runoff &runoff, const std::string& peakName, const std::string& runoffName) { + LatLng peakpos = mCoords.getLatLng(peak.location); + LatLng runoffpos = mCoords.getLatLng(runoff.location); + + mTxt += peakName + " " + runoffName + "\n"; +} + +void TextWriter::addPeakEdge(const Peak &peak1, const Peak &peak2, const std::string& peakName1, const std::string& peakName2) { + mTxt += peakName1 + " " + peakName2 + "\n"; +} + +string TextWriter::finish() { + return mTxt; +} + diff --git a/code/text_writer.h b/code/text_writer.h new file mode 100644 index 0000000..4d49069 --- /dev/null +++ b/code/text_writer.h @@ -0,0 +1,44 @@ +/* + * Oscar Argudo: adapted from Andrew Kirmse kml_writer.h + */ + + +#ifndef _TEXT_WRITER_H_ +#define _TEXT_WRITER_H_ + +// Utilities for building up the divide tree as text + +#include "primitives.h" +#include "coordinate_system.h" + +#include + +class TextWriter { +public: + + // Coordinate system is used to convert offsets to lat/lngs + explicit TextWriter(const CoordinateSystem &coords); + + void startFolder(const std::string &name, unsigned int numElements); + void endFolder(); + + void addPeak(const Peak &peak, const std::string &name); + void addRunoff(const Runoff &runoff, const std::string &name); + void addPromSaddle(const Saddle &saddle, const std::string &name); + void addBasinSaddle(const Saddle &saddle, const std::string &name); + + void addGraphEdge(const Peak &peak1, const Peak &peak2, const Saddle &saddle, const std::string& peakName, const std::string& parentName, const std::string& saddleName); + void addRunoffEdge(const Peak &peak, const Runoff &runoff, const std::string& peakName, const std::string& runoffName); + void addPeakEdge(const Peak &peak1, const Peak &peak2, const std::string& peakName1, const std::string& peakName2); + + // End document and return KML + std::string finish(); + +private: + const CoordinateSystem &mCoords; + std::string mTxt; + + void addSaddle(const Saddle &saddle, const char *styleUrl, const std::string &name); +}; + +#endif // ifndef _KML_WRITER_H_