Esempio n. 1
0
def obj_to_rst(inArray, outRst, template, noData=None, geotrans=None):
    """
    Send Array to Raster
    
    API Available:
    * gdal;
    """

    gisApi = 'gdal'

    if gisApi == 'gdal':
        from osgeo import gdal, osr, gdal_array
        from gasp.gt.prop.ff import drv_name
        from gasp.gt.prop.rst import compress_option

        if type(template).__name__ == 'Dataset':
            img_template = template
        else:
            img_template = gdal.Open(template)

        geo_transform = img_template.GetGeoTransform() if not geotrans else \
            geotrans
        rows, cols = inArray.shape
        drv_n = drv_name(outRst)
        driver = gdal.GetDriverByName(drv_n)

        c_opt = compress_option(drv_n)
        if c_opt:
            out = driver.Create(outRst,
                                cols,
                                rows,
                                1,
                                gdal_array.NumericTypeCodeToGDALTypeCode(
                                    inArray.dtype),
                                options=[c_opt])
        else:
            out = driver.Create(
                outRst, cols, rows, 1,
                gdal_array.NumericTypeCodeToGDALTypeCode(inArray.dtype))
        out.SetGeoTransform(geo_transform)
        outBand = out.GetRasterBand(1)

        if noData:
            outBand.SetNoDataValue(noData)

        outBand.WriteArray(inArray)

        proj = osr.SpatialReference(wkt=img_template.GetProjection())

        if proj:
            out.SetProjection(img_template.GetProjection())

        outBand.FlushCache()

    else:
        raise ValueError('The api {} is not available'.format(gisApi))

    return outRst
Esempio n. 2
0
def obj_to_rst(inArray, outRst, template, noData=None, geotrans=None):
    """
    Send Array to Raster
    """

    from osgeo import gdal, osr, gdal_array
    from glass.g.prop import drv_name
    from glass.g.prop.rst import compress_option

    if type(template).__name__ == 'Dataset':
        img_template = template
    else:
        img_template = gdal.Open(template)

    geo_transform = img_template.GetGeoTransform() if not geotrans else \
        geotrans
    rows, cols = inArray.shape
    drv_n = drv_name(outRst)
    driver = gdal.GetDriverByName(drv_n)

    c_opt = compress_option(drv_n)
    if c_opt:
        out = driver.Create(outRst,
                            cols,
                            rows,
                            1,
                            gdal_array.NumericTypeCodeToGDALTypeCode(
                                inArray.dtype),
                            options=[c_opt])
    else:
        out = driver.Create(
            outRst, cols, rows, 1,
            gdal_array.NumericTypeCodeToGDALTypeCode(inArray.dtype))
    out.SetGeoTransform(geo_transform)
    outBand = out.GetRasterBand(1)

    if noData or noData == 0:
        outBand.SetNoDataValue(noData)

    outBand.WriteArray(inArray)

    proj = osr.SpatialReference(wkt=img_template.GetProjection())

    if proj:
        out.SetProjection(img_template.GetProjection())

    outBand.FlushCache()

    return outRst
Esempio n. 3
0
 def open(self, file=None, dtype=None):
     """
     Open a local file handle for reading and assignment
     :param file:
     :return: None
     """
     # args[0]/file=
     if file is None:
         raise IndexError("invalid file= argument provided")
     # grab raster meta information from GeoRasters
     try:
         self.ndv, self.x_cell_size, self.y_cell_size, self.geot, self.projection, self.dtype = \
             get_geo_info(file)
     except Exception:
         raise AttributeError("problem processing file input -- is this",
                              "a raster file?")
     # args[1]/dtype=
     if dtype is not None:
         # override our shadow'd value from GeoRasters if
         # something was specified by the user
         self.dtype = dtype
     # re-cast our datatype as a numpy type, if needed
     if type(self.dtype) == str:
         self.dtype = NUMPY_TYPES[self.dtype.lower()]
     if self.ndv is None:
         self.ndv = _DEFAULT_NA_VALUE
     # low-level call to gdal with explicit type specification
     # that will store in memory or as a disc cache, depending
     # on the state of our _using_disc_caching property
     if self._using_disc_caching is not None:
         # create a cache file
         self.array = np.memmap(self._using_disc_caching,
                                dtype=dtype,
                                mode='w+',
                                shape=(_x_size, _y_size))
         # load file contents into the cache
         self.array[:] = gdalnumeric.LoadFile(
             filename=self.filename,
             buf_type=gdal_array.NumericTypeCodeToGDALTypeCode(
                 self.dtype))[:]
     # by default, load the whole file into memory
     else:
         self.array = gdalnumeric.LoadFile(
             filename=self.filename,
             buf_type=gdal_array.NumericTypeCodeToGDALTypeCode(self.dtype))
     # make sure we honor our no data value
     self.array = np.ma.masked_array(self.array,
                                     mask=self.array == self.ndv,
                                     fill_value=self.ndv)
Esempio n. 4
0
def stretch(src, dst, stretch, bands, ndv, minmax, pct, _format, dtype, co,
            verbose):
    # Read input image
    try:
        ds = gdal.Open(src, gdal.GA_ReadOnly)
    except:
        click.echo("Could not open source dataset {0}".format(src))
        raise
    driver = gdal.GetDriverByName(str(_format))

    # If no output dtype selected, default to input image dtype
    if not dtype:
        dtype = gdal_array.GDALTypeCodeToNumericTypeCode(
            ds.GetRasterBand(1).DataType)
    dtype = np.dtype(dtype)
    gdal_dtype = gdal_array.NumericTypeCodeToGDALTypeCode(dtype)

    if not bands:
        nbands = ds.RasterCount
        bands = range(1, nbands + 1)
    else:
        nbands = len(bands)

    # Create output
    if _format.lower() in COPY_FORMATS:
        if nbands not in (1, 3, 4):
            raise click.BadParameter(
                'JPEG/PNG images must have 1, 3, or 4 bands')

        mem_driver = gdal.GetDriverByName('MEM')
        out_ds = mem_driver.Create('', ds.RasterXSize, ds.RasterYSize, nbands,
                                   gdal_dtype)
    else:
        out_ds = driver.Create(dst, ds.RasterXSize, ds.RasterYSize, nbands,
                               gdal_dtype)

    for idx, (b, _minmax) in enumerate(zip_longest(bands, minmax)):
        kwargs = dict(ndv=ndv, minmax=_minmax, percent=pct)

        in_band = ds.GetRasterBand(b)
        arr = in_band.ReadAsArray()
        arr, out_ndv = _STRETCH_FUNCS[stretch](arr, **kwargs)
        out_band = out_ds.GetRasterBand(idx + 1)
        out_band.WriteArray(arr)
        out_band.SetDescription(in_band.GetDescription())
        out_band.SetNoDataValue(out_ndv)

    out_ds.SetMetadata(ds.GetMetadata())
    out_ds.SetProjection(ds.GetProjection())
    out_ds.SetGeoTransform(ds.GetGeoTransform())

    if _format.lower() in COPY_FORMATS:
        _out_ds = driver.CreateCopy(dst, out_ds, 0, co)
        _out_ds = None

    ds = None
    out_ds = None

    if verbose:
        click.echo('Complete!')
Esempio n. 5
0
def write_geotiff(out_file, in_arr, geotran, srs_wkt):
    """
    in_arr must be in channels, rows, cols
    """
    driver = gdal.GetDriverByName('GTiff')
    if in_arr.dtype == np.uint64 or in_arr.dtype == np.int64:
        in_arr = in_arr.astype(float)
    type_code = gdal_array.NumericTypeCodeToGDALTypeCode(in_arr.dtype) # get the numpy array data type
    if len(in_arr.shape) == 3: # if the shape is (bands, rows, columns)
        out = driver.Create(out_file, in_arr.shape[2], in_arr.shape[1], in_arr.shape[0], type_code)
        out.SetGeoTransform(geotran) 
        for b in range(in_arr.shape[0]):
            outband = out.GetRasterBand(b+1)
            outband.WriteArray(in_arr[b])
            outband.FlushCache()
    elif len(in_arr.shape) == 4:
        nbands = np.prod([n for n in in_arr.shape[:-2]])
        out = driver.Create(out_file, in_arr.shape[-1], in_arr.shape[-2], int(nbands), type_code)
        out.SetGeoTransform(geotran)
        b = 1
        for b1 in range(in_arr.shape[0]):
            for b2 in range(in_arr.shape[1]):
                outband = out.GetRasterBand(b)
                outband.WriteArray(in_arr[b1,b2,:,:])
                outband.FlushCache()
                b+=1
    else:
        out = driver.Create(out_file, in_arr.shape[1], in_arr.shape[0], 1, type_code)
        out.SetGeoTransform(geotran) # the origin is the upper left of the input shapefile
        outband = out.GetRasterBand(1)
        outband.WriteArray(in_arr)
        outband.FlushCache()
    out.SetProjection(srs_wkt)
Esempio n. 6
0
    def test_datatypes(self):
        datatypes = [
            np.uint8, np.int8, np.uint16, np.int16, np.uint32, np.int32,
            np.float32, np.float64
        ]
        npix_x = 100
        npix_y = 80
        nbands = 1
        output_fname = "/tmp/test_geotiff.tif"
        geot = [0, 1, 0, 0, 0, -1]
        for datatype in datatypes:
            image_data = image_utils.create_uniform_image_data(npix_x,
                                                               npix_y,
                                                               nbands,
                                                               dtype=datatype)
            gtiff_image = ImageFactory.geotiff.from_numpy_array(
                image_data, geot, crs_defs.PROJ_4326)
            gtiff_image.write_to_disk(output_fname)
            gtiff_image_from_file = ImageFactory.geotiff.from_file(
                output_fname)
            gdal_dtype = gdal_array.NumericTypeCodeToGDALTypeCode(datatype)

            assert gtiff_image.get_metadata().get_gdal_datatype(
            ) == gtiff_image_from_file.get_metadata().get_gdal_datatype(
            ) == gdal_dtype
        print("datatype tests passed")
Esempio n. 7
0
def NumPyArrayToRaster(nparr, proj, geot, nodata_value, out_raster_path, dtype=None):
    gdal.AllRegister()
    np_dt = nparr.dtype 
    if dtype == None:
        dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np_dt)

    print( "saving")
    # Check if working with multiband raster
    if len(nparr.shape) == 3:
        n_bands = nparr.shape[0] 
        for x in range(0, n_bands):
            driver = gdal.GetDriverByName('GTIFF')
            outDs = driver.Create(out_raster_path, nparr.shape[2], nparr.shape[1], n_bands, dtype,
                                  ['COMPRESS=LZW', 'TILED=YES', 'BLOCKXSIZE=128', 'BLOCKYSIZE=128'])
            outDs.GetRasterBand(x + 1).WriteArray(nparr[x])
            outDs.GetRasterBand(x + 1).SetNoDataValue(nodata_value)
            outDs.GetRasterBand(x + 1).FlushCache()
            outDs.SetProjection(proj)
            outDs.SetGeoTransform(geot)

            outDs = None
    else:
        driver = gdal.GetDriverByName('GTIFF')
        outDs = driver.Create(out_raster_path, nparr.shape[1], nparr.shape[0], 1, dtype,
                              ['COMPRESS=LZW', 'TILED=YES', 'BLOCKXSIZE=128', 'BLOCKYSIZE=128'])
        outDs.GetRasterBand(1).WriteArray(nparr)
        outDs.GetRasterBand(1).SetNoDataValue(nodata_value)
        outDs.GetRasterBand(1).FlushCache()
        outDs.SetProjection(proj)
        outDs.SetGeoTransform(geot)
        outDs = None
Esempio n. 8
0
def create_dataset(geometry, cellsize, fillvalue, dtype, path):
    """ The big sparse target dateset"""
    # properties
    a, b, c, d = cellsize[0], 0.0, 0.0, -cellsize[1]
    x1, x2, y1, y2 = geometry.GetEnvelope()
    p, q = a * (x1 // a), d * (y2 // d)

    width = -int((p - x2) // a)
    height = -int((q - y1) // d)
    geo_transform = p, a, b, q, c, d
    projection = geometry.GetSpatialReference().ExportToWkt()

    # data type from store, no data value max of that type
    data_type = gdal_array.NumericTypeCodeToGDALTypeCode(dtype)
    no_data_value = fillvalue

    # create
    options = [
        'TILED=YES', 'BIGTIFF=YES', 'SPARSE_OK=TRUE', 'COMPRESS=DEFLATE'
    ]
    dataset = DRIVER_GDAL_GTIFF.Create(
        path,
        width,
        height,
        1,
        data_type,
        options,
    )
    dataset.SetProjection(projection)
    dataset.SetGeoTransform(geo_transform)
    dataset.GetRasterBand(1).SetNoDataValue(no_data_value)

    return dataset
Esempio n. 9
0
def _create_geotiff(filePath, binary, ripDic, metadataDic):
    x = int(ripDic["FT_DATASET_ROWS"])
    y = int(ripDic["FT_DATASET_COLUMNS"])
    # thirdVal's value in the 'Affine GeoTransform' relationship is multiplied by a coefficient of 0, so we always expect it to be zero. Same with fifthVal
    # In case this ever changes, we set them here rather than using magic numbers
    thirdVal = 0
    fifthVal = 0
    upperLeft = ripDic["FT_DATASET_GRID_UPPER_LEFT_XY"]
    yMax = float(ripDic["FT_DATASET_GEOG_NORTH_BOUND_LATITUDE"])
    yMin = float(ripDic["FT_DATASET_GEOG_SOUTH_BOUND_LATITUDE"])
    xMin = float(ripDic["FT_DATASET_GEOG_WEST_BOUND_LONGITUDE"])
    xMax = float(ripDic["FT_DATASET_GEOG_EAST_BOUND_LONGITUDE"])
    xRes = (xMax - xMin) / float(x)
    yRes = (yMax - yMin) / float(y)
    numberBands = 1
    # EASEGRID Global
    EPSG = 3410

    # create geoTransform in accordance with relationship described at https://gdal.org/user/raster_data_model.html#affine-geotransform
    geoTransform = (xMin, xRes, thirdVal, yMax, fifthVal, -yRes)

    gdalType = gdal_array.NumericTypeCodeToGDALTypeCode(binary.dtype)

    geoTiff = gdal.GetDriverByName('GTiff').Create(filePath, y, x, numberBands,
                                                   gdalType)
    geoTiff.SetGeoTransform(geoTransform)
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(EPSG)
    geoTiff.SetProjection(srs.ExportToWkt())
    geoTiff.GetRasterBand(1).WriteArray(binary)
    geoTiff.FlushCache()
    return
Esempio n. 10
0
def create_geotiff(suffix, Array, NDV, xsize, ysize, GeoT, Projection):
    '''
    Creates new GeoTiff from array
    '''
    DataType = gdal_array.NumericTypeCodeToGDALTypeCode(Array.dtype)

    if type(DataType) != np.int:
        if DataType.startswith('gdal.GDT_') == False:
            DataType = eval('gdal.GDT_' + DataType)

    NewFileName = suffix + '.tif'
    zsize = Array.shape[0]

    # create a driver
    driver = gdal.GetDriverByName('GTiff')
    # Set nans to the original No Data Value
    Array[np.isnan(Array)] = NDV
    # Set up the dataset with zsize bands
    DataSet = driver.Create(NewFileName, xsize, ysize, zsize, DataType)
    DataSet.SetGeoTransform(GeoT)
    DataSet.SetProjection(Projection.ExportToWkt())
    # Write each slice of the array along the zsize
    for i in xrange(0, zsize):
        DataSet.GetRasterBand(i + 1).WriteArray(Array[i])
        DataSet.GetRasterBand(i + 1).SetNoDataValue(NDV)

    DataSet.FlushCache()
    return NewFileName
Esempio n. 11
0
def array_to_raster(array, tx, prj, driver, out_path, dtype=None, nodata=None, silent=False):
    # From intersectMask.py
    '''
    Save a numpy array as a new raster
    '''
    if not silent: print 'Saving raster...'
    rows, cols = array.shape
    
    # Save new raster
    if not dtype:
        np_dtype = get_min_numpy_dtype(array)
        array = array.astype(np_dtype)
        dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np_dtype)
    if driver.ShortName == 'GTiff':
        out_ds = driver.Create(out_path, cols, rows, 1, dtype, ['TILED=YES'])
    else:
        out_ds = driver.Create(out_path, cols, rows, 1, dtype)
    if not out_ds:
        import pdb; pdb.set_trace()
        raise IOError('\nCould not create ' + out_path)
    
    # Write the data
    band = out_ds.GetRasterBand(1)
    band.WriteArray(array)
    
    # Flush data to disk
    band.FlushCache()
    if nodata != None: band.SetNoDataValue(nodata)

    # Georeference the image and set the projection
    out_ds.SetGeoTransform(tx)
    out_ds.SetProjection(prj)
    if not silent: print 'Raster written to:\n', out_path
Esempio n. 12
0
def array2geotiff(array, outfile_name, no_data_value, xsize, ysize, 
                  originX, originY, pixelWidth, pixelHeight,
                  compression='LZW'):
    
    """
    This function writes a numpy array into a GeoTIFF-file.
    If compression is not set to anything else, the file is compressed with LZW.
    It is based on the gdal-package.
    """
    
    # the array has to be flipped upside down if originY is at the bottom-left (equal to pixelHeight > 0)
    if pixelHeight > 0:
        array = np.flipud(array)
    
    # create raster
    DataType = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype)
    driver = gdal.GetDriverByName('GTiff')
    
    if compression == None:
        compression = str(compression)
    compression = ['COMPRESS=' + compression]
    out_raster = driver.Create(outfile_name + '.tif', xsize, ysize, 1, DataType, options=compression)
    out_raster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
    
    out_raster_SRS = osr.SpatialReference()
    out_raster_SRS.ImportFromEPSG(4326)
    out_raster.SetProjection(out_raster_SRS.ExportToWkt())
    
    out_raster.GetRasterBand(1).WriteArray(array)
    out_raster.GetRasterBand(1).SetNoDataValue(no_data_value)
Esempio n. 13
0
def array2geotiff_rastercopy(array, outfile_name, raster,
                             compression='LZW'):
    
    """
    This function writes a numpy array into a GeoTIFF-file.
    Properties are copied from the blueprint raster provided.
    If compression is not set to anything else, the file is compressed with LZW.
    It is based on the gdal-package.
    """
    
    # create raster
    DataType = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype)
    driver = gdal.GetDriverByName('GTiff')
    
    if compression == None:
        compression = str(compression)
    compression = ['COMPRESS=' + compression]
    out_raster = driver.Create(outfile_name + '.tif', raster.RasterXSize, raster.RasterYSize, 1, DataType, options=compression)
    out_raster.SetGeoTransform(raster.GetGeoTransform())

    out_raster_SRS = osr.SpatialReference()
    out_raster_SRS.ImportFromEPSG(4326)
    out_raster.SetProjection(out_raster_SRS.ExportToWkt())
    
    out_raster.GetRasterBand(1).WriteArray(array)
    out_raster.GetRasterBand(1).SetNoDataValue(raster.GetRasterBand(1).GetNoDataValue())
Esempio n. 14
0
def to_gdal_dataset(outpath, array):
    driver = gdal.GetDriverByName("GTiff")
    dtype = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype)
    length, width = array.shape
    dset = driver.Create(outpath, xsize=width, ysize=length, bands=1,
                         eType=dtype)
    dset.GetRasterBand(1).WriteArray(array)
def dtype_np2gdal(dtype_np):
    # TODO: Write docstring.

    if dtype_np == np.bool:
        promote_dtype = np.uint8
    elif dtype_np == np.int8:
        promote_dtype = np.int16
    elif dtype_np == np.float16:
        promote_dtype = np.float32
    else:
        promote_dtype = None

    if promote_dtype is not None:
        warn(
            "NumPy array data type ({}) does not have equivalent GDAL data type and is not "
            "supported, but can be safely promoted to {}".format(
                dtype_np,
                promote_dtype(1).dtype))
        dtype_np = promote_dtype

    dtype_gdal = gdal_array.NumericTypeCodeToGDALTypeCode(dtype_np)
    if dtype_gdal is None:
        raise InvalidArgumentError(
            "NumPy array data type ({}) does not have equivalent "
            "GDAL data type and is not supported".format(dtype_np))

    return dtype_gdal, promote_dtype
Esempio n. 16
0
def write_pred_chips(output_path, base_raster, pred_struct, chip_key='predict', ref_shp=None, output_format='GTiff'):
    driver = gdal.GetDriverByName(output_format)
    base_ds = gdal.Open(base_raster)

    x_start, pixel_width, _, y_start, _, pixel_height = base_ds.GetGeoTransform()
    x_size = base_ds.RasterXSize
    y_size = base_ds.RasterYSize

    srs = osr.SpatialReference()
    srs.ImportFromWkt(base_ds.GetProjectionRef())

    num_bands = pred_struct[chip_key][0].shape[-1]
    data_type = gdal_array.NumericTypeCodeToGDALTypeCode(pred_struct[chip_key][0].dtype)

    out_ds = driver.Create(output_path, x_size, y_size, num_bands, data_type)
    out_ds.SetGeoTransform((x_start, pixel_width, 0, y_start, 0, pixel_height))
    out_ds.SetProjection(srs.ExportToWkt())

    for i in range(1, num_bands + 1):
        out_band = out_ds.GetRasterBand(i)
        for idx in range(0, len(pred_struct[chip_key])):
            chip = pred_struct[chip_key][idx]
            chip_band = chip[:, :, i - 1]
            coord = pred_struct['coords'][idx]
            x_start = coord['upper_row'] + round(pred_struct['overlap'][0] / 2)
            y_start = coord['left_col'] + round(pred_struct['overlap'][1] / 2)
            out_band.WriteArray(chip_band, y_start, x_start)

    out_band.FlushCache()
    out_ds = None

    iutils.clip_img_by_network_output(output_path, pred_struct['overlap'])
    if ref_shp is not None:
        iutils.clip_by_aggregated_polygons(output_path, ref_shp, output_path, no_data=0)
Esempio n. 17
0
    def save_data(self):
        """
        Saves data into a local GeoTiff file
        """
        driver = gdal.GetDriverByName('GTiff')
        driver_options = [
            "COMPRESS=LZW", "BIGTIFF=YES", "PREDICTOR=1", "TILED=YES",
            "BLOCKXSIZE=256", "BLOCKYSIZE=256", "INTERLEAVE=BAND"
        ]

        # Get GDAL datatype from NumPy datatype
        dtype = gdal_array.NumericTypeCodeToGDALTypeCode(self.array.dtype)

        # Create destination dataset
        if len(self.array.shape) == 3:
            # 3D array
            bands, rows, cols = self.array.shape
        else:
            # 2D array
            bands = 1
            rows, cols = self.array.shape

        dst_ds = driver.Create(self.output_filename, cols, rows, bands, dtype,
                               driver_options)

        # Set cartographic projection
        dst_ds.SetProjection(self.projection)
        dst_ds.SetGeoTransform(self.geotransform)

        # Write bands
        for band in range(bands):
            dst_ds.GetRasterBand(band + 1).WriteArray(self.array[band])

        # Flush to disk
        dst_ds = None
Esempio n. 18
0
def writeGTiff(dstImage, outputPath, projection, coordinates, dtype = None):
    """
    @brief Writes a GeoTiff file created from an existing coordinate-system
    @Note Coordinates: [Top-Left X, W-E Resolution, 0, Top Left Y, 0, N-S Resolution]
    """
    driver = gdal.GetDriverByName('GTiff')
    #Add dimension for a single band-image
    if(dstImage.ndim is 2):
        dstImage = dstImage[..., np.newaxis]  
    #Set output dtype if not specified
    if(dtype == None):
        dtype = gdal_array.NumericTypeCodeToGDALTypeCode(dstImage.dtype)
    dataset = driver.Create(outputPath, dstImage.shape[1], dstImage.shape[0] , dstImage.shape[2], dtype)
    if(dataset == None):
        raise OSError ("GDAL Could not create {0}".format(outputPath))
    if(not coordinates or len(coordinates) != 6):
        raise ValueError("Geotransform empty or unknown: {0}".format(coordinates))
    dataset.SetGeoTransform(coordinates)  
    if(not projection):
        raise ValueError("Projection empty or unknown: {0}".format(projection))
    dataset.SetProjection(projection)
    for index in range(dstImage.shape[2]):
        dataset.GetRasterBand(index+1).WriteArray(dstImage[:,:,index])
    dataset.FlushCache()  # Write to disk.
    dataset = None
    driver = None
    return 0
Esempio n. 19
0
def geotiff(outDir,outName,resolution, fill_value,ImageContainer, array):
    
    result_data_nn=array

    outputName = os.path.normpath(os.path.join(outDir, '{}_2100.tif'.format(outName))) # Generate output filename
    print(outputName)
    nRow, nCol = result_data_nn.shape                                           # Define rows/cols from array size
    dataType = gdal_array.NumericTypeCodeToGDALTypeCode(result_data_nn.dtype)   #result_data_nn.dtype # Define output data type or np.int16 for smaller files
    if dataType==3:
        fill_value=32767

    driver = gdal.GetDriverByName('GTiff')                              
    
    outFile = driver.Create(outputName, nCol, nRow, 1, dataType)                        # Specify parameters of the GeoTIFF
    band = outFile.GetRasterBand(1)                                                     # Get band 1
    band.WriteArray(result_data_nn)                                                     # Write data array to band 1
    band.FlushCache   
                                                         # Export data
    band.SetNoDataValue(fill_value)
    uul=ImageContainer.geo_def.upper_left_extent
                                              # Set fill value
    geoInfo = (uul[0], resolution, 0, uul[1], 0, -resolution)         # Define geotransform parameters
    outFile.SetGeoTransform(geoInfo)
    
    srs = osgeo.osr.SpatialReference()
    srs.ImportFromEPSG(2100)                                                    # Set Geotransform
    outFile.SetProjection(srs.ExportToWkt())                                                              # Set projection
    outFile = None          
Esempio n. 20
0
def gdal_ds_from_array(arr):
    """
    Returns an in-memory GDAL dataset that is a proxy to the given array
    http://www.gdal.org/frmt_mem.html
    """
    # Ensure 3D
    arr = arr.reshape(arr.shape[0], arr.shape[1], -1)

    assert arr.flags.c_contiguous
    # http://stackoverflow.com/questions/11264838/how-to-get-the-memory-address-of-a-numpy-array-for-c
    pointer, read_only_flag = arr.__array_interface__['data']
    gdal_dtype = gdal_array.NumericTypeCodeToGDALTypeCode(arr.dtype)
    print "arr dtype : ", arr.dtype, " => gdal dtype : ", \
        gdal.GetDataTypeName(gdal_dtype)
    ds = gdal.Open("MEM:::" + ",".join([
        "DATAPOINTER=%d" % pointer,
        "DATATYPE=%d" % gdal_dtype,
        "LINES=%d" % arr.shape[0],
        "PIXELS=%d" % arr.shape[1],
        "BANDS=%d" % arr.shape[2],
        "LINEOFFSET=%d" % arr.strides[0],
        "PIXELOFFSET=%d" % arr.strides[1],
        "BANDOFFSET=%d" % arr.strides[2]
    ]))
    assert ds is not None, "Failed to create in-memory dataset"
    # Kind of ugly hack to keep a reference on arr to avoid garbage collection
    ds._arr = arr
    return ds
Esempio n. 21
0
def create_raster_dataset(data, coords, projection=None, nodata=-9999):
    """ Create In-Memory Raster Dataset

    Parameters
    ----------
    data : :class:`numpy:numpy.ndarray`
        Array of shape (rows, cols) or (bands, rows, cols) containing
        the data values.
    coords : :class:`numpy:numpy.ndarray`
        Array of shape (nrows, ncols, 2) containing pixel center coordinates
        or
        Array of shape (nrows+1, ncols+1, 2) containing pixel edge coordinates
    projection : osr object
        Spatial reference system of the used coordinates, defaults to None.
    nodata : int
        Value of NODATA

    Returns
    -------
    dataset : gdal.Dataset
        In-Memory raster dataset

    Note
    ----
    The origin of the provided data and coordinates is UPPER LEFT.
    """

    # align data
    data = data.copy()
    if data.ndim == 2:
        data = data[np.newaxis, ...]
    bands, rows, cols = data.shape

    # create In-Memory Raster with correct dtype
    mem_drv = gdal.GetDriverByName('MEM')
    gdal_type = gdal_array.NumericTypeCodeToGDALTypeCode(data.dtype)
    dataset = mem_drv.Create('', cols, rows, bands, gdal_type)

    # initialize geotransform
    x_ps, y_ps = coords[1, 1] - coords[0, 0]
    if data.shape[-2:] == coords.shape[0:2]:
        upper_corner_x = coords[0, 0, 0] - x_ps / 2
        upper_corner_y = coords[0, 0, 1] - y_ps / 2
    else:
        upper_corner_x = coords[0, 0, 0]
        upper_corner_y = coords[0, 0, 1]
    geotran = [upper_corner_x, x_ps, 0, upper_corner_y, 0, y_ps]
    dataset.SetGeoTransform(geotran)

    if projection:
        dataset.SetProjection(projection.ExportToWkt())

    # set np.nan to nodata
    dataset.GetRasterBand(1).SetNoDataValue(nodata)

    for i, band in enumerate(data, start=1):
        dataset.GetRasterBand(i).WriteArray(band)

    return dataset
Esempio n. 22
0
def create_dataset(array,
                   geo_transform=None,
                   projection=None,
                   no_data_value=None):
    """
    Create and return a gdal dataset.

    :param array: A numpy array.
    :param geo_transform: 6-tuple of floats
    :param projection: wkt projection string
    :param no_data_value: integer or float

    This is the fastest way to get a gdal dataset from a numpy array, but
    keep a reference to the array around, or a segfault will occur. Also,
    don't forget to call FlushCache() on the dataset after any operation
    that affects the array.
    """
    # prepare dataset name pointing to array
    datapointer = array.ctypes.data
    bands, lines, pixels = array.shape
    datatypecode = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype.type)
    datatype = gdal.GetDataTypeName(datatypecode)
    bandoffset, lineoffset, pixeloffset = array.strides
    # if projection is wrong there will be a segfault in RasterizeLayer
    projection = osr.GetUserInputAsWKT(str(projection))

    dataset_name_template = ("MEM:::"
                             "DATAPOINTER={datapointer},"
                             "PIXELS={pixels},"
                             "LINES={lines},"
                             "BANDS={bands},"
                             "DATATYPE={datatype},"
                             "PIXELOFFSET={pixeloffset},"
                             "LINEOFFSET={lineoffset},"
                             "BANDOFFSET={bandoffset}")
    dataset_name = dataset_name_template.format(
        datapointer=datapointer,
        pixels=pixels,
        lines=lines,
        bands=bands,
        datatype=datatype,
        pixeloffset=pixeloffset,
        lineoffset=lineoffset,
        bandoffset=bandoffset,
    )

    # access the array memory as gdal dataset
    dataset = gdal.Open(dataset_name, gdal.GA_Update)

    # set additional properties from kwargs
    if geo_transform is not None:
        dataset.SetGeoTransform(geo_transform)
    if projection is not None:
        dataset.SetProjection(projection)
    if no_data_value is not None:
        for i in range(len(array)):
            dataset.GetRasterBand(i + 1).SetNoDataValue(no_data_value)

    return dataset
Esempio n. 23
0
    def SavePart(self, data, outOffsetYX, cOpts=None):

        if self._Properties is None:
            raise ValueError(
                "File properties must be set first using SetProperties(RasterProps)"
            )
        rProps = self._Properties

        if outOffsetYX is None:
            outOffset = (0, 0)

        dataShape = data.shape
        currentShape = (rProps.height, rProps.width)
        if ((dataShape[0] + outOffsetYX[0]) > currentShape[0]) or (
            (dataShape[1] + outOffsetYX[1]) > currentShape[1]):
            raise ValueError(
                "data + offset are larger than the specified image size")
        if dataShape[0] == rProps.height and dataShape[1] == rProps.width:
            isFull = True
        else:
            isFull = False
        if self._Exists:
            ds = gdal.Open(self._filePath, gdal.GA_Update)

        else:
            outDir = os.path.dirname(self._filePath)
            if not os.path.exists(outDir):
                os.makedirs(outDir)
            incomingType = gdal_array.NumericTypeCodeToGDALTypeCode(data.dtype)
            if incomingType > rProps.datatype:
                Warning(
                    "Array has higher type than configured file output, values may be truncated"
                )

            outDrv = gdal.GetDriverByName('GTiff')
            if cOpts is None:
                cOpts = [
                    "TILED=YES", "SPARSE_OK=FALSE", "BIGTIFF=YES",
                    "COMPRESS=LZW", "PREDICTOR=2"
                ]
                if isFull:
                    # seem to get corruption when writing subsets of files that seems to occur more when using multithreaded
                    # writers, so use a single thread unless we are writing whole file
                    cOpts.append("NUM_THREADS=ALL_CPUS")
            ds = outDrv.Create(self._filePath, rProps.width, rProps.height, 1,
                               rProps.datatype, cOpts)
            if rProps.gt is not None:
                ds.SetGeoTransform(rProps.gt)
            if rProps.proj is not None:
                ds.SetProjection(rProps.proj)
            if rProps.ndv is not None:
                outBand = ds.GetRasterBand(1)
                outBand.SetNoDataValue(rProps.ndv)
            self._Exists = True

        outBand = ds.GetRasterBand(1)
        outBand.WriteArray(data, outOffsetYX[1], outOffsetYX[0])
        outBand.FlushCache()
        ds = None
Esempio n. 24
0
def array2geotiff(band_array, dst_filename, ref, out_datatype=None):

    """
    Wrapper to GDAL to write an array to disk in GeoTiff format.

    Args:
        band_array: array that will be written to disk
        dst_filename: full path to the output GeoTiff
        ref: reference image with defined geotransform and SRS or a tuple of the form (geotransform, SRS_wkt)
        out_datatype: GDAL datatype for the output, if None the function tries to figure out the corresponding
                        type automatically

    Returns: full path to the GeoTiff on disk.

    """

    # DEBUG
    # band_array = band_corrected_array
    # dst_filename = dst_filename
    # ref = (out_gt, prj)

    # if the input array is a masked array this will set the masked values to zero
    np.ma.set_fill_value(band_array, 0)

    # figure out the output datatype according to the type of the input array
    if not out_datatype:
        out_datatype = gdal_array.NumericTypeCodeToGDALTypeCode(band_array.dtype)

    # from tuple
    if isinstance(ref, tuple):
        geotrans = ref[0]
        proj_info = ref[1]
        cols = band_array.shape[1]
        rows = band_array.shape[0]
    # or provided reference image
    else:
        ref_image = gdal.Open(ref)
        geotrans = ref_image.GetGeoTransform()
        proj_info = ref_image.GetProjection()
        cols = round(ref_image.RasterXSize)
        rows = round(ref_image.RasterYSize)

    driver = gdal.GetDriverByName('GTiff')
    driver.Create(dst_filename, cols, rows, 1, gdal.GDT_Byte)
    out_raster = driver.Create(dst_filename, cols, rows, 1, eType=out_datatype)
    out_raster.SetGeoTransform(geotrans)
    out_raster.SetProjection(proj_info)
    outband = out_raster.GetRasterBand(1)

    if hasattr(band_array, 'mask'):
        outband.WriteArray(band_array.filled())
    else:
        outband.WriteArray(band_array)
    outband.FlushCache()

    out_raster = None
    ref_image = None

    return dst_filename
Esempio n. 25
0
def gdal_write(drv_type, img, dst, projection, coordinates, **kwargs):
    """
    General GDal Write function.
    Writes array `img` to `dst`.

    :param drv_type: The Driver type. E.g. "GTiff" or "MEM"
    :type drv_type: str
    :param img: The :class:`numpy.ndarray`
    :param dst: The destination path
    :param projection: A Gdal projection
    :type projection: str
    :param coordinates: A list of floats for the geotransform. See the description in :func:`write_geotiff`
    :type coordinates: List of float
    :keyword dtype: The desired gdal dtype
    :keyword nodata: Assign a nodata value
    :keyword options: Config options as a list of str, such as ["COMPRESS=DEFLATE"]
    :return: Writes array to `dst` and returns the dataset.
    :rtype: :class:`gdal.Dataset`
    """
    dtype = kwargs.get("dtype", None)
    nodata = kwargs.get("nodata", None)
    options = kwargs.get("options", [])
    driver = gdal.GetDriverByName(drv_type)
    # Add dimension for a single band-image
    if img.ndim == 2:
        img = img[..., np.newaxis]
    # Set output dtype if not specified. GDAL cannot write GTiff as binary files, so convert to uint8:
    if img.dtype == np.bool:
        dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np.uint8)
    if img.dtype == np.int64:
        dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np.int32)
    if not dtype:
        dtype = gdal_array.NumericTypeCodeToGDALTypeCode(img.dtype)
    img_h, img_w, n_bands = img.shape
    mem = driver.Create(dst, img_w, img_h, n_bands, dtype, options)
    mem.SetGeoTransform(coordinates)
    mem.SetProjection(projection)

    for bandIdx in range(n_bands):
        band = img[:, :, bandIdx]
        raster_band = mem.GetRasterBand(bandIdx + 1)
        raster_band.WriteArray(band)
        if nodata:
            raster_band.SetNoDataValue(nodata)
    mem.FlushCache()
    return mem
Esempio n. 26
0
def create_geotiff(suffix, Array, NDV, xsize, ysize, GeoT, Projection, nc_data,
                   filename):
    '''
        从数组中创建新的tiff图像
        Create a new tiff image from the array
        '''
    DataType = gdal_array.NumericTypeCodeToGDALTypeCode(Array.dtype)  ###

    if type(DataType) != np.int:
        if DataType.startswith('gdal.GDT_') == False:
            DataType = eval('gdal.GDT_' + DataType)

    zsize = Array.shape[0]

    #create a driver
    driver = gdal.GetDriverByName('GTiff')
    #Set nans to the original No Data Value
    Array[np.isnan(Array)] = NDV

    #Set up the dataset with zsize
    #write each slice of the array along the zsize
    Array_shape_length = len(Array.shape)
    if Array_shape_length == 3:
        for i, image in enumerate(Array, 1):
            now_file = get_time(i - 1, nc_data, var_name, filename)
            # NewFileName = outpath + var_name + netCDF4文件 + 1999_12_31 + .tif
            NewFileName = suffix + '\\' + now_file + '.tif'
            print('Outpath:', NewFileName, '\n')
            DataSet = driver.Create(NewFileName, xsize, ysize, 1, DataType)
            DataSet.SetGeoTransform(GeoT)
            DataSet.SetProjection(Projection.ExportToWkt())
            #判读数据的维度
            #if Array_shape_length == 3:
            DataSet.GetRasterBand(1).WriteArray(image)
            #else:
            # 数据为n*7*11的矩阵,此代码取的为第0层,一共n层
            #DataSet.GetRasterBand(1).WriteArray(image[0])
            DataSet.GetRasterBand(1).SetNoDataValue(NDV)
            DataSet.FlushCache()
            DataSet = None  # close the tif file
            print('The ' + now_file + '.tif' ' has finished!!!\n')
    else:
        for i, image in enumerate(Array, 1):
            now_file = get_time(i - 1, nc_data, var_name, filename)
            # NewFileName = outpath + var_name + netCDF4文件 + 1999_12_31 + .tif
            NewFileName = suffix + '\\' + now_file + '.tif'
            print('Outpath:', NewFileName, '\n')
            DataSet = driver.Create(NewFileName, xsize, ysize, 1, DataType)
            DataSet.SetGeoTransform(GeoT)
            DataSet.SetProjection(Projection.ExportToWkt())
            #判读数据的维度
            #数据为n*7*11的矩阵,此代码取的为第0层,一共n层
            DataSet.GetRasterBand(1).WriteArray(image[0])
            DataSet.GetRasterBand(1).SetNoDataValue(NDV)
            DataSet.FlushCache()
            DataSet = None  # close the tif file
            print('The ' + now_file + '.tif' ' has finished!!!\n')
Esempio n. 27
0
def cut_raster_yboundaries(raster, outfile_name, y_min_new, y_max_new):
    """
    This function cuts a raster-file to y_min_new and y_max_new values and writes it into GeoTIFF-file.
    It is based on the gdal-package.
    For (in)rasters with the origin at y_min, the raster is flipped and the origin set to y_max.
    """

    xSize_old = raster.RasterXSize
    ySize_old = raster.RasterYSize
    geotransform = raster.GetGeoTransform()
    x_min_old = geotransform[0]
    pixelWidth = geotransform[1]
    pixelHeight = geotransform[5]

    #x_max_old = x_min_old + xSize_old*pixelWidth
    if pixelHeight < 0:
        y_min_old = geotransform[3] + ySize_old * pixelHeight
        y_max_old = geotransform[3]
    else:
        y_max_old = geotransform[3] + ySize_old * pixelHeight
        y_min_old = geotransform[3]

    # calculate rows and columns of raster array to cut:
    #cut_left = abs(x_max_old - x_max)/geotransform[3]
    #cut_right = abs(x_min_old - x_min)/geotransform[3]
    cut_top = round(abs(round(y_max_old - y_max_new) / pixelHeight))
    cut_bottom = round(abs(round(y_min_old - y_min_new) / pixelHeight))

    array = raster.ReadAsArray()
    # the array has to be flipped upside down if originY is at the bottom-left (equal to pixelHeight > 0)
    if pixelHeight > 0:
        array = np.flipud(array)
    array_cut = array[cut_top:array.shape[0] - cut_bottom].copy()
    array = None

    ySize_new = ySize_old - cut_top - cut_bottom
    if pixelHeight > 0:
        pixelHeight = -pixelHeight

    no_data_value = raster.GetRasterBand(1).GetNoDataValue()

    DataType = gdal_array.NumericTypeCodeToGDALTypeCode(array_cut.dtype)
    driver = gdal.GetDriverByName('GTiff')
    out_raster_SRS = osr.SpatialReference()
    out_raster_SRS.ImportFromEPSG(4326)

    out_raster = driver.Create(outfile_name + '.tif', xSize_old, ySize_new, 1,
                               DataType)
    out_raster.SetGeoTransform(
        (x_min_old, pixelWidth, 0, y_max_new, 0, pixelHeight))
    out_raster.SetProjection(out_raster_SRS.ExportToWkt())
    out_raster.GetRasterBand(1).WriteArray(array_cut)
    out_raster.GetRasterBand(1).SetNoDataValue(no_data_value)

    return out_raster

    array_cut = None
Esempio n. 28
0
    def processAlgorithm(self, parameters, context, feedback):

        entrada = self.parameterAsRasterLayer(parameters, self.INPUT, context)
        if entrada is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        n_banda = self.parameterAsInt(parameters, self.BAND, context)
        if n_banda is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.BAND))

        saida = self.parameterAsFileOutput(parameters, self.OUTPUT, context)

        Carregar = self.parameterAsBool(parameters, self.OPEN, context)

        # Abrir banda
        feedback.pushInfo(
            self.tr('Reading the selected band...',
                    'Lendo a banda selecionada...'))
        image = gdal.Open(entrada.dataProvider().dataSourceUri())
        banda = image.GetRasterBand(n_banda).ReadAsArray()
        prj = image.GetProjection()
        geotransform = image.GetGeoTransform()

        # Criar objeto CRS
        CRS = osr.SpatialReference(wkt=prj)

        # Obter número de linhas e colunas
        cols = image.RasterXSize
        rows = image.RasterYSize
        image = None  # fechar magem

        # Pegar tipo de dado do array
        GDT = gdal_array.NumericTypeCodeToGDALTypeCode(banda.dtype)

        # Criar imagem com uma única banda
        feedback.pushInfo(
            self.tr('Writing the selected band...',
                    'Escrevendo a banda selecionada...'))
        nova_imagem = gdal.GetDriverByName('GTiff').Create(
            saida, cols, rows, 1, GDT)
        nova_imagem.SetGeoTransform(geotransform)
        nova_imagem.SetProjection(CRS.ExportToWkt())
        nova_imagem.GetRasterBand(1).WriteArray(banda)
        nova_imagem.FlushCache()  # Escrever no disco
        nova_imagem = None  # Salvar e fechar
        CRS = None

        feedback.pushInfo(
            self.tr('Operation completed successfully!',
                    'Operação finalizada com sucesso!'))
        feedback.pushInfo('Leandro França - Eng Cart')
        self.CAMINHO = saida
        self.CARREGAR = Carregar
        return {self.OUTPUT: saida}
Esempio n. 29
0
def convert_numpy_type_to_gdal_type(array):
    typemap = {}
    for name in dir(np):
        obj = getattr(np, name)
        if hasattr(obj, 'dtype'):
            try:
                npn = obj(0)
                nat = np.asscalar(npn)
                if gdal_array.NumericTypeCodeToGDALTypeCode(npn.dtype.type):
                    typemap[npn.dtype.
                            name] = gdal_array.NumericTypeCodeToGDALTypeCode(
                                npn.dtype.type)
            except:
                pass
    typemap['int64'] = 7
    try:
        return typemap[array.dtype.name]
    except KeyError:
        raise KeyError('Unsupported or undetectable data type!')
Esempio n. 30
0
    def GDTNumCode(self, dtype):
        import numpy as np
        from osgeo import gdal, gdal_array

        typemap = {}
        for name in dir(np):
            obj = getattr(np, name)
            if hasattr(obj, 'dtype'):
                try:
                    npn = obj(0)
                    nat = np.asscalar(npn)
                    if gdal_array.NumericTypeCodeToGDALTypeCode(
                            npn.dtype.type):
                        typemap[
                            npn.dtype.
                            name] = gdal_array.NumericTypeCodeToGDALTypeCode(
                                npn.dtype.type)
                except:
                    pass
        return typemap[dtype]