initial commit

This commit is contained in:
Patrick Brosi 2018-06-09 17:14:08 +02:00
commit efcd3e1892
106 changed files with 27000 additions and 0 deletions

View 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()));
}

View 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_

View 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_

View 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; }

View 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_

View 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());
}
}
}

View 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_

View 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)});
}
}
}

View 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_

View 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; }

View 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_