Schnelles Löschen von Feature-Class-Features mit ArcPy?

8

Ich habe dieses Skript geschrieben, das alle Feature-Classes in einem bestimmten Satz von Feature-Datasets durchläuft und alle ihre Features löscht. Es scheint den Job zu machen, aber es läuft ziemlich langsam. Gibt es irgendetwas, was ich hier falsch mache, oder gibt es offensichtliche Möglichkeiten, die Dinge zu beschleunigen?

Ich benutze DeleteFeatures_management , um die Tat auszuführen . DeleteRows_management scheint ebenfalls zu funktionieren.

import sys
import os
import arcpy
from arcpy import env
import datetime
import getpass

try:
    passwd = getpass.getpass("Enter the sde user password: ")

    sdeConnectionFileDir = os.environ.get("TEMP")
    databaseName = ""
    fileName = "temp.sde"

    # Delete any pre-existing SDE connection file.
    fullPath = sdeConnectionFileDir + '\\' + fileName
    if os.path.exists(fullPath):
        os.remove(fullPath)

    # Create temporary SDE connection file.
    arcpy.CreateArcSDEConnectionFile_management (
        sdeConnectionFileDir, fileName,
        "sdeserver", "5151", "",
        "DATABASE_AUTH", "my_sde_user", passwd,
        "SAVE_USERNAME", "SDE.DEFAULT", "SAVE_VERSION"
    )

    env.workspace = fullPath

    # ArcPy status codes.
    returnCodes = {'WARN' : 0, 'INFO' : 1, 'ERROR' : 2}

    featureDatasets = []
    featureDatasets.extend(arcpy.ListDatasets("dataset1*"))
    featureDatasets.extend(arcpy.ListDatasets("dataset2*"))
    featureDatasets.extend(arcpy.ListDatasets("dataset3*"))

    list = '[%s]' % ', '.join(map(str, featureDatasets))
    response = raw_input("\n***** WARNING!!! ***** \nAll data will be deleted from all feature classess in the following datasets: \n\n" + list + "\n\n |--> Type DELETE to begin removal: ")
    if response == "DELETE":
        print "\nStarted: " + str(datetime.datetime.now()) + "\n"
        for dataset in featureDatasets:
            print "Processing dataset: " + dataset
            for fc in arcpy.ListFeatureClasses("*", "ALL", dataset):
                rowCount = int(arcpy.GetCount_management(fc).getOutput(0))

                if rowCount > 0:
                    print "  -- Processing feature class: " + str(fc) + " (" + str(rowCount) + " rows)"
                    #arcpy.DeleteRows_management(fc)
                    arcpy.DeleteFeatures_management(fc)

        print "\nCompleted: " + str(datetime.datetime.now())

except Exception as e:
    if arcpy:
        arcpyErrors = arcpy.gp.getMessages(returnCodes['ERROR'])
        if arcpyErrors:
            sys.stderr.write(arcpyErrors + "\n")
    sys.stderr.write(str(e) + "\n")
    sys.exit(1)

BEARBEITEN -

Ich habe einige Performance-Timer in das Skript eingefügt und hier sind die Daten:

  • Zeit zum Abrufen von Datensätzen: 0: 00: 01.254000
  • Gesamtfeature-Klassen: 1682
  • Gesamtzahl der Feature-Classes mit Daten: 124
  • Verarbeitete Gesamtfunktionen: 190222
  • Gesamtlaufzeit : 3 Stunden, 16 Minuten

Die Panne:

Feature-Dataset -> Feature-Class-Aufrufe auflisten:

* AVG   0:00:02
* MIN   0:00:01
* MAX   0:00:07
* COUNT 40
* TOTAL 0:01:08

Funktionsanzahlaufrufe (meistens):

* AVG   0:00:06
* MIN   0:00:01
* MAX   0:00:16
* COUNT 1682
* TOTAL 2:41:00

Aufrufe zum Löschen von Features (reduziert, da nur Feature-Classes mit Zeilen verarbeitet werden):

* AVG   0:00:17
* MIN   0:00:02
* MAX   0:03:22
* COUNT 124
* TOTAL 0:34:31
Andy Arismendi
quelle

Antworten:

14

Welcher Teil des Skripts nimmt tatsächlich die meiste Zeit ein? Es gibt ungefähr 5 weitere Schritte, bevor Sie mit dem Löschen beginnen.

Möglicherweise möchten Sie Ihr Skript in mundgerechte Tests aufteilen. Anstatt beispielsweise eine temporäre Verbindungsdatei zu erstellen, eine Reihe von Datasets aufzulisten, deren Inhalt aufzulisten, ihre Datensätze zu zählen und schließlich das zu tun, was Sie tun möchten (Features löschen), übergeben Sie einfach eine einzelne Feature-Class mit einer vorgefertigten Verbindungsdatei zu DeleteFeatures und sehen, wie lange das dauert.

Wenn dies akzeptabel ist, erstellen Sie einen weiteren Test, um den nächsten potenziellen Fehlerpunkt zu ermitteln: das Zählen von Zeilen. Eine weitere zum Auflisten von Feature-Classes in einem Feature-Dataset und eine weitere zum Auflisten von Feature-Datasets in einer Geodatabase.

Wenn DeleteFeatures andererseits nicht akzeptabel funktioniert, wissen wir zumindest, wo das Problem liegt. In diesem Fall würde ich eher darauf achten, wie Ihre Geodatabase aufgebaut ist:

  • Sind einige Ihrer Feature-Datasets versioniert? Bei Verwendung der Versionierung gibt es für jede versionierte Tabelle ein zusätzliches Paar von A-Tabellen (Hinzufügen) und D-Tabellen (Löschen). Wenn Sie Features löschen, löschen Sie keine Datensätze in der Basistabelle, sondern fügen der D-Tabelle Datensätze hinzu. Dies dauert viel länger als ohne Versionierung.

  • Da Ihre Feature-Classes anscheinend alle in Feature-Datasets enthalten sind, nehmen sie am Geodatabase-Verhalten wie einer Topologie oder einem geometrischen Netzwerk teil? Wenn Sie Features hinzufügen / entfernen / ändern, die am Verhalten der Geodatabase beteiligt sind, entsteht viel mehr Overhead.

  • Beachten Sie auch, dass Feature-Datasets entgegen der landläufigen Meinung nicht als organisatorisches Werkzeug konzipiert sind:

    In der Geodatabase sind Feature-Datensätze vorhanden, um einen Bereich für einen Raumbezug zu definieren. Alle Feature-Classes, die an topologischen Beziehungen miteinander beteiligt sind (z. B. ein geometrisches Netzwerk), müssen denselben räumlichen Bezug haben. Feature-Datensätze sind eine Möglichkeit, Feature-Classes mit demselben Raumbezug zu gruppieren, damit sie an topologischen Beziehungen miteinander teilnehmen können.

    Für die meisten Benutzer haben Feature-Datensätze auch eine natürliche organisatorische Qualität, ähnlich wie ein Ordner in einem Dateisystem. Da für viele GIS-Anwendungen der Großteil der Daten denselben räumlichen Bezug hat, ist die Versuchung, eine große Anzahl von Feature-Classes in Feature-Datensätzen zu gruppieren, unwiderstehlich.

    Feature-Datensätze sind jedoch nicht kostenlos. Wenn Sie eine in einem Feature-Datensatz enthaltene Feature-Class öffnen, um deren Eigenschaften anzuzeigen oder sie in ArcCatalog ™, ArcMap ™ oder einer benutzerdefinierten Anwendung zu zeichnen oder abzufragen, werden auch alle anderen Feature-Classes in diesem Feature-Datensatz geöffnet. Dies erfolgt, weil Aktualisierungen einer Feature-Class in einem Feature-Datensatz möglicherweise zu anderen Feature-Classes im Feature-Datensatz führen können, die an topologischen Beziehungen beteiligt sind.

    Aus: Mehrbenutzer-Geoinformationssysteme mit ArcInfo 8 (April 2000)

    Dies kann eine weitere Overhead-Quelle sein, selbst wenn sie nicht an einer Topologie oder einem geometrischen Netzwerk beteiligt sind.

Über die arcpy DeleteFeatures / DeleteRows-Befehle hinaus:

  • Wenn Sie Zugriff auf SDE-Verwaltungsbefehle haben, können Sie Folgendes verwenden:

    sdetable -o truncate -t <tablename>

    Dadurch werden abgeschnittene Tabellenbefehle an Ihr DBMS ausgegeben, sodass es viel schneller sein sollte. Beachten Sie jedoch, dass das Verhalten der Geodatabase ignoriert wird.

  • Verwenden von ArcSDESQLExecute zum TRUNCATE TABLEdirekten Ausgeben von Befehlen (unter Umgehung des Geodatabase-Verhaltens). Dies ist jedoch sehr problematisch , da Sie für jede Tabelle, aus der eine Feature-Class besteht (Basis, F, S, I, A, D usw.), Einen ausgeben müssen Wenn Sie dies nicht sorgfältig und korrekt tun, können Ihre Daten in einem inkonsistenten Zustand bleiben.

blah238
quelle
Dies ist ein guter Rat. Ich werde für jede Operation einige Timer eingeben und die Ergebnisse veröffentlichen. Zumindest aus dem bisherigen Feedback geht hervor, dass ich die entsprechenden ArcPy-API-Methoden verwende. Ich lerne immer noch die ArcPy-API, daher war ich besorgt, dass ich eine andere Methode verwenden sollte.
Andy Arismendi
Was arcpy angeht, denke ich, dass DeleteRows und DeleteFeatures das Beste sind, was Sie tun können, aber ich habe einige andere Optionen hinzugefügt, die es wert sein könnten, geprüft zu werden, zumindest wenn dies zeitkritisch ist.
blah238
Ich habe oben einige Leistungsmetriken hinzugefügt. Es gibt 1682 Feature-Classes. Obwohl das Zählen im Durchschnitt nur 1/3 der Löschzeit in Anspruch nahm. Zugegeben, die Löschvorgänge haben nur Feature-Classes mit Features verarbeitet. Ich werde versuchen, die Anzahl zu entfernen und einfach alle Feature-Classes an DeleteRows_management übergeben und sehen, wie sich das auswirkt. Ich werde auch versuchen, sdetable mit der Option "Abschneiden".
Andy Arismendi
2
Huch, 1682 Feature-Classes?! Ich würde definitiv einen alternativen Workflow in Betracht ziehen, um mit so vielen Daten umzugehen. Wenn Sie über Hunderte von Tabellen sprechen, sollten Sie wirklich im Back-End arbeiten und direkt mit dem DBMS IMO arbeiten.
Lassen
Nur 124 Feature-Classes hatten tatsächlich Features, der Rest war leer. Übrigens hast du mir gerade eine Idee gegeben! Möglicherweise hilft das Erstellen der SDE-Verbindungsdatei mithilfe einer Oracle-Direktverbindung, die Leistung zu verbessern. Ich werde es als nächstes versuchen.
Andy Arismendi
9

Wenn ein Upgrade auf ArcGIS 10.1 (jetzt veröffentlicht) möglich ist, habe ich dies gerade im PDF "Was ist neu in ArcGIS 10.1?" Gefunden:

Neues Tool zum Löschen aller Zeilen aus einer Tabelle

Mit dem Geoverarbeitungswerkzeug "TruncateTable" im Toolset "Tabellen" können alle Zeilen aus einer Tabelle oder Feature-Class gelöscht werden. Sie sollten das Werkzeug "Tabelle abschneiden" anstelle des Werkzeugs "Zeilen löschen" verwenden, wenn Sie alle Zeilen aus einer Tabelle oder Feature-Class löschen möchten.

Die Online-Hilfe finden Sie hier .

PolyGeo
quelle
1
Dies ist so viel schneller als DeleteRows
nmpeterson
3
Das einzige ist, dass es keine versionierten Tabellen / Feature-Classes unterstützt.
Ruchira Welikala
5

Warum nicht einfach die Feature-Datasets selbst löschen arcpy.DeleteFeatures_management(dataset)? Wenn das Feature-Dataset weiterhin vorhanden sein muss, können Sie es nach dem Löschen einfach neu erstellen.

nmpeterson
quelle
Ich muss die Feature-Datasets und ihre Feature-Classes beibehalten, da sie aufgrund der SDE / Oracle-Kombination nicht schnell neu erstellt werden und es einige Feature-Classes gibt. Ich versuche die Funktionen so schnell wie möglich zu löschen.
Andy Arismendi