Implementation of turn restriction exceptions

This commit is contained in:
DennisOSRM 2013-01-05 19:20:25 +01:00
parent 5de2aa1cbf
commit ffdaa71086
6 changed files with 761 additions and 692 deletions

View File

@ -43,6 +43,27 @@ void PBFParser::RegisterCallbacks(ExtractorCallbacks * em) {
void PBFParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) { void PBFParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
scriptingEnvironment = _se; scriptingEnvironment = _se;
if(lua_function_exists(scriptingEnvironment.getLuaStateForThreadID(0), "get_exceptions" )) {
//get list of turn restriction exceptions
try {
luabind::call_function<void>(
scriptingEnvironment.getLuaStateForThreadID(0),
"get_exceptions",
boost::ref(restriction_exceptions_vector)
);
INFO("Found " << restriction_exceptions_vector.size() << " exceptions to turn restriction");
BOOST_FOREACH(std::string & str, restriction_exceptions_vector) {
INFO("ignoring: " << str);
}
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
} else {
INFO("Found no exceptions to turn restrictions");
}
} }
PBFParser::~PBFParser() { PBFParser::~PBFParser() {
@ -218,10 +239,11 @@ inline void PBFParser::parseNode(_ThreadData * ) {
} }
inline void PBFParser::parseRelation(_ThreadData * threadData) { inline void PBFParser::parseRelation(_ThreadData * threadData) {
//TODO: leave early, if relatio is not a restriction //TODO: leave early, if relation is not a restriction
//TODO: reuse rawRestriction container //TODO: reuse rawRestriction container
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ); const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
for(int i = 0; i < group.relations_size(); ++i ) { for(int i = 0; i < group.relations_size(); ++i ) {
std::string exception_of_restriction_tag;
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i); const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false; bool isRestriction = false;
bool isOnlyRestriction = false; bool isOnlyRestriction = false;
@ -238,8 +260,26 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
if(val.find("only_") == 0) if(val.find("only_") == 0)
isOnlyRestriction = true; isOnlyRestriction = true;
} }
if ("except" == key) {
exception_of_restriction_tag = val;
} }
}
//Check if restriction shall be ignored
if(isRestriction && ("" != exception_of_restriction_tag) ) {
//Be warned, this is quadratic work here, but we assume that
//only a few exceptions are actually defined.
std::vector<std::string> tokenized_exception_tags_of_restriction;
boost::algorithm::split_regex(tokenized_exception_tags_of_restriction, exception_of_restriction_tag, boost::regex("[;][ ]*"));
BOOST_FOREACH(std::string & str, tokenized_exception_tags_of_restriction) {
if(restriction_exceptions_vector.end() != std::find(restriction_exceptions_vector.begin(), restriction_exceptions_vector.end(), str)) {
isRestriction = false;
break; //BOOST_FOREACH
}
}
}
if(isRestriction) { if(isRestriction) {
long long lastRef = 0; long long lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction); _RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
@ -247,7 +287,7 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data()); std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
lastRef += inputRelation.memids(rolesIndex); lastRef += inputRelation.memids(rolesIndex);
if(false == ("from" == role || "to" == role || "via" == role)) { if(!("from" == role || "to" == role || "via" == role)) {
continue; continue;
} }
@ -285,11 +325,6 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
break; break;
} }
} }
// if(UINT_MAX != currentRestriction.viaNode) {
// cout << "restr from " << currentRestriction.from << " via ";
// cout << "node " << currentRestriction.viaNode;
// cout << " to " << currentRestriction.to << endl;
// }
if(!externalMemory->restrictionFunction(currentRestrictionContainer)) if(!externalMemory->restrictionFunction(currentRestrictionContainer))
std::cerr << "[PBFParser] relation not parsed" << std::endl; std::cerr << "[PBFParser] relation not parsed" << std::endl;
} }

View File

@ -106,6 +106,8 @@ private:
/* ThreadData Queue */ /* ThreadData Queue */
boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue; boost::shared_ptr<ConcurrentQueue < _ThreadData* > > threadDataQueue;
ScriptingEnvironment scriptingEnvironment; ScriptingEnvironment scriptingEnvironment;
std::vector<std::string> restriction_exceptions_vector;
}; };
#endif /* PBFPARSER_H_ */ #endif /* PBFPARSER_H_ */

View File

@ -18,16 +18,7 @@
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include "ScriptingEnvironment.h" #include "ScriptingEnvironment.h"
#include "../typedefs.h"
#include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h"
ScriptingEnvironment::ScriptingEnvironment() {} ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
@ -45,6 +36,8 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
//open utility libraries string library; //open utility libraries string library;
luaL_openlibs(myLuaState); luaL_openlibs(myLuaState);
luaAddScriptFolderToLoadPath( myLuaState, fileName );
// Add our function to the state's global scope // Add our function to the state's global scope
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::def("print", LUA_print<std::string>), luabind::def("print", LUA_print<std::string>),
@ -53,17 +46,6 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
luabind::def("parseDuration", parseDuration) luabind::def("parseDuration", parseDuration)
]; ];
luaAddScriptFolderToLoadPath( myLuaState, fileName );
//#pragma omp critical
// {
// if(0 != luaL_dostring(
// myLuaState,
// "print('Initializing LUA engine')\n"
// )) {
// ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block");
// }
// }
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<HashTable<std::string, std::string> >("keyVals") luabind::class_<HashTable<std::string, std::string> >("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add) .def("Add", &HashTable<std::string, std::string>::Add)
@ -103,6 +85,10 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
luabind::value("opposite", 3) luabind::value("opposite", 3)
] ]
]; ];
luabind::module(myLuaState) [
luabind::class_<std::vector<std::string> >("vector")
.def("Add", &std::vector<std::string>::push_back)
];
// Now call our function in a lua script // Now call our function in a lua script
//#pragma omp critical //#pragma omp critical

View File

@ -31,7 +31,10 @@ extern "C" {
#include "ExtractionHelperFunctions.h" #include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
#include "../typedefs.h"
#include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h"
class ScriptingEnvironment { class ScriptingEnvironment {
public: public:

View File

@ -40,6 +40,26 @@ void XMLParser::RegisterCallbacks(ExtractorCallbacks * em) {
void XMLParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) { void XMLParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
myLuaState = _se.getLuaStateForThreadID(0); myLuaState = _se.getLuaStateForThreadID(0);
if(lua_function_exists(myLuaState, "get_exceptions" )) {
//get list of turn restriction exceptions
try {
luabind::call_function<void>(
myLuaState,
"get_exceptions",
boost::ref(restriction_exceptions_vector)
);
INFO("Found " << restriction_exceptions_vector.size() << " exceptions to turn restriction");
BOOST_FOREACH(std::string & str, restriction_exceptions_vector) {
INFO(" " << str);
}
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
} else {
INFO("Found no exceptions to turn restrictions");
}
} }
bool XMLParser::Init() { bool XMLParser::Init() {
@ -118,6 +138,8 @@ bool XMLParser::Parse() {
_RawRestrictionContainer XMLParser::_ReadXMLRestriction() { _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
_RawRestrictionContainer restriction; _RawRestrictionContainer restriction;
std::string exception_of_restriction_tag;
bool restriction_is_excepted = false;
if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) {
const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) { const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) {
@ -146,8 +168,11 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
if(0 == std::string((const char *) value).find("only_")) if(0 == std::string((const char *) value).find("only_"))
restriction.restriction.flags.isOnly = true; restriction.restriction.flags.isOnly = true;
} }
} }
if ( xmlStrEqual(k, (const xmlChar *) "except") ) {
exception_of_restriction_tag = (const char*) value;
}
if ( k != NULL ) if ( k != NULL )
xmlFree( k ); xmlFree( k );
if ( value != NULL ) if ( value != NULL )
@ -157,6 +182,7 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
if ( ref != NULL ) { if ( ref != NULL ) {
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" ); xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" );
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" ); xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) { if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.toWay = atoi((const char*) ref); restriction.toWay = atoi((const char*) ref);
} }
@ -178,6 +204,21 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
xmlFree( childName ); xmlFree( childName );
} }
} }
//Check if restriction shall be ignored
if( "" != exception_of_restriction_tag ) {
//Be warned, this is quadratic work here, but we assume that
//only a few exceptions are actually defined.
std::vector<std::string> tokenized_exception_tags_of_restriction;
boost::algorithm::split_regex(tokenized_exception_tags_of_restriction, exception_of_restriction_tag, boost::regex("[;][ ]*"));
BOOST_FOREACH(std::string & str, tokenized_exception_tags_of_restriction) {
if(restriction_exceptions_vector.end() != std::find(restriction_exceptions_vector.begin(), restriction_exceptions_vector.end(), str)) {
restriction.fromWay = UINT_MAX; //workaround to ignore the restriction
break; //BOOST_FOREACH
}
}
}
return restriction; return restriction;
} }

View File

@ -45,6 +45,8 @@ private:
xmlTextReaderPtr inputReader; xmlTextReaderPtr inputReader;
ExtractorCallbacks * externalMemory; ExtractorCallbacks * externalMemory;
lua_State *myLuaState; lua_State *myLuaState;
std::vector<std::string> restriction_exceptions_vector;
}; };
#endif /* XMLPARSER_H_ */ #endif /* XMLPARSER_H_ */