Exemple #1
0
def dem_to_aspect(src_raster, band=0, alg='Horn', trigonometric=False):
    """Calculate the aspect for the DEM.

    Parameters
    ----------
    src_raster : Raster
        The dem used to calculate the aspect.
    band : int, optional, default: 0
        source band number to use.
    alg : {'ZevenbergenThorne' or 'Horn'}, optional, default: Horn
        The literature suggests Zevenbergen & Thorne to be more suited to smooth landscapes, 
        where Horn’s formula to perform better on rougher terrain.
    trigonometric: bool, optional, default: False
        whether to return trigonometric angle instead of azimuth. 
        Thus 0deg means East, 90deg North, 180deg West, 270deg South.

    Returns
    -------
    dst_raster: Raster
        Aspect calculated from the DEM.
    """
    options = dict(band=band + 1,
                   alg=alg,
                   trigonometric=trigonometric,
                   format='MEM')
    ds_src = src_raster.to_gdal_ds()
    ds = gdal.DEMProcessing('', ds_src, 'aspect', **options)
    dst_raster = tgp.read_gdal_ds(ds)
    return dst_raster
Exemple #2
0
def dem_to_slope(src_raster, band=0, alg='Horn', slope_format='degree'):
    """Calculate the slope for the DEM.

    Parameters
    ----------
    src_raster : Raster
        The dem used to calculate the slope.
    band : int, optional, default: 0
        source band number to use.
    alg : {'ZevenbergenThorne' or 'Horn'}, optional, default: Horn
        The literature suggests Zevenbergen & Thorne to be more suited to smooth landscapes, 
        where Horn’s formula to perform better on rougher terrain.
    slope_format: {"degree" or "percent"}, optional, default degree
        The format of the slope.

    Returns
    -------
    dst_raster: Raster
        Slope calculated from the DEM.
    """
    options = dict(band=band + 1,
                   alg=alg,
                   slopeFormat=slope_format,
                   format='MEM')
    ds_src = src_raster.to_gdal_ds()
    ds = gdal.DEMProcessing('', ds_src, 'slope', **options)
    dst_raster = tgp.read_gdal_ds(ds)
    return dst_raster
Exemple #3
0
def dem_to_hillshade(src_raster, band=0, alg='Horn', azimuth=315, altitude=45):
    """Calculate the hillshade for the DEM.

    Parameters
    ----------
    src_raster : Raster
        The dem used to calculate the hillshade.
    band : int, optional, default: 0
        source band number to use.
    alg : {'ZevenbergenThorne' or 'Horn'}, optional, default: Horn
        The literature suggests Zevenbergen & Thorne to be more suited to smooth landscapes, 
        where Horn’s formula to perform better on rougher terrain.
    azimuth : int, optional, default 315
        Azimuth of the light, in degrees. 0 if it comes from the top of the raster, 90 from the east, ... 
        The default value, 315, should rarely be changed as it is the value generally used to generate shaded maps.
    altitude : int, optional, default 45
        Altitude of the light, in degrees. 90 if the light comes from above the DEM, 0 if it is raking light.

    Returns
    -------
    dst_raster: Raster
        Hillshade calculated from the DEM.
    """
    options = dict(band=band + 1,
                   alg=alg,
                   azimuth=azimuth,
                   altitude=altitude,
                   format='MEM')
    ds_src = src_raster.to_gdal_ds()
    ds = gdal.DEMProcessing('', ds_src, 'hillshade', **options)
    dst_raster = tgp.read_gdal_ds(ds)
    return dst_raster
Exemple #4
0
    def remap_by_ref_raster(self, ref_raster):
        """remap the raster on to another canvas drew by referenced raster.

        Parameters
        ----------
        ref_raster: Raster
            The referenced raster. The extent, projection and resolution will be used.

        Returns
        -------
        dst_raster: Raster
            Remapped result.

        """
        src_ds = self.to_gdal_ds()
        src_projection, src_gdaldtype = self.projection, self.gdaldtype
        ref_geo_transform, ref_projection = ref_raster.geo_transform, ref_raster.projection
        output_bounds = ref_raster.extent_for_gdal  # minX, minY, maxX, maxY

        x_res, y_res = ref_geo_transform[1], ref_geo_transform[5]
        output_type = src_gdaldtype
        dst_ds = gdal.Warp('',
                           src_ds,
                           xRes=x_res,
                           yRes=y_res,
                           outputBounds=output_bounds,
                           format='MEM',
                           srcSRS=src_projection,
                           dstSRS=ref_projection,
                           outputType=output_type,
                           resampleAlg='bilinear')
        dst_raster = tgp.read_gdal_ds(dst_ds)
        return dst_raster
Exemple #5
0
    def reproject(self, dst_crs='EPSG:4326', src_crs=None):
        """Reproject the raster data.

        Parameters
        ----------
        dst_crs: str, optional, default: EPSG:4326
            The target crs to transform the raster to.
        src_crs: str, optional
            The source crs to transform the raster from. If None, 
            get the projection from src_raster.

        Returns
        -------
        dst_raster: Raster
            Reprojected result.

        Examples
        -------- 
        >>> import TronGisPy as tgp
        >>> src_raster_fp = tgp.get_testing_fp()
        >>> src_raster = tgp.read_raster(src_raster_fp)
        >>> print("project(before)", src_raster.projection)
        >>> dst_raster = src_raster.reproject(dst_crs='EPSG:4326', src_crs=None)
        >>> print("project(after)", tgp.wkt_to_epsg(dst_raster.projection))
        """
        src_ds = self.to_gdal_ds()
        if src_crs:
            dst_ds = gdal.Warp('',
                               src_ds,
                               srcSRS=src_crs,
                               dstSRS=dst_crs,
                               format='MEM')
        else:
            dst_ds = gdal.Warp('', src_ds, dstSRS=dst_crs, format='MEM')
            if dst_ds is None:
                try:
                    src_crs = "EPSG:" + str(tgp.wkt_to_epsg(self.projection))
                    dst_ds = gdal.Warp('',
                                       src_ds,
                                       srcSRS=src_crs,
                                       dstSRS=dst_crs,
                                       format='MEM')
                    assert dst_ds is not None, "Please provide src_crs since the raster does not contain valid crs information."
                    print("Please provide src_crs to accelerate the process.")
                except:
                    assert False, "Please provide src_crs since the raster does not contain crs information."

        dst_raster = tgp.read_gdal_ds(dst_ds)
        return dst_raster
Exemple #6
0
def clip_raster_with_extent(src_raster, extent):
    """Clip raster with extent.

    Parameters
    ----------
    src_raster: Raster
        Which raster data to be clipped.
    extent: tuple
        extent to clip the data with (xmin, ymin, xmax, ymax) format.

    Returns
    -------
    dst_raster: Raster. 
        Clipped result.

    Examples
    -------- 
    >>> import geopandas as gpd
    >>> import TronGisPy as tgp
    >>> from TronGisPy import ShapeGrid
    >>> from matplotlib import pyplot as plt
    >>> from shapely.geometry import Polygon
    >>> src_raster_fp = tgp.get_testing_fp('satellite_tif')
    >>> src_raster = tgp.read_raster(src_raster_fp)
    >>> ext = xmin, ymin, xmax, ymax = [329454.39272725, 2746809.43272727, 331715.57090906, 2748190.90181818]
    >>> dst_raster = ShapeGrid.clip_raster_with_extent(src_raster, ext)
    >>> fig, (ax1, ax2) = plt.subplots(1, 2) # plot the result
    >>> src_raster.plot(ax=ax1) 
    >>> ext_poly = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
    >>> df_ext_poly = gpd.GeoDataFrame([Polygon(ext_poly)], columns=['geom'], geometry='geom')
    >>> df_ext_poly.boundary.plot(ax=ax1)
    >>> ax1.set_title('original image and clipper')
    >>> dst_raster.plot(ax=ax2)
    >>> ax2.set_title('clipped image')
    >>> plt.show()
    """
    assert src_raster.geo_transform is not None, "src_raster.geo_transform should not be None"
    src_ds = src_raster.to_gdal_ds()
    dst_ds = gdal.Warp('',
                       src_ds,
                       format='MEM',
                       outputBounds=extent,
                       cropToCutline=True)
    dst_raster = tgp.read_gdal_ds(dst_ds)
    return dst_raster
Exemple #7
0
def dem_to_roughness(src_raster, band=0):
    """Calculate the roughness for the DEM.

    Parameters
    ----------
    src_raster : Raster
        The dem used to calculate the roughness.
    band : int, optional, default: 0
        source band number to use.

    Returns
    -------
    dst_raster: Raster
        roughness calculated from the DEM.
    """
    options = dict(band=band + 1, format='MEM')
    ds_src = src_raster.to_gdal_ds()
    ds = gdal.DEMProcessing('', ds_src, 'Roughness', **options)
    dst_raster = tgp.read_gdal_ds(ds)
    return dst_raster
Exemple #8
0
def dem_to_TPI(src_raster, band=0):
    """Calculate the topographic position index (TPI) for the DEM.

    Parameters
    ----------
    src_raster : Raster
        The dem used to calculate the TPI.
    band : int, optional, default: 0
        source band number to use.

    Returns
    -------
    dst_raster: Raster
        TPI calculated from the DEM.
    """
    options = dict(band=band + 1, format='MEM')
    ds_src = src_raster.to_gdal_ds()
    ds = gdal.DEMProcessing('', ds_src, 'TPI', **options)
    dst_raster = tgp.read_gdal_ds(ds)
    return dst_raster
Exemple #9
0
def gdal_fillnodata(raster,
                    band=0,
                    no_data_value=999,
                    max_distance=100,
                    smoothing_iterations=0):
    """Interpolate values on specific cells (generally nan cell) using 
    `gdal.FillNodata`. To be mentioned, this cannot accept zero in its data
    except its no_data_value is zero.

    Parameters
    ----------
    raster: Raster
        The Raster object you want to fill the no_data_value.
    band: int, optional, default: 0
        The band numnber of Raster object you want to fill the no_data_value 
        which start from zero.
    no_data_value: int or float, optional, default: 999
        The value to be filled with interpolated value. If no_data_value == None, 
        use np.nan as no_data_value.
    max_distance: int, optional, default: 100
        The cells within the max distance from no_data_value location will be 
        calculated to fill the no_data_value.
    smoothing_iterations: int, optional, default: 0
        The maximum limitation on loop.

    Returns
    -------
    data_interp: ndarray. 
        Interpolation result.

    Examples
    -------- 
    >>> import numpy as np
    >>> import TronGisPy as tgp 
    >>> from TronGisPy import Interpolation
    >>> from matplotlib import pyplot as plt
    >>> raster_fp = tgp.get_testing_fp('tif_forinterpolation')
    >>> raster = tgp.read_raster(raster_fp)
    >>> raster.data[np.isnan(raster.data)] = 999
    >>> raster_interp = Interpolation.gdal_fillnodata(raster)
    >>> fig, (ax1, ax2) = plt.subplots(1,2)
    >>> raster.plot(ax=ax1)
    >>> raster_interp.plot(ax=ax2)
    >>> plt.show()
    """
    # make dst_band
    ds_dst = raster.to_gdal_ds()
    dstband = ds_dst.GetRasterBand(band + 1)

    # make maskband
    raster_mask = raster.copy()
    raster_mask.data[raster_mask.data == no_data_value] = 0
    raster_mask.data[raster_mask.data != 0] = 1
    raster_mask.astype(bool)
    raster_mask.no_data_value = 0
    ds_mask = raster_mask.to_gdal_ds()
    maskband = ds_mask.GetRasterBand(1)

    gdal.FillNodata(dstband, maskband, max_distance, smoothing_iterations)
    data_interp = tgp.read_gdal_ds(ds_dst)

    ds_dst = None
    ds_mask = None
    return data_interp
Exemple #10
0
    def refine_resolution(self,
                          dst_resolution,
                          resample_alg='near',
                          extent=None,
                          rotate=True):
        """Refine the resolution of the raster.

        Parameters
        ----------
        dst_resolution: int
            Target Resolution.
        resample_alg: {'near', 'bilinear', 'cubic', 'cubicspline', 'lanczos', 'average', 'mode'}.
            ``near``: nearest neighbour resampling (default, fastest algorithm, worst interpolation quality).
            ``bilinear``: bilinear resampling.
            ``cubic``: cubic resampling.
            ``cubicspline``: cubic spline resampling.
            ``lanczos``: Lanczos windowed sinc resampling.
            ``average``: average resampling, computes the weighted average of all non-NODATA contributing pixels.
            ``mode``: mode resampling, selects the value which appears most often of all the sampled points.
        extent: tuple
            extent to clip the data with (xmin, ymin, xmax, ymax) format.
        rotate: bool
            If True, the function will rotate the raster and adds noData values around it to make a new rectangular image 
            matrix if the rotation in Raster.geo_transform is not zero, else it will keep the original rotation angle of 
            Raster.geo_transform. Gdal will rotate the image by default . Please refer to the issue
            https://gis.stackexchange.com/questions/256081/why-does-gdalwarp-rotate-the-data and 
            https://github.com/OSGeo/gdal/issues/1601.

        Returns
        -------
        dst_raster: Raster
            Refined result.

        Examples
        -------- 
        >>> import numpy as np
        >>> import TronGisPy as tgp
        >>> from TronGisPy import ShapeGrid
        >>> from matplotlib import pyplot as plt
        >>> src_raster_fp = tgp.get_testing_fp('dem_process_path')
        >>> src_raster = tgp.read_raster(src_raster_fp)
        >>> src_raster.data[src_raster.data == -999] = np.nan
        >>> dst_raster = src_raster.refine_resolution(dst_resolution=10, resample_alg='bilinear')
        >>> fig, (ax1, ax2) = plt.subplots(1, 2) # plot the result
        >>> src_raster.plot(ax=ax1)
        >>> ax1.set_title('original dem ' + str(src_raster.shape))
        >>> dst_raster.plot(ax=ax2)
        >>> ax2.set_title('refined image ' + str(dst_raster.shape))
        >>> plt.show()
        """
        src_ds = self.to_gdal_ds()

        if rotate:
            dst_ds = gdal.Warp('',
                               src_ds,
                               xRes=dst_resolution,
                               yRes=dst_resolution,
                               outputBounds=extent,
                               format='MEM',
                               resampleAlg=resample_alg)
            dst_raster = tgp.read_gdal_ds(dst_ds)
        else:
            assert extent is None, "you cannot set the extent when rotate == False"
            zoom_in = dst_resolution / self.pixel_size[0]
            dst_ds = gdal.Warp('',
                               src_ds,
                               xRes=zoom_in,
                               yRes=zoom_in,
                               format='MEM',
                               resampleAlg=resample_alg,
                               transformerOptions=[
                                   'SRC_METHOD=NO_GEOTRANSFORM',
                                   'DST_METHOD=NO_GEOTRANSFORM'
                               ])
            dst_geo_transform = np.array(self.geo_transform)
            dst_geo_transform[[1, 2, 4, 5]] *= zoom_in
            dst_raster = tgp.read_gdal_ds(dst_ds)
            dst_raster.geo_transform = tuple(dst_geo_transform)
            dst_raster.projection = self.projection
        return dst_raster