add -W [ --warn ] flag to output warning messages, update cppgtfs

This commit is contained in:
Patrick Brosi 2024-01-30 12:51:22 +01:00
parent a078b22e18
commit ad0252695f
6 changed files with 79 additions and 27 deletions

@ -1 +1 @@
Subproject commit 520be35426083e96e6adc0d1a7915c9640b1f4e3 Subproject commit 7496330a36bdfa7a3cdacff26d785a0607e63328

View file

@ -86,6 +86,9 @@ enum class RetCode {
std::string getFileNameMotStr(const MOTs& mots); std::string getFileNameMotStr(const MOTs& mots);
std::vector<std::string> getCfgPaths(const Config& cfg); std::vector<std::string> getCfgPaths(const Config& cfg);
// _____________________________________________________________________________
void gtfsWarnCb(std::string msg) { LOG(WARN) << msg; }
// _____________________________________________________________________________ // _____________________________________________________________________________
int main(int argc, char** argv) { int main(int argc, char** argv) {
// disable output buffering for standard output // disable output buffering for standard output
@ -136,7 +139,8 @@ int main(int argc, char** argv) {
LOG(INFO) << "Reading GTFS feed " << cfg.feedPaths[0] << " ..."; LOG(INFO) << "Reading GTFS feed " << cfg.feedPaths[0] << " ...";
try { try {
ad::cppgtfs::Parser p(cfg.feedPaths[0], false, ad::cppgtfs::Parser p(cfg.feedPaths[0], false,
cfg.parseAdditionalGTFSFields); cfg.parseAdditionalGTFSFields,
cfg.verbosity ? gtfsWarnCb : 0);
p.parse(&gtfs[0]); p.parse(&gtfs[0]);
} catch (const ad::cppgtfs::ParserException& ex) { } catch (const ad::cppgtfs::ParserException& ex) {
LOG(ERROR) << "Could not parse input GTFS feed, reason was:"; LOG(ERROR) << "Could not parse input GTFS feed, reason was:";
@ -193,7 +197,7 @@ int main(int argc, char** argv) {
for (size_t i = 0; i < cfg.feedPaths.size(); i++) { for (size_t i = 0; i < cfg.feedPaths.size(); i++) {
ShapeBuilder::getGtfsBox(&gtfs[i], cmdCfgMots, cfg.shapeTripId, true, ShapeBuilder::getGtfsBox(&gtfs[i], cmdCfgMots, cfg.shapeTripId, true,
&box, maxSpeed, 0); &box, maxSpeed, 0, cfg.verbosity);
} }
OsmBuilder osmBuilder; OsmBuilder osmBuilder;
std::vector<pfaedle::osm::OsmReadOpts> opts; std::vector<pfaedle::osm::OsmReadOpts> opts;
@ -215,7 +219,7 @@ int main(int argc, char** argv) {
BBoxIdx box(BOX_PADDING); BBoxIdx box(BOX_PADDING);
for (size_t i = 0; i < cfg.feedPaths.size(); i++) { for (size_t i = 0; i < cfg.feedPaths.size(); i++) {
ShapeBuilder::getGtfsBox(&gtfs[i], cmdCfgMots, cfg.shapeTripId, true, ShapeBuilder::getGtfsBox(&gtfs[i], cmdCfgMots, cfg.shapeTripId, true,
&box, maxSpeed, 0); &box, maxSpeed, 0, cfg.verbosity);
} }
OsmBuilder osmBuilder; OsmBuilder osmBuilder;
std::vector<pfaedle::osm::OsmReadOpts> opts; std::vector<pfaedle::osm::OsmReadOpts> opts;
@ -270,9 +274,9 @@ int main(int argc, char** argv) {
pfaedle::osm::OsmBuilder osmBuilder; pfaedle::osm::OsmBuilder osmBuilder;
pfaedle::osm::BBoxIdx box(BOX_PADDING); pfaedle::osm::BBoxIdx box(BOX_PADDING);
ShapeBuilder::getGtfsBox(&gtfs[0], usedMots, cfg.shapeTripId, ShapeBuilder::getGtfsBox(
cfg.dropShapes, &box, &gtfs[0], usedMots, cfg.shapeTripId, cfg.dropShapes, &box,
motCfg.osmBuildOpts.maxSpeed, &hopDists); motCfg.osmBuildOpts.maxSpeed, &hopDists, cfg.verbosity);
T_START(osmBuild); T_START(osmBuild);

View file

@ -111,6 +111,8 @@ void ConfigReader::help(const char* bin) {
<< "Disable hop cache \n" << "Disable hop cache \n"
<< std::setw(35) << " --stats" << std::setw(35) << " --stats"
<< "write stats to stats.json\n" << "write stats to stats.json\n"
<< std::setw(35) << " -W [ --warn ]"
<< "enable verbose warning messages\n"
<< std::setw(35) << " -P" << std::setw(35) << " -P"
<< "additional parameter string (in cfg file format)\n"; << "additional parameter string (in cfg file format)\n";
} }
@ -144,11 +146,12 @@ void ConfigReader::read(Config* cfg, int argc, char** argv) {
{"stats", no_argument, 0, 14}, {"stats", no_argument, 0, 14},
{"no-hop-cache", no_argument, 0, 15}, {"no-hop-cache", no_argument, 0, 15},
{"gaussian-noise", required_argument, 0, 16}, {"gaussian-noise", required_argument, 0, 16},
{"warn", no_argument, 0, 'W'},
{"keep-additional-gtfs-fields", no_argument, 0, 'F'}, {"keep-additional-gtfs-fields", no_argument, 0, 'F'},
{0, 0, 0, 0}}; {0, 0, 0, 0}};
int c; int c;
while ((c = getopt_long(argc, argv, ":o:hvi:c:x:Dm:g:X:T:d:pP:F", ops, 0)) != while ((c = getopt_long(argc, argv, ":o:hvi:c:x:Dm:g:X:T:d:pP:FW", ops, 0)) !=
-1) { -1) {
switch (c) { switch (c) {
case 1: case 1:
@ -220,6 +223,9 @@ void ConfigReader::read(Config* cfg, int argc, char** argv) {
case 16: case 16:
cfg->gaussianNoise = atof(optarg); cfg->gaussianNoise = atof(optarg);
break; break;
case 'W':
cfg->verbosity = 1;
break;
case 'F': case 'F':
cfg->parseAdditionalGTFSFields = true; cfg->parseAdditionalGTFSFields = true;
break; break;

View file

@ -39,7 +39,8 @@ struct Config {
writeStats(false), writeStats(false),
parseAdditionalGTFSFields(false), parseAdditionalGTFSFields(false),
gridSize(2000 / util::geo::M_PER_DEG), gridSize(2000 / util::geo::M_PER_DEG),
gaussianNoise(0) {} gaussianNoise(0),
verbosity(0) {}
std::string dbgOutputPath; std::string dbgOutputPath;
std::string solveMethod; std::string solveMethod;
std::string shapeTripId; std::string shapeTripId;
@ -67,6 +68,7 @@ struct Config {
bool parseAdditionalGTFSFields; bool parseAdditionalGTFSFields;
double gridSize; double gridSize;
double gaussianNoise; double gaussianNoise;
uint8_t verbosity;
std::string toString() { std::string toString() {
std::stringstream ss; std::stringstream ss;
@ -88,6 +90,7 @@ struct Config {
<< "no-a-star: " << noAStar << "\n" << "no-a-star: " << noAStar << "\n"
<< "no-trie: " << noTrie << "\n" << "no-trie: " << noTrie << "\n"
<< "no-hop-cache: " << noHopCache << "\n" << "no-hop-cache: " << noHopCache << "\n"
<< "verbosity: " << verbosity << "\n"
<< "parse-additional-gtfs-fields: " << parseAdditionalGTFSFields << "\n" << "parse-additional-gtfs-fields: " << parseAdditionalGTFSFields << "\n"
<< "write-stats: " << writeStats << "\n" << "write-stats: " << writeStats << "\n"
<< "feed-paths: "; << "feed-paths: ";

View file

@ -73,7 +73,7 @@ ShapeBuilder::ShapeBuilder(
_router(router) { _router(router) {
pfaedle::osm::BBoxIdx box(BOX_PADDING); pfaedle::osm::BBoxIdx box(BOX_PADDING);
ShapeBuilder::getGtfsBox(feed, mots, cfg.shapeTripId, cfg.dropShapes, &box, ShapeBuilder::getGtfsBox(feed, mots, cfg.shapeTripId, cfg.dropShapes, &box,
_motCfg.osmBuildOpts.maxSpeed, 0); _motCfg.osmBuildOpts.maxSpeed, 0, cfg.verbosity);
_eGrid = EdgeGrid(cfg.gridSize, cfg.gridSize, box.getFullBox(), false); _eGrid = EdgeGrid(cfg.gridSize, cfg.gridSize, box.getFullBox(), false);
_nGrid = NodeGrid(cfg.gridSize, cfg.gridSize, box.getFullBox(), false); _nGrid = NodeGrid(cfg.gridSize, cfg.gridSize, box.getFullBox(), false);
@ -270,6 +270,11 @@ EdgeCandGroup ShapeBuilder::getEdgCands(const Stop* s) const {
{}}); {}});
} }
if (ret.size() == 1 && _cfg.verbosity) {
LOG(WARN) << "No snapping candidate found for stop '" << s->getName()
<< "' (" << s->getId() << ")";
}
return ret; return ret;
} }
@ -321,7 +326,7 @@ std::pair<std::vector<LINE>, Stats> ShapeBuilder::shapeL(Trip* trip) {
LOG(INFO) << "Matched 1 trip in " << std::fixed << std::setprecision(2) LOG(INFO) << "Matched 1 trip in " << std::fixed << std::setprecision(2)
<< stats.solveTime << " ms."; << stats.solveTime << " ms.";
// print to line // print to line
return {getGeom(hops, getRAttrs(trip), &colors), stats}; return {getGeom(hops, getRAttrs(trip), &colors, trip, 1), stats};
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
LOG(ERROR) << e.what(); LOG(ERROR) << e.what();
return {std::vector<LINE>(), stats}; return {std::vector<LINE>(), stats};
@ -558,15 +563,16 @@ void ShapeBuilder::setShape(Trip* t, const ad::cppgtfs::gtfs::Shape& s,
// _____________________________________________________________________________ // _____________________________________________________________________________
ad::cppgtfs::gtfs::Shape ShapeBuilder::getGtfsShape( ad::cppgtfs::gtfs::Shape ShapeBuilder::getGtfsShape(
const EdgeListHops& hops, Trip* t, const RoutingAttrs& rAttrs, const EdgeListHops& hops, Trip* t, size_t numOthers,
std::vector<float>* hopDists, uint32_t* bestColor) { const RoutingAttrs& rAttrs, std::vector<float>* hopDists,
uint32_t* bestColor) {
ad::cppgtfs::gtfs::Shape ret(getFreeShapeId(t)); ad::cppgtfs::gtfs::Shape ret(getFreeShapeId(t));
assert(hops.size() == t->getStopTimes().size() - 1); assert(hops.size() == t->getStopTimes().size() - 1);
std::map<uint32_t, double> colors; std::map<uint32_t, double> colors;
const std::vector<LINE>& gl = getGeom(hops, rAttrs, &colors); const std::vector<LINE>& gl = getGeom(hops, rAttrs, &colors, t, numOthers);
const std::vector<float>& measures = getMeasure(gl); const std::vector<float>& measures = getMeasure(gl);
size_t seq = 0; size_t seq = 0;
@ -651,7 +657,8 @@ const RoutingAttrs& ShapeBuilder::getRAttrs(const Trip* trip) const {
void ShapeBuilder::getGtfsBox(const Feed* feed, const MOTs& mots, void ShapeBuilder::getGtfsBox(const Feed* feed, const MOTs& mots,
const std::string& tid, bool dropShapes, const std::string& tid, bool dropShapes,
osm::BBoxIdx* box, double maxSpeed, osm::BBoxIdx* box, double maxSpeed,
std::vector<double>* hopDists) { std::vector<double>* hopDists,
uint8_t verbosity) {
for (const auto& t : feed->getTrips()) { for (const auto& t : feed->getTrips()) {
if (!tid.empty() && t.getId() != tid) continue; if (!tid.empty() && t.getId() != tid) continue;
if (tid.empty() && !t.getShape().empty() && !dropShapes) continue; if (tid.empty() && !t.getShape().empty() && !dropShapes) continue;
@ -695,11 +702,21 @@ void ShapeBuilder::getGtfsBox(const Feed* feed, const MOTs& mots,
if (reqToTime > (BUFFER + toTime) * 3 * MAX_ROUTE_COST_DOUBLING_STEPS && if (reqToTime > (BUFFER + toTime) * 3 * MAX_ROUTE_COST_DOUBLING_STEPS &&
reqFromTime > reqFromTime >
(BUFFER + fromTime) * 3 * MAX_ROUTE_COST_DOUBLING_STEPS) { (BUFFER + fromTime) * 3 * MAX_ROUTE_COST_DOUBLING_STEPS) {
LOG(DEBUG) << "Skipping station " << st.getStop()->getId() << " (" if (verbosity) {
<< st.getStop()->getName() << ") @ " LOG(WARN)
<< st.getStop()->getLat() << ", " << st.getStop()->getLng() << "Skipping station '" << st.getStop()->getName() << "' ("
<< st.getStop()->getId() << ") @ " << st.getStop()->getLat()
<< ", " << st.getStop()->getLng()
<< " for bounding box as the vehicle cannot realistically " << " for bounding box as the vehicle cannot realistically "
"reach and leave it in the scheduled time"; "reach and leave it in the scheduled time";
} else {
LOG(DEBUG)
<< "Skipping station '" << st.getStop()->getName() << "' ("
<< st.getStop()->getId() << ") @ " << st.getStop()->getLat()
<< ", " << st.getStop()->getLng()
<< " for bounding box as the vehicle cannot realistically "
"reach and leave it in the scheduled time";
}
continue; continue;
} }
@ -954,9 +971,10 @@ void ShapeBuilder::buildNetGraph(TrGraphEdgs* edgs,
} }
// _____________________________________________________________________________ // _____________________________________________________________________________
std::vector<LINE> ShapeBuilder::getGeom( std::vector<LINE> ShapeBuilder::getGeom(const EdgeListHops& hops,
const EdgeListHops& hops, const RoutingAttrs& rAttrs, const RoutingAttrs& rAttrs,
std::map<uint32_t, double>* colors) const { std::map<uint32_t, double>* colors,
Trip* t, size_t numOthers) const {
std::vector<LINE> ret; std::vector<LINE> ret;
for (size_t i = hops.size(); i > 0; i--) { for (size_t i = hops.size(); i > 0; i--) {
@ -964,6 +982,23 @@ std::vector<LINE> ShapeBuilder::getGeom(
if (!hop.start || !hop.end) { if (!hop.start || !hop.end) {
// no hop was found, use the fallback geometry // no hop was found, use the fallback geometry
if (_cfg.verbosity) {
const auto stopFr = t->getStopTimes()[hops.size() - i].getStop();
const auto stopTo = t->getStopTimes()[hops.size() - i + 1].getStop();
LOG(WARN) << "No viable hop found between stops '" << stopFr->getName()
<< "' (" << stopFr->getId() << ") and '" << stopTo->getName()
<< "' (" << stopTo->getId() << ") for trip " << t->getId()
<< " of type '"
<< ad::cppgtfs::gtfs::flat::Route::getTypeString(
t->getRoute()->getType())
<< "'"
<< (numOthers > 1 ? " (and " + std::to_string(numOthers) +
" similar trips)"
: "")
<< ", falling back to straight line";
}
if (hop.start) { if (hop.start) {
if (hop.progrStart > 0) { if (hop.progrStart > 0) {
auto l = getLine(hop.start); auto l = getLine(hop.start);
@ -1159,8 +1194,9 @@ void ShapeBuilder::shapeWorker(
uint32_t color; uint32_t color;
const ad::cppgtfs::gtfs::Shape& shp = getGtfsShape( const ad::cppgtfs::gtfs::Shape& shp =
hops.at(leaf.first), leaf.second[0], rAttrs, &distances, &color); getGtfsShape(hops.at(leaf.first), leaf.second[0],
leaf.second.size(), rAttrs, &distances, &color);
if (_cfg.buildTransitGraph) { if (_cfg.buildTransitGraph) {
writeTransitGraph(hops.at(leaf.first), gtfsGraph, leaf.second); writeTransitGraph(hops.at(leaf.first), gtfsGraph, leaf.second);

View file

@ -12,6 +12,7 @@
#include <unordered_map> #include <unordered_map>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "ad/cppgtfs/gtfs/Feed.h" #include "ad/cppgtfs/gtfs/Feed.h"
#include "pfaedle/Def.h" #include "pfaedle/Def.h"
#include "pfaedle/config/MotConfig.h" #include "pfaedle/config/MotConfig.h"
@ -73,7 +74,7 @@ class ShapeBuilder {
static void getGtfsBox(const pfaedle::gtfs::Feed* feed, const MOTs& mots, static void getGtfsBox(const pfaedle::gtfs::Feed* feed, const MOTs& mots,
const std::string& tid, bool dropShapes, const std::string& tid, bool dropShapes,
osm::BBoxIdx* box, double maxSpeed, osm::BBoxIdx* box, double maxSpeed,
std::vector<double>* hopDists); std::vector<double>* hopDists, uint8_t verbosity);
private: private:
pfaedle::gtfs::Feed* _feed; pfaedle::gtfs::Feed* _feed;
@ -103,6 +104,7 @@ class ShapeBuilder {
std::string getFreeShapeId(pfaedle::gtfs::Trip* t); std::string getFreeShapeId(pfaedle::gtfs::Trip* t);
ad::cppgtfs::gtfs::Shape getGtfsShape(const EdgeListHops& shp, ad::cppgtfs::gtfs::Shape getGtfsShape(const EdgeListHops& shp,
pfaedle::gtfs::Trip* t, pfaedle::gtfs::Trip* t,
size_t numOthers,
const RoutingAttrs& rAttrs, const RoutingAttrs& rAttrs,
std::vector<float>* hopDists, std::vector<float>* hopDists,
uint32_t* bestColor); uint32_t* bestColor);
@ -126,7 +128,8 @@ class ShapeBuilder {
void buildIndex(); void buildIndex();
std::vector<LINE> getGeom(const EdgeListHops& shp, const RoutingAttrs& rAttrs, std::vector<LINE> getGeom(const EdgeListHops& shp, const RoutingAttrs& rAttrs,
std::map<uint32_t, double>* colors) const; std::map<uint32_t, double>* colors, Trip* t,
size_t numOthers) const;
double timePen(int candTime, int schedTime) const; double timePen(int candTime, int schedTime) const;
LINE getLine(const EdgeListHop& hop, const RoutingAttrs&, LINE getLine(const EdgeListHop& hop, const RoutingAttrs&,