Пример #1
0
    def single_band_calculator(self, rlist, expression):
        """ Raster calculator """

        logging.debug('Starting single_band_calculator... ')

        array_list = [GdalReader().ds2array(gdal_import.src2ds(r))[0] if np.array(r).ndim is 2 else
                      GdalReader().ds2array(gdal_import.src2ds(r)) for r in rlist]

        calculation = tools.array_calculator(array_list, expression)

        return self._array2raster(calculation, name=str(expression), mask=rlist[0])
Пример #2
0
    def histogram_matching(self, input_raster, reference, output='histogram_matching'):

        logging.debug('Starting histogram_matching... ')

        src_ds = gdal_import.src2ds(input_raster)
        raster_array = GdalReader().ds2array(src_ds)

        ref_ds = gdal_import.src2ds(reference)
        ref_array = GdalReader().ds2array(ref_ds)
        nodata = ref_ds.GetRasterBand(1).GetNoDataValue()

        matched_array= tools.histogram_matching(raster_array, ref_array, nodata=nodata)
        return self._array2raster(matched_array, name=output, mask=input_raster)
Пример #3
0
def src2ds(src):
    logging.debug("Importing file tiles " + str(src))

    if GdalReader().isvalid(src):
        return src

    else:
        try:
            GdalReader().isvalid(src.ds)
            return src.ds

        except:

            logging.exception(" Unknown source.")
Пример #4
0
def raster2file(raster, file_path):

    ds = src2ds(raster)
    GdalReader().gdal2file(ds, file_path, driver_name='GTiff')

    if os.path.exists(file_path):
        return file_path
Пример #5
0
def raster_stats(input_raster, output=None):

    logging.debug('Starting histogram_matching... ')

    src_ds = gdal_import.src2ds(input_raster)
    raster_array = GdalReader().ds2array(src_ds)
    return numpy_tools.array_stats(raster_array)
Пример #6
0
def py2gdal(py_raster):
    """ Convert python format to gdal"""

    if GdalReader().isvalid(py_raster.ds):

        return py_raster.ds

    else:

        geotransform = (py_raster.extent[0], py_raster.xres, 0,
                        py_raster.extent[3], 0, py_raster.yres)

        return GdalReader().array2ds(src_array=py_raster.array,
                                     output=py_raster.filename,
                                     geotransform=geotransform,
                                     projection=py_raster.projection,
                                     nodata=py_raster.nodata)
Пример #7
0
    def zonal_stats(self, raster, zones, resize=True):

        logging.debug('Starting zonal_stats... ')

        src_ds = gdal_import.src2ds(raster)
        raster_array = GdalReader().ds2array(src_ds)

        zones_ds = gdal_import.src2ds(zones)
        zones_array = GdalReader().ds2array(zones_ds)

        outputs = tools.zonal_stats(valuesarr=raster_array[0], zonesarr=zones_array[0],
                                    resize=resize)

        outputs_dict = {}
        name = 'stats'
        for stat in ['count', 'mean', 'stdev']:
            outputs_dict[str(stat)] = (self._array2raster(outputs[stat], name=str(name + '_' + str(stat)),
                                                          mask=raster))

        return outputs_dict
Пример #8
0
    def rgb_intensity(self, input_raster):
        """ Intensity for rgb images 
        :param input_raster dictionary with the RGB bands
        """
        logging.debug('Starting rgb_intensity... ')

        src_ds = gdal_import.src2ds(input_raster)
        raster_array = GdalReader().ds2array(src_ds)

        intensity = tools.rgb_intensity(raster_array)
        return self._array2raster(intensity, name='intensity', mask=input_raster)
Пример #9
0
    def equalization(self, input_raster):
        """Equalization of a 2D array with finite values
        :param input_raster 2D array"""

        logging.debug('Starting equalization... ')

        src_ds = gdal_import.src2ds(input_raster)
        raster_arrays = GdalReader().ds2array(src_ds)
        d_bands = tools.equalization(bands_list=raster_arrays)
        # return gdal_import.gdal_import(toolbox.raster.gdal_utils.poly_clip(raster, polygons, output))

        return self._array2raster(d_bands, name='equalization', mask=input_raster)
Пример #10
0
    def normalisation(self, input_raster):
        """Normalisation of a 2D array to 0-255 
        :param input_raster 2D array"""

        logging.debug('Starting normalisation... ')

        src_ds = gdal_import.src2ds(input_raster)
        raster_arrays = GdalReader().ds2array(src_ds)

        nodata = src_ds.GetRasterBand(1).GetNoDataValue()
        d_bands = tools.normalisation(raster_arrays, nodata=nodata)
        return self._array2raster(d_bands, name="normalization", mask=input_raster)
Пример #11
0
def single_bands_to_multiband(gdal_bands_list, output=None):
    """ Convert several gdal single file to a single gdal datasource"""

    # Get mask
    # src_ds = gdal.OpenShared(gdal_bands_list[0])
    src_ds = GdalReader().gdal2ds(gdal_bands_list[0])
    # src_ds.SetMetadataItem('FilePath', gdal_bands_list[0])

    # Get output
    if not output:
        output = 'image_multiband'

    # Create new ds
    # tmp_ds = gdal.GetDriverByName('MEM').CreateCopy('', src_ds, 0)
    out_ds = gdalr.GdalReader().create_ds(output, src_ds.RasterXSize,
                                          src_ds.RasterYSize,
                                          len(gdal_bands_list),
                                          src_ds.GetRasterBand(1).DataType)

    out_ds.SetProjection(src_ds.GetProjection())
    out_ds.SetGeoTransform(src_ds.GetGeoTransform())

    i = 0
    for band_dataset in gdal_bands_list:

        i = i + 1
        band_ds = GdalReader().gdal2ds(band_dataset)
        # mask_ds = gdal.OpenShared(band_dataset)
        array_i = band_ds.GetRasterBand(1).ReadAsArray()

        out_ds.GetRasterBand(i).WriteArray(array_i)
        band_ds = None
        del array_i

    if GdalReader().isvalid(out_ds):
        return out_ds
Пример #12
0
    def vegetation_index(self, input_raster):
        """ Vegetation Index (GRVI, NDVI) for rgb/rgbnir images 
        :param input_raster dictionary with the RGB bands
        """
        logging.debug('Starting vegetation_index... ')

        src_ds = gdal_import.src2ds(input_raster)
        raster_bands = GdalReader().ds2array(src_ds)

        if len(raster_bands) == 3:
            vi = tools.vegetation_index(red=raster_bands[0], green=raster_bands[1])

        elif len(raster_bands) >= 4:
            vi = tools.vegetation_index(red=raster_bands[0], green=raster_bands[1], nir=raster_bands[3])

        else:
            logging.warning('Not enough bands to create vegetation index.')
            return

        return self._array2raster(vi, name='vi', mask=input_raster)
Пример #13
0
def poly_clip(raster, polygons, outuput):
    """Clip raster with polygons"""

    src_ds = gdal_import.src2ds(raster)
    poly_ds = ogr_import.src2ogr(polygons)

    # 1.- Reproject vector geometry to same projection as raster
    projection = src_ds.GetProjection()
    poly_reprojected = ogr_utils.reproject(poly_ds,
                                           wtk_projection=projection,
                                           outname='polygons_reprojected')

    poly_ds = ogr_import.src2ogr(poly_reprojected)
    poly_lyr = poly_ds.GetLayer()

    # Bound box (debbuging code)
    # geom_type = poly_lyr.GetGeomType()
    # outDataSource = ogrr.create_layer('bound_box', geom_type=geom_type, wkt_proj=projection, file_path=None)
    # outLayer = outDataSource.GetLfpayer()
    # outLayerDefn = outLayer.GetLayerDefn()
    # outFeature = ogr.Feature(outLayerDefn)
    # outFeature.SetGeometry(geom)
    # outLayer.CreateFeature(outFeature)
    # outFeature = None
    # outDataSource = None

    # 2.- Filter and extract features
    # Get Raster Extent
    nodata = src_ds.GetRasterBand(1).GetNoDataValue()

    r_min_x, r_max_x, r_min_y, r_max_y = GdalReader().get_extent(src_ds)

    wkt = 'POLYGON((' + ','.join([
        ' '.join([str(r_min_x), str(r_max_y)]), ' '.join([
            str(r_min_x), str(r_min_y)
        ]), ' '.join([str(r_max_x), str(r_min_y)]), ' '.join([
            str(r_max_x), str(r_max_y)
        ]), ' '.join([str(r_min_x), str(r_max_y)])
    ]) + '))'

    geom = ogr.CreateGeometryFromWkt(wkt)

    poly_lyr.SetSpatialFilter(geom)
    mem_driver = ogr.GetDriverByName('MEMORY')
    filtered_poly_ds = mem_driver.CreateDataSource('filered_polygons')

    # Open the memory datasource with write access and copy content
    mem_driver = ogr.GetDriverByName('MEMORY')
    mem_driver.Open('filered_polygons', 1)
    filtered_poly_ds.CopyLayer(poly_lyr, 'filered_polygons', ['OVERWRITE=YES'])

    poly_lyr.SetSpatialFilter(None)

    # Intersect geometries with boundary box
    geom_type = poly_lyr.GetGeomType()
    clipped_poly_ds = ogrr.create_layer('clipped_polygons',
                                        geom_type=geom_type,
                                        wkt_proj=projection,
                                        file_path=None)

    clipped_poly_lyr = clipped_poly_ds.GetLayer()
    filtered_poly_lyr = filtered_poly_ds.GetLayer()

    clipped_lyr_defn = clipped_poly_lyr.GetLayerDefn()
    infeature = filtered_poly_lyr.GetNextFeature()
    while infeature:
        feat_geom = infeature.GetGeometryRef()
        intersection_geom = feat_geom.Intersection(geom)

        out_feature = ogr.Feature(clipped_lyr_defn)
        out_feature.SetGeometry(intersection_geom)
        clipped_poly_lyr.CreateFeature(out_feature)

        out_feature = None
        infeature = filtered_poly_lyr.GetNextFeature()

    filtered_poly_lyr.ResetReading()
    filtered_poly_lyr = None

    # Bound box (debbuging code)
    # geom_type = poly_lyr.GetGeomType()
    # filtered_poly_ds = ogrr.create_layer('filered_polygons', geom_type=geom_type, wkt_proj=projection,
    #                                     file_path=None)

    # Clip raster to layer extent
    lyr = clipped_poly_lyr
    extent = lyr.GetExtent()

    # Convert the _vector extent to image pixel coordinates
    geo_trans = src_ds.GetGeoTransform()
    # projection = rds.GetProjection()
    ul_x, ul_y = GdalReader().world2pixel(geo_trans, extent[0], extent[3])
    lr_x, lr_y = GdalReader().world2pixel(geo_trans, extent[1], extent[2])

    # Create a new geomatrix for the _raster
    geo_trans = list(geo_trans)
    geo_trans[0] = extent[0]
    geo_trans[3] = extent[3]

    # Get the new array to layer extent
    rarray = gdal_array.DatasetReadAsArray(src_ds)

    if len(rarray.shape) == 3:
        clip = rarray[:, ul_y:lr_y, ul_x:lr_x]

    elif len(rarray.shape) == 2:
        clip = rarray[ul_y:lr_y, ul_x:lr_x]

    else:
        return logging.error('Error in array shape.')

    new_array = clip_raster_array(vds=filtered_poly_ds,
                                  raster_array=clip,
                                  geotransform=geo_trans,
                                  nodata=nodata)

    return GdalReader().array2ds(src_array=np.array(new_array),
                                 output=outuput,
                                 geotransform=geo_trans,
                                 projection=projection,
                                 nodata=nodata)
Пример #14
0
 def nir(self, input_raster):
     src_ds = gdal_import.src2ds(input_raster)
     raster_array = GdalReader().ds2array(src_ds)
     return self._array2raster(raster_array[3], name="nir", mask=input_raster)
Пример #15
0
    def _array2raster(self, src_array, name, mask):
        """ Provide the right format to PY/GDAL outputs"""

        return GdalReader().array2ds(src_array, name, mask_ds=mask)
Пример #16
0
def clip_raster_array(vds, raster_array, geotransform, nodata=0):

    if len(raster_array.shape) == 3:

        nbands = raster_array.shape[0]

    else:
        nbands = 1

    new_array = []
    layer = vds.GetLayer(0)
    layer.ResetReading()

    for band in xrange(nbands):

        if len(raster_array.shape) == 3:
            raster_array_i = raster_array[band]

        else:
            raster_array_i = raster_array

        ysize, xsize = raster_array_i.shape

        # Create data mask
        rasterpoly = Image.new("L", (xsize, ysize), 1)
        raster_im = ImageDraw.Draw(rasterpoly)
        inner_ring_im = ImageDraw.Draw(rasterpoly)

        # for fid in xrange(layer.GetFeatureCount()):
        #     feature = layer.GetFeature(fid)
        for feature in layer:
            geoms = feature.GetGeometryRef()

            if geoms.GetGeometryName().lower() == "multipolygon":
                for geom in geoms:

                    pts = geom.GetGeometryRef(0)
                    points = [(pts.GetX(p), pts.GetY(p))
                              for p in range(pts.GetPointCount())]
                    pixels = [
                        GdalReader().world2pixel(geotransform, p[0], p[1])
                        for p in points
                    ]
                    raster_im.polygon(pixels, 0)

                    if geom.GetGeometryCount() > 1:
                        for i in xrange(1, geom.GetGeometryCount()):
                            pts = geom.GetGeometryRef(i)
                            points1 = [(pts.GetX(p), pts.GetY(p))
                                       for p in range(pts.GetPointCount())]
                            pixels1 = [
                                GdalReader().world2pixel(
                                    geotransform, p[0], p[1]) for p in points1
                            ]

                            inner_ring_im.polygon(pixels1, 1)

            elif geoms.GetGeometryName().lower() == "polygon":
                pts = geoms.GetGeometryRef(0)
                points = [(pts.GetX(p), pts.GetY(p))
                          for p in range(pts.GetPointCount())]
                pixels = [
                    GdalReader().world2pixel(geotransform, p[0], p[1])
                    for p in points
                ]

                raster_im.polygon(pixels, 0)

            del feature

        layer.ResetReading()

        # Image to array
        try:
            # old version
            mask = np.fromstring(rasterpoly.tostring(), 'b')

        except:
            # new version
            mask = np.fromstring(rasterpoly.tobytes(), 'b')

        mask.shape = rasterpoly.im.size[1], rasterpoly.im.size[0]

        # Clip the image using the mask (Note that np.uint8 does not allow nan values
        new_array.append(
            np.choose(mask, (raster_array_i, nodata)).astype(np.float))

    return np.array(new_array)
Пример #17
0
def gdal2tiles(src, tile_size=500, tile_id_y=None, tile_id_x=None):
    """ Load a gdal file to local python instance
    
    :param src: source gdal dataset
    :param tile_size: Tile size
    :param tile_id_y: Single tile ID for Y
    :param tile_id_x: Single tile ID for X
    """

    src_ds = gdal_import.src2ds(src)
    xsize = src_ds.RasterXSize
    ysize = src_ds.RasterYSize
    bands = src_ds.RasterCount
    nxtiles, nytiles = get_number_tiles(src_ds)

    # Read raster as arrays
    dtype = [
        key for key, value in GdalReader().np2gdal.iteritems()
        if value == src_ds.GetRasterBand(1).DataType
    ][0]

    if tile_id_x and str(tile_id_x).isdigit() and tile_id_y and str(
            tile_id_y).isdigit():
        x_tile_range = [tile_id_x]
        y_tile_range = [tile_id_y]

    else:
        x_tile_range = range(nxtiles + 1)
        y_tile_range = range(nytiles + 1)

    tiles = {}
    for xtile in x_tile_range:
        for ytile in y_tile_range:

            # DatasetReadAsArray(ds, xoff=0, yoff=0, win_xsize=None, win_ysize=None)

            if (tile_size * xtile + tile_size) < xsize and (tile_size * ytile +
                                                            tile_size) < ysize:

                # arr_i = np.array(gdal_array.DatasetReadAsArray(src_ds, xoff=tile_size * xtile, yoff=tile_size * ytile,
                # win_xsize=tile_size, win_ysize=tile_size)).astype(dtype)

                arr_i = np.array(
                    gdal_array.DatasetReadAsArray(src_ds, tile_size * xtile,
                                                  tile_size * ytile, tile_size,
                                                  tile_size)).astype(dtype)

            else:

                win_xsize = min(tile_size, xsize - tile_size * xtile)
                win_ysize = min(tile_size, ysize - tile_size * ytile)

                if win_xsize < 0 or win_ysize < 0:
                    # Not square shape
                    continue

                # arr_src = np.array(gdal_array.DatasetReadAsArray(src_ds, xoff=tile_size * xtile,
                # yoff=tile_size * ytile, win_xsize=win_xsize, win_ysize=win_ysize)).astype(dtype)
                arr_src = np.array(
                    gdal_array.DatasetReadAsArray(src_ds, tile_size * xtile,
                                                  tile_size * ytile, win_xsize,
                                                  win_ysize)).astype(dtype)

                arr_i = np.zeros((bands, win_ysize, win_xsize), dtype=dtype)
                arr_i[:, 0:arr_src.shape[1], 0:arr_src.shape[2]] = arr_src

            # Create raster
            # Geotransform
            geotransform = src_ds.GetGeoTransform()
            top_left_x = geotransform[0] + geotransform[
                1] * tile_size * xtile + geotransform[2] * tile_size * ytile
            top_left_y = geotransform[3] + geotransform[
                5] * tile_size * ytile + geotransform[4] * tile_size * xtile

            new_geotransform = [
                top_left_x, geotransform[1], geotransform[2], top_left_y,
                geotransform[4], geotransform[5]
            ]

            projection = src_ds.GetProjection()
            nodata = src_ds.GetRasterBand(1).GetNoDataValue()
            name = src_ds.GetMetadataItem('FilePath')

            tiles[str(xtile) + '_' + str(ytile)] = GdalReader().array2ds(
                arr_i,
                name + '_' + str(xtile) + '_' + str(ytile),
                geotransform=new_geotransform,
                projection=projection)

    return tiles
Пример #18
0
def merge(src_ds_list, outname, smooth_edges=False):
    # First layer metadata
    src_ds = GdalReader().gdal2ds(src_ds_list[0])
    src_ds_list = [GdalReader().gdal2ds(r) for r in src_ds_list]
    geotransform = src_ds.GetGeoTransform()
    xres = geotransform[1]
    yres = geotransform[5]
    projection = src_ds.GetProjection()
    nodata = src_ds.GetRasterBand(1).GetNoDataValue()

    # Get common extent
    xmin, xmax, ymin, ymax = GdalReader().get_extent(src_ds)

    bands = src_ds.RasterCount

    for src_i in src_ds_list:

        xmin_i, xmax_i, ymin_i, ymax_i = GdalReader().get_extent(src_i)
        xmax = max(xmax, xmax_i)
        xmin = min(xmin, xmin_i)
        ymax = max(ymax, ymax_i)
        ymin = min(ymin, ymin_i)
        bands = max(bands, src_i.RasterCount)

    # Aligne Pixels
    xmin = math.floor(xmin / xres) * xres
    xmax = math.ceil(xmax / xres) * xres
    ymin = math.floor(ymin / -yres) * -yres
    ymax = math.ceil(ymax / -yres) * -yres

    # Create output if it does not already exist.
    geotransform = [xmin, xres, 0, ymax, 0, yres]
    xsize = int(math.ceil((xmax - xmin) / xres))
    ysize = int(math.ceil((ymin - ymax) / yres))

    # Copy data from source files into output file 1.
    out_array = np.empty((ysize, xsize))
    out_array[:] = np.nan

    borders = []
    for src_i in src_ds_list:
        for band in xrange(1, src_ds.RasterCount + 1):

            geotransform_i = src_i.GetGeoTransform()
            if not int(xres) == int(geotransform_i[1]) or not int(yres) == int(
                    geotransform_i[5]):
                logging.error(
                    'Merge cannot be performed because the layer resolution are different: '
                    + str(xres) + ',' + str(yres) + ' vs. ' +
                    str(geotransform_i[1]) + ',' + str(geotransform_i[5]))

                continue

            xmin_i, xmax_i, ymin_i, ymax_i = GdalReader().get_extent(src_i)
            xoff = int(math.ceil((xmin_i - xmin) / xres))
            yoff = int(math.ceil((ymax_i - ymax) / yres))

            x_size_i = src_i.RasterXSize
            y_size_i = src_i.RasterYSize
            array_i = GdalReader().ds2array(src_i)

            out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i] = array_i

            #slice_i = out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i]
            #out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i] = np.where(
            #    np.ma.getmask(np.ma.masked_invalid(array_i[band - 1])), slice_i, array_i[band - 1])

            # Edges smoothing
            if smooth_edges:
                mask = np.where(
                    np.ma.getmask(np.ma.masked_invalid(array_i[band - 1])),
                    np.nan, 1)

                if smooth_edges:
                    borders_i = [
                        ([i + yoff, j + xoff] if 0 < [
                            mask[i - 1,
                                 j], mask[i + 1,
                                          j], mask[i, j - 1], mask[i, j + 1]
                        ].count(1) < 4 else None) if
                        (1 <= i < mask.shape[0] - 1) and
                        (1 <= j < mask.shape[1] - 1) else None
                        # ([i+yoff, j+xoff] if mask[i, j] == 1 else None)
                        for i, j in np.ndindex(mask.shape)
                    ]
                    borders = borders + borders_i

    # Edges smoothing
    if smooth_edges:
        for k in borders:
            if k:
                out_array[k[0],
                          k[1]] = np.nanmean(out_array[k[0] - 1:k[0] + 1,
                                                       k[1] - 1:k[1] + 1])

    return GdalReader().array2ds(src_array=out_array,
                                 output=outname,
                                 projection=projection,
                                 geotransform=geotransform,
                                 nodata=nodata)