initial commit
This commit is contained in:
commit
efcd3e1892
106 changed files with 27000 additions and 0 deletions
174
src/pfaedle/trgraph/EdgePL.cpp
Normal file
174
src/pfaedle/trgraph/EdgePL.cpp
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "pfaedle/trgraph/EdgePL.h"
|
||||
|
||||
using pfaedle::trgraph::EdgePL;
|
||||
using pfaedle::trgraph::TransitEdgeLine;
|
||||
|
||||
std::map<util::geo::FLine*, size_t> EdgePL::_flines;
|
||||
std::map<const TransitEdgeLine*, size_t> EdgePL::_tlines;
|
||||
|
||||
// _____________________________________________________________________________
|
||||
EdgePL::EdgePL()
|
||||
: _length(0), _oneWay(0), _hasRestr(false), _rev(false), _lvl(0) {
|
||||
_l = new util::geo::FLine();
|
||||
_flines[_l] = 1;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
EdgePL::EdgePL(const EdgePL& pl) : EdgePL(pl, false) {}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
EdgePL::EdgePL(const EdgePL& pl, bool geoflat)
|
||||
: _length(pl._length),
|
||||
_oneWay(pl._oneWay),
|
||||
_hasRestr(pl._hasRestr),
|
||||
_rev(pl._rev),
|
||||
_lvl(pl._lvl) {
|
||||
if (geoflat) {
|
||||
_l = pl._l;
|
||||
} else {
|
||||
_l = new util::geo::FLine(*pl._l);
|
||||
}
|
||||
_flines[_l]++;
|
||||
|
||||
for (auto l : _lines) addLine(l);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
EdgePL::~EdgePL() {
|
||||
if (_l) {
|
||||
_flines[_l]--;
|
||||
if (_flines[_l] == 0) delete _l;
|
||||
}
|
||||
|
||||
for (auto l : _lines) unRefTLine(l);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::unRefTLine(const TransitEdgeLine* l) {
|
||||
if (l) {
|
||||
_tlines[l]--;
|
||||
if (_tlines[l] == 0) {
|
||||
delete l;
|
||||
_tlines.erase(_tlines.find(l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
EdgePL EdgePL::revCopy() const {
|
||||
EdgePL ret(*this);
|
||||
ret.setRev();
|
||||
if (ret.oneWay() == 1)
|
||||
ret.setOneWay(2);
|
||||
else if (ret.oneWay() == 2)
|
||||
ret.setOneWay(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::setLength(double d) { _length = d; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
double EdgePL::getLength() const { return _length; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::addLine(const TransitEdgeLine* l) {
|
||||
if (_lines.insert(l).second) {
|
||||
if (_tlines.count(l))
|
||||
_tlines[l]++;
|
||||
else
|
||||
_tlines[l] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::addLines(const std::vector<TransitEdgeLine*>& l) {
|
||||
for (auto line : l) addLine(line);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const std::set<const TransitEdgeLine*>& EdgePL::getLines() const {
|
||||
return _lines;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::addPoint(const util::geo::FPoint& p) { _l->push_back(p); }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const util::geo::FLine* EdgePL::getGeom() const { return _l; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
util::geo::FLine* EdgePL::getGeom() { return _l; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::getAttrs(std::map<std::string, std::string>* obj) const {
|
||||
(*obj)["m_length"] = std::to_string(_length);
|
||||
(*obj)["oneway"] = std::to_string(static_cast<int>(_oneWay));
|
||||
(*obj)["level"] = std::to_string(_lvl);
|
||||
(*obj)["restriction"] = isRestricted() ? "yes" : "no";
|
||||
|
||||
std::stringstream ss;
|
||||
bool first = false;
|
||||
|
||||
for (auto* l : _lines) {
|
||||
if (first) ss << ",";
|
||||
ss << l->shortName;
|
||||
if (l->fromStr.size() || l->toStr.size()) {
|
||||
ss << "(" << l->fromStr;
|
||||
ss << "->" << l->toStr << ")";
|
||||
}
|
||||
first = true;
|
||||
}
|
||||
|
||||
(*obj)["lines"] = ss.str();
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::setRestricted() { _hasRestr = true; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
bool EdgePL::isRestricted() const { return _hasRestr; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
uint8_t EdgePL::oneWay() const { return _oneWay; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::setOneWay(uint8_t dir) { _oneWay = dir; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::setOneWay() { _oneWay = 1; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::setLvl(uint8_t lvl) { _lvl = lvl; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
uint8_t EdgePL::lvl() const { return _lvl; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void EdgePL::setRev() { _rev = true; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
bool EdgePL::isRev() const { return _rev; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const util::geo::FPoint& EdgePL::backHop() const {
|
||||
if (isRev()) {
|
||||
return *(++(getGeom()->cbegin()));
|
||||
}
|
||||
return *(++(getGeom()->crbegin()));
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const util::geo::FPoint& EdgePL::frontHop() const {
|
||||
if (isRev()) {
|
||||
return *(++(getGeom()->crbegin()));
|
||||
}
|
||||
return *(++(getGeom()->cbegin()));
|
||||
}
|
||||
133
src/pfaedle/trgraph/EdgePL.h
Normal file
133
src/pfaedle/trgraph/EdgePL.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_TRGRAPH_EDGEPL_H_
|
||||
#define PFAEDLE_TRGRAPH_EDGEPL_H_
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "pfaedle/router/Comp.h"
|
||||
#include "util/geo/GeoGraph.h"
|
||||
|
||||
using util::geograph::GeoEdgePL;
|
||||
|
||||
namespace pfaedle {
|
||||
namespace trgraph {
|
||||
|
||||
|
||||
/*
|
||||
* A line occuring on an edge
|
||||
*/
|
||||
struct TransitEdgeLine {
|
||||
std::string fromStr;
|
||||
std::string toStr;
|
||||
std::string shortName;
|
||||
};
|
||||
|
||||
inline bool operator==(const TransitEdgeLine& a, const TransitEdgeLine& b) {
|
||||
return a.fromStr == b.fromStr && a.toStr == b.toStr &&
|
||||
a.shortName == b.shortName;
|
||||
}
|
||||
|
||||
inline bool operator<(const TransitEdgeLine& a, const TransitEdgeLine& b) {
|
||||
return a.fromStr < b.fromStr ||
|
||||
(a.fromStr == b.fromStr && a.toStr < b.toStr) ||
|
||||
(a.fromStr == b.fromStr && a.toStr == b.toStr &&
|
||||
a.shortName < b.shortName);
|
||||
}
|
||||
|
||||
/*
|
||||
* An edge payload class for the transit graph.
|
||||
*/
|
||||
class EdgePL : public GeoEdgePL<float> {
|
||||
public:
|
||||
EdgePL();
|
||||
~EdgePL();
|
||||
EdgePL(const EdgePL& pl);
|
||||
EdgePL(const EdgePL& pl, bool geoFlat);
|
||||
|
||||
// Return the geometry of this edge.
|
||||
const util::geo::FLine* getGeom() const;
|
||||
util::geo::FLine* getGeom();
|
||||
|
||||
// Extends this edge payload's geometry by Point p
|
||||
void addPoint(const util::geo::FPoint& p);
|
||||
|
||||
// Fill obj with k/v pairs describing the parameters of this payload.
|
||||
void getAttrs(std::map<std::string, std::string>* obj) const;
|
||||
|
||||
// Return the length in meters stored for this edge payload
|
||||
double getLength() const;
|
||||
|
||||
// Set the length in meters for this edge payload
|
||||
void setLength(double d);
|
||||
|
||||
// Set this edge as a one way node, either in the default direction of
|
||||
// the edge (no arg), or the direction specified in dir
|
||||
void setOneWay();
|
||||
void setOneWay(uint8_t dir);
|
||||
|
||||
// Mark this payload' edge as having some restrictions
|
||||
void setRestricted();
|
||||
|
||||
// Mark this payload' edge as being secondary to an inversed partner
|
||||
void setRev();
|
||||
|
||||
// True if this edge is secondary to an inversed partner
|
||||
bool isRev() const;
|
||||
|
||||
// True if this edge is restricted
|
||||
bool isRestricted() const;
|
||||
|
||||
// Set the level of this edge.
|
||||
void setLvl(uint8_t lvl);
|
||||
|
||||
// Return the level of this edge.
|
||||
uint8_t lvl() const;
|
||||
|
||||
// Return the one-way code stored for this edge.
|
||||
uint8_t oneWay() const;
|
||||
|
||||
// Add a TransitedgeLine to this payload's edge
|
||||
void addLine(const TransitEdgeLine* l);
|
||||
|
||||
// Add multiple TransitedgeLine objects to this payload's edge
|
||||
void addLines(const std::vector<TransitEdgeLine*>& l);
|
||||
|
||||
// Return the TransitEdgeLines stored for this payload
|
||||
const std::set<const TransitEdgeLine*>& getLines() const;
|
||||
|
||||
// Returns the last hop of the payload - this is the (n-2)th point in
|
||||
// the payload geometry of length n > 1
|
||||
const util::geo::FPoint& backHop() const;
|
||||
|
||||
// Returns the first hop of the payload - this is the 2nd point in
|
||||
// the payload geometry of length n > 1
|
||||
const util::geo::FPoint& frontHop() const;
|
||||
|
||||
// Obtain an exact copy of this edge, but in reverse.
|
||||
EdgePL revCopy() const;
|
||||
|
||||
private:
|
||||
float _length;
|
||||
uint8_t _oneWay : 2;
|
||||
bool _hasRestr : 1;
|
||||
bool _rev : 1;
|
||||
uint8_t _lvl : 3;
|
||||
|
||||
util::geo::FLine* _l;
|
||||
|
||||
std::set<const TransitEdgeLine*> _lines;
|
||||
|
||||
static void unRefTLine(const TransitEdgeLine* l);
|
||||
|
||||
static std::map<util::geo::FLine*, size_t> _flines;
|
||||
static std::map<const TransitEdgeLine*, size_t> _tlines;
|
||||
};
|
||||
} // namespace trgraph
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_TRGRAPH_EDGEPL_H_
|
||||
35
src/pfaedle/trgraph/Graph.h
Normal file
35
src/pfaedle/trgraph/Graph.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_TRGRAPH_GRAPH_H_
|
||||
#define PFAEDLE_TRGRAPH_GRAPH_H_
|
||||
|
||||
#include "pfaedle/trgraph/NodePL.h"
|
||||
#include "pfaedle/trgraph/EdgePL.h"
|
||||
#include "util/graph/UndirGraph.h"
|
||||
#include "util/graph/DirGraph.h"
|
||||
#include "util/geo/Grid.h"
|
||||
|
||||
using util::geo::Grid;
|
||||
using util::geo::Point;
|
||||
using util::geo::Line;
|
||||
using util::geo::FPoint;
|
||||
using util::geo::FLine;
|
||||
|
||||
namespace pfaedle {
|
||||
namespace trgraph {
|
||||
|
||||
/*
|
||||
* A graph for physical transit networks
|
||||
*/
|
||||
typedef util::graph::Edge<NodePL, EdgePL> Edge;
|
||||
typedef util::graph::Node<NodePL, EdgePL> Node;
|
||||
typedef util::graph::DirGraph<NodePL, EdgePL> Graph;
|
||||
typedef Grid<Node*, Point, float> NodeGrid;
|
||||
typedef Grid<Edge*, Line, float> EdgeGrid;
|
||||
|
||||
} // namespace trgraph
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_TRGRAPH_GRAPH_H_
|
||||
124
src/pfaedle/trgraph/NodePL.cpp
Normal file
124
src/pfaedle/trgraph/NodePL.cpp
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "pfaedle/trgraph/NodePL.h"
|
||||
#include "pfaedle/trgraph/StatGroup.h"
|
||||
#include "pfaedle/trgraph/StatInfo.h"
|
||||
#include "util/String.h"
|
||||
|
||||
using pfaedle::trgraph::StatInfo;
|
||||
using pfaedle::trgraph::NodePL;
|
||||
using pfaedle::trgraph::Component;
|
||||
|
||||
// we use the adress of this dummy station info as a special value
|
||||
// of this node, meaning "is a station block". Re-using the _si field here
|
||||
// saves some memory
|
||||
StatInfo NodePL::_blockerSI = StatInfo();
|
||||
|
||||
std::unordered_map<const Component*, size_t> NodePL::_comps;
|
||||
|
||||
// _____________________________________________________________________________
|
||||
NodePL::NodePL() : _geom(0, 0), _si(0), _component(0), _vis(0) {}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
NodePL::NodePL(const NodePL& pl)
|
||||
: _geom(pl._geom), _si(0), _component(pl._component), _vis(pl._vis) {
|
||||
if (pl._si) setSI(*(pl._si));
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
NodePL::NodePL(const util::geo::FPoint& geom)
|
||||
: _geom(geom), _si(0), _component(0), _vis(0) {}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
NodePL::NodePL(const util::geo::FPoint& geom, const StatInfo& si)
|
||||
: _geom(geom), _si(0), _component(0), _vis(0) {
|
||||
setSI(si);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
NodePL::~NodePL() {
|
||||
if (getSI()) delete _si;
|
||||
if (_component) {
|
||||
_comps[_component]--;
|
||||
if (_comps[_component] == 0) {
|
||||
delete _component;
|
||||
_comps.erase(_comps.find(_component));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void NodePL::setVisited() const { _vis = true; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void NodePL::setNoStat() { _si = 0; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const Component* NodePL::getComp() const { return _component; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void NodePL::setComp(const Component* c) {
|
||||
if (_component == c) return;
|
||||
_component = c;
|
||||
|
||||
// NOT thread safe!
|
||||
if (!_comps.count(c))
|
||||
_comps[c] = 1;
|
||||
else
|
||||
_comps[c]++;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const util::geo::FPoint* NodePL::getGeom() const { return &_geom; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void NodePL::setGeom(const util::geo::FPoint& geom) { _geom = geom; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void NodePL::getAttrs(std::map<std::string, std::string>* obj) const {
|
||||
(*obj)["component"] = std::to_string(reinterpret_cast<size_t>(_component));
|
||||
(*obj)["dijkstra_vis"] = _vis ? "yes" : "no";
|
||||
if (getSI()) {
|
||||
(*obj)["station_info_ptr"] = util::toString(_si);
|
||||
(*obj)["station_name"] = _si->getName();
|
||||
(*obj)["station_alt_names"] = util::implode(_si->getAltNames(), ",");
|
||||
(*obj)["from_osm"] = _si->isFromOsm() ? "yes" : "no";
|
||||
(*obj)["station_platform"] = _si->getTrack();
|
||||
(*obj)["station_group"] =
|
||||
std::to_string(reinterpret_cast<size_t>(_si->getGroup()));
|
||||
|
||||
std::stringstream gtfsIds;
|
||||
if (_si->getGroup()) {
|
||||
for (auto* s : _si->getGroup()->getStops()) {
|
||||
gtfsIds << s->getId() << " (" << s->getName() << "),";
|
||||
}
|
||||
}
|
||||
|
||||
(*obj)["station_group_stops"] = gtfsIds.str();
|
||||
}
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void NodePL::setSI(const StatInfo& si) { _si = new StatInfo(si); }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const StatInfo* NodePL::getSI() const {
|
||||
if (isBlocker()) return 0;
|
||||
return _si;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
StatInfo* NodePL::getSI() {
|
||||
if (isBlocker()) return 0;
|
||||
return _si;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void NodePL::setBlocker() { _si = &_blockerSI; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
bool NodePL::isBlocker() const { return _si == &_blockerSI; }
|
||||
83
src/pfaedle/trgraph/NodePL.h
Normal file
83
src/pfaedle/trgraph/NodePL.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_TRGRAPH_NODEPL_H_
|
||||
#define PFAEDLE_TRGRAPH_NODEPL_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "ad/cppgtfs/gtfs/Feed.h"
|
||||
#include "pfaedle/trgraph/StatInfo.h"
|
||||
#include "util/geo/GeoGraph.h"
|
||||
|
||||
using util::geograph::GeoNodePL;
|
||||
|
||||
namespace pfaedle {
|
||||
namespace trgraph {
|
||||
|
||||
struct Component {
|
||||
uint8_t minEdgeLvl : 3;
|
||||
};
|
||||
|
||||
/*
|
||||
* A node payload class for the transit graph.
|
||||
*/
|
||||
class NodePL : public GeoNodePL<float> {
|
||||
public:
|
||||
NodePL();
|
||||
NodePL(const NodePL& pl); // NOLINT
|
||||
NodePL(const util::geo::FPoint& geom); // NOLINT
|
||||
NodePL(const util::geo::FPoint& geom, const StatInfo& si);
|
||||
~NodePL();
|
||||
|
||||
// Return the geometry of this node.
|
||||
const util::geo::FPoint* getGeom() const;
|
||||
void setGeom(const util::geo::FPoint& geom);
|
||||
|
||||
// Fill obj with k/v pairs describing the parameters of this payload.
|
||||
void getAttrs(std::map<std::string, std::string>* attrs) const;
|
||||
|
||||
// Set the station info for this node
|
||||
void setSI(const StatInfo& si);
|
||||
|
||||
// Return the station info for this node
|
||||
const StatInfo* getSI() const;
|
||||
StatInfo* getSI();
|
||||
|
||||
// Delete the station info for this node
|
||||
void setNoStat();
|
||||
|
||||
// Get the component of this node
|
||||
const Component* getComp() const;
|
||||
|
||||
// Set the component of this node
|
||||
void setComp(const Component* c);
|
||||
|
||||
// Make this node a blocker
|
||||
void setBlocker();
|
||||
|
||||
// Check if this node is a blocker
|
||||
bool isBlocker() const;
|
||||
|
||||
// Mark this node as visited (usefull for counting search space in Dijkstra)
|
||||
void setVisited() const;
|
||||
|
||||
private:
|
||||
std::string _b;
|
||||
// 32bit floats are enough here
|
||||
util::geo::FPoint _geom;
|
||||
StatInfo* _si;
|
||||
const Component* _component;
|
||||
|
||||
static StatInfo _blockerSI;
|
||||
|
||||
mutable bool _vis;
|
||||
|
||||
static std::unordered_map<const Component*, size_t> _comps;
|
||||
};
|
||||
} // namespace trgraph
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_TRGRAPH_NODEPL_H_
|
||||
61
src/pfaedle/trgraph/Normalizer.cpp
Normal file
61
src/pfaedle/trgraph/Normalizer.cpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "pfaedle/trgraph/Normalizer.h"
|
||||
|
||||
using pfaedle::trgraph::Normalizer;
|
||||
|
||||
// _____________________________________________________________________________
|
||||
Normalizer::Normalizer(const ReplRules& rules) : _rulesOrig(rules) {
|
||||
buildRules(rules);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
std::string Normalizer::operator()(std::string sn) const {
|
||||
auto i = _cache.find(sn);
|
||||
if (i != _cache.end()) return i->second;
|
||||
|
||||
std::string ret = sn;
|
||||
for (auto rule : _rules) {
|
||||
std::string tmp;
|
||||
std::regex_replace(std::back_inserter(tmp), ret.begin(), ret.end(),
|
||||
rule.first, rule.second,
|
||||
std::regex_constants::format_sed);
|
||||
std::swap(ret, tmp);
|
||||
}
|
||||
|
||||
std::transform(ret.begin(), ret.end(), ret.begin(), ::tolower);
|
||||
|
||||
_cache[sn] = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
bool Normalizer::operator==(const Normalizer& b) const {
|
||||
return _rulesOrig == b._rulesOrig;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void Normalizer::buildRules(const ReplRules& rules) {
|
||||
for (auto rule : rules) {
|
||||
try {
|
||||
_rules.push_back(ReplRuleComp(
|
||||
std::regex(rule.first, std::regex::ECMAScript | std::regex::icase |
|
||||
std::regex::optimize),
|
||||
rule.second));
|
||||
} catch (const std::regex_error& e) {
|
||||
std::stringstream ss;
|
||||
ss << "'" << rule.first << "'"
|
||||
<< ": " << e.what();
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/pfaedle/trgraph/Normalizer.h
Normal file
45
src/pfaedle/trgraph/Normalizer.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_TRGRAPH_NORMALIZER_H_
|
||||
#define PFAEDLE_TRGRAPH_NORMALIZER_H_
|
||||
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace pfaedle {
|
||||
namespace trgraph {
|
||||
|
||||
typedef std::pair<std::string, std::string> ReplRule;
|
||||
typedef std::vector<ReplRule> ReplRules;
|
||||
|
||||
typedef std::pair<std::regex, std::string> ReplRuleComp;
|
||||
typedef std::vector<ReplRuleComp> ReplRulesComp;
|
||||
|
||||
/*
|
||||
* A class for normalizing station names
|
||||
*/
|
||||
class Normalizer {
|
||||
public:
|
||||
Normalizer() {}
|
||||
explicit Normalizer(const ReplRules& rules);
|
||||
|
||||
// Normalize sn based on the rules of this normalizer
|
||||
std::string operator()(std::string sn) const;
|
||||
bool operator==(const Normalizer& b) const;
|
||||
|
||||
private:
|
||||
ReplRulesComp _rules;
|
||||
ReplRules _rulesOrig;
|
||||
mutable std::unordered_map<std::string, std::string> _cache;
|
||||
|
||||
void buildRules(const ReplRules& rules);
|
||||
};
|
||||
} // namespace trgraph
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_TRGRAPH_NORMALIZER_H_
|
||||
95
src/pfaedle/trgraph/StatGroup.cpp
Normal file
95
src/pfaedle/trgraph/StatGroup.cpp
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#include <set>
|
||||
#include "pfaedle/trgraph/StatGroup.h"
|
||||
#include "util/geo/Geo.h"
|
||||
|
||||
using pfaedle::trgraph::StatGroup;
|
||||
using pfaedle::trgraph::Node;
|
||||
using pfaedle::router::NodeCandGroup;
|
||||
using ad::cppgtfs::gtfs::Stop;
|
||||
|
||||
// _____________________________________________________________________________
|
||||
StatGroup::StatGroup() {}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatGroup::addStop(const Stop* s) { _stops.insert(s); }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatGroup::addNode(trgraph::Node* n) { _nodes.insert(n); }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatGroup::merge(StatGroup* other) {
|
||||
if (other == this) return;
|
||||
|
||||
std::set<Node*> nds = other->getNodes();
|
||||
std::set<const Stop*> stops = other->getStops();
|
||||
|
||||
for (auto on : nds) {
|
||||
on->pl().getSI()->setGroup(this);
|
||||
addNode(on);
|
||||
}
|
||||
|
||||
for (auto* os : stops) {
|
||||
addStop(os);
|
||||
}
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const NodeCandGroup& StatGroup::getNodeCands(const Stop* s) const {
|
||||
return _stopNodePens.at(s);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const std::set<Node*>& StatGroup::getNodes() const {
|
||||
return _nodes;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatGroup::remNode(trgraph::Node* n) {
|
||||
auto it = _nodes.find(n);
|
||||
if (it != _nodes.end()) _nodes.erase(it);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
std::set<Node*>& StatGroup::getNodes() { return _nodes; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const std::set<const Stop*>& StatGroup::getStops() const { return _stops; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
double StatGroup::getPen(const Stop* s, trgraph::Node* n,
|
||||
const trgraph::Normalizer& platformNorm,
|
||||
double trackPen, double distPenFac,
|
||||
double nonOsmPen) const {
|
||||
FPoint p = util::geo::latLngToWebMerc<float>(s->getLat(), s->getLng());
|
||||
|
||||
double distPen = util::geo::webMercMeterDist(p, *n->pl().getGeom());
|
||||
distPen *= distPenFac;
|
||||
|
||||
std::string platform = platformNorm(s->getPlatformCode());
|
||||
|
||||
if (!platform.empty() && !n->pl().getSI()->getTrack().empty() &&
|
||||
n->pl().getSI()->getTrack() == platform) {
|
||||
trackPen = 0;
|
||||
}
|
||||
|
||||
if (n->pl().getSI()->isFromOsm()) nonOsmPen = 0;
|
||||
|
||||
return distPen + trackPen + nonOsmPen;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatGroup::writePens(const trgraph::Normalizer& platformNorm,
|
||||
double trackPen, double distPenFac,
|
||||
double nonOsmPen) {
|
||||
if (_stopNodePens.size()) return; // already written
|
||||
for (auto* s : _stops) {
|
||||
for (auto* n : _nodes) {
|
||||
_stopNodePens[s].push_back(router::NodeCand{
|
||||
n, getPen(s, n, platformNorm, trackPen, distPenFac, nonOsmPen)});
|
||||
}
|
||||
}
|
||||
}
|
||||
72
src/pfaedle/trgraph/StatGroup.h
Normal file
72
src/pfaedle/trgraph/StatGroup.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_TRGRAPH_STATGROUP_H_
|
||||
#define PFAEDLE_TRGRAPH_STATGROUP_H_
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
#include "ad/cppgtfs/gtfs/Feed.h"
|
||||
#include "pfaedle/router/Router.h"
|
||||
#include "pfaedle/trgraph/Graph.h"
|
||||
#include "pfaedle/trgraph/Normalizer.h"
|
||||
|
||||
namespace pfaedle {
|
||||
namespace trgraph {
|
||||
|
||||
using ad::cppgtfs::gtfs::Stop;
|
||||
|
||||
/*
|
||||
* A group of stations that belong together semantically (for example, multiple
|
||||
* stop points of a larger bus station)
|
||||
*/
|
||||
class StatGroup {
|
||||
public:
|
||||
StatGroup();
|
||||
StatGroup(const StatGroup& a) = delete;
|
||||
|
||||
// Add a stop s to this station group
|
||||
void addStop(const Stop* s);
|
||||
|
||||
// Add a node n to this station group
|
||||
void addNode(trgraph::Node* n);
|
||||
|
||||
// Return all nodes contained in this group
|
||||
const std::set<trgraph::Node*>& getNodes() const;
|
||||
std::set<trgraph::Node*>& getNodes();
|
||||
|
||||
// Return all stops contained in this group
|
||||
const std::set<const Stop*>& getStops() const;
|
||||
|
||||
// Remove a node from this group
|
||||
void remNode(trgraph::Node* n);
|
||||
|
||||
// All nodes in other will be in this group, their SI's updated, and the
|
||||
// "other" group deleted.
|
||||
void merge(StatGroup* other);
|
||||
|
||||
// Return node candidates for stop s from this group
|
||||
const router::NodeCandGroup& getNodeCands(const Stop* s) const;
|
||||
|
||||
// Write the penalties for all stops contained in this group so far.
|
||||
void writePens(const trgraph::Normalizer& platformNorm, double trackPen,
|
||||
double distPenFac, double nonOsmPen);
|
||||
|
||||
private:
|
||||
std::set<trgraph::Node*> _nodes;
|
||||
std::set<const Stop*> _stops;
|
||||
|
||||
// for each stop in this group, a penalty for each of the nodes here, based on
|
||||
// its distance and optionally the track number
|
||||
std::unordered_map<const Stop*, router::NodeCandGroup> _stopNodePens;
|
||||
|
||||
double getPen(const Stop* s, trgraph::Node* n,
|
||||
const trgraph::Normalizer& norm, double trackPen,
|
||||
double distPenFac, double nonOsmPen) const;
|
||||
};
|
||||
} // namespace trgraph
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_TRGRAPH_STATGROUP_H_
|
||||
106
src/pfaedle/trgraph/StatInfo.cpp
Normal file
106
src/pfaedle/trgraph/StatInfo.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright 2018, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#include "pfaedle/router/Comp.h"
|
||||
#include "pfaedle/trgraph/StatGroup.h"
|
||||
#include "pfaedle/trgraph/StatInfo.h"
|
||||
|
||||
using pfaedle::trgraph::StatInfo;
|
||||
using pfaedle::trgraph::StatGroup;
|
||||
|
||||
std::unordered_map<const StatGroup*, size_t> StatInfo::_groups;
|
||||
|
||||
// _____________________________________________________________________________
|
||||
StatInfo::StatInfo() : _name(""), _track(""), _fromOsm(false), _group(0) {}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
StatInfo::StatInfo(const StatInfo& si)
|
||||
: _name(si._name),
|
||||
_altNames(si._altNames),
|
||||
_track(si._track),
|
||||
_fromOsm(si._fromOsm),
|
||||
_group(0) {
|
||||
setGroup(si._group);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
StatInfo::StatInfo(const std::string& name, const std::string& track,
|
||||
bool fromOsm)
|
||||
: _name(name), _track(track), _fromOsm(fromOsm), _group(0) {}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
StatInfo::~StatInfo() { unRefGroup(_group); }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatInfo::unRefGroup(StatGroup* g) {
|
||||
if (g) {
|
||||
_groups[g]--;
|
||||
if (_groups[g] == 0) {
|
||||
// std::cout << "Deleting " << g << std::endl;
|
||||
delete g;
|
||||
_groups.erase(_groups.find(g));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatInfo::setGroup(StatGroup* g) {
|
||||
if (_group == g) return;
|
||||
unRefGroup(_group);
|
||||
|
||||
_group = g;
|
||||
|
||||
// NOT thread safe!
|
||||
if (!_groups.count(g))
|
||||
_groups[g] = 1;
|
||||
else
|
||||
_groups[g]++;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
StatGroup* StatInfo::getGroup() const { return _group; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const std::string& StatInfo::getName() const { return _name; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const std::string& StatInfo::getTrack() const { return _track; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
bool StatInfo::isFromOsm() const { return _fromOsm; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatInfo::setIsFromOsm(bool is) { _fromOsm = is; }
|
||||
|
||||
// _____________________________________________________________________________
|
||||
double StatInfo::simi(const StatInfo* other) const {
|
||||
if (!other) return 0;
|
||||
if (router::statSimi(_name, other->getName()) > 0.5) return 1;
|
||||
|
||||
for (const auto& a : _altNames) {
|
||||
if (router::statSimi(a, other->getName()) > 0.5) return 1;
|
||||
for (const auto& b : other->getAltNames()) {
|
||||
if (router::statSimi(a, b) > 0.5) return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& b : other->getAltNames()) {
|
||||
if (router::statSimi(_name, b) > 0.5) return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
const std::vector<std::string>& StatInfo::getAltNames() const {
|
||||
return _altNames;
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatInfo::addAltName(const std::string& name) {
|
||||
_altNames.push_back(name);
|
||||
}
|
||||
|
||||
// _____________________________________________________________________________
|
||||
void StatInfo::setTrack(const std::string& tr) { _track = tr; }
|
||||
71
src/pfaedle/trgraph/StatInfo.h
Normal file
71
src/pfaedle/trgraph/StatInfo.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2017, University of Freiburg,
|
||||
// Chair of Algorithms and Data Structures.
|
||||
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
|
||||
|
||||
#ifndef PFAEDLE_TRGRAPH_STATINFO_H_
|
||||
#define PFAEDLE_TRGRAPH_STATINFO_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace pfaedle {
|
||||
namespace trgraph {
|
||||
|
||||
// forward declaration
|
||||
class StatGroup;
|
||||
|
||||
/*
|
||||
* Meta information (name, alternative names, track, group...) of a single stop
|
||||
*/
|
||||
class StatInfo {
|
||||
public:
|
||||
StatInfo();
|
||||
StatInfo(const StatInfo& si);
|
||||
StatInfo(const std::string& name, const std::string& track, bool _fromOsm);
|
||||
~StatInfo();
|
||||
|
||||
// Return this stops names.
|
||||
const std::string& getName() const;
|
||||
|
||||
// Return this stops track or empty string, if none.
|
||||
const std::string& getTrack() const;
|
||||
|
||||
// Add an alternative name for this station.
|
||||
void addAltName(const std::string& name);
|
||||
|
||||
// Return all alternative names for this station.
|
||||
const std::vector<std::string>& getAltNames() const;
|
||||
|
||||
// Set the track of this stop.
|
||||
void setTrack(const std::string& tr);
|
||||
|
||||
// Return the similarity between this stop and other
|
||||
double simi(const StatInfo* other) const;
|
||||
|
||||
// Set this stations group.
|
||||
void setGroup(StatGroup* g);
|
||||
|
||||
// Return this stations group.
|
||||
StatGroup* getGroup() const;
|
||||
|
||||
// True if this stop was from osm
|
||||
bool isFromOsm() const;
|
||||
|
||||
// Set this stop as coming from osm
|
||||
void setIsFromOsm(bool is);
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
std::vector<std::string> _altNames;
|
||||
std::string _track;
|
||||
bool _fromOsm;
|
||||
StatGroup* _group;
|
||||
|
||||
static std::unordered_map<const StatGroup*, size_t> _groups;
|
||||
static void unRefGroup(StatGroup* g);
|
||||
};
|
||||
} // namespace trgraph
|
||||
} // namespace pfaedle
|
||||
|
||||
#endif // PFAEDLE_TRGRAPH_STATINFO_H_
|
||||
Loading…
Add table
Add a link
Reference in a new issue