diff --git a/pfaedle.cfg b/pfaedle.cfg index 1ec3a62..443935f 100644 --- a/pfaedle.cfg +++ b/pfaedle.cfg @@ -386,9 +386,6 @@ routing_station_unmatched_penalty: 0.3 # If the platform does not match, add this penalty routing_platform_unmatched_penalty: 0.1 -# If the station name does not match, add this penalty -routing_station_unmatched_penalty: 0.3 - # Max angle that should be counted as a full turn routing_full_turn_angle: 100 @@ -803,9 +800,6 @@ routing_full_turn_penalty: 120 # 2 minutes # Penalty added to non-station placements routing_non_station_penalty: 0.5 -# If the station name does not match, add this penalty -routing_station_unmatched_penalty: 0.3 - # Max angle that should be counted as a full turn routing_full_turn_angle: 20 diff --git a/src/pfaedle/config/ConfigReader.cpp b/src/pfaedle/config/ConfigReader.cpp index 54ed140..3075d46 100644 --- a/src/pfaedle/config/ConfigReader.cpp +++ b/src/pfaedle/config/ConfigReader.cpp @@ -136,6 +136,7 @@ void ConfigReader::read(Config* cfg, int argc, char** argv) { {"write-colors", no_argument, 0, 13}, {"stats", no_argument, 0, 14}, {"no-hop-cache", no_argument, 0, 15}, + {"gaussian-noise", required_argument, 0, 16}, {0, 0, 0, 0}}; char c; @@ -205,6 +206,9 @@ void ConfigReader::read(Config* cfg, int argc, char** argv) { case 15: cfg->noHopCache = true; break; + case 16: + cfg->gaussianNoise = atof(optarg); + break; case 'v': std::cout << "pfaedle " << VERSION_FULL << std::endl; exit(0); diff --git a/src/pfaedle/config/PfaedleConfig.h b/src/pfaedle/config/PfaedleConfig.h index feaa645..b490ae7 100644 --- a/src/pfaedle/config/PfaedleConfig.h +++ b/src/pfaedle/config/PfaedleConfig.h @@ -35,7 +35,8 @@ struct Config { noTrie(false), noHopCache(false), writeStats(false), - gridSize(2000 / util::geo::M_PER_DEG) {} + gridSize(2000 / util::geo::M_PER_DEG), + gaussianNoise(0) {} std::string dbgOutputPath; std::string solveMethod; std::string shapeTripId; @@ -60,6 +61,7 @@ struct Config { bool noHopCache; bool writeStats; double gridSize; + double gaussianNoise; std::string toString() { std::stringstream ss; diff --git a/src/pfaedle/router/ShapeBuilder.cpp b/src/pfaedle/router/ShapeBuilder.cpp index 6223cfe..04ec816 100644 --- a/src/pfaedle/router/ShapeBuilder.cpp +++ b/src/pfaedle/router/ShapeBuilder.cpp @@ -167,19 +167,25 @@ EdgeCandGroup ShapeBuilder::getEdgCands(const Stop* s) const { auto pos = POINT(s->getLng(), s->getLat()); ret.push_back({0, 0, 0, pos, 0, {}}); - // unsigned seed = - // std::chrono::system_clock::now().time_since_epoch().count(); - // std::default_random_engine gen(seed); - // std::normal_distribution dist(0.0, 25.0); - - // add some gaussian noise - // pos.setX(pos.getX() + dist(gen)); - // pos.setY(pos.getY() + dist(gen)); - double maxMDist = _motCfg.osmBuildOpts.maxStationCandDistance; double distor = util::geo::latLngDistFactor(pos); + if (_cfg.gaussianNoise > 0) { + unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::default_random_engine gen(seed); + + // the standard dev is given in meters, convert (roughly...) to degrees + double standardDev = (_cfg.gaussianNoise / M_PER_DEG) / distor; + + // mean 0 (no movement), standard dev according to config + std::normal_distribution dist(0.0, standardDev); + + // add gaussian noise + pos.setX(pos.getX() + dist(gen)); + pos.setY(pos.getY() + dist(gen)); + } + std::set frNIdx; _nGrid.get(util::geo::pad(util::geo::getBoundingBox(pos), (maxMDist / M_PER_DEG) / distor), @@ -594,7 +600,7 @@ ad::cppgtfs::gtfs::Shape ShapeBuilder::getGtfsShape( std::string ShapeBuilder::getFreeShapeId(Trip* trip) { std::string ret; std::lock_guard guard(_shpMutex); - while (!ret.size() || _feed->getShapes().get(ret)) { + while (!ret.size() || _feed->getShapes().has(ret)) { _curShpCnt++; ret = "shp_"; ret += std::to_string(trip->getRoute()->getType()); diff --git a/src/shapevl/Collector.cpp b/src/shapevl/Collector.cpp index 67419dd..dffe9c9 100644 --- a/src/shapevl/Collector.cpp +++ b/src/shapevl/Collector.cpp @@ -169,7 +169,7 @@ std::vector Collector::segmentize(const Trip* t, const LINE& shape, // 5) As tracks are often longer than 20 meters, this will dillute our AN // measure, although the shape is CORRECT (because the ground truth uses // a different position philosophy than the test data) - // 6) To normalize this, we always the following approach: + // 6) To normalize this, we use the following approach: // a) Get the exact progression of the measurment on the shape // b) Extract a segment of 200 meters, with the measurement progress in // the middle c) Project the GROUND TRUTH station coordinate to this diff --git a/src/shapevl/ShapevlMain.cpp b/src/shapevl/ShapevlMain.cpp index 1469582..2945299 100644 --- a/src/shapevl/ShapevlMain.cpp +++ b/src/shapevl/ShapevlMain.cpp @@ -56,8 +56,11 @@ void eval(const std::vector* paths, for (const auto& oldTrip : evalFeed->getTrips()) { if (!mots->count(oldTrip.second->getRoute()->getType())) continue; auto newTrip = feed.getTrips().get(oldTrip.first); - if (!newTrip) - LOG(ERROR) << "Trip #" << oldTrip.first << " not present in " << path; + if (!newTrip) { + LOG(ERROR) << "Trip #" << oldTrip.first << " not present in " << path + << ", skipping..."; + continue; + } (*colls)[myFeed].add(oldTrip.second, oldTrip.second->getShape(), newTrip, newTrip->getShape()); } @@ -121,6 +124,7 @@ int main(int argc, char** argv) { evlFeedPaths.push_back(feedPath); if (fullReportPath.size()) { reportStreams.emplace_back(); + reportStreams.back().exceptions(std::ios::failbit | std::ios::badbit); reportStreams.back().open(fullReportPath + "/" + util::split(feedPath, '/').back() + ".fullreport.tsv");