Commit 23c7618a authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

geo.vector.geometry:

- fixed some broken type hints

io.raster.GeoArray:
- GeoArray:
    - fixed some broken type hints
    - arr: added assertion
    - bandnames: now returns an OrderedDict instead of a Python dict
- added class 'MultiGeoArray' (still a draft -> not yet working)

- updated __version__
parent af3a9511
......@@ -15,7 +15,7 @@ __all__=[#'compatibility',
'similarity',
'GeoArray']
__version__ = '20170104_01'
__version__ = '20170116_01'
__author__='Daniel Scheffler'
# Validate GDAL version
......
......@@ -126,7 +126,7 @@ class boxObj(object):
return (ymax-ymin),(xmax-xmin)
def buffer_imXY(self, buffImX=0, buffImY=0):
# type: (float, float)
# type: (float, float) -> None
"""Buffer the box in X- and/or Y-direction.
:param buffImX: <float> buffer value in x-direction as IMAGE UNITS (pixels)
:param buffImY: <float> buffer value in y-direction as IMAGE UNITS (pixels)
......@@ -136,7 +136,7 @@ class boxObj(object):
self.imPoly = box(xmin, ymin, xmax, ymax)
def is_larger_DimXY(self,boundsIm2test):
# type: (tuple) -> bool,bool
# type: (tuple) -> (bool,bool)
"""Checks if the boxObj is larger than a given set of bounding image coordinates (in X- and/or Y-direction).
:param boundsIm2test: <tuple> (xmin,xmax,ymin,ymax) as image coordinates
"""
......@@ -164,7 +164,7 @@ class boxObj(object):
def get_winPoly(wp_imYX, ws, gt, match_grid=0):
# type: (tuple, tuple, list, bool) -> shapely.Polygon, tuple, tuple
# type: (tuple, tuple, list, bool) -> (Polygon, tuple, tuple)
"""Creates a shapely polygon from a given set of image cordinates, window size and geotransform.
:param wp_imYX:
:param ws: <tuple> X/Y window size
......
......@@ -7,6 +7,7 @@ import os
import warnings
from matplotlib import pyplot as plt
from six import PY3
from collections import OrderedDict
# custom
from shapely.geometry import Polygon, box
......@@ -49,7 +50,7 @@ def _alias_property(key):
class GeoArray(object):
def __init__(self, path_or_array, geotransform=None, projection=None, bandnames=None, nodata=None, progress=True,
q=False):
# type: (Any, tuple, str, list, float, bool, bool) -> GeoArray
# type: (any, tuple, str, list, float, bool, bool) -> None
"""This class creates a fast Python inteface to geodata - either on disk or in memory. It can be instanced with
a file path or with a numpy array and the corresponding geoinformation. Instances can always be indexed like
normal numpy arrays, no matter if GeoArray has been instanced from file or from an in-memory array. GeoArray
......@@ -133,6 +134,9 @@ class GeoArray(object):
@arr.setter
def arr(self, ndarray):
assert isinstance(ndarray, np.ndarray), "'arr' can only be set to a numpy array! Got %s." %type(ndarray)
assert ndarray.shape == self.shape, "'arr' can only be set to a numpy array with shape %s. Received %s. " \
"If you need to change the dimensions, create a new instance of %s." \
%(self.shape, ndarray.shape, self.__class__.__name__)
self._arr = ndarray
......@@ -141,19 +145,20 @@ class GeoArray(object):
if self._bandnames and len(self._bandnames)==self.bands:
return self._bandnames
else:
self._bandnames = {'B%s' % band: i for i, band in enumerate(range(1, self.bands + 1))}
self._bandnames = OrderedDict(('B%s' % band, i) for i, band in enumerate(range(1, self.bands + 1)))
#{'B%s' % band: i for i, band in enumerate(range(1, self.bands + 1))}
return self._bandnames
@bandnames.setter
def bandnames(self, list_bandnames):
# type: (list)
# type: (list) -> None
assert len(list_bandnames) == self.bands, \
'Number of given bandnames does not match number of bands in array.'
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 = {band: i for i, band in enumerate(list_bandnames)} # syntax supported since Python 2.7
assert len(bN_dict) == self.bands, 'Bands must not have the same name.'
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
self._bandnames = bN_dict
......@@ -743,7 +748,7 @@ class GeoArray(object):
def save(self, out_path, fmt='ENVI', creationOptions=None):
# type: (str, str, list)
# type: (str, str, list) -> None
"""Write the raster data to disk.
:param out_path: <str> output path
......@@ -791,7 +796,7 @@ class GeoArray(object):
def dump(self, out_path):
# type: (str)
# type: (str) -> None
"""Serialize the whole object instance to disk using dill."""
import dill
with open(out_path,'w') as outF:
......@@ -1297,6 +1302,37 @@ class CloudMask(GeoArray):
class MultiGeoArray(object):
def __init__(self, GeoArray_list):
"""
:param GeoArray_list: a list of GeoArray instances having a geographic overlap
"""
self._arrs = None
self.arrs = GeoArray_list
raise NotImplementedError('This class is not yet working.') # FIXME
@property
def arrs(self):
return self._arrs
@arrs.setter
def arrs(self, GeoArray_list):
for geoArr in GeoArray_list:
assert isinstance(geoArr, GeoArray), "'arrs' can only be set to a list of GeoArray instances."
self._arrs = GeoArray_list
def _clip_array_at_mapPos(arr, mapBounds, arr_gt, band2clip=None, fillVal=0):
"""
......@@ -1355,7 +1391,7 @@ def _clip_array_at_mapPos(arr, mapBounds, arr_gt, band2clip=None, fillVal=0):
# calculate image area to be read from input array
overlap_poly = get_overlap_polygon(box(*arrBounds), box(*mapBounds))['overlap poly']
assert overlap_poly, 'The input array and the requested geo area have no overlap.'
assert overlap_poly, 'The input array and the requested geo area have no spatial overlap.'
xmin_in, ymin_in, xmax_in, ymax_in = overlap_poly.bounds
cS_in, rS_in = [int(i) for i in mapXY2imXY((xmin_in, ymax_in), arr_gt)]
cE_in, rE_in = [int(i)-1 for i in mapXY2imXY((xmax_in, ymin_in), arr_gt)] # -1 because max values do not represent pixel origins
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment