Wie verwenden Benutzer Python-Datenstrukturen und -Klassen in ArcPy?

16

Diese Frage kann meine Unkenntnis in Bezug auf das Programmieren aufdecken, aber ich bin neugierig, wie Benutzer unterschiedliche Python-Datenstrukturen in ArcPy verwenden.

Diese Seite listet die Datenstrukturen in Python auf. Ich verstehe, wie Listen in GIS implementiert werden können (Liste der Objektklassen, Liste der Objekttypen, Liste der Datenrahmen usw.). Ich verstehe, wie Sets auch verwendet werden können (um Duplikate zu entfernen). Wie implementieren Benutzer Tupel, Wörterbücher und andere Datenstrukturen in ArcPy? Gibt es auch andere Beispiele für Listen und Sets, die ich nicht aufgelistet habe?

Darüber hinaus erstellen Benutzer ohne Zweifel benutzerdefinierte Klassen in ArcPy. Unter welchen Umständen und in welchen Situationen benötigen Sie diese? Können Sie Beispiele nennen? Erstellt jemand benutzerdefinierte Klassen, die von den integrierten Arcpy-Klassen erben?

Ich benötige keine Antworten auf all diese Fragen. Ich bin nur neugierig, wie Python in GIS verwendet wird und welche Workflows diese Anpassungen erfordern.

Fezter
quelle
4
Interessante Frage, aber dies hat keine endgültige Antwort. Sollte ein Community-Wiki sein.
RK

Antworten:

14

Viele arcpy-Funktionen, die mehrere Eingaben annehmen, akzeptieren Python-Listenobjekte.

Zum Beispiel Dissolve_managementakzeptiert die Funktion eine Liste von Feldnamen, auf die aufgelöst werden soll:

arcpy.Dissolve_management("taxlots", "C:/output/output.gdb/taxlots_dissolved",
    ["LANDUSE", "TAXCODE"], "", "SINGLE_PART", "DISSOLVE_LINES")

Ein Tupel kann anstelle einer Liste verwendet werden, wenn Sie die Reihenfolge oder Anzahl der Elemente nicht ändern müssen, da Tupel unveränderlich sind . Sie sind eine nützliche Datenstruktur für heterogene, aber verwandte Daten, z. B. die Elemente eines Zeitstempels oder die Koordinaten eines Punkts. Es werden häufig Tupellisten angezeigt, in denen ein Tupel als eindeutiger Datensatz mit einer festen Anzahl von Attributen dient, während die Liste leicht die Größe ändern, neu geordnet (sortiert) werden kann usw. Weitere Informationen zu den Verwendungen finden Sie in dieser StackOverflow-Frage von Listen gegen Tupel.

Ein Wörterbuch kann als schnelle Nachschlagetabelle verwendet werden, um einen relativ kleinen, aber häufig verwendeten Satz von Schlüsselwertpaaren im Speicher zwischenzuspeichern. Ich habe in den ArcGIS-Foren ein interessantes Beispiel dafür gesehen: http://forums.arcgis.com/threads/55099-Update-cursor-with-joined-tables-work-around-w-dictionaries

Die Verwendung eines Wörterbuchs anstelle eines Joins beschleunigte die Berechnung von 3,5 Stunden auf 15 Minuten.

Ein einfacheres Beispiel könnte sein, dass Sie über eine Million Adressdatensätze mit einem Attribut mit dem abgekürzten Statusnamen (CA) verfügen. Für Anzeigezwecke möchten Sie jedoch den richtigen Namen (Kalifornien) formulieren. Sie können dieses Wörterbuch als Nachschlagetabelle verwenden, wenn Füllen eines vollständigen Statusnamensfelds.

Ich habe keine Notwendigkeit gefunden, eine Klasse in Python zu schreiben, um sie in arcpy selbst zu verwenden, aber das heißt nicht, dass es keinen solchen Anwendungsfall gibt. Eine Klasse kann nützlich sein, wenn Sie über eine Reihe eng verwandter Funktionen (Verhaltensweisen) verfügen, die mit bestimmten Eingaben (Daten) arbeiten, und diese Daten und Verhaltensweisen objektorientiert verwenden möchten. Dies ist jedoch mehr Wahrscheinlich geschäftslogikspezifisch und nicht mit Arcpy verwandt.

blah238
quelle
7

Blah238 deckt dieses Thema gut ab, daher füge ich nur einige Beispiele aus meiner eigenen Arbeit hinzu. Ich entwickle viele Flughafendaten, und eines der Dinge, die ich regelmäßig tun muss, ist, die Reihenfolge entlang der gemessenen Pistenmittelpunkte von einer Piste aus zu lesen. Sie würden denken, dass diese Punkte bereits in der Reihenfolge (in der GIS-Datenbank) sind, aber dies ist selten der Fall. Die Mittellinienpunkte treten alle 10 Fuß entlang der Mittellinie auf und werden zu beiden Seiten von zwei weiteren Reihen von Vermessungspunkten flankiert, die 10 Fuß voneinander entfernt sind. Sie erhalten das Bild: eine Fülle von Punkten ... und in der Regel alle Datenbank zusammen gemischt. Mit dem, was ich in meinen Skripten mache, ist es normalerweise am einfachsten, die Mittellinienpunkte nach Attributen (oder gegebenenfalls räumlich) auszuwählen, die Koordinaten für jeden Punkt zu lesen und die Ergebnisse in einer Python-Liste abzulegen. Ich kann dann sortieren, knallen, umkehren usw.

Ebenso benutze ich Python-Wörterbücher ausgiebig (wahrscheinlich weit mehr, als manche befürworten würden). Ich muss für jedes Start-und Landebahnende auf einem Flughafen Sätze von 3D-Einheitsvektoren erstellen, und ich greife innerhalb eines Skripts ständig auf diese zu und mache dies in vielen meiner Skripts. Ich verwalte auch viele andere Daten, auf die regelmäßig zugegriffen wird, in Wörterbüchern. Wie Listen sind sie schnell und flexibel. Sehr empfehlenswert.

Was den Unterricht angeht, habe ich wie bei Blah238 keine Notwendigkeit gefunden, eine zu erstellen. Es gibt wahrscheinlich einige Fälle, in denen eine Klasse in meinen Skripten bevorzugt wird, aber ich konnte diese Orte wirklich nicht identifizieren. Jemand mit mehr Programmiererfahrung würde sie wahrscheinlich schnell finden.

Keltenflöte
quelle
5

Ich liebe auch Wörterbücher - benutze sie die ganze Zeit. Diese Methode ruft einige räumliche Referenzeigenschaften ab und speichert alles in einem Diktat:

def get_coord_sys(self, in_dataset):
    """Get and return info on dataset coord sys/projection"""
    spatial_ref = arcpy.Describe(in_dataset).spatialReference
    # Get spatial ref props and put in dictionary
    spat_ref_dict = {}
    spat_ref_dict["name"] = spatial_ref.name
    spat_ref_dict["type"] = spatial_ref.type
    spat_ref_dict["gcs_code"] = spatial_ref.GCSCode
    spat_ref_dict["gcs_name"] = spatial_ref.GCSName
    spat_ref_dict["pcs_code"] = spatial_ref.PCSCode
    spat_ref_dict["pcs_name"] = spatial_ref.PCSName
    return spat_ref_dict

Dieses Methoden-Snippet extrahiert Punktgeometrien aus zwei Feature-Classes. Ich verwende die Geometrien später, um einige Trigger auszuführen:

def build_fields_of_view(self):
        """For all KOPs in a study area, build left, right, center FoV triangles"""
        try:    
            fcs = {os.path.join(self.gdb, "WindFarmArray"):[], os.path.join(self.gdb, "KOPs"):[]}
            # Build a dict of WTG and KOP array geometries, looks like:
            #  {'KOPs': [[1, -10049.2697098718, 10856.699451165374], 
            #            [2, 6690.4377855260946, 15602.12386816188]], 
            #   'WindFarmArray': [[1, 5834.9321158060666, 7909.3822339441513], 
            #                     [2, 6111.1759513214511, 7316.9684107396561]]}
            for k, v in fcs.iteritems():
                rows = arcpy.SearchCursor(k, "", self.sr)
                for row in rows:
                    geom = row.shape
                    point = geom.getPart()
                    id = row.getValue("OBJECTID")
                    v.append([id, point.X, point.Y])   

            kops = fcs[os.path.join(self.gdb, "KOPs")] # KOP array
            wtgs = fcs[os.path.join(self.gdb, "WindFarmArray")] # WTG array

Eine Menge von dem, woran ich gerade arbeite, beinhaltet das Extrahieren der Koordinaten und Attribute aus Vektor-Feature-Classes und Rastern, so dass die Daten in eine andere Software übertragen werden können, die nicht einmal weiß, was GIS-Daten sind. Deshalb benutze ich häufig Listen und Wörterbücher.

Chad Cooper
quelle
Danke für die Antwort. Warum ist ein Wörterbuch in diesen Fällen eine bessere Wahl als eine andere Datenstruktur?
Fezter
Ich möchte meine Werte nur mit meinen Schlüsseln aufrufen können.
Chad Cooper
2
Ein weiterer Grund, warum Dikte vorzuziehen sind, ist, dass sie viel schneller gelesen werden als Listen, weil sie nicht sortiert sind. Daher kann die Verarbeitung sehr langer Listen etwas länger dauern, wenn sie viele Einträge enthalten.
ndimhypervol
@gotanuki Richtig, und wenn Sie eine große Liste verwenden müssen, verwenden Sie stattdessen ein Tupel, da diese auch schneller als Listen sind.
Chad Cooper
2

Lies dies, während du eine Antwort zusammenstellst und einige Änderungen vornehmen musstest.

Ich bin kein Python-Experte, aber ich denke, die Idee hinter der Verwendung von Klassen ist, dass Sie ein Objekt instanziieren können, das eine Reihe von Methoden bereitstellt, die sich auf die Datenstruktur beziehen, sowie Ihre Methoden zentralisieren. Es gibt auch einige Vorteile mit variablem Geltungsbereich bei Klassen gegenüber Modulen.

Ich habe eine Klasse namens featureLayer (wahrscheinlich nicht pythonisch benannt ... lerne noch). ich kann

sys.path.append(r"\\Path\To\Scripts")
import gpFuncs as gpF
fc = arcpy.GetParameterAsText(0)
featureLayer = gpF.featureLayer(fc)
points = featureLayer.featureVerticesToPoints(featureid, "", first_and_last)

Die Definition hierfür ist eine Klassenmethode, die nur die Features, Teile und Scheitelpunkte iteriert. Dann kann ich mein points-Objekt in eine featureLayer-Instanz verwandeln und andere Dinge tun, die meine Klasse hat.

Ich denke, wenn Klassen richtig erstellt werden, sollte die Funktionalität inkapusliert werden. In Kürze beginne ich beispielsweise mit der Umgestaltung, sodass ich eine featureLayer-Klasse mit Methoden und Attributen habe, über die alle Feature-Layer verfügen. Erben Sie dann davon, um eine featureLayerStrict-Klasseninstanz zu erstellen, die alle featureLayers-Attribute / -Methoden erbt, aber mit einem bestimmten Geometrietyp wie Polygon instanziiert.

Justin
quelle
4
Informationen zu Namenskonventionen finden Sie im Python-Styleguide (auch bekannt als PEP 8) .
blah238
0

Ich arbeite hauptsächlich in VB .net, benutze aber immer mehr Python und Arcpy. In VB mag ich und versuche, Enums zu verwenden, da es das Lesen des Codes klarer macht. Frühere Versionen von Python haben Aufzählungen nicht zu implementieren , so ein Hack eine Klasse auszusetzen einige Eigenschaften, eine Reihe von Beispielen zu schaffen , war auf diskutiert Stack - Überlauf . Es sieht nun aus wie die neueste Version von Python implementiert diese , die diskutiert wird hier .

Hornbydd
quelle