Unikanie niepowodzenia w geoprzetwarzaniu ArcObjects w .NET?

14

W ArcToolbox jest kilka fajnych funkcji, których możemy użyć, ale z jakiegoś powodu NIE działa ono poprawnie. To nawet nie rzuca mi błędu.

Moje oprogramowanie działa w ArcMap, więc nie trzeba ponownie inicjować Ao, prawda?

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

To jest przykład kodu, który mam tutaj. Wygenerowałem zestaw narzędzi DataManagement, ale nie mogłem znaleźć pliku do podpisania.

Ten kod po prostu daje mi błąd. czy to z powodu podpisania?

Próbowałem też w drugą stronę, używając IVariantArray i dzwoniąc z nazwy narzędzia, bez powodzenia. Czy to tylko ja czy ...?

Czy ktoś może wskazać mi „ładniejsze” rozwiązanie? Muszę uruchomić kilka procesów, które są już wbudowane w ArcToolbox, których tak naprawdę nie chcę powielać.

George Silva
źródło
O jakim błędzie wspominasz później w swoim pytaniu?
Dandy
Cześć Dandy. Nie rzuca błędów, po prostu zawodzi.
George Silva,

Odpowiedzi:

14

W poniższym kodzie funkcja multi2single działa dla mnie w wersji 10.0. Nie mogłem przetestować Feature2Point, ponieważ nie mam licencji ArcInfo, prawda?

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
}

Otrzymuję ten wynik w 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
źródło
Obsługa błędów jest fantastyczna Kirk. Nigdy nie spędzałem wystarczająco dużo czasu na używaniu geoprocesora, aby wiedzieć o interfejsach IGeoProcessorEvent. Dzięki za wskazanie tego!
BlinkyBill,
TWÓJ kod działa! ArcObjects mnie nie lubi.
George Silva,
4

Masz rację, ponieważ nie ma potrzeby AoInitialize. Jak odkryłeś, debugowanie za pomocą obiektu geo-procesorowego powoduje ból szyi.

Co musisz zrobić, przeczytaj kolejkę komunikatów, ostrzeżeń i błędów po każdym połączeniu, aby sprawdzić problemy. Nie ma takiego szczęścia, jak poleganie na standardowej obsłudze błędów .NET.

Spróbuj tego po każdym wywołaniu (zwróć uwagę na GetMessageS, a nie GetMessage) ...

Console.WriteLine("Messages: " + gp.GetMessages(1));
Console.WriteLine("Warnings: " + gp.GetMessages(2));
Console.WriteLine("Errors: " + gp.GetMessages(3));
BlinkyBill
źródło
Cześć Eldac! Zrezygnowałem po kilku godzinach walenia w głowę, ale spróbuję to jeszcze raz wkrótce i skończę dalsze pytania dotyczące tego pytania. Czy może to być problem z podpisywaniem zestawu podczas jego pierwszego generowania?
George Silva,
Cześć George, prawdopodobnie nie jest to problem z podpisywaniem. Jeśli masz prosty błąd składni / ścieżki / typu w parametrach FeatureToPoint (lub innego narzędzia do geoprzetwarzania), zakończy się niepowodzeniem bez żadnego powiadomienia, stąd kontrola kolejki błędów. Nie kłopoczę się już narzędziami do geoprzetwarzania. W większości przypadków tak długo trwa, ponieważ debugowanie to piekło.
BlinkyBill,
Jest to ból, ponieważ muszę przetestować centroid, ale nie jestem pewien, jak mogę połączyć zmiany, które muszę wprowadzić bez użycia narzędzia geoprzetwarzania. Muszę zmienić warstwę wielokąta, ale testowanie musi być wykonane pod jej centroidem. Używam zapytania przestrzennego do filtrowania wyników, więc bym to stracił.
George Silva,