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) {
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() {
@ -218,10 +239,11 @@ inline void PBFParser::parseNode(_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
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
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);
bool isRestriction = false;
bool isOnlyRestriction = false;
@ -238,8 +260,26 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
if(val.find("only_") == 0)
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) {
long long lastRef = 0;
_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());
lastRef += inputRelation.memids(rolesIndex);
if(false == ("from" == role || "to" == role || "via" == role)) {
if(!("from" == role || "to" == role || "via" == role)) {
continue;
}
@ -285,11 +325,6 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
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))
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}

View File

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

View File

@ -18,16 +18,7 @@
or see http://www.gnu.org/licenses/agpl.txt.
*/
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include "ScriptingEnvironment.h"
#include "../typedefs.h"
#include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h"
ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
@ -45,6 +36,8 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
//open utility libraries string library;
luaL_openlibs(myLuaState);
luaAddScriptFolderToLoadPath( myLuaState, fileName );
// Add our function to the state's global scope
luabind::module(myLuaState) [
luabind::def("print", LUA_print<std::string>),
@ -53,17 +46,6 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
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::class_<HashTable<std::string, std::string> >("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
@ -103,6 +85,10 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
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
//#pragma omp critical

View File

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

View File

@ -40,6 +40,26 @@ void XMLParser::RegisterCallbacks(ExtractorCallbacks * em) {
void XMLParser::RegisterScriptingEnvironment(ScriptingEnvironment & _se) {
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() {
@ -118,6 +138,8 @@ bool XMLParser::Parse() {
_RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
_RawRestrictionContainer restriction;
std::string exception_of_restriction_tag;
bool restriction_is_excepted = false;
if ( xmlTextReaderIsEmptyElement( 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_"))
restriction.restriction.flags.isOnly = true;
}
}
if ( xmlStrEqual(k, (const xmlChar *) "except") ) {
exception_of_restriction_tag = (const char*) value;
}
if ( k != NULL )
xmlFree( k );
if ( value != NULL )
@ -157,6 +182,7 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
if ( ref != NULL ) {
xmlChar * role = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "role" );
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.toWay = atoi((const char*) ref);
}
@ -178,6 +204,21 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
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;
}

View File

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