chore: fixes and code cleanup

This commit is contained in:
Vlad Vesa 2020-08-19 09:17:34 +03:00
parent c96bd24cca
commit f1aa563d41
3 changed files with 1955 additions and 1933 deletions

View file

@ -1,12 +1,12 @@
// Copyright 2018, University of Freiburg, // Copyright 2018, University of Freiburg,
// Chair of Algorithms and Data Structures. // Chair of Algorithms and Data Structures.
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de> // Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
#include <climits>
#include <pwd.h> #include <pwd.h>
#include <csignal>
#include <cstdio>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <climits>
#include <csignal>
#include <cstdio>
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <string> #include <string>
@ -163,14 +163,12 @@ int main(int argc, char** argv) {
LOG(INFO) << "Writing filtered XML to " << cfg.writeOsm << " ..."; LOG(INFO) << "Writing filtered XML to " << cfg.writeOsm << " ...";
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);
&box);
} }
OsmBuilder osmBuilder; OsmBuilder osmBuilder;
std::vector<pfaedle::osm::OsmReadOpts> opts; std::vector<pfaedle::osm::OsmReadOpts> opts;
for (const auto& o : motCfgReader.getConfigs()) { for (const auto& o : motCfgReader.getConfigs()) {
if (std::find_first_of(o.mots.begin(), o.mots.end(), cmdCfgMots.begin(), if (std::find_first_of(o.mots.begin(), o.mots.end(), cmdCfgMots.begin(), cmdCfgMots.end()) != o.mots.end()) {
cmdCfgMots.end()) != o.mots.end()) {
opts.push_back(o.osmBuildOpts); opts.push_back(o.osmBuildOpts);
} }
} }
@ -185,14 +183,12 @@ int main(int argc, char** argv) {
} else if (cfg.writeOverpass) { } else if (cfg.writeOverpass) {
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);
&box);
} }
OsmBuilder osmBuilder; OsmBuilder osmBuilder;
std::vector<pfaedle::osm::OsmReadOpts> opts; std::vector<pfaedle::osm::OsmReadOpts> opts;
for (const auto& o : motCfgReader.getConfigs()) { for (const auto& o : motCfgReader.getConfigs()) {
if (std::find_first_of(o.mots.begin(), o.mots.end(), cmdCfgMots.begin(), if (std::find_first_of(o.mots.begin(), o.mots.end(), cmdCfgMots.begin(), cmdCfgMots.end()) != o.mots.end()) {
cmdCfgMots.end()) != o.mots.end()) {
opts.push_back(o.osmBuildOpts); opts.push_back(o.osmBuildOpts);
} }
} }
@ -251,8 +247,7 @@ int main(int argc, char** argv) {
} }
} }
ShapeBuilder shapeBuilder(&gtfs[0], &evalFeed, cmdCfgMots, motCfg, &ecoll, ShapeBuilder shapeBuilder(&gtfs[0], &evalFeed, cmdCfgMots, motCfg, &ecoll, &graph, &fStops, &restr, cfg);
&graph, &fStops, &restr, cfg);
if (cfg.writeGraph) { if (cfg.writeGraph) {
LOG(INFO) << "Outputting graph.json..."; LOG(INFO) << "Outputting graph.json...";

View file

@ -2,7 +2,10 @@
// Chair of Algorithms and Data Structures. // Chair of Algorithms and Data Structures.
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de> // Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
#include <cfloat> #include <osmium/io/any_input.hpp>
#include <osmium/geom/haversine.hpp>
#include <osmium/visitor.hpp>
#include <algorithm> #include <algorithm>
#include <exception> #include <exception>
#include <iostream> #include <iostream>
@ -13,12 +16,6 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <osmium/io/any_input.hpp>
#include <osmium/util/file.hpp>
#include <osmium/geom/haversine.hpp>
#include <osmium/visitor.hpp>
#include <osmium/index/map/flex_mem.hpp>
#include "pfaedle/Def.h" #include "pfaedle/Def.h"
#include "pfaedle/osm/BBoxIdx.h" #include "pfaedle/osm/BBoxIdx.h"
#include "pfaedle/osm/Osm.h" #include "pfaedle/osm/Osm.h"
@ -55,52 +52,52 @@ using pfaedle::osm::BlockSearch;
using ad::cppgtfs::gtfs::Stop; using ad::cppgtfs::gtfs::Stop;
class NodeHandler : public osmium::handler::Handler { class NodeHandler : public osmium::handler::Handler {
const pfaedle::osm::OsmFilter& filter; const pfaedle::osm::OsmFilter& _filter;
const pfaedle::osm::BBoxIdx& bbox; const pfaedle::osm::BBoxIdx& _bbox;
pfaedle::osm::OsmIdSet& bboxNodes; pfaedle::osm::OsmIdSet& _bboxNodes;
pfaedle::osm::OsmIdSet& noHupNodes; pfaedle::osm::OsmIdSet& _noHupNodes;
public: public:
NodeHandler(const pfaedle::osm::OsmFilter& filter, NodeHandler(const pfaedle::osm::OsmFilter& filter,
const pfaedle::osm::BBoxIdx& bbox, const pfaedle::osm::BBoxIdx& bbox,
pfaedle::osm::OsmIdSet& bboxNodes, pfaedle::osm::OsmIdSet& bboxNodes,
pfaedle::osm::OsmIdSet& noHupNodes) : pfaedle::osm::OsmIdSet& noHupNodes) :
filter(filter), _filter(filter),
bbox(bbox), _bbox(bbox),
bboxNodes(bboxNodes), _bboxNodes(bboxNodes),
noHupNodes(noHupNodes) _noHupNodes(noHupNodes)
{ {}
}
void node(const osmium::Node& node) { void node(const osmium::Node& node) {
bool ignored = false; bool ignored = false;
for(const auto& tag: node.tags()) {
if (filter.nohup(tag.key(), tag.value())) { for (const auto& tag : node.tags()) {
noHupNodes.add(node.id()); if (_filter.nohup(tag.key(), tag.value())) {
_noHupNodes.add(node.id());
ignored = true; ignored = true;
break; break;
} }
} }
if(!ignored) {
Point<double> point(node.location().lon(), node.location().lat());
if (bbox.contains(point)) {
bboxNodes.add(node.id());
}
}
}
if (!ignored) {
Point<double> point{node.location().lon(), node.location().lat()};
if (_bbox.contains(point)) {
_bboxNodes.add(node.id());
}
}
}
}; };
class RelationHandler: public osmium::handler::Handler { class RelationHandler: public osmium::handler::Handler {
const pfaedle::osm::OsmFilter& filter; const pfaedle::osm::OsmFilter& _filter;
const pfaedle::osm::BBoxIdx& bbox; const pfaedle::osm::BBoxIdx& _bbox;
const pfaedle::osm::AttrKeySet& keepAttrs; const pfaedle::osm::AttrKeySet& _keepAttrs;
pfaedle::osm::RelLst& rels; pfaedle::osm::RelLst& _rels;
pfaedle::osm::RelMap& nodeRels; pfaedle::osm::RelMap& _nodeRels;
pfaedle::osm::RelMap& wayRels; pfaedle::osm::RelMap& _wayRels;
pfaedle::osm::Restrictions& restrictions; pfaedle::osm::Restrictions& _restrictions;
public:
public:
RelationHandler(const pfaedle::osm::OsmFilter& filter, RelationHandler(const pfaedle::osm::OsmFilter& filter,
const pfaedle::osm::BBoxIdx& bbox, const pfaedle::osm::BBoxIdx& bbox,
const pfaedle::osm::AttrKeySet& keepAttrs, const pfaedle::osm::AttrKeySet& keepAttrs,
@ -108,61 +105,68 @@ public:
pfaedle::osm::RelMap& nodeRels, pfaedle::osm::RelMap& nodeRels,
pfaedle::osm::RelMap& wayRels, pfaedle::osm::RelMap& wayRels,
pfaedle::osm::Restrictions& restrictions) : pfaedle::osm::Restrictions& restrictions) :
filter(filter), _filter(filter),
bbox(bbox), _bbox(bbox),
keepAttrs(keepAttrs), _keepAttrs(keepAttrs),
rels(rels), _rels(rels),
nodeRels(nodeRels), _nodeRels(nodeRels),
wayRels(wayRels), _wayRels(wayRels),
restrictions(restrictions){ _restrictions(restrictions)
{}
}
void relation(const osmium::Relation &relation) { void relation(const osmium::Relation &relation) {
OsmRel rel; OsmRel rel;
rel.id = relation.id(); rel.id = relation.id();
if(rel.id == 0) return;
for(const auto& tag: relation.tags()) { if (rel.id == 0) {
if (keepAttrs.count(tag.key())) { return;
}
for (const auto& tag : relation.tags()) {
if (_keepAttrs.count(tag.key())) {
rel.attrs[tag.key()] = tag.value(); rel.attrs[tag.key()] = tag.value();
} }
} }
for(const auto& member: relation.members()) { for (const auto& member : relation.members()) {
using osmium::item_type;
auto& obj = member.get_object(); auto& obj = member.get_object();
if (member.type() == osmium::item_type::node) { if (member.type() == item_type::node) {
rel.nodes.push_back(obj.id()); rel.nodes.push_back(obj.id());
rel.nodeRoles.emplace_back(member.role()); rel.nodeRoles.emplace_back(member.role());
} else if (member.type() == osmium::item_type::way) { } else if (member.type() == item_type::way) {
rel.ways.push_back(obj.id()); rel.ways.push_back(obj.id());
rel.wayRoles.emplace_back(member.role()); rel.wayRoles.emplace_back(member.role());
} }
} }
for (auto id : rel.nodes) { for (auto id : rel.nodes) {
nodeRels[id].push_back(rels.rels.size() - 1); _nodeRels[id].push_back(_rels.rels.size() - 1);
}
for (auto id : rel.ways) {
wayRels[id].push_back(rels.rels.size() - 1);
} }
uint64_t keepFlags = filter.keep(rel.attrs, pfaedle::osm::OsmFilter::REL); for (auto id : rel.ways) {
uint64_t dropFlags = filter.drop(rel.attrs, pfaedle::osm::OsmFilter::REL); _wayRels[id].push_back(_rels.rels.size() - 1);
}
uint64_t keepFlags = _filter.keep(rel.attrs, pfaedle::osm::OsmFilter::REL);
uint64_t dropFlags = _filter.drop(rel.attrs, pfaedle::osm::OsmFilter::REL);
if (rel.id && !rel.attrs.empty() && keepFlags && !dropFlags) { if (rel.id && !rel.attrs.empty() && keepFlags && !dropFlags) {
rel.keepFlags = keepFlags; rel.keepFlags = keepFlags;
rel.dropFlags = dropFlags; rel.dropFlags = dropFlags;
} }
rels.rels.push_back(rel.attrs); _rels.rels.push_back(rel.attrs);
if (rel.keepFlags & pfaedle::osm::REL_NO_DOWN) { if (rel.keepFlags & pfaedle::osm::REL_NO_DOWN) {
rels.flat.insert(rels.rels.size() - 1); _rels.flat.insert(_rels.rels.size() - 1);
} }
// more processing
{ {
if (!rel.attrs.count("type")) return; if (!rel.attrs.count("type")) return;
if (rel.attrs.find("type")->second != "restriction") return; if (rel.attrs.find("type")->second != "restriction") return;
bool pos = filter.posRestr(rel.attrs); bool pos = _filter.posRestr(rel.attrs);
bool neg = filter.negRestr(rel.attrs); bool neg = _filter.negRestr(rel.attrs);
if (!pos && !neg) return; if (!pos && !neg) return;
@ -190,9 +194,9 @@ public:
if (from && to && via) { if (from && to && via) {
if (pos) { if (pos) {
restrictions.pos[via].emplace_back(from, to); _restrictions.pos[via].emplace_back(from, to);
} else if (neg) { } else if (neg) {
restrictions.neg[via].emplace_back(from, to); _restrictions.neg[via].emplace_back(from, to);
} }
} }
} }
@ -200,26 +204,27 @@ public:
}; };
class WayHandler: public osmium::handler::Handler { class WayHandler: public osmium::handler::Handler {
Graph &g; pfaedle::trgraph::Graph& _graph;
const pfaedle::osm::RelLst &rels; const pfaedle::osm::RelLst& _rels;
const pfaedle::osm::RelMap &wayRels; const pfaedle::osm::RelMap& _wayRels;
const pfaedle::osm::OsmFilter &filter; const pfaedle::osm::OsmFilter& _filter;
const pfaedle::osm::OsmIdSet &bBoxNodes; const pfaedle::osm::OsmIdSet& _bBoxNodes;
pfaedle::osm::NIdMap &nodes; pfaedle::osm::NIdMap& _nodes;
pfaedle::osm::NIdMultMap &multiNodes; pfaedle::osm::NIdMultMap& _multiNodes;
const pfaedle::osm::OsmIdSet &noHupNodes; const pfaedle::osm::OsmIdSet& _noHupNodes;
const pfaedle::osm::AttrKeySet &keepAttrs; const pfaedle::osm::AttrKeySet& _keepAttrs;
const pfaedle::osm::Restrictions &rawRests; const pfaedle::osm::Restrictions& _restrictions;
pfaedle::osm::Restrictor &restor; pfaedle::osm::Restrictor& _restrictor;
const pfaedle::osm::FlatRels &fl; const pfaedle::osm::FlatRels& _fl;
pfaedle::osm::EdgTracks &eTracks; pfaedle::osm::EdgTracks& _eTracks;
const pfaedle::osm::OsmReadOpts &opts; const pfaedle::osm::OsmReadOpts& _opts;
std::map<TransitEdgeLine, TransitEdgeLine *> _lines; std::map<TransitEdgeLine, TransitEdgeLine *> _lines;
std::map<size_t, TransitEdgeLine *> _relLines; std::map<size_t, TransitEdgeLine *> _relLines;
public:
WayHandler(Graph &g, public:
WayHandler(pfaedle::trgraph::Graph &g,
const pfaedle::osm::RelLst &rels, const pfaedle::osm::RelLst &rels,
const pfaedle::osm::RelMap &wayRels, const pfaedle::osm::RelMap &wayRels,
const pfaedle::osm::OsmFilter &filter, const pfaedle::osm::OsmFilter &filter,
@ -233,41 +238,40 @@ public:
const pfaedle::osm::FlatRels &fl, const pfaedle::osm::FlatRels &fl,
pfaedle::osm::EdgTracks &eTracks, pfaedle::osm::EdgTracks &eTracks,
const pfaedle::osm::OsmReadOpts &opts) : const pfaedle::osm::OsmReadOpts &opts) :
g(g), _graph(g),
rels(rels), _rels(rels),
wayRels(wayRels), _wayRels(wayRels),
filter(filter), _filter(filter),
bBoxNodes(bBoxNodes), _bBoxNodes(bBoxNodes),
nodes(nodes), _nodes(nodes),
multiNodes(multiNodes), _multiNodes(multiNodes),
noHupNodes(noHupNodes), _noHupNodes(noHupNodes),
keepAttrs(keepAttrs), _keepAttrs(keepAttrs),
rawRests(rawRests), _restrictions(rawRests),
restor(restor), _restrictor(restor),
fl(fl), _fl(fl),
eTracks(eTracks), _eTracks(eTracks),
opts(opts) { _opts(opts)
{}
}
void way(const osmium::Way &way) { void way(const osmium::Way &way) {
OsmWay w; OsmWay w;
w.id = way.id(); w.id = way.id();
for (const auto &node: way.nodes()) { for (const auto &node : way.nodes()) {
w.nodes.emplace_back(node.ref()); w.nodes.emplace_back(node.ref());
} }
for (const auto &tag: way.tags()) { for (const auto &tag : way.tags()) {
if (keepAttrs.count(tag.key())) { if (_keepAttrs.count(tag.key())) {
w.attrs[tag.key()] = tag.value(); w.attrs[tag.key()] = tag.value();
} }
} }
bool valid = false; bool valid = false;
if (w.id && w.nodes.size() > 1 && if (w.id && w.nodes.size() > 1 &&
(relKeep(w.id, wayRels, fl) || filter.keep(w.attrs, pfaedle::osm::OsmFilter::WAY)) && (relKeep(w.id, _wayRels, _fl) || _filter.keep(w.attrs, pfaedle::osm::OsmFilter::WAY)) &&
!filter.drop(w.attrs, pfaedle::osm::OsmFilter::WAY)) { !_filter.drop(w.attrs, pfaedle::osm::OsmFilter::WAY)) {
for (auto nid : w.nodes) { for (auto nid : w.nodes) {
if (bBoxNodes.has(nid)) { if (_bBoxNodes.has(nid)) {
valid = true; valid = true;
break; break;
} }
@ -277,44 +281,48 @@ public:
if (valid) { if (valid) {
Node *last = nullptr; Node *last = nullptr;
std::vector<TransitEdgeLine *> lines; std::vector<TransitEdgeLine *> lines;
if (wayRels.count(w.id)) { if (_wayRels.count(w.id)) {
lines = getLines(wayRels.find(w.id)->second, rels, opts); lines = getLines(_wayRels.find(w.id)->second, _rels, _opts);
} }
std::string track = std::string track =
getAttrByFirstMatch(opts.edgePlatformRules, w.id, w.attrs, wayRels, getAttrByFirstMatch(_opts.edgePlatformRules, w.id, w.attrs, _wayRels, _rels, _opts.trackNormzer);
rels, opts.trackNormzer);
uint64_t lastnid = 0; uint64_t lastnid = 0;
for (auto nid : w.nodes) { for (auto nid : w.nodes) {
Node *n = nullptr; Node *n = nullptr;
if (noHupNodes.has(nid)) {
n = g.addNd(); if (_noHupNodes.has(nid)) {
multiNodes[nid].insert(n); n = _graph.addNd();
} else if (!nodes.count(nid)) { _multiNodes[nid].insert(n);
if (!bBoxNodes.has(nid)) { } else if (!_nodes.count(nid)) {
if (!_bBoxNodes.has(nid)) {
continue; continue;
} }
n = g.addNd(); n = _graph.addNd();
nodes[nid] = n; _nodes[nid] = n;
} else { } else {
n = nodes[nid]; n = _nodes[nid];
} }
if (last) { if (last) {
auto e = g.addEdg(last, n, EdgePL()); auto e = _graph.addEdg(last, n, EdgePL());
if (!e) if (!e)
continue; continue;
processRestr(nid, w.id, rawRests, e, n, &restor); processRestrictor(nid, w.id, _restrictions, e, n, &_restrictor);
processRestr(lastnid, w.id, rawRests, e, last, &restor); processRestrictor(lastnid, w.id, _restrictions, e, last, &_restrictor);
e->pl().addLines(lines); e->pl().addLines(lines);
e->pl().setLvl(filter.level(w.attrs)); e->pl().setLvl(_filter.level(w.attrs));
if (!track.empty()) { if (!track.empty()) {
eTracks[e] = track; _eTracks[e] = track;
} }
if (filter.oneway(w.attrs)) e->pl().setOneWay(1); if (_filter.oneway(w.attrs))
if (filter.onewayrev(w.attrs)) e->pl().setOneWay(2); e->pl().setOneWay(1);
if (_filter.onewayrev(w.attrs))
e->pl().setOneWay(2);
} }
lastnid = nid; lastnid = nid;
last = n; last = n;
@ -322,38 +330,36 @@ public:
} }
} }
static bool relKeep(uint64_t id, const pfaedle::osm::RelMap &rels, static bool relKeep(uint64_t id, const pfaedle::osm::RelMap &rels, const pfaedle::osm::FlatRels &fl) {
const pfaedle::osm::FlatRels &fl) {
auto it = rels.find(id); auto it = rels.find(id);
if (it == rels.end()) return false; if (it == rels.end())
for (auto relId : it->second) {
// as soon as any of this entities relations is not flat, return true
if (!fl.count(relId)) return true;
}
return false; return false;
return std::any_of(it->second.begin(), it->second.end(), [fl](decltype(*it->second.begin()) relId){
return !fl.count(relId);
});
} }
std::vector<TransitEdgeLine *> getLines( std::vector<TransitEdgeLine *> getLines(const std::vector<size_t> &edgeRels,
const std::vector<size_t> &edgeRels, const pfaedle::osm::RelLst &rels, const pfaedle::osm::RelLst &rels,
const pfaedle::osm::OsmReadOpts &ops) { const pfaedle::osm::OsmReadOpts &ops)
{
std::vector<TransitEdgeLine *> ret; std::vector<TransitEdgeLine *> ret;
for (size_t relId : edgeRels) { for (size_t relId : edgeRels) {
TransitEdgeLine *elp = nullptr; TransitEdgeLine* transitEdgeLinePointer = nullptr;
if (_relLines.count(relId)) { if (_relLines.count(relId)) {
elp = _relLines[relId]; transitEdgeLinePointer = _relLines[relId];
} else { } else {
TransitEdgeLine el; TransitEdgeLine transitEdgeLine;
bool found = false; bool found = false;
for (const auto &r : ops.relLinerules.sNameRule) { for (const auto &r : ops.relLinerules.sNameRule) {
for (const auto &relAttr : rels.rels[relId]) { for (const auto &relAttr : rels.rels[relId]) {
if (relAttr.first == r) { if (relAttr.first == r) {
el.shortName = ops.lineNormzer(pfxml::file::decode(relAttr.second)); transitEdgeLine.shortName = ops.lineNormzer(pfxml::file::decode(relAttr.second));
if (!el.shortName.empty()) found = true; if (!transitEdgeLine.shortName.empty()) found = true;
} }
} }
if (found) break; if (found) break;
@ -363,8 +369,8 @@ public:
for (const auto &r : ops.relLinerules.fromNameRule) { for (const auto &r : ops.relLinerules.fromNameRule) {
for (const auto &relAttr : rels.rels[relId]) { for (const auto &relAttr : rels.rels[relId]) {
if (relAttr.first == r) { if (relAttr.first == r) {
el.fromStr = ops.statNormzer(pfxml::file::decode(relAttr.second)); transitEdgeLine.fromStr = ops.statNormzer(pfxml::file::decode(relAttr.second));
if (!el.fromStr.empty()) found = true; if (!transitEdgeLine.fromStr.empty()) found = true;
} }
} }
if (found) break; if (found) break;
@ -374,32 +380,33 @@ public:
for (const auto &r : ops.relLinerules.toNameRule) { for (const auto &r : ops.relLinerules.toNameRule) {
for (const auto &relAttr : rels.rels[relId]) { for (const auto &relAttr : rels.rels[relId]) {
if (relAttr.first == r) { if (relAttr.first == r) {
el.toStr = ops.statNormzer(pfxml::file::decode(relAttr.second)); transitEdgeLine.toStr = ops.statNormzer(pfxml::file::decode(relAttr.second));
if (!el.toStr.empty()) found = true; if (!transitEdgeLine.toStr.empty()) found = true;
} }
} }
if (found) break; if (found) break;
} }
if (!el.shortName.size() && !el.fromStr.size() && !el.toStr.size()) if (transitEdgeLine.shortName.empty() && transitEdgeLine.fromStr.empty() &&
transitEdgeLine.toStr.empty())
continue; continue;
if (_lines.count(el)) { if (_lines.count(transitEdgeLine)) {
elp = _lines[el]; transitEdgeLinePointer = _lines[transitEdgeLine];
_relLines[relId] = elp; _relLines[relId] = transitEdgeLinePointer;
} else { } else {
elp = new TransitEdgeLine(el); transitEdgeLinePointer = new TransitEdgeLine(transitEdgeLine);
_lines[el] = elp; _lines[transitEdgeLine] = transitEdgeLinePointer;
_relLines[relId] = elp; _relLines[relId] = transitEdgeLinePointer;
} }
} }
ret.push_back(elp); ret.push_back(transitEdgeLinePointer);
} }
return ret; return ret;
} }
static void processRestr(uint64_t nid, uint64_t wid, static void processRestrictor(uint64_t nid, uint64_t wid,
const pfaedle::osm::Restrictions &rawRests, const pfaedle::osm::Restrictions &rawRests,
Edge *e, Edge *e,
Node *n, Node *n,
@ -467,18 +474,19 @@ public:
}; };
class NodeHandler2: public osmium::handler::Handler { class NodeHandler2: public osmium::handler::Handler {
Graph &g; pfaedle::trgraph::Graph& _graph;
const pfaedle::osm::RelLst &rels; const pfaedle::osm::RelLst& rels;
const pfaedle::osm::RelMap &nodeRels; const pfaedle::osm::RelMap& nodeRels;
const pfaedle::osm::OsmFilter &filter; const pfaedle::osm::OsmFilter& filter;
const pfaedle::osm::OsmIdSet &bBoxNodes; const pfaedle::osm::OsmIdSet& bBoxNodes;
pfaedle::osm::NIdMap &nodes; pfaedle::osm::NIdMap& nodes;
pfaedle::osm::NIdMultMap &multNodes; pfaedle::osm::NIdMultMap& multNodes;
pfaedle::osm::NodeSet &orphanStations; pfaedle::osm::NodeSet& orphanStations;
const pfaedle::osm::AttrKeySet &keepAttrs; const pfaedle::osm::AttrKeySet& keepAttrs;
const pfaedle::osm::FlatRels &fl; const pfaedle::osm::FlatRels& fl;
const pfaedle::osm::OsmReadOpts &opts; const pfaedle::osm::OsmReadOpts& opts;
public:
public:
NodeHandler2(Graph &g, NodeHandler2(Graph &g,
const pfaedle::osm::RelLst &rels, const pfaedle::osm::RelLst &rels,
const pfaedle::osm::RelMap &nodeRels, const pfaedle::osm::RelMap &nodeRels,
@ -490,7 +498,7 @@ public:
const pfaedle::osm::AttrKeySet &keepAttrs, const pfaedle::osm::AttrKeySet &keepAttrs,
const pfaedle::osm::FlatRels &fl, const pfaedle::osm::FlatRels &fl,
const pfaedle::osm::OsmReadOpts &opts) : const pfaedle::osm::OsmReadOpts &opts) :
g(g), _graph(g),
rels(rels), rels(rels),
nodeRels(nodeRels), nodeRels(nodeRels),
filter(filter), filter(filter),
@ -500,20 +508,19 @@ public:
orphanStations(orphanStations), orphanStations(orphanStations),
keepAttrs(keepAttrs), keepAttrs(keepAttrs),
fl(fl), fl(fl),
opts(opts) { opts(opts)
{}
} void node(const osmium::Node &node) {
void node(const osmium::Node& node) {
OsmNode nd; OsmNode nd;
for(const auto& tag: node.tags()) nd.id = node.id();
{ nd.lat = node.location().lat();
nd.lng = node.location().lon();
for (const auto &tag : node.tags()) {
if (keepAttrs.count(tag.key())) if (keepAttrs.count(tag.key()))
nd.attrs[tag.key()] = tag.value(); nd.attrs[tag.key()] = tag.value();
} }
nd.lat = node.location().lat();
nd.lng = node.location().lon();
nd.id = node.id();
bool valid = false; bool valid = false;
if (nd.id && if (nd.id &&
@ -524,28 +531,32 @@ public:
!filter.drop(nd.attrs, pfaedle::osm::OsmFilter::NODE))) { !filter.drop(nd.attrs, pfaedle::osm::OsmFilter::NODE))) {
valid = true; valid = true;
} }
pfaedle::osm::StAttrGroups attrGroups; pfaedle::osm::StAttrGroups attrGroups;
if(valid) if (valid) {
{ Node *n = nullptr;
Node* n = nullptr;
auto pos = util::geo::latLngToWebMerc<PFAEDLE_PRECISION>(nd.lat, nd.lng); auto pos = util::geo::latLngToWebMerc<PFAEDLE_PRECISION>(nd.lat, nd.lng);
if (nodes.count(nd.id)) { if (nodes.count(nd.id)) {
n = (nodes)[nd.id]; n = nodes[nd.id];
n->pl().setGeom(pos); n->pl().setGeom(pos);
if (filter.station(nd.attrs)) { if (filter.station(nd.attrs)) {
auto si = getStatInfo(n, nd.id, pos, nd.attrs, &attrGroups, nodeRels, auto si = getStatInfo(n, nd.id, pos, nd.attrs, &attrGroups, nodeRels, rels, opts);
rels, opts);
if (!si.isNull()) n->pl().setSI(si); if (!si.isNull())
n->pl().setSI(si);
} else if (filter.blocker(nd.attrs)) { } else if (filter.blocker(nd.attrs)) {
n->pl().setBlocker(); n->pl().setBlocker();
} }
} else if ((multNodes).count(nd.id)) { } else if (multNodes.count(nd.id)) {
for (auto* n : (multNodes)[nd.id]) { for (auto *n : multNodes[nd.id]) {
n->pl().setGeom(pos); n->pl().setGeom(pos);
if (filter.station(nd.attrs)) { if (filter.station(nd.attrs)) {
auto si = getStatInfo(n, nd.id, pos, nd.attrs, &attrGroups, nodeRels, auto si = getStatInfo(n, nd.id, pos, nd.attrs, &attrGroups, nodeRels, rels, opts);
rels, opts);
if (!si.isNull()) n->pl().setSI(si); if (!si.isNull())
n->pl().setSI(si);
} else if (filter.blocker(nd.attrs)) { } else if (filter.blocker(nd.attrs)) {
n->pl().setBlocker(); n->pl().setBlocker();
} }
@ -553,10 +564,12 @@ public:
} else { } else {
// these are nodes without any connected edges // these are nodes without any connected edges
if (filter.station(nd.attrs)) { if (filter.station(nd.attrs)) {
auto tmp = g.addNd(NodePL(pos)); auto tmp = _graph.addNd(NodePL(pos));
auto si = getStatInfo(tmp, nd.id, pos, nd.attrs, &attrGroups, nodeRels, auto si = getStatInfo(tmp, nd.id, pos, nd.attrs, &attrGroups, nodeRels, rels, opts);
rels, opts);
if (!si.isNull()) tmp->pl().setSI(si); if (!si.isNull())
tmp->pl().setSI(si);
if (tmp->pl().getSI()) { if (tmp->pl().getSI()) {
tmp->pl().getSI()->setIsFromOsm(false); tmp->pl().getSI()->setIsFromOsm(false);
orphanStations.insert(tmp); orphanStations.insert(tmp);
@ -567,54 +580,56 @@ public:
} }
bool relKeep(uint64_t id, const pfaedle::osm::RelMap& rels, const pfaedle::osm::FlatRels& fl) const { static bool relKeep(uint64_t id, const pfaedle::osm::RelMap &rels, const pfaedle::osm::FlatRels &fl) {
auto it = rels.find(id); auto it = rels.find(id);
if (it == rels.end()) return false; if (it == rels.end())
return false;
for (uint64_t relId : it->second) { for (uint64_t relId : it->second) {
// as soon as any of this entities relations is not flat, return true // as soon as any of this entities relations is not flat, return true
if (!fl.count(relId)) return true; if (!fl.count(relId))
return true;
} }
return false; return false;
} }
Nullable<StatInfo> getStatInfo(Node* node, uint64_t nid, static Nullable<StatInfo> getStatInfo(Node *node, uint64_t nid,
const POINT& pos, const pfaedle::osm::AttrMap& m, const POINT &pos,
pfaedle::osm::StAttrGroups* groups, const pfaedle::osm::AttrMap &m,
const pfaedle::osm::RelMap& nodeRels, pfaedle::osm::StAttrGroups *groups,
const pfaedle::osm::RelLst& rels, const pfaedle::osm::RelMap &nodeRels,
const pfaedle::osm::OsmReadOpts& ops) const { const pfaedle::osm::RelLst &rels,
std::string platform; const pfaedle::osm::OsmReadOpts &ops) {
std::vector<std::string> names; std::vector<std::string> names =
getAttrMatchRanked(ops.statAttrRules.nameRule, nid, m, nodeRels, rels, ops.statNormzer);
std::string platform =
getAttrByFirstMatch(ops.statAttrRules.platformRule, nid, m, nodeRels, rels, ops.trackNormzer);
names = getAttrMatchRanked(ops.statAttrRules.nameRule, nid, m, nodeRels, rels, if (names.empty()) {
ops.statNormzer); return Nullable<StatInfo>();
platform = getAttrByFirstMatch(ops.statAttrRules.platformRule, nid, m, }
nodeRels, rels, ops.trackNormzer);
if (!names.size()) return Nullable<StatInfo>();
auto ret = StatInfo(names[0], platform, true); auto ret = StatInfo(names[0], platform, true);
#ifdef PFAEDLE_STATION_IDS #ifdef PFAEDLE_STATION_IDS
ret.setId(getAttrByFirstMatch(ops.statAttrRules.idRule, nid, m, nodeRels, ret.setId(getAttrByFirstMatch(ops.statAttrRules.idRule, nid, m, nodeRels, rels, ops.idNormzer));
rels, ops.idNormzer));
#endif #endif
for (size_t i = 1; i < names.size(); i++) ret.addAltName(names[i]); for (size_t i = 1; i < names.size(); i++) {
ret.addAltName(names[i]);
}
bool groupFound = false; bool groupFound = false;
for (const auto& rule : ops.statGroupNAttrRules) { for (const auto &rule : ops.statGroupNAttrRules) {
if (groupFound) break; if (groupFound) break;
std::string ruleVal = getAttr(rule.attr, nid, m, nodeRels, rels); std::string ruleVal = getAttr(rule.attr, nid, m, nodeRels, rels);
if (!ruleVal.empty()) { if (!ruleVal.empty()) {
// check if a matching group exists // check if a matching group exists
for (auto* group : (*groups)[rule.attr.attr][ruleVal]) { for (auto *group : (*groups)[rule.attr.attr][ruleVal]) {
if (groupFound) break; if (groupFound) break;
for (const auto* member : group->getNodes()) { for (const auto *member : group->getNodes()) {
if (webMercMeterDist(*member->pl().getGeom(), pos) <= rule.maxDist) { if (webMercMeterDist(*member->pl().getGeom(), pos) <= rule.maxDist) {
// ok, group is matching // ok, group is matching
groupFound = true; groupFound = true;
@ -628,14 +643,14 @@ public:
} }
if (!groupFound) { if (!groupFound) {
for (const auto& rule : ops.statGroupNAttrRules) { for (const auto &rule : ops.statGroupNAttrRules) {
std::string ruleVal = getAttr(rule.attr, nid, m, nodeRels, rels); std::string ruleVal = getAttr(rule.attr, nid, m, nodeRels, rels);
if (!ruleVal.empty()) { if (!ruleVal.empty()) {
// add new group // add new group
auto* g = new StatGroup(); auto *group = new StatGroup();
if (node) g->addNode(node); if (node) group->addNode(node);
ret.setGroup(g); ret.setGroup(group);
(*groups)[rule.attr.attr][ruleVal].push_back(g); (*groups)[rule.attr.attr][ruleVal].push_back(group);
break; break;
} }
} }
@ -644,43 +659,52 @@ public:
return ret; return ret;
} }
std::string getAttrByFirstMatch(const pfaedle::osm::DeepAttrLst& rule, uint64_t id, static std::string getAttrByFirstMatch(const pfaedle::osm::DeepAttrLst &rule,
const pfaedle::osm::AttrMap& attrs, uint64_t id,
const pfaedle::osm::RelMap& entRels, const pfaedle::osm::AttrMap &attrs,
const pfaedle::osm::RelLst& rels, const pfaedle::osm::RelMap &entRels,
const Normalizer& norm) const { const pfaedle::osm::RelLst &rels,
const Normalizer &norm) {
std::string ret; std::string ret;
for (const auto& s : rule) { for (const auto &s : rule) {
ret = norm(pfxml::file::decode(getAttr(s, id, attrs, entRels, rels))); ret = norm(pfxml::file::decode(getAttr(s, id, attrs, entRels, rels)));
if (!ret.empty()) return ret; if (!ret.empty()) {
break;
}
} }
return ret; return ret;
} }
std::vector<std::string> getAttrMatchRanked( static std::vector<std::string> getAttrMatchRanked(const pfaedle::osm::DeepAttrLst &rule,
const pfaedle::osm::DeepAttrLst& rule, uint64_t id, const pfaedle::osm::AttrMap& attrs, uint64_t id,
const pfaedle::osm::RelMap& entRels, const pfaedle::osm::RelLst& rels, const Normalizer& norm) const { const pfaedle::osm::AttrMap &attrs,
const pfaedle::osm::RelMap &entRels,
const pfaedle::osm::RelLst &rels,
const Normalizer &norm) {
std::vector<std::string> ret; std::vector<std::string> ret;
for (const auto& s : rule) { for (const auto &s : rule) {
std::string tmp = std::string tmp = norm(pfxml::file::decode(getAttr(s, id, attrs, entRels, rels)));
norm(pfxml::file::decode(getAttr(s, id, attrs, entRels, rels))); if (!tmp.empty()) {
if (!tmp.empty()) ret.push_back(tmp); ret.push_back(tmp);
}
} }
return ret; return ret;
} }
std::string getAttr(const pfaedle::osm::DeepAttrRule& s, uint64_t id, static std::string getAttr(const pfaedle::osm::DeepAttrRule &s,
const pfaedle::osm::AttrMap& attrs, const pfaedle::osm::RelMap& entRels, uint64_t id,
const pfaedle::osm::RelLst& rels) const { const pfaedle::osm::AttrMap &attrs,
const pfaedle::osm::RelMap &entRels,
const pfaedle::osm::RelLst &rels) {
if (s.relRule.kv.first.empty()) { if (s.relRule.kv.first.empty()) {
if (attrs.find(s.attr) != attrs.end()) { if (attrs.find(s.attr) != attrs.end()) {
return attrs.find(s.attr)->second; return attrs.find(s.attr)->second;
} }
} else { } else {
if (entRels.count(id)) { if (entRels.count(id)) {
for (const auto& relId : entRels.find(id)->second) { for (const auto &relId : entRels.find(id)->second) {
if (pfaedle::osm::OsmFilter::contained(rels.rels[relId], s.relRule.kv)) { if (pfaedle::osm::OsmFilter::contained(rels.rels[relId], s.relRule.kv)) {
if (rels.rels[relId].count(s.attr)) { if (rels.rels[relId].count(s.attr)) {
return rels.rels[relId].find(s.attr)->second; return rels.rels[relId].find(s.attr)->second;
@ -692,6 +716,7 @@ public:
return ""; return "";
} }
}; };
// _____________________________________________________________________________ // _____________________________________________________________________________
bool EqSearch::operator()(const Node* cand, const StatInfo* si) const { bool EqSearch::operator()(const Node* cand, const StatInfo* si) const {
if (orphanSnap && cand->pl().getSI() && if (orphanSnap && cand->pl().getSI() &&
@ -729,19 +754,21 @@ void OsmBuilder::read(const std::string& path, const OsmReadOpts& opts,
OsmFilter filter(opts); OsmFilter filter(opts);
osmium::io::Reader reader{path, osmium::osm_entity_bits::node | osmium::osm_entity_bits::way |osmium::osm_entity_bits::relation}; osmium::io::Reader reader {path,
osmium::osm_entity_bits::node |
osmium::osm_entity_bits::way |
osmium::osm_entity_bits::relation};
osmium::io::Reader reader_nodes{path,
osmium::osm_entity_bits::node};
NodeHandler nodeHandler(filter, bbox, bboxNodes, noHupNodes); NodeHandler nodeHandler(filter, bbox, bboxNodes, noHupNodes);
RelationHandler relationHandler(filter, bbox, attrKeys[2],intmRels, nodeRels, wayRels, rawRests); RelationHandler relationHandler(filter, bbox, attrKeys[2], intmRels, nodeRels, wayRels, rawRests);
WayHandler wayHandler(*g, intmRels, wayRels, filter, bboxNodes, nodes, multNodes, WayHandler wayHandler(*g, intmRels, wayRels, filter, bboxNodes, nodes, multNodes, noHupNodes,
noHupNodes, attrKeys[1], rawRests, *res, attrKeys[1], rawRests, *res, intmRels.flat, eTracks, opts);
intmRels.flat, eTracks, opts);
osmium::apply(reader, nodeHandler, relationHandler, wayHandler); osmium::apply(reader, nodeHandler, relationHandler, wayHandler);
NodeHandler2 nodeHandler2(*g, intmRels, nodeRels, filter, bboxNodes, nodes, multNodes, orphanStations,
osmium::io::Reader reader_nodes{path, osmium::osm_entity_bits::node}; attrKeys[0], intmRels.flat, opts);
NodeHandler2 nodeHandler2(*g, intmRels, nodeRels, filter, bboxNodes, nodes,
multNodes, orphanStations, attrKeys[0], intmRels.flat, opts);
osmium::apply(reader_nodes, nodeHandler2); osmium::apply(reader_nodes, nodeHandler2);
// we do four passes of the file here to be as memory creedy as possible: // we do four passes of the file here to be as memory creedy as possible:

View file

@ -16,7 +16,7 @@ namespace osm {
class OsmFilter { class OsmFilter {
public: public:
enum Type : uint64_t { NODE = 16, WAY = 8, REL = 4, ALL = 0 }; enum Type : uint64_t { NODE = 16, WAY = 8, REL = 4, ALL = 0 };
OsmFilter() {} OsmFilter() = default;
OsmFilter(const MultAttrMap& keep, const MultAttrMap& drop); OsmFilter(const MultAttrMap& keep, const MultAttrMap& drop);
explicit OsmFilter(const OsmReadOpts& o); explicit OsmFilter(const OsmReadOpts& o);
uint64_t keep(const AttrMap& attrs, Type t) const; uint64_t keep(const AttrMap& attrs, Type t) const;