Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dsm/dsm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

static constexpr uint8_t DSM_VERSION_MAJOR = 2;
static constexpr uint8_t DSM_VERSION_MINOR = 1;
static constexpr uint8_t DSM_VERSION_PATCH = 4;
static constexpr uint8_t DSM_VERSION_PATCH = 5;

#define DSM_VERSION \
std::format("{}.{}.{}", DSM_VERSION_MAJOR, DSM_VERSION_MINOR, DSM_VERSION_PATCH)
Expand Down
50 changes: 47 additions & 3 deletions src/dsm/headers/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,7 @@
if (fileExt == "dsm") {
// first input number is the number of nodes
std::ifstream file{fileName};
if (!file.is_open()) {
throw std::invalid_argument(buildLog("Cannot find file: " + fileName));
}
assert((void("Coordinates file not found."), file.is_open()));
Size n;
file >> n;
if (n < m_nodes.size()) {
Expand All @@ -236,6 +234,33 @@
m_nodes[i]->setCoords(std::make_pair(lat, lon));
}
}
} else if (fileExt == "csv") {
std::ifstream ifs{fileName};
assert((void("Coordinates file not found."), ifs.is_open()));
// Check if the first line is nodeId;lat;lon
std::string line;
std::getline(ifs, line);
assert((void("Invalid file format."), line == "nodeId;lat;lon"));
double dLat, dLon;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
while (!ifs.eof()) {
std::getline(ifs, line);
if (line.empty()) {
continue;
}
std::istringstream iss{line};
std::string nodeId, lat, lon;

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
std::getline(iss, nodeId, ';');
std::getline(iss, lat, ';');
std::getline(iss, lon, '\n');
dLat = lat == "Nan" ? 0. : std::stod(lat);

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.1 rule Note

MISRA 12.1 rule
dLon = lon == "Nan" ? 0. : std::stod(lon);

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.1 rule Note

MISRA 12.1 rule
if (m_nodes.contains(std::stoul(nodeId))) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
m_nodes[std::stoul(nodeId)]->setCoords(std::make_pair(dLat, dLon));
} else {
std::cerr << std::format("WARNING: Node with id {} not found.", nodeId)
<< std::endl;
}
}
} else {
throw std::invalid_argument(buildLog("File extension not supported."));
}
Expand Down Expand Up @@ -361,6 +386,25 @@
}
}

void Graph::exportCoordinates(std::string const& path) {
// assert that path ends with ".csv"
assert((void("Only csv export is supported."),
path.substr(path.find_last_of(".")) == ".csv"));
std::ofstream file{path};
// Column names
file << "nodeId;lat;lon\n";
for (const auto& [id, node] : m_nodes) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 12.3 rule Note

MISRA 12.3 rule
file << id << ';';
if (node->coords().has_value()) {

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 14.4 rule Note

MISRA 14.4 rule
file << node->coords().value().first << ';' << node->coords().value().second;
} else {
file << "Nan;Nan";
}
file << '\n';

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 10.1 rule Note

MISRA 10.1 rule
}
file.close();
}

void Graph::addNode(std::unique_ptr<Node> node) {
m_nodes.emplace(std::make_pair(node->id(), std::move(node)));
}
Expand Down
5 changes: 4 additions & 1 deletion src/dsm/headers/Graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,13 @@
void importOSMEdges(const std::string& fileName);

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

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 17.8 rule Note

MISRA 17.8 rule

Check notice

Code scanning / Cppcheck (reported by Codacy)

MISRA 13.4 rule Note

MISRA 13.4 rule

/// @brief Add a node to the graph
/// @param node A std::unique_ptr to the node to add
Expand Down
34 changes: 25 additions & 9 deletions test/Test_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,31 @@ TEST_CASE("Graph") {
CHECK(graph2.nodeSet().size() == 3);
CHECK(graph2.streetSet().size() == 4);
}
SUBCASE("importCoordinates") {
Graph graph{};
CHECK_THROWS(graph.importCoordinates("./data/coords.txt"));
graph.importMatrix("./data/matrix.dsm");
graph.importCoordinates("./data/coords.dsm");
const auto& nodes = graph.nodeSet();
CHECK_EQ(nodes.at(0)->coords(), std::make_pair(0., 0.));
CHECK_EQ(nodes.at(1)->coords(), std::make_pair(1., 0.));
CHECK_EQ(nodes.at(2)->coords(), std::make_pair(2., 0.));
SUBCASE("Coordinates import/export") {
GIVEN("A Graph object with the adj matrix imported") {
Graph graph{};
graph.importMatrix("./data/matrix.dsm");
auto const& nodes = graph.nodeSet();
WHEN("We import the coordinates in dsm format") {
graph.importCoordinates("./data/coords.dsm");
THEN("The coordinates are correctly imported") {
CHECK_EQ(nodes.at(0)->coords(), std::make_pair(0., 0.));
CHECK_EQ(nodes.at(1)->coords(), std::make_pair(1., 0.));
CHECK_EQ(nodes.at(2)->coords(), std::make_pair(2., 0.));
}
THEN("We are able to save coordinates in csv format") {
graph.exportCoordinates("./data/coordinates.csv");
}
}
WHEN("We import the coordinates in csv format") {
graph.importCoordinates("./data/coordinates.csv");
THEN("The coordinates are correctly imported") {
CHECK_EQ(nodes.at(0)->coords(), std::make_pair(0., 0.));
CHECK_EQ(nodes.at(1)->coords(), std::make_pair(1., 0.));
CHECK_EQ(nodes.at(2)->coords(), std::make_pair(2., 0.));
}
}
}
}
SUBCASE("importMatrix - raw matrix") {
Graph graph{};
Expand Down
4 changes: 4 additions & 0 deletions test/data/coordinates.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
nodeId;lat;lon
1;1;0
0;0;0
2;2;0
Loading