def rstext_to_rst(inrst, outrst, cellsize=None, epsg=None, rstval=None): """ Raster Extent to Raster """ from glass.g.prop.rst import rst_ext, get_cellsize from glass.g.wt.rst import ext_to_rst # Get Raster Extent left, right, bottom, top = rst_ext(inrst) # GET EPSG if not epsg: from glass.g.prop.prj import get_rst_epsg epsg = get_rst_epsg(inrst) # Create raster ext_to_rst( (left, top), (right, bottom), outrst, cellsize=get_cellsize(inrst) if not cellsize else cellsize, epsg=epsg, rstvalue=rstval ) return outrst
def rst_to_geodf(in_rst): """ Raster To GeoDataframe """ from osgeo import gdal import pandas as pd from glass.ng.pd.dagg import dfcolstorows from glass.g.it.pd import pnt_dfwxy_to_geodf from glass.g.prop.prj import get_rst_epsg src = gdal.Open(in_rst) num = src.ReadAsArray() ndval = src.GetRasterBand(1).GetNoDataValue() left, cellx, z, top, c, celly = src.GetGeoTransform() numdf = pd.DataFrame(num) numdf['idx'] = numdf.index res = dfcolstorows(numdf, 'col', 'val', colFid='idx') res = res[res.val != ndval] res['x'] = (left + (cellx / 2)) + (cellx * res.col) res['y'] = (top + (celly / 2)) + (celly * res.idx) res.drop(['col', 'idx'], axis=1, inplace=True) res.rename(columns={'val': 'Value'}, inplace=True) geodf = pnt_dfwxy_to_geodf(res, 'x', 'y', get_rst_epsg(in_rst)) return geodf
def rstext_to_shp(inRst, outShp, epsg=None): """ Raster Extent to Feature Class """ from glass.g.prop.rst import rst_ext # Get Raster Extent left, right, bottom, top = rst_ext(inRst) # Get EPSG if not epsg: from glass.g.prop.prj import get_rst_epsg epsg = get_rst_epsg(inRst) # Create Boundary return coords_to_boundshp((left, top), (right, bottom), epsg, outShp)
def comp_bnds(rsts, outRst): """ Composite Bands """ from osgeo import gdal, gdal_array from glass.g.rd.rst import rst_to_array from glass.g.prop import drv_name from glass.g.prop.rst import get_nodata from glass.g.prop.prj import get_rst_epsg, epsg_to_wkt # Get Arrays _as = [rst_to_array(r) for r in rsts] # Get nodata values nds = [get_nodata(r) for r in rsts] # Assume that first raster is the template img_temp = gdal.Open(rsts[0]) geo_tran = img_temp.GetGeoTransform() band = img_temp.GetRasterBand(1) dataType = gdal_array.NumericTypeCodeToGDALTypeCode(_as[0].dtype) rows, cols = _as[0].shape epsg = get_rst_epsg(rsts[0]) # Create Output drv = gdal.GetDriverByName(drv_name(outRst)) out = drv.Create(outRst, cols, rows, len(_as), dataType) out.SetGeoTransform(geo_tran) out.SetProjection(epsg_to_wkt(epsg)) # Write all bands for i in range(len(_as)): outBand = out.GetRasterBand(i + 1) outBand.SetNoDataValue(nds[i]) outBand.WriteArray(_as[i]) outBand.FlushCache() return outRst
def get_ref_raster(refBoundBox, folder, cellsize=None): """ Get Reference Raster """ import os from glass.g.prop import check_isRaster # Check if refRaster is really a Raster isRst = check_isRaster(refBoundBox) if not isRst: from glass.g.prop import check_isShp if not check_isShp(refBoundBox): raise ValueError(( 'refRaster File has an invalid file format. Please give a file ' 'with one of the following extensions: ' 'shp, gml, json, kml, tif or img')) else: # We have a shapefile # Check SRS and see if it is a projected SRS from glass.g.prop.prj import get_shp_epsg epsg, isProj = get_shp_epsg(refBoundBox, returnIsProj=True) if not epsg: raise ValueError( 'Cannot get epsg code from {}'.format(refBoundBox)) if not isProj: # A conversion between SRS is needed from glass.g.prj import proj ref_shp = proj(refBoundBox, os.path.join(folder, 'tmp_ref_shp.shp'), outEPSG=3857, inEPSG=epsg, gisApi='ogr2ogr') epsg = 3857 else: ref_shp = refBoundBox # Convert to Raster from glass.g.dp.torst import shp_to_rst refRaster = shp_to_rst(ref_shp, None, 2 if not cellsize else cellsize, -1, os.path.join(folder, 'ref_raster.tif'), api='gdal') else: # We have a raster from glass.g.prop.prj import get_rst_epsg epsg, isProj = get_rst_epsg(refBoundBox, returnIsProj=True) if not epsg: raise ValueError( 'Cannot get epsg code from {}'.format(refBoundBox)) # Check if Raster has a SRS with projected coordinates if not isProj: # We need to reproject raster from glass.g.prj import reprj_rst refRaster = reprj_rst(refBoundBox, os.path.join(folder, 'refrst_3857.tif'), epsg, 3857) epsg = 3857 else: refRaster = refBoundBox return refRaster, epsg
def match_cellsize_and_clip(rstBands, refRaster, outFolder, clipShp=None): """ Resample images to make them with the same resolution and clip Good to resample Sentinel bands with more than 10 meters. Dependencies: * GRASS GIS; * GDAL/OGR. """ import os from glass.g.prop.prj import get_rst_epsg from glass.g.wenv.grs import run_grass from glass.pys.oss import fprop, mkdir # Check if outfolder exists if not os.path.exists(outFolder): mkdir(outFolder, overwrite=None) # Get EPSG from refRaster epsg = get_rst_epsg(refRaster, returnIsProj=None) """ Start GRASS GIS Session """ GRS_WORKSPACE = mkdir(os.path.join(outFolder, 'grswork')) grsb = run_grass( GRS_WORKSPACE, grassBIN='grass78', location='resample', srs=epsg ) import grass.script.setup as gsetup gsetup.init(grsb, GRS_WORKSPACE, 'resample', 'PERMANENT') """ Import packages related with GRASS GIS """ from glass.g.it.rst import rst_to_grs, grs_to_rst from glass.g.wenv.grs import rst_to_region from glass.g.it.shp import shp_to_grs from glass.g.dp.torst import grsshp_to_grsrst as shp_to_rst from glass.g.it.rst import grs_to_mask # Send Ref Raster to GRASS GIS and set region extRst = rst_to_grs(refRaster, 'ext_rst') rst_to_region(extRst) # Import all bands in rstBands grs_bands = [rst_to_grs(i, fprop(i, 'fn')) for i in rstBands] if clipShp: # Add clipShp to GRASS grs_clip = shp_to_grs(clipShp, fprop(clipShp, 'fn'), asCMD=True) # SHP to Raster rstClip = shp_to_rst( grs_clip, 1, f'rst_{grs_clip}', cmd=True ) # Set region using rst_to_region(rstClip) # Set mask grs_to_mask(rstClip) # Export bands return [grs_to_rst( i, os.path.join(outFolder, i + '.tif') ) for i in grs_bands]
def osm_extraction(boundary, osmdata, output, each_feat=None, epsg=None): """ Extract OSM Data from a xml file with osmosis The extraction is done using the extent of a boundary """ import os from glass.pys import execmd from glass.g.prj.obj import prj_ogrgeom from glass.g.prop import check_isRaster # Check if boundary is a file if os.path.isfile(boundary): # Check if boundary is a raster is_rst = check_isRaster(boundary) if is_rst: # Get Raster EPSG and Extent from glass.g.prop.prj import get_rst_epsg from glass.g.prop.rst import rst_ext from glass.g.gobj import create_polygon in_epsg = get_rst_epsg(boundary) left, right, bottom, top = rst_ext(boundary) boundaries = [ create_polygon([(left, top), (right, top), (right, bottom), (left, bottom), (left, top)]) ] else: # Get Shape EPSG from glass.g.prop.prj import get_shp_epsg in_epsg = get_shp_epsg(boundary) if not each_feat: # Get Shape Extent from glass.g.prop.feat import get_ext from glass.g.gobj import create_polygon left, right, bottom, top = get_ext(boundary) boundaries = [ create_polygon([(left, top), (right, top), (right, bottom), (left, bottom), (left, top)]) ] else: # Get Extent of each feature from osgeo import ogr from glass.g.prop import drv_name src = ogr.GetDriverByName(drv_name(boundary)).Open(boundary) lyr = src.GetLayer() boundaries = [feat.GetGeometryRef() for feat in lyr] else: from glass.g.gobj import wkt_to_geom in_epsg = 4326 if not epsg else epsg if type(boundary) == str: # Assuming it is a WKT string wkt_boundaries = [boundary] elif type(boundary) == list: # Assuming it is a List with WKT strings wkt_boundaries = boundary else: raise ValueError('Given boundary has a not valid value') boundaries = [wkt_to_geom(g) for g in wkt_boundaries] if None in boundaries: raise ValueError( ("boundary parameter is a string, but it is not a valid path " "to a file or a valid WKT string")) # Get output files if len(boundaries) == 1: if os.path.isdir(output): fn, ff = os.path.splitext(os.path.basename(osmdata)) out_files = [os.path.join(output, "ect_{}.{}".format(fn, ff))] else: out_files = [output] else: fn, ff = os.path.splitext(os.path.basename(osmdata)) path = output if os.path.isdir(output) else os.path.dirname(output) out_files = [ os.path.join(path, "ect_{}_{}.{}".format(fn, str(i), ff)) for i in range(len(boundaries)) ] # Extract data using OSMOSIS cmd = ("osmosis --read-{_f} {dtparse}file={_in} " "--bounding-box top={t} left={l} bottom={b} right={r} " "--write-{outext} file={_out}") for g in range(len(boundaries)): # Convert boundary to WGS84 -EPSG 4326 geom_wgs = prj_ogrgeom( boundaries[g], int(in_epsg), 4326, api='shapely') if int(in_epsg) != 4326 else boundaries[g] # Get boundary extent left, right, bottom, top = geom_wgs.GetEnvelope() # Osmosis shell comand osmext = os.path.splitext(osmdata)[1] # Execute command outcmd = execmd( cmd.format( _f='pbf' if osmext == '.pbf' else 'xml', _in=osmdata, t=str(top), l=str(left), b=str(bottom), r=str(right), _out=out_files[g], outext=os.path.splitext(out_files[g])[1][1:], dtparse="" if osmext == '.pbf' else "enableDataParsing=no ")) return output
def bnds_to_mosaic(bands, outdata, ref_raster, loc=None): """ Satellite image To mosaic bands = { 'bnd_2' : [path_to_file, path_to_file], 'bnd_3' : [path_to_file, path_to_file], 'bnd_4' : [path_to_file, path_to_file], } """ """ Start GRASS GIS Session """ import os from glass.pys.oss import fprop from glass.g.prop.prj import get_rst_epsg from glass.g.wenv.grs import run_grass # Get EPSG from refRaster epsg = get_rst_epsg(ref_raster, returnIsProj=None) LOC = loc if loc else 'gr_loc' grass_base = run_grass(outdata, grassBIN='grass78', location=LOC, srs=epsg) import grass.script as grass import grass.script.setup as gsetup gsetup.init(grass_base, outdata, LOC, 'PERMANENT') # ************************************************************************ # # GRASS MODULES # # ************************************************************************ # from glass.g.it.rst import rst_to_grs, grs_to_rst from glass.g.wenv.grs import rst_to_region # ************************************************************************ # # SET GRASS GIS LOCATION EXTENT # # ************************************************************************ # extRst = rst_to_grs(ref_raster, 'extent_raster') rst_to_region(extRst) # ************************************************************************ # # SEND DATA TO GRASS GIS # # ************************************************************************ # grs_bnds = {} for bnd in bands: l = [] for b in bands[bnd]: bb = rst_to_grs(b, fprop(b, 'fn')) l.append(bb) grs_bnds[bnd] = l # ************************************************************************ # # PATCH bands and export # # ************************************************************************ # for bnd in grs_bnds: mosaic_band = rseries(grs_bnds[bnd], bnd, 'maximum') grs_bnds[bnd] = grs_to_rst(mosaic_band, os.path.join(outdata, mosaic_band + '.tif'), as_cmd=True) return grs_bnds