Esempio n. 1
0
    def to_raster(self, filename, driver='GTiff'):

        from osgeo import gdal_array
        # convert from numpy type to gdal type.
        gdal_type = dict((v, k) for (k, v) \
                in gdal_array.codes.items())[self.dtype.type]

        # make it so we can loop over 3rd axis.
        if len(self.shape) == 2:
            a = self[:, :, np.newaxis]
        else:
            a = self
        bbox = self.extent
        ri = self.agoodle.ri
        d = gdal.GetDriverByName(driver)

        # NOTE: switch of shape[0] and [1] !!!!
        tif = d.Create(filename, a.shape[1], a.shape[0], a.shape[2], gdal_type)
        xsize = (bbox[2] - bbox[0]) / (self.shape[1])
        ysize = (bbox[1] - bbox[3]) / (self.shape[0])
        # could be a bit off since we had to round to pixel.
        assert abs(xsize - ri.xsize) < 1
        assert abs(ysize - ri.ysize) < 1, (ysize, ri.ysize, xsize, ri.xsize)
        tif.SetGeoTransform([bbox[0], xsize, 0, bbox[3], 0, ysize])
        for i in range(a.shape[2]):
            b = tif.GetRasterBand(i + 1)
            ct = self.agoodle.raster.GetRasterBand(i + 1).GetRasterColorTable()
            if ct:
                b.SetRasterColorTable(ct)
            gdal_array.BandWriteArray(b, a[:, :, i])
        tif.SetProjection(self.agoodle.raster.GetProjection())
        return tif
def create_tif_mask(in_fname, out_fname):
    # Open the raster file
    raster = gdal.Open(in_fname, gdal.GA_ReadOnly)
    band_1 = raster.GetRasterBand(1)

    # Read the data as a numpy array
    data_1 = gdal_array.BandReadAsArray(band_1)

    # Create a boolean band with all 1's
    mask = (data_1 >= 0).astype(int)
    assert np.mean(mask) == 1

    # Write the output mask
    driver = gdal.GetDriverByName("GTiff")
    ds_out = driver.Create(out_fname, raster.RasterXSize, raster.RasterYSize,
                           1, band_1.DataType)
    gdal_array.CopyDatasetInfo(raster, ds_out)
    band_out = ds_out.GetRasterBand(1)
    gdal_array.BandWriteArray(band_out, mask)

    # Close the datasets
    band_1 = None
    raster = None
    band_out = None
    ds_out = None
Esempio n. 3
0
 def pixelProfileToRaster(self,
                          idx_row=0,
                          idx_col=0,
                          currentPixelArray=None):
     ''' Saves the current temporal profile for selected pixel @(idx_row,idx_col)
     to a previous created empty raster '''
     if self.out_filename == None:
         self.update(
         )  # It will updated itself if no out filename is given.
     self.status = None
     print('updating pixel in', self.out_filename + self.outfileExt)
     fullpath = self.out_path + self.out_filename + self.outfileExt
     updatedataset = og.Open(fullpath, ogc.GA_Update)
     if currentPixelArray == None:
         currentPixelArray = self.getPixelProfile(idx_row, idx_col)
     nbands = currentPixelArray.shape[0]
     for iband in range(nbands):
         eprofile = np.array(currentPixelArray[iband])
         eprofile.shape = (1, -1)  #shape (1,1)
         currentBand = updatedataset.GetRasterBand(iband + 1)
         oga.BandWriteArray(currentBand,
                            eprofile,
                            xoff=idx_col,
                            yoff=idx_row)
         pass
     updatedataset = None
     self.status = True
     pass
Esempio n. 4
0
def write_array_to_file(dst_filename: PathLikeOrStr,
                        a: MaybeSequence[np.ndarray],
                        gdal_dtype=None) -> gdal.Dataset:
    driver_name = GetOutputDriverFor(dst_filename, is_raster=True)
    driver = gdal.GetDriverByName(driver_name)
    a_shape = a[0].shape
    if len(a_shape) == 1:
        # 2d array, singleband raster
        a = [a]
        bands_count = 1
    elif len(a_shape) == 2:
        # 3d array, multiband raster
        bands_count = a.shape[0]
    else:
        raise Exception('Array should have 2 or 3 dimensions')
    y_size, x_size = a[0].shape

    if gdal_dtype is None:
        np_dtype = a[0].dtype
        gdal_dtype = gdal_array.flip_code(np_dtype)
    ds = driver.Create(dst_filename, x_size, y_size, bands_count, gdal_dtype)
    if ds is None:
        raise Exception(f'failed to create: {dst_filename}')

    for bnd_num in range(bands_count):
        bnd = ds.GetRasterBand(bnd_num + 1)
        if gdal_array.BandWriteArray(bnd, a[bnd_num], xoff=0, yoff=0) != 0:
            raise Exception('I/O error')

    return ds
    def setUp(self):
        self.band = numpy.array([[0, 1], [2, 3]], dtype=numpy.uint16)
        self.mask = numpy.array([[0, 1], [0, 1]], dtype=numpy.bool)
        self.metadata = {'geotransform': (-1.0, 2.0, 0.0, 1.0, 0.0, -1.0)}

        self.test_photometric_alpha_image = 'test_photometric_alpha_image.tif'
        test_ds = gdal.GetDriverByName('GTiff').Create(
            self.test_photometric_alpha_image,
            2,
            2,
            4,
            gdal.GDT_UInt16,
            options=['PHOTOMETRIC=RGB', 'ALPHA=YES'])
        gdal_array.BandWriteArray(test_ds.GetRasterBand(1), self.band)
        gdal_array.BandWriteArray(test_ds.GetRasterBand(2), self.band)
        gdal_array.BandWriteArray(test_ds.GetRasterBand(3), self.band)
        gdal_array.BandWriteArray(test_ds.GetRasterBand(4), self.mask)
        test_ds.SetGeoTransform(self.metadata['geotransform'])
def polygonize(shapepath, file, rasterpath):
    srcarray,projection,geotrans, shape = GetRasterDataSource(file, rasterpath)
    print "Start polygonizing.."
    start = time.time()
    srcarray[srcarray > 1] = 0 #we are interested in the class 1, we put everything else to 0
    drv = gdal.GetDriverByName('MEM')
    srs = osr.SpatialReference()
    srs.ImportFromWkt(projection)
    src_ds  = drv.Create('', shape[1], shape[0], 1, gdal.GDT_UInt16)
    src_ds.SetGeoTransform(geotrans)

    src_ds.SetProjection(projection)
    # gdal_array.BandWriteArray(src_ds.GetRasterBand(1), srcarray.T)
    gdal_array.BandWriteArray(src_ds.GetRasterBand(1), srcarray)

    srcband = src_ds.GetRasterBand(1)

    drv = ogr.GetDriverByName("ESRI Shapefile")
    dst_ds = drv.CreateDataSource(shapepath + file + ".shp")

    dst_layer = dst_ds.CreateLayer(shapepath + file, srs = srs)
    new_field = ogr.FieldDefn("type", ogr.OFTInteger)
    dst_layer.CreateField(new_field)

    new_field = None

    new_field = ogr.FieldDefn("area", ogr.OFTReal)

    # new_field.SetWidth(32)
    # new_field.SetPrecision(2) #added line to set precision (for floating point)
    dst_layer.CreateField(new_field)

    gdal.Polygonize(srcband, srcband, dst_layer, 0, [], callback = None )
    print "Number of features detected: ", dst_layer.GetFeatureCount()

    for feature in dst_layer:
        geom = feature.GetGeometryRef()
        area = geom.GetArea()
        feature.SetField("area", area)
        dst_layer.SetFeature(feature)

        # Filter per size
        if (geom.GetArea() < 1) or (geom.GetArea() > 100):
            dst_layer.DeleteFeature(feature.GetFID())


    dst_layer.SyncToDisk()
    dst_ds.ExecuteSQL("REPACK " + file)

    print "Number of features after deleting: ", dst_layer.GetFeatureCount()
    dst_ds = None

    print "*---------------------------*"
    print "Shapefile correctly saved in: " + shapepath
    end = time.time()
    print "Time for polygonizing: "
    print (end-start)
Esempio n. 7
0
def writeFloatRaster(outpath,inArray,template_DS,FLOAT_NODATA=-9999,mode=0777):#writes a single band raster to the same extent and projection as the template DS
	image_driver=template_DS.GetDriver()
	image_out_DS=image_driver.Create(outpath,template_DS.RasterXSize,template_DS.RasterYSize,template_DS.RasterCount,GDT_Float32)
	projection=template_DS.GetProjectionRef()
	geotransform=template_DS.GetGeoTransform()
	image_out_DS.SetProjection(projection)
	image_out_DS.SetGeoTransform(geotransform)
	image_band_out=image_out_DS.GetRasterBand(1)
	image_band_out.SetNoDataValue(FLOAT_NODATA)
	image_band_out=gdal_array.BandWriteArray(image_band_out,inArray)
	os.chmod(outpath,mode)
	image_out_DS=None
Esempio n. 8
0
def RasterDifference(RasterFile1,
                     RasterFile2,
                     raster_band=1,
                     OutFileName="Test.outfile",
                     OutFileType="ENVI"):
    """
    Takes two rasters of same size and subtracts second from first,
    e.g. Raster1 - Raster2 = raster_of_difference
    then writes it out to file
    """

    Raster1 = gdal.Open(RasterFile1)
    Raster2 = gdal.Open(RasterFile2)

    print("RASTER 1: ")
    print(Raster1.GetGeoTransform())
    print(Raster1.RasterCount)
    print(Raster1.GetRasterBand(1).XSize)
    print(Raster1.GetRasterBand(1).YSize)
    print(Raster1.GetRasterBand(1).DataType)

    print("RASTER 2: ")
    print(Raster2.GetGeoTransform())
    print(Raster2.RasterCount)
    print(Raster2.GetRasterBand(1).XSize)
    print(Raster2.GetRasterBand(1).YSize)
    print(Raster2.GetRasterBand(1).DataType)

    raster_array1 = np.array(Raster1.GetRasterBand(raster_band).ReadAsArray())
    raster_array2 = np.array(Raster2.GetRasterBand(raster_band).ReadAsArray())

    assert (raster_array1.shape == raster_array2.shape)
    print("Shapes: ", raster_array1.shape, raster_array2.shape)

    difference_raster_array = raster_array1 - raster_array2

    #    import matplotlib.pyplot as plt
    #
    #    plt.imshow(difference_raster_array)
    #

    driver = gdal.GetDriverByName(OutFileType)

    dsOut = driver.Create(OutFileName,
                          Raster1.GetRasterBand(1).XSize,
                          Raster1.GetRasterBand(1).YSize, 1, gdal.GDT_Float32)
    #Raster1.GetRasterBand(raster_band).DataType)

    gdal_array.CopyDatasetInfo(Raster1, dsOut)
    bandOut = dsOut.GetRasterBand(1)
    gdal_array.BandWriteArray(bandOut, difference_raster_array)
Esempio n. 9
0
    def save(self, filename):
        band_count = len(self.bands)
        ysize, xsize = self.bands[0].shape

        options = []
        if band_count == 3:
            options.append('PHOTOMETRIC=RGB')

        if self.alpha is not None:
            band_count += 1
            options.append('ALPHA=YES')

        datatype = gdal_array.NumericTypeCodeToGDALTypeCode(
            self.bands[0].dtype.type)

        gdal_ds = gdal.GetDriverByName('GTIFF').Create(filename,
                                                       xsize,
                                                       ysize,
                                                       band_count,
                                                       datatype,
                                                       options=options)

        # Save georeferencing information
        if 'projection' in self.metadata.keys():
            gdal_ds.SetProjection(self.metadata['projection'])
        if 'geotransform' in self.metadata.keys():
            gdal_ds.SetGeoTransform(self.metadata['geotransform'])
        if 'rpc' in self.metadata.keys():
            gdal_ds.SetMetadata(self.metadata['rpc'], 'RPC')

        for i in range(len(self.bands)):
            gdal_array.BandWriteArray(gdal_ds.GetRasterBand(i + 1),
                                      self.bands[i])

        if self.alpha is not None:
            alpha = self.alpha
            alpha_band = gdal_ds.GetRasterBand(gdal_ds.RasterCount)

            # To conform to 16 bit TIFF alpha expectations transform
            # alpha to 16bit.
            if alpha_band.DataType == gdal.GDT_UInt16:
                alpha = ((alpha.astype(np.uint32) * 65535) / 255).astype(
                    np.uint16)
Esempio n. 10
0
    def rowProfileToImage(
            self,
            idx_row=0,
            currentRowArray=None,
            rasterFormat='ERDAS'):  #currentRowArray.shape (nbands,1 row,ncols)
        ''' Saves the current temporal profile for selected pixel @(idx_row,idx_col)
        to a previous created empty raster '''
        def update():
            self.out_filename = self.name[:-4] + '_new'
            self.outfileExt = self.name[-4:]
            if self.out_path == None:
                self.out_path = 'D://My Docs//working//out_test//'

            self.create_emptyRaster(out_path=self.out_path,\
                                    filenameWithoutExtension=self.out_filename,\
                                    outputRasterFormat=rasterFormat)
            pass

        if self.out_filename == None:
            update()  # It will updated itself if no out filename is given.
        if (self.name == (self.out_filename + self.outfileExt)):
            print('Creating an empty raster')
            update()
        self.status = None
        print('updating row in', self.out_filename + self.outfileExt)
        fullpath = self.out_path + self.out_filename + self.outfileExt
        updatedataset = og.Open(fullpath, ogc.GA_Update)
        if currentRowArray == None:  # If array in not given, retrieve the one @ given row. This allows to write other arrays instead of the image.
            currentRowArray = self.getRowProfile(idx_row)
            pass

        for iband in range(currentRowArray.shape[0]):
            currentBand = updatedataset.GetRasterBand(iband + 1)
            rowprofile = currentRowArray[iband]  # (1 row,ncols)
            oga.BandWriteArray(currentBand, rowprofile, xoff=0, yoff=idx_row)

        updatedataset = None
        self.status = True
        pass
 def _create_image_with_geotransform(self, filename):
     gdal_ds = gdal.GetDriverByName('GTiff').Create(filename, 2, 2, 1,
                                                    gdal.GDT_UInt16)
     gdal_array.BandWriteArray(gdal_ds.GetRasterBand(1),
                               np.ones((2, 2), dtype=np.uint16))
     gdal_ds.SetGeoTransform([-1.0, 1.0, 0.0, 1.0, 0.0, -1.0])
Esempio n. 12
0
def process(parsed, target, temp_metatile, temp_processed, save_offsetx,
            save_offsety, save_xsize, save_ysize, nodata, ot, *args, **kwargs):

    _, gt, _, nodata, array_numpy = numpy_read(temp_metatile)

    #target_db = target.split(".")[0] + ".sqlite"
    targetdb = "geodata"
    dbuser = "******"
    targettable = str(parsed.table)
    median = int(parsed.median)

    # geotransform values for tile
    xmin = gt[0] + (save_offsetx * gt[1])
    xmax = gt[0] + ((save_offsetx + save_xsize) * gt[1])
    ymin = gt[3] + ((save_offsety + save_ysize) * gt[5])
    ymax = gt[3] + (save_offsety * gt[5])

    # geotransform values for metatile
    save_offsetx = 0
    save_offsety = 0
    save_xsize = array_numpy.shape[1]
    save_ysize = array_numpy.shape[0]

    # reclassify
    '''
    11: cropland
    14: cropland
    20: cropland
    30: forest
    40: forest
    50: forest
    60: forest
    70: forest
    90: forest
    100: forest
    110: shrubland
    120: shrubland
    130: shrubland
    140: shrubland
    150: shrubland
    160: forest
    170: forest
    180: grassland
    190: sealed
    200: bare
    210: water
    220: ice
    230: nodata
    '''
    '''
    nodata: 0
    cropland: 1
    forest: 2
    shrubland: 3
    grassland: 4
    sealed: 5
    bare: 6
    water: 7
    ice: 8
    '''
    # vectorize (smooth edges)
    # smooth

    # reclassify
    ############
    classification = {
        11: 1,
        14: 1,
        20: 1,
        30: 2,
        40: 2,
        50: 2,
        60: 2,
        70: 2,
        90: 2,
        100: 2,
        110: 3,
        120: 3,
        130: 3,
        140: 3,
        150: 3,
        160: 2,
        170: 2,
        180: 4,
        190: 5,
        200: 6,
        210: 7,
        220: 8  #,
        #230:0
    }

    temp_numpy = numpy.zeros((array_numpy.shape[0], array_numpy.shape[1]))

    for c in classification:
        idx = (array_numpy == c).nonzero()
        temp_numpy[idx] = classification[c]

    # median filter
    ###############
    processed_numpy = ndimage.median_filter(temp_numpy, size=median)

    #create Memory driver
    src_ds = gdal.Open(temp_metatile)
    format = "MEM"
    driver = gdal.GetDriverByName(format)
    mem_ds = driver.CreateCopy('', src_ds)
    # write filtered numpy array to GDAL band
    gdal_array.BandWriteArray(mem_ds.GetRasterBand(1), processed_numpy)
    mem_ds.GetRasterBand(1).WriteArray(processed_numpy)

    drv = ogr.GetDriverByName('Memory')
    ogr_ds = drv.CreateDataSource('out')
    ogr_lyr = ogr_ds.CreateLayer('landcover')
    fieldname = 'type'
    field_defn = ogr.FieldDefn(fieldname, ogr.OFTInteger)
    ogr_lyr.CreateField(field_defn)
    ogr_field = ogr_lyr.GetLayerDefn().GetFieldIndex(fieldname)
    ogr_field = 0

    maskband = None

    gdal.Polygonize(mem_ds.GetRasterBand(1), maskband, ogr_lyr, ogr_field, [])

    # clip to tile boundary
    #######################
    ring = ogr.Geometry(ogr.wkbLinearRing)
    ring.AddPoint(xmin, ymin)
    ring.AddPoint(xmin, ymax)
    ring.AddPoint(xmax, ymax)
    ring.AddPoint(xmax, ymin)
    ring.AddPoint(xmin, ymin)
    clipbox = ogr.Geometry(ogr.wkbPolygon)
    clipbox.AddGeometry(ring)

    cliplayer = ogr_ds.CreateLayer('clipbox', geom_type=ogr.wkbPolygon)
    clipfeaturedefn = cliplayer.GetLayerDefn()
    clipfeature = ogr.Feature(clipfeaturedefn)
    clipfeature.SetGeometry(clipbox)
    cliplayer.CreateFeature(clipfeature)
    clipped = ogr_ds.CreateLayer('landcover_clipped',
                                 geom_type=ogr.wkbMultiPolygon)
    #clipped.ForceToMultiLineString()
    field_defn = ogr.FieldDefn('ID', ogr.OFTInteger)
    clipped.CreateField(field_defn)
    field_defn = ogr.FieldDefn('type', ogr.OFTInteger)
    clipped.CreateField(field_defn)

    ogr_lyr.Clip(cliplayer, clipped)

    connection = psycopg2.connect(database=targetdb, user=dbuser)
    # psql -d geodata -c "DROP TABLE landcover; CREATE TABLE landcover (id bigserial primary key, typeid double precision, type text);  SELECT AddGeometryColumn ('','landcover','the_geom',4326,'MULTIPOLYGON',2);"
    cursor = connection.cursor()

    for i in range(clipped.GetFeatureCount()):
        insert = True
        feature = clipped.GetFeature(i)
        geometry = feature.GetGeometryRef()
        #print geometry.GetGeometryName()
        if geometry.GetGeometryName() in ("POLYGON", "MULTIPOLYGON"):
            continue
            #print "polygon"
        if geometry.GetGeometryName() == "GEOMETRYCOLLECTION":
            geometry_new = ogr.Geometry(ogr.wkbMultiLineString)
            for i in xrange(geometry.GetGeometryCount()):
                g = geometry.GetGeometryRef(i)
                if g.GetGeometryName() in ("POLYGON", "MULTIPOLYGON"):
                    #print "geometrycollection polygon"
                    geometry_new.AddGeometry(g.Clone())
                else:
                    print g.GetGeometryName()
            geometry = geometry_new
        if geometry.GetGeometryName() in ("LINESTRING", "MULTILINESTRING",
                                          "POINT", "MULTIPOINT"):
            insert = False

        if insert:
            lctype = feature.GetField("type")
            geometry.SetCoordinateDimension(2)
            wkt = geometry.ExportToWkt()
            cursor.execute(
                "INSERT INTO " + targettable +
                " (type,the_geom) VALUES (%s, ST_Multi(ST_GeomFromText(%s, " +
                "4326)))", (lctype, wkt))
    connection.commit()

    ogr_ds.Destroy()
    processed_numpy = []
    mem_ds = None

    #numpy_save(processed_numpy, target, save_offsetx, save_offsety, save_xsize, save_ysize, gt, nodata, ot)

    #processed_numpy = array_numpy
    #print "save processed_numpy"
    #print str(processed_numpy.shape[0]) + " " + str(processed_numpy.shape[1])

    cursor.close()
    connection.close()
Esempio n. 13
0
def save_alpha_band(gdal_ds, alpha_array):
    alpha_band = gdal_ds.GetRasterBand(gdal_ds.RasterCount)
    alpha_band.SetColorInterpretation(gdal.GCI_AlphaBand)
    gdal_array.BandWriteArray(alpha_band,
                              alpha_array.astype(numpy.uint16) * 255)
Esempio n. 14
0
def save_band(gdal_ds, band_array, band_no, nodata=None):
    gdal_band = gdal_ds.GetRasterBand(band_no)
    gdal_array.BandWriteArray(gdal_band, band_array)
    if nodata is not None:
        gdal_band.SetNoDataValue(nodata)
Esempio n. 15
0
def process(parsed, target, temp_metatile, temp_processed, save_offsetx, save_offsety, save_xsize, save_ysize, nodata, ot, *args, **kwargs):

    #target_db = target.split(".")[0] + ".sqlite"
    targetdb = "geodata"
    dbuser = "******"
    targettable = str(parsed.table)

    elevation = int(parsed.elevation)
    median = int(parsed.median)
    glacier_mask = parsed.glacier_mask
    nodata = 0
 
    #print "read temp_metatile"
    _, gt, _, nodata, array_numpy = numpy_read(temp_metatile)
    processed_numpy = ndimage.median_filter(array_numpy, size=median)
    #processed_numpy = array_numpy
    #print "save processed_numpy"
    #print str(processed_numpy.shape[0]) + " " + str(processed_numpy.shape[1])

    # geotransform values for tile
    xmin = gt[0] + (save_offsetx * gt[1])
    xmax = gt[0] + ((save_offsetx + save_xsize) * gt[1])
    ymin = gt[3] + ((save_offsety + save_ysize) * gt[5])
    ymax = gt[3] + (save_offsety * gt[5])

    # geotransform values for metatile
    save_offsetx = 0
    save_offsety = 0
    save_xsize = processed_numpy.shape[1]
    save_ysize = processed_numpy.shape[0]
    
    # create contours from processed_numpy
    ds = gdal.Open(temp_metatile)

    drv = ogr.GetDriverByName( 'Memory' )  
    ogr_ds = drv.CreateDataSource('out')  
    #ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource('contours_ogr/contour.shp')
    ogr_lyr = ogr_ds.CreateLayer('contour', geom_type = ogr.wkbMultiLineString)
    field_defn = ogr.FieldDefn('ID', ogr.OFTInteger)
    ogr_lyr.CreateField(field_defn)
    field_defn = ogr.FieldDefn('elev', ogr.OFTReal)
    ogr_lyr.CreateField(field_defn)

    #create Memory driver
    src_ds = gdal.Open( temp_metatile )
    format = "MEM"
    driver = gdal.GetDriverByName( format )
    mem_ds = driver.CreateCopy('', src_ds )
    # write filtered numpy array to GDAL band
    gdal_array.BandWriteArray(mem_ds.GetRasterBand(1), processed_numpy)
    mem_ds.GetRasterBand(1).WriteArray(processed_numpy)

    # write contours to OGR layer
    gdal.ContourGenerate(mem_ds.GetRasterBand(1), elevation, 0, [], 0, 0, ogr_lyr, 0, 1)

    # convert 3D geometries to 2D
    for i in range(ogr_lyr.GetFeatureCount()):  
        feature = ogr_lyr.GetFeature(i)  
        geometry = feature.GetGeometryRef()
        geometry.SetCoordinateDimension(2)

    # clip to tile boundary
    ring = ogr.Geometry(ogr.wkbLinearRing)
    ring.AddPoint(xmin, ymin)
    ring.AddPoint(xmin, ymax)
    ring.AddPoint(xmax, ymax)
    ring.AddPoint(xmax, ymin)
    ring.AddPoint(xmin, ymin)
    clipbox = ogr.Geometry(ogr.wkbPolygon)
    clipbox.AddGeometry(ring)

    cliplayer = ogr_ds.CreateLayer('clipbox', geom_type=ogr.wkbPolygon)
    clipfeaturedefn = cliplayer.GetLayerDefn()
    clipfeature = ogr.Feature(clipfeaturedefn)
    clipfeature.SetGeometry(clipbox)
    cliplayer.CreateFeature(clipfeature)
    clipped = ogr_ds.CreateLayer('contour_clipped', geom_type=ogr.wkbMultiLineString)
    #clipped.ForceToMultiLineString()
    field_defn = ogr.FieldDefn('ID', ogr.OFTInteger)
    clipped.CreateField(field_defn)
    field_defn = ogr.FieldDefn('elev', ogr.OFTReal)
    clipped.CreateField(field_defn)

    ogr_lyr.Clip(cliplayer, clipped)

    # PostGIS connection
    #connection = db.connect('contours.sqlite')
    connection = psycopg2.connect(database = targetdb, user = dbuser)
    # psql -d geodata -c "DROP TABLE contours; CREATE TABLE contours (id bigserial primary key, elev double precision, type text);  SELECT AddGeometryColumn ('','contours','the_geom',4326,'MULTILINESTRING',2);"
    cursor = connection.cursor()

    if glacier_mask:
        # read glacier_mask
        shapefile = glacier_mask
        driver = ogr.GetDriverByName("ESRI Shapefile")
        dataSource = driver.Open(shapefile, 0)
        glacier_layer = dataSource.GetLayer()

        glacier_layer_clipped = ogr_ds.CreateLayer('glacier_clipped', geom_type=ogr.wkbPolygon)

        glacier_layer.Clip(cliplayer, glacier_layer_clipped)

        #print "processing land contours"
        # clip & save land contours
        land_clipped = ogr_ds.CreateLayer('contour_clipped', geom_type=ogr.wkbMultiLineString)
        field_defn = ogr.FieldDefn('ID', ogr.OFTInteger)
        land_clipped.CreateField(field_defn)
        field_defn = ogr.FieldDefn('elev', ogr.OFTReal)
        land_clipped.CreateField(field_defn)

        if glacier_layer_clipped.GetFeatureCount() == 0:
            land_clipped = clipped
        else:
            # create inverse clip
            inverse_clip = ogr_ds.CreateLayer('inverse_clip', geom_type=ogr.wkbPolygon)
            cliplayer.Erase(glacier_layer_clipped, inverse_clip)
            clipped.Clip(inverse_clip, land_clipped)


        contour_type = "land"

        for i in range(land_clipped.GetFeatureCount()):  
            feature = land_clipped.GetFeature(i)  
            geometry = feature.GetGeometryRef()
            # hack removing loose points from geometry
            if geometry.GetGeometryName() in ("POINT", "MULTIPOINT") :
                continue
            if geometry.GetGeometryName() == "GEOMETRYCOLLECTION" :
                geometry_new = ogr.Geometry(ogr.wkbMultiLineString)
                for i in xrange(geometry.GetGeometryCount()): 
                    g = geometry.GetGeometryRef(i)
                    if g.GetGeometryName() == "LINESTRING" :
                        geometry_new.AddGeometry(g.Clone())
                geometry = geometry_new
            elev = feature.GetField("elev")
            geometry.SetCoordinateDimension(2)
            wkt = geometry.ExportToWkt() 
            cursor.execute("INSERT INTO " + targettable + " (elev,the_geom,type) VALUES (%s, ST_Multi(ST_GeomFromText(%s, " +"4326)), %s)", (elev, wkt, contour_type))
        connection.commit()  


        #print "processing glacier contours"    
        # clip & save glacier contours
        glacier_clipped = ogr_ds.CreateLayer('glacier_clipped', geom_type=ogr.wkbMultiLineString)
        field_defn = ogr.FieldDefn('ID', ogr.OFTInteger)
        glacier_clipped.CreateField(field_defn)
        field_defn = ogr.FieldDefn('elev', ogr.OFTReal)
        glacier_clipped.CreateField(field_defn)
    
        clipped.Clip(glacier_layer_clipped, glacier_clipped)

        contour_type = "glaciated"

        for i in range(glacier_clipped.GetFeatureCount()):  
            feature = glacier_clipped.GetFeature(i)  
            geometry = feature.GetGeometryRef()
            # hack removing loose points from geometry
            if geometry.GetGeometryName() in ("POINT", "MULTIPOINT") :
                continue
            if geometry.GetGeometryName() == "GEOMETRYCOLLECTION" :
                geometry_new = ogr.Geometry(ogr.wkbMultiLineString)
                for i in xrange(geometry.GetGeometryCount()): 
                    g = geometry.GetGeometryRef(i)
                    if g.GetGeometryName() == "LINESTRING" :
                        geometry_new.AddGeometry(g.Clone())
                geometry = geometry_new
            elev = feature.GetField("elev")
            geometry.SetCoordinateDimension(2)
            wkt = geometry.ExportToWkt() 
            cursor.execute("INSERT INTO " + targettable + " (elev,the_geom,type) VALUES (%s, ST_Multi(ST_GeomFromText(%s, " +"4326)), %s)",(elev, wkt, contour_type))
        connection.commit()
    
    else:
        # save to POSTGIS
        for i in range(clipped.GetFeatureCount()):  
            feature = clipped.GetFeature(i)
            geometry = feature.GetGeometryRef()
            # hack removing loose points from geometry
            if geometry.GetGeometryName() in ("POINT", "MULTIPOINT") :
                continue
            if geometry.GetGeometryName() == "GEOMETRYCOLLECTION" :
                geometry_new = ogr.Geometry(ogr.wkbMultiLineString)
                for i in xrange(geometry.GetGeometryCount()): 
                    g = geometry.GetGeometryRef(i)
                    if g.GetGeometryName() == "LINESTRING" :
                        geometry_new.AddGeometry(g.Clone())
                geometry = geometry_new
            elev = feature.GetField("elev")
            #feature_geometry = ogr.ForceToMultiLineString(feature.GetGeometryRef())
            geometry.SetCoordinateDimension(2)
            wkt = geometry.ExportToWkt()
            cursor.execute("INSERT INTO " + targettable + " (elev,the_geom) VALUES (%s, ST_Multi(ST_GeomFromText(%s, " +"4326)))", (elev, wkt))
        connection.commit()  

    ogr_ds.Destroy()
    processed_numpy = []
    mem_ds = None
    #os.remove(target)
    #os.remove(temp_target)

    cursor.close()
    connection.close()
Esempio n. 16
0
def Calc(calc: MaybeSequence[str], outfile: Optional[PathLikeOrStr] = None, NoDataValue: Optional[Number] = None,
         type: Optional[Union[GDALDataType, str]] = None, format: Optional[str] = None,
         creation_options: Optional[Sequence[str]] = None, allBands: str = '', overwrite: bool = False,
         hideNoData: bool = False, projectionCheck: bool = False,
         color_table: Optional[ColorTableLike] = None,
         extent: Optional[Extent] = None, projwin: Optional[Union[Tuple, GeoRectangle]] = None,
         user_namespace: Optional[Dict]=None,
         debug: bool = False, quiet: bool = False, **input_files):

    if debug:
        print(f"gdal_calc.py starting calculation {calc}")

    # Single calc value compatibility
    if isinstance(calc, (list, tuple)):
        calc = calc
    else:
        calc = [calc]
    calc = [c.strip('"') for c in calc]

    creation_options = creation_options or []

    # set up global namespace for eval with all functions of gdal_array, numpy
    global_namespace = {key: getattr(module, key)
                        for module in [gdal_array, numpy] for key in dir(module) if not key.startswith('__')}

    if user_namespace:
        global_namespace.update(user_namespace)

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

    if format is None:
        format = GetOutputDriverFor(outfile)

    if isinstance(extent, GeoRectangle):
        pass
    elif projwin:
        if isinstance(projwin, GeoRectangle):
            extent = projwin
        else:
            extent = GeoRectangle.from_lurd(*projwin)
    elif not extent:
        extent = Extent.IGNORE
    else:
        extent = extent_util.parse_extent(extent)

    compatible_gt_eps = 0.000001
    gt_diff_support = {
        GT.INCOMPATIBLE_OFFSET: 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 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...
                alpha_band = f"{alpha}_band"
                if alpha_band in input_files:
                    myBand = input_files[alpha_band]
                else:
                    myBand = 1

                myF_is_ds = not is_path_like(filename)
                if myF_is_ds:
                    myFile = filename
                    filename = None
                else:
                    myFile = open_ds(filename, gdal.GA_ReadOnly)
                if not myFile:
                    raise IOError(f"No such file or directory: '{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 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 extent in [Extent.IGNORE, Extent.FAIL]:
                            raise Exception(
                                f"Error! Dimensions of file {filename} ({myFileDimensions[0]:d}, "
                                f"{myFileDimensions[1]:d}) are different from other files "
                                f"({DimensionsCheck[0]:d}, {DimensionsCheck[1]:d}).  Cannot proceed")
                else:
                    DimensionsCheck = myFileDimensions

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

                # check that the GeoTransforms of each layer are the same
                myFileGeoTransform = myFile.GetGeoTransform(can_return_null=True)
                if extent == Extent.IGNORE:
                    GeoTransformCheck = myFileGeoTransform
                else:
                    Dimensions.append(myFileDimensions)
                    GeoTransforms.append(myFileGeoTransform)
                    if not GeoTransformCheck:
                        GeoTransformCheck = myFileGeoTransform
                    else:
                        my_gt_diff = extent_util.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 != GT.COMPATIBLE_DIFF:
                                raise Exception(
                                    f"Error! GeoTransform of file {filename} {myFileGeoTransform} is incompatible "
                                    f"({gt_diff_error[my_gt_diff]}), first file GeoTransform is {GeoTransformCheck}. "
                                    f"Cannot proceed")
                if debug:
                    print(
                        f"file {alpha}: {filename}, dimensions: "
                        f"{DimensionsCheck[0]}, {DimensionsCheck[1]}, type: {myDataType[-1]}")

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

    if extent not in [Extent.IGNORE, Extent.FAIL] and (
        GeoTransformDiffer or isinstance(extent, GeoRectangle)):
        # mixing different GeoTransforms/Extents
        GeoTransformCheck, DimensionsCheck, ExtentCheck = extent_util.calc_geotransform_and_dimensions(
            GeoTransforms, Dimensions, extent)
        if GeoTransformCheck is None:
            raise Exception("Error! The requested extent is empty. Cannot proceed")
        for i in range(len(myFileNames)):
            temp_vrt_filename, temp_vrt_ds = extent_util.make_temp_vrt(myFiles[i], ExtentCheck)
            myTempFileNames.append(temp_vrt_filename)
            myFiles[i] = None  # close original ds
            myFiles[i] = temp_vrt_ds  # replace original ds with vrt_ds

            # update the new precise dimensions and gt from the new ds
            GeoTransformCheck = temp_vrt_ds.GetGeoTransform()
            DimensionsCheck = [temp_vrt_ds.RasterXSize, temp_vrt_ds.RasterYSize]
        temp_vrt_ds = None

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

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

        myOut = open_ds(outfile, 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(
                f"Error! Output exists, {error}.  Use the --overwrite option "
                f"to automatically overwrite the existing file")

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

    else:
        if outfile:
            # remove existing file and regenerate
            if os.path.isfile(outfile):
                os.remove(outfile)
            # create a new file
            if debug:
                print(f"Generating output file {outfile}")
        else:
            outfile = ''

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

        # create file
        myOutDrv = gdal.GetDriverByName(format)
        myOut = myOutDrv.Create(
            os.fspath(outfile), DimensionsCheck[0], DimensionsCheck[1], allBandsCount,
            myOutType, 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 NoDataValue is None:
            myOutNDV = None if hideNoData else DefaultNDVLookup[
                myOutType]  # use the default noDataValue for this datatype
        elif isinstance(NoDataValue, str) and NoDataValue.lower() == 'none':
            myOutNDV = None  # not to set any noDataValue
        else:
            myOutNDV = 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 color_table:
                # set color table and color interpretation
                if is_path_like(color_table):
                    color_table = get_color_table(color_table)
                myOutB.SetRasterColorTable(color_table)
                myOutB.SetRasterColorInterpretation(gdal.GCI_PaletteIndex)

            myOutB = None  # write to band

    myOutTypeName = gdal.GetDataTypeName(myOutType)
    if debug:
        print(f"output file: {outfile}, dimensions: {myOut.RasterXSize}, {myOut.RasterYSize}, type: {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 debug:
        print(f"using blocksize {myBlockSize[0]} x {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 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 = gdal_array.BandReadAsArray(myFiles[i].GetRasterBand(myBandNo),
                                                       xoff=myX, yoff=myY,
                                                       win_xsize=nXValid, win_ysize=nYValid)
                    if myval is None:
                        raise Exception(f'Input block reading failed from filename {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
                this_calc = calc[bandNo - 1 if len(calc) > 1 else 0]
                try:
                    myResult = eval(this_calc, global_namespace, local_namespace)
                except:
                    print(f"evaluation of calculation {this_calc} failed")
                    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 gdal_array.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 quiet:
        print("100 - Done")

    return myOut
Esempio n. 17
0
def reclassify_raster(infile,
                      outfile,
                      operator,
                      threshold,
                      pixel_value=100,
                      frmt="GTiff",
                      silence=True):
    """
    Reclassify a raster into a single value according to a threshold
    :param infile: path to the input
    :param outfile: path to the output
    :param operator: string, possible values ">","<",">=","<="
    :param threshold: threshold value
    :param pixel_value: the output pixel value for pixels that pass the threshold
    :param frmt: the output format, default "GTiff"
    :param silence: pass any value to enable debug info
    :return: None
    """
    '''using this instead of gdal_calc because gdal calc didn't work
    scriptpath = os.path.join(os.path.dirname(__file__), '../', "pysdss/utility/gdal_calc.py")
    scriptpath = os.path.normpath(scriptpath)
    params = [scriptpath,"-A",path+input,"--outfile="+path+output,"--calc='(A>0.5)'", "--debug"]
    print("Reclassify raster")
    out,err = utils.run_script(params, callpy=["python3"])
    print("output" + out)
    if err:
        print("ERROR:" + err)
        raise Exception("gdal grid failed")'''

    if operator not in [">", "<", ">=", "<="]:
        raise Exception("unknown operator")

    band1 = None
    ds1 = None
    bandOut = None
    dsOut = None

    try:
        if not silence:
            print("opening input")

        # Open the dataset
        ds1 = gdal.Open(infile, gdct.GA_ReadOnly)
        band1 = ds1.GetRasterBand(1)
        # Read the data into numpy arrays
        data1 = gdar.BandReadAsArray(band1)
        # get the nodata value
        nodata = band1.GetNoDataValue()

        if not silence:
            print("filtering input")

        # The actual calculation
        filter = "data1" + operator + str(threshold)
        data1[eval(filter)] = pixel_value
        data1[data1 != pixel_value] = nodata

        if not silence:
            print("output result")

        # Write the out file
        driver = gdal.GetDriverByName(frmt)
        dsOut = driver.Create(outfile, ds1.RasterXSize, ds1.RasterYSize, 1,
                              band1.DataType)
        gdar.CopyDatasetInfo(ds1, dsOut)
        bandOut = dsOut.GetRasterBand(1)
        bandOut.SetNoDataValue(nodata)
        gdar.BandWriteArray(bandOut, data1)

    except RuntimeError as err:
        raise err
    except Exception as e:
        raise e

    finally:
        # Close the datasets
        if band1: band1 = None
        if ds1: ds1 = None
        if bandOut: bandOut = None
        if dsOut: dsOut = None