diff --git a/Extractor/BaseParser.cpp b/Extractor/BaseParser.cpp new file mode 100644 index 000000000..d57c4c5cf --- /dev/null +++ b/Extractor/BaseParser.cpp @@ -0,0 +1,113 @@ +/* +open source routing machine +Copyright (C) Dennis Luxen, others 2010 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. +*/ + +#include "BaseParser.h" + +BaseParser::BaseParser(ExtractorCallbacks* ec, ScriptingEnvironment& se) : +externalMemory(ec), scriptingEnvironment(se), luaState(NULL), use_turn_restrictions(true) { + luaState = se.getLuaStateForThreadID(0); + ReadUseRestrictionsSetting(); + ReadRestrictionExceptions(); +} + +void BaseParser::ReadUseRestrictionsSetting() { + if( 0 != luaL_dostring( luaState, "return use_turn_restrictions\n") ) { + ERR(lua_tostring( luaState,-1)<< " occured in scripting block"); + } + if( lua_isboolean( luaState, -1) ) { + use_turn_restrictions = lua_toboolean(luaState, -1); + } + if( use_turn_restrictions ) { + INFO("Using turn restrictions" ); + } else { + INFO("Ignoring turn restrictions" ); + } +} + +void BaseParser::ReadRestrictionExceptions() { + if(lua_function_exists(luaState, "get_exceptions" )) { + //get list of turn restriction exceptions + try { + luabind::call_function( + luaState, + "get_exceptions", + boost::ref(restriction_exceptions) + ); + INFO("Found " << restriction_exceptions.size() << " exceptions to turn restriction"); + BOOST_FOREACH(std::string & str, restriction_exceptions) { + 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"); + } +} + +void BaseParser::report_errors(lua_State *L, const int status) const { + if( 0!=status ) { + std::cerr << "-- " << lua_tostring(L, -1) << std::endl; + lua_pop(L, 1); // remove error message + } +} + +inline void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) { + try { + luabind::call_function( localLuaState, "node_function", boost::ref(n) ); + } catch (const luabind::error &er) { + lua_State* Ler=er.state(); + report_errors(Ler, -1); + ERR(er.what()); + } +} + +inline void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) { + try { + luabind::call_function( localLuaState, "way_function", boost::ref(w), w.path.size() ); + } catch (const luabind::error &er) { + lua_State* Ler=er.state(); + report_errors(Ler, -1); + ERR(er.what()); + } +} + +inline bool BaseParser::ShouldIgnoreRestriction(const std::string& except_tag_string) const { + //should this restriction be ignored? yes if there's an overlap between: + //a) the list of modes in the except tag of the restriction (except_tag_string), ex: except=bus;bicycle + //b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle] + + if( "" == except_tag_string ) { + return false; + } + + //Be warned, this is quadratic work here, but we assume that + //only a few exceptions are actually defined. + std::vector exceptions; + boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*")); + BOOST_FOREACH(std::string& str, exceptions) { + if( restriction_exceptions.end() != std::find(restriction_exceptions.begin(), restriction_exceptions.end(), str) ) { + return true; + } + } + return false; +} \ No newline at end of file diff --git a/Extractor/BaseParser.h b/Extractor/BaseParser.h index adf417a73..891af320b 100644 --- a/Extractor/BaseParser.h +++ b/Extractor/BaseParser.h @@ -29,23 +29,30 @@ extern "C" { #include +#include "ExtractorCallbacks.h" #include "ScriptingEnvironment.h" -template class BaseParser : boost::noncopyable { public: + BaseParser(ExtractorCallbacks* ec, ScriptingEnvironment& se); virtual ~BaseParser() {} - virtual bool Init() = 0; - virtual void RegisterCallbacks(ExternalMemoryT * externalMemory) = 0; - virtual void RegisterScriptingEnvironment(ScriptingEnvironment & _se) = 0; + virtual bool ReadHeader() = 0; virtual bool Parse() = 0; - void report_errors(lua_State *L, int status) { - if ( status!=0 ) { - std::cerr << "-- " << lua_tostring(L, -1) << std::endl; - lua_pop(L, 1); // remove error message - } - } + inline virtual void ParseNodeInLua(ImportNode& n, lua_State* luaStateForThread); + inline virtual void ParseWayInLua(ExtractionWay& n, lua_State* luaStateForThread); + virtual void report_errors(lua_State *L, const int status) const; + +protected: + virtual void ReadUseRestrictionsSetting(); + virtual void ReadRestrictionExceptions(); + inline virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const; + + ExtractorCallbacks* externalMemory; + ScriptingEnvironment& scriptingEnvironment; + lua_State* luaState; + std::vector restriction_exceptions; + bool use_turn_restrictions; }; diff --git a/Extractor/PBFParser.cpp b/Extractor/PBFParser.cpp index 222475db6..30ad1feb6 100644 --- a/Extractor/PBFParser.cpp +++ b/Extractor/PBFParser.cpp @@ -20,7 +20,7 @@ #include "PBFParser.h" -PBFParser::PBFParser(const char * fileName) : externalMemory(NULL){ +PBFParser::PBFParser(const char * fileName, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser( ec, se ) { GOOGLE_PROTOBUF_VERIFY_VERSION; //TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk? //NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free. @@ -37,38 +37,10 @@ PBFParser::PBFParser(const char * fileName) : externalMemory(NULL){ #endif } -void PBFParser::RegisterCallbacks(ExtractorCallbacks * em) { - externalMemory = 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( - 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() { - if(input.is_open()) + if(input.is_open()) { input.close(); + } // Clean up any leftover ThreadData objects in the queue _ThreadData* td; @@ -82,7 +54,7 @@ PBFParser::~PBFParser() { #endif } -inline bool PBFParser::Init() { +inline bool PBFParser::ReadHeader() { _ThreadData initData; /** read Header */ if(!readPBFBlobHeader(input, &initData)) { @@ -98,11 +70,13 @@ inline bool PBFParser::Init() { for(int i = 0, featureSize = initData.PBFHeaderBlock.required_features_size(); i < featureSize; ++i) { const std::string& feature = initData.PBFHeaderBlock.required_features( i ); bool supported = false; - if ( "OsmSchema-V0.6" == feature ) + if ( "OsmSchema-V0.6" == feature ) { supported = true; - else if ( "DenseNodes" == feature ) + } + else if ( "DenseNodes" == feature ) { supported = true; - + } + if ( !supported ) { std::cerr << "[error] required feature not supported: " << feature.data() << std::endl; return false; @@ -120,9 +94,9 @@ inline void PBFParser::ReadData() { _ThreadData *threadData = new _ThreadData(); keepRunning = readNextBlock(input, threadData); - if (keepRunning) + if (keepRunning) { threadDataQueue->push(threadData); - else { + } else { threadDataQueue->push(NULL); // No more data to read, parse stops when NULL encountered delete threadData; } @@ -133,7 +107,7 @@ inline void PBFParser::ParseData() { while (true) { _ThreadData *threadData; threadDataQueue->wait_and_pop(threadData); - if (threadData == NULL) { + if( NULL==threadData ) { INFO("Parse Data Thread Finished"); threadDataQueue->push(NULL); // Signal end of data for other threads break; @@ -145,14 +119,18 @@ inline void PBFParser::ParseData() { threadData->currentGroupID = i; loadGroup(threadData); - if(threadData->entityTypeIndicator == TypeNode) + if(threadData->entityTypeIndicator == TypeNode) { parseNode(threadData); - if(threadData->entityTypeIndicator == TypeWay) + } + if(threadData->entityTypeIndicator == TypeWay) { parseWay(threadData); - if(threadData->entityTypeIndicator == TypeRelation) + } + if(threadData->entityTypeIndicator == TypeRelation) { parseRelation(threadData); - if(threadData->entityTypeIndicator == TypeDenseNode) + } + if(threadData->entityTypeIndicator == TypeDenseNode) { parseDenseNode(threadData); + } } delete threadData; @@ -193,7 +171,7 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) { n.lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO; while (denseTagIndex < dense.keys_vals_size()) { const int tagValue = dense.keys_vals( denseTagIndex ); - if(tagValue == 0) { + if( 0==tagValue ) { ++denseTagIndex; break; } @@ -210,24 +188,9 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) { #pragma omp parallel for schedule ( guided ) for(unsigned i = 0; i < endi_nodes; ++i) { ImportNode &n = nodesToParse[i]; - /** Pass the unpacked node to the LUA call back **/ - try { - luabind::call_function( - scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()), - "node_function", - boost::ref(n) - ); - } catch (const luabind::error &er) { - lua_State* Ler=er.state(); - report_errors(Ler, -1); - ERR(er.what()); - } - // catch (...) { - // ERR("Unknown error occurred during PBF dense node parsing!"); - // } + ParseNodeInLua( n, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) ); } - BOOST_FOREACH(ImportNode &n, nodesToParse) { if(!externalMemory->nodeFunction(n)) std::cerr << "[PBFParser] dense node not parsed" << std::endl; @@ -241,9 +204,12 @@ inline void PBFParser::parseNode(_ThreadData * ) { inline void PBFParser::parseRelation(_ThreadData * threadData) { //TODO: leave early, if relation is not a restriction //TODO: reuse rawRestriction container + if( !use_turn_restrictions ) { + return; + } const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ); for(int i = 0; i < group.relations_size(); ++i ) { - std::string exception_of_restriction_tag; + std::string except_tag_string; const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i); bool isRestriction = false; bool isOnlyRestriction = false; @@ -251,34 +217,25 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) { 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) { - if( "restriction" == val) + if( "restriction" == val) { isRestriction = true; - else + } else { break; - } - if ("restriction" == key) { - 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 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 ("restriction" == key) { + if(val.find("only_") == 0) { + isOnlyRestriction = true; + } + } + if ("except" == key) { + except_tag_string = val; + } } + if( isRestriction && ShouldIgnoreRestriction(except_tag_string) ) { + isRestriction = false; + } if(isRestriction) { int64_t lastRef = 0; @@ -293,11 +250,13 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) { switch(inputRelation.types(rolesIndex)) { case 0: //node - if("from" == role || "to" == role) //Only via should be a node + if("from" == role || "to" == role) { //Only via should be a node continue; + } assert("via" == role); - if(UINT_MAX != currentRestrictionContainer.viaNode) + if(UINT_MAX != currentRestrictionContainer.viaNode) { currentRestrictionContainer.viaNode = UINT_MAX; + } assert(UINT_MAX == currentRestrictionContainer.viaNode); currentRestrictionContainer.restriction.viaNode = lastRef; break; @@ -325,8 +284,9 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) { break; } } - if(!externalMemory->restrictionFunction(currentRestrictionContainer)) + if(!externalMemory->restrictionFunction(currentRestrictionContainer)) { std::cerr << "[PBFParser] relation not parsed" << std::endl; + } } } } @@ -357,29 +317,12 @@ inline void PBFParser::parseWay(_ThreadData * threadData) { #pragma omp parallel for schedule ( guided ) for(unsigned i = 0; i < endi_ways; ++i) { ExtractionWay & w = waysToParse[i]; - /** Pass the unpacked way to the LUA call back **/ - try { - luabind::call_function( - scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()), - "way_function", - boost::ref(w), - w.path.size() - ); - - } catch (const luabind::error &er) { - lua_State* Ler=er.state(); - report_errors(Ler, -1); - ERR(er.what()); - } - // catch (...) { - // ERR("Unknown error!"); - // } + ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) ); } BOOST_FOREACH(ExtractionWay & w, waysToParse) { - if(!externalMemory->wayFunction(w)) { + if(!externalMemory->wayFunction(w)) std::cerr << "[PBFParser] way not parsed" << std::endl; - } } } @@ -476,9 +419,10 @@ inline bool PBFParser::unpackLZMA(std::fstream &, _ThreadData * ) { } inline bool PBFParser::readBlob(std::fstream& stream, _ThreadData * threadData) { - if(stream.eof()) + if(stream.eof()) { return false; - + } + const int size = threadData->PBFBlobHeader.datasize(); if ( size < 0 || size > MAX_BLOB_SIZE ) { std::cerr << "[error] invalid Blob size:" << size << std::endl; @@ -506,8 +450,9 @@ inline bool PBFParser::readBlob(std::fstream& stream, _ThreadData * threadData) return false; } } else if ( threadData->PBFBlob.has_lzma_data() ) { - if ( !unpackLZMA(stream, threadData) ) + if ( !unpackLZMA(stream, threadData) ) { std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl; + } delete[] data; return false; } else { diff --git a/Extractor/PBFParser.h b/Extractor/PBFParser.h index d3da02706..587fbc96c 100644 --- a/Extractor/PBFParser.h +++ b/Extractor/PBFParser.h @@ -37,11 +37,8 @@ #include "../Util/OpenMPWrapper.h" #include "BaseParser.h" -#include "ExtractorCallbacks.h" -#include "ExtractorStructs.h" -#include "ScriptingEnvironment.h" -class PBFParser : public BaseParser { +class PBFParser : public BaseParser { enum EntityType { TypeNode = 1, @@ -65,13 +62,10 @@ class PBFParser : public BaseParser > threadDataQueue; - ScriptingEnvironment scriptingEnvironment; - - std::vector restriction_exceptions_vector; }; #endif /* PBFPARSER_H_ */ diff --git a/Extractor/XMLParser.cpp b/Extractor/XMLParser.cpp index 64ef2e25b..f28440d36 100644 --- a/Extractor/XMLParser.cpp +++ b/Extractor/XMLParser.cpp @@ -27,42 +27,12 @@ #include "../DataStructures/InputReaderFactory.h" -XMLParser::XMLParser(const char * filename) : externalMemory(NULL), myLuaState(NULL){ +XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) { WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf"); inputReader = inputReaderFactory(filename); } -XMLParser::~XMLParser() {} - -void XMLParser::RegisterCallbacks(ExtractorCallbacks * em) { - externalMemory = 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( - 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::ReadHeader() { return (xmlTextReaderRead( inputReader ) == 1); } bool XMLParser::Parse() { @@ -70,58 +40,28 @@ bool XMLParser::Parse() { const int type = xmlTextReaderNodeType( inputReader ); //1 is Element - if ( type != 1 ) + if ( type != 1 ) { continue; - + } + xmlChar* currentName = xmlTextReaderName( inputReader ); - if ( currentName == NULL ) + if ( currentName == NULL ) { continue; - + } + if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) { - ImportNode n = _ReadXMLNode( ); - /** Pass the unpacked node to the LUA call back **/ - try { - luabind::call_function( - myLuaState, - "node_function", - boost::ref(n) - ); - if(!externalMemory->nodeFunction(n)) - std::cerr << "[XMLParser] dense node not parsed" << std::endl; - } catch (const luabind::error &er) { - std::cerr << er.what() << std::endl; - lua_State* Ler=er.state(); - report_errors(Ler, -1); - } catch (std::exception & e) { - ERR(e.what()); - } catch (...) { - ERR("Unknown error occurred during XML node parsing!"); - } + ImportNode n = _ReadXMLNode(); + ParseNodeInLua( n, luaState ); + + if(!externalMemory->nodeFunction(n)) + std::cerr << "[XMLParser] dense node not parsed" << std::endl; } if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { ExtractionWay way = _ReadXMLWay( ); - - /** Pass the unpacked way to the LUA call back **/ - try { - luabind::call_function( - myLuaState, - "way_function", - boost::ref(way), - way.path.size() - ); - if(!externalMemory->wayFunction(way)) { - std::cerr << "[PBFParser] way not parsed" << std::endl; - } - } catch (const luabind::error &er) { - std::cerr << er.what() << std::endl; - lua_State* Ler=er.state(); - report_errors(Ler, -1); - } catch (std::exception & e) { - ERR(e.what()); - } catch (...) { - ERR("Unknown error occurred during XML way parsing!"); - } + ParseWayInLua( way, luaState ); + if(!externalMemory->wayFunction(way)) + std::cerr << "[PBFParser] way not parsed" << std::endl; } if ( xmlStrEqual( currentName, ( const xmlChar* ) "relation" ) == 1 ) { _RawRestrictionContainer r = _ReadXMLRestriction(); @@ -137,19 +77,20 @@ bool XMLParser::Parse() { } _RawRestrictionContainer XMLParser::_ReadXMLRestriction() { - _RawRestrictionContainer restriction; - std::string exception_of_restriction_tag; + _RawRestrictionContainer restriction; + std::string except_tag_string; if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { const int depth = xmlTextReaderDepth( inputReader );while ( xmlTextReaderRead( inputReader ) == 1 ) { const int childType = xmlTextReaderNodeType( inputReader ); - if ( childType != 1 && childType != 15 ) + if ( childType != 1 && childType != 15 ) { continue; + } const int childDepth = xmlTextReaderDepth( inputReader ); xmlChar* childName = xmlTextReaderName( inputReader ); - if ( childName == NULL ) + if ( childName == NULL ) { continue; - + } if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "relation" ) == 1 ) { xmlFree( childName ); break; @@ -164,18 +105,21 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() { xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); if ( k != NULL && value != NULL ) { if(xmlStrEqual(k, ( const xmlChar* ) "restriction" )){ - if(0 == std::string((const char *) value).find("only_")) + 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; + except_tag_string = (const char*) value; } } - if ( k != NULL ) + if ( k != NULL ) { xmlFree( k ); - if ( value != NULL ) + } + if ( value != NULL ) { xmlFree( value ); + } } else if ( xmlStrEqual( childName, ( const xmlChar* ) "member" ) == 1 ) { xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); if ( ref != NULL ) { @@ -192,32 +136,24 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() { restriction.restriction.viaNode = atoi((const char*) ref); } - if(NULL != type) + if(NULL != type) { xmlFree( type ); - if(NULL != role) + } + if(NULL != role) { xmlFree( role ); - if(NULL != ref) + } + if(NULL != ref) { xmlFree( ref ); + } } } 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 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 - } - } + if( ShouldIgnoreRestriction(except_tag_string) ) { + restriction.fromWay = UINT_MAX; //workaround to ignore the restriction } - return restriction; } @@ -227,12 +163,14 @@ ExtractionWay XMLParser::_ReadXMLWay() { const int depth = xmlTextReaderDepth( inputReader ); while ( xmlTextReaderRead( inputReader ) == 1 ) { const int childType = xmlTextReaderNodeType( inputReader ); - if ( childType != 1 && childType != 15 ) + if ( childType != 1 && childType != 15 ) { continue; + } const int childDepth = xmlTextReaderDepth( inputReader ); xmlChar* childName = xmlTextReaderName( inputReader ); - if ( childName == NULL ) + if ( childName == NULL ) { continue; + } if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) { xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); @@ -249,15 +187,16 @@ ExtractionWay XMLParser::_ReadXMLWay() { if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); - // cout << "->k=" << k << ", v=" << value << endl; + // cout << "->k=" << k << ", v=" << value << endl; if ( k != NULL && value != NULL ) { - way.keyVals.Add(std::string( (char *) k ), std::string( (char *) value)); } - if ( k != NULL ) + if ( k != NULL ) { xmlFree( k ); - if ( value != NULL ) + } + if ( value != NULL ) { xmlFree( value ); + } } else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) { xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); if ( ref != NULL ) { @@ -295,12 +234,14 @@ ImportNode XMLParser::_ReadXMLNode() { while ( xmlTextReaderRead( inputReader ) == 1 ) { const int childType = xmlTextReaderNodeType( inputReader ); // 1 = Element, 15 = EndElement - if ( childType != 1 && childType != 15 ) + if ( childType != 1 && childType != 15 ) { continue; + } const int childDepth = xmlTextReaderDepth( inputReader ); xmlChar* childName = xmlTextReaderName( inputReader ); - if ( childName == NULL ) + if ( childName == NULL ) { continue; + } if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) { xmlFree( childName ); @@ -317,10 +258,12 @@ ImportNode XMLParser::_ReadXMLNode() { if ( k != NULL && value != NULL ) { node.keyVals.Add(std::string( reinterpret_cast(k) ), std::string( reinterpret_cast(value))); } - if ( k != NULL ) + if ( k != NULL ) { xmlFree( k ); - if ( value != NULL ) + } + if ( value != NULL ) { xmlFree( value ); + } } xmlFree( childName ); diff --git a/Extractor/XMLParser.h b/Extractor/XMLParser.h index 3bc54825d..a2af2fb86 100644 --- a/Extractor/XMLParser.h +++ b/Extractor/XMLParser.h @@ -25,28 +25,18 @@ #include "../typedefs.h" #include "BaseParser.h" -#include "ExtractorCallbacks.h" -#include "ScriptingEnvironment.h" -class XMLParser : public BaseParser { +class XMLParser : public BaseParser { public: - XMLParser(const char * filename); - virtual ~XMLParser(); - void RegisterCallbacks(ExtractorCallbacks * em); - void RegisterScriptingEnvironment(ScriptingEnvironment & _se); - bool Init(); + XMLParser(const char* filename, ExtractorCallbacks* ec, ScriptingEnvironment& se); + bool ReadHeader(); bool Parse(); private: _RawRestrictionContainer _ReadXMLRestriction(); ExtractionWay _ReadXMLWay(); - ImportNode _ReadXMLNode( ); - /* Input Reader */ + ImportNode _ReadXMLNode(); xmlTextReaderPtr inputReader; - ExtractorCallbacks * externalMemory; - lua_State *myLuaState; - - std::vector restriction_exceptions_vector; }; #endif /* XMLPARSER_H_ */ diff --git a/extractor.cpp b/extractor.cpp index 1aa72f83b..4912c9b67 100644 --- a/extractor.cpp +++ b/extractor.cpp @@ -94,20 +94,20 @@ int main (int argc, char *argv[]) { stringMap[""] = 0; extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap); - BaseParser * parser; + BaseParser* parser; if(isPBF) { - parser = new PBFParser(argv[1]); + parser = new PBFParser(argv[1], extractCallBacks, scriptingEnvironment); } else { - parser = new XMLParser(argv[1]); + parser = new XMLParser(argv[1], extractCallBacks, scriptingEnvironment); } - parser->RegisterCallbacks(extractCallBacks); - parser->RegisterScriptingEnvironment(scriptingEnvironment); - - if(!parser->Init()) + + if(!parser->ReadHeader()) { ERR("Parser not initialized!"); + } + INFO("Parsing in progress.."); double time = get_timestamp(); parser->Parse(); - INFO("parsing finished after " << get_timestamp() - time << " seconds"); + INFO("Parsing finished after " << get_timestamp() - time << " seconds"); externalMemory.PrepareData(outputFileName, restrictionsFileName, amountOfRAM); diff --git a/features/bicycle/restrictions.feature b/features/bicycle/restrictions.feature index 27c5c353e..2d5fa40c5 100644 --- a/features/bicycle/restrictions.feature +++ b/features/bicycle/restrictions.feature @@ -1,6 +1,6 @@ @routing @bicycle @restrictions Feature: Bike - Turn restrictions - Handle turn restrictions as defined by http://wiki.openstreetmap.org/wiki/Relation:restriction + Ignore turn restrictions on bicycle, since you always become a temporary pedestrian. Note that if u-turns are allowed, turn restrictions can lead to suprising, but correct, routes. Background: @@ -26,7 +26,7 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | - | s | w | | + | s | w | sj,wj | | s | n | sj,nj | | s | e | sj,ej | @@ -52,7 +52,7 @@ Feature: Bike - Turn restrictions | from | to | route | | s | w | sj,wj | | s | n | sj,nj | - | s | e | | + | s | e | sj,ej | @no_turning Scenario: Bike - No u-turn @@ -74,7 +74,7 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | - | s | w | | + | s | w | sj,wj | | s | n | sj,nj | | s | e | sj,ej | @@ -98,7 +98,7 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | - | s | w | | + | s | w | sj,wj | | s | n | sj,nj | | s | e | sj,ej | @@ -123,8 +123,8 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | | s | w | sj,wj | - | s | n | | - | s | e | | + | s | n | sj,nj | + | s | e | sj,ej | @only_turning Scenario: Bike - Only right turn @@ -146,8 +146,8 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | - | s | w | | - | s | n | | + | s | w | sj,wj | + | s | n | sj,nj | | s | e | sj,ej | @only_turning @@ -170,9 +170,9 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | - | s | w | | + | s | w | sj,wj | | s | n | sj,nj | - | s | e | | + | s | e | sj,ej | @no_turning Scenario: Bike - Handle any only_* restriction @@ -194,9 +194,9 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | - | s | w | | + | s | w | sj,wj | | s | n | sj,nj | - | s | e | | + | s | e | sj,ej | @except Scenario: Bike - Except tag and on no_ restrictions @@ -224,8 +224,8 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | | s | a | sj,aj | - | s | b | | - | s | c | | + | s | b | sj,bj | + | s | c | sj,cj | | s | d | sj,dj | @except @@ -281,9 +281,9 @@ Feature: Bike - Turn restrictions When I route I should get | from | to | route | - | s | a | | + | s | a | sj,ja | | s | b | sj,jb | | s | c | sj,jc | | s | d | sj,jd | - | s | e | | - | s | f | | + | s | e | sj,je | + | s | f | sj,jf | diff --git a/features/support/data.rb b/features/support/data.rb index 227a962fc..ce6b995c1 100644 --- a/features/support/data.rb +++ b/features/support/data.rb @@ -205,14 +205,15 @@ def write_timestamp end def reprocess + use_pbf = true Dir.chdir TEST_FOLDER do write_osm write_timestamp - convert_osm_to_pbf + convert_osm_to_pbf if use_pbf unless extracted? log_preprocess_info log "== Extracting #{@osm_file}.osm...", :preprocess - unless system "../osrm-extract #{@osm_file}.osm.pbf 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE} #{PROFILES_PATH}/#{@profile}.lua" + unless system "../osrm-extract #{@osm_file}.osm#{'.pbf' if use_pbf} 1>>#{PREPROCESS_LOG_FILE} 2>>#{PREPROCESS_LOG_FILE} #{PROFILES_PATH}/#{@profile}.lua" log "*** Exited with code #{$?.exitstatus}.", :preprocess raise ExtractError.new $?.exitstatus, "osrm-extract exited with code #{$?.exitstatus}." end diff --git a/profiles/bicycle.lua b/profiles/bicycle.lua index 3a1544cf6..f6609d097 100644 --- a/profiles/bicycle.lua +++ b/profiles/bicycle.lua @@ -64,6 +64,7 @@ man_made_speeds = { route_speeds = { ["ferry"] = 5 } + take_minimum_of_speeds = true obey_oneway = true obey_bollards = false @@ -71,7 +72,7 @@ use_restrictions = true ignore_areas = true -- future feature traffic_signal_penalty = 5 u_turn_penalty = 20 - +use_turn_restrictions = false -- End of globals function get_exceptions(vector) diff --git a/profiles/foot.lua b/profiles/foot.lua index e85cc2fd0..fb0dee8db 100644 --- a/profiles/foot.lua +++ b/profiles/foot.lua @@ -41,7 +41,7 @@ use_restrictions = false ignore_areas = true -- future feature traffic_signal_penalty = 2 u_turn_penalty = 2 - +use_turn_restrictions = false -- End of globals function get_exceptions(vector)