Q How do I count elements by level using MicroStation Python? To ask that another way: How do I count the number of elements on a particular level?
A Here's a small Python program that counts elements by level.
The Count Elements on Level 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
…
elementRef
) in a DGN model using DgnModel.GetGraphicElements()
CollectLevels()
to examine the element's levels
After executing the above we have a Counter
, which is a specialised dictionary,
populated with the count of each level found on each element.
If an element is complex, the code has obtained the level ID from a nested graphic element.
Here's the Python class DgnElementCounter
used to get a list of elements and analyse each one in
method CountElements
…
class DgnElementLevelCounter: """A class to count DGN elements on one or more levels in a DGN model. For example, count elements on level 'Areas'. By default, collects elements from the active model. For each element, it adds its level ID to a Counter object. """ def __init__(self, dgnModel: DgnModel = ISessionMgr.ActiveDgnModelRef.GetDgnModel()): # DgnElementLevelCounter by default searches the active DGN model self._dgnModel = dgnModel self._elementCount = 0 # Instantiate a Counter object to store level IDs and the count of each level self._levelCounter = Counter() def EnumerateElements(self)->int: nElements = 0 for elemRef in self._dgnModel.GetGraphicElements(): nElements += 1 CollectLevels (elemRef, self._dgnModel, self._levelCounter) return nElements @property def LevelCounter (self): # Get the level counter object return self._levelCounter @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() def __str__(self): return f"Element count {self._elementCount} in model '{self.DgnModelName()}'" def __repr__(self): return 'CountElements(Level ID List)'
Function CollectLevels()
fills the Counter
with each found level,
along with the count of the number of elements assigned that level ….
def CollectLevels (elemRef: PersistentElementRef, dgnModel: DgnModel, levelCounter: Counter): """Get level(s) from an element, and insert into a Counter keyed by level ID. This function calls itself recursively to investigate complex elements such as cells.""" eh = ElementHandle (elemRef, dgnModel) handler = eh.GetHandler() description = getElementDescription(eh) MessageCenter.ShowDebugMessage(f"CollectLevels found {description} ComplexElementHandler={handler in ComplexElementHandlers}", f"CollectLevels found {description} in ComplexElementHandlers={handler in ComplexElementHandlers}", False) # If this is a complex element (e.g. a cell or grouped hole) if isinstance (handler, ComplexElementHandlers): component = ChildElemIter(eh, ExposeChildrenCount) while component.IsValid(): handler = component.GetHandler() if isinstance (handler, ComplexElementHandlers): CollectLevels (component.GetElementRef(), dgnModel, levelCounter) else: levelId = component.GetElement().ehdr.level levelCounter.update ((levelId, )) component = component.ToNext() else: levelId = eh.GetElement().ehdr.level count = levelCounter[levelId] MessageCenter.ShowDebugMessage(f"CollectLevels found {count} level ID {levelId}", f"CollectLevels found level ID {levelId}", False) levelCounter.update ((levelId, ))
Once all elements have been investigated, we're left with a Counter
filled with the found levels
and the count of each level.
Ask for the count of a level like this …
nLevels = counter.LevelCounter[levelId]
The Python source code of Count Elements is available for download.
Count Elements is intended to be used by your Python code. Import it as a module …
import la_solutions_elements_count_by_level
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.