refactoring

This commit is contained in:
Patrick Brosi 2019-02-03 12:48:48 +01:00
parent 2fb157ef37
commit 4733b0c676
26 changed files with 774 additions and 406 deletions

View file

@ -65,7 +65,6 @@ void OsmBuilder::read(const std::string& path, const OsmReadOpts& opts,
Graph* g, const BBoxIdx& bbox, size_t gridSize,
router::FeedStops* fs, Restrictor* res) {
if (!bbox.size()) return;
if (!fs->size()) return;
LOG(INFO) << "Reading OSM file " << path << " ... ";
@ -141,119 +140,8 @@ void OsmBuilder::read(const std::string& path, const OsmReadOpts& opts,
LOG(VDEBUG) << "Writing edge geoms...";
writeGeoms(g);
{
NodeGrid sng = buildNodeIdx(g, gridSize, bbox.getFullWebMercBox(), true);
EdgeGrid eg = buildEdgeIdx(g, gridSize, bbox.getFullWebMercBox());
LOG(DEBUG) << "Grid size of " << sng.getXWidth() << "x" << sng.getYHeight();
for (double d : opts.maxSnapDistances) {
for (auto s : orphanStations) {
POINT geom = *s->pl().getGeom();
NodePL pl = s->pl();
pl.getSI()->setIsFromOsm(false);
const auto& r =
snapStation(g, &pl, &eg, &sng, opts, res, false, false, d);
groupStats(r);
for (auto n : r) {
// if the snapped station is very near to the original OSM
// station, set is-from-osm to true
if (webMercMeterDist(geom, *n->pl().getGeom()) <
opts.maxOsmStationDistance) {
if (n->pl().getSI()) n->pl().getSI()->setIsFromOsm(true);
}
}
}
}
std::vector<const Stop*> notSnapped;
for (auto& s : *fs) {
bool snapped = false;
auto pl = plFromGtfs(s.first, opts);
for (size_t i = 0; i < opts.maxSnapDistances.size(); i++) {
double d = opts.maxSnapDistances[i];
StatGroup* group = groupStats(
snapStation(g, &pl, &eg, &sng, opts, res,
i == opts.maxSnapDistances.size() - 1, false, d));
if (group) {
group->addStop(s.first);
(*fs)[s.first] = *group->getNodes().begin();
snapped = true;
}
}
if (!snapped) {
LOG(VDEBUG) << "Could not snap station "
<< "(" << pl.getSI()->getName() << ")"
<< " (" << s.first->getLat() << "," << s.first->getLng()
<< ") in normal run, trying again later in orphan mode.";
if (!bbox.contains(*pl.getGeom())) {
LOG(VDEBUG) << "Note: '" << pl.getSI()->getName()
<< "' does not lie within the bounds for this graph and "
"may be a stray station";
}
notSnapped.push_back(s.first);
}
}
if (notSnapped.size())
LOG(VDEBUG) << notSnapped.size() << " stations could not be snapped in "
"normal run, trying again in orphan "
"mode.";
// try again, but aggressively snap to orphan OSM stations which have
// not been assigned to any GTFS stop yet
for (auto& s : notSnapped) {
bool snapped = false;
auto pl = plFromGtfs(s, opts);
for (size_t i = 0; i < opts.maxSnapDistances.size(); i++) {
double d = opts.maxSnapDistances[i];
StatGroup* group = groupStats(
snapStation(g, &pl, &eg, &sng, opts, res,
i == opts.maxSnapDistances.size() - 1, true, d));
if (group) {
group->addStop(s);
// add the added station name as an alt name to ensure future
// similarity
for (auto n : group->getNodes()) {
if (n->pl().getSI())
n->pl().getSI()->addAltName(pl.getSI()->getName());
}
(*fs)[s] = *group->getNodes().begin();
snapped = true;
}
}
if (!snapped) {
// finally give up
// add a group with only this stop in it
StatGroup* dummyGroup = new StatGroup();
Node* dummyNode = g->addNd(pl);
dummyNode->pl().getSI()->setGroup(dummyGroup);
dummyGroup->addNode(dummyNode);
dummyGroup->addStop(s);
(*fs)[s] = dummyNode;
if (!bbox.contains(*pl.getGeom())) {
LOG(VDEBUG) << "Could not snap station "
<< "(" << pl.getSI()->getName() << ")"
<< " (" << s->getLat() << "," << s->getLng() << ")";
LOG(VDEBUG) << "Note: '" << pl.getSI()->getName()
<< "' does not lie within the bounds for this graph and "
"may be a stray station";
} else {
// only warn if it is contained in the BBOX for this graph
LOG(WARN) << "Could not snap station "
<< "(" << pl.getSI()->getName() << ")"
<< " (" << s->getLat() << "," << s->getLng() << ")";
}
}
}
}
LOG(VDEBUG) << "Snapping stations...";
snapStats(opts, g, bbox, gridSize, fs, res, orphanStations);
LOG(VDEBUG) << "Deleting orphan nodes...";
deleteOrphNds(g);
@ -534,12 +422,17 @@ void OsmBuilder::readWriteWays(xml::File* i, util::xml::XmlWriter* o,
}
// _____________________________________________________________________________
NodePL OsmBuilder::plFromGtfs(const Stop* s, const OsmReadOpts& ops) const {
NodePL OsmBuilder::plFromGtfs(const Stop* s, const OsmReadOpts& ops) {
NodePL ret(
util::geo::latLngToWebMerc<PFAEDLE_PRECISION>(s->getLat(), s->getLng()),
StatInfo(ops.statNormzer(s->getName()),
ops.trackNormzer(s->getPlatformCode()), false));
#ifdef PFAEDLE_STATION_IDS
// debug feature, store station id from GTFS
ret.getSI()->setId(s->getId());
#endif
if (s->getParentStation()) {
ret.getSI()->addAltName(ops.statNormzer(s->getParentStation()->getName()));
}
@ -1109,6 +1002,11 @@ Nullable<StatInfo> OsmBuilder::getStatInfo(Node* node, osmid nid,
auto ret = StatInfo(names[0], platform, true);
#ifdef PFAEDLE_STATION_IDS
ret.setId(getAttrByFirstMatch(ops.statAttrRules.idRule, nid, m, nodeRels,
rels, ops.idNormzer));
#endif
for (size_t i = 1; i < names.size(); i++) ret.addAltName(names[i]);
bool groupFound = false;
@ -1151,26 +1049,17 @@ Nullable<StatInfo> OsmBuilder::getStatInfo(Node* node, osmid nid,
}
// _____________________________________________________________________________
double OsmBuilder::dist(const Node* a, const Node* b) const {
double OsmBuilder::dist(const Node* a, const Node* b) {
return webMercMeterDist(*a->pl().getGeom(), *b->pl().getGeom());
}
// _____________________________________________________________________________
double OsmBuilder::webMercDistFactor(const POINT& a) const {
// euclidean distance on web mercator is in meters on equator,
// and proportional to cos(lat) in both y directions
double lat = 2 * atan(exp(a.getY() / 6378137.0)) - 1.5707965;
return cos(lat);
}
// _____________________________________________________________________________
double OsmBuilder::webMercDist(const Node* a, const Node* b) const {
double OsmBuilder::webMercDist(const Node* a, const Node* b) {
return webMercMeterDist(*a->pl().getGeom(), *b->pl().getGeom());
}
// _____________________________________________________________________________
void OsmBuilder::writeGeoms(Graph* g) const {
void OsmBuilder::writeGeoms(Graph* g) {
for (auto* n : *g->getNds()) {
for (auto* e : n->getAdjListOut()) {
e->pl().addPoint(*e->getFrom()->pl().getGeom());
@ -1181,35 +1070,47 @@ void OsmBuilder::writeGeoms(Graph* g) const {
}
// _____________________________________________________________________________
void OsmBuilder::fixGaps(Graph* g, NodeGrid* ng) const {
void OsmBuilder::fixGaps(Graph* g, NodeGrid* ng) {
double METER = 1;
for (auto* n : *g->getNds()) {
if (n->getInDeg() + n->getOutDeg() == 1) {
// get all nodes in a 1 meter distance
// get all nodes in distance
std::set<Node*> ret;
ng->get(util::geo::pad(util::geo::getBoundingBox(*n->pl().getGeom()), 1),
double distor = util::geo::webMercDistFactor(*n->pl().getGeom());
ng->get(util::geo::pad(util::geo::getBoundingBox(*n->pl().getGeom()),
METER / distor),
&ret);
for (auto* nb : ret) {
if (nb != n && (nb->getInDeg() + nb->getOutDeg()) == 1 &&
webMercDist(nb, n) <= 1.0 && !nb->pl().getSI() &&
!n->pl().getSI()) {
Node* otherN;
if (nb->getOutDeg())
otherN = (*nb->getAdjListOut().begin())->getOtherNd(nb);
else
otherN = (*nb->getAdjListIn().begin())->getOtherNd(nb);
LINE l;
l.push_back(*otherN->pl().getGeom());
l.push_back(*n->pl().getGeom());
webMercDist(nb, n) <= METER / distor) {
// special case: both node are non-stations, move
// the end point nb to n and delete nb
if (!nb->pl().getSI() && !n->pl().getSI()) {
Node* otherN;
if (nb->getOutDeg())
otherN = (*nb->getAdjListOut().begin())->getOtherNd(nb);
else
otherN = (*nb->getAdjListIn().begin())->getOtherNd(nb);
LINE l;
l.push_back(*otherN->pl().getGeom());
l.push_back(*n->pl().getGeom());
Edge* e;
if (nb->getOutDeg())
e = g->addEdg(otherN, n, (*nb->getAdjListOut().begin())->pl());
else
e = g->addEdg(otherN, n, (*nb->getAdjListIn().begin())->pl());
if (e) {
*e->pl().getGeom() = l;
g->delNd(nb);
ng->remove(nb);
Edge* e;
if (nb->getOutDeg())
e = g->addEdg(otherN, n, (*nb->getAdjListOut().begin())->pl());
else
e = g->addEdg(otherN, n, (*nb->getAdjListIn().begin())->pl());
if (e) {
*e->pl().getGeom() = l;
g->delNd(nb);
ng->remove(nb);
}
} else {
// if one of the nodes is a station, just add an edge between them
if (nb->getOutDeg())
g->addEdg(n, nb, (*nb->getAdjListOut().begin())->pl());
else
g->addEdg(n, nb, (*nb->getAdjListIn().begin())->pl());
}
}
}
@ -1219,7 +1120,7 @@ void OsmBuilder::fixGaps(Graph* g, NodeGrid* ng) const {
// _____________________________________________________________________________
EdgeGrid OsmBuilder::buildEdgeIdx(Graph* g, size_t size,
const BOX& webMercBox) const {
const BOX& webMercBox) {
EdgeGrid ret(size, size, webMercBox, false);
for (auto* n : *g->getNds()) {
for (auto* e : n->getAdjListOut()) {
@ -1232,7 +1133,7 @@ EdgeGrid OsmBuilder::buildEdgeIdx(Graph* g, size_t size,
// _____________________________________________________________________________
NodeGrid OsmBuilder::buildNodeIdx(Graph* g, size_t size, const BOX& webMercBox,
bool which) const {
bool which) {
NodeGrid ret(size, size, webMercBox, false);
for (auto* n : *g->getNds()) {
if (!which && n->getInDeg() + n->getOutDeg() == 1)
@ -1246,7 +1147,7 @@ NodeGrid OsmBuilder::buildNodeIdx(Graph* g, size_t size, const BOX& webMercBox,
// _____________________________________________________________________________
Node* OsmBuilder::depthSearch(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns, double minAngle,
const SearchFunc& sfunc) const {
const SearchFunc& sfunc) {
// shortcuts
double dFrom = webMercMeterDist(*e->getFrom()->pl().getGeom(), p);
double dTo = webMercMeterDist(*e->getTo()->pl().getGeom(), p);
@ -1310,23 +1211,22 @@ Node* OsmBuilder::depthSearch(const Edge* e, const StatInfo* si, const POINT& p,
// _____________________________________________________________________________
bool OsmBuilder::isBlocked(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns,
double minAngle) const {
double maxD, int maxFullTurns, double minAngle) {
return depthSearch(e, si, p, maxD, maxFullTurns, minAngle, BlockSearch());
}
// _____________________________________________________________________________
Node* OsmBuilder::eqStatReach(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns, double minAngle,
bool orphanSnap) const {
bool orphanSnap) {
return depthSearch(e, si, p, maxD, maxFullTurns, minAngle,
EqSearch(orphanSnap));
}
// _____________________________________________________________________________
void OsmBuilder::getEdgCands(const POINT& geom, EdgeCandPQ* ret, EdgeGrid* eg,
double d) const {
double distor = webMercDistFactor(geom);
double d) {
double distor = util::geo::webMercDistFactor(geom);
std::set<Edge*> neighs;
BOX box = util::geo::pad(util::geo::getBoundingBox(geom), d / distor);
eg->get(box, &neighs);
@ -1343,9 +1243,9 @@ void OsmBuilder::getEdgCands(const POINT& geom, EdgeCandPQ* ret, EdgeGrid* eg,
// _____________________________________________________________________________
std::set<Node*> OsmBuilder::getMatchingNds(const NodePL& s, NodeGrid* ng,
double d) const {
double d) {
std::set<Node*> ret;
double distor = webMercDistFactor(*s.getGeom());
double distor = util::geo::webMercDistFactor(*s.getGeom());
std::set<Node*> neighs;
BOX box = util::geo::pad(util::geo::getBoundingBox(*s.getGeom()), d / distor);
ng->get(box, &neighs);
@ -1361,8 +1261,8 @@ std::set<Node*> OsmBuilder::getMatchingNds(const NodePL& s, NodeGrid* ng,
}
// _____________________________________________________________________________
Node* OsmBuilder::getMatchingNd(const NodePL& s, NodeGrid* ng, double d) const {
double distor = webMercDistFactor(*s.getGeom());
Node* OsmBuilder::getMatchingNd(const NodePL& s, NodeGrid* ng, double d) {
double distor = util::geo::webMercDistFactor(*s.getGeom());
std::set<Node*> neighs;
BOX box = util::geo::pad(util::geo::getBoundingBox(*s.getGeom()), d / distor);
ng->get(box, &neighs);
@ -1387,7 +1287,7 @@ Node* OsmBuilder::getMatchingNd(const NodePL& s, NodeGrid* ng, double d) const {
std::set<Node*> OsmBuilder::snapStation(Graph* g, NodePL* s, EdgeGrid* eg,
NodeGrid* sng, const OsmReadOpts& opts,
Restrictor* restor, bool surrHeur,
bool orphSnap, double d) const {
bool orphSnap, double d) {
assert(s->getSI());
std::set<Node*> ret;
@ -1467,6 +1367,13 @@ std::set<Node*> OsmBuilder::snapStation(Graph* g, NodePL* s, EdgeGrid* eg,
ret.insert(n);
}
} else {
// if the snapped station is very near to the original OSM station
// write additional info from this snap station to the equivalent stat
if (webMercMeterDist(*s->getGeom(), *eq->pl().getGeom()) <
opts.maxOsmStationDistance) {
if (eq->pl().getSI()->getTrack().empty())
eq->pl().getSI()->setTrack(s->getSI()->getTrack());
}
ret.insert(eq);
}
}
@ -1475,7 +1382,7 @@ std::set<Node*> OsmBuilder::snapStation(Graph* g, NodePL* s, EdgeGrid* eg,
}
// _____________________________________________________________________________
StatGroup* OsmBuilder::groupStats(const NodeSet& s) const {
StatGroup* OsmBuilder::groupStats(const NodeSet& s) {
if (!s.size()) return 0;
// reference group
StatGroup* ret = new StatGroup();
@ -1664,10 +1571,19 @@ void OsmBuilder::getKeptAttrKeys(const OsmReadOpts& opts,
sets[2].insert(i.attr);
}
}
for (const auto& i : opts.statAttrRules.idRule) {
if (i.relRule.kv.first.empty()) {
sets[0].insert(i.attr);
} else {
sets[2].insert(i.relRule.kv.first);
sets[2].insert(i.attr);
}
}
}
// _____________________________________________________________________________
void OsmBuilder::deleteOrphEdgs(Graph* g, const OsmReadOpts& opts) const {
void OsmBuilder::deleteOrphEdgs(Graph* g, const OsmReadOpts& opts) {
size_t ROUNDS = 3;
for (size_t c = 0; c < ROUNDS; c++) {
for (auto i = g->getNds()->begin(); i != g->getNds()->end();) {
@ -1692,11 +1608,10 @@ void OsmBuilder::deleteOrphEdgs(Graph* g, const OsmReadOpts& opts) const {
}
// _____________________________________________________________________________
void OsmBuilder::deleteOrphNds(Graph* g) const {
void OsmBuilder::deleteOrphNds(Graph* g) {
for (auto i = g->getNds()->begin(); i != g->getNds()->end();) {
if ((*i)->getInDeg() + (*i)->getOutDeg() == 0 &&
!((*i)->pl().getSI() && (*i)->pl().getSI()->getGroup() &&
(*i)->pl().getSI()->getGroup()->getStops().size())) {
!((*i)->pl().getSI() && (*i)->pl().getSI()->getGroup())) {
i = g->delNd(i);
// TODO(patrick): maybe delete from node grid?
} else {
@ -1706,7 +1621,7 @@ void OsmBuilder::deleteOrphNds(Graph* g) const {
}
// _____________________________________________________________________________
bool OsmBuilder::edgesSim(const Edge* a, const Edge* b) const {
bool OsmBuilder::edgesSim(const Edge* a, const Edge* b) {
if (static_cast<bool>(a->pl().oneWay()) ^ static_cast<bool>(b->pl().oneWay()))
return false;
if (a->pl().lvl() != b->pl().lvl()) return false;
@ -1721,7 +1636,7 @@ bool OsmBuilder::edgesSim(const Edge* a, const Edge* b) const {
}
// _____________________________________________________________________________
const EdgePL& OsmBuilder::mergeEdgePL(Edge* a, Edge* b) const {
const EdgePL& OsmBuilder::mergeEdgePL(Edge* a, Edge* b) {
const Node* n = 0;
if (a->getFrom() == b->getFrom())
n = a->getFrom();
@ -1760,7 +1675,7 @@ const EdgePL& OsmBuilder::mergeEdgePL(Edge* a, Edge* b) const {
}
// _____________________________________________________________________________
void OsmBuilder::collapseEdges(Graph* g) const {
void OsmBuilder::collapseEdges(Graph* g) {
for (auto* n : *g->getNds()) {
if (n->getOutDeg() + n->getInDeg() != 2 || n->pl().getSI()) continue;
@ -1795,7 +1710,7 @@ void OsmBuilder::collapseEdges(Graph* g) const {
}
// _____________________________________________________________________________
void OsmBuilder::simplifyGeoms(Graph* g) const {
void OsmBuilder::simplifyGeoms(Graph* g) {
for (auto* n : *g->getNds()) {
for (auto* e : n->getAdjListOut()) {
(*e->pl().getGeom()) = util::geo::simplify(*e->pl().getGeom(), 0.5);
@ -1804,7 +1719,7 @@ void OsmBuilder::simplifyGeoms(Graph* g) const {
}
// _____________________________________________________________________________
uint32_t OsmBuilder::writeComps(Graph* g) const {
uint32_t OsmBuilder::writeComps(Graph* g) {
Component* comp = new Component{7};
uint32_t numC = 0;
@ -1843,7 +1758,7 @@ uint32_t OsmBuilder::writeComps(Graph* g) const {
}
// _____________________________________________________________________________
void OsmBuilder::writeEdgeTracks(const EdgTracks& tracks) const {
void OsmBuilder::writeEdgeTracks(const EdgTracks& tracks) {
for (const auto& tr : tracks) {
if (tr.first->getTo()->pl().getSI() &&
tr.first->getTo()->pl().getSI()->getTrack().empty()) {
@ -1857,7 +1772,7 @@ void OsmBuilder::writeEdgeTracks(const EdgTracks& tracks) const {
}
// _____________________________________________________________________________
void OsmBuilder::writeODirEdgs(Graph* g, Restrictor* restor) const {
void OsmBuilder::writeODirEdgs(Graph* g, Restrictor* restor) {
for (auto* n : *g->getNds()) {
for (auto* e : n->getAdjListOut()) {
if (g->getEdg(e->getTo(), e->getFrom())) continue;
@ -1868,7 +1783,7 @@ void OsmBuilder::writeODirEdgs(Graph* g, Restrictor* restor) const {
}
// _____________________________________________________________________________
void OsmBuilder::writeSelfEdgs(Graph* g) const {
void OsmBuilder::writeSelfEdgs(Graph* g) {
for (auto* n : *g->getNds()) {
if (n->pl().getSI() && n->getAdjListOut().size() == 0) {
g->addEdg(n, n);
@ -1877,7 +1792,7 @@ void OsmBuilder::writeSelfEdgs(Graph* g) const {
}
// _____________________________________________________________________________
bool OsmBuilder::keepFullTurn(const trgraph::Node* n, double ang) const {
bool OsmBuilder::keepFullTurn(const trgraph::Node* n, double ang) {
if (n->getInDeg() + n->getOutDeg() != 1) return false;
const trgraph::Edge* e = 0;
@ -1915,3 +1830,123 @@ bool OsmBuilder::keepFullTurn(const trgraph::Node* n, double ang) const {
return false;
}
// _____________________________________________________________________________
void OsmBuilder::snapStats(const OsmReadOpts& opts, Graph* g,
const BBoxIdx& bbox, size_t gridSize,
router::FeedStops* fs, Restrictor* res,
const NodeSet& orphanStations) {
NodeGrid sng = buildNodeIdx(g, gridSize, bbox.getFullWebMercBox(), true);
EdgeGrid eg = buildEdgeIdx(g, gridSize, bbox.getFullWebMercBox());
LOG(DEBUG) << "Grid size of " << sng.getXWidth() << "x" << sng.getYHeight();
for (double d : opts.maxSnapDistances) {
for (auto s : orphanStations) {
POINT geom = *s->pl().getGeom();
NodePL pl = s->pl();
pl.getSI()->setIsFromOsm(false);
const auto& r =
snapStation(g, &pl, &eg, &sng, opts, res, false, false, d);
groupStats(r);
for (auto n : r) {
// if the snapped station is very near to the original OSM
// station, set is-from-osm to true
if (webMercMeterDist(geom, *n->pl().getGeom()) <
opts.maxOsmStationDistance) {
if (n->pl().getSI()) n->pl().getSI()->setIsFromOsm(true);
}
}
}
}
if (!fs) return;
std::vector<const Stop*> notSnapped;
for (auto& s : *fs) {
bool snapped = false;
auto pl = plFromGtfs(s.first, opts);
for (size_t i = 0; i < opts.maxSnapDistances.size(); i++) {
double d = opts.maxSnapDistances[i];
StatGroup* group = groupStats(
snapStation(g, &pl, &eg, &sng, opts, res,
i == opts.maxSnapDistances.size() - 1, false, d));
if (group) {
group->addStop(s.first);
(*fs)[s.first] = *group->getNodes().begin();
snapped = true;
}
}
if (!snapped) {
LOG(VDEBUG) << "Could not snap station "
<< "(" << pl.getSI()->getName() << ")"
<< " (" << s.first->getLat() << "," << s.first->getLng()
<< ") in normal run, trying again later in orphan mode.";
if (!bbox.contains(*pl.getGeom())) {
LOG(VDEBUG) << "Note: '" << pl.getSI()->getName()
<< "' does not lie within the bounds for this graph and "
"may be a stray station";
}
notSnapped.push_back(s.first);
}
}
if (notSnapped.size())
LOG(VDEBUG) << notSnapped.size() << " stations could not be snapped in "
"normal run, trying again in orphan "
"mode.";
// try again, but aggressively snap to orphan OSM stations which have
// not been assigned to any GTFS stop yet
for (auto& s : notSnapped) {
bool snapped = false;
auto pl = plFromGtfs(s, opts);
for (size_t i = 0; i < opts.maxSnapDistances.size(); i++) {
double d = opts.maxSnapDistances[i];
StatGroup* group = groupStats(
snapStation(g, &pl, &eg, &sng, opts, res,
i == opts.maxSnapDistances.size() - 1, true, d));
if (group) {
group->addStop(s);
// add the added station name as an alt name to ensure future
// similarity
for (auto n : group->getNodes()) {
if (n->pl().getSI())
n->pl().getSI()->addAltName(pl.getSI()->getName());
}
(*fs)[s] = *group->getNodes().begin();
snapped = true;
}
}
if (!snapped) {
// finally give up
// add a group with only this stop in it
StatGroup* dummyGroup = new StatGroup();
Node* dummyNode = g->addNd(pl);
dummyNode->pl().getSI()->setGroup(dummyGroup);
dummyGroup->addNode(dummyNode);
dummyGroup->addStop(s);
(*fs)[s] = dummyNode;
if (!bbox.contains(*pl.getGeom())) {
LOG(VDEBUG) << "Could not snap station "
<< "(" << pl.getSI()->getName() << ")"
<< " (" << s->getLat() << "," << s->getLng() << ")";
LOG(VDEBUG) << "Note: '" << pl.getSI()->getName()
<< "' does not lie within the bounds for this graph and "
"may be a stray station";
} else {
// only warn if it is contained in the BBOX for this graph
LOG(WARN) << "Could not snap station "
<< "(" << pl.getSI()->getName() << ")"
<< " (" << s->getLat() << "," << s->getLng() << ")";
}
}
}
}

View file

@ -4,7 +4,6 @@
#ifndef PFAEDLE_OSM_OSMBUILDER_H_
#define PFAEDLE_OSM_OSMBUILDER_H_
#include <map>
#include <queue>
#include <set>
@ -168,65 +167,70 @@ class OsmBuilder {
OsmRel nextRel(xml::File* xml, const OsmFilter& filter,
const AttrKeySet& keepAttrs) const;
protected:
Nullable<StatInfo> getStatInfo(Node* node, osmid nid, const POINT& pos,
const AttrMap& m, StAttrGroups* groups,
const RelMap& nodeRels, const RelLst& rels,
const OsmReadOpts& ops) const;
void writeGeoms(Graph* g) const;
void deleteOrphNds(Graph* g) const;
void deleteOrphEdgs(Graph* g, const OsmReadOpts& opts) const;
double dist(const Node* a, const Node* b) const;
double webMercDist(const Node* a, const Node* b) const;
double webMercDistFactor(const POINT& a) const;
static void snapStats(const OsmReadOpts& opts, Graph* g, const BBoxIdx& bbox,
size_t gridSize, router::FeedStops* fs, Restrictor* res,
const NodeSet& orphanStations);
static void writeGeoms(Graph* g);
static void deleteOrphNds(Graph* g);
static void deleteOrphEdgs(Graph* g, const OsmReadOpts& opts);
static double dist(const Node* a, const Node* b);
static double webMercDist(const Node* a, const Node* b);
NodeGrid buildNodeIdx(Graph* g, size_t size, const BOX& webMercBox,
bool which) const;
static NodeGrid buildNodeIdx(Graph* g, size_t size, const BOX& webMercBox,
bool which);
EdgeGrid buildEdgeIdx(Graph* g, size_t size, const BOX& webMercBox) const;
static EdgeGrid buildEdgeIdx(Graph* g, size_t size, const BOX& webMercBox);
void fixGaps(Graph* g, NodeGrid* ng) const;
void collapseEdges(Graph* g) const;
void writeODirEdgs(Graph* g, Restrictor* restor) const;
void writeSelfEdgs(Graph* g) const;
void writeEdgeTracks(const EdgTracks& tracks) const;
void simplifyGeoms(Graph* g) const;
uint32_t writeComps(Graph* g) const;
bool edgesSim(const Edge* a, const Edge* b) const;
const EdgePL& mergeEdgePL(Edge* a, Edge* b) const;
void getEdgCands(const POINT& s, EdgeCandPQ* ret, EdgeGrid* eg,
double d) const;
static void fixGaps(Graph* g, NodeGrid* ng);
static void collapseEdges(Graph* g);
static void writeODirEdgs(Graph* g, Restrictor* restor);
static void writeSelfEdgs(Graph* g);
static void writeEdgeTracks(const EdgTracks& tracks);
static void simplifyGeoms(Graph* g);
static uint32_t writeComps(Graph* g);
static bool edgesSim(const Edge* a, const Edge* b);
static const EdgePL& mergeEdgePL(Edge* a, Edge* b);
static void getEdgCands(const POINT& s, EdgeCandPQ* ret, EdgeGrid* eg,
double d);
std::set<Node*> getMatchingNds(const NodePL& s, NodeGrid* ng, double d) const;
static std::set<Node*> getMatchingNds(const NodePL& s, NodeGrid* ng,
double d);
Node* getMatchingNd(const NodePL& s, NodeGrid* ng, double d) const;
static Node* getMatchingNd(const NodePL& s, NodeGrid* ng, double d);
NodeSet snapStation(Graph* g, NodePL* s, EdgeGrid* eg, NodeGrid* sng,
const OsmReadOpts& opts, Restrictor* restor, bool surHeur,
bool orphSnap, double maxD) const;
static NodeSet snapStation(Graph* g, NodePL* s, EdgeGrid* eg, NodeGrid* sng,
const OsmReadOpts& opts, Restrictor* restor,
bool surHeur, bool orphSnap, double maxD);
// Checks if from the edge e, a station similar to si can be reach with less
// than maxD distance and less or equal to "maxFullTurns" full turns. If
// such a station exists, it is returned. If not, 0 is returned.
Node* eqStatReach(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns, double maxAng,
bool orph) const;
static Node* eqStatReach(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns, double maxAng,
bool orph);
Node* depthSearch(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns, double minAngle,
const SearchFunc& sfunc) const;
static Node* depthSearch(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns, double minAngle,
const SearchFunc& sfunc);
bool isBlocked(const Edge* e, const StatInfo* si, const POINT& p, double maxD,
int maxFullTurns, double minAngle) const;
static bool isBlocked(const Edge* e, const StatInfo* si, const POINT& p,
double maxD, int maxFullTurns, double minAngle);
static bool keepFullTurn(const trgraph::Node* n, double ang);
StatGroup* groupStats(const NodeSet& s) const;
static StatGroup* groupStats(const NodeSet& s);
static NodePL plFromGtfs(const Stop* s, const OsmReadOpts& ops);
std::vector<TransitEdgeLine*> getLines(const std::vector<size_t>& edgeRels,
const RelLst& rels,
const OsmReadOpts& ops);
NodePL plFromGtfs(const Stop* s, const OsmReadOpts& ops) const;
void getKeptAttrKeys(const OsmReadOpts& opts, AttrKeySet sets[3]) const;
void skipUntil(xml::File* xml, const std::string& s) const;
@ -238,6 +242,7 @@ class OsmBuilder {
const AttrMap& attrs, const RelMap& entRels,
const RelLst& rels,
const Normalizer& norm) const;
std::vector<std::string> getAttrMatchRanked(const DeepAttrLst& rule, osmid id,
const AttrMap& attrs,
const RelMap& entRels,
@ -249,8 +254,6 @@ class OsmBuilder {
bool relKeep(osmid id, const RelMap& rels, const FlatRels& fl) const;
bool keepFullTurn(const trgraph::Node* n, double ang) const;
std::map<TransitEdgeLine, TransitEdgeLine*> _lines;
std::map<size_t, TransitEdgeLine*> _relLines;
};

View file

@ -87,6 +87,7 @@ inline bool operator==(const RelLineRules& a, const RelLineRules& b) {
struct StationAttrRules {
DeepAttrLst nameRule;
DeepAttrLst platformRule;
DeepAttrLst idRule;
};
inline bool operator==(const StationAttrRules& a, const StationAttrRules& b) {
@ -125,6 +126,7 @@ struct OsmReadOpts {
trgraph::Normalizer statNormzer;
trgraph::Normalizer lineNormzer;
trgraph::Normalizer trackNormzer;
trgraph::Normalizer idNormzer;
RelLineRules relLinerules;
StationAttrRules statAttrRules;