def __init__(self, sFolder, visitID): self.directory = sFolder self.visitID = visitID self.Channels = {'Wetted': Channel(), 'Bankfull': Channel()} self.DEM = "" self.Depth = "" self.WaterSurface = "" self.ChannelUnits = "" self.Thalweg = "" self.TopoPoints = "" # This object will be empty if there is no project.rs.xml file in the sFolder self.riverscapes = TopoProject(sFolder)
def downloadExtractParseVisits(visits, outputFolder): log = Logger('Downloading') log.info("Downloading all visits from the API") projects = [] for visit in visits: try: extractpath = os.path.join(outputFolder, 'VISIT_{}'.format(visit)) projpath = os.path.join(extractpath, 'project.rs.xml') downloadUnzipTopo(visit, extractpath) proj = TopoProject(extractpath) if proj.isrsproject: projects.append({"project": proj, "visit": visit}) else: log.error("File not found: {}".format(projpath)) raise DataException("Missing Project File") # Just move on if something fails except Exception as e: pass # If we didn't get anything back then it's time to freak out a little if len(projects) == 0: raise DataException("No TopoData.zip files found for any visit") return projects
def processZipFile(invVisit, APIVisit): dirpath = tempfile.mkdtemp() try: doupload = False # Copy some useful things from the API: for k in ['status', 'lastMeasurementChange', 'lastUpdated', 'name']: invVisit[k] = APIVisit[k] file, projpath = downloadUnzipTopo(APIVisit['id'], dirpath) topo = TopoProject(projpath) invVisit["topozip"] = True latestRealizationdate = latestRealizationDate(topo) if "latestRealization" not in invVisit or APIstrtodate( invVisit["latestRealization"]) >= latestRealizationdate: invVisit["latestRealization"] = APIdatetostr(latestRealizationdate) invVisit["size"] = file['size'] uploadProjectToRiverscapes(dirpath, invVisit) except MissingException, e: invVisit["topozip"] = False invVisit["error"] = e.message
def main(): # parse command line options parser = argparse.ArgumentParser() subparsers = parser.add_subparsers( dest='mode', help='For help type `hydroprep.py manual -h`') # The manual subparser is for when we know explicit paths manual = subparsers.add_parser('manual', help='manual help') manual.add_argument('dem', help='DEM raster path', type=argparse.FileType('r')) manual.add_argument('wsdem', help='Water surface raster path', type=argparse.FileType('r')) manual.add_argument('thalweg', help='Thalweg ShapeFile path', type=argparse.FileType('r')) manual.add_argument('outputfolder', help='Output folder') manual.add_argument('--verbose', help='Get more information in your logs.', action='store_true', default=False) # The project subparser is when we want to pass in a project.rs.xml file project = subparsers.add_parser('project', help='project help') project.add_argument('visitID', help='Visit ID', type=int) project.add_argument('outputfolder', help='Path to output folder', type=str) project.add_argument( '--datafolder', help= '(optional) Top level folder containing TopoMetrics Riverscapes projects', type=str) project.add_argument('--verbose', help='Get more information in your logs.', action='store_true', default=False) args = parser.parse_args() try: if args.mode == "project": resultsFolder = os.path.join(args.outputfolder, "outputs") if not os.path.isdir(args.outputfolder): os.makedirs(args.outputfolder) if not os.path.isdir(resultsFolder): os.makedirs(resultsFolder) # If we need to go get our own topodata.zip file and unzip it we do this if args.datafolder is None: topoDataFolder = os.path.join(args.outputfolder, "inputs") fileJSON, projectFolder = downloadUnzipTopo( args.visitID, topoDataFolder) # otherwise just pass in a path to existing data else: projectFolder = args.datafolder tp = TopoProject(projectFolder) funcargs = (tp.getpath("DEM"), tp.getpath("WaterSurfaceDEM"), tp.getpath("Thalweg"), resultsFolder, args.verbose) else: funcargs = (args.dem.name, args.wsdem.name, args.thalweg.name, args.outputfolder, args.verbose) hydroPrep(*funcargs) except (DataException, MissingException, NetworkException) as e: # Exception class prints the relevant information traceback.print_exc(file=sys.stdout) sys.exit(e.returncode) except AssertionError as e: traceback.print_exc(file=sys.stdout) sys.exit(1) except Exception as e: traceback.print_exc(file=sys.stdout) sys.exit(1) sys.exit(0)
def export_hydro_model(hydro_rs_xml, topo_rs_xml, out_path): log = Logger("Hydro GIS Export") # 1 todo Read project.rs.xml rs_hydro = Project(hydro_rs_xml) rs_topo = TopoProject(topo_rs_xml) hydro_results_folder = os.path.dirname(hydro_rs_xml) csvfile_hydro = os.path.join( hydro_results_folder, "dem_grid_results.csv") # todo get this from hydro project xml if "Visit" not in rs_hydro.ProjectMetadata: raise MissingException("Cannot Find Visit ID") visit_id = rs_hydro.ProjectMetadata['Visit'] df_csv = pandas.read_csv(csvfile_hydro) log.info("Read hydro results csv as data frame") # Get DEM Props with rasterio.open(rs_topo.getpath("DEM")) as rio_dem: dem_crs = rio_dem.crs dem_bounds = rio_dem.bounds dem_nodata = rio_dem.nodata out_transform = rasterio.transform.from_origin(dem_bounds.left, dem_bounds.top, 0.1, 0.1) pad_top = int((dem_bounds.top - max(df_csv['Y'])) / 0.1) pad_bottom = int((min(df_csv['Y']) - dem_bounds.bottom) / 0.1) pad_right = int((dem_bounds.right - max(df_csv['X'])) / 0.1) pad_left = int((min(df_csv['X']) - dem_bounds.left) / 0.1) log.info("Read DEM properties") # generate shp geom = [Point(xy) for xy in zip(df_csv.X, df_csv.Y)] df_output = df_csv.drop( ["X", "Y", "Depth.Error", "WSE", "BedLevel"], axis="columns") #, inplace=True) # save a bit of space gdf_hydro = geopandas.GeoDataFrame(df_output, geometry=geom) gdf_hydro.crs = dem_crs gdf_hydro.columns = gdf_hydro.columns.str.replace(".", "_") gdf_hydro["VelDir"] = numpy.subtract( 90, numpy.degrees( numpy.arctan2(gdf_hydro["Y_Velocity"], gdf_hydro["X_Velocity"]))) gdf_hydro["VelBearing"] = numpy.where(gdf_hydro['VelDir'] < 0, 360 + gdf_hydro["VelDir"], gdf_hydro["VelDir"]) gdf_hydro.drop("VelDir", axis="columns", inplace=True) #gdf_hydro.to_file(os.path.join(out_path, "HydroResults.shp")) del df_output, gdf_hydro log.info("Generated HydroResults.shp") for col in [ col for col in df_csv.columns if col not in ["X", "Y", "X.Velocity", "Y.Velocity"] ]: df_pivot = df_csv.pivot(index="Y", columns="X", values=col) np_raw = df_pivot.iloc[::-1].as_matrix() np_output = numpy.pad(np_raw, ((pad_top, pad_bottom), (pad_left, pad_right)), mode="constant", constant_values=numpy.nan) with rasterio.open(os.path.join(out_path, "{}.tif".format(col)), 'w', driver='GTiff', height=np_output.shape[0], width=np_output.shape[1], count=1, dtype=np_output.dtype, crs=dem_crs, transform=out_transform, nodata=dem_nodata) as rio_output: rio_output.write(np_output, 1) log.info("Generated output Raster for {}".format(col)) if col == "Depth": # Generate water extent polygon np_extent = numpy.greater(np_output, 0) mask = numpy.isfinite(np_output) shapes = features.shapes(np_extent.astype('float32'), mask, transform=out_transform) gdf_extent_raw = geopandas.GeoDataFrame.from_features( geopandas.GeoSeries([asShape(s) for s, v in shapes])) gdf_extent = geopandas.GeoDataFrame.from_features( gdf_extent_raw.geometry.simplify(0.5)) gdf_extent.crs = dem_crs gdf_extent['Area'] = gdf_extent.geometry.area gdf_extent['Extent'] = "" gdf_extent.set_value( gdf_extent.index[gdf_extent['Area'].idxmax()], "Extent", "Channel") # Set largest Polygon as Main Channel gdf_extent.to_file(os.path.join(out_path, "StageExtent.shp")) log.info("Generated Water Extent Polygons") # Generate islands and spatial join existing islands attributes gdf_exterior = geopandas.GeoDataFrame.from_features( geopandas.GeoSeries([ Polygon(shape) for shape in gdf_extent.geometry.exterior ])) gs_diff = gdf_exterior.geometry.difference(gdf_extent.geometry) if not all(g.is_empty for g in gs_diff): gdf_islands_raw = geopandas.GeoDataFrame.from_features( geopandas.GeoSeries( [shape for shape in gs_diff if not shape.is_empty])) gdf_islands_explode = geopandas.GeoDataFrame.from_features( gdf_islands_raw.geometry.explode()) gdf_islands_clean = geopandas.GeoDataFrame.from_features( gdf_islands_explode.buffer(0)) gdf_islands_clean.crs = dem_crs if fiona.open(rs_topo.getpath("WettedIslands")).__len__( ) > 0: # Exception when createing gdf if topo islands shapefile is empty feature class gdf_topo_islands = geopandas.GeoDataFrame.from_file( rs_topo.getpath("WettedIslands")) gdf_islands_sj = geopandas.sjoin(gdf_islands_clean, gdf_topo_islands, how="left", op="intersects") gdf_islands_sj.drop(["index_right", "OBJECTID"], axis="columns", inplace=True) gdf_islands_sj.crs = dem_crs gdf_islands_sj.to_file( os.path.join(out_path, "StageIslands.shp")) #todo: Generate Lyr file and copy #todo: Generate readme return 0
def main(): # parse command line options parser = argparse.ArgumentParser() parser.add_argument('visitID', help='Visit ID', type=int) parser.add_argument('outputfolder', help='Path to output folder', type=str) parser.add_argument( '--datafolder', help= '(optional) Top level folder containing TopoMetrics Riverscapes projects', type=str) parser.add_argument('--verbose', help='Get more information in your logs.', action='store_true', default=False) args = parser.parse_args() # Make sure the output folder exists resultsFolder = os.path.join(args.outputfolder, "outputs") # Initiate the log file logg = Logger("Program") logfile = os.path.join(resultsFolder, "bankfull_metrics.log") xmlfile = os.path.join(resultsFolder, "bankfull_metrics.xml") logg.setup(logPath=logfile, verbose=args.verbose) # Initiate the log file log = Logger("Program") log.setup(logPath=logfile, verbose=args.verbose) try: # Make some folders if we need to: if not os.path.isdir(args.outputfolder): os.makedirs(args.outputfolder) if not os.path.isdir(resultsFolder): os.makedirs(resultsFolder) # If we need to go get our own topodata.zip file and unzip it we do this if args.datafolder is None: topoDataFolder = os.path.join(args.outputfolder, "inputs") fileJSON, projectFolder = downloadUnzipTopo( args.visitID, topoDataFolder) # otherwise just pass in a path to existing data else: projectFolder = args.datafolder from champmetrics.lib.topoproject import TopoProject topo_project = TopoProject( os.path.join(projectFolder, "project.rs.xml")) tree = ET.parse(os.path.join(projectFolder, "project.rs.xml")) root = tree.getroot() visitid = root.findtext( "./MetaData/Meta[@name='Visit']") if root.findtext( "./MetaData/Meta[@name='Visit']" ) is not None else root.findtext( "./MetaData/Meta[@name='VisitID']") finalResult = BankfullMetrics(topo_project.getpath("DEM"), topo_project.getpath("DetrendedDEM"), topo_project.getpath("Topo_Points")) write_bfmetrics_xml(finalResult, visitid, xmlfile) sys.exit(0) except (DataException, MissingException, NetworkException) as e: # Exception class prints the relevant information traceback.print_exc(file=sys.stdout) sys.exit(e.returncode) except AssertionError as e: log.error(e) traceback.print_exc(file=sys.stdout) sys.exit(1) except Exception as e: log.error(e) traceback.print_exc(file=sys.stdout) sys.exit(1)
class TopoData: def __init__(self, sFolder, visitID): self.directory = sFolder self.visitID = visitID self.Channels = {'Wetted': Channel(), 'Bankfull': Channel()} self.DEM = "" self.Depth = "" self.WaterSurface = "" self.ChannelUnits = "" self.Thalweg = "" self.TopoPoints = "" # This object will be empty if there is no project.rs.xml file in the sFolder self.riverscapes = TopoProject(sFolder) def buildManualFile(self, layerFileName, bMandatory): """ Building a file path using manual layer file naming :param layerName: :param bMandatory: :return: """ path = "" log = Logger("buildManualFile") try: match = next(file for file in os.listdir(self.directory) if file.lower() == layerFileName.lower()) path = os.path.join(self.directory, match) except Exception as e: log.warning( "The file called '{0}' does not exist in directory: {1}". format(layerFileName, self.directory)) pass # if bMandatory: # log.error("The file called '{0}' does not exist in directory: {1}".format(layerFileName, self.directory)) # raise DataException("The file called '{0}' does not exist") return path def buildProjectFile(self, layerName, bMandatory): """ Build a file using riverscapes XML :param layerName: :param bMandatory: :return: """ path = "" try: path = self.riverscapes.getpath(layerName) except DataException as e: pass # if bMandatory: # raise e return path def loadlayers(self): # If we have a topo toolbar project with a project.rs.xml file this is what we have to do if self.riverscapes.isrsproject: self.Channels['Wetted'].Centerline = self.buildProjectFile( "WettedCenterline", True) self.Channels['Wetted'].CrossSections = self.buildProjectFile( "WettedCrossSections", False) self.Channels['Wetted'].Extent = self.buildProjectFile( "WaterExtent", True) self.Channels['Wetted'].Islands = self.buildProjectFile( "WettedIslands", False) self.Channels['Bankfull'].Centerline = self.buildProjectFile( "BankfullCenterline", True) self.Channels['Bankfull'].CrossSections = self.buildProjectFile( "BankfullCrossSections", False) self.Channels['Bankfull'].Extent = self.buildProjectFile( "BankfullExtent", True) self.Channels['Bankfull'].Islands = self.buildProjectFile( "BankfullIslands", False) self.DEM = self.buildProjectFile("DEM", True) self.Detrended = self.buildProjectFile("DetrendedDEM", True) self.Depth = self.buildProjectFile("WaterDepth", True) self.WaterSurface = self.buildProjectFile("WaterSurfaceDEM", True) self.ChannelUnits = self.buildProjectFile("ChannelUnits", True) self.Thalweg = self.buildProjectFile("Thalweg", True) self.TopoPoints = self.buildProjectFile("Topo_Points", True) # If this is just a folder full of files we have to use filenames else: self.Channels['Wetted'].Centerline = self.buildManualFile( "Centerline.shp", True) self.Channels['Wetted'].CrossSections = self.buildManualFile( "WettedXS.shp", False) self.Channels['Wetted'].Extent = self.buildManualFile( "WaterExtent.shp", True) self.Channels['Wetted'].Islands = self.buildManualFile( "WIslands.shp", False) self.Channels['Bankfull'].Centerline = self.buildManualFile( "BankfullCL.shp", True) self.Channels['Bankfull'].CrossSections = self.buildManualFile( "BankfullXS.shp", False) self.Channels['Bankfull'].Extent = self.buildManualFile( "Bankfull.shp", True) self.Channels['Bankfull'].Islands = self.buildManualFile( "BIslands.shp", False) self.DEM = self.buildManualFile("DEM.tif", True) self.Detrended = self.buildManualFile("Detrended.tif", True) self.Depth = self.buildManualFile("Water_Depth.tif", True) self.WaterSurface = self.buildManualFile("WSEDEM.tif", True) self.ChannelUnits = self.buildManualFile("Channel_Units.shp", True) self.Thalweg = self.buildManualFile("Thalweg.shp", True) self.TopoPoints = self.buildManualFile("Topo_Points.shp", True)
def channelUnitScraper(outputDir, watersheds): visitData = {} for watershed, apiName in watersheds.items(): visitData[watershed] = {} loadVisitData(watershed, apiName, visitData[watershed]) for watershed, visits in visitData.items(): outPath = os.path.join(outputDir, watershed.replace(' ', '') + ".shp") outShape = None featureID = 0 for visitID, visit in visits.items(): if len(visit['ChannelUnits']) < 1: continue try: dirpath = tempfile.mkdtemp() # Open the visit channel unit shapefile. # Need the spatial reference from one of the visits to create the output watershed shapefile try: fileJSON, projPath = downloadUnzipTopo(visitID, dirpath) topo = TopoProject(projPath) cuPath = topo.getpath('ChannelUnits') except (DataException, MissingException), e: print("Error retrieving channel units ShapeFile for visit {0}").format(visitID) continue try: shpCU = Shapefile(cuPath) except Exception as e: print("Error OGR opening channel unit ShapeFile for visit {0}").format(visitID) continue if not outShape: # Create new ShapeFile for this watershed outShape = Shapefile() outShape.create(outPath, shpCU.spatialRef, geoType=ogr.wkbPolygon) outShape.createField("ID", ogr.OFTInteger) outShape.createField("Watershed", ogr.OFTString) outShape.createField("Site", ogr.OFTString) outShape.createField("VisitID", ogr.OFTInteger) outShape.createField("SampleYear", ogr.OFTInteger) outShape.createField("Org", ogr.OFTString) outShape.createField("UnitNumber", ogr.OFTInteger) outShape.createField("UnitArea", ogr.OFTReal) outShape.createField("Tier1", ogr.OFTString) outShape.createField("Tier2", ogr.OFTString) outShape.createField("AvgSiteWid", ogr.OFTReal) outShape.createField("ReachLen", ogr.OFTReal) # Loop over all channel unit polygons for this visit feats = shpCU.featuresToShapely() for aFeat in feats: featureID += 1 cuNumber = aFeat['fields']['UnitNumber'] featureDefn = outShape.layer.GetLayerDefn() outFeature = ogr.Feature(featureDefn) outFeature.SetField('ID', featureID) outFeature.SetField('Watershed', visit['Watershed']) outFeature.SetField('Site', visit['Site']) outFeature.SetField('VisitID', visitID) outFeature.SetField('SampleYear', visit['SampleYear']) outFeature.SetField('Org', visit['Organization']) outFeature.SetField('AvgSiteWid', visit['AverageSiteWidth']) outFeature.SetField('ReachLen', visit['TotalReachLength']) outFeature.SetField('UnitNumber', cuNumber) outFeature.SetField('Tier1', visit['ChannelUnits'][cuNumber]['Tier1']) outFeature.SetField('Tier2', visit['ChannelUnits'][cuNumber]['Tier2']) outFeature.SetField('UnitArea', aFeat['geometry'].area) outFeature.SetGeometry(ogr.CreateGeometryFromJson(json.dumps(mapping(aFeat['geometry'])))) outShape.layer.CreateFeature(outFeature) finally:
def hydro_gis_export(hydro_project_xml, topo_project_xml, outfolder): """ :param jsonFilePath: :param outputFolder: :param bVerbose: :return: """ #gdal.UseExceptions() log = Logger("Hydro GIS Export") # 1 todo Read project.rs.xml rs_hydro = Project(hydro_project_xml) rs_topo = TopoProject(topo_project_xml) hydro_results_folder = os.path.dirname(hydro_project_xml) if "Visit" not in rs_hydro.ProjectMetadata: raise MissingException("Cannot Find Visit ID") visit_id = rs_hydro.ProjectMetadata['Visit'] dem = gdal.Open(rs_topo.getpath("DEM")) dem_srs = dem.GetProjection() dem_x_size = dem.RasterXSize dem_y_size = dem.RasterYSize dem_band = dem.GetRasterBand(1) dem_ndv = dem_band.GetNoDataValue() dem_geotransfrom = dem.GetGeoTransform() # 3 Get data columns in csv file csvfile = os.path.join(hydro_results_folder, "dem_grid_results.csv") csvfile_clean = os.path.join(hydro_results_folder, "dem_grid_results_clean_header.csv") if not os.path.isfile(csvfile): raise MissingException("Required file {} does not exist.".format(csvfile)) with open(csvfile, "rb") as f_in, open(csvfile_clean, "wb") as f_out: reader = csv.reader(f_in) # writer = csv.writer(f_out) cols = [col for col in reader.next() if col not in ["Y", "X"]]#[col.replace(".", "_") for col in reader.next() if col not in ["Y", "X"]] log.info("Loaded fields from csv file.") # writer.writerow(['X', 'Y'] + cols) # for row in reader: # writer.writerow(row) # log.info("Saved csv file with sanitized headers.") # Write VRT file vrt = os.path.join(hydro_results_folder, '{}.vrt'.format("dem_grid_results")) with open(vrt, 'wt') as f: f.write('<OGRVRTDataSource>\n') f.write('\t<OGRVRTLayer name="{}">\n'.format("dem_grid_results")) f.write('\t\t<SrcDataSource>{}</SrcDataSource>\n'.format(csvfile)) f.write('\t\t<SrcLayer>{}</SrcLayer>\n'.format("dem_grid_results")) f.write('\t\t<GeometryType>wkbPoint25D</GeometryType>\n') f.write('\t\t<LayerSRS>{}</LayerSRS>\n'.format(dem_srs)) f.write('\t\t<GeometryField encoding="PointFromColumns" x="X" y="Y" />\n') for field in cols: f.write('\t\t<Field name="{}" type="Real" subtype="Float32" />\n'.format(field)) f.write('\t</OGRVRTLayer>\n') f.write('</OGRVRTDataSource>\n') log.info("Generated vrt file {}".format(vrt)) # Open csv as OGR ogr_vrt = ogr.Open(vrt, 1) if ogr_vrt is None: raise DataException("unable to open {}".format(vrt)) layer = ogr_vrt.GetLayer() # 4 Generate geotiff for each column in the CSV file driver = gdal.GetDriverByName("GTiff") for col in cols: out_tif = os.path.join(outfolder, '{}.tif'.format(col)) out_raster = driver.Create(out_tif, dem_x_size, dem_y_size, 1, gdalconst.GDT_Float32) out_raster.SetGeoTransform(dem_geotransfrom) out_raster.SetProjection(dem_srs) band = out_raster.GetRasterBand(1) band.SetNoDataValue(dem_ndv) band.FlushCache() gdal.RasterizeLayer(out_raster, [1], layer, options=["ATTRIBUTE={}".format(col)]) band.GetStatistics(0, 1) band.FlushCache() out_raster.FlushCache() log.info("Generated {} for attribute {}".format(out_tif, col)) if col == "Depth": raw = numpy.array(band.ReadAsArray()) masked = numpy.ma.masked_array(raw, raw == dem_ndv) bool_raster = numpy.array(masked, "bool") numpy.greater(masked, 0, bool_raster) raster_mem = gdal.GetDriverByName("GTIFF").Create(os.path.join(outfolder, "Temp.tif"), dem_x_size, dem_y_size, 1, gdalconst.GDT_Int16) raster_mem.SetGeoTransform(dem_geotransfrom) raster_mem.SetProjection(dem_srs) band_mem = raster_mem.GetRasterBand(1) band_mem.WriteArray(bool_raster, 0, 0) band_mem.SetNoDataValue(dem_ndv) band_mem.FlushCache() temp = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource(os.path.join(outfolder, "TempExtent.shp")) temp_layer = temp.CreateLayer("RawExtent", osr.SpatialReference(wkt=dem_srs), ogr.wkbPolygon) temp_layer.CreateField(ogr.FieldDefn("Value", ogr.OFTInteger)) temp_layer.CreateField(ogr.FieldDefn("Area", ogr.OFTReal)) gdal.Polygonize(band_mem, None, temp_layer, 0) del raster_mem # # for feature in temp_layer: # feature.SetField("Area", feature.GetGeometryRef().GetArea()) # temp_layer.SetFeature(feature) # Stage Extent # temp_layer.SetAttributeFilter("Value=1") # shp_extent = os.path.join(outfolder, "StageExtent.shp") # driver_extent = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource(shp_extent) # driver_extent.CopyLayer(temp_layer, "StageExtent") # driver_extent = None # ogr_extent = ogr.Open(shp_extent, 1) # layer_extent = ogr_extent.GetLayer("StageExtent") # field_extent = ogr.FieldDefn("ExtentType", ogr.OFTString) # layer_extent.CreateField(field_extent) # area_current = 0.0 # fid_current = None # for feature in layer_extent: # area_feat = feature.GetGeometryRef().GetArea() # if area_feat > area_current: # area_current = area_feat # fid_current = feature.GetFID() # # edit_feat = layer_extent.GetFeature(fid_current) # edit_feat.SetField("ExtentType", "Channel") # layer_extent.SetFeature(edit_feat) # # layer_extent.DeleteField(layer_extent.FindFieldIndex("Value", True)) # #ogr_extent.Destroy() # log.info("Generated Stage Extent Shapefile {}".format(shp_extent)) # # # Stage Islands # import time # time.sleep(5) # temp_layer.ResetReading() # temp_layer.SetAttributeFilter("Value=0") # shp_islands = os.path.join(outfolder, "StageIslands.shp") # driver_islands = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource(shp_islands) # driver_islands.CopyLayer(temp_layer, "StageIslands") # driver_islands = None # ogr_islands = ogr.Open(shp_islands, 1) # layer_islands = ogr_islands.GetLayer("StageIslands") # # field_qual = ogr.FieldDefn("Qualifying", ogr.OFTInteger) # field_qual.SetDefault("0") # field_valid = ogr.FieldDefn("IsValid", ogr.OFTInteger) # field_valid.SetDefault("0") # layer_islands.CreateField(field_qual) # layer_islands.CreateField(field_valid) # layer_islands.SyncToDisk() # # area_current = 0.0 # fid_current = None # for feature in layer_islands: # if feature is not None: # g = feature.GetGeometryRef() # area_feat = g.GetArea() # # todo identify qualifying islands here? # if area_feat > area_current: # area_current = area_feat # fid_current = feature.GetFID() # # #feat_del = layer_islands.GetFeature(fid_current) # layer_islands.DeleteFeature(fid_current) # # layer_islands.DeleteField(layer_islands.FindFieldIndex("Value", True)) # ogr_islands = None # ogr_extent = None # log.info("Generated Stage Islands Shapefile {}".format(shp_islands)) temp = None del out_raster shp_hydroresults = os.path.join(outfolder, "HydroResults.shp") ogr.GetDriverByName("ESRI Shapefile").CopyDataSource(ogr_vrt, shp_hydroresults) #out_shp = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource() # ogr_shp = ogr.Open(shp_hydroresults, 1) # lyr = ogr_shp.GetLayer() # lyr_defn = lyr.GetLayerDefn() # for i in range(lyr_defn.GetFieldCount()): # fielddefn = lyr_defn.GetFieldDefn(i) # fielddefn.SetName(fielddefn.GetName().replace(".","_")) # lyr.AlterFieldDefn(i, fielddefn, ogr.ALTER_NAME_FLAG) # # new_field = ogr.FieldDefn('V_Bearing', ogr.OFTReal) # lyr.CreateField(new_field) # # Calculate Velocity Bearing # for feat in lyr: # vel_x = feat.GetField("X_Velocity") # vel_y = feat.GetField("Y_Velocity") # dir = 90 - math.degrees(math.atan2(float(vel_y), float(vel_x))) # bearing = 360 + dir if dir < 0 else dir # feat.SetField('V_Bearing', float(bearing)) # lyr.SetFeature(feat) log.info("Generated Hydro Results Shapefile {}".format(shp_hydroresults)) ogr_vrt = None ogr_shp = None return 0
def load_topo_project(self, directory, visitID): """ :param directory: full path to directory of survey, i.e. C://Visit//GISLayers :type directory: str :param channelunitsjson: path to channel unit json file :return: None """ # If we have a project.rs.xml file tp gets a value tp = TopoProject(directory) def getPath(layername): """ This is a tricky little method. If there is a project.rs.xml file (maude) and we have a tp.getNamePath method then run it. Otherwise just return the 'directory' variable (harold) """ try: return tp.getpath(layername) except Exception as e: # This is kind of a weird thing to do. There will be nothing in this path but this will let things # fail gracefully return os.path.join(directory, "FILENOTFOUND.TIF") #CHaMP_Vector.fieldName_Description = "DESCRIPTIO" #CHaMP_ChannelUnits.fieldName_UnitNumber = "Unit_Numbe" # load expected files, does not mean they exist. self.DEM = vc.CHaMP_DEM("DEM", getPath("DEM")) self.DetrendedDEM = vc.CHaMP_DetrendedDEM("DetrendedDEM", getPath("DetrendedDEM")) self.WaterDepth = vc.CHaMP_WaterDepth("WaterDepth", getPath("WaterDepth")) self.ErrorSurface = vc.CHaMP_ErrorSurface("ErrorSurface", getPath("ErrorSurface")) self.WaterSurfaceDEM = vc.CHaMP_WaterSurfaceDEM("WaterSurfaceDEM", getPath("WaterSurfaceDEM")) self.AssocPointQuality = vc.CHaMP_Associated_3DPointQuality("AssocPointQuality", getPath("AssocPointQuality")) self.AssocSlope = vc.CHaMP_Associated_Slope("AssocSlope", getPath("AssocSlope")) self.AssocRough = vc.CHaMP_Associated_Roughness("AssocRough", getPath("AssocRough")) self.AssocPointDensity = vc.CHaMP_Associated_PointDensity("AssocPointDensity", getPath("AssocPointDensity")) self.AssocInterpolationError = vc.CHaMP_Associated_InterpolationError("AssocInterpolationError", getPath("AssocInterpolationError")) self.Topo_Points = vc.CHaMP_TopoPoints("Topo_Points", getPath("Topo_Points")) self.Topo_Points.dem = self.DEM.filename self.StreamFeatures = vc.CHaMP_StreamFeature_Points("StreamFeatures", getPath("StreamFeatures")) self.EdgeofWater_Points = vc.CHaMP_EdgeofWater_Points("EdgeofWater_Points", getPath("EdgeofWater_Points")) self.EdgeofWater_Points.dem = self.DEM.filename self.Control_Points = vc.CHaMP_ControlPoints("Control_Points", getPath("Control_Points")) self.Error_Points = vc.CHaMP_Error_Points("Error_Points", getPath("Error_Points")) self.Breaklines = vc.CHaMP_Breaklines("Breaklines", getPath("Breaklines")) self.Breaklines.survey_points = self.Topo_Points.get_list_geoms() + self.EdgeofWater_Points.get_list_geoms() self.WaterExtent = vc.CHaMP_WaterExtent("WaterExtent", getPath("WaterExtent"), "Wetted") self.WaterExtent.topo_in_point = self.Topo_Points.get_in_point() self.WaterExtent.topo_out_point = self.Topo_Points.get_out_point() self.BankfullExtent = vc.CHaMP_WaterExtent("BankfullExtent", getPath("BankfullExtent"), "Bankfull") self.BankfullExtent.topo_in_Point = self.Topo_Points.get_in_point() self.BankfullExtent.topo_out_point = self.Topo_Points.get_out_point() self.WettedIslands = vc.CHaMP_Islands("WettedIslands", getPath("WettedIslands"), "Wetted") self.BankfullIslands = vc.CHaMP_Islands("BankfullIslands", getPath("BankfullIslands"), "Bankfull") self.ChannelUnits = CHaMP_ChannelUnits("ChannelUnits", getPath("ChannelUnits")) self.ChannelUnits.load_attributes(visitID) if self.WaterExtent.field_exists("ExtentType"): self.ChannelUnits.wetted_extent = self.WaterExtent.get_main_extent_polygon() self.Thalweg = CHaMP_Thalweg("Thalweg", getPath("Thalweg")) self.Thalweg.dem = self.DEM.filename if self.WaterExtent.field_exists("ExtentType"): self.Thalweg.extent_polygon = self.WaterExtent.get_main_extent_polygon() self.Thalweg.topo_in_point = self.Topo_Points.get_in_point() self.Thalweg.topo_out_point = self.Topo_Points.get_out_point() self.WettedCenterline = CHaMP_Centerline("WettedCenterline", getPath("WettedCenterline"), "Wetted") self.WettedCenterline.thalweg = self.Thalweg.get_thalweg() if self.WaterExtent.field_exists("ExtentType"): self.WettedCenterline.extent_polygon = self.WaterExtent.get_main_extent_polygon() self.BankfullCenterline = CHaMP_Centerline("BankfullCenterline", getPath("BankfullCenterline"), "Bankfull") self.BankfullCenterline.thalweg = self.Thalweg.get_thalweg() if self.BankfullExtent.field_exists("ExtentType"): self.BankfullCenterline.extent_polygon = self.BankfullExtent.get_main_extent_polygon() self.WettedCrossSections = CHaMP_CrossSections("WettedCrossSections", getPath("WettedCrossSections"), "Wetted") self.BankfullCrossSections = CHaMP_CrossSections("BankfullCrossSections", getPath("BankfullCrossSections"), "Bankfull") if self.DEM.exists(): self.get_dem_attributes() self.demDataExtent = get_data_polygon(self.DEM.filename) for dataset in self.datasets(): if isinstance(dataset, CHaMP_Raster): dataset.surveyDEM_Polygon = self.dem_extent dataset.spatial_reference_dem_wkt = self.dem_spatial_reference_WKT if isinstance(dataset, CHaMP_Vector): dataset.demDataExtent = self.demDataExtent return