Ejemplo n.º 1
0
 def weirs_from_hydamo(self, weirs, yz_profiles=None, parametrised_profiles=None, afsluitmiddel=None, sturing=None):
     """
     Method to convert dflowfm weirs from hydamo weirs.
     
     Split the HyDAMO weirs object into a subset with 'regular weirs' and 'universal weirs'. 
    
     For now the assumption is that weirs for which a profile is defined, are universal, other weirs are regular.
            
     """
     # Convert to dflowfm input
     
     regular = ExtendedGeoDataFrame(geotype=Point, required_columns=weirs.required_columns)
     index = np.zeros((len(weirs.code)))
     if yz_profiles is not None:
         if 'codegerelateerdobject' in yz_profiles:            
             index[np.isin(weirs.code , np.asarray(yz_profiles.codegerelateerdobject))]=1
     if parametrised_profiles is not None:
         if 'codegerelateerdobject' in parametrised_profiles:            
             index[np.isin(weirs.code , np.asarray(parametrised_profiles.codegerelateerdobject))]=1
        
     regular.set_data(weirs[index==0], index_col='code',check_columns=True)        
     regular_geconverteerd = hydamo_to_dflowfm.generate_weirs(regular, afsluitmiddel=afsluitmiddel)        
     regular.set_data(weirs, index_col='code',check_columns=True)        
     
     # Add to dict
     for weir in regular_geconverteerd.itertuples():
         self.structures.add_weir(
             id=weir.code,
             branchid=weir.branch_id,
             chainage=weir.branch_offset,                
             crestlevel=weir.laagstedoorstroomhoogte,
             crestwidth=weir.laagstedoorstroombreedte,
             corrcoeff=weir.afvoercoefficient
         )
 
     universal = ExtendedGeoDataFrame(geotype=Point, required_columns=weirs.required_columns)
     universal.set_data(weirs[index==1], index_col='code',check_columns=True)                                      
     universal_geconverteerd = hydamo_to_dflowfm.generate_uweirs(universal,yz_profiles=yz_profiles, parametrised_profiles=parametrised_profiles)
     
     if universal_geconverteerd.empty:
         return("No profile detected for universal weir)")
     # Add to dict
     for uweir in universal_geconverteerd.itertuples():
         self.structures.add_uweir(
             id=uweir.code,
             branchid=uweir.branch_id,
             chainage=uweir.branch_offset,                
             crestlevel=uweir.laagstedoorstroomhoogte,                
             numlevels=uweir.numlevels,
             yvalues=uweir.yvalues,
             zvalues=uweir.zvalues,
             allowedflowdir='both',
             dischargecoeff=uweir.afvoercoefficient                
         )    
Ejemplo n.º 2
0
    def from_hydamo(self, dwarsprofielen, parametrised=None, branches=None):
        """
        Method to add cross section from hydamo files. Two files
        can be handed to the function, the cross section file (dwarsprofiel) and the
        parametrised file (normgeparametriseerd). The
        hierarchical order is 1. dwarsprofiel, 2. normgeparametriseerd.
        Each branch will be assigned a profile following this order. If parametrised
        and standard are not given, branches can be without cross section. In that case
        a standard profile should be assigned
        """

        # first, make a selection as to use only the dwarsprofielen/parametrised that are related to branches, not structures
        if dwarsprofielen is not None:
            if 'codegerelateerdobject' not in dwarsprofielen:
                dwarsprofielen['codegerelateerdobject'] = np.empty(
                    (len(dwarsprofielen))) * np.nan
            dp_branches = ExtendedGeoDataFrame(
                geotype=LineString,
                columns=dwarsprofielen.required_columns +
                ['codegerelateerdobject'])
            dp_branches.set_data(
                dwarsprofielen[dwarsprofielen.codegerelateerdobject.isna()],
                index_col='code',
                check_columns=True)
        else:
            dp_branches = ExtendedGeoDataFrame(geotype=LineString)

        if parametrised is not None:
            if 'codegerelateerdobject' not in parametrised:
                parametrised['codegerelateerdobject'] = np.empty(
                    (len(parametrised))) * np.nan
            if len(parametrised) > 0:
                par_branches = ExtendedGeoDataFrame(
                    geotype=LineString,
                    columns=parametrised.required_columns +
                    ['codegerelateerdobject'])
                par_branches.set_data(
                    parametrised[parametrised.codegerelateerdobject.isna()],
                    index_col='code',
                    check_columns=True)
            else:
                par_branches = ExtendedGeoDataFrame(
                    geotype=LineString,
                    columns=parametrised.required_columns +
                    ['codegerelateerdobject'])
            # Assign cross-sections to branches
            nnocross = len(
                self.crosssections.get_branches_without_crosssection())
            logger.info(
                f'Before adding the number of branches without cross section is: {nnocross}.'
            )
        else:
            par_branches = ExtendedGeoDataFrame(geotype=LineString)

        if not dp_branches.empty:
            # 1. Collect cross sections from 'dwarsprofielen'
            crosssections = hydamo_to_dflowfm.dwarsprofiel_to_yzprofiles(
                dp_branches, branches)

            for name, css in crosssections.items():
                # Add definition
                self.crosssections.add_yz_definition(
                    yz=css['yz'],
                    thalweg=css['thalweg'],
                    name=name,
                    roughnesstype=css['ruwheidstypecode'],
                    roughnessvalue=css['ruwheidswaarde'])
                # Add location
                self.crosssections.add_crosssection_location(
                    branchid=css['branchid'],
                    chainage=css['chainage'],
                    definition=name)

        # Check the number of branches with cross sections
        no_crosssection = self.crosssections.get_branches_without_crosssection(
        )
        nnocross = len(no_crosssection)
        logger.info(
            f'After adding \'dwarsprofielen\' the number of branches without cross section is: {nnocross}.'
        )
        if (nnocross == 0):
            print('No further branches without a profile.')
        elif par_branches.empty:
            print('No parametrised crossections available for branches.')
        else:
            # Derive norm cross sections for norm parametrised
            crosssections = hydamo_to_dflowfm.parametrised_to_profiles(
                par_branches, no_crosssection)
            # Get branch information
            branchdata = self.crosssections.dflowfmmodel.network.branches.loc[
                list(crosssections.keys())]
            branchdata['chainage'] = branchdata.length / 2.

            # Add cross sections
            for branchid, css in crosssections.items():
                chainage = branchdata.at[branchid, 'chainage']

                if css['type'] == 'rectangle':
                    name = self.crosssections.add_rectangle_definition(
                        height=css['height'],
                        width=css['width'],
                        closed=css['closed'],
                        roughnesstype=css['ruwheidstypecode'],
                        roughnessvalue=css['ruwheidswaarde'])

                if css['type'] == 'trapezium':
                    name = self.crosssections.add_trapezium_definition(
                        slope=css['slope'],
                        maximumflowwidth=css['maximumflowwidth'],
                        bottomwidth=css['bottomwidth'],
                        closed=css['closed'],
                        roughnesstype=css['ruwheidstypecode'],
                        roughnessvalue=css['ruwheidswaarde'])

                # Add location
                self.crosssections.add_crosssection_location(
                    branchid=branchid,
                    chainage=chainage,
                    definition=name,
                    shift=css['bottomlevel'])

            nnocross = len(
                self.crosssections.get_branches_without_crosssection())
            logger.info(
                f'After adding \'normgeparametriseerd\' the number of branches without cross section is: {nnocross}.'
            )

        # Assign cross-sections to structures
        nnocross = len(
            self.crosssections.get_structures_without_crosssection())
        logger.info(
            f'Before adding the number of structures without cross section is: {nnocross}.'
        )

        if dwarsprofielen is not None:
            # and subsets for structures
            dp_structures = ExtendedGeoDataFrame(geotype=LineString)
            dp_structures.set_data(
                dwarsprofielen[~dwarsprofielen.codegerelateerdobject.isna()],
                index_col='code',
                check_columns=True)

            # 1. Collect cross sections from 'dwarsprofielen'
            crosssections = hydamo_to_dflowfm.dwarsprofiel_to_yzprofiles(
                dp_structures, None)

            for name, css in crosssections.items():
                self.crosssections.add_yz_definition(
                    yz=css['yz'],
                    thalweg=css['thalweg'],
                    name=name,
                    roughnesstype=css['ruwheidstypecode'],
                    roughnessvalue=css['ruwheidswaarde'])

        if parametrised is not None:
            par_structures = ExtendedGeoDataFrame(
                geotype=LineString,
                columns=parametrised.required_columns +
                ['codegerelateerdobject'])
            par_structures.set_data(
                parametrised[~parametrised.codegerelateerdobject.isna()],
                index_col='code',
                check_columns=True)
        else:
            par_structures = ExtendedGeoDataFrame(geotype=LineString)

        no_crosssection = self.crosssections.get_structures_without_crosssection(
        )
        nnocross = len(no_crosssection)
        logger.info(
            f'After adding \'dwarsprofielen\' the number of branches without cross section is: {nnocross}.'
        )
        if (nnocross == 0):
            print('No further structures without a profile.')
        elif par_structures.empty:
            print('No parametrised crosssections available for structures.')
        else:
            # Derive norm cross sections for norm parametrised
            crosssections = hydamo_to_dflowfm.parametrised_to_profiles(
                par_structures, [])
            # Add cross section definitions
            for strucid, css in crosssections.items():

                if css['type'] == 'rectangle':
                    name = self.crosssections.add_rectangle_definition(
                        height=css['height'],
                        width=css['width'],
                        closed=css['closed'],
                        roughnesstype=css['ruwheidstypecode'],
                        roughnessvalue=css['ruwheidswaarde'],
                        name=strucid,
                    )

                if css['type'] == 'trapezium':
                    name = self.crosssections.add_trapezium_definition(
                        slope=css['slope'],
                        maximumflowwidth=css['maximumflowwidth'],
                        bottomwidth=css['bottomwidth'],
                        closed=css['closed'],
                        roughnesstype=css['ruwheidstypecode'],
                        roughnessvalue=css['ruwheidswaarde'],
                        name=strucid)

        nnocross = len(
            self.crosssections.get_structures_without_crosssection())
        logger.info(
            f'After adding \'normgeparametriseerd\' the number of structures without cross section is: {nnocross}.'
        )
Ejemplo n.º 3
0
def parametrised_to_profiles(parametrised, branches):
    """
    Generate parametrised cross sections for all branches,
    or the branches missing a cross section.

    Parameters
    ----------
    parametrised : pd.DataFrame
        GeoDataFrame with geometries and attributes of parametrised profiles.
    branches : list
        List of branches for which the parametrised profiles are derived

    Returns
    -------
    dictionary
        Dictionary with attributes of cross sections, usable for dflowfm
    """

    checks.check_argument(parametrised, 'parametrised',
                          (pd.DataFrame, gpd.GeoDataFrame))
    checks.check_argument(branches, 'branches', (list, tuple))

    # Find
    if len(branches) != 0:
        parambranches = ExtendedGeoDataFrame(
            geotype=LineString,
            columns=parametrised.columns.tolist() + ['css_type'])
        parambranches.set_data(parametrised[np.isin(parametrised.code,
                                                    branches)],
                               index_col='code',
                               check_columns=True)
    else:
        parambranches = parametrised
    #
    #else:
    #parambranches = parametrised.reindex(columns=parametrised.requiredcolumns + ['css_type'])
    #    parambranches = parametrised[np.isin(parametrised.code,branches)]# ['css_type'])

    # Drop profiles for which not enough data is available to write (as rectangle)
    #nulls = pd.isnull(parambranches[['bodembreedte', 'bodemhoogtebenedenstrooms', 'bodemhoogtebovenstrooms']]).any(axis=1).values
    #parambranches = parambranches.drop(ExtendedGeoDataFrame(geotype=LineString), parambranches.index[nulls], index_col='code',axis=0)
    #parambranches.drop(parambranches.index[nulls], inplace=True)

    # Determine characteristics
    botlev = (parambranches['bodemhoogtebenedenstrooms'] +
              parambranches['bodemhoogtebovenstrooms']) / 2.0
    dh1 = parambranches['hoogteinsteeklinkerzijde'] - botlev
    dh2 = parambranches['hoogteinsteekrechterzijde'] - botlev
    parambranches['height'] = (dh1 + dh2) / 2.0
    parambranches['bottomlevel'] = botlev

    # Determine maximum flow width and slope (both needed for output)
    parambranches[
        'maxflowwidth'] = parambranches['bodembreedte'] + parambranches[
            'taludhellinglinkerzijde'] * dh1 + parambranches[
                'taludhellingrechterzijde'] * dh2
    parambranches['slope'] = (parambranches['taludhellinglinkerzijde'] +
                              parambranches['taludhellingrechterzijde']) / 2.0

    # Determine profile type
    parambranches.loc[:, 'css_type'] = 'trapezium'
    nulls = pd.isnull(
        parambranches[parametrised.required_columns]).any(axis=1).values
    parambranches.loc[nulls, 'css_type'] = 'rectangle'

    cssdct = {}
    for branch in parambranches.itertuples():
        # Determine name for cross section
        if branch.css_type == 'trapezium':
            cssdct[branch.Index] = {
                'type':
                branch.css_type,
                'slope':
                round(branch.slope, 1),
                'maximumflowwidth':
                round(branch.maxflowwidth, 1),
                'bottomwidth':
                round(branch.bodembreedte, 3),
                'closed':
                0,
                'thalweg':
                0.0,
                'ruwheidstypecode':
                int(branch.ruwheidstypecode) if isinstance(
                    branch.ruwheidstypecode, float) else
                branch.ruwheidstypecode,
                'ruwheidswaarde':
                branch.ruwheidswaarde,
                'bottomlevel':
                branch.bottomlevel
            }
        elif branch.css_type == 'rectangle':
            cssdct[branch.Index] = {
                'type':
                branch.css_type,
                'height':
                5.0,
                'width':
                round(branch.bodembreedte, 3),
                'closed':
                0,
                'thalweg':
                0.0,
                'ruwheidstypecode':
                int(branch.ruwheidstypecode) if isinstance(
                    branch.ruwheidstypecode, float) else
                branch.ruwheidstypecode,
                'ruwheidswaarde':
                branch.ruwheidswaarde,
                'bottomlevel':
                branch.bottomlevel
            }

    return cssdct