From 4d27b75897e4267027c69629c1860a01919f315d Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Sat, 26 Jul 2014 00:35:48 +0200 Subject: [PATCH 1/9] Move Rectangle2DInt to own header --- DataStructures/Rectangle.h | 164 +++++++++++++++++++++++++++ DataStructures/StaticRTree.h | 214 +++++------------------------------ 2 files changed, 193 insertions(+), 185 deletions(-) create mode 100644 DataStructures/Rectangle.h diff --git a/DataStructures/Rectangle.h b/DataStructures/Rectangle.h new file mode 100644 index 00000000000..beaf0b1dfe8 --- /dev/null +++ b/DataStructures/Rectangle.h @@ -0,0 +1,164 @@ +#ifndef RECTANGLE_H +#define RECTANGLE_H + +// TODO: Make template type +struct RectangleInt2D +{ + RectangleInt2D() : min_lon(INT_MAX), max_lon(INT_MIN), min_lat(INT_MAX), max_lat(INT_MIN) {} + + int32_t min_lon, max_lon; + int32_t min_lat, max_lat; + + + inline void MergeBoundingBoxes(const RectangleInt2D &other) + { + min_lon = std::min(min_lon, other.min_lon); + max_lon = std::max(max_lon, other.max_lon); + min_lat = std::min(min_lat, other.min_lat); + max_lat = std::max(max_lat, other.max_lat); + BOOST_ASSERT(min_lat != std::numeric_limits::min()); + BOOST_ASSERT(min_lon != std::numeric_limits::min()); + BOOST_ASSERT(max_lat != std::numeric_limits::min()); + BOOST_ASSERT(max_lon != std::numeric_limits::min()); + } + + inline FixedPointCoordinate Centroid() const + { + FixedPointCoordinate centroid; + // The coordinates of the midpoints are given by: + // x = (x1 + x2) /2 and y = (y1 + y2) /2. + centroid.lon = (min_lon + max_lon) / 2; + centroid.lat = (min_lat + max_lat) / 2; + return centroid; + } + + inline bool Intersects(const RectangleInt2D &other) const + { + FixedPointCoordinate upper_left(other.max_lat, other.min_lon); + FixedPointCoordinate upper_right(other.max_lat, other.max_lon); + FixedPointCoordinate lower_right(other.min_lat, other.max_lon); + FixedPointCoordinate lower_left(other.min_lat, other.min_lon); + + return (Contains(upper_left) || Contains(upper_right) || Contains(lower_right) || + Contains(lower_left)); + } + + inline float GetMinDist(const FixedPointCoordinate &location) const + { + const bool is_contained = Contains(location); + if (is_contained) + { + return 0.; + } + + enum Direction + { + INVALID = 0, + NORTH = 1, + SOUTH = 2, + EAST = 4, + NORTH_EAST = 5, + SOUTH_EAST = 6, + WEST = 8, + NORTH_WEST = 9, + SOUTH_WEST = 10 + }; + + Direction d = INVALID; + if (location.lat > max_lat) + d = (Direction) (d | NORTH); + else if (location.lat < min_lat) + d = (Direction) (d | SOUTH); + if (location.lon > max_lon) + d = (Direction) (d | EAST); + else if (location.lon < min_lon) + d = (Direction) (d | WEST); + + BOOST_ASSERT(d != INVALID); + + float min_dist = std::numeric_limits::max(); + switch (d) + { + case NORTH: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, location.lon)); + break; + case SOUTH: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, location.lon)); + break; + case WEST: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, min_lon)); + break; + case EAST: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, max_lon)); + break; + case NORTH_EAST: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, max_lon)); + break; + case NORTH_WEST: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, min_lon)); + break; + case SOUTH_EAST: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, max_lon)); + break; + case SOUTH_WEST: + min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, min_lon)); + break; + default: + break; + } + + BOOST_ASSERT(min_dist != std::numeric_limits::max()); + + return min_dist; + } + + inline float GetMinMaxDist(const FixedPointCoordinate &location) const + { + float min_max_dist = std::numeric_limits::max(); + // Get minmax distance to each of the four sides + const FixedPointCoordinate upper_left(max_lat, min_lon); + const FixedPointCoordinate upper_right(max_lat, max_lon); + const FixedPointCoordinate lower_right(min_lat, max_lon); + const FixedPointCoordinate lower_left(min_lat, min_lon); + + min_max_dist = std::min( + min_max_dist, + std::max( + FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left), + FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right))); + + min_max_dist = std::min( + min_max_dist, + std::max( + FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right), + FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right))); + + min_max_dist = std::min( + min_max_dist, + std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right), + FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left))); + + min_max_dist = std::min( + min_max_dist, + std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left), + FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left))); + return min_max_dist; + } + + inline bool Contains(const FixedPointCoordinate &location) const + { + const bool lats_contained = (location.lat >= min_lat) && (location.lat <= max_lat); + const bool lons_contained = (location.lon >= min_lon) && (location.lon <= max_lon); + return lats_contained && lons_contained; + } + + inline friend std::ostream &operator<<(std::ostream &out, const RectangleInt2D &rect) + { + out << rect.min_lat / COORDINATE_PRECISION << "," << rect.min_lon / COORDINATE_PRECISION + << " " << rect.max_lat / COORDINATE_PRECISION << "," + << rect.max_lon / COORDINATE_PRECISION; + return out; + } +}; + +#endif diff --git a/DataStructures/StaticRTree.h b/DataStructures/StaticRTree.h index 62e194e6689..59ae17f611b 100644 --- a/DataStructures/StaticRTree.h +++ b/DataStructures/StaticRTree.h @@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "QueryNode.h" #include "SharedMemoryFactory.h" #include "SharedMemoryVectorWrapper.h" +#include "Rectangle.h" #include "../ThirdParty/variant/variant.hpp" #include "../Util/floating_point.hpp" @@ -70,190 +71,6 @@ template &objects, - const uint32_t element_count, - const std::vector &coordinate_list) - { - for (uint32_t i = 0; i < element_count; ++i) - { - min_lon = std::min(min_lon, - std::min(coordinate_list.at(objects[i].u).lon, - coordinate_list.at(objects[i].v).lon)); - max_lon = std::max(max_lon, - std::max(coordinate_list.at(objects[i].u).lon, - coordinate_list.at(objects[i].v).lon)); - - min_lat = std::min(min_lat, - std::min(coordinate_list.at(objects[i].u).lat, - coordinate_list.at(objects[i].v).lat)); - max_lat = std::max(max_lat, - std::max(coordinate_list.at(objects[i].u).lat, - coordinate_list.at(objects[i].v).lat)); - } - BOOST_ASSERT(min_lat != std::numeric_limits::min()); - BOOST_ASSERT(min_lon != std::numeric_limits::min()); - BOOST_ASSERT(max_lat != std::numeric_limits::min()); - BOOST_ASSERT(max_lon != std::numeric_limits::min()); - } - - inline void MergeBoundingBoxes(const RectangleInt2D &other) - { - min_lon = std::min(min_lon, other.min_lon); - max_lon = std::max(max_lon, other.max_lon); - min_lat = std::min(min_lat, other.min_lat); - max_lat = std::max(max_lat, other.max_lat); - BOOST_ASSERT(min_lat != std::numeric_limits::min()); - BOOST_ASSERT(min_lon != std::numeric_limits::min()); - BOOST_ASSERT(max_lat != std::numeric_limits::min()); - BOOST_ASSERT(max_lon != std::numeric_limits::min()); - } - - inline FixedPointCoordinate Centroid() const - { - FixedPointCoordinate centroid; - // The coordinates of the midpoints are given by: - // x = (x1 + x2) /2 and y = (y1 + y2) /2. - centroid.lon = (min_lon + max_lon) / 2; - centroid.lat = (min_lat + max_lat) / 2; - return centroid; - } - - inline bool Intersects(const RectangleInt2D &other) const - { - FixedPointCoordinate upper_left(other.max_lat, other.min_lon); - FixedPointCoordinate upper_right(other.max_lat, other.max_lon); - FixedPointCoordinate lower_right(other.min_lat, other.max_lon); - FixedPointCoordinate lower_left(other.min_lat, other.min_lon); - - return (Contains(upper_left) || Contains(upper_right) || Contains(lower_right) || - Contains(lower_left)); - } - - inline float GetMinDist(const FixedPointCoordinate &location) const - { - const bool is_contained = Contains(location); - if (is_contained) - { - return 0.; - } - - enum Direction - { - INVALID = 0, - NORTH = 1, - SOUTH = 2, - EAST = 4, - NORTH_EAST = 5, - SOUTH_EAST = 6, - WEST = 8, - NORTH_WEST = 9, - SOUTH_WEST = 10 - }; - - Direction d = INVALID; - if (location.lat > max_lat) - d = (Direction) (d | NORTH); - else if (location.lat < min_lat) - d = (Direction) (d | SOUTH); - if (location.lon > max_lon) - d = (Direction) (d | EAST); - else if (location.lon < min_lon) - d = (Direction) (d | WEST); - - BOOST_ASSERT(d != INVALID); - - float min_dist = std::numeric_limits::max(); - switch (d) - { - case NORTH: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, location.lon)); - break; - case SOUTH: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, location.lon)); - break; - case WEST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, min_lon)); - break; - case EAST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, max_lon)); - break; - case NORTH_EAST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, max_lon)); - break; - case NORTH_WEST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, min_lon)); - break; - case SOUTH_EAST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, max_lon)); - break; - case SOUTH_WEST: - min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, min_lon)); - break; - default: - break; - } - - BOOST_ASSERT(min_dist != std::numeric_limits::max()); - - return min_dist; - } - - inline float GetMinMaxDist(const FixedPointCoordinate &location) const - { - float min_max_dist = std::numeric_limits::max(); - // Get minmax distance to each of the four sides - const FixedPointCoordinate upper_left(max_lat, min_lon); - const FixedPointCoordinate upper_right(max_lat, max_lon); - const FixedPointCoordinate lower_right(min_lat, max_lon); - const FixedPointCoordinate lower_left(min_lat, min_lon); - - min_max_dist = std::min( - min_max_dist, - std::max( - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left), - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right))); - - min_max_dist = std::min( - min_max_dist, - std::max( - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right), - FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right))); - - min_max_dist = std::min( - min_max_dist, - std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right), - FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left))); - - min_max_dist = std::min( - min_max_dist, - std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left), - FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left))); - return min_max_dist; - } - - inline bool Contains(const FixedPointCoordinate &location) const - { - const bool lats_contained = (location.lat >= min_lat) && (location.lat <= max_lat); - const bool lons_contained = (location.lon >= min_lon) && (location.lon <= max_lon); - return lats_contained && lons_contained; - } - - inline friend std::ostream &operator<<(std::ostream &out, const RectangleInt2D &rect) - { - out << rect.min_lat / COORDINATE_PRECISION << "," << rect.min_lon / COORDINATE_PRECISION - << " " << rect.max_lat / COORDINATE_PRECISION << "," - << rect.max_lon / COORDINATE_PRECISION; - return out; - } - }; - using RectangleT = RectangleInt2D; struct TreeNode @@ -412,7 +229,7 @@ class StaticRTree } // generate tree node that resemble the objects in leaf and store it for next level - current_node.minimum_bounding_rectangle.InitializeMBRectangle( + InitializeMBRectangle(current_node.minimum_bounding_rectangle, current_leaf.objects, current_leaf.object_count, coordinate_list); current_node.child_is_on_disk = true; current_node.children[0] = tree_nodes_in_level.size(); @@ -1199,6 +1016,33 @@ class StaticRTree { return (a == b && c == d) || (a == c && b == d) || (a == d && b == c); } + + inline void InitializeMBRectangle(RectangleT& rectangle, + const std::array &objects, + const uint32_t element_count, + const std::vector &coordinate_list) + { + for (uint32_t i = 0; i < element_count; ++i) + { + rectangle.min_lon = std::min(rectangle.min_lon, + std::min(coordinate_list.at(objects[i].u).lon, + coordinate_list.at(objects[i].v).lon)); + rectangle.max_lon = std::max(rectangle.max_lon, + std::max(coordinate_list.at(objects[i].u).lon, + coordinate_list.at(objects[i].v).lon)); + + rectangle.min_lat = std::min(rectangle.min_lat, + std::min(coordinate_list.at(objects[i].u).lat, + coordinate_list.at(objects[i].v).lat)); + rectangle.max_lat = std::max(rectangle.max_lat, + std::max(coordinate_list.at(objects[i].u).lat, + coordinate_list.at(objects[i].v).lat)); + } + BOOST_ASSERT(rectangle.min_lat != std::numeric_limits::min()); + BOOST_ASSERT(rectangle.min_lon != std::numeric_limits::min()); + BOOST_ASSERT(rectangle.max_lat != std::numeric_limits::min()); + BOOST_ASSERT(rectangle.max_lon != std::numeric_limits::min()); + } }; //[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403 From 651c07c72430acb7d94efa45454dfa6c620ece7a Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Fri, 22 Aug 2014 00:50:48 +0200 Subject: [PATCH 2/9] Add global timer utils Global timers can be used to accumulate timings of the same context in a thread-safe way. --- Util/TimingUtil.h | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/Util/TimingUtil.h b/Util/TimingUtil.h index c1505cebfe7..a0cc67e0bd7 100644 --- a/Util/TimingUtil.h +++ b/Util/TimingUtil.h @@ -29,11 +29,51 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define TIMINGUTIL_H #include +#include +#include +#include + +struct GlobalTimer +{ + GlobalTimer() : time(0) {} + std::atomic time; +}; + +class GlobalTimerFactory +{ +public: + static GlobalTimerFactory& get() + { + static GlobalTimerFactory instance; + return instance; + } + + GlobalTimer& getGlobalTimer(const std::string& name) + { + std::lock_guard lock(map_mutex); + return timer_map[name]; + } + +private: + std::mutex map_mutex; + std::unordered_map timer_map; +}; + +#define GLOBAL_TIMER_AQUIRE(_X) auto& _X##_global_timer = GlobalTimerFactory::get().getGlobalTimer(#_X) +#define GLOBAL_TIMER_RESET(_X) _X##_global_timer.time = 0 +#define GLOBAL_TIMER_START(_X) TIMER_START(_X) +#define GLOBAL_TIMER_STOP(_X) TIMER_STOP(_X); _X##_global_timer.time += TIMER_NSEC(_X) +#define GLOBAL_TIMER_NSEC(_X) static_cast(_X##_global_timer.time) +#define GLOBAL_TIMER_USEC(_X) (_X##_global_timer.time / 1000.0) +#define GLOBAL_TIMER_MSEC(_X) (_X##_global_timer.time / 1000.0 / 1000.0) +#define GLOBAL_TIMER_SEC(_X) (_X##_global_timer.time / 1000.0 / 1000.0 / 1000.0) #define TIMER_START(_X) auto _X##_start = std::chrono::steady_clock::now(), _X##_stop = _X##_start #define TIMER_STOP(_X) _X##_stop = std::chrono::steady_clock::now() -#define TIMER_MSEC(_X) std::chrono::duration_cast(_X##_stop - _X##_start).count() -#define TIMER_SEC(_X) (0.001*std::chrono::duration_cast(_X##_stop - _X##_start).count()) +#define TIMER_NSEC(_X) std::chrono::duration_cast(_X##_stop - _X##_start).count() +#define TIMER_USEC(_X) std::chrono::duration_cast(_X##_stop - _X##_start).count() +#define TIMER_MSEC(_X) (0.000001*std::chrono::duration_cast(_X##_stop - _X##_start).count()) +#define TIMER_SEC(_X) (0.000001*std::chrono::duration_cast(_X##_stop - _X##_start).count()) #define TIMER_MIN(_X) std::chrono::duration_cast(_X##_stop - _X##_start).count() #endif // TIMINGUTIL_H From 7d425aa76f1b713581bff04089943bed7c9820eb Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Sun, 24 Aug 2014 23:47:56 +0200 Subject: [PATCH 3/9] Use iterators for DouglasPeucker --- Algorithms/DouglasPeucker.cpp | 52 ++++++++++++++++---------------- Algorithms/DouglasPeucker.h | 6 ++-- Descriptors/DescriptionFactory.h | 2 +- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/Algorithms/DouglasPeucker.cpp b/Algorithms/DouglasPeucker.cpp index 6444f135753..0e43feda5dd 100644 --- a/Algorithms/DouglasPeucker.cpp +++ b/Algorithms/DouglasPeucker.cpp @@ -106,37 +106,38 @@ DouglasPeucker::DouglasPeucker() { } -void DouglasPeucker::Run(std::vector &input_geometry, const unsigned zoom_level) +void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level) { // check if input data is invalid - BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid"); + BOOST_ASSERT_MSG(begin != end, "geometry invalid"); - if (input_geometry.size() < 2) + unsigned size = std::distance(begin, end); + if (size < 2) { return; } - input_geometry.front().necessary = true; - input_geometry.back().necessary = true; + begin->necessary = true; + std::prev(end)->necessary = true; { BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level"); - unsigned left_border = 0; - unsigned right_border = 1; + RandomAccessIt left_border = begin; + RandomAccessIt right_border = std::next(begin); // Sweep over array and identify those ranges that need to be checked do { // traverse list until new border element found - if (input_geometry[right_border].necessary) + if (right_border->necessary) { // sanity checks - BOOST_ASSERT(input_geometry[left_border].necessary); - BOOST_ASSERT(input_geometry[right_border].necessary); + BOOST_ASSERT(left_border->necessary); + BOOST_ASSERT(right_border->necessary); recursion_stack.emplace(left_border, right_border); left_border = right_border; } ++right_border; - } while (right_border < input_geometry.size()); + } while (right_border != end); } // mark locations as 'necessary' by divide-and-conquer @@ -146,24 +147,23 @@ void DouglasPeucker::Run(std::vector &input_geometry, const const GeometryRange pair = recursion_stack.top(); recursion_stack.pop(); // sanity checks - BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary"); - BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary"); - BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry"); - BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side"); + BOOST_ASSERT_MSG(pair.first->necessary, "left border mus be necessary"); + BOOST_ASSERT_MSG(pair.second->necessary, "right border must be necessary"); + BOOST_ASSERT_MSG(std::distance(pair.second, end) > 0, "right border outside of geometry"); + BOOST_ASSERT_MSG(std::distance(pair.first, pair.second) >= 0, "left border on the wrong side"); int max_int_distance = 0; - unsigned farthest_entry_index = pair.second; - const CoordinatePairCalculator dist_calc(input_geometry[pair.first].location, - input_geometry[pair.second].location); + auto farthest_entry_it = pair.second; + const CoordinatePairCalculator dist_calc(pair.first->location, pair.second->location); // sweep over range to find the maximum - for (const auto i : osrm::irange(pair.first + 1, pair.second)) + for (auto it = std::next(pair.first); it != pair.second; ++it) { - const int distance = dist_calc(input_geometry[i].location); + const int distance = dist_calc(it->location); // found new feasible maximum? if (distance > max_int_distance && distance > douglas_peucker_thresholds[zoom_level]) { - farthest_entry_index = i; + farthest_entry_it = it; max_int_distance = distance; } } @@ -172,14 +172,14 @@ void DouglasPeucker::Run(std::vector &input_geometry, const if (max_int_distance > douglas_peucker_thresholds[zoom_level]) { // mark idx as necessary - input_geometry[farthest_entry_index].necessary = true; - if (1 < (farthest_entry_index - pair.first)) + farthest_entry_it->necessary = true; + if (1 < std::distance(pair.first, farthest_entry_it)) { - recursion_stack.emplace(pair.first, farthest_entry_index); + recursion_stack.emplace(pair.first, farthest_entry_it); } - if (1 < (pair.second - farthest_entry_index)) + if (1 < std::distance(pair.second, farthest_entry_it)) { - recursion_stack.emplace(farthest_entry_index, pair.second); + recursion_stack.emplace(farthest_entry_it, pair.second); } } } diff --git a/Algorithms/DouglasPeucker.h b/Algorithms/DouglasPeucker.h index 60fc377b101..759cbfce6eb 100644 --- a/Algorithms/DouglasPeucker.h +++ b/Algorithms/DouglasPeucker.h @@ -43,16 +43,18 @@ struct SegmentInformation; class DouglasPeucker { + public: + using RandomAccessIt = std::vector::iterator; private: std::vector douglas_peucker_thresholds; - using GeometryRange = std::pair; + using GeometryRange = std::pair; // Stack to simulate the recursion std::stack recursion_stack; public: DouglasPeucker(); - void Run(std::vector &input_geometry, const unsigned zoom_level); + void Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level); }; #endif /* DOUGLASPEUCKER_H_ */ diff --git a/Descriptors/DescriptionFactory.h b/Descriptors/DescriptionFactory.h index ac4c70234ff..7eb4661ca35 100644 --- a/Descriptors/DescriptionFactory.h +++ b/Descriptors/DescriptionFactory.h @@ -190,7 +190,7 @@ class DescriptionFactory } // Generalize poly line - polyline_generalizer.Run(path_description, zoomLevel); + polyline_generalizer.Run(path_description.begin(), path_description.end(), zoomLevel); // fix what needs to be fixed else unsigned necessary_pieces = 0; // a running index that counts the necessary pieces From f16b2adec76f59f70366b050a13d87467d883108 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Mon, 25 Aug 2014 00:21:21 +0200 Subject: [PATCH 4/9] Allow empty ranges in DP --- Algorithms/DouglasPeucker.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Algorithms/DouglasPeucker.cpp b/Algorithms/DouglasPeucker.cpp index 0e43feda5dd..344bf7c8ace 100644 --- a/Algorithms/DouglasPeucker.cpp +++ b/Algorithms/DouglasPeucker.cpp @@ -108,9 +108,6 @@ DouglasPeucker::DouglasPeucker() void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level) { - // check if input data is invalid - BOOST_ASSERT_MSG(begin != end, "geometry invalid"); - unsigned size = std::distance(begin, end); if (size < 2) { From 3b727dea998448d85b91fba9bd03cdbeebe86937 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Sat, 11 Oct 2014 13:46:06 +0200 Subject: [PATCH 5/9] Make atan2_lookup inline since it is header-declared --- Util/TrigonometryTables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Util/TrigonometryTables.h b/Util/TrigonometryTables.h index 64076a23c35..d14540482d2 100644 --- a/Util/TrigonometryTables.h +++ b/Util/TrigonometryTables.h @@ -722,7 +722,7 @@ constexpr unsigned short atan_table[4096] = { // max value is pi/4 constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF; -double atan2_lookup(double y, double x) +inline double atan2_lookup(double y, double x) { if (std::abs(x) < std::numeric_limits::epsilon()) { From edc39112e25fca6adc92eb2b0b648b367cb428a6 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Thu, 23 Oct 2014 00:51:29 +0200 Subject: [PATCH 6/9] Add wrapper function to DouglasPlucker for backwards-compability --- Algorithms/DouglasPeucker.cpp | 5 +++++ Algorithms/DouglasPeucker.h | 1 + 2 files changed, 6 insertions(+) diff --git a/Algorithms/DouglasPeucker.cpp b/Algorithms/DouglasPeucker.cpp index 344bf7c8ace..afd833cccfb 100644 --- a/Algorithms/DouglasPeucker.cpp +++ b/Algorithms/DouglasPeucker.cpp @@ -106,6 +106,11 @@ DouglasPeucker::DouglasPeucker() { } +void DouglasPeucker::Run(std::vector &input_geometry, const unsigned zoom_level) +{ + Run(std::begin(input_geometry), std::end(input_geometry), zoom_level); +} + void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level) { unsigned size = std::distance(begin, end); diff --git a/Algorithms/DouglasPeucker.h b/Algorithms/DouglasPeucker.h index 759cbfce6eb..b5146721ea7 100644 --- a/Algorithms/DouglasPeucker.h +++ b/Algorithms/DouglasPeucker.h @@ -55,6 +55,7 @@ class DouglasPeucker public: DouglasPeucker(); void Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level); + void Run(std::vector &input_geometry, const unsigned zoom_level); }; #endif /* DOUGLASPEUCKER_H_ */ From 00a43221acb7025f72c94c7a0a18804bb463c09c Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Thu, 23 Oct 2014 01:32:05 +0200 Subject: [PATCH 7/9] Use numeric_limits --- DataStructures/Rectangle.h | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/DataStructures/Rectangle.h b/DataStructures/Rectangle.h index beaf0b1dfe8..0c3e4a6070c 100644 --- a/DataStructures/Rectangle.h +++ b/DataStructures/Rectangle.h @@ -1,25 +1,33 @@ #ifndef RECTANGLE_H #define RECTANGLE_H -// TODO: Make template type +#include + +#include +#include +#include + +// TODO: Make template type, add tests struct RectangleInt2D { - RectangleInt2D() : min_lon(INT_MAX), max_lon(INT_MIN), min_lat(INT_MAX), max_lat(INT_MIN) {} + RectangleInt2D() : min_lon(std::numeric_limits::max()), + max_lon(std::numeric_limits::min()), + min_lat(std::numeric_limits::max()), + max_lat(std::numeric_limits::min()) {} int32_t min_lon, max_lon; int32_t min_lat, max_lat; - inline void MergeBoundingBoxes(const RectangleInt2D &other) { min_lon = std::min(min_lon, other.min_lon); max_lon = std::max(max_lon, other.max_lon); min_lat = std::min(min_lat, other.min_lat); max_lat = std::max(max_lat, other.max_lat); - BOOST_ASSERT(min_lat != std::numeric_limits::min()); - BOOST_ASSERT(min_lon != std::numeric_limits::min()); - BOOST_ASSERT(max_lat != std::numeric_limits::min()); - BOOST_ASSERT(max_lon != std::numeric_limits::min()); + BOOST_ASSERT(min_lat != std::numeric_limits::min()); + BOOST_ASSERT(min_lon != std::numeric_limits::min()); + BOOST_ASSERT(max_lat != std::numeric_limits::min()); + BOOST_ASSERT(max_lon != std::numeric_limits::min()); } inline FixedPointCoordinate Centroid() const From 13ed1864697788ffa6884f460564c7026c1009ad Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Thu, 23 Oct 2014 01:32:24 +0200 Subject: [PATCH 8/9] Fix include order in staticrtree --- DataStructures/StaticRTree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DataStructures/StaticRTree.h b/DataStructures/StaticRTree.h index 59ae17f611b..ef4fc2d8b65 100644 --- a/DataStructures/StaticRTree.h +++ b/DataStructures/StaticRTree.h @@ -32,9 +32,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "HilbertValue.h" #include "PhantomNodes.h" #include "QueryNode.h" +#include "Rectangle.h" #include "SharedMemoryFactory.h" #include "SharedMemoryVectorWrapper.h" -#include "Rectangle.h" #include "../ThirdParty/variant/variant.hpp" #include "../Util/floating_point.hpp" From 9805b05738b4bc261a15c18cb62270787a73bcf7 Mon Sep 17 00:00:00 2001 From: Patrick Niklaus Date: Thu, 23 Oct 2014 01:40:52 +0200 Subject: [PATCH 9/9] Reorder include and use correct datatypes --- DataStructures/Rectangle.h | 2 +- Util/TimingUtil.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/DataStructures/Rectangle.h b/DataStructures/Rectangle.h index 0c3e4a6070c..7cbd31504ec 100644 --- a/DataStructures/Rectangle.h +++ b/DataStructures/Rectangle.h @@ -56,7 +56,7 @@ struct RectangleInt2D const bool is_contained = Contains(location); if (is_contained) { - return 0.; + return 0.0f; } enum Direction diff --git a/Util/TimingUtil.h b/Util/TimingUtil.h index a0cc67e0bd7..5f16ff7ca47 100644 --- a/Util/TimingUtil.h +++ b/Util/TimingUtil.h @@ -28,15 +28,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef TIMINGUTIL_H #define TIMINGUTIL_H -#include #include +#include +#include #include #include struct GlobalTimer { GlobalTimer() : time(0) {} - std::atomic time; + std::atomic time; }; class GlobalTimerFactory