Mengapa penjelasan ini tampak bertumpuk / tumpang tindih?

8

Saya mengalami masalah aneh ketika mencoba mengisi kelas fitur anotasi secara terprogram (ArcObjects, C #). Seperti yang dapat Anda lihat pada gambar di bawah ini, karakter dalam setiap string teks tampaknya saling menumpuk, daripada meletakkan secara horizontal seperti yang saya harapkan.

Saya menarik beberapa nilai dari MySQL (dibuat oleh aplikasi yang berbeda), dan itu terlihat bagus di debugger. Saya sudah mencoba menggunakan campuran sistem koordinat yang tidak diketahui / diproyeksikan, serta beberapa antarmuka Elemen yang berbeda. Jika ada yang melihat dan mengatasi masalah ini sebelumnya saya pasti akan menghargai dorongan ke arah yang benar.

Inilah bagian yang relevan dari C # saya:

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();

Dan seperti yang dijanjikan, inilah hasil yang saya dapatkan:

masukkan deskripsi gambar di sini

[Memperbarui]

Per @ Radar's saran saya mencoba revisi berikut, tetapi masih membuat teks penjelasan ditumpuk / tumpang tindih:

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;

Adakah yang memiliki wawasan tambahan?

[Pembaruan Kedua]

Pada dasarnya saya mencoba untuk menyelesaikan apa yang @murdoch lakukan di posting ArcScripts "lama" ini (lihat entri keduanya). Saya meninjau pendekatannya lagi dan memperhatikan bahwa dia menggunakan antarmuka IFormattedTextSymbol, jadi saya mencobanya, namun saya terus mengalami masalah yang sama dengan teks bertumpuk / tumpang tindih dalam anotasi yang ditempatkan. Inilah dorongan terakhir saya dari 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();

Adakah yang mempertanyakan hal ini? atau memiliki implementasi yang disukai? Begini tampilannya sekarang; seperti yang Anda lihat, pendekatannya agak berubah, tetapi hasilnya sama:

masukkan deskripsi gambar di sini

[Pembaruan Ketiga]

Pada analisis akhir, masalahnya bukan kode yang saya gunakan untuk membuat anotasi individu tetapi seperti yang diungkapkan oleh @Kirk Kuykendall, masalahnya adalah bagaimana saya membuat AnnotationLayer dengan saya IAnnotationLayerFactory.CreateAnnotationLayer(). Saya mengirimkan nulluntuk IGraphicsLayerScaleargumen, asumsi itu akan memutuskan untuk fungsional, jika tidak jelek, nilai-nilai default. Ternyata tidak. Saya membuat objek itu sebagai berikut, dan itu memperbaiki masalah saya:

// 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!

masukkan deskripsi gambar di sini

elrobis
sumber

Jawaban:

4

Dengan menggunakan arccatalog 10 sp2, saya membuat kelas fitur anotasi anotasi baru (non-featureink) dengan proyeksi web mercator, xy toleransi 0,001, skala referensi 1: 100.000, unit peta meter.

Saya tidak memeriksa "memerlukan simbol untuk dipilih dari tabel simbol". Menerima semua default untuk sisanya.

Saya kemudian pergi ke arcmap dan dapat menambahkan secara manual, kemudian menjalankan kode ini tanpa masalah yang tumpang tindih.

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
sumber
Hai Kirk, saya menghargai wawasan Anda di sini. Karena penasaran, apakah annoClass melakukan sesuatu yang signifikan di puncak AddAnno ()? Namun demikian, Anda masih melakukan beberapa "pengaturan hal" berbeda dari saya. Saya akan memberikan rekomendasi ini putaran dan melaporkan kembali. Terima kasih.
elrobis
oops, tidak ada yang bisa diabaikan. Itu sisa dari tes yang saya lakukan dengan koleksi simbol, yang saya dapatkan dari IAnnoClass.
Kirk Kuykendall
1
Terima kasih @Kirk Kuykendall, Anda membuka masalah sebenarnya di sini (lihat pembaruan ketiga saya di bagian pertanyaan). Terima kasih banyak!
elrobis
2

Menggunakan ISymbolCollectionElement akan memungkinkan Anda untuk mengatur properti seperti spasi karakter.

Artikel ini menjelaskan bagaimana Anda harus melakukan pendekatan menggunakan elemen teks untuk mencegah masalah yang Anda gambarkan.

"Jika TextElement digunakan, Anda dapat mereferensikan sebuah TextSymbol keluar yang disimpan dalam SymbolCollection dari AnnotationFeatureClassExtension dengan menggunakan antarmuka ISymbolCollectionElement . Sangat disarankan agar Anda referensi simbol di SymbolCollection ketika menyimpan TextElements dalam kelas fitur anotasi. Lihat bantuan untuk ISymbolCollectionElement untuk detail lebih lanjut tentang sistem penyimpanan ini. "

"ISymbolCollectionElement menyediakan akses ke properti TextElements yang mereferensikan TextSymbols yang disimpan dalam SymbolCollection sebagai bagian dari Kelas Fitur Anotasi Geodatabase. Saat mengedit TextElements fitur anotasi, sangat penting bahwa antarmuka ini digunakan untuk menjaga hubungan dengan simbol SymbolCollection. Mengakses dan memperbarui properti simbol melalui ITextElement :: Symbol akan menyebabkan TextElement terputus dari simbol SymbolCollection dan simbol akan disimpan sesuai dengan fitur di kelas fitur. Ini tidak diinginkan karena ukuran TextSymbols bisa besar. "

Mengatasi suntingan Anda. Mencoba:

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
sumber
Saya menghargai minat Anda, @Radar, sungguh. Namun, saya percaya kasus yang Anda sajikan adalah salah satu peningkatan efisiensi penyimpanan, di mana masalah yang saya alami berkaitan dengan tata letak karakter teks dalam elemen anotasi. Saya percaya ini karena saya sudah mencoba ISymbolCollectionElement dan mendapat hasil yang sama.
elrobis
Untuk memastikan, saya hanya mencoba lagi menggunakan pendekatan yang Anda rekomendasikan dan saya memang mendapatkan hasil yang sama. Saya akan memperbarui pertanyaan untuk memasukkan upaya saya yang dimodifikasi.
elrobis
Paragraf kedua dalam jawaban saya membahas kasus di mana tautan ITextElement :: Symbol rusak, menghasilkan simbol teks yang miring. Ini bukan masalah efisiensi penyimpanan, ini lebih berkaitan dengan pemeliharaan properti. Bermain-main dengan beberapa properti ISymbolCollectionElement dan lihat apakah Anda dapat memodifikasi teks Anda. Misalnya, cobalah mengubah spasi atau membuatnya menjadi tebal.
Radar
Saya memperbarui pertanyaan untuk mencerminkan upaya saya untuk memasukkan rekomendasi Anda. Juga, saya baru saja mencoba menambahkan scElement.Bold = true; (ide penasaran), dan sementara itu memang membuat teks tebal, bahkan dengan CharacterSpacing set ke 5, teks masih merender ditumpuk. Ada pemikiran lain?
elrobis
Saya bertanya-tanya apakah para pemain untuk IElement (scElement as IElement) menyebabkan masalah untuk IAnnotationFeature. Bisakah Anda mengirim langsung ke ISymbolCollectionElement? (mis. (fitur sebagai IAnnotationFeature2) .Annotation = scElement;)
Radar