Extracting additional features from graph

This commit is contained in:
Dennis Luxen
2011-07-06 12:33:41 +00:00
parent 4883c6c197
commit a37528362d
6 changed files with 382 additions and 128 deletions
+2 -2
View File
@@ -21,12 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASEPARSER_H_
#define BASEPARSER_H_
template<typename NodeT, typename RelationT, typename WayT>
template<typename NodeT, typename RestrictionT, typename WayT>
class BaseParser {
public:
virtual ~BaseParser() {}
virtual bool Init() = 0;
virtual bool RegisterCallbacks(bool (*nodeCallbackPointer)(NodeT), bool (*relationCallbackPointer)(RelationT), bool (*wayCallbackPointer)(WayT), bool (*addressCallbackPointer)(NodeT, HashTable<std::string, std::string>)) = 0;
virtual bool RegisterCallbacks(bool (*nodeCallbackPointer)(NodeT), bool (*restrictionCallbackPointer)(RestrictionT), bool (*wayCallbackPointer)(WayT), bool (*addressCallbackPointer)(NodeT, HashTable<std::string, std::string>)) = 0;
virtual bool Parse() = 0;
private:
};
+27 -23
View File
@@ -30,28 +30,31 @@ typedef stxxl::vector<_Node> STXXLNodeVector;
typedef stxxl::vector<_Edge> STXXLEdgeVector;
typedef stxxl::vector<_Address> STXXLAddressVector;
typedef stxxl::vector<string> STXXLStringVector;
typedef stxxl::vector<_RawRestrictionContainer> STXXLRestrictionsVector;
typedef stxxl::vector<_WayIDStartAndEndEdge> STXXLWayIDStartEndVector;
struct STXXLContainers {
STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes;
STXXLEdgeVector allEdges;
STXXLAddressVector adressVector;
STXXLStringVector nameVector;
STXXLRestrictionsVector restrictionsVector;
STXXLWayIDStartEndVector wayStartEndVector;
};
class ExtractorCallbacks{
private:
static const unsigned MAX_LOCAL_VECTOR_SIZE = 100;
STXXLNodeVector * allNodes;
STXXLNodeIDVector * usedNodeIDs;
STXXLEdgeVector * allEdges;
STXXLStringVector * nameVector;
STXXLAddressVector * addressVector;
Settings settings;
StringMap * stringMap;
STXXLContainers * externalMemory;
public:
ExtractorCallbacks(STXXLNodeVector * aNodes, STXXLNodeIDVector * uNodes, STXXLEdgeVector * aEdges, STXXLStringVector * nVector, STXXLAddressVector * adrVector, Settings s, StringMap * strMap){
allNodes = aNodes;
usedNodeIDs = uNodes;
allEdges = aEdges;
nameVector = nVector;
addressVector = adrVector;
settings = s;
ExtractorCallbacks(STXXLContainers * ext, Settings set, StringMap * strMap){
externalMemory = ext;
settings = set;
stringMap = strMap;
}
@@ -80,12 +83,12 @@ public:
/** warning: caller needs to take care of synchronization! */
bool nodeFunction(_Node &n) {
allNodes->push_back(n);
externalMemory->allNodes.push_back(n);
return true;
}
bool relationFunction(_Relation &r) {
//do nothing;
bool restrictionFunction(_RawRestrictionContainer &r) {
externalMemory->restrictionsVector.push_back(r);
return true;
}
@@ -178,18 +181,17 @@ public:
w.access = false;
}
if ( w.useful && w.access && w.path.size() ) {
if ( w.useful && w.access && w.path.size() > 1 ) {
StringMap::iterator strit = stringMap->find(w.name);
if(strit == stringMap->end())
{
w.nameID = nameVector->size();
nameVector->push_back(w.name);
if(strit == stringMap->end()) {
w.nameID = externalMemory->nameVector.size();
externalMemory->nameVector.push_back(w.name);
stringMap->insert(std::make_pair(w.name, w.nameID) );
} else {
w.nameID = strit->second;
}
for ( unsigned i = 0; i < w.path.size(); ++i ) {
usedNodeIDs->push_back(w.path[i]);
externalMemory->usedNodeIDs.push_back(w.path[i]);
}
if ( w.direction == _Way::opposite ){
@@ -197,7 +199,7 @@ public:
}
vector< NodeID > & path = w.path;
assert(w.type > -1 || w.maximumSpeed != -1);
assert(path.size()>0);
assert(path.size()>1);
if(w.maximumSpeed == -1)
w.maximumSpeed = settings.speedProfile.speed[w.type];
@@ -209,8 +211,10 @@ public:
e.direction = w.direction;
e.speed = w.maximumSpeed;
e.nameID = w.nameID;
allEdges->push_back(e);
externalMemory->allEdges.push_back(e);
}
assert(w.id != UINT_MAX);
externalMemory->wayStartEndVector.push_back(_WayIDStartAndEndEdge(w.id, path[0], path[1], path[path.size()-2], path[path.size()-1]));
}
return true;
}
+101 -4
View File
@@ -82,7 +82,8 @@ ostream & operator<<(ostream & out, const _Coordinate & c){
}
struct _Way {
_Way() {
_Way() : id(UINT_MAX) {
direction = _Way::notSure;
maximumSpeed = -1;
type = -1;
@@ -125,9 +126,11 @@ struct _Address {
};
struct _Relation {
_Relation() : type(unknown){}
enum {
unknown = 0, ferry
unknown = 0, ferry, turnRestriction
} type;
HashTable<std::string, std::string> keyVals;
};
struct _Edge {
@@ -153,13 +156,107 @@ struct _Edge {
};
struct _Restriction {
NodeID viaNode;
NodeID fromNode;
NodeID toNode;
struct bits { //mostly unused
char isOnly:1;
char unused1:1;
char unused2:1;
char unused3:1;
char unused4:1;
char unused5:1;
char unused6:1;
char unused7:1;
} flags;
_Restriction(NodeID vn) : viaNode(vn), fromNode(UINT_MAX), toNode(UINT_MAX) { }
_Restriction(bool isOnly = false) : viaNode(UINT_MAX), fromNode(UINT_MAX), toNode(UINT_MAX) {
flags.isOnly = isOnly;
}
};
struct _RawRestrictionContainer {
_Restriction restriction;
EdgeID fromWay;
EdgeID toWay;
unsigned viaWay;
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaWay(vw) { restriction.viaNode = vn;}
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaWay(UINT_MAX) { restriction.flags.isOnly = isOnly;}
static _RawRestrictionContainer min_value() {
return _RawRestrictionContainer(numeric_limits<unsigned>::min(), numeric_limits<unsigned>::min(), numeric_limits<unsigned>::min(), numeric_limits<unsigned>::min());
}
static _RawRestrictionContainer max_value() {
return _RawRestrictionContainer(numeric_limits<unsigned>::max(), numeric_limits<unsigned>::max(), numeric_limits<unsigned>::max(), numeric_limits<unsigned>::max());
}
};
struct CmpRestrictionByFrom: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
return a.fromWay < b.fromWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
}
};
struct CmpRestrictionByTo: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
return a.toWay < b.toWay;
}
value_type max_value() {
return _RawRestrictionContainer::max_value();
}
value_type min_value() {
return _RawRestrictionContainer::min_value();
}
};
struct _WayIDStartAndEndEdge {
unsigned wayID;
NodeID firstStart;
NodeID firstTarget;
NodeID lastStart;
NodeID lastTarget;
_WayIDStartAndEndEdge() : wayID(UINT_MAX), firstStart(UINT_MAX), firstTarget(UINT_MAX), lastStart(UINT_MAX), lastTarget(UINT_MAX) {}
_WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) : wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt) {}
static _WayIDStartAndEndEdge min_value() {
return _WayIDStartAndEndEdge(numeric_limits<unsigned>::min(), numeric_limits<unsigned>::min(), numeric_limits<unsigned>::min(), numeric_limits<unsigned>::min(), numeric_limits<unsigned>::min());
}
static _WayIDStartAndEndEdge max_value() {
return _WayIDStartAndEndEdge(numeric_limits<unsigned>::max(), numeric_limits<unsigned>::max(), numeric_limits<unsigned>::max(), numeric_limits<unsigned>::max(), numeric_limits<unsigned>::max());
}
};
struct CmpWayStartAndEnd : public std::binary_function<_WayIDStartAndEndEdge, _WayIDStartAndEndEdge, bool> {
typedef _WayIDStartAndEndEdge value_type;
bool operator () (const _WayIDStartAndEndEdge & a, const _WayIDStartAndEndEdge & b) const {
return a.wayID < b.wayID;
}
value_type max_value() {
return _WayIDStartAndEndEdge::max_value();
}
value_type min_value() {
return _WayIDStartAndEndEdge::min_value();
}
};
struct Settings {
struct SpeedProfile {
vector< double > speed;
vector< string > names;
} speedProfile;
// vector<string> accessList;
// int trafficLightPenalty;
int indexInAccessListOf( const string & key) {
for(unsigned i = 0; i< speedProfile.names.size(); i++) {
if(speedProfile.names[i] == key)
+73 -9
View File
@@ -32,7 +32,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "ExtractorStructs.h"
class PBFParser : public BaseParser<_Node, _Relation, _Way> {
class PBFParser : public BaseParser<_Node, _RawRestrictionContainer, _Way> {
enum EntityType {
TypeNode = 1,
@@ -74,10 +74,10 @@ public:
groupCount = 0;
}
bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*relationCallbackPointer)(_Relation), bool (*wayCallbackPointer)(_Way),bool (*addressCallbackPointer)(_Node, HashTable<std::string, std::string>) ) {
bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*restrictionCallbackPointer)(_RawRestrictionContainer), bool (*wayCallbackPointer)(_Way),bool (*addressCallbackPointer)(_Node, HashTable<std::string, std::string>) ) {
nodeCallback = *nodeCallbackPointer;
wayCallback = *wayCallbackPointer;
relationCallback = *relationCallbackPointer;
restrictionCallback = *restrictionCallbackPointer;
addressCallback = *addressCallbackPointer;
return true;
}
@@ -226,12 +226,76 @@ private:
void parseRelation(_ThreadData * threadData) {
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
for(int i = 0; i < group.relations_size(); i++ ) {
_Relation r;
r.type = _Relation::unknown;
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false;
bool isOnlyRestriction = false;
for(int k = 0; k < inputRelation.keys_size(); k++) {
const std::string key = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string val = threadData->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key && "restriction" == val) {
isRestriction = true;
}
if ("restriction" == key) {
if(val.find("only_") == 0)
isOnlyRestriction = true;
}
}
if(isRestriction) {
long long lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); rolesIndex++) {
string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
lastRef += inputRelation.memids(rolesIndex);
if(false == ("from" == role || "to" == role || "via" == role)) {
continue;
}
switch(inputRelation.types(rolesIndex)) {
case 0: //node
if("from" == role || "to" == role) //Only via should be a node
continue;
assert("via" == role);
if(UINT_MAX != currentRestrictionContainer.viaWay)
currentRestrictionContainer.viaWay = UINT_MAX;
assert(UINT_MAX == currentRestrictionContainer.viaWay);
currentRestrictionContainer.restriction.viaNode = lastRef;
break;
case 1: //way
assert("from" == role || "to" == role || "via" == role);
if("from" == role) {
currentRestrictionContainer.fromWay = lastRef;
}
if ("to" == role) {
currentRestrictionContainer.toWay = lastRef;
}
if ("via" == role) {
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
currentRestrictionContainer.viaWay = lastRef;
}
break;
case 2: //relation, not used. relations relating to relations are evil.
continue;
assert(false);
break;
default: //should not happen
cout << "unknown";
assert(false);
break;
}
}
// if(UINT_MAX != currentRestriction.viaNode) {
// cout << "restr from " << currentRestriction.from << " via ";
// cout << "node " << currentRestriction.viaNode;
// cout << " to " << currentRestriction.to << endl;
// }
#pragma omp critical
{
if(!(*relationCallback)(r))
std::cerr << "[PBFParser] relation not parsed" << std::endl;
{
if(!(*restrictionCallback)(currentRestrictionContainer))
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
}
@@ -442,7 +506,7 @@ private:
/* Function pointer for nodes */
bool (*nodeCallback)(_Node);
bool (*wayCallback)(_Way);
bool (*relationCallback)(_Relation);
bool (*restrictionCallback)(_RawRestrictionContainer);
bool (*addressCallback)(_Node, HashTable<std::string, std::string>);
/* the input stream to parse */
std::fstream input;
+6 -6
View File
@@ -29,17 +29,18 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "ExtractorStructs.h"
#include "InputReaderFactory.h"
class XMLParser : public BaseParser<_Node, _Relation, _Way> {
class XMLParser : public BaseParser<_Node, _RawRestrictionContainer, _Way> {
public:
XMLParser(const char * filename) {
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf");
inputReader = inputReaderFactory(filename);
}
~XMLParser() {}
bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*relationCallbackPointer)(_Relation), bool (*wayCallbackPointer)(_Way), bool (*addressCallbackPointer)(_Node, HashTable<std::string, std::string>) ) {
bool RegisterCallbacks(bool (*nodeCallbackPointer)(_Node), bool (*restrictionCallbackPointer)(_RawRestrictionContainer), bool (*wayCallbackPointer)(_Way), bool (*addressCallbackPointer)(_Node, HashTable<std::string, std::string>) ) {
nodeCallback = *nodeCallbackPointer;
wayCallback = *wayCallbackPointer;
relationCallback = *relationCallbackPointer;
restrictionCallback = *restrictionCallbackPointer;
return true;
}
bool Init() {
@@ -73,8 +74,7 @@ public:
if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) {
_Relation r;
r.type = _Relation::unknown;
if(!(*relationCallback)(r))
std::cerr << "[XMLParser] relation not parsed" << std::endl;
//todo: parse relation
}
xmlFree( currentName );
}
@@ -210,7 +210,7 @@ private:
/* Function pointer for nodes */
bool (*nodeCallback)(_Node);
bool (*wayCallback)(_Way);
bool (*relationCallback)(_Relation);
bool (*restrictionCallback)(_RawRestrictionContainer);
};