Extracting additional features from graph
This commit is contained in:
@@ -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:
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user