Evitare i fallimenti del geoprocessing di ArcObjects con .NET?


14

In ArcToolbox ci sono alcune funzioni interessanti che possiamo usare, ma per qualche ragione NON funziona correttamente. Non mi lancia nemmeno un errore.

Il mio software funziona all'interno di ArcMap, quindi non è necessario eseguire nuovamente AoInitialize, correggilo?

    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");
        }

Questo è un esempio di codice che sto avendo qui. Ho generato l'assemblaggio degli strumenti DataManagement, ma non sono riuscito a trovare il file per firmarlo.

Questo codice mi dà solo un errore. è a causa della firma?

Ho provato anche dall'altra parte, usando IVariantArray e chiamando dal nome dello strumento, senza successo. Sono solo io o ...?

Qualcuno può indicarmi una soluzione "più bella"? Ho bisogno di eseguire diversi processi che sono già integrati in ArcToolbox che non voglio davvero duplicare.


Qual è l'errore che menzioni più avanti nella tua domanda?
Dandy,

Ciao dandy Non genera errori, fallisce e basta.
George Silva,

Risposte:


14

Nel codice seguente, la funzione multi2single funziona per me in 10.0. Non ho potuto testare Feature2Point poiché non ho una licenza ArcInfo, vero?

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
}

Ottengo questo output in 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

Quella gestione degli errori è Kirk fantastico. Non ho mai trascorso abbastanza tempo usando il geoprocessore per conoscere le interfacce IGeoProcessorEvent. Grazie per segnalarlo!
BlinkyBill,

IL TUO codice funziona! Ad ArcObjects non piaccio.
George Silva,

4

Hai ragione in quanto non è necessario per AoInitialize. Come hai scoperto, il debug con l'oggetto geo-processore è un dolore al collo.

Quello che devi fare è leggere il messaggio, l'avviso e la coda degli errori dopo ogni chiamata, per verificare la presenza di problemi. Non c'è fortuna come fare affidamento sulla gestione degli errori .NET standard.

Prova questo dopo ogni chiamata di esecuzione (nota GetMessageS, non GetMessage) ...

Console.WriteLine("Messages: " + gp.GetMessages(1));
Console.WriteLine("Warnings: " + gp.GetMessages(2));
Console.WriteLine("Errors: " + gp.GetMessages(3));

Ciao Eldac! Mi sono arreso dopo alcune ore di colpi alla testa, ma ci riproverò presto e finirò i follow-up sulla domanda. Potrebbe essere un problema con la firma dell'assembly quando lo si genera per la prima volta?
George Silva,

Ciao George, probabilmente non è un problema di firma. Se hai un semplice errore di sintassi / percorso / tipo nei parametri per FeatureToPoint (o qualsiasi altro strumento di geoprocessing), fallirà senza alcuna notifica, quindi l'ispezione della coda degli errori. Non mi preoccupo più degli strumenti di geoprocessing. Ci vuole così tanto tempo per farlo funzionare nella maggior parte dei casi, poiché il debug è un inferno.
BlinkyBill,

Questo è un dolore, perché devo testare un centroide, ma non sono sicuro di come posso collegare le alterazioni che devo fare senza usare uno strumento di geoprocessing. Devo modificare uno strato poligonale, ma il test deve essere eseguito sotto il suo centroide. Sto usando una query spaziale per filtrare i miei risultati, quindi lo perderei.
George Silva,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.