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
16bd1d75
Commit
16bd1d75
authored
5 months ago
by
Joseph Siddons
Browse files
Options
Download
Email Patches
Plain Diff
refactor(quadtree)!: Use bounding box definition for Rectangle class
parent
724926b6
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
81 additions
and
76 deletions
+81
-76
GeoSpatialTools/quadtree.py
GeoSpatialTools/quadtree.py
+51
-55
test/test_quadtree.py
test/test_quadtree.py
+30
-21
No files found.
GeoSpatialTools/quadtree.py
View file @
16bd1d75
...
...
@@ -90,59 +90,55 @@ class Rectangle:
Parameters
----------
lon
: float
Horizontal centre
of the
r
ectangle
la
t : float
Vertical centre
of the
r
ectangle
lon_range
: float
Width
of the
r
ectangle
lat_range
: float
Height
of the
r
ectangle
west
: float
Western boundary
of the
R
ectangle
eas
t : float
Eastern boundary
of the
R
ectangle
south
: float
Southern boundary
of the
R
ectangle
north
: float
Northern boundary
of the
R
ectangle
"""
lon
:
float
la
t
:
float
lon_range
:
float
lat_range
:
float
west
:
float
eas
t
:
float
south
:
float
north
:
float
def
__post_init__
(
self
):
if
self
.
lon
>
180
:
self
.
lon
-=
360
if
self
.
lat
>
90
or
self
.
lat
<
-
90
:
if
self
.
east
>
180
or
self
.
east
<
-
180
:
self
.
east
=
((
self
.
east
+
540
)
%
360
)
-
180
if
self
.
west
>
180
or
self
.
west
<
-
180
:
self
.
west
=
((
self
.
west
+
540
)
%
360
)
-
180
if
self
.
north
>
90
or
self
.
south
<
-
90
:
raise
LatitudeError
(
f
"Central latitude value out of range
{
self
.
lat
}
,
"
+
"should be between -90, 90 degrees
"
"Latitude bounds are out of bounds.
"
+
f
"
{
self
.
north
=
}
,
{
self
.
south
=
}
"
)
@
property
def
west
(
self
)
->
float
:
"""
Western boundary
of the Rectangle"""
return
(((
self
.
lon
-
self
.
lon_range
/
2
)
+
540
)
%
360
)
-
180
def
lat_range
(
self
)
->
float
:
"""
Latitude range
of the Rectangle"""
return
self
.
north
-
self
.
south
@
property
def
eas
t
(
self
)
->
float
:
"""
Eastern boundary
of the Rectangle"""
return
(((
self
.
lon
+
self
.
l
on
_range
/
2
)
+
540
)
%
360
)
-
180
def
la
t
(
self
)
->
float
:
"""
Centre latitude
of the Rectangle"""
return
self
.
south
+
self
.
l
at
_range
/
2
@
property
def
north
(
self
)
->
float
:
"""Northern boundary of the Rectangle"""
north
=
self
.
lat
+
self
.
lat_range
/
2
if
north
>
90
:
raise
LatitudeError
(
"Rectangle crosses north pole - Use two Rectangles"
)
return
north
def
lon_range
(
self
)
->
float
:
"""Longitude range of the Rectangle"""
if
self
.
east
<
self
.
west
:
return
self
.
east
-
self
.
west
+
360
return
self
.
east
-
self
.
west
@
property
def
south
(
self
)
->
float
:
"""Southern boundary of the Rectangle"""
south
=
self
.
lat
-
self
.
lat_range
/
2
if
south
<
-
90
:
raise
LatitudeError
(
"Rectangle crosses south pole - Use two Rectangles"
)
return
south
def
lon
(
self
)
->
float
:
"""Centre longitude of the Rectangle"""
lon
=
self
.
west
+
self
.
lon_range
/
2
return
((
lon
+
540
)
%
360
)
-
180
@
property
def
edge_dist
(
self
)
->
float
:
...
...
@@ -332,10 +328,10 @@ class QuadTree:
"""Divide the QuadTree"""
self
.
northwest
=
QuadTree
(
Rectangle
(
self
.
boundary
.
lon
-
self
.
boundary
.
lon_range
/
4
,
self
.
boundary
.
l
at
+
self
.
boundary
.
lat_range
/
4
,
self
.
boundary
.
l
on_range
/
2
,
self
.
boundary
.
lat_range
/
2
,
self
.
boundary
.
west
,
self
.
boundary
.
l
on
,
self
.
boundary
.
l
at
,
self
.
boundary
.
north
,
),
capacity
=
self
.
capacity
,
depth
=
self
.
depth
+
1
,
...
...
@@ -343,10 +339,10 @@ class QuadTree:
)
self
.
northeast
=
QuadTree
(
Rectangle
(
self
.
boundary
.
lon
+
self
.
boundary
.
lon_range
/
4
,
self
.
boundary
.
lat
+
self
.
boundary
.
lat_range
/
4
,
self
.
boundary
.
l
on_range
/
2
,
self
.
boundary
.
lat_range
/
2
,
self
.
boundary
.
lon
,
self
.
boundary
.
east
,
self
.
boundary
.
l
at
,
self
.
boundary
.
north
,
),
capacity
=
self
.
capacity
,
depth
=
self
.
depth
+
1
,
...
...
@@ -354,10 +350,10 @@ class QuadTree:
)
self
.
southwest
=
QuadTree
(
Rectangle
(
self
.
boundary
.
lon
-
self
.
boundary
.
lon_range
/
4
,
self
.
boundary
.
l
at
-
self
.
boundary
.
lat_range
/
4
,
self
.
boundary
.
lon_range
/
2
,
self
.
boundary
.
lat
_range
/
2
,
self
.
boundary
.
west
,
self
.
boundary
.
l
on
,
self
.
boundary
.
south
,
self
.
boundary
.
lat
,
),
capacity
=
self
.
capacity
,
depth
=
self
.
depth
+
1
,
...
...
@@ -365,10 +361,10 @@ class QuadTree:
)
self
.
southeast
=
QuadTree
(
Rectangle
(
self
.
boundary
.
lon
+
self
.
boundary
.
lon_range
/
4
,
self
.
boundary
.
lat
-
self
.
boundary
.
lat_range
/
4
,
self
.
boundary
.
lon_range
/
2
,
self
.
boundary
.
lat
_range
/
2
,
self
.
boundary
.
lon
,
self
.
boundary
.
east
,
self
.
boundary
.
south
,
self
.
boundary
.
lat
,
),
capacity
=
self
.
capacity
,
depth
=
self
.
depth
+
1
,
...
...
This diff is collapsed.
Click to expand it.
test/test_quadtree.py
View file @
16bd1d75
...
...
@@ -7,7 +7,7 @@ from GeoSpatialTools.quadtree import QuadTree, Record, Rectangle, Ellipse
class
TestRect
(
unittest
.
TestCase
):
def
test_contains
(
self
):
rect
=
Rectangle
(
1
0
,
5
,
2
0
,
10
)
rect
=
Rectangle
(
0
,
20
,
0
,
10
)
points
:
list
[
Record
]
=
[
Record
(
10
,
5
),
Record
(
20
,
10
),
...
...
@@ -20,20 +20,20 @@ class TestRect(unittest.TestCase):
assert
res
==
expected
def
test_intersection
(
self
):
rect
=
Rectangle
(
1
0
,
5
,
2
0
,
10
)
rect
=
Rectangle
(
0
,
20
,
0
,
10
)
test_rects
:
list
[
Rectangle
]
=
[
Rectangle
(
1
0
,
5
,
1
8
,
8
),
Rectangle
(
25
,
5
,
9
,
1
2
),
Rectangle
(
15
,
8
,
12
,
7
),
Rectangle
(
1
,
19
,
1
,
9
),
Rectangle
(
2
0.
5
,
29.
5
,
-
1
,
1
1
),
Rectangle
(
9
,
21
,
4.5
,
11.5
),
]
expected
=
[
True
,
False
,
True
]
res
=
list
(
map
(
rect
.
intersects
,
test_rects
))
assert
res
==
expected
def
test_wrap
(
self
):
rect
=
Rectangle
(
17
0
,
45
,
180
,
20
)
assert
rect
.
east
<
0
assert
rect
.
west
>
0
rect
=
Rectangle
(
8
0
,
-
100
,
35
,
55
)
assert
rect
.
lon
==
17
0
assert
rect
.
lat
==
45
test_points
:
list
[
Record
]
=
[
Record
(
-
140
,
40
),
Record
(
0
,
50
),
...
...
@@ -43,20 +43,19 @@ class TestRect(unittest.TestCase):
res
=
list
(
map
(
rect
.
contains
,
test_points
))
assert
res
==
expected
test_rect
=
Rectangle
(
-
100
,
40
,
80
,
40
)
assert
test_rect
.
east
<
rect
.
west
test_rect
=
Rectangle
(
-
140
,
-
60
,
20
,
60
)
assert
rect
.
intersects
(
test_rect
)
class
TestQuadTree
(
unittest
.
TestCase
):
def
test_divides
(
self
):
boundary
=
Rectangle
(
1
0
,
4
,
2
0
,
8
)
boundary
=
Rectangle
(
0
,
20
,
0
,
8
)
qtree
=
QuadTree
(
boundary
)
expected
:
list
[
Rectangle
]
=
[
Rectangle
(
5
,
6
,
10
,
4
),
Rectangle
(
1
5
,
6
,
1
0
,
4
),
Rectangle
(
5
,
2
,
1
0
,
4
),
Rectangle
(
1
5
,
2
,
1
0
,
4
),
Rectangle
(
0
,
10
,
4
,
8
),
Rectangle
(
1
0
,
2
0
,
4
,
8
),
Rectangle
(
0
,
10
,
0
,
4
),
Rectangle
(
1
0
,
2
0
,
0
,
4
),
]
qtree
.
divide
()
res
=
[
...
...
@@ -68,7 +67,7 @@ class TestQuadTree(unittest.TestCase):
assert
res
==
expected
def
test_insert
(
self
):
boundary
=
Rectangle
(
1
0
,
4
,
2
0
,
8
)
boundary
=
Rectangle
(
0
,
20
,
0
,
8
)
qtree
=
QuadTree
(
boundary
,
capacity
=
3
)
points
:
list
[
Record
]
=
[
Record
(
10
,
5
),
...
...
@@ -97,7 +96,7 @@ class TestQuadTree(unittest.TestCase):
assert
res
==
expected
def
test_query
(
self
):
boundary
=
Rectangle
(
1
0
,
4
,
2
0
,
8
)
boundary
=
Rectangle
(
0
,
20
,
0
,
8
)
qtree
=
QuadTree
(
boundary
,
capacity
=
3
)
points
:
list
[
Record
]
=
[
Record
(
10
,
5
),
...
...
@@ -106,7 +105,7 @@ class TestQuadTree(unittest.TestCase):
Record
(
-
2
,
-
9.2
),
Record
(
12.8
,
2.1
),
]
test_rect
=
Rectangle
(
12
.5
,
2.5
,
1
,
1
)
test_rect
=
Rectangle
(
12
,
13
,
2
,
3
)
expected
=
[
Record
(
12.8
,
2.1
)]
for
point
in
points
:
...
...
@@ -118,10 +117,20 @@ class TestQuadTree(unittest.TestCase):
def
test_wrap_query
(
self
):
N
=
100
qt_boundary
=
Rectangle
(
0
,
0
,
360
,
180
)
qt_boundary
=
Rectangle
(
-
180
,
180
,
-
90
,
90
)
assert
qt_boundary
.
lon
==
0
assert
qt_boundary
.
lon_range
==
360
assert
qt_boundary
.
lat
==
0
assert
qt_boundary
.
lat_range
==
180
qt
=
QuadTree
(
qt_boundary
,
capacity
=
3
)
quert_rect
=
Rectangle
(
170
,
45
,
60
,
10
)
quert_rect
=
Rectangle
(
140
,
-
160
,
40
,
50
)
assert
quert_rect
.
lon
==
170
assert
quert_rect
.
lon_range
==
60
assert
quert_rect
.
lat
==
45
assert
quert_rect
.
lat_range
==
10
points_want
:
list
[
Record
]
=
[
Record
(
175
,
43
),
Record
(
-
172
,
49
),
...
...
@@ -163,7 +172,7 @@ class TestQuadTree(unittest.TestCase):
assert
not
ellipse
.
contains
(
Record
(
12.5
,
3.01
))
assert
not
ellipse
.
contains
(
Record
(
12.5
,
1.99
))
boundary
=
Rectangle
(
1
0
,
4
,
2
0
,
8
)
boundary
=
Rectangle
(
0
,
20
,
0
,
8
)
qtree
=
QuadTree
(
boundary
,
capacity
=
3
)
points
:
list
[
Record
]
=
[
Record
(
10
,
5
),
...
...
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