Delete part of a MoMa tree

For this example we want to delete some part ofthe MoMa tree.

Let us assume our current MoMa tree looks like the following.

../_images/example_moma_tree.png

In this example we want to delete the element Area1 and its corresponding MoMa node with all children. Afterwards it should look like the following.

../_images/example_moma_tree_after_delete.png

To delete an element we first need to delete all nodes that refer to the element. To delete a node we first need to delete all of its child nodes.

Getting some prerequisite information first

First we need the current user, the levels and a list of models and units.

owner = ni.get_current_gst_user()
levels = ni.list_levels()
models = ni.list_elements(owner, levels[0])
units = ni.list_elements(owner, levels[1])

Getting the Area1 link handle

To get the handle to the Area1 node, we need to do some work.

First, since we know Area1 is a child of Augsburg, we start by getting the node handle for Augsburg first.

model_links = ni.list_children()
augsburg_model = next((model for model in models if model.label == "Augsburg"))
augsburg_link = next(
    (link for link in model_links
     if link.target_id == augsburg_model.id and
     link.target_type == GSTPy.LinkAdjacencyTargetType.Element))

We then go over the child nodes of Augsburg and pick the Area1 node.

augsburg_child_links = ni.list_children(augsburg_link)
area1_unit = next((unit for unit in units if unit.label == "Area1"))
area1_link = next((link for link in augsburg_child_links
                   if link.target_id == area1_unit.id and
                   link.target_type == GSTPy.LinkAdjacencyTargetType.Element))

Removing the Area1 node and element

With the Area1 handle we can get to actually start deleting something.

To help us, we use the following function.

from collections import deque

def list_all_child_links_breadth_first(ni, link):
    result = []
    child_links = deque(ni.list_children(link))
    while len(child_links) > 0:
        current_link = child_links.popleft()
        result.append(current_link)
        child_links.extend(ni.list_children(current_link))
    return result

With this at hand, we can delete all of Area1’s child nodes in the correct order like so.

child_links = list_all_child_links_breadth_first(ni, area1_link)
for child_link in reversed(child_links):
    ni.delete_link_adjacency(child_link)

Finally we delete the Area1 node itself and the Area1 element.

ni.delete_link_adjacency(area1_link)
ni.delete_element(area1_unit)

Full code sample

import GSTPy
from collections import deque

def list_all_child_links_breadth_first(ni, link):
    result = []
    child_links = deque(ni.list_children(link))
    while len(child_links) > 0:
        current_link = child_links.popleft()
        result.append(current_link)
        child_links.extend(ni.list_children(current_link))
    return result

owner = ni.get_current_gst_user()
levels = ni.list_levels()
models = ni.list_elements(owner, levels[0])
units = ni.list_elements(owner, levels[1])

model_links = ni.list_children()
augsburg_model = next((model for model in models if model.label == "Augsburg"))
augsburg_link = next(
    (link for link in model_links
     if link.target_id == augsburg_model.id and
     link.target_type == GSTPy.LinkAdjacencyTargetType.Element))
augsburg_child_links = ni.list_children(augsburg_link)
area1_unit = next((unit for unit in units if unit.label == "Area1"))
area1_link = next((link for link in augsburg_child_links
                   if link.target_id == area1_unit.id and
                   link.target_type == GSTPy.LinkAdjacencyTargetType.Element))

child_links = list_all_child_links_breadth_first(ni, area1_link)
for child_link in reversed(child_links):
    ni.delete_link_adjacency(child_link)
ni.delete_link_adjacency(area1_link)
ni.delete_element(area1_unit)