Merge pull request #1217 from TheMarex/sketch-upstream
Bring general sketch commits upstream
This commit is contained in:
		
						commit
						9f96c98f02
					
				| @ -108,35 +108,38 @@ DouglasPeucker::DouglasPeucker() | ||||
| 
 | ||||
| void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level) | ||||
| { | ||||
|     // check if input data is invalid
 | ||||
|     BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid"); | ||||
|     Run(std::begin(input_geometry), std::end(input_geometry), zoom_level); | ||||
| } | ||||
| 
 | ||||
|     if (input_geometry.size() < 2) | ||||
| void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level) | ||||
| { | ||||
|     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 +149,23 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &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 +174,14 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -43,15 +43,18 @@ struct SegmentInformation; | ||||
| 
 | ||||
| class DouglasPeucker | ||||
| { | ||||
|   public: | ||||
|     using RandomAccessIt = std::vector<SegmentInformation>::iterator; | ||||
|   private: | ||||
|     std::vector<int> douglas_peucker_thresholds; | ||||
| 
 | ||||
|     using GeometryRange = std::pair<unsigned, unsigned>; | ||||
|     using GeometryRange = std::pair<RandomAccessIt, RandomAccessIt>; | ||||
|     // Stack to simulate the recursion
 | ||||
|     std::stack<GeometryRange> recursion_stack; | ||||
| 
 | ||||
|   public: | ||||
|     DouglasPeucker(); | ||||
|     void Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level); | ||||
|     void Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										172
									
								
								DataStructures/Rectangle.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								DataStructures/Rectangle.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,172 @@ | ||||
| #ifndef RECTANGLE_H | ||||
| #define RECTANGLE_H | ||||
| 
 | ||||
| #include <boost/assert.hpp> | ||||
| 
 | ||||
| #include <algorithm> | ||||
| #include <cstdint> | ||||
| #include <limits> | ||||
| 
 | ||||
| // TODO: Make template type, add tests
 | ||||
| struct RectangleInt2D | ||||
| { | ||||
|     RectangleInt2D() : min_lon(std::numeric_limits<int32_t>::max()), | ||||
|                        max_lon(std::numeric_limits<int32_t>::min()), | ||||
|                        min_lat(std::numeric_limits<int32_t>::max()), | ||||
|                        max_lat(std::numeric_limits<int32_t>::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<int32_t>::min()); | ||||
|         BOOST_ASSERT(min_lon != std::numeric_limits<int32_t>::min()); | ||||
|         BOOST_ASSERT(max_lat != std::numeric_limits<int32_t>::min()); | ||||
|         BOOST_ASSERT(max_lon != std::numeric_limits<int32_t>::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.0f; | ||||
|         } | ||||
| 
 | ||||
|         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<float>::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<float>::max()); | ||||
| 
 | ||||
|         return min_dist; | ||||
|     } | ||||
| 
 | ||||
|     inline float GetMinMaxDist(const FixedPointCoordinate &location) const | ||||
|     { | ||||
|         float min_max_dist = std::numeric_limits<float>::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 | ||||
| @ -32,6 +32,7 @@ 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" | ||||
| 
 | ||||
| @ -70,190 +71,6 @@ template <class EdgeDataT, | ||||
| class StaticRTree | ||||
| { | ||||
|   public: | ||||
|     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 InitializeMBRectangle(const std::array<EdgeDataT, LEAF_NODE_SIZE> &objects, | ||||
|                                           const uint32_t element_count, | ||||
|                                           const std::vector<NodeInfo> &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<int>::min()); | ||||
|             BOOST_ASSERT(min_lon != std::numeric_limits<int>::min()); | ||||
|             BOOST_ASSERT(max_lat != std::numeric_limits<int>::min()); | ||||
|             BOOST_ASSERT(max_lon != std::numeric_limits<int>::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<int>::min()); | ||||
|             BOOST_ASSERT(min_lon != std::numeric_limits<int>::min()); | ||||
|             BOOST_ASSERT(max_lat != std::numeric_limits<int>::min()); | ||||
|             BOOST_ASSERT(max_lon != std::numeric_limits<int>::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<float>::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<float>::max()); | ||||
| 
 | ||||
|             return min_dist; | ||||
|         } | ||||
| 
 | ||||
|         inline float GetMinMaxDist(const FixedPointCoordinate &location) const | ||||
|         { | ||||
|             float min_max_dist = std::numeric_limits<float>::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<EdgeDataT, LEAF_NODE_SIZE> &objects, | ||||
|                                       const uint32_t element_count, | ||||
|                                       const std::vector<NodeInfo> &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<int>::min()); | ||||
|         BOOST_ASSERT(rectangle.min_lon != std::numeric_limits<int>::min()); | ||||
|         BOOST_ASSERT(rectangle.max_lat != std::numeric_limits<int>::min()); | ||||
|         BOOST_ASSERT(rectangle.max_lon != std::numeric_limits<int>::min()); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| //[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
 | ||||
|  | ||||
| @ -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
 | ||||
|  | ||||
| @ -28,12 +28,53 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| #ifndef TIMINGUTIL_H | ||||
| #define TIMINGUTIL_H | ||||
| 
 | ||||
| #include <atomic> | ||||
| #include <chrono> | ||||
| #include <cstdint> | ||||
| #include <mutex> | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| struct GlobalTimer | ||||
| { | ||||
|     GlobalTimer() : time(0) {} | ||||
|     std::atomic<uint64_t> time; | ||||
| }; | ||||
| 
 | ||||
| class GlobalTimerFactory | ||||
| { | ||||
| public: | ||||
|     static GlobalTimerFactory& get() | ||||
|     { | ||||
|         static GlobalTimerFactory instance; | ||||
|         return instance; | ||||
|     } | ||||
| 
 | ||||
|     GlobalTimer& getGlobalTimer(const std::string& name) | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(map_mutex); | ||||
|         return timer_map[name]; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     std::mutex map_mutex; | ||||
|     std::unordered_map<std::string, GlobalTimer> 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<double>(_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<std::chrono::milliseconds>(_X##_stop - _X##_start).count() | ||||
| #define TIMER_SEC(_X) (0.001*std::chrono::duration_cast<std::chrono::milliseconds>(_X##_stop - _X##_start).count()) | ||||
| #define TIMER_NSEC(_X) std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count() | ||||
| #define TIMER_USEC(_X) std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count() | ||||
| #define TIMER_MSEC(_X) (0.000001*std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count()) | ||||
| #define TIMER_SEC(_X)  (0.000001*std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count()) | ||||
| #define TIMER_MIN(_X) std::chrono::duration_cast<std::chrono::minutes>(_X##_stop - _X##_start).count() | ||||
| 
 | ||||
| #endif // TIMINGUTIL_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<double>::epsilon()) | ||||
|     { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user