Skip to content

Commit 303f541

Browse files
authored
Add exportCoordinates function to Graph class (#214)
* Add `exportCoordinates` function to Graph class * Add csv file for tests * Update version
1 parent 6f79569 commit 303f541

File tree

5 files changed

+81
-14
lines changed

5 files changed

+81
-14
lines changed

src/dsm/dsm.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
static constexpr uint8_t DSM_VERSION_MAJOR = 2;
88
static constexpr uint8_t DSM_VERSION_MINOR = 1;
9-
static constexpr uint8_t DSM_VERSION_PATCH = 4;
9+
static constexpr uint8_t DSM_VERSION_PATCH = 5;
1010

1111
#define DSM_VERSION \
1212
std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH)

src/dsm/headers/Graph.cpp

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,7 @@ namespace dsm {
220220
if (fileExt == "dsm") {
221221
// first input number is the number of nodes
222222
std::ifstream file{fileName};
223-
if (!file.is_open()) {
224-
throw std::invalid_argument(buildLog("Cannot find file: " + fileName));
225-
}
223+
assert((void("Coordinates file not found."), file.is_open()));
226224
Size n;
227225
file >> n;
228226
if (n < m_nodes.size()) {
@@ -236,6 +234,33 @@ namespace dsm {
236234
m_nodes[i]->setCoords(std::make_pair(lat, lon));
237235
}
238236
}
237+
} else if (fileExt == "csv") {
238+
std::ifstream ifs{fileName};
239+
assert((void("Coordinates file not found."), ifs.is_open()));
240+
// Check if the first line is nodeId;lat;lon
241+
std::string line;
242+
std::getline(ifs, line);
243+
assert((void("Invalid file format."), line == "nodeId;lat;lon"));
244+
double dLat, dLon;
245+
while (!ifs.eof()) {
246+
std::getline(ifs, line);
247+
if (line.empty()) {
248+
continue;
249+
}
250+
std::istringstream iss{line};
251+
std::string nodeId, lat, lon;
252+
std::getline(iss, nodeId, ';');
253+
std::getline(iss, lat, ';');
254+
std::getline(iss, lon, '\n');
255+
dLat = lat == "Nan" ? 0. : std::stod(lat);
256+
dLon = lon == "Nan" ? 0. : std::stod(lon);
257+
if (m_nodes.contains(std::stoul(nodeId))) {
258+
m_nodes[std::stoul(nodeId)]->setCoords(std::make_pair(dLat, dLon));
259+
} else {
260+
std::cerr << std::format("WARNING: Node with id {} not found.", nodeId)
261+
<< std::endl;
262+
}
263+
}
239264
} else {
240265
throw std::invalid_argument(buildLog("File extension not supported."));
241266
}
@@ -361,6 +386,25 @@ namespace dsm {
361386
}
362387
}
363388

389+
void Graph::exportCoordinates(std::string const& path) {
390+
// assert that path ends with ".csv"
391+
assert((void("Only csv export is supported."),
392+
path.substr(path.find_last_of(".")) == ".csv"));
393+
std::ofstream file{path};
394+
// Column names
395+
file << "nodeId;lat;lon\n";
396+
for (const auto& [id, node] : m_nodes) {
397+
file << id << ';';
398+
if (node->coords().has_value()) {
399+
file << node->coords().value().first << ';' << node->coords().value().second;
400+
} else {
401+
file << "Nan;Nan";
402+
}
403+
file << '\n';
404+
}
405+
file.close();
406+
}
407+
364408
void Graph::addNode(std::unique_ptr<Node> node) {
365409
m_nodes.emplace(std::make_pair(node->id(), std::move(node)));
366410
}

src/dsm/headers/Graph.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,13 @@ namespace dsm {
136136
void importOSMEdges(const std::string& fileName);
137137

138138
/// @brief Export the graph's adjacency matrix to a file
139-
/// @param path The path to the file to export the adjacency matrix to.
139+
/// @param path The path to the file to export the adjacency matrix to (default: ./matrix.dsm)
140140
/// @param isAdj A boolean value indicating if the file contains the adjacency matrix or the distance matrix.
141141
/// @throws std::invalid_argument if the file is not found or invalid
142142
void exportMatrix(std::string path = "./matrix.dsm", bool isAdj = true);
143+
/// @brief Export the nodes' coordinates to a file
144+
/// @param path The path to the file to export the nodes' coordinates to (default: ./nodes.dsm)
145+
void exportCoordinates(std::string const& path = "./coordinates.csv");
143146

144147
/// @brief Add a node to the graph
145148
/// @param node A std::unique_ptr to the node to add

test/Test_graph.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,31 @@ TEST_CASE("Graph") {
128128
CHECK(graph2.nodeSet().size() == 3);
129129
CHECK(graph2.streetSet().size() == 4);
130130
}
131-
SUBCASE("importCoordinates") {
132-
Graph graph{};
133-
CHECK_THROWS(graph.importCoordinates("./data/coords.txt"));
134-
graph.importMatrix("./data/matrix.dsm");
135-
graph.importCoordinates("./data/coords.dsm");
136-
const auto& nodes = graph.nodeSet();
137-
CHECK_EQ(nodes.at(0)->coords(), std::make_pair(0., 0.));
138-
CHECK_EQ(nodes.at(1)->coords(), std::make_pair(1., 0.));
139-
CHECK_EQ(nodes.at(2)->coords(), std::make_pair(2., 0.));
131+
SUBCASE("Coordinates import/export") {
132+
GIVEN("A Graph object with the adj matrix imported") {
133+
Graph graph{};
134+
graph.importMatrix("./data/matrix.dsm");
135+
auto const& nodes = graph.nodeSet();
136+
WHEN("We import the coordinates in dsm format") {
137+
graph.importCoordinates("./data/coords.dsm");
138+
THEN("The coordinates are correctly imported") {
139+
CHECK_EQ(nodes.at(0)->coords(), std::make_pair(0., 0.));
140+
CHECK_EQ(nodes.at(1)->coords(), std::make_pair(1., 0.));
141+
CHECK_EQ(nodes.at(2)->coords(), std::make_pair(2., 0.));
142+
}
143+
THEN("We are able to save coordinates in csv format") {
144+
graph.exportCoordinates("./data/coordinates.csv");
145+
}
146+
}
147+
WHEN("We import the coordinates in csv format") {
148+
graph.importCoordinates("./data/coordinates.csv");
149+
THEN("The coordinates are correctly imported") {
150+
CHECK_EQ(nodes.at(0)->coords(), std::make_pair(0., 0.));
151+
CHECK_EQ(nodes.at(1)->coords(), std::make_pair(1., 0.));
152+
CHECK_EQ(nodes.at(2)->coords(), std::make_pair(2., 0.));
153+
}
154+
}
155+
}
140156
}
141157
SUBCASE("importMatrix - raw matrix") {
142158
Graph graph{};

test/data/coordinates.csv

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
nodeId;lat;lon
2+
1;1;0
3+
0;0;0
4+
2;2;0

0 commit comments

Comments
 (0)