Skip to main content
Version: 13

viktor.geo

RobertsonMethod

class viktor.geo.RobertsonMethod(soil_properties)

Bases: _ClassificationMethod

Class to pass Robertson specific properties such as soil_properties. Every list element at least requires a ‘name’ key that specifies the RobertsonZone. It is important that ‘name’ key matches with hardcoded RobertsonZone.name property. There are 9 Robertson zones and 1 Robertson zone unknown that can be specified

By default, the colors as defined in (red, green, blue) for each zone are as shown in this figure:

/_images/robertson_colors.png

Example:

soil_properties = [
   {'name': 'Robertson zone unknown', 'extra_property1': 1, 'extra_property2': 2},
   {'name': 'Robertson zone 1', 'extra_property1': 3, 'extra_property2': 4},
]
method = RobertsonMethod(soil_properties)
Parameters

soil_properties (List[dict]) – dictionary with soil properties

get_method_params()
Return type

dict

TableMethod

class viktor.geo.TableMethod(qualification_table, ground_water_level)

Bases: _ClassificationMethod

Class to pass TableMethod specific properties, such as a qualification_table and ground_water_level. The qualification_table is a list of dictionaries, containing for each user-specified soil type the accompanying qualification parameters (and possibly additional material properties). The required fields for each row are:

  • name

  • color in r, g, b

Also required fields, but can also be (partly) empty:

  • qc_min

  • qc_max

  • qc_norm_min

  • qc_norm_max

  • rf_min

  • rf_max

  • gamma_dry_min

  • gamma_dry_max

  • gamma_wet_min

  • gamma_wet_max

For more information about qc_norm (qc_normalized), see table 2.b in in NEN 9997-1+C1:2012, point g specifically. Besides the qualification table, a ground_water_level has to be provided as well, which is used to determine if gamma_dry or gamma_wet should be used to calculate qc_norm for each entry in the GEF file.

Example:

qualification_table = [
    {'name': 'Peat', 'color': '166,42,42', 'qc_min': 0, 'qc_max': '', 'qc_norm_min': '',
        'qc_norm_max': '', 'rf_min': 8, 'rf_max': '', 'gamma_dry_min': 10, 'gamma_wet_min': 10, <OTHER>},
    {'name': 'Clay', 'color': '125,180,116', 'qc_min': '', 'qc_max': 2, 'qc_norm_min': '',
        'qc_norm_max': '', 'rf_min': 1, 'rf_max': 8, 'gamma_dry_min': 20, 'gamma_wet_min': 22, <OTHER>},
    {'name': 'Loam', 'color': '125,150,116', 'qc_min': 2, 'qc_max': '', 'qc_norm_min': '',
        'qc_norm_max': '', 'rf_min': 1, 'rf_max': 8, 'gamma_dry_min': 20, 'gamma_wet_min': 22, <OTHER>},
    {'name': 'Sand', 'color': '239,255,12', 'qc_min': '', 'qc_max': '', 'qc_norm_min': 22,
        'qc_norm_max': '', 'rf_min': 0, 'rf_max': 1, 'gamma_dry_min': 24, 'gamma_wet_min': 26, <OTHER>},
    {'name': 'Gravel', 'color': '255,255,128', 'qc_min': '', 'qc_max': '', 'qc_norm_min': '',
        'qc_norm_max': 22, 'rf_min': 0, 'rf_max': 1, 'gamma_dry_min': 24, 'gamma_wet_min': 26, <OTHER>}
]
ground_water_level = -4.63
method = TableMethod(qualification_table, ground_water_level)
Parameters
  • ground_water_level (float) – Ground water level is used to compute qc_norm using either gamma_dry or gamma_wet

  • qualification_table (List[dict]) – List containing rows defining a soil

get_qualification_table_plot(fileformat)

Use this method to obtain a plot of the qualification table. On the x axis the Rf values are plotted, on the y axis Qc values are shown. Each line, representing a soil, is shown as an area in this plot. This allows for easy inspection of the qualification rules, showing areas of the plot that might still be empty, or soil areas that overlap (in which case the area on top will be chosen). Use the fileformat argument to specify if the result should be a BytesIO containing pdf or png bytes or a StringIO containing svg data

Parameters

fileformat (str) – specify if required fileformat is pdf, png or svg

Return type

Union[BytesIO, StringIO]

Returns

qualification table plot as either BytesIO (‘pdf’ or ‘png’) or StringIO (‘svg’) object

get_method_params()
Return type

dict

NormalizedSoilBehaviourTypeIndexMethod

class viktor.geo.NormalizedSoilBehaviourTypeIndexMethod(ic_table, ground_water_level, specific_weight_soil, resolution=None)

Bases: _ClassificationMethod

Class to classify soil based on the normalized soil behaviour type index

Example:

ic_table = [
   {'name': 'Sand', 'color': '0, 50, 255', 'ic_min': 0, 'ic_max': 3.5},
   {'name': 'Clay', 'color': '80, 70, 25', 'ic_min': 3.5, 'cone_factor': 20},
]

ground_water_level = 0
specific_weight_soil = 17
method = NormalizedSoilBehaviourTypeIndexMethod(ic_table, ground_water_level, specific_weight_soil)

This method uses the assumption that the specific weight of all the soil layers is the same, this is a simplification. It is possible to calculate the specific weight from qc values.

Parameters
  • ic_table (List[dict]) – Table with soil types that correspond to Ic values. Keys: name, ic_min, ic_max, color, cone_factor

  • ground_water_level (float) – Ground water level used to compute qc_norm

  • specific_weight_soil (float) – Specific weight of soil in kN/m^3 used to calculate sigma’

  • resolution (Optional[float]) – Resolution of the classification in m; if None classify each line of data

get_method_params()
Return type

dict

GEFData

class viktor.geo.GEFData(gef_dict)

Initialize GEFData object to simplify working with GEF data. Every GEF has different header fields, and therefore only a limited amount of fields is compulsory. All other header fields are also added as attribute. Compulsory header fields are:

  • name

  • ground_level_wrt_reference

Other header fields might be compulsory for methods on the object (e.g. get_cone_visualization). See docstring of the specific method for needed headers.

The following measurement_data fields are also compulsory and are implicitly parsed from the file (do NOT need to be specified explicitly):

  • elevation

  • qc

  • Rf

Examples of optional attributes from header are:

  • height_system

  • project_name

  • project_id

  • gef_file_date

  • gef_version_number

  • x_y_coordinates

  • coordinate_system

  • excavation_depth

  • measurement_standard

  • surface_area_quotient_tip

  • water_level

  • cone_tip_area

  • cone_type

Measurement_data fields that are optional are:

  • u2

  • fs

  • penetration_length

  • corrected_depth

  • inclination

  • inclination_n_s

  • inclination_e_w

Example implementation to create GEFData object:

from viktor.core import ViktorController, ParamsFromFile
from viktor.geo import GEFFile, GEFData


class GEFFileController(ViktorController):
    ...

    @ParamsFromFile(file_types=['.gef'])
    def process_file(self, file, **kwargs) -> dict:
        file_content = file.getvalue(encoding="ISO-8859-1")
        gef_file = GEFFile(file_content)
        gef_data_object = gef_file.parse(additional_columns=['elevation', 'qc', 'Rf', 'fs', 'u2'],
                                         return_gef_data_obj=True)
        gef_dict = gef_data_object.serialize()
        return {'gef_dict': gef_dict}

    def get_gef_content_from_database(self) -> GEFData:
        # API call to right entity
        return GEFData(gef_file_entity.last_saved_params['gef_dict'])
Parameters

gef_dict (Union[dict, Munch]) – dictionary with [‘headers’] and [‘measurement_data’] keys

classify(method, return_soil_layout_obj=True)

Create SoilLayout object or dictionary by classifying the GEF measurement data, using either the Robertson method or a qualification table method.

RobertsonMethod

This method requires the GEFData object to at least contain the measurement data ‘corrected_depth’. See GEFData for all possible measurement data columns.

from viktor.geo import RobertsonMethod


soil_properties = [
    {'name': 'Robertson zone unknown', 'extra_property1': 1, 'extra_property2': 2},
    {'name': 'Robertson zone 1', 'extra_property1': 3, 'extra_property2': 4},
]
classification_method = RobertsonMethod(soil_properties)
soil_layout_dict = gef_data.classify(method=classification_method, return_soil_layout_obj=False)

TableMethod

For this method a qualification table has to be provided by the user, for example through a VIKTOR editor. Please refer to the docstring of TableMethod for the structure of this table.

This table is usually controlled on a project-wide level, so in a parent entity. On the controller of the GEF file, you can use the API to retrieve the table content and pass it to the TableMethod:

from viktor.api_v1 import API

api = API()
parent_entity = api.get_entity(entity_id).parent()
parent_params = parent.last_saved_params
qualification_table = parent_params['material_properties']
ground_water_level = parent_params['ground_water_level']

classification_method = TableMethod(qualification_table, ground_water_level)
soil_layout_obj = gef_data.classify(method=classification_method, return_soil_layout_obj=False)

Note

This method needs to be mocked in (automated) unit and integration tests.

Parameters
  • method (_ClassificationMethod) – Specifies which method should be used for qualification: TableMethod | RobertsonMethod | NormalizedSoilBehaviourTypeIndexMethod.

  • return_soil_layout_obj (bool) – Flag to return SoilLayout object or dictionary

Return type

Union[dict, SoilLayout]

Returns

SoilLayout object or dictionary (=SoilLayout.serialize())

serialize()
Return type

Union[dict, Munch]

get_cone_visualization(axes)

Modify (clean/empty) ‘axes’ input argument to plot cone resistance (with pore pressure if present in GEF data).

Parameters

axes (Axes) – Axes object that will be modified.

The following header fields are compulsory and need to be specified when the GEFData object is created:

  • max_measurement_depth_wrt_reference

  • ground_level_wrt_reference

  • height_system

Example usage:

import matplotlib.pyplot as plt

# Create main figure
fig = plt.figure(figsize=(8.27, 11.69))

# Define contour (rectangle) for cone visualization, and create Axes object that can be modified by
# functions
rect_cone = [0.1, 0.1, 0.4, 0.9]  # [left, bottom, width, height]
cone_axes = plt.axes(rect_cone)
# Modify created Axes objects
self.gef_data.get_cone_visualization(cone_axes)

# Convert to SVG for visualization
svg_data = StringIO()
fig.savefig(svg_data, format='svg', bbox_inches='tight', pad_inches=0.8)
plt.close()
gef_visualisation_data = svg_data.getvalue()
Return type

None

get_resistance_visualization(axes)

Modify (clean/empty) ‘axes’ input argument to plot resistance number.

Parameters

axes (Axes) – Axes object that will be modified.

The following header fields are compulsory and need to be specified when the GEFData object is created:

  • max_measurement_depth_wrt_reference

  • ground_level_wrt_reference

Example usage:

import matplotlib.pyplot as plt

# Create main figure
fig = plt.figure(figsize=(8.27, 11.69))

# Define contour (rectangle) for resistance number visualization, and create Axes object that can be
# modified by functions
rect_resistance = [0.1, 0.1, 0.4, 0.9]  # [left, bottom, width, height]
resistance_axes = plt.axes(rect_resistance)
# Modify created Axes objects
self.gef_data.get_resistance_visualization(resistance_axes)

# Convert to SVG for visualization
svg_data = StringIO()
fig.savefig(svg_data, format='svg', bbox_inches='tight', pad_inches=0.8)
plt.close()
gef_visualisation_data = svg_data.getvalue()
Return type

None

get_plotted_denotation_large_qc_values(axes, x_loc_text)

Can be used to add text labels with the maximum qc value of a layer that exceeds the maximum value of the x-axis.

Parameters
  • axes (Axes) – Axes object that will be modified.

  • x_loc_text (float) – Maximum qc value.

The following header fields are compulsory and need to be specified when the GEFData object is created:

  • max_measurement_depth_wrt_reference

An example is shown below where the figure is capped at a maximum qc of 30 MPa (hence x_loc_text=30).

/_images/gefdata_plot_large_qc.svg
Return type

None

GEFFile

class viktor.geo.GEFFile(file_content)
classmethod from_file(file_path, encoding='ISO-8859-1')
Return type

GEFFile

parse(additional_columns=None, verbose=True, return_gef_data_obj=True)

Parse GEFFile, and return information from GEF in dict with [‘headers’] and [‘measurement data’] sub-dicts or a GEFData object.

Example implementation:

from viktor.core import ViktorController, ParamsFromFile
from viktor.geo import GEFFile, GEFData


class GEFFileController(ViktorController):
    ...

    @ParamsFromFile(file_types=['.gef'])
    def process_file(self, file, **kwargs) -> dict:
        file_content = file.getvalue(encoding="ISO-8859-1")
        gef_file = GEFFile(file_content)
        gef_data_obj = gef_file.parse(additional_columns=['fs', 'u2'], return_gef_data_obj=True)

        soil_properties = [
            {'name': Robertson zone unknown, 'extra_property1': 1, 'extra_property2': 2},
            {'name': Robertson zone 1, 'extra_property1': 3, 'extra_property2': 4},
        ]

        soil_layout_dict = gef_data_obj.classify(method=RobertsonMethod(soil_properties), return_soil_layout_obj=False)
        parsed_dict = gef_data_obj.serialize()
        parsed_dict['soils'] = soil_layout_dict
        return parsed_dict

Note

This method needs to be mocked in (automated) unit and integration tests.

Parameters
  • additional_columns (Optional[List[str]]) –

    In order for a GEF file to be of use in VIKTOR, three columns are required:

    • elevation (corrected depth with respect to a specified datum)

    • qc (tip pressure as measured)

    • Rf (friction number, either measured or computed using qc and fs)

    These three columns will always be parsed and returned, additional columns can be parsed as well. Possible columns to request are:

    • ”penetration_length”

    • ”corrected_depth”

    • ”fs”

    • ”u2” (for more accuracy when qualifying layers using Robertson method)

    • ”inclination”

    • ”inclination_n_s”

    • ”inclination_e_w”

  • verbose (bool) – Boolean specifying if parsing should output warnings or work in silence

  • return_gef_data_obj (bool) – Boolean to return GEFData or dictionary

Return type

Union[dict, GEFData]

Returns

dictionary with GEF parameters or GEFData object with GEF parameters as attributes

gef_visualization

viktor.geo.gef_visualization(gef_data, soil_layout_original, soil_layout_user, *, as_file=False)

Standard visualization for GEF File.

Example usage:

class Controller(ViktorController):
   ...

    @ImageView("GEF plot", duration_guess=2)
    def visualize(self, params, **kwargs):
        gef_data = ...
        soil_layout_original = ...
        soil_layout_user = ...
        svg_image = gef_visualization(gef_data, soil_layout_original, soil_layout_user)
        return ImageResult(svg_image)
Parameters
  • gef_data (GEFData) – GEFData object to be visualized

  • soil_layout_original (SoilLayout) – SoilLayout from GEFData. Layers must be sorted from top to bottom.

  • soil_layout_user (SoilLayout) – SoilLayout that is filtered/modified by user. Layers must be sorted from top to bottom.

  • as_file (bool) – return as str (default) or File

    New in v13.5.0

Return type

Union[str, File]

Returns

SVG image file

Soil

class viktor.geo.Soil(name, color, properties=None)

Set name and color of Soil material. Extra properties can be added with dictionary, and keys are added as attribute via ‘munchify’. They are accessible as self.properties.{extra_property_name}

Parameters
  • name (str) –

  • color (Color) – color of soil used in plots

  • properties (Union[dict, Munch, None]) – dict with optional extra parameters to be added to Soil

classmethod from_dict(d)
Return type

Soil

property color: Color
Return type

Color

update_properties(properties)

Replace the current properties dict with the provided new one.

For backwards compatibility, this function is kept with this functionality. In order to be able to update the existing properties dict, the properties property is public and mutable.

Parameters

properties (Union[dict, Munch]) – dictionary with all SoilLayer properties

Return type

None

serialize()

Serialize Soil in following dictionary structure:

{
    'name',
    'color',
    'properties': {
        (..extra_properties..)
    },
}
Return type

dict

Returns

dictionary with all properties of Soil

UndefinedSoil

class viktor.geo.UndefinedSoil

Bases: Soil

Set name and color of Soil material. Extra properties can be added with dictionary, and keys are added as attribute via ‘munchify’. They are accessible as self.properties.{extra_property_name}

Parameters
  • name

  • color – color of soil used in plots

  • properties – dict with optional extra parameters to be added to Soil

PiezoLine

class viktor.geo.PiezoLine(points, phreatic=False)

Bases: Polyline

Class to represent a Piezo line.

Essentially, this is a polyline with a flag added to mark the phreatic polyline.

Parameters
  • points (List[Point]) – points of the polyline

  • phreatic (bool) – mark the phreatic waterline

serialize()

Return a json serializable dict of form:

[
    {'x': point_1.x, 'y': point_1.y},
    {'x': point_2.x, 'y': point_2.y}
]
Return type

dict

classmethod from_dict(piezo_line_dict)
Return type

PiezoLine

classmethod from_lines(lines, phreatic=False)

create a polyline object from a list of lines the end of one line must always coincide with the start of the next

Parameters
  • lines (List[Union[Line, Polyline]]) –

  • phreatic (bool) –

Return type

PiezoLine

SoilLayer

class viktor.geo.SoilLayer(soil, top_of_layer, bottom_of_layer, properties=None)

Create a SoilLayer to be used in SoilLayout

Parameters
  • soil (Soil) – Type of soil

  • top_of_layer (float) – Top of layer

  • bottom_of_layer (float) – Bottom of layer

  • properties (Union[dict, Munch, None]) – dict with optional extra parameters to be added to SoilLayer

classmethod from_dict(soil_layer_dict)
Return type

SoilLayer

property thickness: float
Return type

float

serialize()

Serialize SoilLayer in following dictionary structure:

{
    'soil',
    'top_of_layer',
    'bottom_of_layer',
}
Return type

dict

Returns

dictionary with properties of SoilLayer

update_soil_properties(properties)
Return type

None

update_properties(properties)

Replace the current properties dict with the provided new one.

For backwards compatibility, this function is kept with this functionality. In order to be able to update the existing properties dict, the properties property is public and mutable.

Parameters

properties (Union[dict, Munch]) – dictionary with all SoilLayer properties

Return type

None

SoilLayer2D

class viktor.geo.SoilLayer2D(soil, top_profile, bottom_profile, properties=None, piezo_line_top=None, piezo_line_bottom=None)

A 2D representation of a soil layer

A Soil layer 2d always consists of a soil and a top and bottom profile Optionally, properties and top and bottom pl lines can be added

Top and bottom profiles need to be monotonic ascending in x-direction Top and bottom profiles need to have identical start x and end x coordinates. These will become the left and right boundaries

Top and bottom profiles can overlap, but not intersect. The layer can have one or multiple ranges with zero thickness, but the top profile may never lie below the bottom profile

Parameters
  • soil (Soil) –

  • top_profile (Polyline) –

  • bottom_profile (Polyline) –

  • properties (Union[dict, Munch, None]) –

  • piezo_line_top (Optional[PiezoLine]) –

  • piezo_line_bottom (Optional[PiezoLine]) –

serialize()

Serialize SoilLayer in following dictionary structure:

{
    'soil': Soil
    'top_profile': Polyline
    'bottom_profile': Polyline
    'piezo_line_top': serialized PiezoLine
    'piezo_line_bottom': serialized PiezoLine
    'properties': Dict
}
Return type

dict

Returns

dictionary with properties of SoilLayer

classmethod from_dict(soil_layer_dict)

Instantiates a SoilLayer2D from the provided soil layer data.

dict structure:

{
    'soil': serialized Soil
    'top_profile': serialized Polyline
    'bottom_profile': serialized Polyline
    'piezo_line_top': serialized PiezoLine
    'piezo_line_bottom': serialized PiezoLine
    'properties': Dict
}
Parameters

soil_layer_dict (Union[dict, Munch]) – Soil layer data.

Return type

SoilLayer2D

property left_boundary: float
Return type

float

property right_boundary: float
Return type

float

update_soil_properties(properties)

Replace the current soil properties dict with a new one

Parameters

properties (Union[dict, Munch]) –

Return type

None

Returns

update_properties(properties)

Replace the current properties dict with the provided new one.

For backwards compatibility, this function is kept with this functionality. In order to be able to update the existing properties dict, the properties property is public and mutable.

Parameters

properties (Union[dict, Munch]) – dictionary with all SoilLayer properties

Return type

None

Returns

polygons()

Generate a list of polygons representing this soil layer.

For every region of this soil layout that has a non-zero thickness, a polygon is generated.

Return type

List[Polygon]

visualize_geometry(visualize_border=False, opacity=1, material=None)

Returns the visualization elements (group, labels) of the SoilLayer2D which can be used in a GeometryView.

Parameters
  • visualize_border (bool) – visualize the border surrounding this soil layout with an extra line.

  • opacity (float) – float between 0 (transparent) - 1 (opaque)

  • material (Optional[Material]) – optional material to be applied on the geometry.

Return type

Tuple[Group, List[Label]]

height_at_x(x)

Returns the height at a specific x location.

If a profile has a vertical section on the given x-location, this method will return the first touching point of the polyline with the vertical line

Parameters

x (float) – The x-coordinate where the height is requested.

Return type

float

Returns

The height at the x-coordinate location.

top_y_coordinate(x)

Determine the y-coordinate along the top boundary, belonging to the x value used as input

If a profile has a vertical section on the given x-location, this method will return the first touching point of the polyline with the vertical line

Parameters

x (float) – The x-coordinate where the height is requested.

Return type

float

Returns

The y-coordinate of the top at the x-coordinate location.

bottom_y_coordinate(x)

Determine the y-coordinate along the bottom boundary, belonging to the x value used as input

If a profile has a vertical section on the given x-location, this method will return the first touching point of the polyline with the vertical line

Parameters

x (float) – The x-coordinate where the height is requested.

Return type

float

Returns

The y-coordinate of the top at the x-coordinate location.

SoilLayout

class viktor.geo.SoilLayout(soil_layers)

Aggregation object of SoilLayer

Parameters

soil_layers (List[SoilLayer]) – list of SoilLayer objects

classmethod from_dict(soil_layout_dict)

Create SoilLayout with dictionary from SoilLayout.serialize(). Useful when SoilLayout needs to be created from dictionary from the database.

Example usage:

class Controller(ViktorController):
    ...

    def get_soil_layout_from_database(self) -> SoilLayout:
        # API call to entity that stores complete SoilLayout
        layout_dict = entity.last_saved_params['layout_dict']
        soil_layout = SoilLayout.from_dict(layout_dict)
        return soil_layout
Parameters

soil_layout_dict (Union[Dict[str, List], Munch]) – dictionary with same structure as SoilLayout.serialize()

Return type

SoilLayout

update_soil_properties(df)

Update SoilLayout with Soil properties

Parameters

df (DataFrame) – dataframe with soil properties by name (must at least have column ‘name’).

Return type

None

Returns

serialize()

Serialize SoilLayout to dict (e.g. to store in database). The structure of dict is:

{
   'layers': [...]
}
Return type

dict

get_visualization(axes)

Modify (clean/empty) ‘axes’ input argument to plot SoilLayout structure. Layers must be sorted from top to bottom.

Parameters

axes (Axes) – Axes object that will be modified

Return type

None

property top: float

Height level of the top of the layout.

Return type

float

property bottom: float

Height level of the bottom of the layout.

Return type

float

property number_of_layers: int

Number of layers

Return type

int

update_layers()

Merges adjacent layers that have the same soil type. The merged layer is assigned the average value of each SoilLayer’s individual properties. This average is calculated in ratio to the thickness of the layers. After merging layer depths are corrected by going from top to bottom and setting each bottom_of_layer equal to top_of_layer of next SoilLayer

Example

layer 1 has thickness 10 and for property A a value of 5 layer 2 has thickness 40 and for property A a value of 2 Resulting layer will have thickness 50, and property A = (10 * 5 + 40 * 2) / (10 + 40) = 2.6

Return type

None

append(layer)

Add a layer to the bottom of the classification

Parameters

layer (SoilLayer) – SoilLayer instance

Return type

None

filter_layers_on_thickness(min_layer_thickness, merge_adjacent_same_soil_layers=False)

Collects layers that are thinner than min_layer_thickness in groups, and replaces them by one of two things:

  • If the group is thinner than min_layer_thickness, it is removed from the soil layout and the layer above it is elongated to fill the gap. See explanation figure, situation A.

  • If the group is equal to or thicker than min_layer_thickness, a new layer with Soil and properties of the most dominant (based cumulative thickness) soiltype occurring within this block of layers that was replaced by the new layer. See explanation figure, situation B.

After all replacements have been made, if merge_adjacent_same_soil_layers is specified as True (default is False), _merge_adjacent_same_soil_layers() is called, which merges adjacent soil layers that have the same soiltype and have the same set of parameters. Note that this merging results in a new layer that has the average value for all soil layer properties present in the layers that were merged. See the docstring of _merge_adjacent_same_soil_layers() for more detailed information about how this is done.

Parameters
  • min_layer_thickness (float) – Minimum thickness

  • merge_adjacent_same_soil_layers (bool) – Try to merge adjacent layers that have the same soil type

Note: this method alters the instance!

/_images/soil_layout_filtering_explanation.svg
Return type

SoilLayout

filter_unique_soils()
Return type

List[Soil]

PositionalSoilLayout

class viktor.geo.PositionalSoilLayout(x, soil_layers)

Bases: SoilLayout

A subclass of SoilLayout that adds an x location. This can be useful to generate a Soil Layout 2D

Generate a positional soil layout from an x location and a list of soil layers

Parameters
  • x (float) –

  • soil_layers (List[SoilLayer]) –

classmethod from_dict(positional_soil_layout_dict)

Instantiates a PositionalSoilLayout from the provided soil layout data.

Parameters

positional_soil_layout_dict (Union[dict, Munch]) – Soil layout data.

Return type

PositionalSoilLayout

serialize()

Generate a JSON serializable dict from this positional soil layout.

Return type

dict

SoilLayout2D

class viktor.geo.SoilLayout2D(soil_layers, piezo_lines=None)

A 2D representation of a soil body build up from layers.

A Soil Layout 2D basically consists of the following elements:

  • A list of soil layers: objects of the class SoilLayer2D

  • A list of piezo lines

  • A left and right boundary

  • A top and bottom profile

Left and right boundaries, as well as top and bottom profiles, are automatically taken from the given soil layers

The following requirements are to be met:

  • Each soil layer has to stretch all the way from the left boundary to the right boundary

  • The layers have to be stacked starting from bottom to top

  • There can be no holes in the soil layout 2d, meaning that the top profile of a previous layer always has to be identical to the bottom profile of the next layer

  • A layer can have zero thickness over (part of) the width of the soil layout 2d

  • All soil layers and piezo lines have to exactly identical ranges in x direction, meaning that they all range exactly from left boundary to right boundary

A SoilLayout2D will have roughly the following shape, with each layer containing it’s own soil and soil properties:

|                       xxxxxxxxxx                                |
|xxxxxxxxxxxxxxxxxxxxxxx          xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
|                                                                 |
|                                                                 |
|                                         xxxxxxxx                |
|xxxxxxxxxxxxxx              xxxxxxxxxxxxx        xxxxxxxxxxxxxxxx|
|              xxx     xxxxxx                                     |
|                  xxx                                            |
|                                                                 |
|                                                                 |
|xxxxxxxxxxxxxxxxxxxxxxx                  xxxxxxxxxxxxxxxxxxxxxxxx|
|                       xxxxxxxxxxxxxxxxxx                        |
|                                                                 |
|                  xxxxxxxxxxxxxxx                                |
|xxxxxxxxxxxxxxxxxx               xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|

The SoilLayout2D class is immutable. Any methods that alter or change properties of the class will return a new instance.

Parameters
  • soil_layers (List[SoilLayer2D]) – an ordered dict of 2D soil layers. Starting from the bottom layer

  • piezo_lines (Optional[List[PiezoLine]]) – list of piezo lines

classmethod from_positional_soil_layouts(positional_soil_layouts, top_profile, piezo_lines=None)

Instantiate a soil layout 2d from multiple 1d soil layouts combined with x locations and a ground profile

all 1d soil layouts should have the same layers in the same order. Variation in height and thickness are possible

the top profile has to be monotonic ascending in x direction

Parameters
  • positional_soil_layouts (List[PositionalSoilLayout]) – 1d soil layouts with x locations

  • top_profile (Polyline) – a polyline representing the ground level

  • piezo_lines (Optional[List[PiezoLine]]) – list of piezo lines

Return type

SoilLayout2D

classmethod from_single_soil_layout(soil_layout, left_boundary, right_boundary, top_profile, piezo_lines=None)

A special case when a 1D soil layout is stretched in the 2D plane.

This class method will create a 2D layout with horizontal layers and a top_profile.

Parameters
  • soil_layout (SoilLayout) –

  • top_profile (Polyline) –

  • left_boundary (float) –

  • right_boundary (float) –

  • piezo_lines (Optional[List[PiezoLine]]) –

Return type

SoilLayout2D

classmethod combine_soil_layouts_2d(*soil_layouts_2d)

Combine multiple SoilLayout2D’s in into one big SoilLayout2D

All given soil layouts need to connect seemlessly, so that the resulting SoilLayout2D fullfills the requirement that it has got no holes and the top and bottom profile are monotonic ascending in x direction

All layers will be continued (with zero thickness) to the new right and left boundaries

Parameters

soil_layouts_2d (SoilLayout2D) –

Return type

SoilLayout2D

Returns

POSSIBLE COMBINATIONS:

combining a left and a right soil layout 2d

_____________________
|                   |_______________________
|                   |                      |
|-------------------|----------------------|
|                   |                      |
|___________________|----------------------|
                    |                      |
                    |______________________|

combining a top and bottom soil layout 2d

_____________________
|                   |
|-------------------|
|                   |
|___________________|______________
       |                          |
       |--------------------------|
       |__________________________|

combining n soil layouts, as long as there are no holes in the resulting soil layout, and it is possible to keep all layer profiles monotonic ascending in x-directions

_____________________
|                   |_______________________
|                   |                      |
|-------------------|----------------------|
|                   |                      |
|___________________|______________________|
            |                   |
            |-------------------|
            |___________________|

IMPOSSIBLE COMBINATIONS:

soillayouts without seem

_____________________
|                   |   ________________________
|                   |   |                      |
|-------------------|   |----------------------|
|                   |   |                      |
|___________________|   |----------------------|
                        |                      |
                        |______________________|

overlapping soil layouts

_____________________
|           ________|_______________
|           |       |              |
|-----------|-------|              |
|           |-------|--------------|
|___________|_______|              |
            |                      |
            |______________________|

the resulting soil layout does contain layers with profiles that are not monotonic ascending in x-direction

_____________________
|                   |_______________________
|                   |                      |
|-------------------|                      |
|                   |----------------------|
|___________________|                      |
                    |                      |
            ________|______________________|
            |                   |
            |-------------------|
            |___________________|
classmethod from_dict(soil_layout_2d_dict)

Create SoilLayout2D with dictionary from SoilLayout2D.serialize(). Useful when SoilLayout2D needs to be created from dictionary from the database.

Example usage:

class Controller(ViktorController):
    ...

    def get_interpolated_soil_layout_from_database(self) -> SoilLayout2D:
        # API call to entity that stores complete SoilLayout2D
        layout_dict = entity.last_saved_params['layout_dict']
        interpolated_soil_layout = SoilLayout2D.from_dict(layout_dict)
        return interpolated_soil_layout
Parameters

soil_layout_2d_dict (Union[dict, Munch]) – dictionary with same structure as SoilLayout2D.serialize()

Return type

SoilLayout2D

serialize()

Serialize to dict (e.g. to store in database). The structure of dict is:

{'layers': [layer.serialize} for layer in self.layers,
 'piezo_lines': [line.serialize() for line in self.piezo_lines]}
Return type

dict

Returns

dictionary with structure above

property top_profile: Polyline

top profile of the soil layout: Polyline

Type

return

Return type

Polyline

property bottom_profile: Polyline

bottom profile of the soil layout: Polyline

Type

return

Return type

Polyline

visualize_geometry(visualize_border=False, opacity=1)

Returns the visualization elements (group, labels) of the SoilLayout2D which can be used in a GeometryView.

Parameters
  • visualize_border (bool) – visualize the border surrounding this soil layout with an extra line.

  • opacity (float) – float between 0 (transparent) - 1 (opaque)

Return type

Tuple[Group, List[Label]]

split(*split_lines)

Split the soil layout by given polylines.

Each split line has to:

  • have a start and end point that lies outside of this soil layout

  • intersect the soil layout in at least one region

  • be monotonic ascending in x-direction

Split lines are allowed to cross each other one or multiple times.

Examples:

Single split line

___________ ___________          ___________     ____________
|         /           |          |         /    /           |
|        /            |   ==>    |        /    /            |
|-------/-------------|          |-------/    /-------------|
|______/______________|          |______/    /______________|

Single split line with multiple intersections

            /\
___________/__\________          _______________________
|         /    \      |          |         /    \      |
|        /      \     |   ==>    |        /      \     |
|-------/--------\----|          |-------/  ____  \----|
|______/__________\___|          |______/  /    \  \___|
      /            \                      /      \
                                         /--------\
                                        /__________\

Two crossing split lines

                                             ____
______ ____ ___________          _______     \  /   ____________
|      \  /           |          |      \     \/   /           |
|       \/            |   ==>    |       \        /            |
|-------/\------------|          |-------/        \------------|
|______/__\___________|          |______/    /\    \___________|
                                            /__\
Parameters

split_lines (Polyline) – a list of polylines

Return type

List[SoilLayout2D]

get_left_boundary_polyline()

Get the polyline describing the left boundary This will always be a straight boundary This will contain a point on every boundary between layers

Return type

Polyline

Returns

Polyline

get_right_boundary_polyline()

Get the polyline describing the right boundary This will always be a straight boundary This will contain a point on every boundary between layers

Return type

Polyline

Returns

Polyline