move distance computation from r-tree to element type class
This commit is contained in:
		
							parent
							
								
									e2c093856c
								
							
						
					
					
						commit
						50ccfbf554
					
				| @ -4,6 +4,7 @@ | ||||
| #include "Coordinate.h" | ||||
| 
 | ||||
| struct EdgeBasedNode { | ||||
| 
 | ||||
|     EdgeBasedNode() : | ||||
|         id(INT_MAX), | ||||
|         lat1(INT_MAX), | ||||
| @ -16,6 +17,55 @@ struct EdgeBasedNode { | ||||
|         ignoreInGrid(false) | ||||
|     { } | ||||
| 
 | ||||
| 
 | ||||
|     double ComputePerpendicularDistance( | ||||
|         const FixedPointCoordinate& inputPoint, | ||||
|         FixedPointCoordinate & nearest_location, | ||||
|         double & r | ||||
|     ) const { | ||||
|         const double x = inputPoint.lat/COORDINATE_PRECISION; | ||||
|         const double y = inputPoint.lon/COORDINATE_PRECISION; | ||||
|         const double a = lat1/COORDINATE_PRECISION; | ||||
|         const double b = lon1/COORDINATE_PRECISION; | ||||
|         const double c = lat2/COORDINATE_PRECISION; | ||||
|         const double d = lon2/COORDINATE_PRECISION; | ||||
|         double p,q,mX,nY; | ||||
|         if(std::fabs(a-c) > std::numeric_limits<double>::epsilon() ){ | ||||
|             const double m = (d-b)/(c-a); // slope
 | ||||
|             // Projection of (x,y) on line joining (a,b) and (c,d)
 | ||||
|             p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m); | ||||
|             q = b + m*(p - a); | ||||
|         } else { | ||||
|             p = c; | ||||
|             q = y; | ||||
|         } | ||||
|         nY = (d*p - c*q)/(a*d - b*c); | ||||
|         mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we need
 | ||||
|         // not calculate the explicit values of m an n as we
 | ||||
|         // are just interested in the ratio
 | ||||
|         if(std::isnan(mX)) { | ||||
|             r = ((lat2 == inputPoint.lat) && (lon2 == inputPoint.lon)) ? 1. : 0.; | ||||
|         } else { | ||||
|             r = mX; | ||||
|         } | ||||
|         if(r<=0.){ | ||||
|             nearest_location.lat = lat1; | ||||
|             nearest_location.lon = lon1; | ||||
|             return ((b - y)*(b - y) + (a - x)*(a - x)); | ||||
| //            return std::sqrt(((b - y)*(b - y) + (a - x)*(a - x)));
 | ||||
|         } else if(r >= 1.){ | ||||
|             nearest_location.lat = lat2; | ||||
|             nearest_location.lon = lon2; | ||||
|             return ((d - y)*(d - y) + (c - x)*(c - x)); | ||||
| //            return std::sqrt(((d - y)*(d - y) + (c - x)*(c - x)));
 | ||||
|         } | ||||
|         // point lies in between
 | ||||
|         nearest_location.lat = p*COORDINATE_PRECISION; | ||||
|         nearest_location.lon = q*COORDINATE_PRECISION; | ||||
| //        return std::sqrt((p-x)*(p-x) + (q-y)*(q-y));
 | ||||
|         return (p-x)*(p-x) + (q-y)*(q-y); | ||||
|     } | ||||
| 
 | ||||
|     bool operator<(const EdgeBasedNode & other) const { | ||||
|         return other.id < id; | ||||
|     } | ||||
|  | ||||
| @ -124,10 +124,10 @@ public: | ||||
|             FixedPointCoordinate lower_left (other.min_lat, other.min_lon); | ||||
| 
 | ||||
|             return ( | ||||
|                     Contains(upper_left) | ||||
|                     || Contains(upper_right) | ||||
|                     || Contains(lower_right) | ||||
|                     || Contains(lower_left) | ||||
|                     Contains(upper_left ) || | ||||
|                     Contains(upper_right) || | ||||
|                     Contains(lower_right) || | ||||
|                     Contains(lower_left ) | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
| @ -318,8 +318,8 @@ public: | ||||
| 
 | ||||
|             uint64_t current_hilbert_value = HilbertCode::GetHilbertNumberForCoordinate(current_centroid); | ||||
|             input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         //open leaf file
 | ||||
|         boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary); | ||||
|         leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t)); | ||||
| @ -334,6 +334,7 @@ public: | ||||
| 
 | ||||
|             LeafNode current_leaf; | ||||
|             TreeNode current_node; | ||||
|         //SimpleLogger().Write() << "reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes";
 | ||||
|             for(uint32_t current_element_index = 0; RTREE_LEAF_NODE_SIZE > current_element_index; ++current_element_index) { | ||||
|                 if(m_element_count > (processed_objects_count + current_element_index)) { | ||||
|                     uint32_t index_of_next_object = input_wrapper_vector[processed_objects_count + current_element_index].m_array_index; | ||||
| @ -391,6 +392,7 @@ public: | ||||
| 
 | ||||
|         //reverse and renumber tree to have root at index 0
 | ||||
|         std::reverse(m_search_tree.begin(), m_search_tree.end()); | ||||
| 
 | ||||
| #pragma omp parallel for schedule(guided) | ||||
|         for(uint32_t i = 0; i < m_search_tree.size(); ++i) { | ||||
|             TreeNode & current_tree_node = m_search_tree[i]; | ||||
| @ -435,7 +437,7 @@ public: | ||||
| 
 | ||||
|         uint32_t tree_size = 0; | ||||
|         tree_node_file.read((char*)&tree_size, sizeof(uint32_t)); | ||||
|         //SimpleLogger().Write() << "reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes";
 | ||||
| 
 | ||||
|         m_search_tree.resize(tree_size); | ||||
|         tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size); | ||||
|         tree_node_file.close(); | ||||
| @ -526,12 +528,10 @@ public: | ||||
|                         } | ||||
| 
 | ||||
|                         double current_ratio = 0.; | ||||
|                         double current_perpendicular_distance = ComputePerpendicularDistance( | ||||
|                         double current_perpendicular_distance = current_edge.ComputePerpendicularDistance( | ||||
|                                                                                              input_coordinate, | ||||
|                                                                                              FixedPointCoordinate(current_edge.lat1, current_edge.lon1), | ||||
|                                                                                              FixedPointCoordinate(current_edge.lat2, current_edge.lon2), | ||||
|                                                                                              nearest, | ||||
|                                                                                              ¤t_ratio | ||||
|                                                                                              current_ratio | ||||
|                                                                                              ); | ||||
| 
 | ||||
|                         if( | ||||
| @ -556,7 +556,7 @@ public: | ||||
|                         } else if( | ||||
|                                   DoubleEpsilonCompare(current_perpendicular_distance, min_dist) && | ||||
|                                   1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) | ||||
|                                   && CoordinatesAreEquivalent( | ||||
|                                   && EdgesAreEquivalent( | ||||
|                                                               current_start_coordinate, | ||||
|                                                               FixedPointCoordinate( | ||||
|                                                                           current_edge.lat1, | ||||
| @ -736,7 +736,6 @@ public: | ||||
|         return found_a_nearest_edge; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     bool FindPhantomNodeForCoordinate( | ||||
|             const FixedPointCoordinate & input_coordinate, | ||||
|             PhantomNode & result_phantom_node, | ||||
| @ -746,7 +745,7 @@ public: | ||||
|         bool ignore_tiny_components = (zoom_level <= 14); | ||||
|         DataT nearest_edge; | ||||
| 
 | ||||
|         uint32_t io_count = 0; | ||||
|         // uint32_t io_count = 0;
 | ||||
|         uint32_t explored_tree_nodes_count = 0; | ||||
|         //SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
 | ||||
|         double min_dist = std::numeric_limits<double>::max(); | ||||
| @ -758,9 +757,7 @@ public: | ||||
|         //initialize queue with root element
 | ||||
|         std::priority_queue<QueryCandidate> traversal_queue; | ||||
|         double current_min_dist = m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate); | ||||
|         traversal_queue.push( | ||||
|                              QueryCandidate(0, current_min_dist) | ||||
|         ); | ||||
|         traversal_queue.push( QueryCandidate(0, current_min_dist) ); | ||||
| 
 | ||||
|         BOOST_ASSERT_MSG( | ||||
|             std::numeric_limits<double>::epsilon() > (0. - traversal_queue.top().min_dist), | ||||
| @ -778,7 +775,7 @@ public: | ||||
|                 if (current_tree_node.child_is_on_disk) { | ||||
|                     LeafNode current_leaf_node; | ||||
|                     LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node); | ||||
|                     ++io_count; | ||||
|                     // ++io_count;
 | ||||
|                     for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) { | ||||
|                         DataT & current_edge = current_leaf_node.objects[i]; | ||||
|                         if(ignore_tiny_components && current_edge.belongsToTinyComponent) { | ||||
| @ -789,17 +786,16 @@ public: | ||||
|                         } | ||||
| 
 | ||||
|                         double current_ratio = 0.; | ||||
|                        double current_perpendicular_distance = ComputePerpendicularDistance( | ||||
|                         double current_perpendicular_distance = current_edge.ComputePerpendicularDistance( | ||||
|                             input_coordinate, | ||||
|                                 FixedPointCoordinate(current_edge.lat1, current_edge.lon1), | ||||
|                                 FixedPointCoordinate(current_edge.lat2, current_edge.lon2), | ||||
|                             nearest, | ||||
|                                 ¤t_ratio | ||||
|                             current_ratio | ||||
|                         ); | ||||
|                         BOOST_ASSERT( 0 <= current_perpendicular_distance ); | ||||
| 
 | ||||
|                         if( | ||||
|                                 current_perpendicular_distance < min_dist | ||||
|                                 && !DoubleEpsilonCompare( | ||||
|                             ( current_perpendicular_distance < min_dist ) && | ||||
|                             !DoubleEpsilonCompare( | ||||
|                                 current_perpendicular_distance, | ||||
|                                 min_dist | ||||
|                             ) | ||||
| @ -816,10 +812,10 @@ public: | ||||
|                             current_end_coordinate.lon = current_edge.lon2; | ||||
|                             nearest_edge = current_edge; | ||||
|                             found_a_nearest_edge = true; | ||||
|                         } else if( | ||||
|                                 DoubleEpsilonCompare(current_perpendicular_distance, min_dist) && | ||||
|                                 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) | ||||
|                         && CoordinatesAreEquivalent( | ||||
|                         } else | ||||
|                         if( DoubleEpsilonCompare(current_perpendicular_distance, min_dist) && | ||||
|                             ( 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) ) && | ||||
|                             EdgesAreEquivalent( | ||||
|                                 current_start_coordinate, | ||||
|                                 FixedPointCoordinate( | ||||
|                                         current_edge.lat1, | ||||
| @ -885,7 +881,6 @@ public: | ||||
|         } | ||||
| 
 | ||||
|         return found_a_nearest_edge; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
| @ -910,55 +905,7 @@ private: | ||||
|         thread_local_rtree_stream->read((char *)&result_node, sizeof(LeafNode)); | ||||
|     } | ||||
| 
 | ||||
|     inline double ComputePerpendicularDistance( | ||||
|             const FixedPointCoordinate& inputPoint, | ||||
|             const FixedPointCoordinate& source, | ||||
|             const FixedPointCoordinate& target, | ||||
|             FixedPointCoordinate& nearest, double *r) const { | ||||
|         const double x = inputPoint.lat/COORDINATE_PRECISION; | ||||
|         const double y = inputPoint.lon/COORDINATE_PRECISION; | ||||
|         const double a = source.lat/COORDINATE_PRECISION; | ||||
|         const double b = source.lon/COORDINATE_PRECISION; | ||||
|         const double c = target.lat/COORDINATE_PRECISION; | ||||
|         const double d = target.lon/COORDINATE_PRECISION; | ||||
|         double p,q,mX,nY; | ||||
|         if(std::fabs(a-c) > std::numeric_limits<double>::epsilon() ){ | ||||
|             const double m = (d-b)/(c-a); // slope
 | ||||
|             // Projection of (x,y) on line joining (a,b) and (c,d)
 | ||||
|             p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m); | ||||
|             q = b + m*(p - a); | ||||
|         } else { | ||||
|             p = c; | ||||
|             q = y; | ||||
|         } | ||||
|         nY = (d*p - c*q)/(a*d - b*c); | ||||
|         mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we need
 | ||||
|         // not calculate the explicit values of m an n as we
 | ||||
|         // are just interested in the ratio
 | ||||
|         if(std::isnan(mX)) { | ||||
|             *r = (target == inputPoint) ? 1. : 0.; | ||||
|         } else { | ||||
|             *r = mX; | ||||
|         } | ||||
|         if(*r<=0.){ | ||||
|             nearest.lat = source.lat; | ||||
|             nearest.lon = source.lon; | ||||
|             return ((b - y)*(b - y) + (a - x)*(a - x)); | ||||
| //            return std::sqrt(((b - y)*(b - y) + (a - x)*(a - x)));
 | ||||
|         } else if(*r >= 1.){ | ||||
|             nearest.lat = target.lat; | ||||
|             nearest.lon = target.lon; | ||||
|             return ((d - y)*(d - y) + (c - x)*(c - x)); | ||||
| //            return std::sqrt(((d - y)*(d - y) + (c - x)*(c - x)));
 | ||||
|         } | ||||
|         // point lies in between
 | ||||
|         nearest.lat = p*COORDINATE_PRECISION; | ||||
|         nearest.lon = q*COORDINATE_PRECISION; | ||||
| //        return std::sqrt((p-x)*(p-x) + (q-y)*(q-y));
 | ||||
|         return (p-x)*(p-x) + (q-y)*(q-y); | ||||
|     } | ||||
| 
 | ||||
|     inline bool CoordinatesAreEquivalent(const FixedPointCoordinate & a, const FixedPointCoordinate & b, const FixedPointCoordinate & c, const FixedPointCoordinate & d) const { | ||||
|     inline bool EdgesAreEquivalent(const FixedPointCoordinate & a, const FixedPointCoordinate & b, const FixedPointCoordinate & c, const FixedPointCoordinate & d) const { | ||||
|         return (a == b && c == d) || (a == c && b == d) || (a == d && b == c); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user