def rastermask_average_gdalwarp(rasterpath, shapepath): """ Description: A function to mask/clip a raster by the boundaries of a shapefile and computer the average value of the resulting raster Dependencies: gdal, gdalnumeric, numpy Params: View README.md Returns: mean value of an array within a shapefile's boundaries Author: Riley Hales, RCH Engineering, April 2019 """ # rastermask_average_gdalwarp(r'/Users/rileyhales/Documents/sampledata/gldasgeotiff/gldasgeotiff.tif', # r'/Users/rileyhales/Documents/sampledata/shapefilegcs/shapefile_Project.shp') import gdal import gdalnumeric import numpy inraster = gdal.Open(rasterpath) outraster = r'/Users/rileyhales/Documents/sampledata/gldalwarp.tif' # your output raster file clippedraster = gdal.Warp(outraster, inraster, format='GTiff', cutlineDSName=shapepath, dstNodata=numpy.nan) array = gdalnumeric.DatasetReadAsArray(clippedraster) array = array.flatten() array = array[~numpy.isnan(array)] mean = array.mean() print(mean) return mean
def ReadAsArray(self, xoff=0, yoff=0, xsize=None, ysize=None, buf_obj=None): import gdalnumeric return gdalnumeric.DatasetReadAsArray(self, xoff, yoff, xsize, ysize, buf_obj)
def rastermask_average_gdalwarp(data): """ Description: A function to mask/clip a raster by the boundaries of a shapefile and computer the average value of the resulting raster Dependencies: gdal, gdalnumeric, numpy, os, shutil, ogr from .app import Gldas as App Params: View README.md Returns: mean value of an array within a shapefile's boundaries Author: Riley Hales, RCH Engineering, April 2019 """ values = [] times = data['times'] times.sort() shppath = '' wrkpath = App.get_app_workspace().path if data['shapefile'] == 'true': region = data['region'].replace(' ', '').lower() shppath = os.path.join(wrkpath, 'shapefiles', region, region + '.shp') else: # todo: still under development- turn a geojson into a shapefile print('you can\'t do that') # setup the working directories for the geoprocessing geotiffdir = os.path.join(wrkpath, 'geotiffs') geotiffs = os.listdir(geotiffdir) # perform the gropreccesing on each file in the geotiff directory for i in range(len(geotiffs)): # clip the raster inraster = gdal.Open( os.path.join(geotiffdir, 'geotiff' + str(i) + '.tif')) savepath = os.path.join(geotiffdir, 'outraster.tif') clippedraster = gdal.Warp(savepath, inraster, format='GTiff', cutlineDSName=shppath, dstNodata=numpy.nan) # do the averaging math on the raster as an array array = gdalnumeric.DatasetReadAsArray(clippedraster) array = array.flatten() array = array[~numpy.isnan(array)] mean = array.mean() values.append((times[i][0], float(mean), times[i][1], times[i][2])) if os.path.isdir(geotiffdir): shutil.rmtree(geotiffdir) return values
def getElevation(self, lat, lon, bilinear=False): """Returns the elevation in metres of point (lat,lon). Uses bilinar interpolation to interpolate the SRTM data to the required point if bilinear=True, otherwise uses single point. An error (-999) is returned if the location is not covered by any of the loaded tiles. """ tdi = self.getTileIndex(lat, lon) td = self.tilearr[tdi] fname = td['fname'] if (tdi == -999): print "Error (%s,%s) out of Range." % (lat, lon) return -999 else: dataset = gdal.Open(fname) (row, col) = self.posFromLatLon(lat, lon, td) if (self.verbose): print "row=%s, col=%s" % (row, col) if (bilinear): if (self.debug): print "Using bilinear interpolation to find height" htarr = gdalnumeric.DatasetReadAsArray(dataset, col, row, 2, 2) if (self.debug): print htarr height = bilinearInterpolation(htarr[0][0], htarr[0][1], htarr[1][0], htarr[1][1], lat, lon) else: if (self.debug): print "Using single point to get height" htarr = gdalnumeric.DatasetReadAsArray(dataset, col, row, 1, 1) height = htarr[0][0] return height return -999
def execute_cb(self, *args): layer = gview.app.sel_manager.get_active_layer() if not layer_is_raster(layer): gvutils.error("Please select a raster layer.") return ds = layer.get_parent().get_dataset() data = gdalnumeric.DatasetReadAsArray(ds) if self.switch_forward.get_active(): data_tr = FFT.fft2d(data) else: data_tr = FFT.inverse_fft2d(data) array_name = gdalnumeric.GetArrayFilename(data_tr) if self.switch_new_view.get_active(): gview.app.new_view() gview.app.file_open_by_name(array_name)
def loadTile(self, filename): """ Loads a GeoTIFF tile from disk and returns a dictionary containing the file data, plus metadata about the tile. The dictionary returned by this function contains the following data: xsize - the width of the tile in pixels. ysize - the height of the tile in pixels. lat_origin - the latitude of the top left pixel in the tile. lon_origin - the longitude of the top left pixel in the tile. lat_pixel - the height of one pixel in degrees latitude. lon_pixel - the width of one pixel in degrees longitude. N, S, E, W - the bounding box for this tile in degrees. data - a two dimensional array containing the tile data. """ dataset = gdal.Open(filename) geotransform = dataset.GetGeoTransform() xsize = dataset.RasterXSize ysize = dataset.RasterYSize lon_origin = geotransform[0] lat_origin = geotransform[3] lon_pixel = geotransform[1] lat_pixel = geotransform[5] retdict = {} retdict["xsize"] = xsize retdict["ysize"] = ysize retdict["lat_origin"] = lat_origin retdict["lon_origin"] = lon_origin retdict["lat_pixel"] = lat_pixel retdict["lon_pixel"] = lon_pixel retdict["N"] = lat_origin retdict["S"] = lat_origin + lat_pixel * ysize retdict["E"] = lon_origin + lon_pixel * xsize retdict["W"] = lon_origin retdict["data"] = gdalnumeric.DatasetReadAsArray(dataset) return retdict
def getElevation(self, lat, lon, bilinear=False): """Returns the elevation in metres of point (lat,lon). Uses bilinar interpolation to interpolate the SRTM data to the required point if bilinear=True, otherwise uses single point. An error (-999) is returned if the location is not covered by any of the loaded tiles. """ tdi = self.getTileIndex(lat, lon) if (tdi == -999): if (self.verbose): print "Error (%s,%s) out of Range." % (lat, lon) return -999 else: td = self.tilearr[tdi] fname = td['fname'] """ If the required file is not open, open it. But if we are already have the maximum number of files open, we have to close one first """ if (td['handle'] == -1): if (self.debug): print "Required file is closed" if (self.NumOpenFiles >= self.MaxOpenFiles): if (self.debug): print "Maximum number of open files reached - closing one first" self.closeAFile() else: if (self.debug): print "Number of open files ok - NumOpenFiles = %s, MaxOpenFiles=%s" % \ (self.NumOpenFiles, self.MaxOpenFiles) if (self.debug): print "Opening file %s" % fname td['handle'] = gdal.Open(fname) self.NumOpenFiles += 1 if (self.debug): print "NumOpenFiles = %s" % self.NumOpenFiles else: if (self.debug): print "File already open - NumOpenFiles = %s" % self.NumOpenFiles (row, col, row_f, col_f) = self.posFromLatLon(lat, lon, td) if (self.verbose): print "row=%s, col=%s,row_f=%s,col_f=%s" % (row, col, row_f, col_f) if (bilinear): if (self.debug): print "Using bilinear interpolation to find height" # NOTE - THIS IS A FIDDLE TO STOP ERRORS AT THE EDGE OF # TILES - IT IS NO CORRECT - WE SHOULD GET TWO POINTS # FROM THE NEXT TILE. if row == 5999: row = 5998 if col == 5999: col = 5998 htarr = gdalnumeric.DatasetReadAsArray(td['handle'], col, row, 2, 2) if (self.debug): print htarr height = bilinearInterpolation(htarr[0][0], htarr[0][1], htarr[1][0], htarr[1][1], row_f - row, col_f - col) else: if (self.debug): print "Using single point to get height" htarr = gdalnumeric.DatasetReadAsArray(td['handle'], col, row, 1, 1) height = htarr[0][0] return height return -999
def execute(self, args, line, interp): import gvutils import gview import gdalnumeric clayer = gview.app.sel_manager.get_active_layer() if clayer is None: interp.showText('No layer is currently active!', 'error') return 0 try: roi = gview.app.toolbar.get_roi() except: roi = None # /s argument is 1 if user requested screenshot, 0 # if the underlying data was requested (default). # NOTE: roi is ignored for screenshot option is_ss = args[1] shell_vars = {} if is_ss == 1: cview = gview.app.sel_manager.get_active_view() if roi is not None: txt='Warning- ROI is ignored for screenshot-style get.\n'+\ 'Grabbing whole view area.\n' interp.showText(txt, 'error') # Note: for now, assume colour mode to start with (since # even single band images may have luts applied), and # if all three bands are identical in the end (greyscale # equivalent), return 1. err = cview.print_to_file(cview.get_width(), cview.get_height(), '_temp.tif', 'GTiff', 1) import os if err != 0: interp.showText( 'Error grabbing screenshot- unable to generate temporary file.\n', 'error') os.unlink('_temp.tif') return 0 try: import Numeric new_arr = gdalnumeric.LoadFile('_temp.tif') if ((max( Numeric.ravel( Numeric.fabs(new_arr[0, :, :] - new_arr[1, :, :]))) == 0) and (max( Numeric.ravel( Numeric.fabs(new_arr[2, :, :] - new_arr[1, :, :]))) == 0)): shp = Numeric.shape(new_arr) new_arr = Numeric.reshape(new_arr[0, :, :], (shp[1], shp[2])) except: interp.showText( 'Error grabbing screenshot- unable to load temporary file.\n', 'error') os.unlink('_temp.tif') return 0 shell_vars[args[0]] = new_arr os.unlink('_temp.tif') return (1, shell_vars) if gvutils.is_of_class(clayer.__class__, 'GvRasterLayer'): ds = clayer.get_parent().get_dataset() if roi is None: shell_vars[args[0]] = gdalnumeric.DatasetReadAsArray(ds) return (1, shell_vars) else: # Here, need to check if georeferencing is on or not and # convert to pixel/line coordinates if it is on. cview = gview.app.sel_manager.get_active_view() if (cview.get_raw(clayer) == 0): # view is georeferenced- convert corners [pixel, line] = clayer.view_to_pixel(roi[0], roi[1]) [pixel2, line2] = clayer.view_to_pixel(roi[0] + roi[2], roi[1] + roi[3]) [pixel3, line3] = clayer.view_to_pixel(roi[0], roi[1] + roi[3]) [pixel4, line4] = clayer.view_to_pixel(roi[0] + roi[2], roi[1]) # Get pixel-space rectangle (offsets of 1 ensure that # only pixels fully enclosed by the roi are included- # int casting will round floating point pixel/line # values down) max_pix = int(max(pixel, pixel2, pixel3, pixel4)) min_pix = int(min(pixel, pixel2, pixel3, pixel4)) + 1 max_line = int(max(line, line2, line3, line4)) min_line = int(min(line, line2, line3, line4)) + 1 # in pixel/line space, selected region is a parallelogram # but not necessarily a rectangle. Choose a rectangle # that fully encloses the parallelogram roi = (min_pix, min_line, max_pix - min_pix, max_line - min_line) shell_vars = {} shell_vars[args[0]] = gdalnumeric.DatasetReadAsArray( ds, roi[0], roi[1], roi[2], roi[3]) return (1, shell_vars) elif gvutils.is_of_class(clayer.__class__, 'GvShapesLayer'): shps = clayer.get_parent() selected = clayer.get_selected() if len(selected) == 0: newshps = gview.GvShapes() for item in shps.get_schema(): newshps.add_field(item[0], item[1], item[2], item[3]) for shp in shps: if shp is not None: newshps.append(shp.copy()) shell_vars = {} shell_vars[args[0]] = newshps return (1, shell_vars) else: newshps = gview.GvShapes() for item in shps.get_schema(): newshps.add_field(item[0], item[1], item[2], item[3]) for idx in selected: newshps.append(shps[idx].copy()) shell_vars = {} shell_vars[args[0]] = newshps return (1, shell_vars) else: interp.showText( 'Active layer is not a raster or recognized vector layer!', 'error') return 0