def __initialize_bands(output_file, bands_to_copy):
     na_values = numpy.full(
         (output_file.RasterYSize, output_file.RasterXSize), NO_DATA_VALUE)
     for band in bands_to_copy:
         target_band = output_file.GetRasterBand(band)
         target_band.SetNoDataValue(NO_DATA_VALUE)
         gdalnumeric.BandWriteArray(target_band, na_values)
     del na_values
Example #2
0
 def numpy_to_layer(self,array,name):
     array = np.rot90(array)
     sy, sx = array.shape
     pathname = QgsProject.instance().readPath("./")+'/'+name
     driver = gdal.GetDriverByName("GTiff")
     dsOut = driver.Create(pathname, sx+1,sy+1,1,gdal.GDT_Float32 ,)
     dsOut.SetGeoTransform(self.transform)
     dsOut.SetProjection(self.wkt)
     bandOut=dsOut.GetRasterBand(1)
     gdalnumeric.BandWriteArray(bandOut, array)
     bandOut = None
     dsOut = None
     layer = QgsRasterLayer(pathname,name)
     QgsProject.instance().addMapLayer(layer)
Example #3
0
    def WriteArray(self, array, xoff=0, yoff=0):
        import gdalnumeric

        return gdalnumeric.BandWriteArray(self, array, xoff, yoff)
Example #4
0
def write_raster(array, template, filename):
    driver = gdal.GetDriverByName("GTiff")
    raster_out = driver.Create(filename, template.RasterXSize, template.RasterYSize, 1, template.GetRasterBand(1).DataType)
    gdalnumeric.CopyDatasetInfo(template,raster_out)
    bandOut=raster_out.GetRasterBand(1)
    gdalnumeric.BandWriteArray(bandOut, array)
Example #5
0
def rast_math(output_path, expression, *args):
    """
    A raster math calculator that uses GDALs python bindings instead of command line
    interface for simple math. The syntax of this feels more pythonic than the native gdal_calc.py
    syntax. Supports up to 26 raster images for each letter of the alphabet as
    arguments. Supports single band raster images or gdal.Band instances as *args inputs.
    Input expression will be directly evaluated, so users can input numerical constants
    and simple ``numpy`` or ``math`` module operators with lowercase function names. Because
    this function uses python bindings and numpy data structures, be mindful of the memory
    limitations associated with 32-bit python, highly recommend using 64 bit.

    :param output_path: filepath at which to store expression result. Set to False to just return
                        the numeric array instead of saving it.
    :param expression:  the mathematical expression using rasters as A,B,C, etc
    :param args:        Filepaths to single band rasters that represent A,B,C, etc (in order)
                        OR, gdal.Band instances which could be used with multi-band rasters via...
                            ds = gdal.Open(rastpath)
                            bandA = ds.GetRasterBand(1)
                            bandB = ds.GetRasterBand(2)
                            rast_math(outpath, "numpy.log(A) + 3 * B", bandA, bandB)
    :return:            the output path to the file created by this function

    An example for the ubiquitous NDVI calculation from landsat bands:

    ..code-block: python

        root = r"my_landsat_directory"              # directory with landsat tiffs
        A_path = os.path.join(root, "tile_B5.TIF")  # filepath to Band5
        B_path = os.path.join(root, "tile_B4.TIF")  # filepath to Band4
        out_path = os.path.join(root, "NDVI.TIF")   # filepath of new output image

        rast_math(out_path, "(A + B) / (A - B)", A_path, B_path)

    An example where we want to conditionally mask one raster by another, say
    image "A" is our raster with data, and image "B" is a mask where a value of 1
    indicates a bad value, and zero indicates a good value.

    ..code-block:python

        rast_math(out_path, "A * (B == 0)", A_path, B_path)
    """

    # set up the iterators and structures
    datasets = {}  # dictionary where actual data will go
    eval_args = {}  # dictionary with string literals to be evaluated as code
    alphabet = string.ascii_uppercase[:len(args)]

    # format the expression with curly brackets around letters
    print("Executing expression '{0}'".format(expression))
    for letter in alphabet:
        expression = expression.replace(letter, "{%s}" % letter)

    # create the numpy arrays from raster datasets with gdal
    for arg, letter in zip(args, alphabet):

        # handle filepath input and raise exception for invalid filepaths
        if isinstance(arg, str):
            if not os.path.exists(arg):
                raise Exception("file {0} does not exist!".format(arg))

            print("\tLoading {0} as raster '{1}'".format(arg, letter))
            dataset_in = gdal.Open(arg, gdalconst.GA_ReadOnly)
            band = dataset_in.GetRasterBand(1)
            datasets[letter] = numpy.array(band.ReadAsArray(), dtype="float32")

        # handles input type of a gdal.Band instance
        elif isinstance(arg, gdal.Band):
            datasets[letter] = numpy.array(arg.ReadAsArray(), dtype="float32")

        eval_args[letter] = "datasets['{0}']".format(letter)

    # assemble and evaluate the expression
    eval_expression = expression.format(**eval_args)
    print(eval_expression)
    out_array = eval(eval_expression)

    # either save the output or return an output array
    if output_path:
        driver = gdal.GetDriverByName(
            "GTiff")  # create the geotiff driver object
        yshape, xshape = datasets["A"].shape  # set dimensions of output file
        num_bands = 1  # only supports single band output
        dataset_out = driver.Create(output_path, xshape, yshape, num_bands,
                                    gdal.GDT_Float32)
        gdalnumeric.CopyDatasetInfo(dataset_in, dataset_out)
        band_out = dataset_out.GetRasterBand(1)
        gdalnumeric.BandWriteArray(band_out, out_array)
        return os.path.abspath(output_path)

    else:
        return out_array