geokdtree 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geokdtree-1.0.0/PKG-INFO +67 -0
- geokdtree-1.0.0/README.md +52 -0
- geokdtree-1.0.0/geokdtree/__init__.py +56 -0
- geokdtree-1.0.0/geokdtree/bin/__init__.py +0 -0
- geokdtree-1.0.0/geokdtree/core.py +345 -0
- geokdtree-1.0.0/geokdtree.egg-info/PKG-INFO +67 -0
- geokdtree-1.0.0/geokdtree.egg-info/SOURCES.txt +10 -0
- geokdtree-1.0.0/geokdtree.egg-info/dependency_links.txt +1 -0
- geokdtree-1.0.0/geokdtree.egg-info/top_level.txt +1 -0
- geokdtree-1.0.0/pyproject.toml +33 -0
- geokdtree-1.0.0/setup.cfg +12 -0
geokdtree-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: geokdtree
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Given a coordinate point, find a very close point given a set of coordinate points.
|
|
5
|
+
Author-email: Connor Makowski <conmak@mit.edu>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/connor-makowski/geokdtree
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/connor-makowski/geokdtree/issues
|
|
9
|
+
Project-URL: Documentation, https://connor-makowski.github.io/geokdtree/geokdtree.html
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: C++
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# GeoKDTree
|
|
17
|
+
[](https://badge.fury.io/py/geokdtree)
|
|
18
|
+
[](https://opensource.org/licenses/MIT)
|
|
19
|
+
[](https://pypi.org/project/geokdtree/)
|
|
20
|
+
<!-- [](https://pypi.org/project/geokdtree/) -->
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### A Geo KD Tree package for Python
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
## Quick Start:
|
|
29
|
+
```py
|
|
30
|
+
from geokdtree import GeoKDTree
|
|
31
|
+
|
|
32
|
+
example_points = [
|
|
33
|
+
(34.0522, -118.2437), # Los Angeles
|
|
34
|
+
(40.7128, -74.0060), # New York
|
|
35
|
+
(37.7749, -122.4194), # San Francisco
|
|
36
|
+
(51.5074, -0.1278), # London
|
|
37
|
+
(48.8566, 2.3522), # Paris
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
geo_kd_tree = GeoKDTree(points = example_points)
|
|
41
|
+
test_point = (47.6062, -122.3321) # Seattle
|
|
42
|
+
|
|
43
|
+
closest_idx = geo_kd_tree.closest_idx(test_point) # Expect San Francisco to be closest
|
|
44
|
+
print(f"Closest point to {test_point} is {example_points[closest_idx] }")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Documentation
|
|
48
|
+
|
|
49
|
+
- Docs: https://connor-makowski.github.io/geokdtree/geokdtree.html
|
|
50
|
+
- Git Repo: https://github.com/connor-makowski/geokdtree
|
|
51
|
+
|
|
52
|
+
# Development
|
|
53
|
+
## Running Tests, Prettifying Code, and Updating Docs
|
|
54
|
+
|
|
55
|
+
Make sure Docker is installed and running on a Unix system (Linux, MacOS, WSL2).
|
|
56
|
+
|
|
57
|
+
- Create a docker container and drop into a shell
|
|
58
|
+
- `./run.sh`
|
|
59
|
+
- Run all tests (see ./utils/test.sh)
|
|
60
|
+
- `./run.sh test`
|
|
61
|
+
- Prettify the code (see ./utils/prettify.sh)
|
|
62
|
+
- `./run.sh prettify`
|
|
63
|
+
- Update the docs (see ./utils/docs.sh)
|
|
64
|
+
- `./run.sh docs`
|
|
65
|
+
|
|
66
|
+
- Note: You can and should modify the `Dockerfile` to test different python versions.
|
|
67
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# GeoKDTree
|
|
2
|
+
[](https://badge.fury.io/py/geokdtree)
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://pypi.org/project/geokdtree/)
|
|
5
|
+
<!-- [](https://pypi.org/project/geokdtree/) -->
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### A Geo KD Tree package for Python
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
## Quick Start:
|
|
14
|
+
```py
|
|
15
|
+
from geokdtree import GeoKDTree
|
|
16
|
+
|
|
17
|
+
example_points = [
|
|
18
|
+
(34.0522, -118.2437), # Los Angeles
|
|
19
|
+
(40.7128, -74.0060), # New York
|
|
20
|
+
(37.7749, -122.4194), # San Francisco
|
|
21
|
+
(51.5074, -0.1278), # London
|
|
22
|
+
(48.8566, 2.3522), # Paris
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
geo_kd_tree = GeoKDTree(points = example_points)
|
|
26
|
+
test_point = (47.6062, -122.3321) # Seattle
|
|
27
|
+
|
|
28
|
+
closest_idx = geo_kd_tree.closest_idx(test_point) # Expect San Francisco to be closest
|
|
29
|
+
print(f"Closest point to {test_point} is {example_points[closest_idx] }")
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Documentation
|
|
33
|
+
|
|
34
|
+
- Docs: https://connor-makowski.github.io/geokdtree/geokdtree.html
|
|
35
|
+
- Git Repo: https://github.com/connor-makowski/geokdtree
|
|
36
|
+
|
|
37
|
+
# Development
|
|
38
|
+
## Running Tests, Prettifying Code, and Updating Docs
|
|
39
|
+
|
|
40
|
+
Make sure Docker is installed and running on a Unix system (Linux, MacOS, WSL2).
|
|
41
|
+
|
|
42
|
+
- Create a docker container and drop into a shell
|
|
43
|
+
- `./run.sh`
|
|
44
|
+
- Run all tests (see ./utils/test.sh)
|
|
45
|
+
- `./run.sh test`
|
|
46
|
+
- Prettify the code (see ./utils/prettify.sh)
|
|
47
|
+
- `./run.sh prettify`
|
|
48
|
+
- Update the docs (see ./utils/docs.sh)
|
|
49
|
+
- `./run.sh docs`
|
|
50
|
+
|
|
51
|
+
- Note: You can and should modify the `Dockerfile` to test different python versions.
|
|
52
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
# GeoKDTree
|
|
3
|
+
[](https://badge.fury.io/py/geokdtree)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://pypi.org/project/geokdtree/)
|
|
6
|
+
<!-- [](https://pypi.org/project/geokdtree/) -->
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### A Geo KD Tree package for Python
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
## Quick Start:
|
|
15
|
+
```py
|
|
16
|
+
from geokdtree import GeoKDTree
|
|
17
|
+
|
|
18
|
+
example_points = [
|
|
19
|
+
(34.0522, -118.2437), # Los Angeles
|
|
20
|
+
(40.7128, -74.0060), # New York
|
|
21
|
+
(37.7749, -122.4194), # San Francisco
|
|
22
|
+
(51.5074, -0.1278), # London
|
|
23
|
+
(48.8566, 2.3522), # Paris
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
geo_kd_tree = GeoKDTree(points = example_points)
|
|
27
|
+
test_point = (47.6062, -122.3321) # Seattle
|
|
28
|
+
|
|
29
|
+
closest_idx = geo_kd_tree.closest_idx(test_point) # Expect San Francisco to be closest
|
|
30
|
+
print(f"Closest point to {test_point} is {example_points[closest_idx] }")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Documentation
|
|
34
|
+
|
|
35
|
+
- Docs: https://connor-makowski.github.io/geokdtree/geokdtree.html
|
|
36
|
+
- Git Repo: https://github.com/connor-makowski/geokdtree
|
|
37
|
+
|
|
38
|
+
# Development
|
|
39
|
+
## Running Tests, Prettifying Code, and Updating Docs
|
|
40
|
+
|
|
41
|
+
Make sure Docker is installed and running on a Unix system (Linux, MacOS, WSL2).
|
|
42
|
+
|
|
43
|
+
- Create a docker container and drop into a shell
|
|
44
|
+
- `./run.sh`
|
|
45
|
+
- Run all tests (see ./utils/test.sh)
|
|
46
|
+
- `./run.sh test`
|
|
47
|
+
- Prettify the code (see ./utils/prettify.sh)
|
|
48
|
+
- `./run.sh prettify`
|
|
49
|
+
- Update the docs (see ./utils/docs.sh)
|
|
50
|
+
- `./run.sh docs`
|
|
51
|
+
|
|
52
|
+
- Note: You can and should modify the `Dockerfile` to test different python versions.
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
from .core import KDTree, GeoKDTree
|
|
File without changes
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
from math import pi, cos, sin
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def kdtree(points, depth=0, axis_count=2):
|
|
5
|
+
"""
|
|
6
|
+
Function:
|
|
7
|
+
|
|
8
|
+
- Build a KDTree from a list of points.
|
|
9
|
+
|
|
10
|
+
Required Arguments:
|
|
11
|
+
|
|
12
|
+
- `points`
|
|
13
|
+
- Type: list of tuples
|
|
14
|
+
- What: A list of points to build the KDTree from
|
|
15
|
+
|
|
16
|
+
Optional Arguments:
|
|
17
|
+
|
|
18
|
+
- `depth`
|
|
19
|
+
- Type: int
|
|
20
|
+
- What: The current depth in the tree (used for axis selection)
|
|
21
|
+
- `axis_count`
|
|
22
|
+
- Type: int
|
|
23
|
+
- What: The number of dimensions in the points (default is 2 for 2D points)
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
|
|
27
|
+
- The constructed KDTree as a tuple in the format (point, axis, left, right).
|
|
28
|
+
- Where left and right are subtrees.
|
|
29
|
+
"""
|
|
30
|
+
if not points:
|
|
31
|
+
return 0
|
|
32
|
+
axis = depth % axis_count
|
|
33
|
+
points.sort(key=lambda p: p[axis])
|
|
34
|
+
median = len(points) // 2
|
|
35
|
+
return (
|
|
36
|
+
points[median],
|
|
37
|
+
axis,
|
|
38
|
+
kdtree(points[:median], depth + 1),
|
|
39
|
+
kdtree(points[median + 1 :], depth + 1),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def squared_distance(p1, p2, axis_count=2):
|
|
44
|
+
"""
|
|
45
|
+
Function:
|
|
46
|
+
|
|
47
|
+
- Calculate the squared distance between two points.
|
|
48
|
+
|
|
49
|
+
Required Arguments:
|
|
50
|
+
|
|
51
|
+
- `p1`
|
|
52
|
+
- Type: tuple
|
|
53
|
+
- What: The first point
|
|
54
|
+
- `p2`
|
|
55
|
+
- Type: tuple
|
|
56
|
+
- What: The second point
|
|
57
|
+
|
|
58
|
+
Optional Arguments:
|
|
59
|
+
|
|
60
|
+
- `axis_count`
|
|
61
|
+
- Type: int
|
|
62
|
+
- What: The number of dimensions in the points
|
|
63
|
+
- Default: 2 (for 2D points)
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
|
|
67
|
+
- The squared distance between the two points.
|
|
68
|
+
"""
|
|
69
|
+
return sum([(p1[i] - p2[i]) ** 2 for i in range(axis_count)])
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def closest_point(
|
|
73
|
+
node, point, depth=0, best=None, axis_count=2, best_dist=float("inf")
|
|
74
|
+
):
|
|
75
|
+
"""
|
|
76
|
+
Function:
|
|
77
|
+
|
|
78
|
+
- Find the closest point in the KDTree to a given point.
|
|
79
|
+
|
|
80
|
+
Required Arguments:
|
|
81
|
+
|
|
82
|
+
- `node`
|
|
83
|
+
- Type: tuple
|
|
84
|
+
- What: The node of the KDTree
|
|
85
|
+
- `point`
|
|
86
|
+
- Type: tuple
|
|
87
|
+
- What: The point to find the closest point to
|
|
88
|
+
|
|
89
|
+
Optional Arguments:
|
|
90
|
+
|
|
91
|
+
- `depth`
|
|
92
|
+
- Type: int
|
|
93
|
+
- What: The current depth in the tree (used for axis selection)
|
|
94
|
+
- `best`
|
|
95
|
+
- Type: tuple or None
|
|
96
|
+
- What: The best point found so far (default is None)
|
|
97
|
+
- `axis_count`
|
|
98
|
+
- Type: int
|
|
99
|
+
- What: The number of dimensions in the points (default is 2 for 2D points)
|
|
100
|
+
- `best_dist`
|
|
101
|
+
- Type: float
|
|
102
|
+
- What: The best distance found so far (default is infinity)
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
|
|
106
|
+
- The closest point found in the KDTree to the given point.
|
|
107
|
+
"""
|
|
108
|
+
if node == 0:
|
|
109
|
+
return best, best_dist
|
|
110
|
+
# Get the median node and its distance
|
|
111
|
+
median_node = node[0]
|
|
112
|
+
median_node_dist = squared_distance(
|
|
113
|
+
point, median_node, axis_count=axis_count
|
|
114
|
+
)
|
|
115
|
+
# Update the best point and distance if necessary
|
|
116
|
+
if best is None or median_node_dist < best_dist:
|
|
117
|
+
best = median_node
|
|
118
|
+
best_dist = median_node_dist
|
|
119
|
+
# Calculate the difference for node selection given the current axis
|
|
120
|
+
axis = node[1]
|
|
121
|
+
diff = point[axis] - median_node[axis]
|
|
122
|
+
# Choose side to search
|
|
123
|
+
close, away = (node[2], node[3]) if diff < 0 else (node[3], node[2])
|
|
124
|
+
# Search the close side first
|
|
125
|
+
best, best_dist = closest_point(
|
|
126
|
+
close,
|
|
127
|
+
point,
|
|
128
|
+
depth + 1,
|
|
129
|
+
best,
|
|
130
|
+
axis_count=axis_count,
|
|
131
|
+
best_dist=best_dist,
|
|
132
|
+
)
|
|
133
|
+
# Check the other side if needed
|
|
134
|
+
if diff**2 < best_dist:
|
|
135
|
+
best, best_dist = closest_point(
|
|
136
|
+
away,
|
|
137
|
+
point,
|
|
138
|
+
depth + 1,
|
|
139
|
+
best,
|
|
140
|
+
axis_count=axis_count,
|
|
141
|
+
best_dist=best_dist,
|
|
142
|
+
)
|
|
143
|
+
return best, best_dist
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def squared_distance_3d(p1, p2):
|
|
147
|
+
"""
|
|
148
|
+
Function:
|
|
149
|
+
|
|
150
|
+
- Calculate the squared distance between two 3D points.
|
|
151
|
+
|
|
152
|
+
Required Arguments:
|
|
153
|
+
|
|
154
|
+
- `p1`
|
|
155
|
+
- Type: tuple
|
|
156
|
+
- What: The first point in 3D space
|
|
157
|
+
- `p2`
|
|
158
|
+
- Type: tuple
|
|
159
|
+
- What: The second point in 3D space
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
|
|
163
|
+
- The squared distance between the two 3D points.
|
|
164
|
+
"""
|
|
165
|
+
return sum(
|
|
166
|
+
[(p1[0] - p2[0]) ** 2, (p1[1] - p2[1]) ** 2, (p1[2] - p2[2]) ** 2]
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def closest_point_3d(node, point, depth=0, best=None, best_dist=float("inf")):
|
|
171
|
+
"""
|
|
172
|
+
Function:
|
|
173
|
+
|
|
174
|
+
- Find the closest point in the KDTree to a given point.
|
|
175
|
+
|
|
176
|
+
Required Arguments:
|
|
177
|
+
|
|
178
|
+
- `node`
|
|
179
|
+
- Type: tuple
|
|
180
|
+
- What: The node of the KDTree
|
|
181
|
+
- `point`
|
|
182
|
+
- Type: tuple
|
|
183
|
+
- What: The point to find the closest point to
|
|
184
|
+
|
|
185
|
+
Optional Arguments:
|
|
186
|
+
|
|
187
|
+
- `depth`
|
|
188
|
+
- Type: int
|
|
189
|
+
- What: The current depth in the tree (used for axis selection)
|
|
190
|
+
- `best`
|
|
191
|
+
- Type: tuple or None
|
|
192
|
+
- What: The best point found so far (default is None)
|
|
193
|
+
- `best_dist`
|
|
194
|
+
- Type: float
|
|
195
|
+
- What: The best distance found so far (default is infinity)
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
|
|
199
|
+
- The closest point found in the KDTree to the given point.
|
|
200
|
+
"""
|
|
201
|
+
if node == 0:
|
|
202
|
+
return best, best_dist
|
|
203
|
+
# Get the median node and its distance
|
|
204
|
+
median_node = node[0]
|
|
205
|
+
median_node_dist = squared_distance_3d(point, median_node)
|
|
206
|
+
# Update the best point and distance if necessary
|
|
207
|
+
if best is None or median_node_dist < best_dist:
|
|
208
|
+
best = median_node
|
|
209
|
+
best_dist = median_node_dist
|
|
210
|
+
# Calculate the difference for node selection given the current axis
|
|
211
|
+
axis = node[1]
|
|
212
|
+
diff = point[axis] - median_node[axis]
|
|
213
|
+
# Choose side to search
|
|
214
|
+
close, away = (node[2], node[3]) if diff < 0 else (node[3], node[2])
|
|
215
|
+
# Search the close side first
|
|
216
|
+
best, best_dist = closest_point_3d(close, point, depth + 1, best, best_dist)
|
|
217
|
+
# Check the other side if needed
|
|
218
|
+
if diff**2 < best_dist:
|
|
219
|
+
best, best_dist = closest_point_3d(
|
|
220
|
+
away, point, depth + 1, best, best_dist
|
|
221
|
+
)
|
|
222
|
+
return best, best_dist
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class KDTree:
|
|
226
|
+
def __init__(self, points):
|
|
227
|
+
"""
|
|
228
|
+
Function:
|
|
229
|
+
|
|
230
|
+
- Build a KDTree from a list of points.
|
|
231
|
+
|
|
232
|
+
Required Arguments:
|
|
233
|
+
|
|
234
|
+
- `points`
|
|
235
|
+
- Type: list of tuples
|
|
236
|
+
- What: A list of points to build the KDTree from
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
|
|
240
|
+
- A KDTree object that can be used to find the closest point to a given point.
|
|
241
|
+
"""
|
|
242
|
+
self.tree = kdtree(points, axis_count=len(points[0]))
|
|
243
|
+
|
|
244
|
+
def closest_point(self, point):
|
|
245
|
+
"""
|
|
246
|
+
Function:
|
|
247
|
+
|
|
248
|
+
- Find the closest point in the KDTree to a given point.
|
|
249
|
+
|
|
250
|
+
Required Arguments:
|
|
251
|
+
|
|
252
|
+
- `point`
|
|
253
|
+
- Type: tuple
|
|
254
|
+
- What: The point to find the closest point to
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
|
|
258
|
+
- The closest point found in the KDTree to the given point.
|
|
259
|
+
"""
|
|
260
|
+
return closest_point(self.tree, point)[
|
|
261
|
+
0
|
|
262
|
+
] # Return only the point, not the distance
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class GeoKDTree:
|
|
266
|
+
def __init__(self, points: list[tuple]):
|
|
267
|
+
"""
|
|
268
|
+
Function:
|
|
269
|
+
|
|
270
|
+
- Build a GeoKDTree from a list of latitude and longitude points or an existing KDTree.
|
|
271
|
+
|
|
272
|
+
Required Arguments:
|
|
273
|
+
|
|
274
|
+
- `points`
|
|
275
|
+
- Type: list of tuples
|
|
276
|
+
- What: A list of latitude and longitude points to build the GeoKDTree from
|
|
277
|
+
- The points should be in the format [(lat1, lon1), (lat2, lon2), ...].
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
|
|
281
|
+
- A GeoKDTree object that can be used to find the closest point to a given latitude and longitude.
|
|
282
|
+
- The points should be in the format [(lat1, lon1), (lat2, lon2), ...].
|
|
283
|
+
"""
|
|
284
|
+
self.tree = kdtree(
|
|
285
|
+
[
|
|
286
|
+
GeoKDTree.lat_lon_idx_to_xyz_idx(point[0], point[1], idx)
|
|
287
|
+
for idx, point in enumerate(points)
|
|
288
|
+
],
|
|
289
|
+
axis_count=3,
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
def closest_idx(self, point: tuple):
|
|
293
|
+
"""
|
|
294
|
+
Function:
|
|
295
|
+
|
|
296
|
+
- Find the index of the closest point in the GeoKDTree to a given latitude and longitude point.
|
|
297
|
+
|
|
298
|
+
Required Arguments:
|
|
299
|
+
|
|
300
|
+
- `point`
|
|
301
|
+
- Type: tuple
|
|
302
|
+
- What: The latitude and longitude point to find the closest point to
|
|
303
|
+
|
|
304
|
+
Returns:
|
|
305
|
+
|
|
306
|
+
- The index of the closest point found in the GeoKDTree to the given latitude and longitude point.
|
|
307
|
+
"""
|
|
308
|
+
return closest_point_3d(
|
|
309
|
+
self.tree,
|
|
310
|
+
GeoKDTree.lat_lon_idx_to_xyz_idx(point[0], point[1]),
|
|
311
|
+
)[0][
|
|
312
|
+
3
|
|
313
|
+
] # Return the point [0] and the index of the point [3]
|
|
314
|
+
|
|
315
|
+
@staticmethod
|
|
316
|
+
def lat_lon_idx_to_xyz_idx(
|
|
317
|
+
lat: int | float, lon: int | float, idx: int = 0
|
|
318
|
+
):
|
|
319
|
+
"""
|
|
320
|
+
Function:
|
|
321
|
+
|
|
322
|
+
- Convert latitude and longitude to Cartesian coordinates (x, y, z) and include an index.
|
|
323
|
+
|
|
324
|
+
Required Arguments:
|
|
325
|
+
|
|
326
|
+
- `lat`
|
|
327
|
+
- Type: int or float
|
|
328
|
+
- What: The latitude in degrees
|
|
329
|
+
- `lon`
|
|
330
|
+
- Type: int or float
|
|
331
|
+
- What: The longitude in degrees
|
|
332
|
+
|
|
333
|
+
Optional Arguments:
|
|
334
|
+
|
|
335
|
+
- `idx`
|
|
336
|
+
- Type: int
|
|
337
|
+
- What: An index to include with the coordinates (default is 0)
|
|
338
|
+
"""
|
|
339
|
+
lat_rad = lat * pi / 180
|
|
340
|
+
lon_rad = lon * pi / 180
|
|
341
|
+
cos_lat = cos(lat_rad)
|
|
342
|
+
x = cos_lat * cos(lon_rad)
|
|
343
|
+
y = cos_lat * sin(lon_rad)
|
|
344
|
+
z = sin(lat_rad)
|
|
345
|
+
return (x, y, z, idx)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: geokdtree
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Given a coordinate point, find a very close point given a set of coordinate points.
|
|
5
|
+
Author-email: Connor Makowski <conmak@mit.edu>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/connor-makowski/geokdtree
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/connor-makowski/geokdtree/issues
|
|
9
|
+
Project-URL: Documentation, https://connor-makowski.github.io/geokdtree/geokdtree.html
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: C++
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# GeoKDTree
|
|
17
|
+
[](https://badge.fury.io/py/geokdtree)
|
|
18
|
+
[](https://opensource.org/licenses/MIT)
|
|
19
|
+
[](https://pypi.org/project/geokdtree/)
|
|
20
|
+
<!-- [](https://pypi.org/project/geokdtree/) -->
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### A Geo KD Tree package for Python
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
## Quick Start:
|
|
29
|
+
```py
|
|
30
|
+
from geokdtree import GeoKDTree
|
|
31
|
+
|
|
32
|
+
example_points = [
|
|
33
|
+
(34.0522, -118.2437), # Los Angeles
|
|
34
|
+
(40.7128, -74.0060), # New York
|
|
35
|
+
(37.7749, -122.4194), # San Francisco
|
|
36
|
+
(51.5074, -0.1278), # London
|
|
37
|
+
(48.8566, 2.3522), # Paris
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
geo_kd_tree = GeoKDTree(points = example_points)
|
|
41
|
+
test_point = (47.6062, -122.3321) # Seattle
|
|
42
|
+
|
|
43
|
+
closest_idx = geo_kd_tree.closest_idx(test_point) # Expect San Francisco to be closest
|
|
44
|
+
print(f"Closest point to {test_point} is {example_points[closest_idx] }")
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Documentation
|
|
48
|
+
|
|
49
|
+
- Docs: https://connor-makowski.github.io/geokdtree/geokdtree.html
|
|
50
|
+
- Git Repo: https://github.com/connor-makowski/geokdtree
|
|
51
|
+
|
|
52
|
+
# Development
|
|
53
|
+
## Running Tests, Prettifying Code, and Updating Docs
|
|
54
|
+
|
|
55
|
+
Make sure Docker is installed and running on a Unix system (Linux, MacOS, WSL2).
|
|
56
|
+
|
|
57
|
+
- Create a docker container and drop into a shell
|
|
58
|
+
- `./run.sh`
|
|
59
|
+
- Run all tests (see ./utils/test.sh)
|
|
60
|
+
- `./run.sh test`
|
|
61
|
+
- Prettify the code (see ./utils/prettify.sh)
|
|
62
|
+
- `./run.sh prettify`
|
|
63
|
+
- Update the docs (see ./utils/docs.sh)
|
|
64
|
+
- `./run.sh docs`
|
|
65
|
+
|
|
66
|
+
- Note: You can and should modify the `Dockerfile` to test different python versions.
|
|
67
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
geokdtree
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[tool.black]
|
|
2
|
+
line-length = 80
|
|
3
|
+
target-version = ['py312']
|
|
4
|
+
exclude = '/.*(migrations|__pycache__).*/'
|
|
5
|
+
|
|
6
|
+
[tool.setuptools]
|
|
7
|
+
py-modules = ["geokdtree"]
|
|
8
|
+
|
|
9
|
+
[build-system]
|
|
10
|
+
requires = ["setuptools>=61.0"]
|
|
11
|
+
build-backend = "setuptools.build_meta"
|
|
12
|
+
|
|
13
|
+
[project]
|
|
14
|
+
name = "geokdtree"
|
|
15
|
+
version = "1.0.0"
|
|
16
|
+
description = "Given a coordinate point, find a very close point given a set of coordinate points."
|
|
17
|
+
authors = [
|
|
18
|
+
{name="Connor Makowski", email="conmak@mit.edu"}
|
|
19
|
+
]
|
|
20
|
+
readme = "README.md"
|
|
21
|
+
requires-python = ">=3.10"
|
|
22
|
+
license="MIT"
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: C++",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
]
|
|
28
|
+
dependencies = []
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
"Homepage" = "https://github.com/connor-makowski/geokdtree"
|
|
32
|
+
"Bug Tracker" = "https://github.com/connor-makowski/geokdtree/issues"
|
|
33
|
+
"Documentation" = "https://connor-makowski.github.io/geokdtree/geokdtree.html"
|