Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Daniel Scheffler
geoarray
Commits
e7b5c9ed
Commit
e7b5c9ed
authored
Nov 22, 2017
by
Daniel Scheffler
1
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'bugfix/fix_subset_zsclice'
parents
a32e379f
7c89ff4d
Pipeline
#1593
passed with stages
in 1 minute and 43 seconds
Changes
2
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
97 additions
and
26 deletions
+97
-26
geoarray/baseclasses.py
geoarray/baseclasses.py
+32
-7
tests/test_geoarray.py
tests/test_geoarray.py
+65
-19
No files found.
geoarray/baseclasses.py
View file @
e7b5c9ed
...
...
@@ -149,7 +149,7 @@ class GeoArray(object):
if
self
.
_bandnames
and
len
(
self
.
_bandnames
)
==
self
.
bands
:
return
self
.
_bandnames
else
:
self
.
_
bandnames
=
OrderedDict
((
'B%s'
%
band
,
i
)
for
i
,
band
in
enumerate
(
range
(
1
,
self
.
bands
+
1
)))
del
self
.
bandnames
# runs deleter which sets it to default values
return
self
.
_bandnames
@
bandnames
.
setter
...
...
@@ -164,11 +164,23 @@ class GeoArray(object):
assert
len
(
list
(
set
([
type
(
b
)
for
b
in
list_bandnames
])))
==
1
and
type
(
list_bandnames
[
0
]
==
'str'
),
\
"'bandnames must be a set of strings. Got other datetypes in there.'"
bN_dict
=
OrderedDict
((
band
,
i
)
for
i
,
band
in
enumerate
(
list_bandnames
))
assert
len
(
bN_dict
)
==
self
.
bands
,
'Bands must not have the same name. Received band list: %s'
%
list_bandnames
assert
len
(
bN_dict
)
==
self
.
bands
,
\
'Bands must not have the same name. Received band list: %s'
%
list_bandnames
self
.
_bandnames
=
bN_dict
# update bandnames in metadata
if
self
.
_metadata
is
not
None
:
self
.
metadata
.
loc
[
'band_name'
,
:]
=
list_bandnames
else
:
del
self
.
bandnames
@
bandnames
.
deleter
def
bandnames
(
self
):
self
.
_bandnames
=
OrderedDict
((
'B%s'
%
band
,
i
)
for
i
,
band
in
enumerate
(
range
(
1
,
self
.
bands
+
1
)))
if
self
.
_metadata
is
not
None
:
self
.
metadata
.
loc
[
'band_name'
,
:]
=
list
(
self
.
_bandnames
.
keys
())
@
property
def
is_inmem
(
self
):
"""Check if associated image array is completely loaded into memory."""
...
...
@@ -1397,7 +1409,7 @@ class GeoArray(object):
progress
=
progress
)
return
sub_arr
,
sub_gt
,
sub_prj
def
get_subset
(
self
,
xslice
=
None
,
yslice
=
None
,
zslice
=
None
,
return_GeoArray
=
True
):
def
get_subset
(
self
,
xslice
=
None
,
yslice
=
None
,
zslice
=
None
,
return_GeoArray
=
True
,
reset_bandnames
=
False
):
# type: (slice, slice, slice, bool) -> GeoArray
"""Returns a new instatnce of GeoArray representing a subset of the initial one wit respect to given array position.
...
...
@@ -1411,13 +1423,26 @@ class GeoArray(object):
sub_arr
=
self
[
yslice
if
yslice
else
slice
(
None
),
# row
xslice
if
xslice
else
slice
(
None
),
# col
zslice
if
zslice
else
slice
(
None
)]
# band
sub_ulXY
=
imXY2mapXY
((
xslice
.
start
,
yslice
.
start
),
self
.
gt
)
if
sub_arr
is
None
:
raise
ValueError
(
'Unable to return an array for the given slice parameters.'
)
sub_ulXY
=
imXY2mapXY
((
xslice
.
start
or
0
,
yslice
.
start
or
0
),
self
.
gt
)
sub_gt
=
(
sub_ulXY
[
0
],
self
.
gt
[
1
],
self
.
gt
[
2
],
sub_ulXY
[
1
],
self
.
gt
[
4
],
self
.
gt
[
5
])
# apply zslice to bandnames and metadata
bNs_out
=
list
(
np
.
array
(
list
(
self
.
bandnames
))[
zslice
])
meta_out
=
None
if
self
.
_metadata
is
None
else
self
.
meta
[
list
(
np
.
array
(
range
(
self
.
bands
))[
zslice
])]
# get output GeoArray and copy some properties from the input GeoArray
sub_gA
=
GeoArray
(
sub_arr
,
sub_gt
,
self
.
prj
,
bandnames
=
list
(
self
.
bandnames
.
keys
())
,
nodata
=
self
.
nodata
,
progress
=
self
.
progress
,
q
=
self
.
q
)
sub_gA
.
meta
=
self
.
meta
bandnames
=
bNs_out
,
nodata
=
self
.
nodata
,
progress
=
self
.
progress
,
q
=
self
.
q
)
sub_gA
.
meta
=
meta
_out
sub_gA
.
filePath
=
self
.
filePath
if
reset_bandnames
:
del
self
.
bandnames
# also updates the respective row in self.meta
return
sub_gA
if
return_GeoArray
else
(
sub_arr
,
sub_gt
,
self
.
prj
)
# import copy # TODO implement that in order to include all previously set attribute values
...
...
tests/test_geoarray.py
View file @
e7b5c9ed
...
...
@@ -35,6 +35,7 @@ import unittest
from
unittest
import
TestLoader
import
matplotlib
from
typing
import
Iterable
from
importlib
import
util
# Imports regarding the created python module.
from
py_tools_ds.geo.vector
import
geometry
...
...
@@ -183,7 +184,7 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
reason
=
"The variable committed to the 'GeoArray'-class is neither a path nor a numpy.ndarray."
"All tests of the Test Case 'Test_GeoarrayAppliedOnTiffPath' will be skipped!"
)
def
test_
B
andnames
(
self
):
def
test_
b
andnames
(
self
):
"""
Testing the function: bandnames.
Test, if the default (for k=0) and set (for k=1) band names respectively were correctly assigned.
...
...
@@ -191,7 +192,7 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
self
.
assertEqual
(
self
.
testtiff
.
bandnames
,
self
.
expected_bandnames
,
msg
=
"The bandnames of the Tiff-file are different than ['B1', 'B2'] (format: OrderedDict)"
)
def
test_
S
hape
OfTiffArray
(
self
):
def
test_
s
hape
(
self
):
"""
Testing the functions: shape - ndim - rows - columns - bands,
indirect testing of the function: set_gdalDataset_meta(!),
...
...
@@ -216,7 +217,7 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
self
.
skipTest
(
"The shape of the array behind the 'Geoarray'-object is not as expected! "
"The test 'test_ShapeOfTiffArray' will be skipped."
)
def
test_
D
type
OfTiffArray
(
self
):
def
test_
d
type
(
self
):
"""
Testing the function: dtype,
indirect testing of the function: set_gdalDataset_meta(!).
...
...
@@ -226,7 +227,7 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
self
.
assertEqual
(
self
.
testtiff
.
dtype
,
self
.
expected_dtype
,
msg
=
'The dtype of the corresponding array is not as expected!'
)
def
test_
G
eotransform
Tiff
(
self
):
def
test_
g
eotransform
(
self
):
"""
Testing the functions: geotransform - xgsd - ygsd - xygrid_specs,
indirect testing of the function: set_gdalDataset_meta(!),
...
...
@@ -254,7 +255,7 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
self
.
skipTest
(
"The geotransform-tuple of the array behind the 'GeoArray'-object is not as expected! "
"The test 'test_GeotransformTiff' will be skipped."
)
def
test_
P
rojection
Tiff
(
self
):
def
test_
p
rojection
(
self
):
"""
Testing the functions: projection - epsg,
indirect testing of the function: set_gdalDataset_meta(!),
...
...
@@ -283,7 +284,7 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
self
.
skipTest
(
"The projections of the 'GeoArray'-object is not as expected! "
"The test 'test_ProjectionTiff' will be skipped."
)
def
test_
NoDataValueOfTiff
(
self
):
def
test_
nodata
(
self
):
"""
Testing the function: nodata,
indirect testing of the functions: find_noDataVal(), set_gdalDataset_meta(!).
...
...
@@ -301,6 +302,30 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
msg
=
"The nodata-value of the tested Tiff-file (%s) is not as expected (%s)!"
%
(
self
.
testtiff
.
nodata
,
self
.
given_nodata
))
def
test___getitem__
(
self
):
def
validate
(
array
,
exp_shape
):
self
.
assertIsInstance
(
array
,
np
.
ndarray
)
self
.
assertEqual
(
array
.
shape
,
exp_shape
)
R
,
C
,
B
=
self
.
testtiff
.
shape
# (10, 11, 2)
# test full array
validate
(
self
.
testtiff
[:],
(
R
,
C
,
B
))
# test row/col subset
validate
(
self
.
testtiff
[
2
:
5
,
:
3
],
(
3
,
3
,
B
))
# third dimension is not given
validate
(
self
.
testtiff
[
2
:
5
,
:
3
,
:],
(
3
,
3
,
B
))
# test band subset
validate
(
self
.
testtiff
[:,
:,
0
:
1
],
(
R
,
C
,
1
))
# band slice # FIXME returns 3D array
validate
(
self
.
testtiff
[
1
],
(
R
,
C
))
# only band is given # FIXME returns 2D
validate
(
self
.
testtiff
[
'B1'
],
(
R
,
C
))
# only bandname is given
# test wrong inputs
self
.
assertRaises
(
ValueError
,
self
.
testtiff
.
__getitem__
,
'B01'
)
# TODO: add further tests
###################################
# Test case: Test_GeoarrayFunctions
...
...
@@ -357,14 +382,13 @@ class Test_GeoarrayFunctions(unittest.TestCase):
def
tearDownClass
(
cls
):
# Removing the "../tests/data/output"-directory with all files. If test case 2 is not executed, the files
# will be removed at the end of this script in the "if __name__ == '__main__'"-code segment.
data_dir
=
os
.
path
.
join
(
tests_path
,
"tests"
,
"data"
,
"output"
)
data_dir_list
=
os
.
listdir
(
data_dir
)
out_dir
=
os
.
path
.
join
(
tests_path
,
"tests"
,
"data"
,
"output"
)
for
file
s
in
data_dir_list
:
os
.
remove
(
path
.
join
(
data
_dir
,
file
s
))
os
.
rmdir
(
data
_dir
)
for
file
in
os
.
listdir
(
out_dir
)
:
os
.
remove
(
path
.
join
(
out
_dir
,
file
))
os
.
rmdir
(
out
_dir
)
def
test_
BoxIsInstanceOfBoxObj
(
self
):
def
test_
box
(
self
):
"""
Testing the function: box.
Test, if the output of the box-function is an instance boxObj (class, defined in geometry.py, py_tools_ds).
...
...
@@ -372,7 +396,7 @@ class Test_GeoarrayFunctions(unittest.TestCase):
self
.
assertIsInstance
(
self
.
testtiff
.
box
,
geometry
.
boxObj
)
def
test_
M
ask
N
odata
IsInstanceOfNoDataMask
(
self
):
def
test_
m
ask
_n
odata
(
self
):
# TODO: Consider the dependency of mask_nodata on the calc_mask_nodata-function.
"""
Testing the function: mask_nodata.
...
...
@@ -381,7 +405,7 @@ class Test_GeoarrayFunctions(unittest.TestCase):
self
.
assertIsInstance
(
self
.
testtiff
.
mask_nodata
,
masks
.
NoDataMask
)
def
test_
M
ask
B
addata
OffTiff
(
self
):
def
test_
m
ask
_b
addata
(
self
):
"""
Testing the function: mask_baddata.
Test,
...
...
@@ -399,7 +423,7 @@ class Test_GeoarrayFunctions(unittest.TestCase):
self
.
testtiff
.
mask_baddata
=
bdm
self
.
assertIsInstance
(
self
.
testtiff
.
mask_baddata
,
masks
.
BadDataMask
)
def
test_
F
ootprint
PolyIsInstanceOfShape
ly
(
self
):
def
test_
f
ootprint
_po
ly
(
self
):
# TODO: Test the validation of the footprint_poly-function.
# TODO: Consider the dependencies of the footprint_poly-function on mask_nodata, boxObj.
"""
...
...
@@ -409,7 +433,7 @@ class Test_GeoarrayFunctions(unittest.TestCase):
self
.
assertIsInstance
(
self
.
testtiff
.
footprint_poly
,
Polygon
)
def
test_
M
etadata
IsInstanceOfGeodataframe
(
self
):
def
test_
m
etadata
(
self
):
# TODO: Create a metadata-file for the tested TIFF-Image.
# TODO: Test, if the metadata-function gives an output
"""
...
...
@@ -426,7 +450,27 @@ class Test_GeoarrayFunctions(unittest.TestCase):
for
((
rS
,
rE
),
(
cS
,
cE
)),
tile
in
tiles
:
self
.
assertTrue
(
np
.
array_equal
(
tile
,
self
.
testtiff
[
rS
:
rE
+
1
,
cS
:
cE
+
1
]))
def
test_SaveTiffToDisk
(
self
):
def
test_get_subset
(
self
):
# test without reseting band names
sub_gA
=
self
.
testtiff
.
get_subset
(
xslice
=
slice
(
2
,
5
),
yslice
=
slice
(
None
,
3
),
zslice
=
slice
(
1
,
2
))
self
.
assertIsInstance
(
sub_gA
,
GeoArray
)
self
.
assertTrue
(
list
(
sub_gA
.
bandnames
),
list
(
self
.
testtiff
.
bandnames
)[
1
])
# test with reseting band names
sub_gA
=
self
.
testtiff
.
get_subset
(
xslice
=
slice
(
2
,
5
),
yslice
=
slice
(
None
,
3
),
zslice
=
slice
(
1
,
2
),
reset_bandnames
=
True
)
self
.
assertTrue
(
list
(
sub_gA
.
bandnames
),
[
'B1'
])
# test not to return GeoArray
out
=
self
.
testtiff
.
get_subset
(
xslice
=
slice
(
2
,
5
),
yslice
=
slice
(
None
,
3
),
zslice
=
slice
(
1
,
2
),
return_GeoArray
=
False
)
self
.
assertIsInstance
(
out
,
tuple
)
self
.
assertTrue
(
len
(
out
),
3
)
self
.
assertIsInstance
(
out
[
0
],
np
.
ndarray
)
self
.
assertIsInstance
(
out
[
1
],
tuple
)
self
.
assertIsInstance
(
out
[
2
],
str
)
def
test_save
(
self
):
"""
Testing the function: save,
test with 2 stages.
...
...
@@ -467,8 +511,10 @@ class Test_GeoarrayFunctions(unittest.TestCase):
# TODO: https://github.com/ketch/griddle/blob/master/tests/plot_tests.py
self
.
testtiff
.
show
()
# self.testtiff.show(interactive=True) # only works if test is started with ipython.
# self.testtiff.show_map()
# self.testtiff.show_map_utm() # Function still under construction.
if
util
.
find_spec
(
'mpl_toolkits.basemap'
):
self
.
testtiff
.
show_map
()
self
.
testtiff
.
show_map_utm
()
# Function still under construction.
self
.
testtiff
.
show_histogram
()
# ----> TODO: Write tests for the remaining functions!
...
...
Daniel Scheffler
@danschef
mentioned in issue
#13 (closed)
·
Nov 22, 2017
mentioned in issue
#13 (closed)
mentioned in issue #13
Toggle commit list
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