MicroStation Python: Search Element by ID


Welcome to the world of MicroStation Python! One of the common tasks when working with MicroStation is searching for specific element based on their unique IDs. In this wiki, we will guide you through a Python script that demonstrates how to search for elements with a specific ID in MicroStation.

 

Search Element by ID in MicroStation with Python

Let us dive into, searching for a linear element in a model based on its element id. Refer to the Python Manager wiki to create and load a python project. Name your project as “SearchElementById.py” and save it to your preferred directory. Open the project in the editor for writing your Python script.

 

Import Modules

The script begins by importing several modules offering functions and classes to interact with MicroStation and to query geometric elements.

 

from MSPyBentley import *
from MSPyBentleyGeom import *
from MSPyECObjects import *
from MSPyDgnPlatform import *
from MSPyDgnView import *
from MSPyMstnPlatform import *
import os
import pandas as pd

 

Data Storage

A dictionary named data is initialized to store the coordinates (X, Y, Z) of the element.

 

data = {'X': [], 'Y': [], 'Z': []}

 

Adding Data

The add_data() function appends the coordinates to the data dictionary.

 

def add_data(x, y, z):
    global data

    data['X'].append(x)
    data['Y'].append(y)
    data['Z'].append(z)

 

Search Element By ID

The GetElementById()function, takes element ID as an input argument and selects the element with that ID in the active model. Here is a breakdown of what it does:

  1. ACTIVEMODEL: Retrieves the active model using ISessionMgr.ActiveDgnModelRef.
  2. DgnModel: Retrieves DGN model using ACTIVEMODEL.GetDgnModel().
  1. EditElementHandle: Get a Handle to an element passing the Element Id and DGN model. Check if the element is a linear element (line string - type 4).
  2. ElementToCurveVector: Convert the element to a Curve element.
  3. GetLineString: Extract and append the coordinates to the data dictionary.

 

def GetElementById(elementId):
    global data

    ACTIVEMODEL = ISessionMgr.ActiveDgnModelRef
    dgn_model = ACTIVEMODEL.GetDgnModel()
    eeh = EditElementHandle(elementId, dgn_model)

    model_info = dgn_model.GetModelInfo() 
    uor = model_info.GetUorPerStorage()

    selSetManager = SelectionSetManager.GetManager()
    selSetManager.EmptyAll()

    if (eeh.ElementType == 4):
        selSetManager.AddElement(eeh.ElementRef, dgn_model)

        curve = ICurvePathQuery.ElementToCurveVector(eeh)
        curve_len = curve.Length()
        print(f"Element Id: {eeh.ElementId}, Length: {curve_len/uor}")

        primitive = curve[0]
        curve_pts = primitive.GetLineString()

        for i in range(len(curve_pts)):
            add_data (curve_pts[i].x/uor, curve_pts[i].y/uor, curve_pts[i].z/uor)

 

 

Putting it all Together: The main Function

The main function constructs the report file name based on the active DGN file’s name and directory.

It calls GetElementById with a specific element ID (1154 in this case) and then exports the coordinates to a CSV file.

 

Here is the complete script.

 

from MSPyBentley import *
from MSPyBentleyGeom import *
from MSPyECObjects import *
from MSPyDgnPlatform import *
from MSPyDgnView import *
from MSPyMstnPlatform import *
import os
import pandas as pd


# Dictionary to store coordinates
data = {'X': [], 'Y': [], 'Z': []}


# Add coordinates to dictionary (data)
def add_data(x, y, z):
    global data

    data['X'].append(x)
    data['Y'].append(y)
    data['Z'].append(z)


# Get Element By Id
def GetElementById(elementId):
    global data

    ACTIVEMODEL = ISessionMgr.ActiveDgnModelRef
    dgn_model = ACTIVEMODEL.GetDgnModel()
    eeh = EditElementHandle(elementId, dgn_model)

    model_info = dgn_model.GetModelInfo() 
    uor = model_info.GetUorPerStorage()

    selSetManager = SelectionSetManager.GetManager()
    selSetManager.EmptyAll()

    if (eeh.ElementType == 4):
        selSetManager.AddElement(eeh.ElementRef, dgn_model)

        curve = ICurvePathQuery.ElementToCurveVector(eeh)
        curve_len = curve.Length()
        print(f"Element Id: {eeh.ElementId}, Length: {curve_len/uor}")

        primitive = curve[0]
        curve_pts = primitive.GetLineString()

        for i in range(len(curve_pts)):
            add_data (curve_pts[i].x/uor, curve_pts[i].y/uor, curve_pts[i].z/uor)
            #print(f"[{i}] X: {curve_pts[i].x/uor}, Y:{curve_pts[i].y/uor}, Z:{curve_pts[i].z/uor}")


# Main function
def main():
    global data

    # Construct Report Name
    dgnFile = ISessionMgr.GetActiveDgnFile()
    file_path = dgnFile.GetFileName().GetWCharCP()
    directory_path = os.path.dirname(file_path)
    file_name_with_extension = os.path.basename(file_path)
    file_name = os.path.splitext(file_name_with_extension)[0]
    file_extension = os.path.splitext(file_name_with_extension)[1]
    report_extension = ".csv"
    report_file_name = os.path.join(directory_path, file_name + report_extension)

    # Get Element By Id - Line String element
    GetElementById(1154)

    # Export Line String element coordinates to csv file
    df = pd.DataFrame(data)
    df.to_csv(report_file_name, index=False)


# main
if __name__ == "__main__":
    main()

 

Run/Execute project

Load the project “SearchElementById.py” from the Python Manager dialog and Run/Execute the python script.

Linear element with element id 1154 present in the active Model is identified and added to the Selection Set.

After identifying the linear element, its coordinates are extracted and exported to a CSV file using the Pandas | DataFrame.

 

 

This script provides a straightforward way to search for an element by its ID and export its coordinates to a CSV file.

 

Happy coding!