Warum erscheinen diese Anmerkungen gestapelt / überlappend?

8

Beim Versuch, eine Annotation-Feature-Class programmgesteuert zu füllen (ArcObjects, C #), ist ein seltsames Problem aufgetreten. Wie Sie im Bild unten sehen können, scheinen sich die Zeichen in jeder Textzeichenfolge zu stapeln, anstatt horizontal zu liegen, wie ich es erwartet hätte.

Ich ziehe mehrere Werte aus MySQL (erstellt von einer anderen Anwendung) ein, und diese sehen im Debugger gut aus. Ich habe versucht, eine Mischung aus unbekanntem / projiziertem Koordinatensystem sowie einige verschiedene Elementschnittstellen zu verwenden. Wenn jemand dieses Problem schon einmal gesehen und gelöst hat, würde ich mich über einen Vorstoß in die richtige Richtung freuen.

Hier ist der relevante Teil meines C #:

IFeature feature = featureClass.CreateFeature();

ITextElement textElement = new TextElementClass();
textElement.Text = textString;                         // value like: '183

IElement element = textElement as IElement;
element.Geometry = pointGeom;                         // Point: x=2986785, y=629058

(feature as IAnnotationFeature2).Annotation = element;
(feature as IAnnotationFeature2).AnnotationClassID = 0;
(feature as IAnnotationFeature2).Status = annoStatus;  // ESRI constant for 0, "placed"

feature.Store();

Und wie versprochen, hier ein Blick auf die Ergebnisse, die ich bekomme:

Geben Sie hier die Bildbeschreibung ein

[Aktualisieren]

Per @ Radars Rat habe ich die folgende Überarbeitung versucht, aber es wird immer noch gestapelter / überlappender Anmerkungstext wiedergegeben:

ISymbolCollectionElement scElement = new TextElementClass(); 
scElement.CharacterSpacing = 5; 
scElement.Geometry = pointGeom; 
scElement.Text = textString; 

(feature as IAnnotationFeature2).Annotation = scElement as IElement; 
(feat as IAnnotationFeature2).AnnotationClassID = 0; 
(feat as IAnnotationFeature2).Status = annoStatus;

Hat jemand zusätzliche Einblicke?

[Zweites Update]

Grundsätzlich versuche ich zu erreichen, was @murdoch in diesem "alten" ArcScripts-Beitrag getan hat (siehe seinen zweiten Eintrag). Ich habe seinen Ansatz erneut überprüft und festgestellt, dass er die IFormattedTextSymbol-Schnittstelle verwendet. Daher habe ich dies versucht, habe jedoch weiterhin das gleiche Problem mit gestapeltem / überlappendem Text in den platzierten Anmerkungen. Hier ist mein letzter Schub von C #:

IFeature feature = featureClass.CreateFeature();

IFontDisp font = new StdFontClass() as IFontDisp;
font.Name = "Arial";
font.Bold = true;
// font.Size = 30;

// load in some reasonable default values..
IFormattedTextSymbol fmtTextSymb = new TextSymbolClass();
fmtTextSymb.Font = font;
fmtTextSymb.Size = 30;
fmtTextSymb.VerticalAlignment = esriTextVerticalAlignment.esriTVABottom;
fmtTextSymb.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft;
fmtTextSymb.Angle = 0;
fmtTextSymb.CharacterSpacing = 100;
fmtTextSymb.CharacterWidth = 100;
fmtTextSymb.FlipAngle = 90;
fmtTextSymb.Leading = 0;
fmtTextSymb.WordSpacing = 100;
fmtTextSymb.Text = textString;  // my special text value..

ITextElement textElement = new TextElementClass();
textElement.Symbol = fmtTextSymb;
textElement.Text = textString;

IElement element = textElement as IElement;
element.Geometry = pt;

(feature as IAnnotationFeature2).Annotation = element;

feature.Store();

Hat jemand Probleme damit? oder eine bevorzugte Umsetzung haben? So sieht es jetzt aus; Wie Sie sehen, hat sich der Ansatz etwas geändert, aber die Ergebnisse sind dieselben:

Geben Sie hier die Bildbeschreibung ein

[Drittes Update]

Letztendlich war das Problem nicht der Code, mit dem ich die einzelnen Anmerkungen erstellt habe, aber wie @Kirk Kuykendall enthüllte, bestand das Problem darin, wie ich meinen AnnotationLayer ursprünglich erstellt habe IAnnotationLayerFactory.CreateAnnotationLayer(). Ich reichte nulldas IGraphicsLayerScaleArgument ein und ging davon aus, dass es sich in funktionale, wenn nicht hässliche Standardwerte auflösen würde. Anscheinend nicht. Ich habe dieses Objekt wie folgt erstellt und mein Problem behoben:

// Set the map scale and units the annos should be "cooked for".
// To get ReferenceScale, open ArcMap and zoom to an appropriate level. 
// In the Standard toolbar, click the 1:N button (tip says "MapScale").
// It'll output something like 1:1,200. Drop the 1: and the comma
// and that's the value you want for ReferenceScale.

IGraphicsLayerScale graphicsLayerScale = new GraphicsLayerScaleClass();
graphicsLayerScale.ReferenceScale = 1200;
graphicsLayerScale.Units = esriUnits.esriFeet; // this should agree with your proj

Voila!

Geben Sie hier die Bildbeschreibung ein

Elrobis
quelle

Antworten:

4

Mit arccatalog 10 sp2 habe ich eine neue (nicht mit Funktionen verknüpfte) Anmerkungs-Feature-Class mit Web-Mercator-Projektion, xy-Toleranz 0,001, Referenzmaßstab 1: 100.000, Karteneinheiten Meter erstellt.

Ich habe das Kontrollkästchen "Symbol muss aus der Symboltabelle ausgewählt werden" nicht aktiviert. Akzeptierte alle Standardeinstellungen für den Rest.

Ich ging dann in arcmap und konnte manuell hinzufügen, dann führte ich diesen Code ohne überlappende Probleme aus.

public class TestButton : ESRI.ArcGIS.Desktop.AddIns.Button
{
    public TestButton()
    {
    }

    protected override void OnClick()
    {
        try
        {
            Test();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    protected override void OnUpdate()
    {
    }
    public void Test()
    {
        var editor = ArcMap.Application.FindExtensionByName("ESRI Object Editor") as IEditor;
        if (editor.EditState != esriEditState.esriStateEditing)
        {
            MessageBox.Show("start editing first");
            return;
        }
        var fLayer = ((IEditLayers)editor).CurrentLayer;
        if(!(fLayer is IAnnotationLayer))
        {
            MessageBox.Show("not an anno layer");
            return;
        }
        var pnt = ((IArea)ArcMap.Document.ActiveView.Extent).Centroid;
        string s = Environment.TickCount.ToString();
        try
        {
            editor.StartOperation();
            AddAnno(fLayer.FeatureClass,pnt,s);
            editor.StopOperation("add anno at center of screen");
            ArcMap.Document.ActiveView.Refresh();
        }
        catch
        {
            editor.AbortOperation();
            throw;
        }
    }

    private void AddAnno(IFeatureClass featClass, IPoint pt, string textString)
    {
        IFeature feature = featClass.CreateFeature();
        var annoClass = featClass.Extension as IAnnoClass;

        IFontDisp font = new StdFontClass() as IFontDisp;
        font.Name = "Arial";
        font.Bold = true;
        // font.Size = 30;

        // load in some reasonable default values..
        IFormattedTextSymbol fmtTextSymb = new TextSymbolClass();
        fmtTextSymb.Font = font;
        fmtTextSymb.Size = 30;
        fmtTextSymb.VerticalAlignment = esriTextVerticalAlignment.esriTVABottom;
        fmtTextSymb.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft;
        fmtTextSymb.Angle = 0;
        fmtTextSymb.CharacterSpacing = 100;
        fmtTextSymb.CharacterWidth = 100;
        fmtTextSymb.FlipAngle = 90;
        fmtTextSymb.Leading = 0;
        fmtTextSymb.WordSpacing = 100;
        fmtTextSymb.Text = textString;  // my special text value..

        ITextElement textElement = new TextElementClass();

        textElement.Symbol = fmtTextSymb;
        textElement.Text = textString;

        IElement element = textElement as IElement;
        element.Geometry = pt;

        (feature as IAnnotationFeature2).Annotation = element;

        feature.Store();
    }
}
Kirk Kuykendall
quelle
Hallo Kirk, ich schätze deine Erkenntnisse hier. Tut diese AnnoClass aus Neugier etwas Bedeutendes an der Spitze von AddAnno ()? Trotzdem machst du immer noch ein paar "Setup-Dinge" anders als ich. Ich werde diese Empfehlung ausprobieren und zurückmelden. Vielen Dank.
Elrobis
oops, nein das kann ignoriert werden. Das ist von einem Test übrig geblieben, den ich mit einer Symbolsammlung durchgeführt habe, die ich von IAnnoClass erhalten habe.
Kirk Kuykendall
1
Danke @Kirk Kuykendall, Sie haben hier das eigentliche Problem aufgedeckt (siehe mein drittes Update im Fragenbereich). Danke vielmals!
Elrobis
2

Mit ISymbolCollectionElement können Sie Eigenschaften wie den Zeichenabstand festlegen.

In diesem Artikel wird erläutert, wie Sie ein Textelement verwenden sollten, um das von Ihnen beschriebene Problem zu vermeiden.

"Wenn ein TextElement verwendet wird, können Sie mithilfe der ISymbolCollectionElement- Schnittstelle auf ein in der SymbolCollection der AnnotationFeatureClassExtension gespeichertes TextSymbol verweisen . Es wird dringend empfohlen, beim Speichern von TextElements in einer Annotation-Feature-Class auf Symbole in der SymbolCollection zu verweisen. Weitere Informationen finden Sie in der Hilfe zu ISymbolCollectionElement für weitere Details zu diesem Speichersystem. "

"ISymbolCollectionElement bietet Zugriff auf Eigenschaften von TextElements, die auf TextSymbols verweisen, die in einer SymbolCollection als Teil von Geodatabase Annotation Feature Classes gespeichert sind. Beim Bearbeiten der TextElements von Annotation Features ist es wichtig, dass diese Schnittstelle verwendet wird, um die Verknüpfung mit dem SymbolCollection-Symbol aufrechtzuerhalten. Durch den Zugriff auf und die Aktualisierung von Symboleigenschaften über ITextElement :: Symbol wird das TextElement vom SymbolCollection-Symbol getrennt und das Symbol wird in Übereinstimmung mit dem Feature in der Feature-Class gespeichert. Dies ist unerwünscht, da TextSymbols groß sein können. "

Adressierung Ihrer Änderungen. Versuchen:

ISymbolCollectionElement scElement = new TextElementClass(); 
scElement.CharacterSpacing = 5; 
scElement.Geometry = pointGeom; 
scElement.Text = textString; 

(feature as IAnnotationFeature2).Annotation = scElement; 
(feat as IAnnotationFeature2).AnnotationClassID = 0; 
(feat as IAnnotationFeature2).Status = annoStatus;
Radar
quelle
Ich schätze Ihr Interesse, @Radar, wirklich. Ich glaube jedoch, dass der von Ihnen vorgestellte Fall eine verbesserte Speichereffizienz ist, bei der das Problem, das ich habe, mit dem Layout der Textzeichen innerhalb des Anmerkungselements zusammenhängt. Ich glaube das, weil ich ISymbolCollectionElement bereits ausprobiert habe und es die gleichen Ergebnisse erzielt hat.
Elrobis
Um sicherzugehen, habe ich es erneut mit dem von Ihnen empfohlenen Ansatz versucht und erhalte tatsächlich die gleichen Ergebnisse. Ich werde die Frage aktualisieren, um meinen geänderten Versuch einzuschließen.
Elrobis
Der zweite Absatz in meiner Antwort befasst sich mit dem Fall, dass die ITextElement :: Symbol-Verknüpfung unterbrochen ist, was zu einem verzerrten Textsymbol führt. Dies ist kein Problem der Speichereffizienz, sondern hat mehr mit der Instandhaltung von Immobilien zu tun. Spielen Sie mit einigen der ISymbolCollectionElement-Eigenschaften herum und prüfen Sie, ob Sie Ihren Text ändern können. Versuchen Sie beispielsweise, den Abstand zu ändern oder fett zu machen.
Radar
Ich habe die Frage aktualisiert, um meinen Versuch widerzuspiegeln, Ihre Empfehlung aufzunehmen. Außerdem habe ich gerade versucht, scElement.Bold = true hinzuzufügen. (eine merkwürdige Idee), und während es hat den Text fett machen, auch mit dem CharacterSpacing Satz bis 5, wird der Text noch gestapelt. Irgendwelche anderen Gedanken?
Elrobis
Ich frage mich, ob die Umwandlung in IElement (scElement als IElement) ein Problem für IAnnotationFeature verursacht. Können Sie direkt auf das ISymbolCollectionElement übertragen? (zB (Funktion als IAnnotationFeature2) .Annotation = scElement;)
Radar