示例#1
0
    def __init__(self,img,known_depths):
        self.img_original = img
        self.imrds = None
        try:
            self.imlevel = img.ndim
        except AttributeError:
            if type(img).__name__ == 'RasterDS':
                self.imlevel = 4
                self.imrds = img
            else:
                # next line should raise exception if `img` can't make RasterDS
                self.imrds = RasterDS(img)
                self.imlevel = 4
        self.known_original = known_depths
        if type(self.known_original).__name__=='RasterDS':
            self.kdrds = known_depths
        elif np.ma.isMaskedArray(self.known_original):
            self.kdrds = None
        else:
            self.kdrds = RasterDS(self.known_original)
        self.known_depth_arr = self.__known_depth_arr()
        self.imarr = self.__imarr()
        self.__mask_depths_with_no_image()
        self.nbands = self.imarr_flat.shape[-1]

        # Check that the numbers of pixels are compatible
        impix = self.imarr_flat.size / self.nbands
        dpix = self.known_depth_arr_flat.size
        errstr = "{} image pixels and {} depth pixels. Need the same number of pixels."
        assert impix == dpix, errstr.format(impix,dpix)
示例#2
0
    def __init__(self, img_rds, depth_rds, sand_shp, gdf_query=None,
                 depth_range=None, surface_refraction=False,
                 surface_reflectance=False):
        self.surf_reflectance = surface_reflectance
        self.surf_refraction = surface_refraction
        self.depth_range = depth_range
        if type(img_rds).__name__ == 'RasterDS':
            self.img_rds = img_rds
        else:
            self.img_rds = RasterDS(img_rds)

        if type(depth_rds).__name__ == 'RasterDS':
            self.depth_rds = depth_rds
        else:
            self.depth_rds = RasterDS(depth_rds)

        if type(sand_shp).__name__ == 'GeoDataFrame':
            self.gdf = sand_shp
        else:
            self.gdf = gpd.read_file(sand_shp)

        self.gdf_query = gdf_query
        # self.full_image_array = self.img_rds.band_array

        self._set_arrays()
示例#3
0
    def __init__(self, img_rds, depth_rds, sand_shp, gdf_query=None,
                 depth_range=None, surface_refraction=False,
                 surface_reflectance=False):
        self.surf_reflectance = surface_reflectance
        self.surf_refraction = surface_refraction
        self.depth_range = depth_range
        if type(img_rds).__name__ == 'RasterDS':
            self.img_rds = img_rds
        else:
            self.img_rds = RasterDS(img_rds)

        if type(depth_rds).__name__ == 'RasterDS':
            self.depth_rds = depth_rds
        else:
            self.depth_rds = RasterDS(depth_rds)

        if type(sand_shp).__name__ == 'GeoDataFrame':
            self.gdf = sand_shp
        else:
            self.gdf = gpd.read_file(sand_shp)

        self.gdf_query = gdf_query
        # self.full_image_array = self.img_rds.band_array

        self._set_arrays()
示例#4
0
    def __init__(self, rds, shp, gdf_query=None):
        if type(rds).__name__ == 'RasterDS':
            self.rds = rds
        else:
            self.rds = RasterDS(rds)

        if type(shp).__name__ == 'GeoDataFrame':
            self.gdf = shp
        else:
            self.gdf = gpd.read_file(shp)
示例#5
0
    def __init__(self, rds, shp, gdf_query=None):
        if type(rds).__name__ == 'RasterDS':
            self.rds = rds
        else:
            self.rds = RasterDS(rds)

        if type(shp).__name__ == 'GeoDataFrame':
            self.gdf = shp
        else:
            self.gdf = gpd.read_file(shp)
示例#6
0
    def __init__(self,
                 pred_rds,
                 true_rds,
                 pred_range=None,
                 true_range=None,
                 pred_name='Predicted',
                 true_name='True'):
        self.pred_range = pred_range
        self.true_range = true_range
        if type(pred_rds).__name__ == 'RasterDS':
            self.pred_rds = pred_rds
        else:
            self.pred_rds = RasterDS(pred_rds)

        if type(true_rds).__name__ == 'RasterDS':
            self.true_rds = true_rds
        else:
            self.true_rds = RasterDS(true_rds)
        self.pred_name = pred_name
        self.true_name = true_name
        self._set_arrays()
示例#7
0
class RasterShape(object):
    """
    Provide a object to make it more convenient to deal with a raster and a
    shapefile.

    Parameters
    ----------
    rds : RasterDS or string or QGIS raster layer
        If `rds` is a RasterDS, then yay. If not, try to make a RasterDS out of
        whatever `rds` is. RasterDS can take a filepath to a GDAL compatible
        raster (like a GeoTiff) or a QGIS raster layer.
    shp : GeoPandas.GeoDataFrame or string (filepath to a shapefile)
        If `shp` is a GeoDataFrame, that will be used. Otherwise `shp` will be
        assumed to be a filepath string and will be handed to
        GeoPandas.read_file().
    gdf_query : string or None
        A string for the pandas query method:
        http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.query.html
        Where a single geometry is used in a method: If `None` is passed, the
        first geometry in the GeoDataFrame will be used. If a query is passed,
        the first geometry in the query results will be used.
    """
    def __init__(self, rds, shp, gdf_query=None):
        if type(rds).__name__ == 'RasterDS':
            self.rds = rds
        else:
            self.rds = RasterDS(rds)

        if type(shp).__name__ == 'GeoDataFrame':
            self.gdf = shp
        else:
            self.gdf = gpd.read_file(shp)

    def geometry_subset(self, gdf_query=None, all_touched=False):
        if gdf_query == None:
            geom = self.gdf.ix[0].geometry
        else:
            geom = gdf.query(gdf_query).ix[0].geometry

        return self.rds.geometry_subset(geom, all_touched=all_touched)
示例#8
0
class RasterShape(object):
    """
    Provide a object to make it more convenient to deal with a raster and a
    shapefile.

    Parameters
    ----------
    rds : RasterDS or string or QGIS raster layer
        If `rds` is a RasterDS, then yay. If not, try to make a RasterDS out of
        whatever `rds` is. RasterDS can take a filepath to a GDAL compatible
        raster (like a GeoTiff) or a QGIS raster layer.
    shp : GeoPandas.GeoDataFrame or string (filepath to a shapefile)
        If `shp` is a GeoDataFrame, that will be used. Otherwise `shp` will be
        assumed to be a filepath string and will be handed to
        GeoPandas.read_file().
    gdf_query : string or None
        A string for the pandas query method:
        http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.query.html
        Where a single geometry is used in a method: If `None` is passed, the
        first geometry in the GeoDataFrame will be used. If a query is passed,
        the first geometry in the query results will be used.
    """
    def __init__(self, rds, shp, gdf_query=None):
        if type(rds).__name__ == 'RasterDS':
            self.rds = rds
        else:
            self.rds = RasterDS(rds)

        if type(shp).__name__ == 'GeoDataFrame':
            self.gdf = shp
        else:
            self.gdf = gpd.read_file(shp)

    def geometry_subset(self, gdf_query=None, all_touched=False):
        if gdf_query == None:
            geom = self.gdf.ix[0].geometry
        else:
            geom = gdf.query(gdf_query).ix[0].geometry

        return self.rds.geometry_subset(geom, all_touched=all_touched)
示例#9
0
class RasterShape(object):
    """
    Provide a object to make it more convenient to deal with a raster and a
    shapefile.

    Parameters
    ----------
    rds : RasterDS or string or QGIS raster layer
        If `rds` is a RasterDS, then yay. If not, try to make a RasterDS out of
        whatever `rds` is. RasterDS can take a filepath to a GDAL compatible
        raster (like a GeoTiff) or a QGIS raster layer.
    shp : GeoPandas.GeoDataFrame or string (filepath to a shapefile)
        If `shp` is a GeoDataFrame, that will be used. Otherwise `shp` will be
        assumed to be a filepath string and will be handed to
        GeoPandas.read_file().
    gdf_query : string or None
        A string for the pandas query method:
        http://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.DataFrame.query.html
        Where a single geometry is used in a method: If `None` is passed, the
        first geometry in the GeoDataFrame will be used. If a query is passed,
        the first geometry in the query results will be used.
    """
    def __init__(self, rds, shp, gdf_query=None):
        if type(rds).__name__ == 'RasterDS':
            self.rds = rds
        else:
            self.rds = RasterDS(rds)

        if type(shp).__name__ == 'GeoDataFrame':
            self.gdf = shp
        else:
            self.gdf = gpd.read_file(shp)

    def geometry_subset(self, gdf_query=None, all_touched=False):
        if gdf_query == None:
            geom = self.gdf.ix[0].geometry
        else:
            geom = gdf.query(gdf_query).ix[0].geometry

        return self.rds.geometry_subset(geom, all_touched=all_touched)

    def rmse(self, rast_col='Raster Value', point_col='Point Value'):
        df = self.gdf
        df[rast_col] = self.point_sample()
        errs = (df[point_col] - df[rast_col])
        return np.sqrt(np.square(errs).sum() / float(errs.count()))

    def rsquared(self, rast_col='Raster Value', point_col='Point Value'):
        df = self.gdf
        df[rast_col] = self.point_sample()
        return df[[rast_col,point_col]].corr().ix[0,1]**2

    def point_sample(self):
        """
        If `self.shp` is a point shapefile, sample `self.rds` at each point and
        return a `geopandas.GeoSeries` of the results.
        """
        gser = self.gdf.geometry.apply(lambda p: self.rds.value_at_point(p))
        gser[gser==self.rds.band_array.fill_value] = np.nan
        return gser

    def seaborn_jointplot(self, rast_col='Raster Value', point_col='Point Value'):
        import seaborn as sns
        df = self.gdf
        df[rast_col] = self.point_sample()
        def r2(x,y):
            return stats.pearsonr(x,y)[0] ** 2
        fig = sns.jointplot(rast_col, point_col, data=df, kind='reg',
                            stat_func=r2)
        return fig

    def hexbin_plot(self, rast_col='Raster Value', point_col='Point Value'):
        df = self.gdf
        df[rast_col] = self.point_sample()
        fig,ax = plt.subplots(1,1)
        mapa = ax.hexbin(df[point_col],df[rast_col],mincnt=1,bins=None,gridsize=500,\
                             cmap=plt.cm.jet)
        ax.set_xlabel(point_col)
        ax.set_ylabel(rast_col)
        ax.set_aspect('equal')
        dmin = df[point_col].min()
        dmax = df[point_col].max()
        ax.plot([dmin,dmax],[dmin,dmax],c='black',alpha=0.6)
        ax.set_title(r"RMSE: {:.2f}, $R^2$: {:.2f}".format(self.rmse(rast_col,point_col),\
                                                        self.rsquared(rast_col,point_col)))
        return fig
示例#10
0
class ParameterEstimator(RasterShape):
    """
    An object to simplify the process of estimating some apparent optical
    properties (AOPs). Most importantly, the diffuse attenuation coefficient (K).
    I need to add more documentation.
    """
    def __init__(self, img_rds, depth_rds, sand_shp, gdf_query=None,
                 depth_range=None, surface_refraction=False,
                 surface_reflectance=False):
        self.surf_reflectance = surface_reflectance
        self.surf_refraction = surface_refraction
        self.depth_range = depth_range
        if type(img_rds).__name__ == 'RasterDS':
            self.img_rds = img_rds
        else:
            self.img_rds = RasterDS(img_rds)

        if type(depth_rds).__name__ == 'RasterDS':
            self.depth_rds = depth_rds
        else:
            self.depth_rds = RasterDS(depth_rds)

        if type(sand_shp).__name__ == 'GeoDataFrame':
            self.gdf = sand_shp
        else:
            self.gdf = gpd.read_file(sand_shp)

        self.gdf_query = gdf_query
        # self.full_image_array = self.img_rds.band_array

        self._set_arrays()

    def copy(self, gdf_query="unchanged", depth_range="unchanged",
             surface_refraction="unchanged", surface_reflectance="unchanged"):
        if gdf_query is "unchanged":
            gdf_query = self.gdf_query
        if depth_range is "unchanged":
            depth_range = self.depth_range
        if surface_refraction is "unchanged":
            surface_refraction = self.surf_refraction
        if surface_reflectance is "unchanged":
            surface_reflectance = self.surf_reflectance
        return ParameterEstimator(self.img_rds, self.depth_rds, self.gdf,
                                  gdf_query, depth_range, surface_refraction,
                                  surface_reflectance)

    @property
    def _unequal_image_subset(self):
        """
        The image array masked outside of the geometry. The mask on this array
        may not match the mask on the depth array.
        """
        # print "Image Shape: {}".format(self.img_rds.geometry_subset(self.geometry).shape)
        return self.img_rds.geometry_subset(self.geometry)

    @property
    def _unequal_depth_subset(self):
        """
        The depth array masked outside of the geometry. The mask on this array
        may not match the mask on the image array.
        """
        darr = self.depth_rds.geometry_subset(self.geometry).squeeze()
        if type(self.depth_range).__name__ != 'NoneType':
            darr = np.ma.masked_outside(darr, *self.depth_range)
        # print "Depth Shape: {}".format(darr.shape)
        return darr

    def set_depth_range(self, depth_range):
        self.depth_range = depth_range
        self._set_arrays()

    def _set_arrays(self):
        imarr, darr = equalize_array_masks(self._unequal_image_subset, self._unequal_depth_subset)
        fullim = self.img_rds.band_array
        if self.surf_refraction:
            imarr = surface_refraction_correction(imarr)
            fullim = surface_refraction_correction(fullim)
        if self.surf_reflectance:
            acceptable = ['ndarray','list','tuple']
            if type(self.surf_reflectance).__name__ in acceptable:
                imarr = surface_reflectance_correction(imarr, self.surf_reflectance)
                fullim = surface_reflectance_correction(fullim, self.surf_reflectance)
            elif self.surf_reflectance == True:
                imarr = surface_reflectance_correction(imarr)
                fullim = surface_reflectance_correction(fullim)
            else:
                raise TypeError("If self.surf_reflectance doesn't evaluate to \
                            False, then it should be an ndarray, a list, or a \
                            tuple.")
        self.image_subset_array = imarr
        self.full_image_array = fullim
        self.depth_subset_array = darr.squeeze()
        return True

    def same_resolution(self, print_res=False):
        """
        Check if the gdal geotransforms match for the rasters. If they match,
        the resolutions are the same.
        """
        gt1 = np.array(self.img_rds.gdal_ds.GetGeoTransform())[[1,5]]
        gt2 = np.array(self.depth_rds.gdal_ds.GetGeoTransform())[[1,5]]
        if print_res:
            print gt1, gt2
        return np.allclose(gt1, gt2)

    @property
    def geometry(self):
        """
        Return a single geometry from `self.gdf` (the GeoDataFrame representation
        of `sand_shp`). If `gdf_query` has not been set, the geometry returned
        will just be the first geometry in `sand_shp`. If `gdf_query` has been
        set, the returned geometry will be the first one returned by that query.

        Returns
        -------
        shapely.geometry
            A geometry shapely (https://pypi.python.org/pypi/Shapely) geometry
            object.

        """
        if self.gdf_query == None:
            geom = self.gdf.ix[0].geometry
        else:
            geom = self.gdf.query(self.gdf_query).iloc[0].geometry
        return geom

    def deep_water_means(self, p=10, win_size=3, win_percentage=50):
        """
        This is really the darkest pixel means base on brightness. In some cases
        this may select shallow water over a dark bottom rather than selecting
        deep water. If you're using this for the Lyzenga log transformation, you
        probably don't want that. For more information see the docstrings in
        `OpticalRS.Lyzenga2006`. You can use `dark_pixel_array` to figure out
        which pixels are actually being selected.
        """
        dpa = dark_pixel_array(self.full_image_array, p=p, win_size=win_size,
                               win_percentage=win_percentage)
        deep_water_means = dpa.reshape(-1,dpa.shape[-1]).mean(0)
        return deep_water_means.data

    def dark_percentile(self, p=1):
        """
        This is a simpler alternative (of sorts) to `deep_water_means`. Rather
        than using a version of Lyzenga's criteria to select the pixels, this
        method just chooses gives the `p`th percetile of each band. This method
        assumes that land has been masked from the image (shadows on land can be
        darker than water and that could throw off the returns).

        If you subtract these values from the image bands and curve fit, you'll
        get `Rinf` values close to zero. This is like having the deep water as
        completely black. The left over signal might approximate just what's
        reflected from the bottom. ...or not. This is just something I messed
        around with a bit.
        """
        # I had problems trying to subtract these values as type float64 from
        # a float32 image so I'm casting them to float32 here.
        return band_percentiles(self.full_image_array, p=p).astype(np.float32)

    def linear_parameters(self, deep_water_means=None, geometric_factor=2.0):
        if type(deep_water_means).__name__ == 'NoneType':
            dwm = self.deep_water_means()
        else:
            dwm = deep_water_means
        X = np.ma.log(self.image_subset_array - dwm)
        # X, Xdepth = equalize_array_masks(X, self.depth_subset_array)
        Xdepth = self.depth_subset_array
        params = regressions(Xdepth, X)
        Kg_arr = -1 * params[0]
        n_pix = X.reshape(-1,X.shape[-1]).count(0)
        nbands = np.atleast_3d(X).shape[-1]
        pardf = pd.DataFrame(Kg_arr, columns=["Kg"],
                             index=wv2_center_wavelength[:nbands])
        pardf['K'] = pardf.Kg / geometric_factor
        pardf['nPix'] = n_pix
        return pardf

    def linear_fit_plot(self, deep_water_means=None, visible_only=True):
        if type(deep_water_means).__name__ == 'NoneType':
            dwm = self.deep_water_means()
        else:
            dwm = deep_water_means
        X = np.ma.log(self.image_subset_array - dwm)
        Xdepth = self.depth_subset_array
        fig = regression_plot(Xdepth, X, visible_only=visible_only)
        return fig
        # return X, Xdepth

    def curve_fit_parameters(self, geometric_factor=2.0):
        paramdf = param_df(self.depth_subset_array, self.image_subset_array,
                            geometric_factor=geometric_factor)
        return paramdf

    def curve_fit_plots(self, params=None, plot_params=True,
                        ylabel='Reflectance', visible_only=True):
        return albedo_parameter_plots(self.image_subset_array,
                                        self.depth_subset_array, params=params,
                                        plot_params=plot_params, ylabel=ylabel,
                                        visible_only=visible_only)

    def K_comparison_plot(self, paramdf, columns='K',
                       figure_title="$K$ Estimates vs. $K$ Values from Jerlov"):
        return jerlov_Kd_plot(paramdf, columns, figure_title)
示例#11
0
class ParameterEstimator(RasterShape):
    """
    An object to simplify the process of estimating some apparent optical
    properties (AOPs). Most importantly, the diffuse attenuation coefficient (K).
    I need to add more documentation.
    """
    def __init__(self, img_rds, depth_rds, sand_shp, gdf_query=None,
                 depth_range=None, surface_refraction=False,
                 surface_reflectance=False):
        self.surf_reflectance = surface_reflectance
        self.surf_refraction = surface_refraction
        self.depth_range = depth_range
        if type(img_rds).__name__ == 'RasterDS':
            self.img_rds = img_rds
        else:
            self.img_rds = RasterDS(img_rds)

        if type(depth_rds).__name__ == 'RasterDS':
            self.depth_rds = depth_rds
        else:
            self.depth_rds = RasterDS(depth_rds)

        if type(sand_shp).__name__ == 'GeoDataFrame':
            self.gdf = sand_shp
        else:
            self.gdf = gpd.read_file(sand_shp)

        self.gdf_query = gdf_query
        # self.full_image_array = self.img_rds.band_array

        self._set_arrays()

    def copy(self, gdf_query="unchanged", depth_range="unchanged",
             surface_refraction="unchanged", surface_reflectance="unchanged"):
        if gdf_query is "unchanged":
            gdf_query = self.gdf_query
        if depth_range is "unchanged":
            depth_range = self.depth_range
        if surface_refraction is "unchanged":
            surface_refraction = self.surf_refraction
        if surface_reflectance is "unchanged":
            surface_reflectance = self.surf_reflectance
        return ParameterEstimator(self.img_rds, self.depth_rds, self.gdf,
                                  gdf_query, depth_range, surface_refraction,
                                  surface_reflectance)

    @property
    def _unequal_image_subset(self):
        """
        The image array masked outside of the geometry. The mask on this array
        may not match the mask on the depth array.
        """
        # print "Image Shape: {}".format(self.img_rds.geometry_subset(self.geometry).shape)
        return self.img_rds.geometry_subset(self.geometry)

    @property
    def _unequal_depth_subset(self):
        """
        The depth array masked outside of the geometry. The mask on this array
        may not match the mask on the image array.
        """
        darr = self.depth_rds.geometry_subset(self.geometry).squeeze()
        if type(self.depth_range).__name__ != 'NoneType':
            darr = np.ma.masked_outside(darr, *self.depth_range)
        # print "Depth Shape: {}".format(darr.shape)
        return darr

    def set_depth_range(self, depth_range):
        self.depth_range = depth_range
        self._set_arrays()

    def _set_arrays(self):
        imarr, darr = equalize_array_masks(self._unequal_image_subset, self._unequal_depth_subset)
        fullim = self.img_rds.band_array
        if self.surf_refraction:
            imarr = surface_refraction_correction(imarr)
            fullim = surface_refraction_correction(fullim)
        if self.surf_reflectance:
            acceptable = ['ndarray','list','tuple']
            if type(self.surf_reflectance).__name__ in acceptable:
                imarr = surface_reflectance_correction(imarr, self.surf_reflectance)
                fullim = surface_reflectance_correction(fullim, self.surf_reflectance)
            elif self.surf_reflectance == True:
                imarr = surface_reflectance_correction(imarr)
                fullim = surface_reflectance_correction(fullim)
            else:
                raise TypeError("If self.surf_reflectance doesn't evaluate to \
                            False, then it should be an ndarray, a list, or a \
                            tuple.")
        self.image_subset_array = imarr
        self.full_image_array = fullim
        self.depth_subset_array = darr.squeeze()
        return True

    def same_resolution(self, print_res=False):
        """
        Check if the gdal geotransforms match for the rasters. If they match,
        the resolutions are the same.
        """
        gt1 = np.array(self.img_rds.gdal_ds.GetGeoTransform())[[1,5]]
        gt2 = np.array(self.depth_rds.gdal_ds.GetGeoTransform())[[1,5]]
        if print_res:
            print gt1, gt2
        return np.allclose(gt1, gt2)

    @property
    def geometry(self):
        """
        Return a single geometry from `self.gdf` (the GeoDataFrame representation
        of `sand_shp`). If `gdf_query` has not been set, the geometry returned
        will just be the first geometry in `sand_shp`. If `gdf_query` has been
        set, the returned geometry will be the first one returned by that query.

        Returns
        -------
        shapely.geometry
            A geometry shapely (https://pypi.python.org/pypi/Shapely) geometry
            object.

        """
        if self.gdf_query == None:
            geom = self.gdf.ix[0].geometry
        else:
            geom = gdf.query(self.gdf_query).ix[0].geometry
        return geom

    def deep_water_means(self, p=10, win_size=3, win_percentage=50):
        """
        This is really the darkest pixel means base on brightness. In some cases
        this may select shallow water over a dark bottom rather than selecting
        deep water. If you're using this for the Lyzenga log transformation, you
        probably don't want that. For more information see the docstrings in
        `OpticalRS.Lyzenga2006`. You can use `dark_pixel_array` to figure out
        which pixels are actually being selected.
        """
        dpa = dark_pixel_array(self.full_image_array, p=p, win_size=win_size,
                               win_percentage=win_percentage)
        deep_water_means = dpa.reshape(-1,dpa.shape[-1]).mean(0)
        return deep_water_means.data

    def dark_percentile(self, p=1):
        """
        This is a simpler alternative (of sorts) to `deep_water_means`. Rather
        than using a version of Lyzenga's criteria to select the pixels, this
        method just chooses gives the `p`th percetile of each band. This method
        assumes that land has been masked from the image (shadows on land can be
        darker than water and that could throw off the returns).

        If you subtract these values from the image bands and curve fit, you'll
        get `Rinf` values close to zero. This is like having the deep water as
        completely black. The left over signal might approximate just what's
        reflected from the bottom. ...or not. This is just something I messed
        around with a bit.
        """
        # I had problems trying to subtract these values as type float64 from
        # a float32 image so I'm casting them to float32 here.
        return band_percentiles(self.full_image_array, p=p).astype(np.float32)

    def linear_parameters(self, deep_water_means=None, geometric_factor=2.0):
        if type(deep_water_means).__name__ == 'NoneType':
            dwm = self.deep_water_means()
        else:
            dwm = deep_water_means
        X = np.ma.log(self.image_subset_array - dwm)
        # X, Xdepth = equalize_array_masks(X, self.depth_subset_array)
        Xdepth = self.depth_subset_array
        params = regressions(Xdepth, X)
        Kg_arr = -1 * params[0]
        n_pix = X.reshape(-1,X.shape[-1]).count(0)
        nbands = np.atleast_3d(X).shape[-1]
        pardf = pd.DataFrame(Kg_arr, columns=["Kg"],
                             index=wv2_center_wavelength[:nbands])
        pardf['K'] = pardf.Kg / geometric_factor
        pardf['nPix'] = n_pix
        return pardf

    def linear_fit_plot(self, deep_water_means=None, visible_only=True):
        if type(deep_water_means).__name__ == 'NoneType':
            dwm = self.deep_water_means()
        else:
            dwm = deep_water_means
        X = np.ma.log(self.image_subset_array - dwm)
        Xdepth = self.depth_subset_array
        fig = regression_plot(Xdepth, X, visible_only=visible_only)
        return fig
        # return X, Xdepth

    def curve_fit_parameters(self, geometric_factor=2.0):
        paramdf = param_df(self.depth_subset_array, self.image_subset_array,
                            geometric_factor=geometric_factor)
        return paramdf

    def curve_fit_plots(self, params=None, plot_params=True,
                        ylabel='Reflectance', visible_only=True):
        return albedo_parameter_plots(self.image_subset_array,
                                        self.depth_subset_array, params=params,
                                        plot_params=plot_params, ylabel=ylabel,
                                        visible_only=visible_only)

    def K_comparison_plot(self, paramdf, columns='K',
                       figure_title="$K$ Estimates vs. $K$ Values from Jerlov"):
        return jerlov_Kd_plot(paramdf, columns, figure_title)
示例#12
0
    def rasterize(self,
                  buffer_radius=None,
                  raster_template=None,
                  pixel_size=1.99976,
                  value_field='hab_num',
                  float_values=False,
                  array_only=False,
                  out_file_path=None):
        """
        Return a raster that can be used for classification training.

        buffer_radius: A float value in projection units to buffer the
        geometries by. If buffer_radius is left None then only pixels right
        under points will be classified.

        raster_template: A RasterDS object. If supplied, the resulting
        rasterized image will have the same extent and geotransform as the
        template. Also, if a raster_template is provided, the pixel_size keyword
        value will be ignored and pixel size will come from the template.

        pixel_size: A float value representing pixel size in projection units.
        This value will be ignored if a raster_template is supplied.

        value_field: A string representing the name of the field in the
        shapefile that holds the numeric code that will be burned into the
        raster output as the pixel value.

        float_values: Boolean. If `True`, the output raster will contain floats.
        If `False`, the output will be integers. Default is `False`.

        array_only: A boolean. If true we'll try to just write the raster to
        memory and not to disk. If you don't need to keep the raster, this will
        just keep you from having to clean up useless files later. Then we'll
        just return an array instead of GroundTruthRaster object.

        out_file_path: String. Path to the raster file output. If `None`
        (default) and `array_only=False`, a file name based on the
        `GroundTruthShapefile` file name will be created. If `array_only=True`,
        `out_file_path` is ignored.
        """
        if float_values:
            datatype = gdal.GDT_Float32
        else:
            datatype = gdal.GDT_Byte
        # Make a copy of the layer's data source because we'll need to
        # modify its attributes table
        if buffer_radius:
            source_ds = ogr.GetDriverByName("Memory").CopyDataSource(
                self.buffer(radius=buffer_radius), "")
        else:
            source_ds = ogr.GetDriverByName("Memory").CopyDataSource(
                self.ds, "")
        source_layer = source_ds.GetLayer(0)
        source_srs = source_layer.GetSpatialRef()

        if raster_template:
            gTrans = raster_template.gdal_ds.GetGeoTransform()
            pixsizeX = gTrans[1]
            pixsizeY = gTrans[5]
            x_res = raster_template.gdal_ds.RasterXSize
            y_res = raster_template.gdal_ds.RasterYSize
            rdsarr = raster_template.band_array
            # if np.ma.is_masked(rdsarr):
            #     mask = rdsarr[...,0].mask
            # else:
            #     mask = None
        else:
            x_min, x_max, y_min, y_max = source_layer.GetExtent()
            # Create the destination data source
            x_res = int((x_max - x_min) / pixel_size)
            y_res = int((y_max - y_min) / pixel_size)

        if out_file_path:
            targ_fn = out_file_path
        else:
            # make a target ds with filename based on source filename
            targ_fn = self.file_path.rsplit(
                os.path.extsep, 1)[0] + '_rast' + os.path.extsep + 'tif'
        # print "x_res: %i, y_res: %i" % (x_res,y_res)
        target_ds = gdal.GetDriverByName('GTiff').Create(
            targ_fn, x_res, y_res, 1, datatype)

        if raster_template:
            # Use the raster template supplied so that we get the same extent as the raster
            # we're trying to classify
            target_ds.SetGeoTransform(gTrans)
        else:
            # None supplied so use the pixel_size value and the extent of the shapefile
            target_ds.SetGeoTransform((
                x_min,
                pixel_size,
                0,
                y_max,
                0,
                -pixel_size,
            ))
        if raster_template:
            target_ds.SetProjection(raster_template.gdal_ds.GetProjection())
        elif source_srs:
            # Make the target raster have the same projection as the source
            target_ds.SetProjection(source_srs.ExportToWkt())
        else:
            # Source has no projection (needs GDAL >= 1.7.0 to work)
            target_ds.SetProjection('LOCAL_CS["arbitrary"]')
        # Rasterize
        err = gdal.RasterizeLayer(target_ds, [1],
                                  source_layer,
                                  burn_values=[0],
                                  options=["ATTRIBUTE=%s" % value_field])
        if err != 0:
            raise Exception("error rasterizing layer: %s" % err)
        # clean up
        source_layer = None
        source_srs = None
        source_ds = None

        if array_only:
            out_array = target_ds.ReadAsArray()
            target_ds = None
            os.remove(targ_fn)
            return out_array
        else:
            target_ds = None
            return RasterDS(targ_fn)
示例#13
0
 def __init__(self, rlayer, overwrite=True):
     RasterDS.__init__(self, rlayer, overwrite=overwrite)
     self.ratdf = self.__get_or_create_rat()