Skip to content

Commit 5ce7a4a

Browse files
authored
Enhance OSM data I/O and management (#237)
* Enhance construction * Enhance osm I/O testing * Add filters for residential/motorways * Update utils Readme
1 parent 8592bb3 commit 5ce7a4a

File tree

7 files changed

+3797
-12313
lines changed

7 files changed

+3797
-12313
lines changed

src/dsm/headers/Graph.cpp

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,15 @@ namespace dsm {
252252
}
253253
} else if (fileExt == "csv") {
254254
std::ifstream ifs{fileName};
255-
assert((void("Coordinates file not found."), ifs.is_open()));
255+
if (!ifs.is_open()) {
256+
throw std::invalid_argument(buildLog("Cannot find file: " + fileName));
257+
}
256258
// Check if the first line is nodeId;lat;lon
257259
std::string line;
258260
std::getline(ifs, line);
259-
assert((void("Invalid file format."), line == "nodeId;lat;lon"));
261+
if (line != "nodeId;lat;lon") {
262+
throw std::invalid_argument(buildLog("Invalid file format."));
263+
}
260264
double dLat, dLon;
261265
while (!ifs.eof()) {
262266
std::getline(ifs, line);
@@ -304,10 +308,16 @@ namespace dsm {
304308
std::getline(iss, lat, ';');
305309
std::getline(iss, lon, ';');
306310
std::getline(iss, highway, ';');
307-
Id nodeId{static_cast<Id>(std::stoul(id))};
308-
m_nodes.emplace(nodeIndex,
309-
std::make_unique<Intersection>(
310-
nodeIndex, std::make_pair(std::stod(lat), std::stod(lon))));
311+
auto const nodeId{static_cast<Id>(std::stoul(id))};
312+
if (highway.find("traffic_signals") != std::string::npos) {
313+
addNode<TrafficLight>(
314+
nodeIndex, 60, std::make_pair(std::stod(lat), std::stod(lon)));
315+
} else if (highway.find("roundabout") != std::string::npos) {
316+
addNode<Roundabout>(nodeIndex, std::make_pair(std::stod(lat), std::stod(lon)));
317+
} else {
318+
addNode<Intersection>(nodeIndex,
319+
std::make_pair(std::stod(lat), std::stod(lon)));
320+
}
311321
m_nodeMapping.emplace(std::make_pair(nodeId, nodeIndex));
312322
++nodeIndex;
313323
}
@@ -321,9 +331,8 @@ namespace dsm {
321331
if (fileExt == "csv") {
322332
std::ifstream file{fileName};
323333
if (!file.is_open()) {
324-
std::string errrorMsg{"Error at line " + std::to_string(__LINE__) + " in file " +
325-
__FILE__ + ": " + "File not found"};
326-
throw std::invalid_argument(errrorMsg);
334+
throw std::invalid_argument(
335+
buildLog(std::format("File \'{}\' not found", fileName)));
327336
}
328337
std::string line;
329338
std::getline(file, line); // skip first line
@@ -333,54 +342,48 @@ namespace dsm {
333342
continue;
334343
}
335344
std::istringstream iss{line};
336-
std::string sourceId, targetId, length, oneway, lanes, highway, maxspeed, bridge;
337-
// u;v;length;oneway;highway;maxspeed;bridge
345+
std::string sourceId, targetId, length, oneway, lanes, highway, maxspeed, name;
346+
// u;v;length;oneway;highway;maxspeed;name
338347
std::getline(iss, sourceId, ';');
339348
std::getline(iss, targetId, ';');
340349
std::getline(iss, length, ';');
341350
std::getline(iss, oneway, ';');
342351
std::getline(iss, lanes, ';');
343352
std::getline(iss, highway, ';');
344353
std::getline(iss, maxspeed, ';');
345-
std::getline(iss, bridge, ';');
346-
try {
347-
std::stod(maxspeed);
348-
} catch (const std::invalid_argument& e) {
349-
maxspeed = "30";
354+
std::getline(iss, name, ';');
355+
if (maxspeed.empty()) {
356+
maxspeed = "30"; // Default to 30 km/h if no maxspeed is provided
357+
} else {
358+
try {
359+
std::stod(maxspeed);
360+
} catch (const std::invalid_argument& e) {
361+
maxspeed = "30"; // Default to 30 km/h if maxspeed is invalid
362+
}
350363
}
351364

352-
uint8_t numLanes;
353365
if (lanes.empty()) {
354-
numLanes = 1; // Default to 1 lane if no value is provided
366+
lanes = "1"; // Default to 1 lane if no value is provided
355367
} else {
356368
try {
357-
// Convert lanes to a double first, then cast to uint8_t
358-
double lanesVal = std::stod(lanes);
359-
if (lanesVal < 1 || std::isnan(lanesVal)) {
360-
numLanes = 1; // Default to 1 if lanes is invalid
361-
} else {
362-
numLanes = static_cast<uint8_t>(lanesVal); // Cast to uint8_t
363-
}
364-
} catch (const std::invalid_argument&) {
365-
numLanes = 1; // Default to 1 if conversion fails
369+
std::stoul(lanes);
370+
} catch (const std::invalid_argument& e) {
371+
lanes = "1"; // Default to 1 lane if lanes is invalid
366372
}
367373
}
368374

369375
Id streetId = std::stoul(sourceId) + std::stoul(targetId) * m_nodes.size();
370-
m_streets.emplace(
371-
streetId,
372-
std::make_unique<Street>(streetId,
373-
1,
374-
std::stod(maxspeed),
375-
std::stod(length),
376-
std::make_pair(m_nodeMapping[std::stoul(sourceId)],
377-
m_nodeMapping[std::stoul(targetId)]),
378-
numLanes));
376+
addEdge<Street>(streetId,
377+
std::stod(length) / 5,
378+
std::stod(maxspeed),
379+
std::stod(length),
380+
std::make_pair(m_nodeMapping[std::stoul(sourceId)],
381+
m_nodeMapping[std::stoul(targetId)]),
382+
std::stoul(lanes),
383+
name);
379384
}
380385
} else {
381-
std::string errrorMsg{"Error at line " + std::to_string(__LINE__) + " in file " +
382-
__FILE__ + ": " + "File extension not supported"};
383-
throw std::invalid_argument(errrorMsg);
386+
throw std::invalid_argument(buildLog("File extension not supported"));
384387
}
385388
}
386389

src/dsm/headers/TrafficLight.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ namespace dsm {
5252
TrafficLight(Id id, Delay cycleTime)
5353
: Intersection{id}, m_cycleTime{cycleTime}, m_counter{0} {}
5454

55+
TrafficLight(Id id, Delay cycleTime, std::pair<double, double> coords)
56+
: Intersection{id, std::move(coords)}, m_cycleTime{cycleTime}, m_counter{0} {}
57+
5558
TrafficLight(Node const& node, Delay const cycleTime, Delay const counter = 0)
5659
: Intersection{node}, m_cycleTime{cycleTime}, m_counter{counter} {}
5760

test/Test_graph.cpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,25 +186,53 @@ TEST_CASE("Graph") {
186186
WHEN("We import nodes and edges from OSM") {
187187
graph.importOSMNodes("./data/nodes.csv");
188188
graph.importOSMEdges("./data/edges.csv");
189+
std::ifstream fNodes{"./data/nodes.csv"};
190+
// get number of lines
191+
std::string line;
192+
int nNodes{-1}; // -1 because of the header
193+
while (std::getline(fNodes, line)) {
194+
++nNodes;
195+
}
196+
fNodes.close();
197+
std::ifstream fEdges{"./data/edges.csv"};
198+
int nEdges{-1}; // -1 because of the header
199+
while (std::getline(fEdges, line)) {
200+
++nEdges;
201+
}
202+
fEdges.close();
189203
THEN("Sizes are correct") {
190-
CHECK_EQ(graph.nNodes(), 25);
191-
CHECK_EQ(graph.nEdges(), 60);
204+
CHECK_EQ(graph.nNodes(), nNodes);
205+
CHECK_EQ(graph.nEdges(), nEdges);
192206
}
193207
THEN("We are able to build the adjacency matrix") {
194208
graph.buildAdj();
195-
CHECK_EQ(graph.adjMatrix().size(), 60);
209+
CHECK_EQ(graph.adjMatrix().size(), nEdges);
196210
}
197211
}
198212
WHEN("We import many nodes and edges from OSM") {
199213
graph.importOSMNodes("./data/nodes_big.csv");
200214
graph.importOSMEdges("./data/edges_big.csv");
215+
std::ifstream fNodes{"./data/nodes_big.csv"};
216+
// get number of lines
217+
std::string line;
218+
int nNodes{-1}; // -1 because of the header
219+
while (std::getline(fNodes, line)) {
220+
++nNodes;
221+
}
222+
fNodes.close();
223+
std::ifstream fEdges{"./data/edges_big.csv"};
224+
int nEdges{-1}; // -1 because of the header
225+
while (std::getline(fEdges, line)) {
226+
++nEdges;
227+
}
228+
fEdges.close();
201229
THEN("Sizes are correct") {
202-
CHECK_EQ(graph.nNodes(), 4077);
203-
CHECK_EQ(graph.nEdges(), 8875);
230+
CHECK_EQ(graph.nNodes(), nNodes);
231+
CHECK_EQ(graph.nEdges(), nEdges);
204232
}
205233
THEN("We are able to build the adjacency matrix") {
206234
graph.buildAdj();
207-
CHECK_EQ(graph.adjMatrix().size(), 8875);
235+
CHECK_EQ(graph.adjMatrix().size(), nEdges);
208236
}
209237
}
210238
}

0 commit comments

Comments
 (0)