Python

TextAssociationHandler

When labelling a DGN element we want to create a text label that somehow belongs to a host element such as a DGN line. We want the label to display a measurement of the line, such as its length, and move with the line if a MicroStation user drags or moves that line.

To achieve that goal we should associate the label with the line. In Bentley terminology, the label is associative. The AssociativePoint API is available to help you write associative logic.

I wrote the TextAssociationHandler class to simplify working with associative points in the particular case where a DGN text element is associated with another graphic element.

TextAssociationHandler Usage

The class encapsulates the AssocPoint code. When you use it, you don't even see the AssocPoint …

#  Get ElementHandler of target
assoc_handler = TextAssociationHandler(eh)
# Get the anchor point, typically a point on the line
assoc_handler.setup_offset_association(label, anchor_point)

TextHandlerBase

MicroStation Python provides the TextHandlerBase class.

TextAssociationHandler uses TextHandlerBase.SetupOffsetAssociation(), which unfortunately is not documented in the Python API help. Because I've previously used the C++ implemention, I was able to make a guess at how the Python code works. You can see the call below in method setup_offset_association.

TextAssociationHandler Class Definition

class TextAssociationHandler():
  '''
  Class encapsulates the steps required to associate a DGN text element (e.g. a line length label)
  with a DGN object (e.g. the line being measured).
  With this association, the text element is tied to the target element: when you move the target, the text follows it.
  '''
  def __init__(self, target: ElementHandle):
    self._target = target
    self._init_assoc_point(target)

  def _init_assoc_point(self, target: ElementHandle)->BentleyStatus:
    '''
    Initialize an AssocPoint using the Element ID of a root element, which is the target of the association.
    '''
    self._assoc_point = AssocPoint()
    AssociativePoint.InitOrigin (self._assoc_point, 0)
    return AssociativePoint.SetRoot (self._assoc_point, target.GetElementId(), 0, 0)

  def _calculate_offset(self, offset: DPoint3d, ref_point: DPoint3d)->BentleyStatus:
    '''
    Calculate offset from text element to target element.
    '''
    offset = DPoint3d.FromZero ()
    assoc_point = DPoint3d()
    status = AssociativePoint.GetPoint (assoc_point, self._assoc_point, self._target.GetModelRef())
    if BentleyStatus.eSUCCESS == status:
      offset.DifferenceOf (assoc_point, ref_point)
    return status
  
  def setup_offset_association(self, label: EditElementHandle, point: DPoint3d)->BentleyStatus:
    '''
    Set up an offset association between a label and a target element.
    In this app the label displays a measurement from the target, which is typically a line element.
    '''
    offset = DPoint3d()
    self._calculate_offset(offset, point)
    return TextHandlerBase.SetupOffsetAssociation(label, self._target, self._assoc_point)

Examples

The examples page lists example projects written by LA Solutions.

Questions

Post questions about MicroStation Python programming to the MicroStation Programming Forum.