Example #1
0
def build_xml(projectpath):
    """Here's an example of how to build a project.rs.xml file

    Args:
        projectpath ([type]): [description]
    """
    # Create the top-level nodes
    log = Logger('build_xml')
    log.info('Starting the build of the XML')
    project_name = 'Inundation Mapper'
    project = RSProject(cfg, projectpath)
    project.create(project_name, 'Inundation')

    # Add the root metadata
    project.add_metadata({
        'ModelVersion': cfg.version,
        'date_created': str(int(time.time())),
        'HUC8': '16010201',
        'InundationVersion': cfg.version,
        'watershed': 'Upper Bear',
        'site_name': 'Mill Creek',
    })

    # Create the realizations container node
    realizations = project.XMLBuilder.add_sub_element(project.XMLBuilder.root,
                                                      'Realizations')

    # Example InundationContext Realization
    # ================================================================================================
    r1_node = project.XMLBuilder.add_sub_element(
        realizations, 'InundationContext', None, {
            'id': 'INN_CTX01',
            'dateCreated': datetime.datetime.now().isoformat(),
            'guid': str(uuid.uuid1()),
            'productVersion': cfg.version
        })
    #  add a <Name> node
    project.XMLBuilder.add_sub_element(r1_node, 'Name', project_name)

    # Realization <MetaData>
    project.add_metadata(
        {
            'mapper': 'Karen Bartelt',
            'date_mapped': '02042020',
            'year1': 'estimated pre beaver',
            'year2': '2019',
            'RS_used': 'RS_01'
        }, r1_node)

    # Add an <Input> and <Output> nodes
    r1_inputs = project.XMLBuilder.add_sub_element(r1_node, 'Inputs')
    r1_outputs = project.XMLBuilder.add_sub_element(r1_node, 'Outputs')

    # Now we can add inputs to the context raster
    # Note the return is an HTML node and a raster path we can use for other things
    raster_node, raster_path = project.add_project_raster(r1_inputs,
                                                          LayerTypes['AP_01'],
                                                          replace=False)

    # Here we add a vector node
    vector_node, vector_path = project.add_project_vector(
        r1_inputs, LayerTypes['APSTR_01'], replace=False)

    # Example DCE Realization
    # ================================================================================================
    r2_node = project.XMLBuilder.add_sub_element(
        realizations, 'InundationDCE', None, {
            'id': 'DCE_01',
            'dateCreated': datetime.datetime.now().isoformat(),
            'guid': str(uuid.uuid1()),
            'productVersion': cfg.version
        })

    r2_name_node = project.XMLBuilder.add_sub_element(r2_node, 'Name',
                                                      'August 2019')
    # Add an <Input> and <Output> nodes
    r2_inputs = project.XMLBuilder.add_sub_element(r2_node, 'Inputs')
    r2_outputs = project.XMLBuilder.add_sub_element(r2_node, 'Outputs')

    # Example CD Realization
    # ================================================================================================
    r3_node = project.XMLBuilder.add_sub_element(
        realizations, 'InundationCD', None, {
            'id': '',
            'dateCreated': datetime.datetime.now().isoformat(),
            'guid': str(uuid.uuid1()),
            'productVersion': cfg.version
        })
    r3_name_node = project.XMLBuilder.add_sub_element(
        r3_node, 'Name', '2019 vs estimated pre beaver')
    # Add an <Input> and <Output> nodes
    r3_inputs = project.XMLBuilder.add_sub_element(r3_node, 'Inputs')
    r3_outputs = project.XMLBuilder.add_sub_element(r3_node, 'Outputs')

    # Finally write the file
    log.info('Writing file')
    project.XMLBuilder.write()
    log.info('Done')
def brat_run(project_root, csv_dir):
    """Run the BRAT model and calculat dam capacity
    as well as conservation and restoration.

    Arguments:
        database {str} -- Path to existing BRAT SQLite database
        csv_dir {str} -- Path to the directory containing the BRAT lookup CSV data files
        shapefile {str} -- Path to the existing BRAT reach segment ShapeFile
        project_root {str} -- (Optional) path to Riverscapes project directory
    """

    log = Logger('BRAT Run')
    log.info('Starting BRAT run')

    project = RSProject(cfg, project_root)

    project.add_metadata({
        'BRATRunVersion': cfg.version,
        'BRATRunTimestamp': str(int(time.time()))
    })

    realizations = project.XMLBuilder.find('Realizations').findall('BRAT')
    if len(realizations) != 1:
        raise Exception(
            'Could not find a valid realization inside the existing brat project'
        )

    # Fetch some XML nodes we'll need to aleter
    r_node = realizations[0]
    input_node = r_node.find('Inputs')
    intermediate_node = r_node.find('Intermediates')
    outputs_node = r_node.find('Outputs')

    # Get the filepaths for the DB and shapefile
    gpkg_path = os.path.join(
        project.project_dir,
        r_node.find('Outputs/Geopackage[@id="OUTPUTS"]/Path').text)

    if not os.path.isfile(gpkg_path):
        raise Exception(
            'BRAT geopackage file missing at {}. You must run Brat Build first.'
            .format(gpkg_path))

    # Update any of the lookup tables we need
    update_database(gpkg_path, csv_dir)

    # Store the BRAT Run date time to the database (for reporting)
    store_metadata(gpkg_path, 'BRAT_Run_DateTime',
                   datetime.datetime.now().isoformat())

    watershed, max_drainage_area, ecoregion = get_watershed_info(gpkg_path)

    # Set database output columns to NULL before processing (note omission of string lookup fields from view)
    set_reach_fields_null(gpkg_path, output_fields[ogr.OFTReal])
    set_reach_fields_null(gpkg_path, output_fields[ogr.OFTInteger])

    # Calculate the low and high flow using regional discharge equations
    hydrology(gpkg_path, 'Low', watershed)
    hydrology(gpkg_path, '2', watershed)

    # Calculate the vegetation and combined FIS for the existing and historical vegetation epochs
    for epoch, prefix, ltype, orig_id in Epochs:

        # Calculate the vegetation suitability for each buffer
        [
            vegetation_suitability(gpkg_path, buffer, prefix, ecoregion)
            for buffer in get_stream_buffers(gpkg_path)
        ]

        # Run the vegetation and then combined FIS for this epoch
        vegetation_fis(gpkg_path, epoch, prefix)
        combined_fis(gpkg_path, epoch, prefix, max_drainage_area)

        orig_raster = os.path.join(
            project.project_dir,
            input_node.find('Raster[@id="{}"]/Path'.format(orig_id)).text)
        _veg_suit_raster_node, veg_suit_raster = project.add_project_raster(
            intermediate_node, LayerTypes[ltype], None, True)
        output_vegetation_raster(gpkg_path, orig_raster, veg_suit_raster,
                                 epoch, prefix, ecoregion)

    # Calculate departure from historical conditions
    with SQLiteCon(gpkg_path) as database:
        log.info('Calculating departure from historic conditions')
        database.curs.execute(
            'UPDATE ReachAttributes SET mCC_HisDep = mCC_HPE_CT - mCC_EX_CT WHERE (mCC_EX_CT IS NOT NULL) AND (mCC_HPE_CT IS NOT NULL)'
        )
        database.conn.commit()

    # Land use intesity, conservation and restoration
    land_use(gpkg_path, 100.0)
    conservation(gpkg_path)

    report_path = os.path.join(project.project_dir,
                               LayerTypes['BRAT_RUN_REPORT'].rel_path)
    project.add_report(outputs_node,
                       LayerTypes['BRAT_RUN_REPORT'],
                       replace=True)

    report = BratReport(gpkg_path, report_path, project)
    report.write()

    log.info('BRAT run complete')