Evitar falhas no geoprocessamento do ArcObjects com o .NET?

14

Existem alguns recursos interessantes no ArcToolbox que podemos usar, mas por algum motivo, isso NÃO está funcionando corretamente. Nem me lança um erro.

Meu software está rodando no ArcMap, então não é necessário AoInitialize novamente, 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");
        }

Este é um exemplo de código que estou tendo aqui. Gerei o conjunto de ferramentas DataManagement, mas não consegui encontrar o arquivo para assiná-lo.

Este código apenas me dá um erro. é por causa da assinatura?

Também tentei o contrário, usando IVariantArray e chamando a partir do nome da ferramenta, sem sucesso. Sou só eu ou ...?

Alguém pode me apontar uma solução "melhor"? Preciso executar vários processos já construídos no ArcToolbox que realmente não quero duplicar.

George Silva
fonte
Qual é o erro que você mencionou mais adiante na sua pergunta?
Dandy
Olá Dandy. Ele não gera erros, apenas falha.
George Silva

Respostas:

14

No código abaixo, a função multi2single funciona para mim na 10.0. Não pude testar o Feature2Point porque não tenho uma licença ArcInfo, pode?

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
}

Eu recebo esta saída no 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
fonte
Esse tratamento de erros é fantástico Kirk. Nunca gastei tempo suficiente usando o geoprocessador para conhecer as interfaces IGeoProcessorEvent. Obrigado por apontar isso!
BlinkyBill
SEU código funciona! O ArcObjects não gosta de mim.
George Silva
4

Você está correto, pois não há necessidade de AoInitialize. Como você descobriu, a depuração com o objeto de geoprocessador é uma dor no pescoço.

O que você precisa fazer é ler as mensagens, as filas de aviso e erro após cada chamada, para verificar se há problemas. Não existe a mesma sorte que confiar na entrega padrão de erros do .NET.

Tente isso após cada chamada de execução (observe o GetMessageS, não o GetMessage) ...

Console.WriteLine("Messages: " + gp.GetMessages(1));
Console.WriteLine("Warnings: " + gp.GetMessages(2));
Console.WriteLine("Errors: " + gp.GetMessages(3));
BlinkyBill
fonte
Olá eldac! Desisti depois de algumas horas de bater a cabeça, mas tentarei novamente em breve e terminarei o acompanhamento da questão. Isso poderia ser um problema com a assinatura do assembly quando você o gerou pela primeira vez?
George Silva
Olá George, provavelmente não é um problema de assinatura. Se houver um erro simples de sintaxe / caminho / tipo nos parâmetros do FeatureToPoint (ou qualquer outra ferramenta de geoprocessamento), ele falhará sem nenhuma notificação, portanto, a inspeção das filas de erros. Eu quase não me incomodo mais com as ferramentas de geoprocessamento. Leva muito tempo para fazê-lo funcionar na maioria dos casos, pois a depuração é um inferno.
BlinkyBill
Isso é doloroso, porque preciso testar um centróide, mas não sei como vincular as alterações que preciso fazer sem usar uma ferramenta de geoprocessamento. Preciso alterar uma camada de polígono, mas o teste precisa ser feito sob o centróide. Estou usando uma consulta espacial para filtrar meus resultados, para perder isso.
George Silva