Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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
Exemplo n.º 6
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)
Exemplo n.º 7
0
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
Exemplo n.º 10
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