예제 #1
0
    def NDSI(self, inFile_):
        """
        Program description: 
        Normalized-Difference Snow Index (NDSI)

        INPUT_PARAMETERS:
        inputValue_      - 

        COMMENTS:
        """

        try:

            pB2 = inFile_.GetRasterBand(2)
            pB5 = inFile_.GetRasterBand(5)

            #Read the bands of the dataset into numpy arrays
            pB2numpy = np.float32(gdalnumeric.BandReadAsArray(pB2))
            pB5numpy = np.float32(gdalnumeric.BandReadAsArray(pB5))

            #Calculation in numpy
            pNum = np.subtract(pB2numpy, pB5numpy)
            pDenom = np.add(pB2numpy, pB5numpy)
            pNDSI = np.divide(pNum, pDenom)

        except Exception:
            raise Exception("Error: Error in calculating NDSI")

        return pNDSI
예제 #2
0
def raster2array(raster, dim_ordering="channels_last", dtype='float32'):
    '''
    Modified from: https://gis.stackexchange.com/a/283207
    '''
    bands = [raster.GetRasterBand(i) for i in range(1, raster.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands]).astype(dtype)
    return arr
예제 #3
0
def gdal_convert(inFolder, outFolder, inType, outType):
    """
    Converts geotiffs and erdas imagine images to .tif,.jpg, .png, or .img
    inputs:
    inFolder (string): folder of .tif or .img images
    outFolder (string): folder to save result to
    inType (string): extension of input images ('.tif' or '.img')
    outType (string): extension of output images ('.tif', '.img', '.jpg', '.png')
    """

    for im in glob.glob(inFolder + '/*' + inType):
        print('in: ' + im)
        imName = os.path.splitext(os.path.basename(im))[0]
        outIm = os.path.join(outFolder, imName + outType)
        print('out: ' + outIm)
        if outType == '.npy':
            raster = gdal.Open(im)
            bands = [
                raster.GetRasterBand(i)
                for i in range(1, raster.RasterCount + 1)
            ]
            arr = np.array([gdn.BandReadAsArray(band)
                            for band in bands]).astype('float32')
            arr = np.transpose(arr, [1, 2, 0])
            np.save(outIm, arr)
        else:
            raster = gdal.Open(im)
            gdal.Translate(outIm, raster)
            raster = None
예제 #4
0
def read_tif(tif, band=1, nodata=0):
    """reads in the a tif, the specified band or all bands
        band default is 1 
        if you read in on band the return is a 2d array
        if band is set to 'all', it will return a 3d array (bands, x, y)"""
    try:
        #default band is 1 and default for return nodata value is False ~ 0 ;1 ~ True
        inTif = zz_gdalnum.gdal.Open(tif, zz_gdalcon.GA_ReadOnly)
        if type(inTif) != 'NoneType':
            #test if passed band is in the raster
            nr_of_bands = inTif.RasterCount
            if band > nr_of_bands and band != 'all':
                raise NameError(
                    'band not in file max Nr. of bands: {0}'.format(
                        nr_of_bands))
            if band == 'all':
                #create a 3d stack of the data (band, x, y)
                bands = inTif.GetRasterBand(1)
                data = zz_gdalnum.BandReadAsArray(bands)
                y, x = data.shape
                shape = (1, y, x)
                data = data.reshape(shape)
                for b in range(2, nr_of_bands):
                    bands = inTif.GetRasterBand(b)
                    data = np.vstack(
                        (data,
                         zz_gdalnum.BandReadAsArray(bands).reshape(shape)))
            else:

                band = inTif.GetRasterBand(band)
                data = zz_gdalnum.BandReadAsArray(band)
                inTif = None

            if type(data) == None.__class__:
                raise
            else:
                if nodata == 0:
                    return data
                elif nodata == 1:
                    noda = band.GetNoDataValue()
                    return data, noda
        else:
            raise NameError('input is not a file or file is broken')
    except:
        print "Error:", sys.exc_info()[:2]
        inTif = None
        raise
예제 #5
0
def raster_2_array(raster_full_path):
    """Read a raster dem as array
    """
    data_set = gdal.Open(raster_full_path)
    data_set_band = data_set.GetRasterBand(1)
    raster_array = gnum.BandReadAsArray(data_set_band)
    no_data_value = data_set_band.GetNoDataValue()
    
    return raster_array, no_data_value
예제 #6
0
def img_to_array(input_file, dim_ordering="channels_last", dtype='uint32'):
    #https://gis.stackexchange.com/questions/32995/fully-load-raster-into-a-numpy-array/33070
    file = gdal.Open(input_file, gdal.GA_ReadOnly)
    bands = [file.GetRasterBand(i) for i in range(1, file.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands]).astype(dtype)
    if dim_ordering == "channels_last":
        arr = np.transpose(
            arr, [1, 2, 0])  # Reorders dimensions, so that channels are last
    return arr
def img_to_array(tif_path, dtype='float32'):
    """
    Returns numpy array of the input tif_path.
    """
    file = gdal.Open(tif_path)
    bands = [file.GetRasterBand(i) for i in range(1, file.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands]).astype(dtype)
    arr = np.transpose(
        arr, [1, 2, 0])  # Reordering dimensions, so that channels are last
    return arr
예제 #8
0
def isothermal():
    alpha = -0.0055182680606
    beta = 28.2088488402
    raster_filename = '../data/SRTM_Bog_DEM.tif'
    raster = gdal.Open(raster_filename)
    trans_data = raster.GetGeoTransform()
    band = raster.GetRasterBand(1)
    no_data_value = band.GetNoDataValue()

    output = gdalnumeric.BandReadAsArray(band) * alpha + beta
    pd.DataFrame(output).to_clipboard()
    pass
예제 #9
0
 def read_data(inTif, band_nr, nodata=0):
     band = inTif.GetRasterBand(band_nr)
     data = zz_gdalnum.BandReadAsArray(band)
     inTif = None
     if type(data)==None.__class__:
         raise
     else:
         if nodata==0:
             return data
         elif nodata==1:
             noda = band.GetNoDataValue()
             return data, noda
def img_to_array(input_file, dtype='uint16'):   ###reads multiband image as ndarray
    #specify band list - indices of each band# you want to open as multiband array 
    #not specifying band list opens all bands into an array 
    #returns wavelengths only when header is available for image 

    file  = gdal.Open(input_file)
    bands = [file.GetRasterBand(i) for i in range(1, file.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands]).astype(dtype) 
    #geotransform = file.GetGeoTransform()
    #spatialreference = file.GetProjection()

    #sometimes single band images have shape of length 2- reshape to (bands, rows, cols) to be consistent
    if len(arr.shape) == 2:  
        arr = np.reshape(arr, (1, arr.shape[0], arr.shape[1]))
    
    return arr
예제 #11
0
    def get_raster_attribute(self, attribute, **kwargs):
        raster = gdal.DEMProcessing('',
                                    self.file,
                                    attribute,
                                    format='MEM',
                                    **kwargs)
        raster_band = raster.GetRasterBand(1)
        raster_values = np.ma.masked_values(
            gdalnumeric.BandReadAsArray(raster_band),
            raster_band.GetNoDataValue(),
            copy=False)

        del raster
        del raster_band

        return raster_values
예제 #12
0
    def copy_into(self, output_file, source_band=1, target_band=1):
        """
        Copy data to target file and filter according to the type given in
        the initializer.

        output_file -- gdal.Dataset object for the file into which some or all
        of this file may be copied.
        """
        t_geotransform = output_file.GetGeoTransform()
        t_ulx = t_geotransform[0]
        t_uly = t_geotransform[3]
        t_pixel_width = t_geotransform[1]
        t_pixel_height = t_geotransform[5]

        # Intersection region
        tgw_ulx = max(t_ulx, self.ulx)
        if t_pixel_height < 0:
            tgw_uly = min(t_uly, self.uly)
        else:
            tgw_uly = max(t_uly, self.uly)

        # Target window in pixel coordinates.
        tw_xoff = int((tgw_ulx - t_ulx) / t_pixel_width + 0.1)
        tw_yoff = int((tgw_uly - t_uly) / t_pixel_height + 0.1)

        source_file = gdal.Open(self.filename, gdalconst.GA_ReadOnly)

        target_band = output_file.GetRasterBand(target_band)

        source_values = gdalnumeric.BandReadAsArray(
            source_file.GetRasterBand(source_band),
            buf_type=gdal.GDT_Float32
        )

        no_data_value = target_band.GetNoDataValue()
        # Filter by upper and lower band threshold values
        source_values[source_values < self.lower_limit] = no_data_value
        source_values[source_values > self.upper_limit] = no_data_value

        gdalnumeric.BandWriteArray(
            target_band, source_values, xoff=tw_xoff, yoff=tw_yoff
        )

        del source_values
        del source_file
예제 #13
0
    def __copy_band_data(self):
        target_band = self.output_file.GetRasterBand(self.BAND_NUMBER)
        target_band.SetNoDataValue(self.BAND_NO_DATA_VALUE)

        source_values = gdalnumeric.BandReadAsArray(
            self.mosaic_vrt.GetRasterBand(self.BAND_NUMBER),
            buf_type=self.BAND_DATA_TYPE,
        )

        # Filter by upper and lower band threshold values
        source_values[(source_values < self.lower_limit) | (
            source_values > self.upper_limit)] = self.BAND_NO_DATA_VALUE

        gdalnumeric.BandWriteArray(target_band, source_values)
        target_band.FlushCache()
        target_band.SetMetadata(self.BAND_METADATA[self.source_type])

        del target_band
        del source_values
예제 #14
0
def img_to_array(input_file, dim_ordering="channels_last", dtype='float32'):
    """
    Loads multi-spectral raster to numpy array using gdal.
    Based on: https://gis.stackexchange.com/questions/32995/fully-load-raster-into-a-numpy-array

    Parameters:
    input_file (tiff): multi-spectral raster
    dim_ordering (string): reorders dimensions, so that channels are last

    Returns:
    arr (ndarray): 2D array
    """

    file  = gdal.Open(input_file)
    bands = [file.GetRasterBand(i) for i in range(1, file.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands])

    if dim_ordering=="channels_last":
        arr = np.transpose(arr, [1, 2, 0])  # Reorders dimensions, so that channels are last

    return arr
예제 #15
0
파일: utils.py 프로젝트: dtheo91/simclr
def img_to_array(input_file, dim_ordering="HWC", dtype='float32', band_mapping=None, return_extent=False):
    """Reads an image from disk and returns it as numpy array.

    Args:
        input_file: Path to the input file.
        dim_ordering: One of HWC or CHW, C=Channels, H=Height, W=Width
        dtype: Desired data type for loading, e.g. np.uint8, np.float32...
        band_mapping: Dictionary of which image band to load into which array band. E.g. {1:0, 3:1}
        return_extent: Whether or not to return the raster extent in the form (ymin, ymax, xmin, xmax). Defaults to False.

    Returns:
        Numpy array containing the image and optionally the extent.
    """
    ds = gdal.Open(input_file)
    extent = get_map_extent(ds)

    if band_mapping is None:
        num_bands = ds.RasterCount
        band_mapping = {i+1: i for i in range(num_bands)}
    elif isinstance(band_mapping, dict):
        num_bands = len(band_mapping)
    else:
        raise TypeError("band_mapping must be a dict, not {}.".format(type(band_mapping)))

    arr = np.empty((num_bands, ds.RasterYSize, ds.RasterXSize), dtype=dtype)

    for source_layer, target_layer in band_mapping.items():
        arr[target_layer] = gdn.BandReadAsArray(ds.GetRasterBand(source_layer))

    if dim_ordering == "HWC":
        arr = np.transpose(arr, (1, 2, 0))  # Reorders dimensions, so that channels are last
    elif dim_ordering == "CHW":
        pass
    else:
        raise ValueError("Dim ordering {} not supported. Choose one of 'HWC' or 'CHW'.".format(dim_ordering))

    if return_extent:
        return arr, extent
    else:
        return arr
예제 #16
0
    def __init__(self, source_folder, source_type):
        self.filename = self.get_file_name(source_type)
        file = gdal.Open(os.path.join(source_folder, self.filename))

        self.bands = file.RasterCount
        _raster_band = file.GetRasterBand(1)
        self.band_type = _raster_band.DataType
        self.no_data_value = _raster_band.GetNoDataValue()
        self.band_values = gdalnumeric.BandReadAsArray(_raster_band)

        _projection = osr.SpatialReference(wkt=file.GetProjection())
        self.projection = _projection.GetAttrValue('geogcs')

        self.xsize = file.RasterXSize
        self.ysize = file.RasterYSize
        _geo_transform = file.GetGeoTransform()
        self.ulx = _geo_transform[0]
        self.uly = _geo_transform[3]
        self.pixel_width = _geo_transform[1]
        self.pixel_height = _geo_transform[5]

        del file
예제 #17
0
    def band_values(self, **kwargs):
        """
        Method to read band from arguments or from initialized raster.
        Will mask values defined in the band NoDataValue and store this mask
        with the `current_mask` property if the band is the same as the
        initialized one.

        :param kwargs:
            'band_number': band_number to read instead of the one given with
                           the initialize call.

        :return: Numpy masked array
        """
        band_number = kwargs.get('band_number', self.band_number)

        band = self.file.GetRasterBand(band_number)
        values = np.ma.masked_values(gdalnumeric.BandReadAsArray(band),
                                     band.GetNoDataValue(),
                                     copy=False)

        del band
        return values
예제 #18
0
    def run(self):

        self._abort = False

        self.progress.emit("Starting RasterBender", float(0), float(0))

        #####################################
        # Step 1 : create the delaunay mesh #
        #####################################

        self.progress.emit("Loading delaunay mesh...", float(0), float(0))

        # Create the delaunay triangulation
        triangles, pointsA, pointsB, hull, constraints = triangulate.triangulate(
            self.pairsLayer, self.pairsLimitToSelection, self.constraintsLayer,
            self.constraintsLimitToSelection, self.bufferValue)

        ###############################
        # Step 2. Opening the dataset #
        ###############################

        self.progress.emit(
            "Opening the dataset... This shouldn't be too long...", float(0),
            float(0))

        #Open the dataset
        gdal.UseExceptions()

        # Read the source data into numpy arrays
        dsSource = gdal.Open(self.sourcePath, gdal.GA_ReadOnly)

        sourceDataR = gdalnumeric.BandReadAsArray(dsSource.GetRasterBand(1))
        sourceDataG = gdalnumeric.BandReadAsArray(dsSource.GetRasterBand(2))
        sourceDataB = gdalnumeric.BandReadAsArray(dsSource.GetRasterBand(3))

        # Get the transformation
        pixW = float(dsSource.RasterXSize - 1)  #width in pixel
        pixH = float(dsSource.RasterYSize - 1)  #width in pixel
        mapW = float(dsSource.RasterXSize) * dsSource.GetGeoTransform()[
            1]  #width in map units
        mapH = float(dsSource.RasterYSize) * dsSource.GetGeoTransform()[
            5]  #width in map units
        offX = dsSource.GetGeoTransform()[0]  #offset in map units
        offY = dsSource.GetGeoTransform()[3]  #offset in map units

        # Open the target into numpy array
        #dsTarget = gdal.Open(self.targetPath, gdal.GA_Update )
        driver = gdal.GetDriverByName("GTiff")
        dsTarget = driver.CreateCopy(self.targetPath, dsSource, 0)
        #dsTarget.SetGeoTransform( dsSource.GetGeoTransform() )
        dsTarget = None  #close

        def xyToQgsPoint(x, y):
            return QgsPoint(offX + mapW * (x / pixW), offY + mapH * (y / pixH))

        def qgsPointToXY(qgspoint):
            return (int((qgspoint.x() - offX) / mapW * pixW),
                    int((qgspoint.y() - offY) / mapH * pixH))

        #######################################
        # Step 3A. Looping through the blocks #
        #######################################

        #Loop through every block
        blockCountX = dsSource.RasterXSize // self.blockSize + 1
        blockCountY = dsSource.RasterYSize // self.blockSize + 1
        blockCount = blockCountX * blockCountY
        blockI = 0

        displayTotal = dsSource.RasterXSize * dsSource.RasterYSize
        displayStep = min((self.blockSize**2) / 20,
                          10000)  # update gui every n steps

        self.progress.emit("Starting computation... This can take a while...",
                           float(0), float(0))

        for blockNumY in range(0, blockCountY):
            blockOffsetY = blockNumY * self.blockSize
            blockH = min(self.blockSize, dsSource.RasterYSize - blockOffsetY)
            if blockH <= 0: continue

            for blockNumX in range(0, blockCountX):
                blockOffsetX = blockNumX * self.blockSize
                blockW = min(self.blockSize,
                             dsSource.RasterXSize - blockOffsetX)
                if blockW <= 0: continue

                blockI += 1
                pixelCount = blockW * blockH
                pixelI = 0

                blockRectangle = QgsRectangle(
                    xyToQgsPoint(blockOffsetX, blockOffsetY),
                    xyToQgsPoint(blockOffsetX + blockW, blockOffsetY + blockH)
                )  # this is the shape of the block, used for optimization

                # We check if the block intersects the hull, if not, we skip it
                if not hull.intersects(blockRectangle):
                    self.progress.emit(
                        "Block %i out of %i is out of the convex hull, we skip it..."
                        % (blockI, blockCount), float(0),
                        float(blockI / float(blockCount)))
                    continue

                # We create the trifinder for the block
                blockTrifinder = trifinder.Trifinder(pointsB, triangles,
                                                     blockRectangle)

                targetDataR = gdalnumeric.BandReadAsArray(
                    dsSource.GetRasterBand(1), blockOffsetX, blockOffsetY,
                    blockW, blockH)
                targetDataG = gdalnumeric.BandReadAsArray(
                    dsSource.GetRasterBand(2), blockOffsetX, blockOffsetY,
                    blockW, blockH)
                targetDataB = gdalnumeric.BandReadAsArray(
                    dsSource.GetRasterBand(3), blockOffsetX, blockOffsetY,
                    blockW, blockH)

                #######################################
                # Step 3B. Looping through the pixels #
                #######################################

                # Loop through every pixel
                for y in range(0, blockH):
                    for x in range(0, blockW):
                        # If abort was called, we finish the process
                        if self._abort:
                            self.error.emit(
                                "Aborted on pixel %i out of %i on block %i out of %i..."
                                % (pixelI, pixelCount, blockI, blockCount),
                                float(0), float(0))
                            return

                        pixelI += 1

                        # Ever now and then, we update the status
                        if pixelI % displayStep == 0:
                            self.progress.emit(
                                "Working on pixel %i out of %i on block %i out of %i... Trifinder has %i triangles"
                                % (pixelI, pixelCount, blockI, blockCount,
                                   len(blockTrifinder.triangles)),
                                float(pixelI) / float(pixelCount),
                                float(blockI) / float(blockCount))

                        # We find in which triangle the point lies using the trifinder.
                        p = xyToQgsPoint(blockOffsetX + x, blockOffsetY + y)
                        tri = blockTrifinder.find(p)
                        if tri is None:
                            # If it's in no triangle, we don't change it
                            continue

                        # If it's in a triangle, we transform the coordinates
                        newP = trimapper.map(p, pointsB[tri[0]],
                                             pointsB[tri[1]], pointsB[tri[2]],
                                             pointsA[tri[0]], pointsA[tri[1]],
                                             pointsA[tri[2]])

                        newX, newY = qgsPointToXY(newP)

                        # TODO : this would maybe get interpolated results
                        #ident = sourceRaster.dataProvider().identify( pt, QgsRaster.IdentifyFormatValue)
                        #targetDataR[y][x] = ident.results()[1]
                        #targetDataG[y][x] = ident.results()[2]
                        #targetDataB[y][x] = ident.results()[3]

                        try:
                            if newY < 0 or newX < 0:
                                raise IndexError()  #avoid looping
                            targetDataR[y][x] = sourceDataR[newY][newX]
                            targetDataG[y][x] = sourceDataG[newY][newX]
                            targetDataB[y][x] = sourceDataB[newY][newX]
                        except IndexError, e:
                            targetDataR[y][x] = 0
                            targetDataG[y][x] = 0
                            targetDataB[y][x] = 0

                # Write to the image

                dsTarget = gdal.Open(self.targetPath, gdal.GA_Update)

                gdalnumeric.BandWriteArray(dsTarget.GetRasterBand(1),
                                           targetDataR, blockOffsetX,
                                           blockOffsetY)
                gdalnumeric.BandWriteArray(dsTarget.GetRasterBand(2),
                                           targetDataG, blockOffsetX,
                                           blockOffsetY)
                gdalnumeric.BandWriteArray(dsTarget.GetRasterBand(3),
                                           targetDataB, blockOffsetX,
                                           blockOffsetY)

                dsTarget = None
def createDistanceTransform(rasterSrc,
                            vectorSrc,
                            npDistFileName='',
                            units='pixels'):

    ## open source vector file that truth data
    source_ds = ogr.Open(vectorSrc)
    source_layer = source_ds.GetLayer()

    ## extract data from src Raster File to be emulated
    ## open raster file that is to be emulated
    srcRas_ds = gdal.Open(rasterSrc)
    cols = srcRas_ds.RasterXSize
    rows = srcRas_ds.RasterYSize
    noDataValue = 0

    if units == 'meters':
        geoTrans, poly, ulX, ulY, lrX, lrY = gT.getRasterExtent(srcRas_ds)
        transform_WGS84_To_UTM, transform_UTM_To_WGS84, utm_cs = gT.createUTMTransform(
            poly)
        line = ogr.Geometry(ogr.wkbLineString)
        line.AddPoint(geoTrans[0], geoTrans[3])
        line.AddPoint(geoTrans[0] + geoTrans[1], geoTrans[3])

        line.Transform(transform_WGS84_To_UTM)
        metersIndex = line.Length()
    else:
        metersIndex = 1

    ## create First raster memory layer
    memdrv = gdal.GetDriverByName('MEM')
    dst_ds = memdrv.Create('', cols, rows, 1, gdal.GDT_Byte)
    dst_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    dst_ds.SetProjection(srcRas_ds.GetProjection())
    band = dst_ds.GetRasterBand(1)
    band.SetNoDataValue(noDataValue)

    gdal.RasterizeLayer(dst_ds, [1], source_layer, burn_values=[255])
    srcBand = dst_ds.GetRasterBand(1)

    memdrv2 = gdal.GetDriverByName('MEM')
    prox_ds = memdrv2.Create('', cols, rows, 1, gdal.GDT_Int16)
    prox_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    prox_ds.SetProjection(srcRas_ds.GetProjection())
    proxBand = prox_ds.GetRasterBand(1)
    proxBand.SetNoDataValue(noDataValue)
    options = ['NODATA=0']

    ##compute distance to non-zero pixel values and scrBand and store in proxBand
    gdal.ComputeProximity(srcBand, proxBand, options)

    memdrv3 = gdal.GetDriverByName('MEM')
    proxIn_ds = memdrv3.Create('', cols, rows, 1, gdal.GDT_Int16)
    proxIn_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    proxIn_ds.SetProjection(srcRas_ds.GetProjection())
    proxInBand = proxIn_ds.GetRasterBand(1)
    proxInBand.SetNoDataValue(noDataValue)
    options = ['NODATA=0', 'VALUES=0']

    ##compute distance to zero pixel values and scrBand and store in proxInBand
    gdal.ComputeProximity(srcBand, proxInBand, options)

    proxIn = gdalnumeric.BandReadAsArray(proxInBand)
    proxOut = gdalnumeric.BandReadAsArray(proxBand)

    ##distance tranform is the distance to zero pixel values minus distance to non-zero pixel values
    proxTotal = proxIn.astype(float) - proxOut.astype(float)
    proxTotal = proxTotal * metersIndex

    if npDistFileName != '':
        np.save(npDistFileName, proxTotal)

    return proxTotal
def createDistanceTransformByFeatureIndex(feature_index,
                                          rasterSrc,
                                          vectorSrc,
                                          npDistFileName='',
                                          units='pixels'):
    ## open source vector file that truth data
    source_ds = ogr.Open(vectorSrc)
    source_layer = source_ds.GetLayer()

    #Define feature
    my_feature = source_layer[feature_index]

    #Spatial Reference
    srs = source_layer.GetSpatialRef()

    #Create feature Layer
    outDriver = ogr.GetDriverByName('MEMORY')
    outDataSource = outDriver.CreateDataSource('memData')
    Feature_Layer = outDataSource.CreateLayer("this_feature",
                                              srs,
                                              geom_type=ogr.wkbPolygon)

    #Add feature to layer
    Feature_Layer.CreateFeature(my_feature)

    ## extract data from src Raster File to be emulated
    ## open raster file that is to be emulated
    srcRas_ds = gdal.Open(rasterSrc)
    cols = srcRas_ds.RasterXSize
    rows = srcRas_ds.RasterYSize
    noDataValue = 0
    metersIndex = 1

    ## create First raster memory layer
    memdrv = gdal.GetDriverByName('MEM')
    dst_ds = memdrv.Create('', cols, rows, 1, gdal.GDT_Byte)
    dst_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    dst_ds.SetProjection(srcRas_ds.GetProjection())
    band = dst_ds.GetRasterBand(1)
    band.SetNoDataValue(noDataValue)

    gdal.RasterizeLayer(dst_ds, [1], Feature_Layer, burn_values=[255])
    srcBand = dst_ds.GetRasterBand(1)

    memdrv2 = gdal.GetDriverByName('MEM')
    prox_ds = memdrv2.Create('', cols, rows, 1, gdal.GDT_Int16)
    prox_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    prox_ds.SetProjection(srcRas_ds.GetProjection())
    proxBand = prox_ds.GetRasterBand(1)
    proxBand.SetNoDataValue(noDataValue)

    options = ['NODATA=0']

    gdal.ComputeProximity(srcBand, proxBand, options)

    memdrv3 = gdal.GetDriverByName('MEM')
    proxIn_ds = memdrv3.Create('', cols, rows, 1, gdal.GDT_Int16)
    proxIn_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    proxIn_ds.SetProjection(srcRas_ds.GetProjection())
    proxInBand = proxIn_ds.GetRasterBand(1)
    proxInBand.SetNoDataValue(noDataValue)
    options = ['NODATA=0', 'VALUES=0']
    gdal.ComputeProximity(srcBand, proxInBand, options)

    proxIn = gdalnumeric.BandReadAsArray(proxInBand)
    proxOut = gdalnumeric.BandReadAsArray(proxBand)

    proxTotal = proxIn.astype(float) - proxOut.astype(float)
    proxTotal = proxTotal * metersIndex

    if npDistFileName != '':
        np.save(npDistFileName, proxTotal)

    return proxTotal
예제 #21
0
     if (tilesy*ybs!=ysize): tilesy=tilesy+1
     
     t1=time.time()
     
     tread[nthread-1]+=t1-t0
     
     for itx in range(0,tilesx*xbs,xbs):
         for ity in range(0,tilesy*ybs,ybs):
             _xbs=xbs if itx+xbs<xsize else xsize-itx
             _ybs=ybs if ity+ybs<ysize else ysize-ity
             
             t2=time.time()
             
             red_array = gdalnumeric.BandReadAsArray(red_band, 
                 xoff=itx,
                 yoff=ity,
                 win_xsize=_xbs,
                 win_ysize=_ybs,
                 buf_type=gdalconst.GDT_UInt16)
 
             t3=time.time()
 
             ndvi_array = red_array*0.5 
             
             ndvi_band.WriteArray(ndvi_array, xoff=itx, yoff=ity)
 
             ndvi_array = None
 
             t4=time.time()
             
             tread[nthread-1]+=t3-t2
             tprocess[nthread-1]+=t4-t3
예제 #22
0
def create_dist_map(rasterSrc,
                    vectorSrc,
                    npDistFileName='',
                    noDataValue=0,
                    burn_values=1,
                    dist_mult=1,
                    vmax_dist=64):
    '''
    Create building signed distance transform from Yuan 2016 
    (https://arxiv.org/pdf/1602.06564v1.pdf).
    vmax_dist: absolute value of maximum distance (meters) from building edge
    Adapted from createNPPixArray in labeltools
    '''

    ## open source vector file that truth data
    source_ds = ogr.Open(vectorSrc)
    source_layer = source_ds.GetLayer()

    ## extract data from src Raster File to be emulated
    ## open raster file that is to be emulated
    srcRas_ds = gdal.Open(rasterSrc)
    cols = srcRas_ds.RasterXSize
    rows = srcRas_ds.RasterYSize

    geoTrans, poly, ulX, ulY, lrX, lrY = gT.getRasterExtent(srcRas_ds)
    transform_WGS84_To_UTM, transform_UTM_To_WGS84, utm_cs \
                                        = gT.createUTMTransform(poly)
    line = ogr.Geometry(ogr.wkbLineString)
    line.AddPoint(geoTrans[0], geoTrans[3])
    line.AddPoint(geoTrans[0] + geoTrans[1], geoTrans[3])

    line.Transform(transform_WGS84_To_UTM)
    metersIndex = line.Length()

    memdrv = gdal.GetDriverByName('MEM')
    dst_ds = memdrv.Create('', cols, rows, 1, gdal.GDT_Byte)
    dst_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    dst_ds.SetProjection(srcRas_ds.GetProjection())
    band = dst_ds.GetRasterBand(1)
    band.SetNoDataValue(noDataValue)

    gdal.RasterizeLayer(dst_ds, [1], source_layer, burn_values=[burn_values])
    srcBand = dst_ds.GetRasterBand(1)

    memdrv2 = gdal.GetDriverByName('MEM')
    prox_ds = memdrv2.Create('', cols, rows, 1, gdal.GDT_Int16)
    prox_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    prox_ds.SetProjection(srcRas_ds.GetProjection())
    proxBand = prox_ds.GetRasterBand(1)
    proxBand.SetNoDataValue(noDataValue)

    opt_string = 'NODATA=' + str(noDataValue)
    options = [opt_string]

    gdal.ComputeProximity(srcBand, proxBand, options)

    memdrv3 = gdal.GetDriverByName('MEM')
    proxIn_ds = memdrv3.Create('', cols, rows, 1, gdal.GDT_Int16)
    proxIn_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    proxIn_ds.SetProjection(srcRas_ds.GetProjection())
    proxInBand = proxIn_ds.GetRasterBand(1)
    proxInBand.SetNoDataValue(noDataValue)
    opt_string2 = 'VALUES=' + str(noDataValue)
    options = [opt_string, opt_string2]
    #options = ['NODATA=0', 'VALUES=0']

    gdal.ComputeProximity(srcBand, proxInBand, options)

    proxIn = gdalnumeric.BandReadAsArray(proxInBand)
    proxOut = gdalnumeric.BandReadAsArray(proxBand)

    proxTotal = proxIn.astype(float) - proxOut.astype(float)
    proxTotal = proxTotal * metersIndex
    proxTotal *= dist_mult

    # clip array
    proxTotal = np.clip(proxTotal, -1 * vmax_dist, 1 * vmax_dist)

    if npDistFileName != '':
        # save as numpy file since some values will be negative
        np.save(npDistFileName, proxTotal)
        #cv2.imwrite(npDistFileName, proxTotal)

    return proxTotal
def extract(raster_in, mask, class_nb, class_names, out_file_pickle,
            out_file_csv):
    """
    Extract values from raster file. Saves into csv and pickle file.

    raster_in: in raster to extract values
    mask: mask with rasterised training data
    class_nb: number of classes to extract values
    class_names: class names to extract values
    out_file_csv: output csv
    out_file_pickle: output pickle
    """
    drivers_raster = gdal.GetDriverByName('ENVI')
    drivers_raster.Register()

    raster = gdal.Open(raster_in, gdalconst.GA_ReadOnly)

    inmask = gdal.Open(mask, gdalconst.GA_ReadOnly)
    band_mask = inmask.GetRasterBand(2)
    data_mask = band_mask.ReadAsArray(0, 0)

    coords = np.nonzero(data_mask)
    new_coords = np.array([0, 0])
    for i in range(len(coords[0])):  # reads coordinates from input raster
        m = np.array([coords[0][i], coords[1][i]])
        new_coords = np.vstack((new_coords, m))

    np.delete(new_coords, 0, 0)  # removers first empty row

    pixel_class = ([data_mask[x, y] for x, y in new_coords])
    px_vals = [[] for x in range(class_nb)]
    for nb, x in enumerate(pixel_class):
        px_vals[x - 1].append(new_coords[nb])

    data = []
    band_mask_index = inmask.GetRasterBand(1)

    for nb, class_nb in enumerate(px_vals):
        coord_list_class = px_vals[nb]
        class_id = nb + 1
        for counter, i in enumerate(coord_list_class):
            x, y = int(i[0]), int(i[1])
            bands = [
                raster.GetRasterBand(i)
                for i in range(1, raster.RasterCount + 1)
            ]
            pix_val = np.squeeze(
                np.array([
                    gdalnumeric.BandReadAsArray(band, y, x, 1, 1)
                    for band in bands
                ]).astype('int64'))
            pixel_extract = [x] + [y] + [pix_val] + ['{0}'.format(class_names[class_id])] + \
                            [int(band_mask_index.ReadAsArray(y, x, 1, 1))]
            data.append(pixel_extract)
            print('extracted', round((counter + 1) / len(coord_list_class), 2),
                  '% form class {0}'.format(class_names[class_id]))

    # cleaning data
    x = [x[0] for x in data]
    y = [x[1] for x in data]
    values = [x[2] for x in data]
    class_name = [x[3] for x in data]
    index = [x[4] for x in data]

    df = pd.DataFrame(
        list(zip(x, y, values, class_name, index)),
        columns=['x', 'y', 'coordinates', 'values', 'class', 'index'])

    print(df.loc[:, 'class'].value_counts())
    df.to_csv(out_file_csv)
    df.to_pickle(out_file_pickle)
    print('done!')
예제 #24
0
def create_dist_map(rasterSrc, vectorSrc, npDistFileName='',
                           noDataValue=0, burn_values=255,
                           dist_mult=1, vmax_dist=64):

    source_ds = ogr.Open(vectorSrc)
    source_layer = source_ds.GetLayer()

    srcRas_ds = gdal.Open(rasterSrc)
    cols = srcRas_ds.RasterXSize
    rows = srcRas_ds.RasterYSize

    geoTrans, poly, ulX, ulY, lrX, lrY = gT.getRasterExtent(srcRas_ds)
    transform_WGS84_To_UTM, transform_UTM_To_WGS84, utm_cs \
                                        = gT.createUTMTransform(poly)
    line = ogr.Geometry(ogr.wkbLineString)
    line.AddPoint(geoTrans[0], geoTrans[3])
    line.AddPoint(geoTrans[0]+geoTrans[1], geoTrans[3])

    line.Transform(transform_WGS84_To_UTM)
    metersIndex = line.Length()

    memdrv = gdal.GetDriverByName('MEM')
    dst_ds = memdrv.Create('', cols, rows, 1, gdal.GDT_Byte)
    dst_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    dst_ds.SetProjection(srcRas_ds.GetProjection())
    band = dst_ds.GetRasterBand(1)
    band.SetNoDataValue(noDataValue)

    gdal.RasterizeLayer(dst_ds, [1], source_layer, burn_values=[burn_values])
    srcBand = dst_ds.GetRasterBand(1)

    memdrv2 = gdal.GetDriverByName('MEM')
    prox_ds = memdrv2.Create('', cols, rows, 1, gdal.GDT_Int16)
    prox_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    prox_ds.SetProjection(srcRas_ds.GetProjection())
    proxBand = prox_ds.GetRasterBand(1)
    proxBand.SetNoDataValue(noDataValue)

    opt_string = 'NODATA='+str(noDataValue)
    options = [opt_string]

    gdal.ComputeProximity(srcBand, proxBand, options)

    memdrv3 = gdal.GetDriverByName('MEM')
    proxIn_ds = memdrv3.Create('', cols, rows, 1, gdal.GDT_Int16)
    proxIn_ds.SetGeoTransform(srcRas_ds.GetGeoTransform())
    proxIn_ds.SetProjection(srcRas_ds.GetProjection())
    proxInBand = proxIn_ds.GetRasterBand(1)
    proxInBand.SetNoDataValue(noDataValue)
    opt_string2 = 'VALUES='+str(noDataValue)
    options = [opt_string, opt_string2]

    gdal.ComputeProximity(srcBand, proxInBand, options)

    proxIn = gdalnumeric.BandReadAsArray(proxInBand)
    proxOut = gdalnumeric.BandReadAsArray(proxBand)

    proxTotal = proxIn.astype(float) - proxOut.astype(float)
    proxTotal = proxTotal*metersIndex
    proxTotal *= dist_mult

    proxTotal = np.clip(proxTotal, -1*vmax_dist, 1*vmax_dist)

    if npDistFileName != '':
        np.save(npDistFileName, proxTotal)
예제 #25
0
def img_to_array(input_file, dim_ordering="channels_last", dtype='float32':
    """
    Loads multi-spectral raster to numpy array using gdal.

    Parameters:
    input_file (tiff): multi-spectral raster
    dim_ordering (string): reorders dimensions, so that channels are last

    Returns:
    arr (ndarray): 2D array
    """

    file  = gdal.Open(input_file)
    bands = [file.GetRasterBand(i) for i in range(1, file.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands])

    if dim_ordering=="channels_last":
        arr = np.transpose(arr, [1, 2, 0])  # Reorders dimensions, so that channels are last

    return arr

def labels_to_array(input_file):
    """ Loads geotif labels to numpy array """

    labels = Image.open(input_file)
    arr = np.array(labels)

    return arr

예제 #26
0
def doit(opts, args):
    # pylint: disable=unused-argument

    if opts.debug:
        print("gdal_calc.py starting calculation %s" % (opts.calc))

    # set up global namespace for eval with all functions of gdalnumeric
    global_namespace = dict([(key, getattr(gdalnumeric, key))
                             for key in dir(gdalnumeric) if not key.startswith('__')])

    if not opts.calc:
        raise Exception("No calculation provided.")
    elif not opts.outF:
        raise Exception("No output file provided.")

    if opts.format is None:
        opts.format = GetOutputDriverFor(opts.outF)

    ################################################################
    # fetch details of input layers
    ################################################################

    # set up some lists to store data for each band
    myFiles = []
    myBands = []
    myAlphaList = []
    myDataType = []
    myDataTypeNum = []
    myNDV = []
    DimensionsCheck = None

    # loop through input files - checking dimensions
    for myI, myF in opts.input_files.items():
        if not myI.endswith("_band"):
            # check if we have asked for a specific band...
            if "%s_band" % myI in opts.input_files:
                myBand = opts.input_files["%s_band" % myI]
            else:
                myBand = 1

            myFile = gdal.Open(myF, gdal.GA_ReadOnly)
            if not myFile:
                raise IOError("No such file or directory: '%s'" % myF)

            myFiles.append(myFile)
            myBands.append(myBand)
            myAlphaList.append(myI)
            myDataType.append(gdal.GetDataTypeName(myFile.GetRasterBand(myBand).DataType))
            myDataTypeNum.append(myFile.GetRasterBand(myBand).DataType)
            myNDV.append(myFile.GetRasterBand(myBand).GetNoDataValue())
            # check that the dimensions of each layer are the same
            if DimensionsCheck:
                if DimensionsCheck != [myFile.RasterXSize, myFile.RasterYSize]:
                    raise Exception("Error! Dimensions of file %s (%i, %i) are different from other files (%i, %i).  Cannot proceed" %
                                    (myF, myFile.RasterXSize, myFile.RasterYSize, DimensionsCheck[0], DimensionsCheck[1]))
            else:
                DimensionsCheck = [myFile.RasterXSize, myFile.RasterYSize]

            if opts.debug:
                print("file %s: %s, dimensions: %s, %s, type: %s" % (myI, myF, DimensionsCheck[0], DimensionsCheck[1], myDataType[-1]))

    # process allBands option
    allBandsIndex = None
    allBandsCount = 1
    if opts.allBands:
        try:
            allBandsIndex = myAlphaList.index(opts.allBands)
        except ValueError:
            raise Exception("Error! allBands option was given but Band %s not found.  Cannot proceed" % (opts.allBands))
        allBandsCount = myFiles[allBandsIndex].RasterCount
        if allBandsCount <= 1:
            allBandsIndex = None

    ################################################################
    # set up output file
    ################################################################

    # open output file exists
    if os.path.isfile(opts.outF) and not opts.overwrite:
        if allBandsIndex is not None:
            raise Exception("Error! allBands option was given but Output file exists, must use --overwrite option!")
        if opts.debug:
            print("Output file %s exists - filling in results into file" % (opts.outF))
        myOut = gdal.Open(opts.outF, gdal.GA_Update)
        if [myOut.RasterXSize, myOut.RasterYSize] != DimensionsCheck:
            raise Exception("Error! Output exists, but is the wrong size.  Use the --overwrite option to automatically overwrite the existing file")
        myOutB = myOut.GetRasterBand(1)
        myOutNDV = myOutB.GetNoDataValue()
        myOutType = gdal.GetDataTypeName(myOutB.DataType)

    else:
        # remove existing file and regenerate
        if os.path.isfile(opts.outF):
            os.remove(opts.outF)
        # create a new file
        if opts.debug:
            print("Generating output file %s" % (opts.outF))

        # find data type to use
        if not opts.type:
            # use the largest type of the input files
            myOutType = gdal.GetDataTypeName(max(myDataTypeNum))
        else:
            myOutType = opts.type

        # create file
        myOutDrv = gdal.GetDriverByName(opts.format)
        myOut = myOutDrv.Create(
            opts.outF, DimensionsCheck[0], DimensionsCheck[1], allBandsCount,
            gdal.GetDataTypeByName(myOutType), opts.creation_options)

        # set output geo info based on first input layer
        myOut.SetGeoTransform(myFiles[0].GetGeoTransform())
        myOut.SetProjection(myFiles[0].GetProjection())

        if opts.NoDataValue is not None:
            myOutNDV = opts.NoDataValue
        else:
            myOutNDV = DefaultNDVLookup[myOutType]

        for i in range(1, allBandsCount + 1):
            myOutB = myOut.GetRasterBand(i)
            myOutB.SetNoDataValue(myOutNDV)
            # write to band
            myOutB = None

    if opts.debug:
        print("output file: %s, dimensions: %s, %s, type: %s" % (opts.outF, myOut.RasterXSize, myOut.RasterYSize, myOutType))

    ################################################################
    # find block size to chop grids into bite-sized chunks
    ################################################################

    # use the block size of the first layer to read efficiently
    myBlockSize = myFiles[0].GetRasterBand(myBands[0]).GetBlockSize()
    # find total x and y blocks to be read
    nXBlocks = (int)((DimensionsCheck[0] + myBlockSize[0] - 1) / myBlockSize[0])
    nYBlocks = (int)((DimensionsCheck[1] + myBlockSize[1] - 1) / myBlockSize[1])
    myBufSize = myBlockSize[0] * myBlockSize[1]

    if opts.debug:
        print("using blocksize %s x %s" % (myBlockSize[0], myBlockSize[1]))

    # variables for displaying progress
    ProgressCt = -1
    ProgressMk = -1
    ProgressEnd = nXBlocks * nYBlocks * allBandsCount

    ################################################################
    # start looping through each band in allBandsCount
    ################################################################

    for bandNo in range(1, allBandsCount + 1):

        ################################################################
        # start looping through blocks of data
        ################################################################
        
        # store these numbers in variables that may change later
        nXValid = myBlockSize[0]
        nYValid = myBlockSize[1]

        # loop through X-lines
        for X in range(0, nXBlocks):

            # in case the blocks don't fit perfectly
            # change the block size of the final piece
            if X == nXBlocks - 1:
                nXValid = DimensionsCheck[0] - X * myBlockSize[0]

            # find X offset
            myX = X * myBlockSize[0]

            # reset buffer size for start of Y loop
            nYValid = myBlockSize[1]
            myBufSize = nXValid * nYValid

            # loop through Y lines
            for Y in range(0, nYBlocks):
                ProgressCt += 1
                if 10 * ProgressCt / ProgressEnd % 10 != ProgressMk and not opts.quiet:
                    ProgressMk = 10 * ProgressCt / ProgressEnd % 10
                    from sys import version_info
                    if version_info >= (3, 0, 0):
                        exec('print("%d.." % (10*ProgressMk), end=" ")')
                    else:
                        exec('print 10*ProgressMk, "..",')

                # change the block size of the final piece
                if Y == nYBlocks - 1:
                    nYValid = DimensionsCheck[1] - Y * myBlockSize[1]
                    myBufSize = nXValid * nYValid

                # find Y offset
                myY = Y * myBlockSize[1]

                # create empty buffer to mark where nodata occurs
                myNDVs = None

                # make local namespace for calculation
                local_namespace = {}

                # fetch data for each input layer
                for i, Alpha in enumerate(myAlphaList):

                    # populate lettered arrays with values
                    if allBandsIndex is not None and allBandsIndex == i:
                        myBandNo = bandNo
                    else:
                        myBandNo = myBands[i]
                    myval = gdalnumeric.BandReadAsArray(myFiles[i].GetRasterBand(myBandNo),
                                                        xoff=myX, yoff=myY,
                                                        win_xsize=nXValid, win_ysize=nYValid)

                    # fill in nodata values
                    if myNDV[i] is not None:
                        if myNDVs is None:
                            myNDVs = numpy.zeros(myBufSize)
                            myNDVs.shape = (nYValid, nXValid)
                        myNDVs = 1 * numpy.logical_or(myNDVs == 1, myval == myNDV[i])

                    # add an array of values for this block to the eval namespace
                    local_namespace[Alpha] = myval
                    myval = None

                # try the calculation on the array blocks
                try:
                    myResult = eval(opts.calc, global_namespace, local_namespace)
                except:
                    print("evaluation of calculation %s failed" % (opts.calc))
                    raise

                # Propagate nodata values (set nodata cells to zero
                # then add nodata value to these cells).
                if myNDVs is not None:
                    myResult = ((1 * (myNDVs == 0)) * myResult) + (myOutNDV * myNDVs)
                elif not isinstance(myResult, numpy.ndarray):
                    myResult = numpy.ones((nYValid, nXValid)) * myResult

                # write data block to the output file
                myOutB = myOut.GetRasterBand(bandNo)
                gdalnumeric.BandWriteArray(myOutB, myResult, xoff=myX, yoff=myY)

    if not opts.quiet:
        print("100 - Done")
예제 #27
0
def files_mean(file_array, filename_out):
    myFiles=[]
    myNDV=[]
    DimensionsCheck=None
    allBandsCount=1
    myOutNDV=-32767

    for (i, filename) in enumerate(file_array):
        if os.path.isfile(filename):
            myFile = gdal.Open(filename, gdal.GA_ReadOnly)
            if not myFile:
                raise IOError("No such file or directory: '%s'" % myFile)
            myFiles.append(myFile)
            myNDV.append(myFile.GetRasterBand(1).GetNoDataValue())
            if DimensionsCheck:
                if DimensionsCheck != [myFile.RasterXSize, myFile.RasterYSize]:
                    raise Exception("Error! Dimensions of file %s (%i, %i) are different from other files (%i, %i).  Cannot proceed" % (myF, myFile.RasterXSize, myFile.RasterYSize, DimensionsCheck[0], DimensionsCheck[1]))
            else:
                DimensionsCheck = [myFile.RasterXSize, myFile.RasterYSize]

    if os.path.isfile(filename_out):
        os.remove(filename_out)

    myBlockSize=myFiles[0].GetRasterBand(1).GetBlockSize();
    # store these numbers in variables that may change later
    nXValid = myBlockSize[0]
    nYValid = myBlockSize[1]
    # find total x and y blocks to be read
    nXBlocks = (int)((DimensionsCheck[0] + myBlockSize[0] - 1) / myBlockSize[0]);
    nYBlocks = (int)((DimensionsCheck[1] + myBlockSize[1] - 1) / myBlockSize[1]);
    myBufSize = myBlockSize[0]*myBlockSize[1]

    myOutDrv = gdal.GetDriverByName('GTiff')
    myOut = myOutDrv.Create(filename_out, DimensionsCheck[0], DimensionsCheck[1], 1,gdal.GDT_Float32)

    # set output geo info based on first input layer
    myOut.SetGeoTransform(myFiles[0].GetGeoTransform())
    myOut.SetProjection(myFiles[0].GetProjection())

    for bandNo in range(1,allBandsCount+1):
        for X in range(0,nXBlocks):
            if X==nXBlocks-1:
                nXValid = DimensionsCheck[0] - X * myBlockSize[0]
                myBufSize = nXValid*nYValid

            # find X offset
            myX=X*myBlockSize[0]

            # reset buffer size for start of Y loop
            nYValid = myBlockSize[1]
            myBufSize = nXValid*nYValid

            # loop through Y lines
            for Y in range(0,nYBlocks):
                # change the block size of the final piece
                if Y==nYBlocks-1:
                    nYValid = DimensionsCheck[1] - Y * myBlockSize[1]
                    myBufSize = nXValid*nYValid
                # find Y offset
                myY=Y*myBlockSize[1]
                # create empty buffer to mark where nodata occurs
                myNDVs = None
                # make local namespace for calculation
                local_namespace = []
                for (i, myFile) in enumerate(myFiles):
                    myval=gdalnumeric.BandReadAsArray(myFile.GetRasterBand(1),
                                            xoff=myX, yoff=myY,
                                            win_xsize=nXValid, win_ysize=nYValid)
                    # fill in nodata values
                    if myNDV[i] is not None:
                        if myNDVs is None:
                            myNDVs = numpy.zeros(myBufSize)
                            myNDVs.shape=(nYValid,nXValid)
                        myNDVs=1*numpy.logical_or(myNDVs==1, myval==myNDV[i])

                    local_namespace.append(myval)
                    myval=None

                # calculate mean between bands using Numpy
                myResult = numpy.mean(local_namespace, axis=0)

                if myNDVs is not None:
                    myResult = ((1*(myNDVs==0))*myResult) + (myOutNDV*myNDVs)
                elif not isinstance(myResult, numpy.ndarray):
                    myResult = numpy.ones( (nYValid,nXValid) ) * myResult

                myOutB=myOut.GetRasterBand(bandNo)
                gdalnumeric.BandWriteArray(myOutB, myResult, xoff=myX, yoff=myY)
    return

    # how to use it
    files_mean(['./input_01.tif', './input_02.tif', './input_02.tif', ...  './input_n.tif',],'./output.tif')
예제 #28
0
def main():
    # initiate the parser
    parser = argparse.ArgumentParser(
        description='Summarize a set of rasters layers.')
    parser.add_argument('files', nargs='+', help='input raster file(s)')
    parser.add_argument('--outfile', '-o', required=True, help='output raster')
    band_help = 'bands to summarize. ' + \
        'single file: bands in this file to summarize (default all bands); ' + \
        'multiple files: bands in corresponding files to summarize (default = 1)'
    parser.add_argument('--bands', '-b', nargs='+', type=int, help=band_help)
    function_help = 'function to apply to cell values across layers.' + \
        'meannz gives a mean of the non-zero values.' + \
        'count counts the number layers with non-negative values for each cell.' + \
        'richness counts the number of layers with positive values for each cell.'
    parser.add_argument('--function',
                        '-f',
                        dest='summary_function',
                        default='mean',
                        choices=[
                            'mean', 'median', 'max', 'sum', 'meannz', 'count',
                            'richness'
                        ],
                        help="summarization function (default = 'mean')")
    parser.add_argument(
        '--block_size',
        '-s',
        nargs=2,
        type=int,
        help='x and y dimensions of blocks to process (default based on input)'
    )
    parser.add_argument(
        '--nrows',
        '-n',
        type=int,
        help=
        'number of rows to process in a single block (block_size ignored if provided)'
    )
    parser.add_argument('--overwrite',
                        '-w',
                        action="store_true",
                        help='overwrite existing file')
    parser.add_argument(
        '--creation-option',
        '--co',
        dest='creation_options',
        default=[],
        action='append',
        help=
        'passes one or more creation options to the output format driver multiple'
    )
    parser.add_argument('--quiet',
                        '-q',
                        action="store_true",
                        help='supress messages')

    # read arguments from the command line
    args = parser.parse_args()

    # summarize multiple bands of same file or bands across files
    if len(args.files) == 1:
        # use all bands if not specified
        if not args.bands:
            b = gdal.Open(args.files[0], gdal.GA_ReadOnly).RasterCount
            args.bands = [i for i in range(1, b + 1)]
        # elif len(args.bands) == 1:
        #     raise Exception('For a single input file, provide multiple bands to summarize over.')
        args.files = [args.files[0]] * len(args.bands)
    else:
        # use band 1 if not specified
        if not args.bands:
            args.bands = [1] * len(args.files)
        elif len(args.bands) == 1:
            args.bands = [args.bands[0]] * len(args.files)
        elif len(args.bands) != len(args.files):
            raise Exception(
                'The number of bands must be 1 or equal to the number of input files.'
            )

    # set up some default nodatavalues for each datatype
    ndv_lookup = {
        'Byte': 255,
        'UInt16': 65535,
        'Int16': -32767,
        'UInt32': 4294967293,
        'Int32': -2147483647,
        'Float32': 3.402823466E+38,
        'Float64': 1.7976931348623158E+308
    }

    stack = []
    in_type = []
    in_ndv = []
    raster_dim = None
    block_size = None
    out_transform = None
    out_projection = None
    # pass over files to get metadata and check arguments
    for i in range(len(args.files)):
        f = args.files[i]
        b = args.bands[i]
        s = gdal.Open(f, gdal.GA_ReadOnly)

        # check that file exists
        if not s:
            raise IOError('No such file or directory: {}'.format(f))

        # check that band is valid
        if b > s.RasterCount:
            raise IOError('Invalid band number ({}) for file: {}'.format(b, f))

        # get specified band
        r = s.GetRasterBand(b)

        # store raster file
        stack.append(s)

        # metadata
        in_type.append(r.DataType)
        dt_name = gdal.GetDataTypeName(r.DataType).lower()
        in_ndv.append(np.float64(r.GetNoDataValue()).astype(dt_name))

        # check that the dimensions of each layer are the same
        if raster_dim:
            if raster_dim != [s.RasterXSize, s.RasterYSize]:
                raise Exception('Input files have different dimensions.')
        else:
            raster_dim = [s.RasterXSize, s.RasterYSize]

        # block size to chop grids into bite-sized chunks
        if not block_size:
            # use the block size of the first layer to read efficiently
            # or use user provided block size
            if not args.nrows:
                if not args.block_size:
                    block_size = s.GetRasterBand(1).GetBlockSize()
                else:
                    # block size can't be larger than raster dimensions
                    block_size = np.minimum(args.block_size,
                                            raster_dim).tolist()
            else:
                block_size = [raster_dim[0], min(raster_dim[1], args.nrows)]

        # get geo info from first layer
        if not out_transform:
            out_transform = s.GetGeoTransform()
        if not out_projection:
            out_projection = s.GetProjection()

    # prepare output file
    if os.path.isfile(args.outfile) and not args.overwrite:
        raise Exception(
            "Output exists, use the --overwrite to overwrite the existing file"
        )
    else:
        # remove existing file and regenerate
        if os.path.isfile(args.outfile):
            os.remove(args.outfile)

        # for sum use the largest type of the input files
        # otherise use a value suitable for the function
        if args.summary_function == 'sum':
            out_type = gdal.GetDataTypeName(max(in_type))
            out_type_np = out_type.lower()
            np_nan = 0
        elif args.summary_function == 'mean':
            out_type = 'Float32'
            out_type_np = out_type.lower()
            np_nan = np.nan
        elif args.summary_function == 'median':
            out_type = 'Float32'
            out_type_np = out_type.lower()
            np_nan = np.nan
        elif args.summary_function == 'max':
            out_type = 'Float32'
            out_type_np = out_type.lower()
            np_nan = np.nan
        elif args.summary_function == 'meannz':
            out_type = 'Float32'
            out_type_np = out_type.lower()
            np_nan = np.nan
        elif args.summary_function == 'count':
            out_type = 'Int16'
            out_type_np = out_type.lower()
            np_nan = -1
        elif args.summary_function == 'richness':
            out_type = 'Int16'
            out_type_np = out_type.lower()
            np_nan = -1

        # create file
        out_driver = gdal.GetDriverByName('GTiff')
        r_out = out_driver.Create(args.outfile, raster_dim[0], raster_dim[1],
                                  1, gdal.GetDataTypeByName(out_type),
                                  args.creation_options)

        # set output geo info based on first input layer
        r_out.SetGeoTransform(out_transform)
        r_out.SetProjection(out_projection)

        # set no data value
        out_ndv = ndv_lookup[out_type]
        out_ndv_np = np.float64(out_ndv).astype(out_type_np)
        r_out.GetRasterBand(1).SetNoDataValue(out_ndv)

    # find total x and y blocks to be read
    xblocks = math.ceil(raster_dim[0] / block_size[0])
    yblocks = math.ceil(raster_dim[1] / block_size[1])

    # loop through blocks of data
    # store these numbers in variables that may change later
    xvalid = block_size[0]
    yvalid = block_size[1]

    # variables for displaying progress
    progress_cnt = -1
    progress_stp = 0
    progress_end = xblocks * yblocks
    progress_stps = [round(progress_end * i / 100) for i in range(0, 101, 10)]

    # message
    if not args.quiet:
        m = "Processing {} X {} raster (cols X rows) in {} blocks of {} X {}"
        m = m.format(raster_dim[0], raster_dim[1], xblocks * yblocks,
                     block_size[0], block_size[1])
        print(m)

    # loop through x dimension
    for x in range(0, xblocks):
        # in case the blocks don't fit perfectly
        # change the block size of the final piece
        if x == xblocks - 1:
            xvalid = raster_dim[0] - x * block_size[0]

        # find x offset
        x_off = x * block_size[0]

        # reset buffer size for start of Y loop
        yvalid = block_size[1]

        # loop through y dimension
        for y in range(0, yblocks):
            # progress bar
            progress_cnt += 1
            if progress_cnt == progress_stps[progress_stp] and not args.quiet:
                print('%d...' % (10 * progress_stp), end="", flush=True)
                progress_stp += 1

            # change the block size of the final piece
            if y == yblocks - 1:
                yvalid = raster_dim[1] - y * block_size[1]

            # find y offset
            y_off = y * block_size[1]

            # create empty buffer to mark where nodata occurs
            ndv_buffer = None

            # make array to store block
            block = np.empty(shape=(len(stack), yvalid, xvalid),
                             dtype='float32')

            # fetch data for each input layer
            for i in range(len(stack)):
                vals = gdalnumeric.BandReadAsArray(stack[i].GetRasterBand(
                    args.bands[i]),
                                                   xoff=x_off,
                                                   yoff=y_off,
                                                   win_xsize=xvalid,
                                                   win_ysize=yvalid)
                if out_type != "Int16":
                    vals = vals.astype(out_type_np)

                # fill in nodata values
                if in_ndv[i] is not None:
                    vals[vals == in_ndv[i]] = np_nan

                # add block to array
                block[i] = vals
                vals = None

            # ignore empty slice warnings
            with warnings.catch_warnings():
                warnings.simplefilter('ignore', category=RuntimeWarning)
                if args.summary_function == 'sum':
                    result = np.nansum(block, axis=0)
                elif args.summary_function == 'mean':
                    result = np.nanmean(block, axis=0)
                elif args.summary_function == 'median':
                    result = np.nanmedian(block, axis=0)
                elif args.summary_function == 'max':
                    result = np.nanmax(block, axis=0)
                elif args.summary_function == 'meannz':
                    block = np.ma.masked_equal(block, 0)
                    result = np.nanmean(block, axis=0)
                elif args.summary_function == 'count':
                    result = np.nansum(block >= 0, axis=0)
                elif args.summary_function == 'richness':
                    result = np.nansum(block > 0, axis=0)

            # replace nan with no data value
            result[np.isnan(result)] = out_ndv_np

            # write data block to the output file
            gdalnumeric.BandWriteArray(r_out.GetRasterBand(1),
                                       result,
                                       xoff=x_off,
                                       yoff=y_off)

    # end progress bar
    if not args.quiet:
        print('100 - Done')
예제 #29
0
def doit(opts, args):
    # pylint: disable=unused-argument

    if opts.debug:
        print("gdal_calc.py starting calculation %s" % (opts.calc))

    # set up global namespace for eval with all functions of gdalnumeric
    global_namespace = dict([(key, getattr(gdalnumeric, key))
                             for key in dir(gdalnumeric) if not key.startswith('__')])
    if opts.user_namespace:
        global_namespace.update(opts.user_namespace)

    if not opts.calc:
        raise Exception("No calculation provided.")
    elif not opts.outF and opts.format.upper() != 'MEM':
        raise Exception("No output file provided.")

    if opts.format is None:
        opts.format = GetOutputDriverFor(opts.outF)

    if not hasattr(opts, "color_table"):
        opts.color_table = None
    if not opts.extent:
        opts.extent = EXTENT_IGNORE
    else:
        opts.extent = parse_extent(opts.extent)

    compatible_gt_eps = 0.000001
    gt_diff_support = {
        GT_INCOMPATIBLE_OFFSET: opts.extent != EXTENT_FAIL,
        GT_INCOMPATIBLE_PIXEL_SIZE: False,
        GT_INCOMPATIBLE_ROTATION: False,
        GT_NON_ZERO_ROTATION: False,
    }
    gt_diff_error = {
        GT_INCOMPATIBLE_OFFSET: 'different offset',
        GT_INCOMPATIBLE_PIXEL_SIZE: 'different pixel size',
        GT_INCOMPATIBLE_ROTATION: 'different rotation',
        GT_NON_ZERO_ROTATION: 'non zero rotation',
    }

    ################################################################
    # fetch details of input layers
    ################################################################

    # set up some lists to store data for each band
    myFileNames = []  # input filenames
    myFiles = []  # input DataSets
    myBands = []  # input bands
    myAlphaList = []  # input alpha letter that represents each input file
    myDataType = []  # string representation of the datatype of each input file
    myDataTypeNum = []  # datatype of each input file
    myNDV = []  # nodatavalue for each input file
    DimensionsCheck = None  # dimensions of the output
    Dimensions = []  # Dimensions of input files
    ProjectionCheck = None  # projection of the output
    GeoTransformCheck = None  # GeoTransform of the output
    GeoTransforms = []  # GeoTransform of each input file
    GeoTransformDiffer = False  # True if we have inputs with different GeoTransforms
    myTempFileNames = []  # vrt filename from each input file
    myAlphaFileLists = []  # list of the Alphas which holds a list of inputs

    # loop through input files - checking dimensions
    for alphas, filenames in opts.input_files.items():
        if isinstance(filenames, (list, tuple)):
            # alpha is a list of files
            myAlphaFileLists.append(alphas)
        elif is_path_like(filenames) or isinstance(filenames, gdal.Dataset):
            # alpha is a single filename or a Dataset
            filenames = [filenames]
            alphas = [alphas]
        else:
            # I guess this alphas should be in the global_namespace,
            # It would have been better to pass it as user_namepsace, but I'll accept it anyway
            global_namespace[alphas] = filenames
            continue
        for alpha, filename in zip(alphas*len(filenames), filenames):
            if not alpha.endswith("_band"):
                # check if we have asked for a specific band...
                if "%s_band" % alpha in opts.input_files:
                    myBand = opts.input_files["%s_band" % alpha]
                else:
                    myBand = 1

                myF_is_ds = not is_path_like(filename)
                if myF_is_ds:
                    myFile = filename
                    filename = None
                else:
                    filename = str(filename)
                    myFile = gdal.Open(filename, gdal.GA_ReadOnly)
                if not myFile:
                    raise IOError("No such file or directory: '%s'" % filename)

                myFileNames.append(filename)
                myFiles.append(myFile)
                myBands.append(myBand)
                myAlphaList.append(alpha)
                dt = myFile.GetRasterBand(myBand).DataType
                myDataType.append(gdal.GetDataTypeName(dt))
                myDataTypeNum.append(dt)
                myNDV.append(None if opts.hideNoData else myFile.GetRasterBand(myBand).GetNoDataValue())

                # check that the dimensions of each layer are the same
                myFileDimensions = [myFile.RasterXSize, myFile.RasterYSize]
                if DimensionsCheck:
                    if DimensionsCheck != myFileDimensions:
                        GeoTransformDiffer = True
                        if opts.extent in [EXTENT_IGNORE, EXTENT_FAIL]:
                            raise Exception("Error! Dimensions of file %s (%i, %i) are different from other files (%i, %i).  Cannot proceed" %
                                            (filename, myFileDimensions[0], myFileDimensions[1], DimensionsCheck[0], DimensionsCheck[1]))
                else:
                    DimensionsCheck = myFileDimensions

                # check that the Projection of each layer are the same
                myProjection = myFile.GetProjection()
                if ProjectionCheck:
                    if opts.projectionCheck and ProjectionCheck != myProjection:
                        raise Exception(
                            "Error! Projection of file %s %s are different from other files %s.  Cannot proceed" %
                            (filename, myProjection, ProjectionCheck))
                else:
                    ProjectionCheck = myProjection

                # check that the GeoTransforms of each layer are the same
                myFileGeoTransform = myFile.GetGeoTransform(can_return_null=True)
                if opts.extent == EXTENT_IGNORE:
                    GeoTransformCheck = myFileGeoTransform
                else:
                    Dimensions.append(myFileDimensions)
                    GeoTransforms.append(myFileGeoTransform)
                    if not GeoTransformCheck:
                        GeoTransformCheck = myFileGeoTransform
                    else:
                        my_gt_diff = gt_diff(GeoTransformCheck, myFileGeoTransform, eps=compatible_gt_eps, diff_support=gt_diff_support)
                        if my_gt_diff not in [GT_SAME, GT_ALMOST_SAME]:
                            GeoTransformDiffer = True
                            if my_gt_diff not in [GT_COMPATIBLE_DIFF]:
                                raise Exception(
                                    "Error! GeoTransform of file {} {} is incompatible ({}), first file GeoTransform is {}. Cannot proceed".
                                        format(filename, myFileGeoTransform, gt_diff_error[my_gt_diff], GeoTransformCheck))
                if opts.debug:
                    print("file %s: %s, dimensions: %s, %s, type: %s" % (
                        alpha, filename, DimensionsCheck[0], DimensionsCheck[1], myDataType[-1]))

    # process allBands option
    allBandsIndex = None
    allBandsCount = 1
    if opts.allBands:
        if len(opts.calc) > 1:
            raise Exception("Error! --allBands implies a single --calc")
        try:
            allBandsIndex = myAlphaList.index(opts.allBands)
        except ValueError:
            raise Exception("Error! allBands option was given but Band %s not found.  Cannot proceed" % (opts.allBands))
        allBandsCount = myFiles[allBandsIndex].RasterCount
        if allBandsCount <= 1:
            allBandsIndex = None
    else:
        allBandsCount = len(opts.calc)

    if opts.extent not in [EXTENT_IGNORE, EXTENT_FAIL] and (GeoTransformDiffer or not isinstance(opts.extent, EXTENT)):
        raise Exception('Error! mixing different GeoTransforms/Extents is not supported yet.')

    ################################################################
    # set up output file
    ################################################################

    # open output file exists
    if opts.outF and os.path.isfile(opts.outF) and not opts.overwrite:
        if allBandsIndex is not None:
            raise Exception("Error! allBands option was given but Output file exists, must use --overwrite option!")
        if len(opts.calc) > 1:
            raise Exception("Error! multiple calc options were given but Output file exists, must use --overwrite option!")
        if opts.debug:
            print("Output file %s exists - filling in results into file" % (opts.outF))

        myOut = gdal.Open(opts.outF, gdal.GA_Update)
        if myOut is None:
            error = 'but cannot be opened for update'
        elif [myOut.RasterXSize, myOut.RasterYSize] != DimensionsCheck:
            error = 'but is the wrong size'
        elif ProjectionCheck and ProjectionCheck != myOut.GetProjection():
            error = 'but is the wrong projection'
        elif GeoTransformCheck and GeoTransformCheck != myOut.GetGeoTransform(can_return_null=True):
            error = 'but is the wrong geotransform'
        else:
            error = None
        if error:
            raise Exception("Error! Output exists, %s.  Use the --overwrite option to automatically overwrite the existing file" % error)

        myOutB = myOut.GetRasterBand(1)
        myOutNDV = myOutB.GetNoDataValue()
        myOutType = myOutB.DataType

    else:
        if opts.outF:
            # remove existing file and regenerate
            if os.path.isfile(opts.outF):
                os.remove(opts.outF)
            # create a new file
            if opts.debug:
                print("Generating output file %s" % (opts.outF))
        else:
            opts.outF = ''

        # find data type to use
        if not opts.type:
            # use the largest type of the input files
            myOutType = max(myDataTypeNum)
        else:
            myOutType = opts.type
            if isinstance(myOutType, str):
                myOutType = gdal.GetDataTypeByName(myOutType)

        # create file
        myOutDrv = gdal.GetDriverByName(opts.format)
        myOut = myOutDrv.Create(
            opts.outF, DimensionsCheck[0], DimensionsCheck[1], allBandsCount,
            myOutType, opts.creation_options)

        # set output geo info based on first input layer
        if not GeoTransformCheck:
            GeoTransformCheck = myFiles[0].GetGeoTransform(can_return_null=True)
        if GeoTransformCheck:
            myOut.SetGeoTransform(GeoTransformCheck)

        if not ProjectionCheck:
            ProjectionCheck = myFiles[0].GetProjection()
        if ProjectionCheck:
            myOut.SetProjection(ProjectionCheck)

        if opts.NoDataValue is None:
            myOutNDV = None if opts.hideNoData else DefaultNDVLookup[myOutType]  # use the default noDataValue for this datatype
        elif isinstance(opts.NoDataValue, str) and opts.NoDataValue.lower() == 'none':
            myOutNDV = None  # not to set any noDataValue
        else:
            myOutNDV = opts.NoDataValue  # use the given noDataValue

        for i in range(1, allBandsCount + 1):
            myOutB = myOut.GetRasterBand(i)
            if myOutNDV is not None:
                myOutB.SetNoDataValue(myOutNDV)
            if opts.color_table:
                # set color table and color interpretation
                if is_path_like(opts.color_table):
                    raise Exception('Error! reading a color table from a file is not supported yet')
                myOutB.SetRasterColorTable(opts.color_table)
                myOutB.SetRasterColorInterpretation(gdal.GCI_PaletteIndex)

            myOutB = None  # write to band

    myOutTypeName = gdal.GetDataTypeName(myOutType)
    if opts.debug:
        print("output file: %s, dimensions: %s, %s, type: %s" % (opts.outF, myOut.RasterXSize, myOut.RasterYSize, myOutTypeName))

    ################################################################
    # find block size to chop grids into bite-sized chunks
    ################################################################

    # use the block size of the first layer to read efficiently
    myBlockSize = myFiles[0].GetRasterBand(myBands[0]).GetBlockSize()
    # find total x and y blocks to be read
    nXBlocks = (int)((DimensionsCheck[0] + myBlockSize[0] - 1) / myBlockSize[0])
    nYBlocks = (int)((DimensionsCheck[1] + myBlockSize[1] - 1) / myBlockSize[1])
    myBufSize = myBlockSize[0] * myBlockSize[1]

    if opts.debug:
        print("using blocksize %s x %s" % (myBlockSize[0], myBlockSize[1]))

    # variables for displaying progress
    ProgressCt = -1
    ProgressMk = -1
    ProgressEnd = nXBlocks * nYBlocks * allBandsCount

    ################################################################
    # start looping through each band in allBandsCount
    ################################################################

    for bandNo in range(1, allBandsCount + 1):

        ################################################################
        # start looping through blocks of data
        ################################################################

        # store these numbers in variables that may change later
        nXValid = myBlockSize[0]
        nYValid = myBlockSize[1]

        # loop through X-lines
        for X in range(0, nXBlocks):

            # in case the blocks don't fit perfectly
            # change the block size of the final piece
            if X == nXBlocks - 1:
                nXValid = DimensionsCheck[0] - X * myBlockSize[0]

            # find X offset
            myX = X * myBlockSize[0]

            # reset buffer size for start of Y loop
            nYValid = myBlockSize[1]
            myBufSize = nXValid * nYValid

            # loop through Y lines
            for Y in range(0, nYBlocks):
                ProgressCt += 1
                if 10 * ProgressCt / ProgressEnd % 10 != ProgressMk and not opts.quiet:
                    ProgressMk = 10 * ProgressCt / ProgressEnd % 10
                    from sys import version_info
                    if version_info >= (3, 0, 0):
                        exec('print("%d.." % (10*ProgressMk), end=" ")')
                    else:
                        exec('print 10*ProgressMk, "..",')

                # change the block size of the final piece
                if Y == nYBlocks - 1:
                    nYValid = DimensionsCheck[1] - Y * myBlockSize[1]
                    myBufSize = nXValid * nYValid

                # find Y offset
                myY = Y * myBlockSize[1]

                # create empty buffer to mark where nodata occurs
                myNDVs = None

                # make local namespace for calculation
                local_namespace = {}

                val_lists = defaultdict(list)

                # fetch data for each input layer
                for i, Alpha in enumerate(myAlphaList):

                    # populate lettered arrays with values
                    if allBandsIndex is not None and allBandsIndex == i:
                        myBandNo = bandNo
                    else:
                        myBandNo = myBands[i]
                    myval = gdalnumeric.BandReadAsArray(myFiles[i].GetRasterBand(myBandNo),
                                                        xoff=myX, yoff=myY,
                                                        win_xsize=nXValid, win_ysize=nYValid)
                    if myval is None:
                        raise Exception('Input block reading failed from filename %s' % filename[i])

                    # fill in nodata values
                    if myNDV[i] is not None:
                        # myNDVs is a boolean buffer.
                        # a cell equals to 1 if there is NDV in any of the corresponding cells in input raster bands.
                        if myNDVs is None:
                            # this is the first band that has NDV set. we initializes myNDVs to a zero buffer
                            # as we didn't see any NDV value yet.
                            myNDVs = numpy.zeros(myBufSize)
                            myNDVs.shape = (nYValid, nXValid)
                        myNDVs = 1 * numpy.logical_or(myNDVs == 1, myval == myNDV[i])

                    # add an array of values for this block to the eval namespace
                    if Alpha in myAlphaFileLists:
                        val_lists[Alpha].append(myval)
                    else:
                        local_namespace[Alpha] = myval
                    myval = None

                for lst in myAlphaFileLists:
                    local_namespace[lst] = val_lists[lst]

                # try the calculation on the array blocks
                calc = opts.calc[bandNo-1 if len(opts.calc) > 1 else 0]
                try:
                    myResult = eval(calc, global_namespace, local_namespace)
                except:
                    print("evaluation of calculation %s failed" % (calc))
                    raise

                # Propagate nodata values (set nodata cells to zero
                # then add nodata value to these cells).
                if myNDVs is not None and myOutNDV is not None:
                    myResult = ((1 * (myNDVs == 0)) * myResult) + (myOutNDV * myNDVs)
                elif not isinstance(myResult, numpy.ndarray):
                    myResult = numpy.ones((nYValid, nXValid)) * myResult

                # write data block to the output file
                myOutB = myOut.GetRasterBand(bandNo)
                if gdalnumeric.BandWriteArray(myOutB, myResult, xoff=myX, yoff=myY) != 0:
                    raise Exception('Block writing failed')
                myOutB = None  # write to band

    # remove temp files
    for idx, tempFile in enumerate(myTempFileNames):
        myFiles[idx] = None
        os.remove(tempFile)

    gdal.ErrorReset()
    myOut.FlushCache()
    if gdal.GetLastErrorMsg() != '':
        raise Exception('Dataset writing failed')

    if not opts.quiet:
        print("100 - Done")

    return myOut
예제 #30
0
import pandas
import numpy as np
import matplotlib.pyplot as plt
from osgeo import gdal, gdalnumeric

#filename = "Users/mattolson/data/ASO/CASI/20170220/174008/CASI_2017_02_20_174008_atm_ort"
filename = "/Users/mattolson/data/ASO/CASI/20170220/174008/CASI_2017_02_20_174008_atm_ort"

casi = gdal.Open(filename)

b1 = casi.GetRasterBand(1)

b1arr = gdalnumeric.BandReadAsArray(b1)
b1mask = np.ma.masked_values(b1arr, b1.GetNoDataValue(), copy=False)

plt.figure()
plt.imshow(b1mask)
plt.legend()
plt.show()

# np.ma.vstack or dstack
# multi-dimentional array