Q How do I count elements using MicroStation Python?
Q How do I count elements by type (e.g. lines, line-strings) using MicroStation Python?
A Here's a small Python program that uses type-matching to count elements by type.
The Count Elements by Type example borrows from Python articles and examples delivered with MicroStation Python.
We get a list of DGN elements (as elementRef) in a DGN model using DgnModel.GetGraphicElements().
Next we enumerate the list and analyse each elementRef.
In this example, we filter the list by element type (e.g. MicroStation classes LineHandler, LineStringHandler etc) …
elementRef) in a DGN model using DgnModel.GetGraphicElements()
IsInteresting() to examine the element
Function IsInteresting() analyses an element to see if it is interesting for our purposes …
ElementHandle.GetHandler()
True if our handler matches one in the list
Count Elements filters the element list by examining the element's handler. Element handlers are classes in MicroStation Python that provide type-specific methods. For example, you can use a LineHandler to create a DGN line element.
Here, we supply a list of handlers used by Count Elements.
For example, here's a Python tuple of handlers for lines and line-strings …
LineHandlers = (LineHandler, LineStringHandler, )
You'll find more examples of handler lists in the project's source code.
Here's the Python class DgnElementCounter used to get a list of elements and analyse each one in
method CountElements …
class DgnElementCounter:
"""A class to count DGN elements in a DGN model for one or more element types.
"""
def __init__(self, dgnModel: DgnModel = ISessionMgr.ActiveDgnModelRef.GetDgnModel()):
self._dgnModel = dgnModel
self._elementCount = 0
self._searchName = ""
def CountElements(self, handlers: namedtuple)->int:
# Pass a namedtuple of DGN element classes (e.g. LineHandler et alia).
# The class name of the namedtuple is our search name
self._searchName = type(handlers).__name__
# Execute the element test to produce a new list of elements from a
# Python list comprehension
matchedElements = [elemRef for elemRef in self._dgnModel.GetGraphicElements() if IsInteresting(elemRef, self._dgnModel, handlers)]
return len(matchedElements)
@property
def ElementCount (self):
# Get the element count
return self._elementCount
@property
def DgnModelName (self):
# Get the name of the DGN model that contains elements to be counted
if (self._dgnModel is None):
return "unknown"
else:
return self._dgnModel.GetModelName()
@property
def SearchName(self):
# Get the name of the search criteria supplied in the namedtuple
return self._searchName
def __str__(self):
return f"Element count {self._elementCount} in model '{self.DgnModelName()}'"
def __repr__(self):
return 'CountElements(Handler List)'
Function IsInteresting() provides a boolean test to determine whether a particular DGN element
is interesting for our purposes.
In this example the element is interesting if it is one of MicroStation's element types,
indicated by a list of ElementHandler.
Here's function IsInteresting() …
def IsInteresting (elemRef: PersistentElementRef, dgnModel: DgnModel, handlers: namedtuple):
"""Function tests whether a DGN element is interesting, whatever that means"""
# Create an element handle and get its Handler
eh = ElementHandle (elemRef, dgnModel)
handler = eh.GetHandler()
if isinstance (handler, handlers):
return True
#else
return False
The Python source code of Count Elements is available for download.
namedtuple
Here's a
Python tuple of element handlers: (LineHandler, LineStringHandler, ).
We prefer to use a
namedtuple because it has a name.
Otherwise, namedtuple behaves just like a tuple.
In this example, there's a function MakeNamedTupleFromHandlerList that accepts a name and a
tuple of ElementHandlers.
It analyses the tuple and converts it to a namedtuple.
Subsequently, you can get the name like this …
searchName = type(handlers).__name__
Count Elements is intended to be used by your Python code. Import it as a module …
import la_solutions_elements_count_by_type
You can test it as stand-alone code from the MicroStation Python manager. You'll find these lines in the project …
if __name__ == "__main__": # check if this script is being run directly (not imported as a module)
counter = DgnElementCounter()
Everything after those lines will be executed from a Python prompt or in MicroStation's Python Manager.
Unpack the ZIP file and copy the Python file into a folder that MicroStation knows about.
Use MicroStation's Python Manager to find and execute the script.
Post questions about MicroStation programming to the MicroStation Programming Forum.