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

@ -109,7 +109,7 @@ int main(int argc, char** argv) {
exit(static_cast<int>(RetCode::MOT_CFG_PARSE_ERR));
}
if (cfg.osmPath.empty() && !cfg.writeOverpass) {
if (cfg.osmPath.empty() && !cfg.writeOverpass && !cfg.writeOsmfilter) {
std::cerr << "No OSM input file specified (-x), see --help." << std::endl;
exit(static_cast<int>(RetCode::NO_OSM_INPUT));
}
@ -124,7 +124,7 @@ int main(int argc, char** argv) {
if (cfg.feedPaths.size() == 1) {
if (cfg.inPlace) cfg.outputPath = cfg.feedPaths[0];
if (!cfg.writeOverpass)
if (!cfg.writeOverpass && !cfg.writeOsmfilter)
LOG(INFO) << "Reading GTFS feed " << cfg.feedPaths[0] << " ...";
try {
ad::cppgtfs::Parser p;
@ -136,7 +136,7 @@ int main(int argc, char** argv) {
}
} else if (cfg.writeOsm.size() || cfg.writeOverpass) {
for (size_t i = 0; i < cfg.feedPaths.size(); i++) {
if (!cfg.writeOverpass)
if (!cfg.writeOverpass && !cfg.writeOsmfilter)
LOG(INFO) << "Reading GTFS feed " << cfg.feedPaths[i] << " ...";
ad::cppgtfs::Parser p;
try {
@ -218,6 +218,18 @@ int main(int argc, char** argv) {
}
osmBuilder.overpassQryWrite(&std::cout, opts, box);
exit(static_cast<int>(RetCode::SUCCESS));
} else if (cfg.writeOsmfilter) {
BBoxIdx box(BOX_PADDING);
OsmBuilder osmBuilder;
std::vector<pfaedle::osm::OsmReadOpts> opts;
for (const auto& o : motCfgReader.getConfigs()) {
if (std::find_first_of(o.mots.begin(), o.mots.end(), cmdCfgMots.begin(),
cmdCfgMots.end()) != o.mots.end()) {
opts.push_back(o.osmBuildOpts);
}
}
osmBuilder.osmfilterRuleWrite(&std::cout, opts, box);
exit(static_cast<int>(RetCode::SUCCESS));
} else if (!cfg.feedPaths.size()) {
std::cout << "No input feed specified, see --help" << std::endl;
exit(static_cast<int>(RetCode::NO_INPUT_FEED));

View file

@ -10,14 +10,15 @@
#include "pfaedle/Def.h"
#include "pfaedle/_config.h"
#include "pfaedle/config/ConfigReader.h"
#include "pfaedle/config/PfaedleConfig.h"
#include "util/String.h"
#include "util/geo/Geo.h"
#include "util/log/Log.h"
using pfaedle::config::ConfigReader;
using std::string;
using std::exception;
using std::string;
using std::vector;
static const char* YEAR = &__DATE__[7];
@ -32,8 +33,7 @@ void ConfigReader::help(const char* bin) {
<< " with geometry precision <" << PFDL_PREC_STR << ">)\n\n"
<< "(C) " << YEAR << " " << COPY << "\n"
<< "Authors: " << AUTHORS << "\n\n"
<< "Usage: " << bin
<< " -x <OSM FILE> <GTFS FEED>\n\n"
<< "Usage: " << bin << " -x <OSM FILE> <GTFS FEED>\n\n"
<< "Allowed options:\n\n"
<< "General:\n"
<< std::setw(35) << " -v [ --version ]"
@ -93,6 +93,8 @@ void ConfigReader::help(const char* bin) {
<< " to <dbg-path>/path.json\n"
<< std::setw(35) << " --overpass"
<< "Output overpass query for matching OSM data\n"
<< std::setw(35) << " --osmfilter"
<< "Output osmfilter filter rules for matching OSM data\n"
<< std::setw(35) << " --grid-size arg (=2000)"
<< "Approx. grid cell size in meters\n"
<< std::setw(35) << " --no-fast-hops"
@ -122,6 +124,7 @@ void ConfigReader::read(Config* cfg, int argc, char** argv) {
{"mots", required_argument, NULL, 'm'},
{"grid-size", required_argument, 0, 'g'},
{"overpass", no_argument, 0, 'a'},
{"osmfilter", no_argument, 0, 'f'},
{"osm-out", required_argument, 0, 'X'},
{"trip-id", required_argument, 0, 'T'},
{"write-graph", no_argument, 0, 1},
@ -194,6 +197,9 @@ void ConfigReader::read(Config* cfg, int argc, char** argv) {
case 'a':
cfg->writeOverpass = true;
break;
case 'f':
cfg->writeOsmfilter = true;
break;
case 9:
cfg->inPlace = true;
break;

View file

@ -47,6 +47,13 @@ void MotConfigReader::parse(const std::vector<std::string>& paths,
std::string secStr = sec.first;
if (secStr.empty()) continue;
if (p.hasKey(secStr, "routing_emission_method")) {
cfg.routingOpts.emPenMethod =
p.getStr(secStr, "routing_emission_method");
} else {
cfg.routingOpts.emPenMethod = "exp";
}
if (p.hasKey(secStr, "routing_transition_method")) {
cfg.routingOpts.transPenMethod =
p.getStr(secStr, "routing_transition_method");

View file

@ -9,8 +9,8 @@
#include <sstream>
#include <string>
#include <vector>
#include "util/geo/Geo.h"
#include "ad/cppgtfs/gtfs/Route.h"
#include "util/geo/Geo.h"
namespace pfaedle {
namespace config {
@ -28,6 +28,7 @@ struct Config {
buildTransitGraph(false),
useCaching(false),
writeOverpass(false),
writeOsmfilter(false),
inPlace(false),
writeColors(false),
noFastHops(false),
@ -53,6 +54,7 @@ struct Config {
bool buildTransitGraph;
bool useCaching;
bool writeOverpass;
bool writeOsmfilter;
bool inPlace;
bool writeColors;
bool noFastHops;
@ -76,6 +78,7 @@ struct Config {
<< "grid-size: " << gridSize << "\n"
<< "use-cache: " << useCaching << "\n"
<< "write-overpass: " << writeOverpass << "\n"
<< "write-osmfilter: " << writeOsmfilter << "\n"
<< "inplace: " << inPlace << "\n"
<< "write-colors: " << writeColors << "\n"
<< "no-fast-hops: " << noFastHops << "\n"

View file

@ -183,6 +183,50 @@ void OsmBuilder::read(const std::string& path, const OsmReadOpts& opts,
LOG(DEBUG) << _lines.size() << " transit lines have been read.";
}
// _____________________________________________________________________________
void OsmBuilder::osmfilterRuleWrite(std::ostream* out,
const std::vector<OsmReadOpts>& opts,
const BBoxIdx& latLngBox) const {
UNUSED(latLngBox);
OsmIdSet bboxNodes, noHupNodes;
MultAttrMap emptyF;
RelLst rels;
OsmIdList ways;
RelMap nodeRels, wayRels;
NIdMap nodes;
OsmFilter filter;
AttrKeySet attrKeys[3] = {};
for (const OsmReadOpts& o : opts) {
filter = filter.merge(OsmFilter(o.keepFilter, o.dropFilter));
getKeptAttrKeys(o, attrKeys);
}
*out << "--keep=\n";
for (auto r : filter.getKeepRules()) {
for (auto val : r.second) {
*out << r.first << "=";
if (val.first != "*") *out << val.first;
*out << "\n";
}
}
*out << "\n";
*out << "--keep-tags=\n";
for (const auto& keys : attrKeys) {
for (auto val : keys) {
*out << val << "=\n";
}
}
}
// _____________________________________________________________________________
void OsmBuilder::overpassQryWrite(std::ostream* out,
const std::vector<OsmReadOpts>& opts,

View file

@ -92,6 +92,12 @@ class OsmBuilder {
void overpassQryWrite(std::ostream* out, const std::vector<OsmReadOpts>& opts,
const BBoxIdx& latLngBox) const;
// Based on the list of options, output an osmfilter configuration file
// to filter the data needed for routing
void osmfilterRuleWrite(std::ostream* out,
const std::vector<OsmReadOpts>& opts,
const BBoxIdx& latLngBox) const;
// Based on the list of options, read an OSM file from in and output an
// OSM file to out which contains exactly the entities that are needed
// from the file at in

View file

@ -61,6 +61,7 @@ struct RoutingOpts {
bool useStations;
double transitionPen;
std::string transPenMethod;
std::string emPenMethod;
};
// _____________________________________________________________________________
@ -80,6 +81,7 @@ inline bool operator==(const RoutingOpts& a, const RoutingOpts& b) {
fabs(a.transitionPen - b.transitionPen) < 0.01 &&
fabs(a.nonStationPen - b.nonStationPen) < 0.01 &&
a.transPenMethod == b.transPenMethod &&
a.emPenMethod == b.emPenMethod &&
a.useStations == b.useStations && a.popReachEdge == b.popReachEdge &&
a.noSelfHops == b.noSelfHops;
}

View file

@ -206,7 +206,6 @@ EdgeCandGroup ShapeBuilder::getEdgCands(const Stop* s) const {
// stations do not match, punish
nameMatchPunish = _motCfg.routingOpts.stationUnmatchedPen;
}
std::string platform = s->getPlatformCode();
if (!platform.empty() && !nd->pl().getSI()->getTrack().empty() &&
@ -218,8 +217,7 @@ EdgeCandGroup ShapeBuilder::getEdgCands(const Stop* s) const {
// don't snap to one way edges
if (e->pl().oneWay() == 2) continue;
ret.push_back({e,
mDist * _motCfg.routingOpts.stationDistPenFactor +
nameMatchPunish + trackMatchPunish,
emWeight(mDist) + nameMatchPunish + trackMatchPunish,
0,
{},
0,
@ -265,8 +263,7 @@ EdgeCandGroup ShapeBuilder::getEdgCands(const Stop* s) const {
for (auto e : selected) {
ret.push_back({e,
scores[e] * _motCfg.routingOpts.stationDistPenFactor +
_motCfg.routingOpts.nonStationPen,
emWeight(scores[e]) + _motCfg.routingOpts.nonStationPen,
progrs[e],
{},
0,
@ -981,7 +978,7 @@ std::vector<LINE> ShapeBuilder::getGeom(
ret.push_back({hop.pointStart, *hop.end->getFrom()->pl().getGeom()});
}
} else {
ret.push_back({hop.pointEnd, hop.pointStart});
ret.push_back({hop.pointStart, hop.pointEnd});
}
} else {
const auto& l = getLine(hop, rAttrs, colors);
@ -1222,3 +1219,17 @@ uint32_t ShapeBuilder::getTextColor(uint32_t c) const {
if (a < 140) return 0x00FFFFFF;
return 0;
}
// _____________________________________________________________________________
double ShapeBuilder::emWeight(double mDist) const {
if (_motCfg.routingOpts.emPenMethod == "exp") {
return mDist * _motCfg.routingOpts.stationDistPenFactor;
}
if (_motCfg.routingOpts.emPenMethod == "norm") {
double s = mDist * _motCfg.routingOpts.stationDistPenFactor;
return 0.5 * s * s;
}
return mDist;
}

View file

@ -119,6 +119,8 @@ class ShapeBuilder {
std::map<size_t, router::EdgeListHops> route(const TripTrie* trie,
const EdgeCandMap& ecm,
HopCache* hopCache) const;
double emWeight(double mDist) const;
void buildCandCache(const TripForests& clusters);
void buildIndex();

View file

@ -237,8 +237,6 @@ double DistDiffTransWeight::weight(uint32_t c, double d, double t0, double d0,
const RoutingOpts& rOpts) {
UNUSED(t0);
UNUSED(c);
// double mean = 250; // expectation value of 250 meters for buses
// double lambda = 1.0 / mean;
double w = fabs(d - d0);