Vermeiden von Fehlern bei der ArcObjects-Geoverarbeitung mit .NET?

14

Es gibt einige nette Funktionen in ArcToolbox, die wir verwenden können, aber aus irgendeinem Grund funktioniert dies NICHT richtig. Es macht mir nicht einmal einen Fehler.

Meine Software wird in ArcMap ausgeführt, daher muss AoInitialize nicht erneut ausgeführt werden.

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

Dies ist ein Codebeispiel, das ich hier habe. Ich habe die DataManagement-Toolassembly generiert, die Datei zum Signieren jedoch nicht gefunden.

Dieser Code gibt mir nur einen Fehler. liegt es an der signierung?

Ich habe es auch andersherum versucht, indem ich IVariantArray verwendet und vom Toolnamen aus aufgerufen habe, ohne Erfolg. Bin es nur ich oder ...?

Kann mir jemand eine "schönere" Lösung zeigen? Ich muss mehrere Prozesse ausführen, die bereits in ArcToolbox erstellt wurden und die ich wirklich nicht duplizieren möchte.

George Silva
quelle
Was ist der Fehler, den Sie später in Ihrer Frage erwähnen?
Dandy
Hallo Dandy. Es wirft keine Fehler, es scheitert nur.
George Silva

Antworten:

14

Im folgenden Code funktioniert die Multi2Single-Funktion für mich in 10.0. Ich konnte Feature2Point nicht testen, da ich keine ArcInfo-Lizenz habe.

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
}

Ich bekomme diese Ausgabe 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
Kirk Kuykendall
quelle
Diese Fehlerbehandlung ist fantastisch, Kirk. Ich habe nie genug Zeit mit dem Geoprozessor verbracht, um die IGeoProcessorEvent-Schnittstellen zu kennen. Vielen Dank für den Hinweis!
BlinkyBill
IHR Code funktioniert! ArcObjects mag mich nicht.
George Silva
4

Sie haben Recht, dass AoInitialize nicht erforderlich ist. Wie Sie herausgefunden haben, ist das Debuggen mit dem Geoprozessorobjekt eine harte Angelegenheit.

Was Sie dazu benötigen, lesen Sie die Warteschlangen für Nachrichten, Warnungen und Fehler nach jedem Anruf, um nach Problemen zu suchen. Es gibt kein Glück, sich auf die standardmäßige .NET-Fehlerbehandlung zu verlassen.

Versuchen Sie dies nach jedem Ausführungsaufruf (beachten Sie die GetMessageS, nicht GetMessage) ...

Console.WriteLine("Messages: " + gp.GetMessages(1));
Console.WriteLine("Warnings: " + gp.GetMessages(2));
Console.WriteLine("Errors: " + gp.GetMessages(3));
BlinkyBill
quelle
Hallo eldac! Ich habe nach ein paar Stunden Headbangen aufgegeben, aber ich werde es bald wieder versuchen und die Folgemaßnahmen zu dieser Frage abschließen. Könnte dies ein Problem beim Signieren der Assembly sein, wenn Sie sie zum ersten Mal generieren?
George Silva
Hallo George, es ist wahrscheinlich kein Unterzeichnungsproblem. Wenn in den Parametern für FeatureToPoint (oder ein anderes Geoverarbeitungswerkzeug) ein einfacher Syntax- / Pfad- / Typfehler auftritt, schlägt der Vorgang ohne Benachrichtigung fehl, daher wird die Fehlerwarteschlange überprüft. Die Geoverarbeitungswerkzeuge beschäftigen mich kaum noch. In den meisten Fällen dauert es nur so lange, bis es funktioniert, denn das Debuggen ist die Hölle.
BlinkyBill
Dies ist ein Schmerz, da ich einen Schwerpunkt testen muss, aber ich bin nicht sicher, wie ich die Änderungen verknüpfen kann, die ich vornehmen muss, ohne ein Geoverarbeitungswerkzeug zu verwenden. Ich muss eine Polygonebene ändern, aber das Testen muss unter ihrem Schwerpunkt erfolgen. Ich verwende eine räumliche Abfrage, um meine Ergebnisse zu filtern, also würde ich das verlieren.
George Silva