add --osmfilter option

This commit is contained in:
Patrick Brosi 2022-01-11 17:32:50 +01:00
parent 6473dcdb52
commit c25d174e60
14 changed files with 185 additions and 30 deletions

View file

@ -67,8 +67,15 @@ double Collector::add(const Trip* oldT, const Shape* oldS, const Trip* newT,
std::vector<double> newDists;
LINE newL = getWebMercLine(newS, &newDists);
auto oldSegs = segmentize(oldT, oldL, oldDists);
auto newSegs = segmentize(newT, newL, newDists);
std::vector<std::pair<double, double>> newLenDists;
std::vector<std::pair<double, double>> oldLenDists;
auto oldSegs = segmentize(oldT, oldL, oldDists, newLenDists);
auto newSegs = segmentize(newT, newL, newDists, oldLenDists);
for (const auto& p : oldLenDists) {
_distDiffs.push_back(fabs(p.first - p.second));
}
// new lines build from cleaned-up shapes
LINE oldLCut;
@ -77,8 +84,9 @@ double Collector::add(const Trip* oldT, const Shape* oldS, const Trip* newT,
for (auto oldL : oldSegs)
oldLCut.insert(oldLCut.end(), oldL.begin(), oldL.end());
for (auto newL : newSegs)
for (auto newL : newSegs) {
newLCut.insert(newLCut.end(), newL.begin(), newL.end());
}
// determine the scale factor between the distance in projected
// coordinates and the real-world distance in meters
@ -150,8 +158,9 @@ double Collector::add(const Trip* oldT, const Shape* oldS, const Trip* newT,
}
// _____________________________________________________________________________
std::vector<LINE> Collector::segmentize(const Trip* t, const LINE& shape,
const std::vector<double>& dists) {
std::vector<LINE> Collector::segmentize(
const Trip* t, const LINE& shape, const std::vector<double>& dists,
std::vector<std::pair<double, double>>& lenDist) {
// The straightforward way to segmentize the shape would be to just cut it at
// the exact measurements in stop_times.txt. We have tried that, but found
// that it produces misleading results for the following reason:
@ -182,7 +191,7 @@ std::vector<LINE> Collector::segmentize(const Trip* t, const LINE& shape,
if (t->getStopTimes().size() < 2) return ret;
POLYLINE pl(shape);
std::vector<std::pair<POINT, double> > cuts;
std::vector<std::pair<POINT, double>> cuts;
size_t i = 0;
for (auto st : t->getStopTimes()) {
@ -213,7 +222,17 @@ std::vector<LINE> Collector::segmentize(const Trip* t, const LINE& shape,
auto curLp = beforePl.projectOnAfter(cuts[i].first, lastLp.lastIndex);
ret.push_back(pl.getSegment(lastLp, curLp).getLine());
auto curL = pl.getSegment(lastLp, curLp).getLine();
double dist =
util::geo::haversine(t->getStopTimes()[i - 1].getStop()->getLat(),
t->getStopTimes()[i - 1].getStop()->getLng(),
t->getStopTimes()[i].getStop()->getLat(),
t->getStopTimes()[i].getStop()->getLng());
double len = util::geo::webMercLen(curL);
lenDist.push_back({dist, len});
ret.push_back(curL);
lastLp = curLp;
}
@ -365,13 +384,27 @@ void Collector::printStats(std::ostream* os) const {
}
// _____________________________________________________________________________
util::json::Dict Collector::getJSONStats() const {
util::json::Dict stats = {};
std::map<string, double> Collector::getStats() {
std::map<string, double> stats;
if (_distDiffs.size()) {
auto i = _distDiffs.begin() + _distDiffs.size() / 2;
std::nth_element(_distDiffs.begin(), i, _distDiffs.end());
stats["median-dist-diff"] = *i;
} else {
stats["median-dist-diff"] = -1;
}
stats["num-trips"] = _trips;
stats["num-trips-matched"] = _results.size();
stats["num-trips-wo-shapes"] = _noOrigShp;
stats["avg-fr"] = getAvgDist();
if (_results.size()) {
stats["max-avg-frech-dist"] = (--_results.end())->getDist();
} else {
stats["max-avg-frech-dist"] = -1;
}
stats["an-0"] =
(static_cast<double>(_an0) / static_cast<double>(_results.size())) * 100;
stats["an-5"] =

View file

@ -59,7 +59,7 @@ class Collector {
void printShortStats(std::ostream* os) const;
// Get JSON stats
util::json::Dict getJSONStats() const;
std::map<string, double> getStats();
// Print a CSV for the results to os
void printCsv(std::ostream* os, const std::set<Result>& result) const;
@ -79,6 +79,8 @@ class Collector {
size_t _trips;
size_t _noOrigShp;
std::vector<double> _distDiffs;
double _fdSum;
size_t _unmatchedSegSum;
double _unmatchedSegLengthSum;
@ -97,7 +99,8 @@ class Collector {
const std::vector<LINE>& b);
static std::vector<LINE> segmentize(const Trip* t, const LINE& shape,
const std::vector<double>& dists);
const std::vector<double>& dists,
std::vector<std::pair<double, double>>& lenDist);
static std::vector<double> getBins(double mind, double maxd, size_t steps);
};

View file

@ -27,6 +27,7 @@ void printHelp(int argc, char** argv) {
<< "\nAllowed arguments:\n -g <gtfs> Ground truth GTFS file\n";
std::cout << " -s Only output summary\n";
std::cout << " --json Output JSON\n";
std::cout << " --avg Take avg of all inputs (only for --json)\n";
std::cout << " -f <folder> Output full reports (per feed) to <folder>\n";
std::cout
<< " -m MOTs to match (GTFS MOT or string, default: all)\n";
@ -87,6 +88,7 @@ int main(int argc, char** argv) {
std::vector<std::ofstream> reportStreams;
bool summarize = false;
bool json = false;
bool avg = false;
for (int i = 1; i < argc; i++) {
std::string cur = argv[i];
@ -103,6 +105,8 @@ int main(int argc, char** argv) {
summarize = true;
} else if (cur == "--json") {
json = true;
} else if (cur == "--avg") {
avg = true;
} else if (cur == "-f") {
if (++i >= argc) {
LOG(ERROR) << "Missing argument for full reports (-f).";
@ -173,7 +177,11 @@ int main(int argc, char** argv) {
util::json::Dict stats = {};
for (size_t i = 0; i < evalColls.size(); i++) {
stats[evlFeedPaths[i]] = evalColls[i].getJSONStats();
util::json::Dict locStats = {};
for (const auto& kv : evalColls[i].getStats()) {
locStats[kv.first] = kv.second;
}
stats[evlFeedPaths[i]] = locStats;
}
util::json::Dict jsonStats;
@ -183,9 +191,28 @@ int main(int argc, char** argv) {
{"statistics", stats[evlFeedPaths[0]]
}};
} else {
jsonStats = {
{"statistics", stats
}};
if (avg) {
double count = evalColls.size();
std::vector<std::string> keys;
for (const auto& a : evalColls[0].getStats()) {
keys.push_back(a.first);
}
util::json::Dict avgStats;
for (const auto& k : keys) {
double sum = 0;
for (size_t i = 0; i < evalColls.size(); i++) {
sum += evalColls[i].getStats()[k];
}
avgStats[k] = sum / count;
}
jsonStats = {
{"statistics", avgStats
}};
} else {
jsonStats = {
{"statistics", stats
}};
}
}
util::json::Writer wr(&std::cout, 10, true);