Menghindari gagal dari ArcObjects geoprocessing dengan .NET?

14

Ada beberapa fitur bagus di ArcToolbox yang dapat kita gunakan, tetapi untuk beberapa alasan, ini TIDAK berfungsi dengan baik. Bahkan tidak membuat saya kesalahan.

Perangkat lunak saya berjalan di dalam ArcMap, jadi tidak perlu AoInitialize lagi, corret?

    public void Execute()
    {
        InitializeProduct();
        try
        {
            Geoprocessor gp = new Geoprocessor();
            gp.OverwriteOutput = true;

            FeatureToPoint featureToPoint = new FeatureToPoint();

            string outputPathName = CurrentWorkspace.PathName + "\\teste_centroide";

            featureToPoint.in_features = InputFeatureClass;
            featureToPoint.out_feature_class = outputPathName;
            featureToPoint.point_location = "INSIDE";

            IGeoProcessorResult result = (IGeoProcessorResult)gp.Execute(featureToPoint, null);

            if (result == null)
            {
                for (int i = 0; i <= gp.MessageCount - 1; i++)
                {
                    Console.WriteLine(gp.GetMessage(i));
                }
            }

            IGPUtilities gpUtils = new GPUtilitiesClass();
            this.OutputFeatureClass = gpUtils.OpenFeatureClassFromString(outputPathName);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message + "\r\n");
        }

Ini adalah contoh kode yang saya miliki di sini. Saya menghasilkan perakitan alat DataManagement, tetapi saya tidak dapat menemukan file untuk menandatanganinya.

Kode ini hanya memberi saya kesalahan. apakah karena penandatanganan?

Saya sudah mencoba cara lain juga, menggunakan IVariantArray dan memanggil dari nama alat, tanpa berhasil. Apakah hanya saya atau ...?

Adakah yang bisa memberi saya solusi "lebih baik"? Saya perlu menjalankan beberapa proses yang sudah dibangun di ArcToolbox yang saya benar-benar tidak ingin tiru.

George Silva
sumber
Apa kesalahan yang Anda sebutkan nanti dalam pertanyaan Anda?
Dandy
Halo Dandy. Itu tidak melempar kesalahan, itu hanya gagal.
George Silva

Jawaban:

14

Dalam kode di bawah ini, fungsi multi2single bekerja untuk saya di 10.0. Saya tidak dapat menguji Feature2Point karena saya tidak memiliki lisensi ArcInfo, bukan?

public class Test
{
    public static void TestGP(IApplication app)
    {
        IMxDocument mxDoc = (IMxDocument)app.Document;
        //Feat2Point((IFeatureLayer)mxDoc.FocusMap.get_Layer(0), @"D:\Projects\AmberGIS\Forums\forumtest.gdb\f2p");
        Multi2Single((IFeatureLayer)mxDoc.FocusMap.get_Layer(0), @"D:\Projects\AmberGIS\Forums\forumtest.gdb\m2s");
    }

    public static void Multi2Single(IFeatureLayer inLayer, string outPath)
    {
        MultipartToSinglepart m2s = new MultipartToSinglepart();
        m2s.in_features = inLayer.FeatureClass;
        m2s.out_feature_class = outPath;
        Execute(m2s);
    }

    public static void Feat2Point(IFeatureLayer inLayer, string outPath)
    {
        FeatureToPoint f2p = new FeatureToPoint();
        f2p.in_features = inLayer.FeatureClass;
        f2p.out_feature_class = outPath;
        Execute(f2p);
    }

    public static void Execute(IGPProcess proc)
    {
        Geoprocessor gp = new Geoprocessor();
        gp.AddOutputsToMap = true;
        gp.OverwriteOutput = true;
        gp.RegisterGeoProcessorEvents((IGeoProcessorEvents)new GPEvents());
        IGeoProcessorResult2 result = gp.Execute(proc, null) as IGeoProcessorResult2;
        IGPMessages msgs = result.GetResultMessages();
        for(int i=0;i<msgs.Count;i++)
            Debug.Print("{0} {1}", msgs.GetMessage(i).Description, msgs.GetMessage(i).Type);            
    }
}
public class GPEvents : IGeoProcessorEvents3, IGeoProcessorEvents 
{
    #region IGeoProcessorEvents3 Members
    public void OnProcessMessages(IGeoProcessorResult result, IGPMessages pMsgs)
    {
        Debug.Print("OnProcessMessages {0}", result.Status);
    }
    public void OnProgressMessage(IGeoProcessorResult result, string message)
    {
        Debug.Print("OnProgressMessages {0}", result.Status);
    }
    public void OnProgressPercentage(IGeoProcessorResult result, double percentage)
    {
        Debug.Print("OnProgressPercentage {0}", result.Status);
    }
    public void OnProgressShow(IGeoProcessorResult result, bool Show)
    {
        Debug.Print("OnProgressShow {0}", result.Status);
    }
    public void PostToolExecute(IGeoProcessorResult result)
    {
        Debug.Print("PostToolExecute {0}", result.Status);
    }
    public void PreToolExecute(IGeoProcessorResult result)
    {
        Debug.Print("PreToolExecute {0}",result.Status);
    }
    #endregion

    #region IGeoProcessorEvents Members

    void IGeoProcessorEvents.OnMessageAdded(IGPMessage message)
    {
        Debug.Print("OnMessageAdded {0} {1}", message.Description, message.Type);
        throw new NotImplementedException();
    }

    void IGeoProcessorEvents.PostToolExecute(IGPTool Tool, ESRI.ArcGIS.esriSystem.IArray Values, int result, IGPMessages Messages)
    {
        Debug.Print("PostToolExecute2 {0}", Tool.Name);
    }

    void IGeoProcessorEvents.PreToolExecute(IGPTool Tool, ESRI.ArcGIS.esriSystem.IArray Values, int processID)
    {
        if (Tool.IsLicensed())
            Debug.Print("PreToolExecute");
        else
            Debug.Print("tool is not licensed to run");
    }

    void IGeoProcessorEvents.ToolboxChange()
    {
        Debug.Print("ToolboxChange");
    }

    #endregion
}

Saya mendapatkan output ini dalam VS:

PreToolExecute
PostToolExecute2 MultipartToSinglepart
Executing: MultipartToSinglepart GPL0 D:\Projects\AmberGIS\Forums\forumtest.gdb\m2s esriGPMessageTypeProcessDefinition
Start Time: Thu Sep 02 11:32:44 2010 esriGPMessageTypeProcessStart
Succeeded at Thu Sep 02 11:32:51 2010 (Elapsed Time: 7.00 seconds) esriGPMessageTypeProcessStop
Kirk Kuykendall
sumber
Penanganan kesalahan itu fantastis, Kirk. Saya tidak pernah menghabiskan cukup waktu menggunakan geoprocessor untuk mengetahui tentang antarmuka IGeoProcessorEvent. Terima kasih telah menunjukkannya!
BlinkyBill
Kode ANDA berfungsi! ArcObjects tidak menyukai saya.
George Silva
4

Anda benar karena tidak perlu untuk AoInitialize. Seperti yang telah Anda temukan, debugging dengan objek geo-prosesor adalah rasa sakit di leher.

Yang perlu Anda lakukan adalah membaca pesan, antrian peringatan dan kesalahan setelah setiap panggilan, untuk memeriksa masalah. Tidak ada keberuntungan mengandalkan mengandalkan standar .NET error.

Coba ini setelah setiap panggilan dijalankan (perhatikan GetMessageS, bukan GetMessage) ...

Console.WriteLine("Messages: " + gp.GetMessages(1));
Console.WriteLine("Warnings: " + gp.GetMessages(2));
Console.WriteLine("Errors: " + gp.GetMessages(3));
BlinkyBill
sumber
Halo eldac! Saya menyerah setelah beberapa jam melakukan head-banging, tetapi saya akan segera mencoba ini lagi dan saya akan menyelesaikan tindak lanjut dari pertanyaan tersebut. Mungkinkah ini masalah dengan menandatangani majelis saat Anda pertama kali membuatnya?
George Silva
Hai George, ini mungkin bukan masalah penandatanganan. Jika Anda memiliki kesalahan sintaks / jalur / tipe sederhana dalam params untuk FeatureToPoint (atau alat geoprocessing lainnya), itu akan gagal tanpa pemberitahuan, karenanya pemeriksaan antrian kesalahan itu. Saya tidak lagi repot dengan alat geoproses. Hanya butuh waktu lama untuk membuatnya berfungsi dalam banyak kasus, karena debugging adalah neraka.
BlinkyBill
Ini menyakitkan, karena saya perlu menguji centroid, tetapi saya tidak yakin bagaimana saya bisa menghubungkan perubahan yang perlu saya buat tanpa menggunakan alat geoprocessing. Saya perlu mengubah lapisan poligon, tetapi pengujian harus dilakukan di bawah centroid itu. Saya menggunakan kueri spasial untuk memfilter hasil saya, jadi saya akan kehilangan itu.
George Silva