Unfortunately, the Revit API does not currently provide any direct method to access the tag of a tagged element, and vice versa. Normally, I do not write about things that do not work. In this case, however, we have a couple of suggestions for workarounds. I would love to hear back from you whether you are already using any of the methods described below, or other techniques not described, in spite of the lack of direct API support. So this is the question:
Question: How can I find the tag associated with a given family instance, or the tagged element from a given tag?
I want to find a tag that was associated to a family instance through the API. I can go through the document and find both the family instance and the associated IndependentTag object, but I see no clear link between the two. The IndependentTag has a TagHeadPosition which I can match up with the family instance location, but I would hope there is a more accurate way to determine the relationship. When you delete the family instance, the IndependentTag also gets deleted, so Revit is maintaining some kind of link internally.
Can you tell me how to find the FamilyInstance through the IndependentTag or vice versa?
Answer: Unfortunately, the Revit API does not currently provide any direct method to access the relationship between a tag and the tagged element. Here are some workarounds that we currently suggest:
- Use Document.Delete() and the ElementIdSet returned.
- Maintain an association list for programmatically created elements and associated tags.
- Use the element sequence in the database.
- Use geometric proximity between the tag and the tagged element.
Here are the detailed descriptions of each of these approaches:
Document.Delete()
Use the Document.Delete() method to temporarily delete the tagged element, and retrieve the affected tag through the ElementIdSet returned.
The tagged element is regarded as a sort of parent object or host of the tag. Therefore, to find the tag of a given tagged element, we can delete the host, which in turn deletes all its tags and other child objects. One of the method overloads of Document.Delete() returns an ElementIdSet with the element ids of all the elements that will be deleted for the specific host element. Since we do not really want to delete any elements at all, we can wrap the deletion call in a transaction, retrieve the ElementIdSet, and abort the transaction and thus the deletion by calling AbortTransaction. This provides a way to access the associated tags of an element. For example, deleting the wall displayed below will return three tags: the wall tag, door tag and window tag. You can check the tag category to determine which one is the wall tag.
Unfortunately, this does not provide any way to access the host element from a given tag.
Association List
If the elements and their associated tags are generated by an application, the application can maintain an internal list of pairs of element ids for both.
Database Element Sequence
When iterating over all database elements, they are returned in the sequential order in which they were added to the database. Normally the door and window tags will follow immediately after the door and window they are attached to. This holds both for elements generated through the user interface, as well as for many API-generated instances.
Geometric Proximity
Collect all family instance elements and tags of the category you are interested in, for instance all doors and door tags, and pair them up by identical level and geometric proximity. That should generate a pretty reliable pairing in all normal cases.
Introducing DevLabs
Kean Walmsley just posted an exciting announcement on the DevLabs we are holding in various Autodesk offices around the world to provide even more direct development support to our partners. The Revit API sessions are in Beijing, China, in August, and in Bangalore, India, in September.Addendum: As I just pointed out to Martin, who kindly added a comment on it below, the Revit 2012 introduced some new methods and properties on the IndependentTag class to determine the elements referenced by the tag, including:
- TaggedElementId – provides the id of the element referenced by the tag.
- TaggedLocalElementId – provides the id of a linked element reference by the tag.
- GetTaggedLocalElement – returns the handle of the element reference by the tag.
- IsOrphaned – Orphans are those tags that are associated with an instance of a linked Revit file but have no host element. Tags become orphaned when the element they were tagging was deleted from the link.