Ich war unschlüssig, ob ich einen Blogbeitrag schreiben oder einfach eine Diskussion im Python-Bereich eröffnen sollte. Es ist schon eine Weile her, seit ich zu meinem Blog beigetragen habe, also entscheide ich mich für Ersteres.<\/EM><\/P>
<\/P>
Die ArcPy Data Access Walk-Funktion (arcpy.da.Walk<\/SPAN>) ist eine echte Arbeitspferdfunktion, auf die ich ziemlich oft zurückgreife. Die ArcPy Walk-Funktion ist ein Beispiel dafür, dass Esri mit ihrer Python-Implementierung alles richtig gemacht hat. Ich kann nicht sagen, was ihr Designziel war, aber es scheint ziemlich offensichtlich, dass das Ziel darin bestand, eine geospatial-bewusste Version von Pythons os.walk -Funktion zu schaffen. Die Namen sind gleich, viele der Parameter sind gleich, die Ergebnisse sind ähnlich usw.... Ich denke, die Nachahmung dieser langjährigen, nativen Python-Funktionalität in ArcPy war ein Gewinn, weil es kein perfekt funktionierendes Rad neu erfunden hat, d.h. Benutzer, die mit os.walk vertraut sind, können leicht auf arcpy.da.Walk umsteigen.<\/P>
<\/P>
So sehr ich die ArcPy Walk-Funktion auch mag, gibt es ein paar kleinere Probleme damit. Das erste ist ein Dokumentationsproblem oder besser gesagt ein Mangel an Dokumentation. Einer der Parameter der Walk-Funktion ist datatype. Die Dokumentation enthält eine Tabelle mit allen akzeptablen Argumenten für datatype, aber es gibt keine eigentliche Dokumentation der Datentypen selbst. Wenn man sich die Namen der Datentypen ansieht, scheinen die meisten offensichtlich zu sein, daher hat Esri vielleicht entschieden, dass sie diese nicht dokumentieren müssen.<\/P>
<\/P>
So beschreibend ein Name auf den ersten Blick auch erscheinen mag, führt fehlende Dokumentation meist zu Mehrdeutigkeit und Verwirrung. Zum Beispiel: Was fällt unter "FeatureClass"? Offensichtlich würde man annehmen, dass eine Feature-Class in einer Geodatabase abgedeckt ist, aber wie sieht es mit Shape-Dateien aus? Sind Shape-Dateien Feature-Classes? In Esri-Welt lautet die Antwort normalerweise "Ja", aber nicht immer. Das wirkliche Rätsel ist der "Geo"-Datentyp, da er Shape-Dateien einschließt, aber keine Feature-Classes in einer Geodatabase. Feature-Classes sind also nicht "geo?" So wichtig Dokumentation für Bibliotheken/APIs auch ist, sie ist heute nicht der Hauptgrund für diesen Beitrag.<\/P>
<\/P>
Eines meiner Lieblingsmuster mit ArcPy Walk ist es, die eingebaute Python-next()<\/SPAN>-Funktion einmal aufzurufen, um eine Liste von Shape-Dateien in einem Ordner oder Feature-Classes in einer Geodatabase oder Feature-Classes in einem Feature-Dataset zurückzugeben.<\/P>
>>> workspace = #Pfad zu Ordner oder Geodatabase oder Feature-Dataset
>>>
>>> _, _, filenames = next(arcpy.da.Walk(workspace, datatype="FeatureClass"))
>>> filenames
[u'canadwshed_p.shp', u'plots.shp']
>>>
>>> #oder Schleife über Feature-Classes oder Shape-Dateien
>>> for file in next(arcpy.da.Walk(workspace, datatype="FeatureClass"))[2]:
... print file
canadwshed_p.shp
plots.shp
>>>
<\/code><\/pre>
<\/P>
Im ersten Beispiel erstelle ich ein Wegwerf-Workspace-Walker-Objekt, das ich nicht behalten oder zerlegen muss. Im zweiten Beispiel ermöglicht mir der Aufruf von next() in der for-Schleife eine zusätzliche Schleife zu vermeiden, wenn ich nur an einer Ebene geospatialer Daten interessiert bin.<\/P>
<\/P>
Wie bei den meisten Dingen im Leben gibt es nicht nur einen Weg, Feature-Classes in einer Geodatabase oder Shape-Dateien in einem Ordner aufzulisten. Tatsächlich ist die ArcPy Walk-Funktion der neue Player und wurde mit ArcGIS 10.1 SP1 eingeführt. Vor ArcPy Walk konnte ein Benutzer eine der vielen ArcPy-Auflistungsfunktionen verwenden (ListDatasets, ListFeatureClasses, ListFiles, ListRasters, ListTables und ListWorkspaces) oder die ArcPy Describe -Funktion verwenden. Ich bevorzuge ArcPy Walk gegenüber den anderen wegen seiner Benutzerfreundlichkeit und Ähnlichkeit zur eingebauten Python-Funktionalität.<\/P>
<\/P>
Der Hauptgrund für diesen Blogbeitrag ist es, einen Bereich zu teilen, in dem die ArcPy Walk-Funktion stolpert, nämlich bei In-Memory-Datenquellen. Während die älteren Methoden zum Auflisten von Datenquellen mit In-Memory-Arbeitsbereichen funktionieren, trifft dies auf ArcPy Walk nicht zu.<\/P>
>>> arcpy.CreateFeatureclass_management('in_memory', 'test_fc')
<Result 'in_memory\\test_fc'>
>>> arcpy.CreateTable_management('in_memory', 'test_tbl')
<Result 'in_memory\\test_tbl'>
>>> arcpy.CreateRasterDataset_management('in_memory','test_rd')
<Result 'in_memory\\test_rd'>
>>>
>>> #mit ArcPy Walk
>>> next(arcpy.da.Walk('in_memory'))[2]
[]
>>>
>>> #mit ArcPy-Auflistungsfunktionen
>>> arcpy.env.workspace = 'in_memory'
>>> arcpy.ListFeatureClasses()
[u'test_fc']
>>> arcpy.ListTables()
[u'test_tbl']
>>> arcpy.ListRasters()
[u'test_rd']
>>> arcpy.ListDatasets()
[u'test_rd']
>>>
>>> #mit ArcPy Describe-Funktion
>>> [child.name for child in arcpy.Describe('in_memory').children]
[u'test_tbl', u'test_fc', u'test_rd']
>>>
<\/code><\/pre>
<\/P>
Das Nicht-Unterstützen von In-Memory-Arbeitsbereichen ist nicht viel mehr als ein Stolperer, aber dennoch ein Stolperer. Schließlich sagt die Dokumentation zwar aus, dass der erste Parameter der "Top-Level-Arbeitsbereich" ist und doch wird nicht erwähnt, dass In-Memory-Arbeitsbereiche nicht unterstützt werden. Glücklicherweise gibt es für Benutzer mindestens zwei andere Möglichkeiten, In-Memory-Datenquellen aufzulisten.<\/P>
<\/P>
UPDATE 06/2017:<\/STRONG><\/P>
<\/P>
Seit ich diesen Blogbeitrag vor fast 18 Monaten geschrieben habe (Ich weiß „die Zeit vergeht schnell“, aber trotzdem schon 18 Monate? ), habe ich festgestellt, dass das Problem mit ArcPy Walk und In-Memory-Arbeitsbereichen nuancierter ist als ursprünglich gedacht. Lassen Sie mich das demonstrieren:<\/P>
>>> arcpy.CreateFeatureclass_management('in_memory', 'test_fc')
<Result 'in_memory\\test_fc'>
>>> arcpy.CreateTable_management('in_memory', 'test_tbl')
<Result 'in_memory\\test_tbl'>
>>> arcpy.CreateRasterDataset_management('in_memory','test_rd')
<Result 'in_memory\\test_rd'>
>>>
>>> # Verwendung von ArcPy Walk mit "GPInMemoryWorkspace" statt dem üblichen "in_memory"
>>> next(arcpy.da.Walk('GPInMemoryWorkspace'))[2]
[u'test_tbl', u'test_fc', u'test_rd']
>>> <\/code><\/pre>
<\/P>
Es stellt sich also heraus, dass ArcPy Walk mit In-Memory-Arbeitsbereichen gut funktioniert, wenn es tatsächlich weiß, dass Sie auf einen In-Memory-Arbeitsbereich verweisen. Der wirklich frustrierende Teil daran und sogar etwas bedauerlich ist, dass es hier einfach um Semantik geht und Esri es immer noch nicht schafft, das zu beheben. Funktional arbeitet ArcPy Walk bereits mit In-Memory-Arbeitsbereichen zusammen – die Funktion weiß nur nicht, dass alle anderen und jedes andere Tool diese Bereiche als "in_memory" statt als "GPInMemoryWorkspace" bezeichnen.<\/P>