diff --git a/features/car/conditional_restrictions.feature b/features/car/conditional_restrictions.feature index 3662c2d58..9f687fde0 100644 --- a/features/car/conditional_restrictions.feature +++ b/features/car/conditional_restrictions.feature @@ -318,11 +318,11 @@ Feature: Car - Turn restrictions | m | p | mj,jp,jp | @only_turning @conditionals - Scenario: Car - Somewhere in Liverpool, the UK, GMT timezone + Scenario: Car - Somewhere in London, the UK, GMT timezone Given the extract extra arguments "--parse-conditional-restrictions=1" # 9am UTC, 10am BST - Given the contract extra arguments "--time-zone-file=test/data/tz/liverpool.geojson --parse-conditionals-from-now=1493802000" - Given the customize extra arguments "--time-zone-file=test/data/tz/liverpool.geojson --parse-conditionals-from-now=1493802000" + Given the contract extra arguments "--time-zone-file=test/data/tz/london.geojson --parse-conditionals-from-now=1493802000" + Given the customize extra arguments "--time-zone-file=test/data/tz/london.geojson --parse-conditionals-from-now=1493802000" # """ # a @@ -664,11 +664,11 @@ Feature: Car - Turn restrictions | e | c | florida ne,cap south,cap south | depart,turn left,arrive | @only_turning @conditionals - Scenario: Car - Somewhere in Liverpool, the UK, GMT timezone + Scenario: Car - Somewhere in london, the UK, GMT timezone Given the extract extra arguments "--parse-conditional-restrictions=1" # 9am UTC, 10am BST - Given the contract extra arguments "--time-zone-file=test/data/tz/liverpool.geojson --parse-conditionals-from-now=1493802000" - Given the customize extra arguments "--time-zone-file=test/data/tz/liverpool.geojson --parse-conditionals-from-now=1493802000" + Given the contract extra arguments "--time-zone-file=test/data/tz/london.geojson --parse-conditionals-from-now=1493802000" + Given the customize extra arguments "--time-zone-file=test/data/tz/london.geojson --parse-conditionals-from-now=1493802000" # """ # a diff --git a/include/util/timezones.hpp b/include/util/timezones.hpp index dc9553233..b5d6b6972 100644 --- a/include/util/timezones.hpp +++ b/include/util/timezones.hpp @@ -35,11 +35,10 @@ class Timezoner Timezoner(const char geojson[], std::time_t utc_time_now); Timezoner(const boost::filesystem::path &tz_shapes_filename, std::time_t utc_time_now); - struct tm operator()(const point_t &point) const; + boost::optional operator()(const point_t &point) const; private: void LoadLocalTimesRTree(rapidjson::Document &geojson, std::time_t utc_time); - struct tm default_time; rtree_t rtree; std::vector local_times; }; diff --git a/src/updater/updater.cpp b/src/updater/updater.cpp index f93dc7bfb..6c9370711 100644 --- a/src/updater/updater.cpp +++ b/src/updater/updater.cpp @@ -487,6 +487,8 @@ bool IsRestrictionValid(const Timezoner &tz_handler, // Get local time of the restriction const auto &local_time = tz_handler(point_t{lon, lat}); + if (!local_time) + return false; // TODO: check restriction type [:][:] // http://wiki.openstreetmap.org/wiki/Conditional_restrictions#Tagging @@ -494,7 +496,7 @@ bool IsRestrictionValid(const Timezoner &tz_handler, // TODO: parsing will fail for combined conditions, e.g. Sa-Su AND weight>7 // http://wiki.openstreetmap.org/wiki/Conditional_restrictions#Combined_conditions:_AND - if (osrm::util::CheckOpeningHours(condition, local_time)) + if (osrm::util::CheckOpeningHours(condition, *local_time)) return true; return false; diff --git a/src/util/timezones.cpp b/src/util/timezones.cpp index c0c19a029..36107b2e6 100644 --- a/src/util/timezones.cpp +++ b/src/util/timezones.cpp @@ -6,12 +6,14 @@ #include #include #include +#include #include "rapidjson/document.h" #include "rapidjson/istreamwrapper.h" #include #include +#include #include // Function loads time zone shape polygons, computes a zone local time for utc_time, @@ -25,8 +27,6 @@ namespace updater Timezoner::Timezoner(const char geojson[], std::time_t utc_time_now) { util::Log() << "Time zone validation based on UTC time : " << utc_time_now; - // Thread safety: MT-Unsafe const:env - default_time = *gmtime(&utc_time_now); rapidjson::Document doc; rapidjson::ParseResult ok = doc.Parse(geojson); if (!ok) @@ -41,8 +41,6 @@ Timezoner::Timezoner(const char geojson[], std::time_t utc_time_now) Timezoner::Timezoner(const boost::filesystem::path &tz_shapes_filename, std::time_t utc_time_now) { util::Log() << "Time zone validation based on UTC time : " << utc_time_now; - // Thread safety: MT-Unsafe const:env - default_time = *gmtime(&utc_time_now); if (tz_shapes_filename.empty()) throw osrm::util::exception("Missing time zone geojson file"); @@ -107,7 +105,9 @@ void Timezoner::LoadLocalTimesRTree(rapidjson::Document &geojson, std::time_t ut throw osrm::util::exception("Feature has non-string TZID value."); } const std::string &feat_type = features_array[i].GetObject()["geometry"].GetObject()["type"].GetString(); - if (feat_type == "polygon") + std::regex polygon_match("polygon", std::regex::icase); + std::smatch res; + if (std::regex_match(feat_type, res, polygon_match)) { polygon_t polygon; // per geojson spec, the first array of polygon coords is the exterior ring, we only want to access that @@ -127,7 +127,7 @@ void Timezoner::LoadLocalTimesRTree(rapidjson::Document &geojson, std::time_t ut // Get time zone name and emplace polygon and local time for the UTC input const auto tzname = - features_array[i].GetObject()["properties"].GetObject()["TZID"].GetString(); + features_array[i].GetObject()["properties"].GetObject()["tzid"].GetString(); local_times.push_back(local_time_t{polygon, get_local_time_in_tz(tzname)}); } else @@ -140,7 +140,7 @@ void Timezoner::LoadLocalTimesRTree(rapidjson::Document &geojson, std::time_t ut rtree = rtree_t(polygons); } -struct tm Timezoner::operator()(const point_t &point) const +boost::optional Timezoner::operator()(const point_t &point) const { std::vector result; rtree.query(boost::geometry::index::intersects(point), std::back_inserter(result)); @@ -149,6 +149,7 @@ struct tm Timezoner::operator()(const point_t &point) const const auto index = v.second; if (boost::geometry::within(point, local_times[index].first)) return local_times[index].second; + } } } diff --git a/test/data/tz/liverpool.geojson b/test/data/tz/liverpool.geojson index 91a2a0576..6753d9b6f 100644 --- a/test/data/tz/liverpool.geojson +++ b/test/data/tz/liverpool.geojson @@ -1,8 +1,195 @@ { -"type": "FeatureCollection", - -"features": [ -{ "type": "Feature", "properties": { "tzid": "Europe\/Isle_of_Man" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -4.115297325087907, 54.52745749948722 ], [ -4.0344301, 54.479 ], [ -3.9654913, 54.292 ], [ -3.9921158, 54.219 ], [ -4.1294243, 54.062 ], [ -4.3969301, 53.905 ], [ -4.4945949, 53.869 ], [ -4.8076135, 53.845 ], [ -4.9658203125, 53.863090828317766 ], [ -4.9658203125, 54.353344549330089 ], [ -4.8948807, 54.392 ], [ -4.868376, 54.4339904 ], [ -4.542761329182349, 54.52745749948722 ], [ -4.115297325087907, 54.52745749948722 ] ] ] } }, -{ "type": "Feature", "properties": { "tzid": "Europe\/London" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -4.868376, 54.4339904 ], [ -4.9658203125, 54.440433357982556 ], [ -4.9658203125, 54.52745749948722 ], [ -4.542761329182349, 54.52745749948722 ], [ -4.868376, 54.4339904 ] ] ], [ [ [ -4.9658203125, 52.991764530370652 ], [ -4.8118632, 53.085 ], [ -4.9658203125, 53.175318218576706 ], [ -4.9658203125, 53.428980227009838 ], [ -4.8911294, 53.532 ], [ -4.7808677, 53.595 ], [ -4.6646014, 53.621 ], [ -4.4026046, 53.634 ], [ -4.147566, 53.599 ], [ -4.0053089, 53.526 ], [ -3.8324713, 53.541 ], [ -3.6271987, 53.508 ], [ -3.4402166, 53.547 ], [ -3.4248294, 53.62 ], [ -3.3683406, 53.697 ], [ -3.3958062, 53.764 ], [ -3.3917274, 53.8697263 ], [ -3.5494708, 53.99 ], [ -3.605841, 54.079 ], [ -3.729297, 54.198 ], [ -3.7790165, 54.288 ], [ -3.9491542, 54.4245157 ], [ -4.115297325087907, 54.52745749948722 ], [ -2.13134765625, 54.52745749948722 ], [ -2.13134765625, 52.656393941988028 ], [ -4.9658203125, 52.656393941988028 ], [ -4.9658203125, 52.991764530370652 ] ] ] ] } } -] + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "tzid": "Europe\\/Isle_of_Man" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.115297325087907, + 54.52745749948722 + ], + [ + -4.0344301, + 54.479 + ], + [ + -3.9654913, + 54.292 + ], + [ + -3.9921158, + 54.219 + ], + [ + -4.1294243, + 54.062 + ], + [ + -4.3969301, + 53.905 + ], + [ + -4.4945949, + 53.869 + ], + [ + -4.8076135, + 53.845 + ], + [ + -4.9658203125, + 53.863090828317766 + ], + [ + -4.9658203125, + 54.35334454933009 + ], + [ + -4.8948807, + 54.392 + ], + [ + -4.868376, + 54.4339904 + ], + [ + -4.542761329182349, + 54.52745749948722 + ], + [ + -4.115297325087907, + 54.52745749948722 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": { + "tzid": "Europe\\/London" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -4.9658203125, + 52.99176453037065 + ], + [ + -4.8118632, + 53.085 + ], + [ + -4.9658203125, + 53.175318218576706 + ], + [ + -4.9658203125, + 53.42898022700984 + ], + [ + -4.8911294, + 53.532 + ], + [ + -4.7808677, + 53.595 + ], + [ + -4.6646014, + 53.621 + ], + [ + -4.4026046, + 53.634 + ], + [ + -4.147566, + 53.599 + ], + [ + -4.0053089, + 53.526 + ], + [ + -3.8324713, + 53.541 + ], + [ + -3.6271987, + 53.508 + ], + [ + -3.4402166, + 53.547 + ], + [ + -3.4248294, + 53.62 + ], + [ + -3.3683406, + 53.697 + ], + [ + -3.3958062, + 53.764 + ], + [ + -3.3917274, + 53.8697263 + ], + [ + -3.5494708, + 53.99 + ], + [ + -3.605841, + 54.079 + ], + [ + -3.729297, + 54.198 + ], + [ + -3.7790165, + 54.288 + ], + [ + -3.9491542, + 54.4245157 + ], + [ + -4.115297325087907, + 54.52745749948722 + ], + [ + -2.13134765625, + 54.52745749948722 + ], + [ + -2.13134765625, + 52.65639394198803 + ], + [ + -4.9658203125, + 52.65639394198803 + ], + [ + -4.9658203125, + 52.99176453037065 + ] + ] + ] + } + } + ] }