¿Evitar fallas del geoprocesamiento de ArcObjects con .NET?

14

Hay algunas características interesantes en ArcToolbox que podemos usar, pero por alguna razón, esto NO funciona correctamente. Ni siquiera me arroja un error.

Mi software se está ejecutando dentro de ArcMap, por lo que no es necesario volver a inicializar, ¿corregir?

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

Este es un ejemplo de código que estoy teniendo aquí. Generé el conjunto de herramientas de DataManagement, pero no pude encontrar el archivo para firmarlo.

Este código solo me da un error. ¿Es por la firma?

También he intentado lo contrario, usando IVariantArray y llamando desde el nombre de la herramienta, sin éxito. ¿Soy solo yo o ...?

¿Alguien puede señalarme una solución "más agradable"? Necesito ejecutar varios procesos que ya están construidos en ArcToolbox que realmente no quiero duplicar.

George Silva
fuente
¿Cuál es el error que menciona más adelante en su pregunta?
Dandy
Hola dandy No arroja errores, simplemente falla.
George Silva el

Respuestas:

14

En el siguiente código, la función multi2single funciona para mí en 10.0. No pude probar Feature2Point ya que no tengo una licencia de ArcInfo, ¿puedes?

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
}

Me sale esta salida en 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
fuente
Ese manejo de errores es fantástico Kirk. Nunca pasé suficiente tiempo usando el geoprocesador para conocer las interfaces IGeoProcessorEvent. ¡Gracias por mencionarlo!
BlinkyBill
¡Tu código funciona! ArcObjects no me quiere.
George Silva
4

Tienes razón en que no hay necesidad de AoInitialize. Como has descubierto, la depuración con el objeto del geoprocesador es un dolor de cabeza.

Lo que debe hacer es leer el mensaje, la advertencia y la cola de errores después de cada llamada, para verificar si hay problemas. No existe la suerte de confiar en la entrega estándar de errores .NET.

Intente esto después de cada llamada de ejecución (tenga en cuenta GetMessageS, no GetMessage) ...

Console.WriteLine("Messages: " + gp.GetMessages(1));
Console.WriteLine("Warnings: " + gp.GetMessages(2));
Console.WriteLine("Errors: " + gp.GetMessages(3));
BlinkyBill
fuente
Hola eldac Me di por vencido después de unas horas de golpes en la cabeza, pero volveré a intentarlo pronto y terminaré los seguimientos sobre la pregunta. ¿Podría ser un problema al firmar el ensamblado cuando lo genera por primera vez?
George Silva
Hola George, probablemente no sea un problema de firma. Si tiene un error simple de sintaxis / ruta / tipo en los parámetros para FeatureToPoint (o cualquier otra herramienta de geoprocesamiento), fallará sin ninguna notificación, por lo tanto, la inspección de la cola de errores. Ya casi no me molesto con las herramientas de geoprocesamiento. Solo lleva mucho tiempo hacerlo funcionar en la mayoría de los casos, ya que la depuración es un infierno.
BlinkyBill
Esto es un dolor, porque necesito probar un centroide, pero no estoy seguro de cómo podría vincular las alteraciones que necesito hacer sin usar una herramienta de geoprocesamiento. Necesito alterar una capa de polígono, pero la prueba debe hacerse bajo su centroide. Estoy usando una consulta espacial para filtrar mis resultados, por lo que perdería eso.
George Silva