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 ElementHandler
s.
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.