Skip to content
This repository was archived by the owner on Sep 28, 2022. It is now read-only.

Model Layers

Mark Gray edited this page Oct 14, 2016 · 4 revisions

The main organizational feature of the application is the tree of things that can be edited. This is a pretty close match to the list of sections in the input sequence and it segregates the different node and link types into different sections. Clicking on a section in the tree control puts the list of items in that section (items of that type) below the tree.

The current implementation creates a separate QGIS map layer for each different type of visual model object. This is managed by a small ModelLayers class, which has SWMM and EPANET-specific variants. Here is an excerpt of the SWMM version:

class ModelLayersSWMM(ModelLayers):
    def create_layers_from_project(self, project):
        addCoordinates = self.map_widget.addCoordinates
        addLinks = self.map_widget.addLinks

        # Add new layers containing objects from this project
        self.junctions = addCoordinates(project.junctions.value, "Junctions")
        self.outfalls = addCoordinates(project.outfalls.value, "Outfalls")
        self.dividers = addCoordinates(project.dividers.value, "Dividers")
        self.storage = addCoordinates(project.storage.value, "Storage Units")
        self.raingages = addCoordinates(project.raingages.value, "Rain Gages")
        self.labels = addCoordinates(project.labels.value, "Map Labels")
        coordinates = project.all_coordinates()
        self.pumps = addLinks(coordinates, project.pumps.value, "Pumps", "name", QColor('red'), 1)
        self.orifices = addLinks(coordinates, project.orifices.value, "Orifices", "name", QColor('green'), 1.5)
        self.outlets = addLinks(coordinates, project.outlets.value, "Outlets", "name", QColor('pink'), 2)
        self.weirs = addLinks(coordinates, project.weirs.value, "Weirs", "name", QColor('orange'), 2.5)
        self.conduits = addLinks(coordinates, project.conduits.value, "Conduits", "name", QColor('gray'), 3.5)
        self.subcatchments = self.map_widget.addPolygons(project.polygons.value, "Subcatchments")
        self.set_lists()

    def set_lists(self):
        self.nodes_layers = [self.junctions, self.outfalls, self.dividers, self.storage]
        self.links_layers = [self.pumps, self.orifices, self.outlets, self.weirs, self.conduits]
        self.all_layers = [self.raingages, self.labels, self.subcatchments]
        self.all_layers.extend(self.nodes_layers)
        self.all_layers.extend(self.links_layers)

This strategy maintains a 1:1 mapping between groups of model objects in the input and map layers. Class attributes nodes_layers, links_layers and all_layers are provided to make it convenient to iterate through all of the related QGIS layers. Convenience methods for accessing all QGIS node features (and all link features) as one list have now been added to the base ModelLayers base class to demonstrate that if this type of access is desired it is not difficult to construct from the separate lists:

    def all_node_features(self):
        features = []
        for layer in self.nodes_layers:
            for feature in layer.getFeatures():
                features.append(feature)
        return features

On the input side, different kinds of model nodes (or links) are very different from each other with different properties. On the output side, all nodes (or links) are more similar to each other since they all have the same output values available.

A redesign could be done that would group all nodes into one layer and all links into another layer. This would be slightly more convenient for operations that treat all nodes the same way, but would be slightly less convenient for operating on only one type of node at a time, which seems to be the more common case so far.

The operations we have been focusing on are adding new objects and editing and removing existing objects from the model. Listing, adding and editing an object depends heavily on which sub-type of node or link it is, so it is convenient for the sub-types to be segregated for these operations. Deleting or moving an object would be equally easy whether or not they were segregated. Operations on all nodes or all links are easily accommodated by convenience functions like all_node_features described above and the existing all_coordinates method of the core project classes that returns all the objects in the project that are logically nodes.

The GUI user will never see whether or not there are separate QGIS layers if we replace the QGIS legend window introduced during the last call with a simpler legend that more closely matches the one in the legacy interface.

Clone this wiki locally