Table of Contents

Elevation Tags

Elevation Tags is a Revit add-in tool that automatically aligns spot elevation tags in floor, structural, and ceiling plan views, ensuring consistent text positioning relative to leader endpoints.

Overview

Elevation Tags provides two modes of operation:

  • Automatic Update: Tags are aligned when activating floor/structural/ceiling plan views
  • Manual Update: Users can trigger alignment on-demand via the ribbon button

The tool calculates precise text positioning based on:

  • Tag type font metrics (size, width scale, font family)
  • View scale factor
  • Leader direction
  • Configurable leader-relative offsets

Source: src/Tools/Common/ElevationTags/Features/ElevationTagsAutoUpdater.cs:59-91

Features

Feature Description
Auto-Update on View Activation Automatically aligns elevation tags when opening floor/structural/ceiling plan views
Manual Alignment Command Ribbon button to align tags in the active view on-demand
Regex Tag Filtering Configure which tags to align using regex patterns (up to 3 patterns), matched case-insensitively against spot/tag type family+type naming
Detailed No-Update Diagnostics Manual command distinguishes no spots, no regex matches, and already-aligned results
Live Preview Settings pack includes a compact real-time preview of the configured nudges
Leader-Relative Offsets Fine-tune alignment with Along Leader and Perpendicular offsets instead of raw X/Y nudges
Warning System Tool can be disabled via warnings, preventing accidental auto-updates

Source: src/Tools/Common/ElevationTags/Settings/ElevationTagsSettings.cs:21-56

User Interface

Ribbon Button

The tool adds a single ribbon button:

  • Display Text: "Align Elevation Tags"
  • Tooltip: "Align elevation tags in the active view"
  • Icon: align_elevation_tags_icon.png
  • Availability: Only enabled when an active view is present

Source: src/Tools/Common/ElevationTags/manifest.yml:18-26

Settings Panel

The settings UI provides controls for:

  1. Auto-Update Toggle - Enable/disable automatic updates on view activation
  2. Tag Name Patterns - Regex patterns to match elevation tag names (max 3)
  3. Alignment Offsets - Along Leader and Perpendicular offset values with spinner controls
  4. Live Preview - Inline specimen that redraws as offsets change

Source: src/Tools/Common/ElevationTags/Settings/ElevationTagsSettingsPackView.xaml:1

Architecture

Module Structure

src/Tools/Common/ElevationTags/
+-- DBTools.ElevationTags.csproj    # Project file
+-- ElevationTagsToolModule.cs      # DI registration entry point
+-- manifest.yml                    # Tool manifest
+-- Assets/
|   +-- align_elevation_tags_icon.png
+-- Features/
|   +-- AlignElevationTagsInViewCommand.cs  # Ribbon command
|   +-- ElevationTagsAutoUpdater.cs         # Core alignment logic
+-- Hooks/
|   +-- ElevationTagsViewActivatedTask.cs   # View activation handler
+-- Settings/
    +-- ElevationTagsSettings.cs            # Settings model
    +-- ElevationTagsSettingsPackContext.cs # Settings UI context
    +-- ElevationTagsSettingsPackView.xaml  # Settings UI view
    +-- ElevationTagsSettingsPackView.xaml.cs

Source: Directory structure of src/Tools/Common/ElevationTags/

Data Flow

                    +---------------------------+
                    | View Activation / Command |
                    +-----------+---------------+
                                |
                                v
                    +---------------------------+
                    | ElevationTagsViewActivated|
                    | Task / Command            |
                    +-----------+---------------+
                                |
                                | Retrieves settings, creates updater
                                v
                    +---------------------------+
                    |  ElevationTagsAutoUpdater |
                    +-----------+---------------+
                                |
         +----------------------+----------------------+
         |                      |                      |
         v                      v                      v
  +--------------+    +-----------------+    +------------------+
  | Collect Tags |    | Compute Layout  |    | Update Positions |
  | (Regex Match)|    | Inputs          |    | (Transaction)    |
  +--------------+    +-----------------+    +------------------+

Key Classes

Class File Purpose
ElevationTagsToolModule ElevationTagsToolModule.cs:14-92 Tool module registration; registers settings, services, and settings packs
AlignElevationTagsInViewCommand Features/AlignElevationTagsInViewCommand.cs:19-48 Ribbon command entry point; creates updater and runs alignment
ElevationTagsAutoUpdater Features/ElevationTagsAutoUpdater.cs:15-232 Core alignment logic; computes text positions and updates spot dimensions
ElevationTagsViewActivatedTask Hooks/ElevationTagsViewActivatedTask.cs:20-66 View activation hook; triggers auto-update on floor/structural/ceiling plan views
ElevationTagsSettings Settings/ElevationTagsSettings.cs:21-56 Settings model with default values
ElevationTagsSettingsPackContext Settings/ElevationTagsSettingsPackContext.cs:18-242 MVVM context for settings UI with validation

Source: src/Tools/Common/ElevationTags/ElevationTagsToolModule.cs:14-92

Alignment Algorithm

The ElevationTagsAutoUpdater.TryUpdateSpot() method performs the alignment calculation:

  1. Extract Tag Properties

    • Origin position, leader end position, current text position
    • Tag type parameters (text height, width scale, font name)
    • Elevation base setting (Project Base Point, Survey Point, Relative)
  2. Format Elevation Value

    • Apply elevation indicator prefix/suffix
    • Format using document unit settings
  3. Measure Text

    • Use GDI+ to measure formatted text string
    • Account for font size scaled to view
  4. Calculate New Position

    • Resolve a base placement from the current tag type/text side
    • Derive semantic directions from that placement
    • Apply Along Leader and Perpendicular user offsets without overriding the tag type's own above/below behavior
  5. Update Position

    • Update when either X or Y changes (rounded to 2 decimal places)
    • Set SpotDimension.TextPosition to new XYZ

Source: src/Tools/Common/ElevationTags/Features/ElevationTagsAutoUpdater.cs

View Activation Hook

The ElevationTagsViewActivatedTask implements ViewActivatedTaskBase<ElevationTagsSettings>:

protected override Task<bool> ShouldRunInternalAsync(
    UIApplication uiapp,
    ViewActivatedEventArgs args,
    ElevationTagsSettings settings,
    CancellationToken ct)
{
    var view = app.ActiveUIDocument?.Document?.ActiveView;
    if (view == null)
        return Task.FromResult(false);

	    return Task.FromResult(
	        view.ViewType == ViewType.FloorPlan ||
	        view.ViewType == ViewType.EngineeringPlan ||
	        view.ViewType == ViewType.CeilingPlan);
	}
	```

The task only runs when:
- Auto-update is enabled in settings
- No active warning is set
- The activated view is a floor plan, structural plan, or ceiling plan

> **Source:** `src/Tools/Common/ElevationTags/Hooks/ElevationTagsViewActivatedTask.cs:40-52`

## Settings

### Settings Model

```csharp
public sealed class ElevationTagsSettings : IAutoUpdateSettings
{
    /// <summary>Whether auto-update on view activation is enabled.</summary>
    public bool AutoUpdateEnabled { get; set; } = true;

    /// <summary>Whether a warning has been set (disables auto-update).</summary>
    public bool HasWarning { get; set; }

    /// <summary>
    /// Regex patterns to match tag names. Tags matching any pattern will be aligned.
    /// Default pattern matches:
    /// - DB Elevation Tag - Concrete Label
    /// - DB Elevation Tag - Steel Label
    /// - DB Elevation Tag - Wall Label
    /// Maximum of 3 patterns.
    /// </summary>
    public List<string> TagNamePatterns { get; set; } = new()
    {
        "^DB Elevation Tag - (?:Concrete|Steel|Wall) Label$"
    };

    /// <summary>Semantic offset along the leader direction.</summary>
    public double AlongLeaderOffset { get; set; }

    /// <summary>Semantic offset perpendicular to the leader direction.</summary>
    public double PerpendicularOffset { get; set; }
}

Source: src/Tools/Common/ElevationTags/Settings/ElevationTagsSettings.cs:1

Default Values

Setting Default Value Description
AutoUpdateEnabled true Auto-update is enabled by default
HasWarning false No warning set initially
TagNamePatterns ["^DB Elevation Tag - (?:Concrete|Steel|Wall) Label$"] Matches the three DB elevation label families
AlongLeaderOffset 0.0 No additional along-leader nudge
PerpendicularOffset 0.0 No additional perpendicular nudge

Configuration Section

Settings are stored under the Tools.ElevationTags configuration section.

Source: src/Tools/Common/ElevationTags/manifest.yml:7

Manifest

id: DBTools.ElevationTags
assembly: DBTools
moduleType: DBTools.ElevationTags.ElevationTagsToolModule
order: 0
tool:
  settings:
    configSection: Tools.ElevationTags
  settingsPacks:
    - key: common.elevation_tags
      title: "Elevation Tags"
      warnings:
        - id: core.structural.elevation_tags
          title: "Elevation Tags Disabled"
          message: "Elevation tag alignment is disabled due to a warning. Clear the warning to re-enable."
          disableTools:
            - DBTools.AlignElevationTagsInView
  ribbonTools:
    - internalName: DBTools.AlignElevationTagsInView
      commandType: DBTools.ElevationTags.AlignElevationTagsInViewCommand
      availabilityType: DBTools.App.Tools.Availability.DbtActiveViewAvailability
      runProfile: InlineUi
      displayText: "Align Elevation\nTags"
      iconBaseKey: align_elevation_tags
      tooltip: "Align elevation tags in the active view"
      controlKind: PushButton
      order: 20

Source: src/Tools/Common/ElevationTags/manifest.yml:1-27

Manifest Properties

Property Value Description
id DBTools.ElevationTags Unique tool identifier
assembly DBTools Target assembly name
moduleType DBTools.ElevationTags.ElevationTagsToolModule Entry point class
order 0 Load order priority
configSection Tools.ElevationTags Settings configuration key
runProfile InlineUi Runs on UI thread with inline modal gate
availabilityType DbtActiveViewAvailability Command available when active view exists

Warning System

The tool defines a single warning that can disable functionality:

  • Warning ID: core.structural.elevation_tags
  • Title: "Elevation Tags Disabled"
  • Effect: When active, disables the AlignElevationTagsInView command and auto-update

When the warning is set:

  • HasWarning becomes true
  • AutoUpdateEnabled is forced to false
  • The toggle in settings is disabled

Source: src/Tools/Common/ElevationTags/ElevationTagsToolModule.cs:47-68

API Reference

ElevationTagsAutoUpdater

The main alignment class that processes spot elevation tags:

public sealed class ElevationTagsAutoUpdater
{
    public ElevationTagsAutoUpdater(
        ITransactionRunner tx,
        Document doc,
        View activeView,
        ILogger<ElevationTagsAutoUpdater> logger,
        ElevationTagsSettings? settings = null);

    /// <summary>
    /// Runs the alignment process and returns the count of updated tags.
    /// Only processes floor plan and ceiling plan views.
    /// </summary>
    public int Run();
}

Source: src/Tools/Common/ElevationTags/Features/ElevationTagsAutoUpdater.cs:27-91

Filtering Logic

Tags are collected using a FilteredElementCollector scoped to the active view:

var tags = new FilteredElementCollector(_doc, _view.Id)
    .OfCategory(BuiltInCategory.OST_SpotElevations)
    .WhereElementIsNotElementType()
    .ToElements();

Each tag's name is tested against all configured regex patterns. Tags matching any pattern are included.

Source: src/Tools/Common/ElevationTags/Features/ElevationTagsAutoUpdater.cs:96-122

Elevation Base Handling

The tool respects the elevation base setting on tag types:

Base Setting Behavior
Survey Point Uses raw elevation value
Project Base Point Subtracts project base point Z from elevation
Relative Tag is skipped (not aligned)

Source: src/Tools/Common/ElevationTags/Features/ElevationTagsAutoUpdater.cs:166-170

Troubleshooting

Common Issues

Issue Cause Resolution
Tags not aligning No patterns match tag names Add regex pattern matching your tag family names
Auto-update not running Warning is active Clear the warning in settings panel
Auto-update not running Disabled in settings Enable auto-update toggle
No tags in view View type not supported Only floor and ceiling plans are processed
Invalid regex pattern Syntax error in pattern Check regex syntax; patterns are validated
Tags with Relative base skipped By design Tags with Relative elevation base cannot be aligned

Logging

The tool logs diagnostic information via ILogger<ElevationTagsAutoUpdater>:

  • Invalid regex patterns are logged as warnings
  • Tags that fail to filter or update are logged (first occurrence only)
  • Units format option errors are logged
_logger.LogWarning(ex, "[ElevationTags] Invalid regex pattern '{Pattern}'; skipping.", pattern);
_logger.LogWarning("[ElevationTags] No valid tag name patterns are configured; auto-update will be skipped.");
_logger.LogWarning(ex, "[ElevationTags] Some elevation tags could not be updated; continuing.");

Source: src/Tools/Common/ElevationTags/Features/ElevationTagsAutoUpdater.cs:51-189

Source Files Reviewed

File Purpose
manifest.yml Tool declaration and ribbon configuration
ElevationTagsToolModule.cs Module registration and DI setup
AlignElevationTagsInViewCommand.cs Ribbon command entry point
ElevationTagsAutoUpdater.cs Core alignment algorithm
ElevationTagsViewActivatedTask.cs View activation hook
ElevationTagsSettings.cs Settings model definition
ElevationTagsSettingsPackContext.cs Settings UI view model
ElevationTagsSettingsPackView.xaml Settings UI layout
DBTools.ElevationTags.csproj Project configuration