Mass annotation update

624
5
09-21-2017 04:14 PM
forestknutsen1
MVP Regular Contributor

I am working with a "map book" that has a large number of call outs (~3000). We have a request to change the line color and weight for the leaders. The annotation is in a SDE feature class. Is it possible to do this change in bulk?

ArcGIS 10.1

Thanks!

0 Kudos
5 Replies
DanPatterson_Retired
MVP Emeritus

Just to check... this doesn't do it in bulk I suppose

0 Kudos
forestknutsen1
MVP Regular Contributor

Ya, looks like that has to do with setting up a "default" anno style before you place it.

I have also tried selecting a bunch of them (30 or so) and updating them with the Attribute panel; however, only one is updated. Furthermore, the far end of the leader is "reset" (i.e. the length of the leader is reduced to zero). So one must drag the leader back to the feature that the anno is referring to. I fear that even if I do find a way to mass update the annotation I would still need to drag all the leaders back by hand....

0 Kudos
SteveCole
Frequent Contributor

You certainly should be able to do this with ArcObjects. I did something kinda similar about 10 years ago using ArcObjects and VBA. I developed some internal tools to help automate and speed up mapping emergency road closures & one map product used balloon callouts that were symbolized either green (re-opened) or red (closed). Rather than drill down 12 levels in the symbol properties, I used VBA ArcObjects to quickly "flip" the color for the selected callout.

Screenshot:

And here's the VBA code:

Private Sub ToggleLabelColor_Click()
'==========================================================================
'This subroutine adds a one point white halo to the currently selected label
'==========================================================================
Dim pIMxDoc As IMxDocument
Dim pMap As IMap
Dim pActiveView As IActiveView
Dim pGraphSel As IGraphicsContainerSelect
Dim numSel As Integer
Dim pEnv As IEnvelope
Dim pDisplay As IDisplay
Dim pContainer As IGraphicsContainer
Dim pSymbol As ITextSymbol
Dim myColor As IRgbColor
Dim whiteFill As IRgbColor
Dim pTextElement As ITextElement

Dim pCallout As IBalloonCallout
Dim pFillSymbol As IFillSymbol
Dim pLineSymbol As ILineSymbol
Dim pTextBackground As ITextBackground
Dim pTextSymbol As IFormattedTextSymbol

Set pIMxDoc = ThisDocument
Set pActiveView = pIMxDoc.FocusMap
Set pDisplay = pActiveView.ScreenDisplay
Set pMap = pIMxDoc.FocusMap

Set pContainer = pIMxDoc.FocusMap
Set pGraphSel = pContainer


'--------------------------------------------------------------------------
'Make sure only one label is selected. Adjust as desired..
'--------------------------------------------------------------------------
numSel = pGraphSel.ElementSelectionCount

Dim index As Integer
Dim pElement As IElement
Dim haloSize As Double

For index = 0 To numSel - 1
Set pElement = pGraphSel.SelectedElement(index)
If TypeOf pElement Is ITextElement Then
Set pTextElement = pGraphSel.SelectedElement(index)
Set pSymbol = pTextElement.Symbol

Set myColor = pSymbol.Color

If myColor.Red = 255 Then
'Road is changing from closed to OPEN
myColor.Red = 38
myColor.Green = 115
myColor.Blue = 0

'MsgBox "This road is closed!", vbInformation, "Results"
Else
'Road is changing from open to CLOSED
myColor.Red = 255
myColor.Green = 0
myColor.Blue = 0

'MsgBox "This road is open!", vbInformation, "Results"
End If

pSymbol.Color = myColor

Set whiteFill = New RgbColor
whiteFill.Red = 255
whiteFill.Green = 255
whiteFill.Blue = 255

Set pLineSymbol = New SimpleLineSymbol
Set pFillSymbol = New SimpleFillSymbol
pLineSymbol.Color = myColor
pLineSymbol.Width = 1

pFillSymbol.Color = whiteFill
pFillSymbol.Outline = pLineSymbol

pTextElement.Symbol = pSymbol

Set pElement = pTextElement

Set pTextSymbol = pTextElement.Symbol
Set pTextBackground = pTextSymbol.Background
Set pCallout = pTextBackground

Set pCallout.Symbol = pFillSymbol '.Outline.Color = myColor

Set pTextSymbol.Background = pCallout
pTextElement.Symbol = pTextSymbol

Set pElement = pTextElement
End If
Next index

pActiveView.PartialRefresh esriViewGraphics, Nothing, Nothing

'----------------------------------------------------------------------
'Release any memory allocated
'----------------------------------------------------------------------
Set pElement = Nothing
Set pTextElement = Nothing
End Sub

Private Function ToggleLabelColor_Message() As String
ToggleLabelColor_Message = "Toggles the Road Closure Balloon Callout Color Between Red (Closed) and Green (open)"
End Function

Private Function ToggleLabelColor_ToolTip() As String
ToggleLabelColor_ToolTip = "Toggle Closure Callout Color"
End Function

In the example above, I'm working with graphic labels within an MXD but I think the principle is the same in terms of accessing the symbol properties for a callout.

Sorry I don't have a Dot Net version of this code since we moved away from producing the PDF map based updates during events.

Steve

SteveCole
Frequent Contributor

Hah. Spoke too soon. Looks like I kind of have a Dot Net version of the VBA code. I frankly don't know if this works. I think it does but it's been years since I used it. Looks like this updated code only changes the color TO green in this example but you get the idea:

Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Display

Public Class cmdMakeLabelGreen
Inherits ESRI.ArcGIS.Desktop.AddIns.Button

Public Sub New()

End Sub

Protected Overrides Sub OnClick()
Dim application As ESRI.ArcGIS.Framework.IApplication = Nothing
Dim pIMxDoc As IMxDocument
Dim pMap As IMap
Dim pActiveView As IActiveView
Dim pGraphSel As IGraphicsContainerSelect
Dim numSel As Integer
Dim pDisplay As IDisplay
Dim pContainer As IGraphicsContainer
Dim pSymbol As ITextSymbol
Dim myColor As IRgbColor
Dim whiteFill As IRgbColor
Dim pTextElement As ITextElement

Dim pCallout As IBalloonCallout
Dim pFillSymbol As IFillSymbol
Dim pLineSymbol As ILineSymbol
Dim pTextBackground As ITextBackground
Dim pTextSymbol As IFormattedTextSymbol

Try
application = My.ArcMap.Application
Dim document As ESRI.ArcGIS.Framework.IDocument = application.Document
'pMxDoc = application.Document
pIMxDoc = CType(document, ESRI.ArcGIS.ArcMapUI.IMxDocument)
pActiveView = pIMxDoc.FocusMap
pDisplay = pActiveView.ScreenDisplay
pMap = pIMxDoc.FocusMap

pContainer = pIMxDoc.FocusMap
pGraphSel = pContainer


'--------------------------------------------------------------------------
'Make sure only one label is selected. Adjust as desired..
'--------------------------------------------------------------------------
numSel = pGraphSel.ElementSelectionCount

Select Case numSel
Case 0
MsgBox("You must select a label!", vbExclamation, "Error Encountered")
Exit Sub
Case 1
'Do Nothing
Case Else
MsgBox("You must have one label selected!", vbExclamation, "Error Encountered")
Exit Sub
End Select

Dim index As Integer
Dim pElement As IElement

For index = 0 To numSel - 1
pElement = pGraphSel.SelectedElement(index)
If TypeOf pElement Is ITextElement Then
pTextElement = pGraphSel.SelectedElement(index)
pSymbol = pTextElement.Symbol

myColor = pSymbol.Color

'Road is changing from closed to OPEN
myColor.Red = 38
myColor.Green = 115
myColor.Blue = 0


pSymbol.Color = myColor

whiteFill = New RgbColor
whiteFill.Red = 255
whiteFill.Green = 255
whiteFill.Blue = 255

pLineSymbol = New SimpleLineSymbol
pFillSymbol = New SimpleFillSymbol
pLineSymbol.Color = myColor
pLineSymbol.Width = 1

pFillSymbol.Color = whiteFill
pFillSymbol.Outline = pLineSymbol

pTextElement.Symbol = pSymbol

pElement = pTextElement

pTextSymbol = pTextElement.Symbol
pTextBackground = pTextSymbol.Background
pCallout = pTextBackground

pCallout.Symbol = pFillSymbol '.Outline.Color = myColor

pTextSymbol.Background = pCallout
pTextElement.Symbol = pTextSymbol

pElement = pTextElement
pContainer.UpdateElement(pElement)
End If
Next index

pActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeography, Nothing, Nothing)

'----------------------------------------------------------------------
'Release any memory allocated
'----------------------------------------------------------------------
pElement = Nothing
pTextElement = Nothing
pLineSymbol = Nothing
pFillSymbol = Nothing
pTextSymbol = Nothing
pActiveView = Nothing
whiteFill = Nothing
pSymbol = Nothing
myColor = Nothing
pGraphSel = Nothing
pContainer = Nothing
pMap = Nothing
pDisplay = Nothing
pIMxDoc = Nothing
pTextBackground = Nothing
Catch ex As Exception
globalErrorHandler(ex)
End Try
End Sub

Protected Overrides Sub OnUpdate()

End Sub
End Class

forestknutsen1
MVP Regular Contributor

This worked well in a test run:

http://www.cartotalk.com/index.php?showtopic=5401