initial commit
This commit is contained in:
commit
efcd3e1892
106 changed files with 27000 additions and 0 deletions
201
src/pfaedle/config/ConfigReader.cpp
Normal file
201
src/pfaedle/config/ConfigReader.cpp
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#include <float.h>
|
||||
#include <getopt.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "pfaedle/_config.h"
|
||||
#include "pfaedle/config/ConfigReader.h"
|
||||
#include "util/String.h"
|
||||
#include "util/log/Log.h"
|
||||
|
||||
using pfaedle::config::ConfigReader;
|
||||
|
||||
using std::string;
|
||||
using std::exception;
|
||||
using std::vector;
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void ConfigReader::help() {
|
||||
std::cout
|
||||
<< std::setfill(' ') << std::left
|
||||
<< "\033[1mpfaedle GTFS map matcher \033[22m\n"
|
||||
<< VERSION_FULL << " (built " << __DATE__ << " " << __TIME__ << ")\n\n"
|
||||
<< "(C) 2018 University of Freiburg\n"
|
||||
<< "Author: Patrick Brosi <brosi@informatik.uni-freiburg.de>\n\n"
|
||||
<< "Usage: "
|
||||
<< " -x <OSM FILE> -c <CFG FILE> <GTFS FEED>\n\n"
|
||||
<< "Allowed options:\n\n"
|
||||
<< "General:\n"
|
||||
<< std::setw(35) << " -v [ --version ]"
|
||||
<< "print version\n"
|
||||
<< std::setw(35) << " -h [ --help ]"
|
||||
<< "show this help message\n"
|
||||
<< "\nInput:\n"
|
||||
<< std::setw(35) << " -c [ --config ] arg"
|
||||
<< "pfaedle config file\n"
|
||||
<< std::setw(35) << " -i [ --input ] arg"
|
||||
<< "gtfs feed(s), may also be given as positional parameter (see usage)\n"
|
||||
<< std::setw(35) << " -x [ --osm-file ] arg"
|
||||
<< "OSM xml input file\n"
|
||||
<< std::setw(35) << " -m [ --mots ] arg (=all)"
|
||||
<< "MOTs to calculate shapes for, comma separated, either as string "
|
||||
"{all,\n"
|
||||
<< std::setw(35) << " "
|
||||
<< "tram | streetcar, subway | metro, rail | train, bus, ferry | boat | "
|
||||
"\n"
|
||||
<< std::setw(35) << " "
|
||||
<< "ship, cableclar, gondola, funicular} or as GTFS mot codes\n"
|
||||
<< "\nOutput:\n"
|
||||
<< std::setw(35) << " -o [ --output ] arg (=gtfs-out)"
|
||||
<< "GTFS output path\n"
|
||||
<< std::setw(35) << " -X [ --osm-out ] arg"
|
||||
<< "if specified, a filtered OSM file will be written to <arg>\n"
|
||||
<< "\nDebug Output:\n"
|
||||
<< std::setw(35) << " -d [ --dbg-path ] arg (=geo)"
|
||||
<< "output path for debug files\n"
|
||||
<< std::setw(35) << " --write-trgraph"
|
||||
<< "write transit graph as GeoJSON to <dbg-path>/trgraph.json\n"
|
||||
<< std::setw(35) << " --write-graph"
|
||||
<< "write routing graph as GeoJSON to <dbg-path>/graph.json\n"
|
||||
<< std::setw(35) << " --write-cgraph"
|
||||
<< "write combination graph as GeoJSON to <dbg-path>/combraph.json\n"
|
||||
<< std::setw(35) << " --method arg (=global)"
|
||||
<< "matching method to use, either 'global' (based on HMM), 'greedy' or "
|
||||
"'greedy2'\n"
|
||||
<< std::setw(35) << " --eval"
|
||||
<< "evaluate existing shapes against matched shapes and print results\n"
|
||||
<< std::setw(35) << " --eval-path arg (=.)"
|
||||
<< "path for eval file output\n"
|
||||
<< std::setw(35) << " --eval-df-bins arg (= )"
|
||||
<< "bins to use for d_f histogram, comma separated (e.g. 10,20,30,40)\n"
|
||||
<< "\nMisc:\n"
|
||||
<< std::setw(35) << " -T [ --trip-id ] arg"
|
||||
<< "Do routing only for trip <arg>, write result to\n"
|
||||
<< std::setw(35) << " "
|
||||
<< "<dbg-path>/path.json\n"
|
||||
<< std::setw(35) << " --grid-size arg (=2000)"
|
||||
<< "Grid cell size\n";
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void ConfigReader::read(Config* cfg, int argc, char** argv) {
|
||||
std::string motStr = "all";
|
||||
bool printOpts = false;
|
||||
|
||||
struct option ops[] = {{"output", required_argument, 0, 'o'},
|
||||
{"input", required_argument, 0, 'i'},
|
||||
{"config", required_argument, 0, 'c'},
|
||||
{"osm-file", required_argument, 0, 'x'},
|
||||
{"drop-shapes", required_argument, 0, 'D'},
|
||||
{"mots", required_argument, NULL, 'm'},
|
||||
{"grid-size", required_argument, 0, 'g'},
|
||||
{"osm-out", required_argument, 0, 'X'},
|
||||
{"trip-id", required_argument, 0, 'T'},
|
||||
{"write-graph", no_argument, 0, 1},
|
||||
{"write-cgraph", no_argument, 0, 2},
|
||||
{"write-trgraph", no_argument, 0, 4},
|
||||
{"method", required_argument, 0, 5},
|
||||
{"eval", no_argument, 0, 3},
|
||||
{"eval-path", required_argument, 0, 6},
|
||||
{"eval-df-bins", required_argument, 0, 7},
|
||||
{"dbg-path", required_argument, 0, 'd'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
char c;
|
||||
while ((c = getopt_long(argc, argv, ":o:hvi:c:x:Dm:g:X:T:d:p", ops, 0)) !=
|
||||
-1) {
|
||||
switch (c) {
|
||||
case 1:
|
||||
cfg->writeGraph = true;
|
||||
break;
|
||||
case 2:
|
||||
cfg->writeCombGraph = true;
|
||||
break;
|
||||
case 3:
|
||||
cfg->evaluate = true;
|
||||
break;
|
||||
case 4:
|
||||
cfg->buildTransitGraph = true;
|
||||
break;
|
||||
case 5:
|
||||
cfg->solveMethod = optarg;
|
||||
break;
|
||||
case 6:
|
||||
cfg->evalPath = optarg;
|
||||
break;
|
||||
case 7:
|
||||
cfg->evalDfBins = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
cfg->outputPath = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
cfg->feedPaths.push_back(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
cfg->configPaths.push_back(optarg);
|
||||
break;
|
||||
case 'x':
|
||||
cfg->osmPath = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
cfg->dropShapes = true;
|
||||
break;
|
||||
case 'm':
|
||||
motStr = optarg;
|
||||
break;
|
||||
case 'g':
|
||||
cfg->gridSize = atof(optarg);
|
||||
break;
|
||||
case 'X':
|
||||
cfg->writeOsm = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
cfg->shapeTripId = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
cfg->dbgOutputPath = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
std::cout << VERSION_FULL << " (built " << __DATE__ << " " << __TIME__
|
||||
<< ")\n\n";
|
||||
exit(0);
|
||||
case 'p':
|
||||
printOpts = true;
|
||||
break;
|
||||
case 'h':
|
||||
help();
|
||||
exit(0);
|
||||
case ':':
|
||||
std::cerr << argv[optind - 1];
|
||||
std::cerr << " requires an argument" << std::endl;
|
||||
exit(1);
|
||||
case '?':
|
||||
std::cerr << argv[optind - 1];
|
||||
std::cerr << " option unknown" << std::endl;
|
||||
exit(1);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Error while parsing arguments" << std::endl;
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = optind; i < argc; i++) cfg->feedPaths.push_back(argv[i]);
|
||||
|
||||
auto v = util::split(motStr, ',');
|
||||
for (const auto& motStr : v) {
|
||||
const auto& mots = Route::getTypesFromString(util::trim(motStr));
|
||||
cfg->mots.insert(mots.begin(), mots.end());
|
||||
}
|
||||
|
||||
if (printOpts)
|
||||
std::cout << "\nConfigured options:\n\n" << cfg->toString() << std::endl;
|
||||
}
|
||||
21
src/pfaedle/config/ConfigReader.h
Normal file
21
src/pfaedle/config/ConfigReader.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_CONFIG_CONFIGREADER_H_
|
||||
#define PFAEDLE_CONFIG_CONFIGREADER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "pfaedle/config/PfaedleConfig.h"
|
||||
|
||||
namespace pfaedle {
|
||||
namespace config {
|
||||
|
||||
class ConfigReader {
|
||||
public:
|
||||
static void read(Config* targetConfig, int argc, char** argv);
|
||||
static void help();
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // PFAEDLE_CONFIG_CONFIGREADER_H_
|
||||
28
src/pfaedle/config/MotConfig.h
Normal file
28
src/pfaedle/config/MotConfig.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_CONFIG_MOTCONFIG_H_
|
||||
#define PFAEDLE_CONFIG_MOTCONFIG_H_
|
||||
|
||||
#include "pfaedle/osm/OsmBuilder.h"
|
||||
#include "pfaedle/router/Router.h"
|
||||
|
||||
namespace pfaedle {
|
||||
namespace config {
|
||||
|
||||
|
||||
struct MotConfig {
|
||||
router::MOTs mots;
|
||||
osm::OsmReadOpts osmBuildOpts;
|
||||
router::RoutingOpts routingOpts;
|
||||
};
|
||||
|
||||
inline bool operator==(const MotConfig& a, const MotConfig& b) {
|
||||
return a.osmBuildOpts == b.osmBuildOpts && a.routingOpts == b.routingOpts;
|
||||
}
|
||||
|
||||
} // namespace config
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_CONFIG_MOTCONFIG_H_
|
||||
463
src/pfaedle/config/MotConfigReader.cpp
Normal file
463
src/pfaedle/config/MotConfigReader.cpp
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "pfaedle/config/MotConfigReader.h"
|
||||
#include "util/Misc.h"
|
||||
#include "util/String.h"
|
||||
|
||||
using pfaedle::config::MotConfigReader;
|
||||
using pfaedle::config::MotConfig;
|
||||
using pfaedle::osm::FilterRule;
|
||||
using pfaedle::osm::KeyVal;
|
||||
using configparser::ConfigFileParser;
|
||||
using configparser::ParseExc;
|
||||
using pfaedle::osm::DeepAttrRule;
|
||||
using pfaedle::trgraph::ReplRules;
|
||||
using ad::cppgtfs::gtfs::Route;
|
||||
|
||||
// _____________________________________________________________________________
|
||||
MotConfigReader::MotConfigReader() {}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void MotConfigReader::parse(const std::vector<std::string>& paths) {
|
||||
for (const auto& s : paths) {
|
||||
ConfigFileParser p;
|
||||
p.parse(s);
|
||||
|
||||
for (const auto& sec : p.getSecs()) {
|
||||
MotConfig curCfg;
|
||||
std::string secStr = sec.first;
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_keep")) {
|
||||
for (const auto& kvs : p.getStrArr(sec.first, "osm_filter_keep", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.keepFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 7; i++) {
|
||||
std::string name =
|
||||
std::string("osm_filter_lvl") + std::to_string(i + 1);
|
||||
if (p.hasKey(secStr, name)) {
|
||||
for (const auto& kvs : p.getStrArr(sec.first, name, ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.levelFilters[i][fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_drop")) {
|
||||
for (const auto& kvs : p.getStrArr(sec.first, "osm_filter_drop", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.dropFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_max_snap_level")) {
|
||||
curCfg.osmBuildOpts.maxSnapLevel =
|
||||
p.getInt(sec.first, "osm_max_snap_level");
|
||||
} else {
|
||||
curCfg.osmBuildOpts.maxSnapLevel = 7;
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_nohup")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_filter_nohup", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.noHupFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_oneway")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_filter_oneway", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.oneWayFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_oneway_reverse")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_filter_oneway_reverse", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.oneWayFilterRev[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_undirected")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_filter_undirected", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.twoWayFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_station")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_filter_station", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.stationFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_station_blocker")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_filter_station_blocker", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.stationBlockerFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_node_positive_restriction")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_node_positive_restriction", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.restrPosRestr[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_node_negative_restriction")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_node_negative_restriction", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.restrNegRestr[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_filter_no_restriction")) {
|
||||
for (const auto& kvs :
|
||||
p.getStrArr(sec.first, "osm_filter_no_restriction", ' ')) {
|
||||
auto fRule = getFRule(kvs);
|
||||
curCfg.osmBuildOpts.noRestrFilter[fRule.kv.first].insert(
|
||||
osm::AttrFlagPair(fRule.kv.second, getFlags(fRule.flags)));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_station_name_attrs")) {
|
||||
for (const std::string& r :
|
||||
p.getStrArr(sec.first, "osm_station_name_attrs", ' ')) {
|
||||
curCfg.osmBuildOpts.statAttrRules.nameRule.push_back(
|
||||
getDeepAttrRule(r));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_track_number_tags")) {
|
||||
for (const std::string& r :
|
||||
p.getStrArr(sec.first, "osm_track_number_tags", ' ')) {
|
||||
curCfg.osmBuildOpts.statAttrRules.platformRule.push_back(
|
||||
getDeepAttrRule(r));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_edge_track_number_tags")) {
|
||||
for (const std::string& r :
|
||||
p.getStrArr(sec.first, "osm_edge_track_number_tags", ' ')) {
|
||||
curCfg.osmBuildOpts.edgePlatformRules.push_back(getDeepAttrRule(r));
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_station_group_attrs")) {
|
||||
auto arr = p.getStrArr(secStr, "osm_station_group_attrs", ' ');
|
||||
|
||||
for (const auto& ruleStr : arr) {
|
||||
auto deep = getDeepAttrRule(ruleStr);
|
||||
// TODO(patrick): getKv is misused here as a a=b parser
|
||||
auto attrD = getKv(deep.attr);
|
||||
deep.attr = attrD.first;
|
||||
double dist = atof(attrD.second.c_str());
|
||||
curCfg.osmBuildOpts.statGroupNAttrRules.push_back({deep, dist});
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_line_relation_tags")) {
|
||||
auto arr = p.getStrArr(secStr, "osm_line_relation_tags", ' ');
|
||||
|
||||
for (const auto& ruleStr : arr) {
|
||||
auto rule = getKv(ruleStr);
|
||||
auto tags = util::split(rule.second, ',');
|
||||
if (rule.first == "from_name")
|
||||
curCfg.osmBuildOpts.relLinerules.fromNameRule = tags;
|
||||
else if (rule.first == "to_name")
|
||||
curCfg.osmBuildOpts.relLinerules.toNameRule = tags;
|
||||
else if (rule.first == "line_name")
|
||||
curCfg.osmBuildOpts.relLinerules.sNameRule = tags;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_max_snap_distance")) {
|
||||
curCfg.osmBuildOpts.maxSnapDistances =
|
||||
p.getDoubleArr(secStr, "osm_max_snap_distance", ',');
|
||||
} else {
|
||||
curCfg.osmBuildOpts.maxSnapDistances.push_back(50);
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_max_snap_fallback_distance")) {
|
||||
curCfg.osmBuildOpts.maxSnapFallbackHeurDistance =
|
||||
p.getDouble(secStr, "osm_max_snap_fallback_distance");
|
||||
} else {
|
||||
curCfg.osmBuildOpts.maxSnapFallbackHeurDistance =
|
||||
*std::max_element(curCfg.osmBuildOpts.maxSnapDistances.begin(),
|
||||
curCfg.osmBuildOpts.maxSnapDistances.end()) *
|
||||
2;
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_max_group_search_distance")) {
|
||||
curCfg.osmBuildOpts.maxGroupSearchDistance =
|
||||
p.getDouble(secStr, "osm_max_group_search_distance");
|
||||
} else {
|
||||
curCfg.osmBuildOpts.maxGroupSearchDistance =
|
||||
*std::max_element(curCfg.osmBuildOpts.maxSnapDistances.begin(),
|
||||
curCfg.osmBuildOpts.maxSnapDistances.end()) *
|
||||
4;
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_max_osm_station_distance")) {
|
||||
curCfg.osmBuildOpts.maxOsmStationDistance =
|
||||
p.getDouble(secStr, "osm_max_osm_station_distance");
|
||||
} else {
|
||||
curCfg.osmBuildOpts.maxOsmStationDistance = 5;
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "osm_max_node_block_distance")) {
|
||||
curCfg.osmBuildOpts.maxBlockDistance =
|
||||
p.getDouble(secStr, "osm_max_node_block_distance");
|
||||
} else {
|
||||
curCfg.osmBuildOpts.maxBlockDistance =
|
||||
*std::max_element(curCfg.osmBuildOpts.maxSnapDistances.begin(),
|
||||
curCfg.osmBuildOpts.maxSnapDistances.end()) /
|
||||
8;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
std::string name =
|
||||
std::string("routing_lvl") + std::to_string(i) + "_fac";
|
||||
if (p.hasKey(secStr, name)) {
|
||||
double v = p.getDouble(sec.first, name);
|
||||
curCfg.routingOpts.levelPunish[i] = v;
|
||||
} else {
|
||||
curCfg.routingOpts.levelPunish[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "routing_full_turn_punish")) {
|
||||
curCfg.routingOpts.fullTurnPunishFac =
|
||||
p.getDouble(secStr, "routing_full_turn_punish");
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_full_turn_angle")) {
|
||||
double ang = p.getDouble(secStr, "routing_full_turn_angle");
|
||||
curCfg.routingOpts.fullTurnAngle = ang;
|
||||
} else {
|
||||
curCfg.routingOpts.fullTurnAngle = 5;
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_snap_full_turn_angle")) {
|
||||
double ang = p.getDouble(secStr, "routing_snap_full_turn_angle");
|
||||
curCfg.osmBuildOpts.maxAngleSnapReach = ang;
|
||||
} else {
|
||||
curCfg.osmBuildOpts.maxAngleSnapReach =
|
||||
curCfg.routingOpts.fullTurnAngle;
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_pass_thru_station_punish")) {
|
||||
curCfg.routingOpts.passThruStationsPunish =
|
||||
p.getDouble(secStr, "routing_pass_thru_station_punish");
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_one_way_meter_punish_fac")) {
|
||||
curCfg.routingOpts.oneWayPunishFac =
|
||||
p.getDouble(secStr, "routing_one_way_meter_punish_fac");
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_one_way_edge_punish")) {
|
||||
curCfg.routingOpts.oneWayEdgePunish =
|
||||
p.getDouble(secStr, "routing_one_way_edge_punish");
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_line_unmatched_punish_fac")) {
|
||||
curCfg.routingOpts.lineUnmatchedPunishFact =
|
||||
p.getDouble(secStr, "routing_line_unmatched_punish_fac");
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_platform_unmatched_punish")) {
|
||||
curCfg.routingOpts.platformUnmatchedPen =
|
||||
p.getDouble(secStr, "routing_platform_unmatched_punish");
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_non_osm_station_punish")) {
|
||||
curCfg.routingOpts.nonOsmPen =
|
||||
p.getDouble(secStr, "routing_non_osm_station_punish");
|
||||
} else {
|
||||
curCfg.routingOpts.nonOsmPen = 0;
|
||||
}
|
||||
if (p.hasKey(secStr, "routing_station_distance_punish_fac")) {
|
||||
curCfg.routingOpts.stationDistPenFactor =
|
||||
p.getDouble(secStr, "routing_station_distance_punish_fac");
|
||||
} else {
|
||||
curCfg.routingOpts.stationDistPenFactor = 1;
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "station_normalize_chain")) {
|
||||
try {
|
||||
auto arr = p.getStrArr(secStr, "station_normalize_chain", ';');
|
||||
curCfg.osmBuildOpts.statNormzer =
|
||||
trgraph::Normalizer(getNormRules(arr));
|
||||
} catch (const std::exception& e) {
|
||||
throw ParseExc(p.getVal(secStr, "station_normalize_chain").line,
|
||||
p.getVal(secStr, "station_normalize_chain").pos,
|
||||
"<valid regular expression>",
|
||||
std::string("<regex error: ") + e.what() + ">", s);
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "track_normalize_chain")) {
|
||||
try {
|
||||
auto arr = p.getStrArr(secStr, "track_normalize_chain", ';');
|
||||
curCfg.osmBuildOpts.trackNormzer =
|
||||
trgraph::Normalizer(getNormRules(arr));
|
||||
} catch (const std::exception& e) {
|
||||
throw ParseExc(p.getVal(secStr, "track_normalize_chain").line,
|
||||
p.getVal(secStr, "station_normalize_chain").pos,
|
||||
"<valid regular expression>",
|
||||
std::string("<regex error: ") + e.what() + ">", s);
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hasKey(secStr, "line_normalize_chain")) {
|
||||
try {
|
||||
auto arr = p.getStrArr(secStr, "line_normalize_chain", ';');
|
||||
curCfg.osmBuildOpts.lineNormzer =
|
||||
trgraph::Normalizer(getNormRules(arr));
|
||||
} catch (const std::exception& e) {
|
||||
throw ParseExc(p.getVal(secStr, "station_normalize_chain").line,
|
||||
p.getVal(secStr, "station_normalize_chain").pos,
|
||||
"<valid regular expression>",
|
||||
std::string("<regex error: ") + e.what() + ">", s);
|
||||
}
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
for (auto& cfg : _cfgs) {
|
||||
if (cfg == curCfg) {
|
||||
for (auto mot : Route::getTypesFromString(secStr)) {
|
||||
cfg.mots.insert(mot);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
curCfg.mots = Route::getTypesFromString(secStr);
|
||||
_cfgs.push_back(curCfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
ReplRules MotConfigReader::getNormRules(
|
||||
const std::vector<std::string>& arr) const {
|
||||
trgraph::ReplRules ret;
|
||||
|
||||
for (auto a : arr) {
|
||||
size_t p = a.find(" -> ");
|
||||
if (p == std::string::npos) continue;
|
||||
|
||||
trgraph::ReplRule r;
|
||||
r.first = a.substr(0, p);
|
||||
r.second = a.substr(p + 4, std::string::npos);
|
||||
|
||||
if (r.first.size() > 1 && r.first.front() == '\'' &&
|
||||
r.first.back() == '\'') {
|
||||
r.first = r.first.substr(1, r.first.size() - 2);
|
||||
}
|
||||
|
||||
if (r.second.size() > 1 && r.second.front() == '\'' &&
|
||||
r.second.back() == '\'') {
|
||||
r.second = r.second.substr(1, r.second.size() - 2);
|
||||
}
|
||||
|
||||
ret.push_back(r);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
uint64_t MotConfigReader::getFlags(const std::set<string>& flags) const {
|
||||
uint64_t ret = osm::USE;
|
||||
|
||||
for (const auto& flag : flags) {
|
||||
if (flag == "rel_flat") {
|
||||
ret |= osm::REL_NO_DOWN;
|
||||
continue;
|
||||
}
|
||||
if (flag == "no_match_nds") {
|
||||
ret |= osm::NO_NODES;
|
||||
continue;
|
||||
}
|
||||
if (flag == "no_match_rels") {
|
||||
ret |= osm::NO_RELATIONS;
|
||||
continue;
|
||||
}
|
||||
if (flag == "no_match_ways") {
|
||||
ret |= osm::NO_WAYS;
|
||||
continue;
|
||||
}
|
||||
if (flag == "mult_val_match") {
|
||||
ret |= osm::MULT_VAL_MATCH;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
FilterRule MotConfigReader::getFRule(const std::string& r) const {
|
||||
osm::FilterRule ret;
|
||||
|
||||
auto parts = util::split(util::trim(r), '|');
|
||||
|
||||
ret.kv = getKv(parts[0]);
|
||||
ret.flags = std::set<std::string>(parts.begin() + 1, parts.end());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
KeyVal MotConfigReader::getKv(const std::string& kv) const {
|
||||
osm::KeyVal ret;
|
||||
size_t p = kv.find('=', 0);
|
||||
ret.first = kv.substr(0, p);
|
||||
|
||||
if (p != std::string::npos) {
|
||||
ret.second = kv.substr(p + 1, std::string::npos);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const std::vector<MotConfig>& MotConfigReader::getConfigs() const {
|
||||
return _cfgs;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
DeepAttrRule MotConfigReader::getDeepAttrRule(const std::string& rule) const {
|
||||
if (rule[0] == '[' && rule.find(']') != std::string::npos) {
|
||||
auto kv = getFRule(rule.substr(1, rule.find(']') - 1));
|
||||
std::string attr = rule.substr(rule.find(']') + 1);
|
||||
return osm::DeepAttrRule{attr, kv};
|
||||
} else {
|
||||
return osm::DeepAttrRule{rule, osm::FilterRule()};
|
||||
}
|
||||
}
|
||||
42
src/pfaedle/config/MotConfigReader.h
Normal file
42
src/pfaedle/config/MotConfigReader.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_CONFIG_MOTCONFIGREADER_H_
|
||||
#define PFAEDLE_CONFIG_MOTCONFIGREADER_H_
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "ad/cppgtfs/gtfs/Route.h"
|
||||
#include "configparser/ConfigFileParser.h"
|
||||
#include "pfaedle/config/MotConfig.h"
|
||||
#include "pfaedle/osm/OsmBuilder.h"
|
||||
|
||||
namespace pfaedle {
|
||||
namespace config {
|
||||
|
||||
using ad::cppgtfs::gtfs::Route;
|
||||
|
||||
class MotConfigReader {
|
||||
public:
|
||||
MotConfigReader();
|
||||
void parse(const std::vector<std::string>& paths);
|
||||
|
||||
const std::vector<MotConfig>& getConfigs() const;
|
||||
|
||||
private:
|
||||
std::vector<MotConfig> _cfgs;
|
||||
|
||||
osm::KeyVal getKv(const std::string& kv) const;
|
||||
osm::FilterRule getFRule(const std::string& kv) const;
|
||||
|
||||
trgraph::ReplRules getNormRules(const std::vector<std::string>& arr) const;
|
||||
osm::DeepAttrRule getDeepAttrRule(const std::string& rule) const;
|
||||
uint64_t getFlags(const std::set<string>& flags) const;
|
||||
};
|
||||
} // namespace config
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_CONFIG_MOTCONFIGREADER_H_
|
||||
89
src/pfaedle/config/PfaedleConfig.h
Normal file
89
src/pfaedle/config/PfaedleConfig.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_CONFIG_PFAEDLECONFIG_H_
|
||||
#define PFAEDLE_CONFIG_PFAEDLECONFIG_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "ad/cppgtfs/gtfs/Route.h"
|
||||
|
||||
namespace pfaedle {
|
||||
namespace config {
|
||||
|
||||
using ad::cppgtfs::gtfs::Route;
|
||||
|
||||
struct Config {
|
||||
Config()
|
||||
: dbgOutputPath("geo"),
|
||||
solveMethod("global"),
|
||||
evalPath("."),
|
||||
dropShapes(false),
|
||||
useHMM(false),
|
||||
writeGraph(false),
|
||||
writeCombGraph(false),
|
||||
evaluate(false),
|
||||
buildTransitGraph(false),
|
||||
gridSize(2000) {}
|
||||
std::string dbgOutputPath;
|
||||
std::string solveMethod;
|
||||
std::string evalPath;
|
||||
std::string shapeTripId;
|
||||
std::string outputPath;
|
||||
std::string writeOsm;
|
||||
std::string osmPath;
|
||||
std::string evalDfBins;
|
||||
std::vector<std::string> feedPaths;
|
||||
std::vector<std::string> configPaths;
|
||||
std::set<Route::TYPE> mots;
|
||||
bool dropShapes;
|
||||
bool useHMM;
|
||||
bool writeGraph;
|
||||
bool writeCombGraph;
|
||||
bool evaluate;
|
||||
bool buildTransitGraph;
|
||||
double gridSize;
|
||||
|
||||
std::string toString() {
|
||||
std::stringstream ss;
|
||||
ss << "trip-id: " << shapeTripId << "\n"
|
||||
<< "output-path: " << outputPath << "\n"
|
||||
<< "write-osm-path: " << writeOsm << "\n"
|
||||
<< "read-osm-path: " << osmPath << "\n"
|
||||
<< "debug-output-path: " << dbgOutputPath << "\n"
|
||||
<< "drop-shapes: " << dropShapes << "\n"
|
||||
<< "use-hmm: " << useHMM << "\n"
|
||||
<< "write-graph: " << writeGraph << "\n"
|
||||
<< "write-cgraph: " << writeCombGraph << "\n"
|
||||
<< "grid-size: " << gridSize << "\n"
|
||||
<< "feed-paths: ";
|
||||
|
||||
for (const auto& p : feedPaths) {
|
||||
ss << p << " ";
|
||||
}
|
||||
|
||||
ss << "\nconfig-paths: ";
|
||||
|
||||
for (const auto& p : configPaths) {
|
||||
ss << p << " ";
|
||||
}
|
||||
|
||||
ss << "\nmots: ";
|
||||
|
||||
for (const auto& mot : mots) {
|
||||
ss << mot << " ";
|
||||
}
|
||||
|
||||
ss << "\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace config
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_CONFIG_PFAEDLECONFIG_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue