Избегать сбоев в геообработке ArcObjects с .NET

14

В ArcToolbox есть несколько приятных функций, которые мы можем использовать, но по некоторым причинам это НЕ работает должным образом. Это даже не дает мне ошибки.

Мое программное обеспечение работает внутри ArcMap, поэтому нет необходимости снова AoInitialize, не так ли?

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

Это пример кода у меня здесь. Я сгенерировал сборку инструментов DataManagement, но не смог найти файл для его подписи.

Этот код просто дает мне ошибку. это из-за подписания?

Я пробовал и другой путь, используя IVariantArray и вызывая имя инструмента, но безуспешно. Это только я или ...?

Кто-нибудь может указать мне «более хорошее» решение? Мне нужно запустить несколько процессов, уже встроенных в ArcToolbox, которые я действительно не хочу дублировать.

Джордж Сильва
источник
Какую ошибку вы упоминаете позже в своем вопросе?
Денди
Привет Денди. Он не выдает ошибки, он просто терпит неудачу.
Джордж Сильва

Ответы:

14

В приведенном ниже коде функция multi2single работает для меня в 10.0. Я не смог протестировать Feature2Point, так как у меня нет лицензии ArcInfo, не так ли?

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
}

Я получаю этот вывод в 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
Кирк Куйкендалл
источник
Обработка ошибок - фантастика, Кирк. Я никогда не тратил достаточно времени на использование геопроцессора, чтобы узнать об интерфейсах IGeoProcessorEvent. Спасибо за указание на это!
BlinkyBill
ВАШ код работает! ArcObjects не любит меня.
Джордж Сильва
4

Вы правы в том, что нет необходимости в AoInitialize. Как вы обнаружили, отладка с помощью объекта геопроцессора - это боль в шее.

Что нужно сделать, так это читать сообщения, предупреждения и очереди ошибок после каждого вызова, чтобы проверить наличие проблем. Нет такой удачи, как полагаться на стандартную обработку ошибок .NET.

Попробуйте это после каждого вызова execute (обратите внимание на GetMessageS, а не на GetMessage) ...

Console.WriteLine("Messages: " + gp.GetMessages(1));
Console.WriteLine("Warnings: " + gp.GetMessages(2));
Console.WriteLine("Errors: " + gp.GetMessages(3));
BlinkyBill
источник
Привет, Эльдак! Я сдался после нескольких часов ударов головой, но скоро попробую еще раз, и я закончу дальнейшие действия по этому вопросу. Может ли это быть проблемой с подписью сборки при первом ее создании?
Джордж Сильва
Привет Джордж, это, вероятно, не проблема подписи. Если в параметрах FeatureToPoint (или любого другого инструмента геообработки) имеется простая ошибка синтаксиса / пути / типа, она завершится неудачей без какого-либо уведомления, следовательно, будет проверена очередь ошибок. Я больше не утруждаюсь инструментами геообработки. В большинстве случаев это просто занимает много времени, так как отладка - это ад.
BlinkyBill
Это боль, потому что мне нужно протестировать центроид, но я не уверен, как можно связать изменения, которые мне нужно сделать, без использования инструмента геообработки. Мне нужно изменить слой многоугольника, но тестирование нужно проводить под его центроидом. Я использую пространственный запрос для фильтрации своих результатов, поэтому я бы потерял его.
Джордж Сильва