Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Joseph Siddons
GeoSpatialTools
Commits
3c6aed6a
Commit
3c6aed6a
authored
5 months ago
by
Joseph Siddons
Browse files
Options
Download
Plain Diff
Merge branch 'update_readme' into 'main'
docs: update README with examples See merge request
!6
parents
c2e58af0
be29d753
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
180 additions
and
2 deletions
+180
-2
README.md
README.md
+180
-2
No files found.
README.md
View file @
3c6aed6a
...
...
@@ -2,12 +2,190 @@
Python module containing useful functions and classes for Spatial Analysis.
This package supports Python 3.11 and beyond.
Tested on Python versions 3.11, 3.12, and 3.13. Not expected to work with Python 3.9 or below due
to usage of type annotations.
## Installation
As a dependency with
`pip`
```
bash
pip
install
git+git@git.noc.ac.uk:josidd/geospatialtools.git
pip
install
git+git@git.noc.ac.uk:nocsurfaceprocesses/geospatialtools.git
```
## Neighbours
### 1d neighbours
For example, finding the closest time value in a list of _sorted_ time values:
```
python
def
find_nearest
(
vals
:
list
[
Numeric
],
test
:
list
[
Numeric
])
->
list
[
int
]:
...
```
Example:
```
python
from
GeoSpatialTools
import
find_nearest
import
numpy
as
np
# Generate random neighbours and test points
potential_neighbours
=
list
(
np
.
random
.
randn
(
100
))
potential_neighbours
.
sort
()
test_values
=
list
(
np
.
random
.
randn
(
3
))
neighbour_i
=
find_nearest
(
potential_neighbours
,
test_values
)
```
Returns the index of the value in
`potential_neighbours`
that is closest to each value in
`test_values`
. This function makes use of
`bisect.bisect`
from the python standard library and
requires that the list
`potential_neighbours`
is sorted. No check on sorted-ness is performed, if
the list is unsorted then the incorrect answer will be returned.
This calculation is performed in
`O(log(n))`
time.
### 2d neighbours
An implementation of
`KDTree`
(specifically a
`2DTree`
) using Haversine distance as the query
distance and accounting for longitudinal wrapping at -180, 180.
Uses a
`Record`
class:
```
python
Record
(
lon
:
float
,
lat
:
float
,
datetime
:
datetime
.
datetime
|
None
,
uid
:
str
|
None
,
**
data
)
```
Fast look-up of nearest neighbours in 2 spatial dimensions (longitude and latitude).
```
python
KDTree
(
points
:
list
[
Record
],
max_depth
:
int
,
depth
:
int
=
0
# Internal parameter
)
```
```
python
from
GeoSpatialTools
import
KDTree
,
Record
from
random
import
choice
lon_range
=
list
(
range
(
-
180
,
180
))
lat_range
=
list
(
range
(
-
90
,
90
))
N_samples
=
1000
records
:
list
[
Record
]
=
[
Record
(
choice
(
lon_range
),
choice
(
lat_range
))
for
_
in
range
(
N_samples
)]
# Construct Tree
kt
=
KDTree
(
records
)
test_value
:
Record
=
Record
(
lon
=
47.6
,
lat
=-
31.1
)
neighbours
:
list
[
Record
]
=
[]
neighbours
,
dist
=
kt
.
query
(
test_value
)
```
### Points within distance (2d \& 3d)
Also included is an implementation of
`QuadTree`
and
`OctTree`
using Haversine distance for querying
with a test
`Record`
and distance.
```
python
QuadTree
(
boundary
:
Rectangle
,
capacity
:
int
,
max_depth
:
int
,
depth
:
int
=
0
# Internal parameter
)
Rectangle
(
lon
:
float
,
# Centre longitude
lat
:
float
,
# Centre latitude
lon_range
:
float
,
# Full width of rectangle (degrees)
lat_range
:
float
,
# Full height of rectangle (degrees)
)
```
```
python
from
GeoSpatialTools
import
QuadTree
,
Record
,
Rectangle
from
random
import
choice
lon_range
=
list
(
range
(
-
180
,
180
))
lat_range
=
list
(
range
(
-
90
,
90
))
N_samples
=
1000
# Construct Tree
boundary
=
Rectangle
(
0
,
0
,
360
,
180
)
# Full domain
qt
=
QuadTree
(
boundary
)
records
:
list
[
Record
]
=
[
Record
(
choice
(
lon_range
),
choice
(
lat_range
))
for
_
in
range
(
N_samples
)]
for
record
in
records
:
qt
.
insert
(
record
)
test_value
:
Record
=
Record
(
lon
=
47.6
,
lat
=-
31.1
)
dist
:
float
=
340
# km
neighbours
:
list
[
Record
]
=
qt
.
nearby_points
(
test_value
,
dist
)
```
#### OctTree - 3d QuadTree
Adds
`SpaceTimeRecord`
,
`SpaceTimeRectangle`
and
`OctTree`
classes.
```
python
SpaceTimeRecord
(
lon
:
float
,
lat
:
float
,
datetime
:
datetime
.
datetime
,
# datetime no longer optional
uid
:
str
|
None
,
**
data
)
SpaceTimeRectangle
(
lon
:
float
,
# Centre longitude
lat
:
float
,
# Centre latitude
datetime
:
datetime
,
# Central datetime
w
:
float
,
# Full width of rectangle (degrees)
h
:
float
,
# Full height of rectangle (degrees)
dt
:
timedelta
,
# Time extent of rectangle
)
```
Example
```
python
from
GeoSpatialTools.octtree
import
OctTree
,
SpaceTimeRecord
,
SpaceTimeRectangle
from
datetime
import
datetime
,
timedelta
from
random
import
choice
from
pandas
import
date_range
lon_range
=
list
(
range
(
-
180
,
180
))
lat_range
=
list
(
range
(
-
90
,
90
))
dates
=
date_range
(
start
=
datetime
(
2009
,
1
,
1
,
0
,
0
),
end
=
datetime
(
2009
,
2
,
1
,
0
,
0
),
interval
=
timedelta
(
hours
=
1
),
inclusive
=
"left"
,
)
N_samples
=
1000
# Construct Tree
boundary
=
SpaceTimeRectangle
(
0
,
0
,
datetime
(
2009
,
1
,
15
,
12
),
360
,
180
,
timedelta
(
days
=
31
))
# Full domain
ot
=
OctTree
(
boundary
)
records
:
list
[
SpaceTimeRecord
]
=
[
SpaceTimeRecord
(
choice
(
lon_range
),
choice
(
lat_range
),
choice
(
dates
))
for
_
in
range
(
N_samples
)]
for
record
in
records
:
ot
.
insert
(
record
)
test_value
:
SpaceTimeRecord
=
SpaceTimeRecord
(
lon
=
47.6
,
lat
=-
31.1
,
datetime
=
datetime
(
2009
,
1
,
23
,
17
,
41
))
dist
:
float
=
340
# km
t_dist
=
timedelta
(
hours
=
4
)
neighbours
:
list
[
Record
]
=
ot
.
nearby_points
(
test_value
,
dist
,
t_dist
)
```
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment