diff --git a/Extractor/BaseParser.h b/Extractor/BaseParser.h index d0dcbff27..4d6782a3f 100644 --- a/Extractor/BaseParser.h +++ b/Extractor/BaseParser.h @@ -31,6 +31,14 @@ public: virtual bool RegisterCallbacks(bool (*nodeCallbackPointer)(NodeT), bool (*restrictionCallbackPointer)(RestrictionT), bool (*wayCallbackPointer)(WayT)) = 0; virtual void RegisterLUAState(lua_State *myLuaState) = 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 + } + } + }; #endif /* BASEPARSER_H_ */ diff --git a/Extractor/ExtractionContainers.cpp b/Extractor/ExtractionContainers.cpp index bd96e406c..33452e6b5 100644 --- a/Extractor/ExtractionContainers.cpp +++ b/Extractor/ExtractionContainers.cpp @@ -20,7 +20,7 @@ #include "ExtractionContainers.h" -void ExtractionContainers::PrepareData(const Settings & settings, const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM) { +void ExtractionContainers::PrepareData(const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM) { try { unsigned usedNodeCounter = 0; unsigned usedEdgeCounter = 0; @@ -157,8 +157,6 @@ void ExtractionContainers::PrepareData(const Settings & settings, const std::str continue; } if(*usedNodeIDsIT == nodesIT->id) { - if(!settings.obeyBollards && nodesIT->bollard) - nodesIT->bollard = false; fout.write((char*)&(*nodesIT), sizeof(_Node)); ++usedNodeCounter; ++usedNodeIDsIT; diff --git a/Extractor/ExtractionContainers.h b/Extractor/ExtractionContainers.h index d66115c88..40ce02ec4 100644 --- a/Extractor/ExtractionContainers.h +++ b/Extractor/ExtractionContainers.h @@ -46,7 +46,7 @@ public: wayStartEndVector.clear(); } - void PrepareData(const Settings & settings, const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM); + void PrepareData( const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM); STXXLNodeIDVector usedNodeIDs; STXXLNodeVector allNodes; diff --git a/Extractor/ExtractionHelperFunctions.h b/Extractor/ExtractionHelperFunctions.h new file mode 100644 index 000000000..80f4d4884 --- /dev/null +++ b/Extractor/ExtractionHelperFunctions.h @@ -0,0 +1,64 @@ +/* + 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. + */ + + + +#ifndef EXTRACTIONHELPERFUNCTIONS_H_ +#define EXTRACTIONHELPERFUNCTIONS_H_ + +#include + +inline bool durationIsValid(const std::string &s) { + boost::regex e ("((\\d|\\d\\d):)*(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl); + + std::vector< std::string > result; + boost::algorithm::split_regex( result, s, boost::regex( ":" ) ) ; + bool matched = regex_match(s, e); + return matched; +} + +inline unsigned parseDuration(const std::string &s) { + int hours = 0; + int minutes = 0; + boost::regex e ("((\\d|\\d\\d):)*(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl); + + std::vector< std::string > result; + boost::algorithm::split_regex( result, s, boost::regex( ":" ) ) ; + bool matched = regex_match(s, e); + if(matched) { + hours = (result.size()== 2) ? atoi(result[0].c_str()) : 0; + minutes = (result.size()== 2) ? atoi(result[1].c_str()) : atoi(result[0].c_str()); + return 600*(hours*60+minutes); + } + return UINT_MAX; + +} + +inline int parseMaxspeed(std::string input) { //call-by-value on purpose. + boost::algorithm::to_lower(input); + int n = atoi(input.c_str()); + if (input.find("mph") != std::string::npos || input.find("mp/h") != std::string::npos) { + n = (n*1609)/1000; + } + return n; +} + + +#endif /* EXTRACTIONHELPERFUNCTIONS_H_ */ diff --git a/Extractor/ExtractorCallbacks.cpp b/Extractor/ExtractorCallbacks.cpp index 3c522bbcc..218a285d2 100644 --- a/Extractor/ExtractorCallbacks.cpp +++ b/Extractor/ExtractorCallbacks.cpp @@ -40,40 +40,17 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "ExtractorCallbacks.h" - -bool ExtractorCallbacks::checkForValidTiming(const std::string &s, DurationContainer & duration) { - boost::regex e ("((\\d|\\d\\d):)*(\\d|\\d\\d)",boost::regex_constants::icase|boost::regex_constants::perl); - - std::vector< std::string > result; - boost::algorithm::split_regex( result, s, boost::regex( ":" ) ) ; - bool matched = regex_match(s, e); - if(matched) { - duration.hours = (result.size()== 2) ? atoi(result[0].c_str()) : 0; - duration.minutes = (result.size()== 2) ? atoi(result[1].c_str()) : atoi(result[0].c_str()); - } - return matched; -} - -inline int ExtractorCallbacks::parseMaxspeed(std::string input) const { //call-by-value on purpose. - boost::algorithm::to_lower(input); - int n = atoi(input.c_str()); - if (input.find("mph") != std::string::npos || input.find("mp/h") != std::string::npos) { - n = (n*1609)/1000; - } - return n; -} +#include "ExtractionHelperFunctions.h" ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; } -ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, Settings set, StringMap * strMap) { +ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) { externalMemory = ext; - settings = set; stringMap = strMap; } ExtractorCallbacks::~ExtractorCallbacks() { } - /** warning: caller needs to take care of synchronization! */ bool ExtractorCallbacks::nodeFunction(_Node &n) { externalMemory->allNodes.push_back(n); @@ -87,146 +64,9 @@ bool ExtractorCallbacks::restrictionFunction(_RawRestrictionContainer &r) { /** warning: caller needs to take care of synchronization! */ bool ExtractorCallbacks::wayFunction(_Way &w) { + /*** Store name of way and split it into edge segments ***/ - //Get the properties of the way. - std::string highway( w.keyVals.Find("highway") ); - std::string name( w.keyVals.Find("name") ); - std::string ref( w.keyVals.Find("ref")); - std::string junction( w.keyVals.Find("junction") ); - std::string route( w.keyVals.Find("route") ); - int maxspeed( parseMaxspeed(w.keyVals.Find("maxspeed")) ); - std::string man_made( w.keyVals.Find("man_made") ); - std::string barrier( w.keyVals.Find("barrier") ); - std::string oneway( w.keyVals.Find("oneway")); - std::string cycleway( w.keyVals.Find("cycleway")); - std::string duration ( w.keyVals.Find("duration")); - std::string service (w.keyVals.Find("service")); - std::string area(w.keyVals.Find("area")); - - if("yes" == area && settings.ignoreAreas) - return true; - - //Save the name of the way if it has one, ref has precedence over name tag. - if ( 0 < ref.length() ) - w.name = ref; - else - if ( 0 < name.length() ) - w.name = name; - - if(junction == "roundabout") { - w.roundabout = true; - } - - //Is the route tag listed as usable way in the profile? - if(settings[route] > 0 || settings[man_made] > 0) { - w.useful = true; - DurationContainer dc; - if(checkForValidTiming(duration, dc)){ - w.speed = (600*(dc.hours*60+dc.minutes))/std::max((unsigned)(w.path.size()-1),1u); - w.isDurationSet = true; - } else { - w.speed = settings[route]; - } - w.direction = _Way::bidirectional; - if(0 < settings[route]) - highway = route; - else if (0 < settings[man_made]) { - highway = man_made; - } - } - - //determine the access value - std::string access; - std::string onewayClass; - std::string accessTag; - BOOST_FOREACH(std::string & s, settings.accessTags) { - access = std::string(w.keyVals.Find(s)); - if(0 < access.size()) { - accessTag = s; - onewayClass = std::string(w.keyVals.Find("oneway:"+access)); - break; - } - } - - if(0 < access.size()) { - // handle ways with default access = no - if(settings.accessForbiddenDefault.find(access) != settings.accessForbiddenDefault.end()) { - access = std::string("no"); - } - } - - //Is the highway tag listed as usable way? - if(0 < settings[highway] || "yes" == access || "designated" == access) { - if(!w.isDurationSet) { - if(0 < settings[highway]) { - if(0 < maxspeed) - if(settings.takeMinimumOfSpeeds) - w.speed = std::min(settings[highway], maxspeed); - else - w.speed = maxspeed; - else - w.speed = settings[highway]; - } else { - if(0 < maxspeed) - if(settings.takeMinimumOfSpeeds) - w.speed = std::min(settings.defaultSpeed, maxspeed); - else w.speed = maxspeed; - else - w.speed = settings.defaultSpeed; - highway = "default"; - } - } - w.useful = true; - - //Okay, do we have access to that way? - if(0 < access.size()) { //fastest way to check for non-empty string - //If access is forbidden, we don't want to route there. - if(settings.accessForbiddenKeys.find(access) != settings.accessForbiddenKeys.end()) { - w.access = false; - } - if(settings.accessRestrictionKeys.find(access) != settings.accessRestrictionKeys.end()) { - w.isAccessRestricted = true; - } - } - - if(0 < service.size()) { - if(settings.accessRestrictedService.find(service) != settings.accessRestrictedService.end()) { - w.isAccessRestricted = true; - } - } - - if("no" == access) { - return true; - } - - if( settings.obeyOneways ) { - if( onewayClass == "yes" || onewayClass == "1" || onewayClass == "true" ) { - w.direction = _Way::oneway; - } else if( onewayClass == "no" || onewayClass == "0" || onewayClass == "false" ) { - w.direction = _Way::bidirectional; - } else if( onewayClass == "-1" ) { - w.direction = _Way::opposite; - } else if( oneway == "no" || oneway == "0" || oneway == "false" ) { - w.direction = _Way::bidirectional; - } else if( accessTag == "bicycle" && (cycleway == "opposite" || cycleway == "opposite_track" || cycleway == "opposite_lane") ) { - w.direction = _Way::bidirectional; - } else if( oneway == "-1") { - w.direction = _Way::opposite; - } else if( oneway == "yes" || oneway == "1" || oneway == "true" || junction == "roundabout" || highway == "motorway_link" || highway == "motorway" ) { - w.direction = _Way::oneway; - } else { - w.direction = _Way::bidirectional; - } - } else { - w.direction = _Way::bidirectional; - } - } - - if ( w.useful && w.access && (1 < w.path.size()) ) { //Only true if the way is specified by the speed profile - w.type = settings.GetHighwayTypeID(highway); - if(0 > w.type) { - ERR("Resolved highway " << highway << " to " << w.type); - } + if ( w.speed > 0 ) { //Only true if the way is specified by the speed profile //Get the unique identifier for the street name const StringMap::const_iterator strit = stringMap->find(w.name); @@ -252,7 +92,7 @@ bool ExtractorCallbacks::wayFunction(_Way &w) { } for(vector< NodeID >::size_type n = 0; n < w.path.size()-1; ++n) { - externalMemory->allEdges.push_back(_Edge(w.path[n], w.path[n+1], w.type, w.direction, w.speed, w.nameID, w.roundabout, highway == settings.excludeFromGrid || "pier" == highway, w.isDurationSet, w.isAccessRestricted)); + externalMemory->allEdges.push_back(_Edge(w.path[n], w.path[n+1], w.type, w.direction, w.speed, w.nameID, w.roundabout, w.ignoreInGrid, w.isDurationSet, w.isAccessRestricted)); externalMemory->usedNodeIDs.push_back(w.path[n]); } externalMemory->usedNodeIDs.push_back(w.path.back()); @@ -262,7 +102,3 @@ bool ExtractorCallbacks::wayFunction(_Way &w) { } return true; } - - - - diff --git a/Extractor/ExtractorCallbacks.h b/Extractor/ExtractorCallbacks.h index 917e89529..ddf64cb9d 100644 --- a/Extractor/ExtractorCallbacks.h +++ b/Extractor/ExtractorCallbacks.h @@ -33,20 +33,12 @@ or see http://www.gnu.org/licenses/agpl.txt. class ExtractorCallbacks{ private: - Settings settings; StringMap * stringMap; ExtractionContainers * externalMemory; - struct DurationContainer { - int hours; - int minutes; - }; - - bool checkForValidTiming(const std::string &s, DurationContainer & duration); - inline int parseMaxspeed(std::string input) const; ExtractorCallbacks(); public: - explicit ExtractorCallbacks(ExtractionContainers * ext, Settings set, StringMap * strMap); + explicit ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap); ~ExtractorCallbacks(); diff --git a/Extractor/ExtractorStructs.h b/Extractor/ExtractorStructs.h index 7e7890a60..120551f24 100644 --- a/Extractor/ExtractorStructs.h +++ b/Extractor/ExtractorStructs.h @@ -23,7 +23,12 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include + +#include +#include +#include #include + #include "../DataStructures/Coordinate.h" #include "../DataStructures/HashTable.h" #include "../DataStructures/ImportNode.h" @@ -41,11 +46,12 @@ struct _Way { direction = _Way::notSure; speed = -1; type = -1; - useful = false; +// useful = false; access = true; roundabout = false; isDurationSet = false; isAccessRestricted = false; + ignoreInGrid = false; } enum { @@ -56,11 +62,12 @@ struct _Way { std::string name; double speed; short type; - bool useful; +// bool useful; bool access; bool roundabout; bool isDurationSet; bool isAccessRestricted; + bool ignoreInGrid; std::vector< NodeID > path; HashTable keyVals; }; @@ -133,41 +140,6 @@ struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDSta } }; -struct Settings { - Settings() : obeyBollards(true), obeyOneways(true), useRestrictions(true), ignoreAreas(false), defaultSpeed(30), takeMinimumOfSpeeds(false), excludeFromGrid("ferry") {} - StringToIntPairMap speedProfile; - int operator[](const std::string & param) const { - if(speedProfile.find(param) == speedProfile.end()) - return 0; - else - return speedProfile.at(param).first; - } - int GetHighwayTypeID(const std::string & param) const { - if(param == excludeFromGrid) { - return SHRT_MAX; - } - assert(param != "ferry"); - if(speedProfile.find(param) == speedProfile.end()) { - ERR("There is a bug with highway \"" << param << "\""); - return -1; - } else { - return speedProfile.at(param).second; - } - } - bool obeyBollards; - bool obeyOneways; - bool useRestrictions; - bool ignoreAreas; - std::vector accessTags; - int defaultSpeed; - bool takeMinimumOfSpeeds; - std::string excludeFromGrid; - boost::unordered_map accessRestrictedService; - boost::unordered_map accessRestrictionKeys; - boost::unordered_map accessForbiddenKeys; - boost::unordered_map accessForbiddenDefault; -}; - struct Cmp : public std::binary_function { typedef NodeID value_type; bool operator () (const NodeID & a, const NodeID & b) const { diff --git a/Extractor/LuaUtil.h b/Extractor/LuaUtil.h index a1060164a..7134f96e0 100644 --- a/Extractor/LuaUtil.h +++ b/Extractor/LuaUtil.h @@ -30,4 +30,6 @@ void LUA_print(T number) { std::cout << "[LUA] " << number << std::endl; } + + #endif /* LUAUTIL_H_ */ diff --git a/Extractor/PBFParser.h b/Extractor/PBFParser.h index 372e8d817..2710cad88 100644 --- a/Extractor/PBFParser.h +++ b/Extractor/PBFParser.h @@ -234,6 +234,7 @@ private: denseTagIndex += 2; } + /** Pass the unpacked node to the LUA call back **/ int ret = -1; try { ret = luabind::call_function( @@ -249,23 +250,16 @@ private: report_errors(Ler, -1); } catch (...) { - cerr<<"Unknown error!"<( + myLuaState, + "way_function", + boost::ref(w), + w.path.size() + ); + if(!(*wayCallback)(w)) { + std::cerr << "[PBFParser] way not parsed" << std::endl; + } + } catch (const luabind::error &er) { + cerr << er.what() << endl; + lua_State* Ler=er.state(); + report_errors(Ler, -1); + } + catch (...) { + cerr<<"Unknown error!"< #include #include "../typedefs.h" @@ -65,15 +66,49 @@ public: if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) { _Node n = _ReadXMLNode( ); - if(!(*nodeCallback)(n)) - std::cerr << "[XMLParser] node not parsed" << std::endl; + /** Pass the unpacked node to the LUA call back **/ + int ret = -1; + try { + ret = luabind::call_function( + myLuaState, + "node_function", + boost::ref(n) + ); + if(!(*nodeCallback)(n)) + std::cerr << "[XMLParser] dense node not parsed" << std::endl; + } catch (const luabind::error &er) { + cerr << er.what() << endl; + lua_State* Ler=er.state(); + report_errors(Ler, -1); + } + catch (...) { + ERR("Unknown error occurred during PBF dense node parsing!"); + } } if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { string name; _Way way = _ReadXMLWay( ); - if(!(*wayCallback)(way)) { - std::cerr << "[XMLParser] way not parsed" << std::endl; + + /** Pass the unpacked way to the LUA call back **/ + int ret = -1; + try { + ret = luabind::call_function( + myLuaState, + "way_function", + boost::ref(way), + way.path.size() + ); + if(!(*wayCallback)(way)) { + std::cerr << "[PBFParser] way not parsed" << std::endl; + } + } catch (const luabind::error &er) { + cerr << er.what() << endl; + lua_State* Ler=er.state(); + report_errors(Ler, -1); + } + catch (...) { + cerr<<"Unknown error!"<first); - INFO("Using profile \"" << usedSpeedProfile << "\"") - BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child(usedSpeedProfile)) { - std::string name = v.first; - std::string value = v.second.get(""); - DEBUG("inserting " << name << "=" << value); - if(name == "obeyOneways") { - if(value == "no") - settings.obeyOneways = false; - } else if(name == "obeyBollards") { - if(value == "no") { - settings.obeyBollards = false; - } - } else if(name == "useRestrictions") { - if(value == "no") - settings.useRestrictions = false; - } else if(name == "accessTags") { - std::vector tokens; - stringSplit(value, ',', tokens); - settings.accessTags = tokens; - } else if(name == "excludeFromGrid") { - settings.excludeFromGrid = value; - } else if(name == "defaultSpeed") { - settings.defaultSpeed = atoi(value.c_str()); - settings.speedProfile["default"] = std::make_pair(settings.defaultSpeed, settings.speedProfile.size() ); - } else if( name == "takeMinimumOfSpeeds") { - settings.takeMinimumOfSpeeds = ("yes" == value); - } else if( name == "ignoreAreas") { - settings.ignoreAreas = ("yes" == value); - } else if( name == "accessRestrictedService") { - //split value at commas - std::vector tokens; - stringSplit(value, ',', tokens); - //put each value into map - BOOST_FOREACH(std::string & s, tokens) { - INFO("adding " << s << " to accessRestrictedService"); - settings.accessRestrictedService.insert(std::make_pair(s, true)); - } - } else if( name == "accessRestrictionKeys") { - //split value at commas - std::vector tokens; - stringSplit(value, ',', tokens); - //put each value into map - BOOST_FOREACH(std::string & s, tokens) { - INFO("adding " << s << " to accessRestrictionKeys"); - settings.accessRestrictionKeys.insert(std::make_pair(s, true)); - } - } else if( name == "accessForbiddenKeys") { - //split value at commas - std::vector tokens; - stringSplit(value, ',', tokens); - //put each value into map - BOOST_FOREACH(std::string & s, tokens) { - INFO("adding " << s << " to accessForbiddenKeys"); - settings.accessForbiddenKeys.insert(std::make_pair(s, true)); - } - } else if( name == "accessForbiddenDefault") { - //split value at commas - std::vector tokens; - stringSplit(value, ',', tokens); - //put each value into map - BOOST_FOREACH(std::string & s, tokens) { - INFO("adding " << s << " to accessForbiddenDefault"); - settings.accessForbiddenDefault.insert(std::make_pair(s, true)); - } - } - settings.speedProfile[name] = std::make_pair(std::atoi(value.c_str()), settings.speedProfile.size() ); - } - } catch(std::exception& e) { - ERR("caught: " << e.what() ); - } /*** Setup Scripting Environment ***/ @@ -207,7 +122,10 @@ int main (int argc, char *argv[]) { // Add our function to the state's global scope luabind::module(myLuaState) [ - luabind::def("print", LUA_print) + luabind::def("print", LUA_print), + luabind::def("parseMaxspeed", parseMaxspeed), + luabind::def("durationIsValid", durationIsValid), + luabind::def("parseDuration", parseDuration) ]; if(0 != luaL_dostring( @@ -233,13 +151,35 @@ int main (int argc, char *argv[]) { .def_readwrite("traffic_light", &ImportNode::trafficLight) .def_readwrite("tags", &ImportNode::keyVals) ]; + + luabind::module(myLuaState) [ + luabind::class_<_Way>("Way") + .def(luabind::constructor<>()) + .def_readwrite("name", &_Way::name) + .def_readwrite("speed", &_Way::speed) + .def_readwrite("type", &_Way::type) + .def_readwrite("access", &_Way::access) + .def_readwrite("roundabout", &_Way::roundabout) + .def_readwrite("is_duration_set", &_Way::isDurationSet) + .def_readwrite("is_access_restricted", &_Way::isAccessRestricted) + .def_readwrite("ignore_in_grid", &_Way::ignoreInGrid) + .def_readwrite("tags", &_Way::keyVals) + .def_readwrite("direction", &_Way::direction) + .enum_("constants") + [ + luabind::value("notSure", 0), + luabind::value("oneway", 1), + luabind::value("bidirectional", 2), + luabind::value("opposite", 3) + ] + ]; // Now call our function in a lua script if(0 != luaL_dofile(myLuaState, "profile.lua")) { ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); } - //open string library; - luaopen_string(myLuaState); + //open utility libraries string library; + luaL_openlibs(myLuaState); /*** End of Scripting Environment Setup; ***/ @@ -260,7 +200,7 @@ int main (int argc, char *argv[]) { ExtractionContainers externalMemory; stringMap[""] = 0; - extractCallBacks = new ExtractorCallbacks(&externalMemory, settings, &stringMap); + extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap); BaseParser<_Node, _RawRestrictionContainer, _Way> * parser; if(isPBF) { parser = new PBFParser(argv[1]); @@ -274,7 +214,7 @@ int main (int argc, char *argv[]) { INFO("Parser not initialized!"); parser->Parse(); - externalMemory.PrepareData(settings, outputFileName, restrictionsFileName, amountOfRAM); + externalMemory.PrepareData(outputFileName, restrictionsFileName, amountOfRAM); stringMap.clear(); delete parser; @@ -289,7 +229,6 @@ bool nodeFunction(_Node n) { extractCallBacks->nodeFunction(n); return true; } - bool restrictionFunction(_RawRestrictionContainer r) { extractCallBacks->restrictionFunction(r); ++globalRestrictionCounter; diff --git a/profile.lua b/profile.lua index 946ba8f0c..cdc424590 100644 --- a/profile.lua +++ b/profile.lua @@ -1,27 +1,168 @@ +-- Begin of globals + bollards_whitelist = { [""] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["no"] = true} -access_whitelist = { ["yes"] = true, ["motorcar"] = true, ["permissive"] = true } -access_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestery"] = true } +access_tag_whitelist = { ["yes"] = true, ["motorcar"] = true, ["motor_vehicle"] = true, ["vehicle"] = true, ["permissive"] = true, ["designated"] = true } +access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestery"] = true } +access_tag_restricted = { ["destination"] = true, ["delivery"] = true } +service_tag_restricted = { ["parking_aisle"] = true } +ignore_in_grid = { ["ferry"] = true, ["pier"] = true } + +speed_profile = { + ["motorway"] = 90, + ["motorway_link"] = 75, + ["trunk"] = 85, + ["trunk_link"] = 70, + ["primary"] = 65, + ["primary_link"] = 60, + ["secondary"] = 55, + ["secondary_link"] = 50, + ["tertiary"] = 40, + ["tertiary_link"] = 30, + ["unclassified"] = 25, + ["residential"] = 25, + ["living_street"] = 10, + ["service"] = 15, +-- ["track"] = 5, + ["ferry"] = 5, + ["pier"] = 5, + ["default"] = 50 +} + +take_minimum_of_speeds = true +obey_oneway = true + +-- End of globals function node_function (node) - local barrier = node.tags:Find("barrier") - local access = node.tags:Find("access") + local barrier = node.tags:Find ("barrier") + local access = node.tags:Find ("access") local traffic_signal = node.tags:Find("highway") if traffic_signal == "traffic_signals" then node.traffic_light = true; end - if access_blacklist[barrier] then + if access_tag_blacklist[barrier] then node.bollard = true; end - if not bollards_whitelist[barrier] then + if not bollards_whitelist[barrier] and not access_tag_whitelist[barrier] then node.bollard = true; end return 1 end -function way_function (way) +function way_function (way, numberOfNodesInWay) + -- A way must have two nodes or more + if(numberOfNodesInWay < 2) then + return 0; + end + + -- First, get the properties of each way that we come across + local highway = way.tags:Find("highway") + local name = way.tags:Find("name") + local ref = way.tags:Find("ref") + local junction = way.tags:Find("junction") + local route = way.tags:Find("route") + local maxspeed = parseMaxspeed(way.tags:Find ( "maxspeed") ) + local man_made = way.tags:Find("man_made") + local barrier = way.tags:Find("barrier") + local oneway = way.tags:Find("oneway") + local cycleway = way.tags:Find("cycleway") + local duration = way.tags:Find("duration") + local service = way.tags:Find("service") + local area = way.tags:Find("area") + local access = way.tags:Find("access") + + -- Second parse the way according to these properties + + if("yes" == area) then + return 0 + end + + -- Check if we are allowed to access the way + if access_tag_blacklist[access] ~=nil and access_tag_blacklist[access] then + return 0; + end + + if "" ~= ref then + way.name = ref + elseif "" ~= name then + way.name = name + end + + if "roundabout" == junction then + way.roundabout = true; + end + + -- Handling ferries and piers + + if (speed_profile[route] ~= nil and speed_profile[route] > 0) or + (speed_profile[man_made] ~= nil and speed_profile[man_made] > 0) + then + if durationIsValid(duration) then + way.speed = parseDuration / math.max(1, numberOfSegments-1); + way.is_duration_set = true; + end + way.direction = Way.bidirectional; + if speed_profile[route] ~= nil then + highway = route; + elseif speed_profile[man_made] ~= nil then + highway = man_made; + end + if not way.is_duration_set then + way.speed = speed_profile[highway] + end + + end + + -- Set the avg speed on the way if it is accessible by road class + if (speed_profile[highway] ~= nil and way.speed == -1 ) then + if (0 < maxspeed and not take_minimum_of_speeds) or (maxspeed == 0) then + maxspeed = math.huge + end + way.speed = math.min(speed_profile[highway], maxspeed) + end + + -- Set the avg speed on ways that are marked accessible + if access_tag_whitelist[access] and way.speed == -1 then + if (0 < maxspeed and not take_minimum_of_speeds) or maxspeed == 0 then + maxspeed = math.huge + end + way.speed = math.min(speed_profile["default"], maxspeed) + end + + -- Set access restriction flag if access is allowed under certain restrictions only + if access ~= "" and access_tag_restricted[access] then + way.is_access_restricted = true + end + + -- Set access restriction flag if service is allowed under certain restrictions only + if service ~= "" and service_tag_restricted[service] then + way.is_access_restricted = true + end + + -- Set direction according to tags on way + if obey_oneway then + if oneway == "no" or oneway == "0" or oneway == "false" then + way.direction = Way.bidirectional + elseif oneway == "-1" then + way.direction = Way.opposite + elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" or highway == "motorway_link" or highway == "motorway" then + way.direction = Way.oneway + else + way.direction = Way.bidirectional + end + else + way.direction = Way.bidirectional + end + + -- Override general direction settings of there is a specific one for our mode of travel + + if ignore_in_grid[highway] ~= nil and ignore_in_grid[highway] then + way.ignore_in_grid = true + end + way.type = 1 return 1 end