geokdtree.geokdtree
1from .core import kdtree 2from math import cos, sin, pi 3 4 5# Speed Utils for the 3D GeoKDTree 6def __squared_distance_3d__(p1, p2): 7 """ 8 Function: 9 10 - Calculate the squared distance between two 3D points. 11 12 Required Arguments: 13 14 - `p1` 15 - Type: tuple 16 - What: The first point in 3D space 17 - `p2` 18 - Type: tuple 19 - What: The second point in 3D space 20 21 Returns: 22 23 - The squared distance between the two 3D points. 24 """ 25 return sum( 26 [(p1[0] - p2[0]) ** 2, (p1[1] - p2[1]) ** 2, (p1[2] - p2[2]) ** 2] 27 ) 28 29 30def __closest_point_3d__(node, point, best=None, best_dist=float("inf")): 31 """ 32 Function: 33 34 - Find the closest point in a 3d cartesian system using a KDTree. 35 36 Required Arguments: 37 38 - `node` 39 - Type: tuple 40 - What: The node of the KDTree 41 - `point` 42 - Type: tuple 43 - What: The point to find the closest point to 44 45 Optional Arguments: 46 47 - `best` 48 - Type: tuple or None 49 - What: The best point found so far (default is None) 50 - `best_dist` 51 - Type: float 52 - What: The best distance found so far (default is infinity) 53 54 Returns: 55 56 - The closest point found in the KDTree to the given point. 57 """ 58 if node == 0: 59 return best, best_dist 60 # Get the median node and its distance 61 median_node = node[0] 62 median_node_dist = __squared_distance_3d__(point, median_node) 63 # Update the best point and distance if necessary 64 if best is None or median_node_dist < best_dist: 65 best = median_node 66 best_dist = median_node_dist 67 # Calculate the difference for node selection given the current axis 68 axis = node[1] 69 diff = point[axis] - median_node[axis] 70 # Choose side to search 71 close, away = (node[2], node[3]) if diff < 0 else (node[3], node[2]) 72 # Search the close side first 73 best, best_dist = __closest_point_3d__(close, point, best, best_dist) 74 # Check the other side if needed 75 if diff**2 < best_dist: 76 best, best_dist = __closest_point_3d__(away, point, best, best_dist) 77 return best, best_dist 78 79 80# Special Serializer to convert lat,lon,index to x,y,z,index 81def __lat_lon_idx_to_xyz_idx__( 82 lat: int | float, lon: int | float, idx: int = 0 83): 84 """ 85 Function: 86 87 - Convert latitude and longitude to Cartesian coordinates (x, y, z) and include an index. 88 89 Required Arguments: 90 91 - `lat` 92 - Type: int or float 93 - What: The latitude in degrees 94 - `lon` 95 - Type: int or float 96 - What: The longitude in degrees 97 98 Optional Arguments: 99 100 - `idx` 101 - Type: int 102 - What: An index to include with the coordinates (default is 0) 103 """ 104 lat_rad = lat * pi / 180 105 lon_rad = lon * pi / 180 106 cos_lat = cos(lat_rad) 107 x = cos_lat * cos(lon_rad) 108 y = cos_lat * sin(lon_rad) 109 z = sin(lat_rad) 110 return (x, y, z, idx) 111 112 113class GeoKDTree: 114 def __init__(self, points: list[tuple]): 115 """ 116 Function: 117 118 - Build a GeoKDTree from a list of latitude and longitude points or an existing KDTree. 119 120 Required Arguments: 121 122 - `points` 123 - Type: list of tuples 124 - What: A list of latitude and longitude points to build the GeoKDTree from 125 - The points should be in the format [(lat1, lon1), (lat2, lon2), ...]. 126 127 """ 128 # Store the original points 129 self.points = points 130 # Store the KDTree built from the converted points 131 self.tree = kdtree( 132 [ 133 __lat_lon_idx_to_xyz_idx__(point[0], point[1], idx) 134 for idx, point in enumerate(points) 135 ], 136 depth=0, 137 axis_count=3, 138 ) 139 140 def closest_idx(self, point: tuple): 141 """ 142 Function: 143 144 - Find the index of the closest point in the GeoKDTree to a given latitude and longitude point. 145 146 Required Arguments: 147 148 - `point` 149 - Type: tuple 150 - What: The latitude and longitude point to find the closest point to 151 152 Returns: 153 154 - The index of the closest point found in the GeoKDTree to the given latitude and longitude point. 155 """ 156 best, best_dist = __closest_point_3d__( 157 self.tree, 158 __lat_lon_idx_to_xyz_idx__(point[0], point[1]), 159 ) 160 return best[3] # Return the index of the closest point 161 162 def closest_point(self, point: tuple): 163 """ 164 Function: 165 166 - Find the closest latitude and longitude point in the GeoKDTree to a given latitude and longitude point. 167 168 Required Arguments: 169 170 - `point` 171 - Type: tuple 172 - What: The latitude and longitude point to find the closest point to 173 174 Returns: 175 176 - The closest latitude and longitude point found in the GeoKDTree to the given latitude and longitude point. 177 """ 178 return self.points[self.closest_idx(point)]
class
GeoKDTree:
114class GeoKDTree: 115 def __init__(self, points: list[tuple]): 116 """ 117 Function: 118 119 - Build a GeoKDTree from a list of latitude and longitude points or an existing KDTree. 120 121 Required Arguments: 122 123 - `points` 124 - Type: list of tuples 125 - What: A list of latitude and longitude points to build the GeoKDTree from 126 - The points should be in the format [(lat1, lon1), (lat2, lon2), ...]. 127 128 """ 129 # Store the original points 130 self.points = points 131 # Store the KDTree built from the converted points 132 self.tree = kdtree( 133 [ 134 __lat_lon_idx_to_xyz_idx__(point[0], point[1], idx) 135 for idx, point in enumerate(points) 136 ], 137 depth=0, 138 axis_count=3, 139 ) 140 141 def closest_idx(self, point: tuple): 142 """ 143 Function: 144 145 - Find the index of the closest point in the GeoKDTree to a given latitude and longitude point. 146 147 Required Arguments: 148 149 - `point` 150 - Type: tuple 151 - What: The latitude and longitude point to find the closest point to 152 153 Returns: 154 155 - The index of the closest point found in the GeoKDTree to the given latitude and longitude point. 156 """ 157 best, best_dist = __closest_point_3d__( 158 self.tree, 159 __lat_lon_idx_to_xyz_idx__(point[0], point[1]), 160 ) 161 return best[3] # Return the index of the closest point 162 163 def closest_point(self, point: tuple): 164 """ 165 Function: 166 167 - Find the closest latitude and longitude point in the GeoKDTree to a given latitude and longitude point. 168 169 Required Arguments: 170 171 - `point` 172 - Type: tuple 173 - What: The latitude and longitude point to find the closest point to 174 175 Returns: 176 177 - The closest latitude and longitude point found in the GeoKDTree to the given latitude and longitude point. 178 """ 179 return self.points[self.closest_idx(point)]
GeoKDTree(points: list[tuple])
115 def __init__(self, points: list[tuple]): 116 """ 117 Function: 118 119 - Build a GeoKDTree from a list of latitude and longitude points or an existing KDTree. 120 121 Required Arguments: 122 123 - `points` 124 - Type: list of tuples 125 - What: A list of latitude and longitude points to build the GeoKDTree from 126 - The points should be in the format [(lat1, lon1), (lat2, lon2), ...]. 127 128 """ 129 # Store the original points 130 self.points = points 131 # Store the KDTree built from the converted points 132 self.tree = kdtree( 133 [ 134 __lat_lon_idx_to_xyz_idx__(point[0], point[1], idx) 135 for idx, point in enumerate(points) 136 ], 137 depth=0, 138 axis_count=3, 139 )
Function:
- Build a GeoKDTree from a list of latitude and longitude points or an existing KDTree.
Required Arguments:
points- Type: list of tuples
- What: A list of latitude and longitude points to build the GeoKDTree from
- The points should be in the format [(lat1, lon1), (lat2, lon2), ...].
def
closest_idx(self, point: tuple):
141 def closest_idx(self, point: tuple): 142 """ 143 Function: 144 145 - Find the index of the closest point in the GeoKDTree to a given latitude and longitude point. 146 147 Required Arguments: 148 149 - `point` 150 - Type: tuple 151 - What: The latitude and longitude point to find the closest point to 152 153 Returns: 154 155 - The index of the closest point found in the GeoKDTree to the given latitude and longitude point. 156 """ 157 best, best_dist = __closest_point_3d__( 158 self.tree, 159 __lat_lon_idx_to_xyz_idx__(point[0], point[1]), 160 ) 161 return best[3] # Return the index of the closest point
Function:
- Find the index of the closest point in the GeoKDTree to a given latitude and longitude point.
Required Arguments:
point- Type: tuple
- What: The latitude and longitude point to find the closest point to
Returns:
- The index of the closest point found in the GeoKDTree to the given latitude and longitude point.
def
closest_point(self, point: tuple):
163 def closest_point(self, point: tuple): 164 """ 165 Function: 166 167 - Find the closest latitude and longitude point in the GeoKDTree to a given latitude and longitude point. 168 169 Required Arguments: 170 171 - `point` 172 - Type: tuple 173 - What: The latitude and longitude point to find the closest point to 174 175 Returns: 176 177 - The closest latitude and longitude point found in the GeoKDTree to the given latitude and longitude point. 178 """ 179 return self.points[self.closest_idx(point)]
Function:
- Find the closest latitude and longitude point in the GeoKDTree to a given latitude and longitude point.
Required Arguments:
point- Type: tuple
- What: The latitude and longitude point to find the closest point to
Returns:
- The closest latitude and longitude point found in the GeoKDTree to the given latitude and longitude point.