Select to view content in your preferred language

populate annotation feature class through code

5134
4
04-28-2010 11:53 AM
AndrewMurdoch
Regular Contributor
I'm trying to populate a blank annotation feature class through ArcObjects code, reading in the column values from a remote annotation class.  When I go to view the output annotation file in ArcMap I get an "ArcMap Drawing Errors" window with the message that there is a "Drawing error due to invalid annotation features". 

I'm using an IFeatureCursor to edit the target annotation feature class.  However, when I get to the "OVERRIDE" column, I can't push the old value into the new feature class.  I've read that this OVERRIDE column is maintained internally by ArcObjects.  That's fine, but after I've finished editing, I discover that the OVERRIDE column has NULL values and ArcMap will not display the new annotation feature class features.

I'm also reading and writing the ELEMENT BLOB column through ArcObjects, but that seems to be working (BLOBs are going into the ELEMENT column in the target anno feature class).

I think the problem with the output annotation is the NULL value in the OVERRIDE column.  Can anyone help me figure out how to populate that OVERRIDE column through ArcObjects?

Thanks,
Andrew
0 Kudos
4 Replies
AndrewMurdoch
Regular Contributor
OK, I determined that my approach was fundamentally flawed and that you really aren't supposed to be able to copy annotation feature classes via Oracle table editing.  What I wound up doing was use a feature cursor, a TextElement and an AnnotationFeature object to set the Annotation property for each feature.  I know I could optimize this by using the SymbolCollection object to store the symbol properties once for the feature class, instead of once for each record, but that wasn't required at this stage.  The code looked something like this:

               'set up the feature buffer to insert the new features
                pFCursor = pFClass.Insert(True)
                pFeatBuffer = pFClass.CreateFeatureBuffer()
                pFeature = CType(pFeatBuffer, IFeature)


                        '** Create TextSymbol, Font and TextElement for Annotation feature
                        Dim pElement As IElement
                        Dim pTextElement As ITextElement
                        pTextElement = New TextElement

                        Dim pTextSymbol As ESRI.ArcGIS.Display.IFormattedTextSymbol
                        pTextSymbol = New ESRI.ArcGIS.Display.TextSymbol

                        Dim pFont As stdole.IFontDisp = CType(New stdole.StdFont, stdole.IFontDisp)
                        pFont.Name = myFontName
                        pFont.Italic = myItalic
                        pFont.Underline = myUnderline
                        pFont.Bold = myBold

                        pTextSymbol.Font = pFont
                        '** Font size must be set on TextSymbol, not on Font to avoid font-sizing problem with stdole library
                        pTextSymbol.Size = myFontSize
                        pTextSymbol.VerticalAlignment = CType(myVAlign, ESRI.ArcGIS.Display.esriTextVerticalAlignment)
                        pTextSymbol.HorizontalAlignment = CType(myHAlign, ESRI.ArcGIS.Display.esriTextHorizontalAlignment)
                        pTextSymbol.Angle = myAngle
                        pTextSymbol.CharacterSpacing = myCharSpacing
                        pTextSymbol.CharacterWidth = myCharWidth
                        pTextSymbol.FlipAngle = myFlipAngle
                        pTextSymbol.Leading = myFontLeading
                        pTextSymbol.WordSpacing = myWordSpacing

                        pTextElement.Symbol = pTextSymbol
                        pTextElement.Text = myText

                        '** set Element equal to TextElement and get lower-left point from input polygon geometry
                        pElement = CType(pTextElement, IElement)
                        pElement.Geometry = CType(pGeometry, IPolygon).FromPoint

                        '** set AnnotationFeature.Annotation property to newly created TextElement and point geometry
                        Dim pAnnotationFeature As IAnnotationFeature
                        pAnnotationFeature = CType(pFeature, IAnnotationFeature)
                        pAnnotationFeature.Annotation = pElement
                        pFeature = CType(pAnnotationFeature, IFeature)

                        pFCursor.InsertFeature(CType(pFeature, IFeatureBuffer))

                       pFCursor.Flush()
0 Kudos
BobCave
Emerging Contributor
I am also trying to populate annotation features using ArcObjects (ArcGIS 9.3).  In my case, I am using data stored in our custom objects to fill out the annotation.  I have created an annotation layer, and added annotation features to the layer, but when I load the layer into ArcMap, my text does not get displayed.  When I select the features, I see their bounding boxes, and when I look at a feature's properties, I see my text, but I can't figure out how to get ArcMap to show the annotation text.

I haven't been able to find documentation for the steps needed to create an annotation using ArcObjects.  If anyone could provide a pointer to that documentation, that would be very helpful.

Here is the code I am using to create the text element object and annotation:

// pText is my custom text object
// font is the font information from my custom text object
// m_featClass is the annotation feature class
// gdbGeo is the point geometry for the annotation

HRESULT hr = S_OK;
IUnknownPtr ext;
hr = m_featClass->get_Extension(&ext);
IAnnotationClassExtensionPtr annoExt(ext);
ISymbolPtr defaultSymbol;
hr = annoExt->get_Symbol(0, &defaultSymbol);

ITextElementPtr gdbText(CLSID_TextElement); 
ISymbolCollectionElementPtr gdbSymColElem(gdbText);
hr = gdbSymColElem->put_SharedSymbol(0, defaultSymbol);
hr = gdbSymColElem->put_Geometry(gdbGeo);
hr = gdbSymColElem->put_Text(CComBSTR(pText->GetText().c_str()));
hr = gdbSymColElem->put_Bold(font.IsBold() ? VARIANT_TRUE : VARIANT_FALSE);
hr = gdbSymColElem->put_Italic(font.IsItalic() ? VARIANT_TRUE : VARIANT_FALSE);
hr = gdbSymColElem->put_Underline(font.IsUnderlined() ? VARIANT_TRUE : VARIANT_FALSE);
hr = gdbSymColElem->put_FontName(CComBSTR(font.GetFaceName().c_str()));
gdbSymColElem->put_Size(font.GetSize());
IColorPtr gdbColor(CLSID_RgbColor);
gdbColor->put_RGB(font.GetFGColor().ToRGB());
gdbColor->put_Transparency(font.GetFGColor().GetOpacity());
gdbSymColElem->put_Color(gdbColor);
hr = gdbText->put_Text(CComBSTR(pText->GetText().c_str()));

// m_featureBuffer was created for the annotation feature
IAnnotationFeature2Ptr annoFeature2(m_featureBuffer);

if (annoFeature2 != NULL)
{
 HRESULT hr = annoFeature2->put_Annotation(IElementPtr(gdbText));
 if (SUCCEEDED(hr))
 {
  annoFeature2->put_Status(esriAnnoStatusPlaced);
  annoFeature2->put_AnnotationClassID(0);
 }
} 


Does anyone have an idea why the text is not being displayed?

Thanks,

Bob
0 Kudos
AndrewMurdoch
Regular Contributor
I had a little trouble following the syntax.  Is the syntax "->put_" for C# or C++?  I don't have any experience with those yet.

I had a similar problem (blank text but bounding box can be selected) initially, when I was using a polygon geometry as input to the IElement object.  I fixed that by using a point geometry instead.  However, I saw in your header that you are using a point geometry for the "gdbGeo" variable. 

I think you need to make sure you are setting the point geometry on an IElement object and not just on the ITextElement or ISymbolCollectionElement object.

Good luck!
Andrew
0 Kudos
BobCave
Emerging Contributor
Thanks for the suggestion.  Actually, it turns out I was using a polygon for the geometry.  When I switched it to a point, the annotations appeared in ArcMap.

To answer your question: my code snippet is C++.

Thanks again.

Bob
0 Kudos