In che modo le persone utilizzano le strutture e le classi di dati Python in ArcPy?


16

Questa domanda può esporre la mia ignoranza sulla programmazione, ma sono curioso di sapere come le persone utilizzano diverse strutture di dati Python in ArcPy.

Questa pagina elenca le strutture di dati in Python. Comprendo come gli elenchi possono essere implementati in GIS (elenco di classi di funzionalità, elenco di tipi di funzionalità, elenco di frame di dati, ecc.). Capisco anche come utilizzare i set (per rimuovere i duplicati). In che modo le persone implementano tuple, dizionari e altre strutture di dati all'interno di ArcPy? Inoltre, ci sono altri esempi di elenchi e set che non ho elencato?

Inoltre, senza dubbio, le persone stanno creando classi personalizzate in ArcPy. In quali circostanze e situazioni sono necessarie? Potete fornire esempi? Qualcuno sta creando classi personalizzate che ereditano dalle classi arcpy integrate?

Non ho bisogno di risposte a tutte queste domande, sono solo curioso di sapere come le persone usano Python in GIS e quali flussi di lavoro richiedono queste personalizzazioni.


4
Domanda interessante ma questa non ha una risposta definitiva. Dovrebbe essere un wiki della comunità.
RK,

Risposte:


14

Molte funzioni arcpy che accettano più input accettano oggetti dell'elenco Python.

Ad esempio la Dissolve_managementfunzione accetta un elenco di nomi di campo su cui dissolversi:

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

Una tupla può essere utilizzata al posto di un elenco quando non è necessario modificare l'ordine o il numero di elementi, poiché le tuple sono immutabili . Sono una struttura dati utile per dati eterogenei ma correlati, come gli elementi di un timestamp o le coordinate di un punto. Vedrai spesso elenchi di tuple, in cui una tupla funge da record distinto con un numero fisso di attributi, mentre l'elenco potrebbe facilmente cambiare dimensione, essere riordinato (ordinato), ecc. Vedi questa domanda StackOverflow per ulteriori informazioni sugli usi di liste contro tuple.

Un dizionario può essere utilizzato come tabella di ricerca rapida per memorizzare nella cache un insieme relativamente piccolo ma di uso frequente di coppie chiave-valore. Ho visto un esempio interessante di questo sui forum ArcGIS: http://forums.arcgis.com/threads/55099-Update-cursor-with-joined-tables-work-around-w-dictionaries

Il loro uso di un dizionario anziché di un join ha velocizzato il calcolo da 3,5 ore a 15 minuti.

Un esempio più semplice potrebbe essere se si dispone di un milione di record di indirizzi con un attributo con il nome dello stato abbreviato (CA), ma per scopi di visualizzazione si desidera precisare il nome proprio (California), è possibile utilizzare questo dizionario come tabella di ricerca quando compilando un campo nome completo.

Non ho trovato la necessità di scrivere una classe in Python per l'uso in arcpy, ma questo non vuol dire che non esiste un caso d'uso. Una classe potrebbe essere utile quando si dispone di un insieme di funzioni (comportamenti) strettamente correlate che operano su alcuni input (dati) e si desidera poter utilizzare tali dati e comportamenti in modo orientato agli oggetti, ma questo è più probabilmente sarà specifico per la logica aziendale e non correlato all'arcpia.


7

Blah238 tratta bene questo argomento, quindi aggiungerò solo un paio di esempi dal mio lavoro. Sviluppo molti dati aeroportuali e una delle cose che devo fare regolarmente è leggere in ordine lungo i punti della linea centrale della pista esaminata da una pista. Penseresti che questi punti sarebbero già in ordine (nel database GIS), ma raramente lo sono. I punti della linea centrale si verificano ogni 10 piedi lungo la linea centrale e sono fiancheggiati su entrambi i lati da altre due file di punti di rilevamento distanziati di 10 piedi. Ottieni l'immagine: una miriade di punti ... e di solito tutti mescolati insieme in termini di database. Con quello che sto facendo nei miei script, di solito è più semplice selezionare i punti della linea centrale per attributi (o spazialmente se necessario), leggere le coordinate per ciascuno e scaricare i risultati in un elenco Python. Posso quindi ordinare, pop, reverse, ecc.

Allo stesso modo, uso ampiamente i dizionari Python (probabilmente molto più di quanto alcuni approverebbero). Devo creare set di vettori di unità 3D per ciascuna estremità della pista di un aeroporto e accedervi costantemente all'interno di uno script e farlo in molti dei miei script. Conservo anche molti altri set di dati a cui si accede regolarmente nei dizionari. Come le liste, sono veloci e flessibili. Altamente raccomandato.

Per quanto riguarda le lezioni, come Blah238, non ho trovato la necessità di crearne una. Probabilmente ci sono alcuni casi in cui una classe sarebbe preferita nei miei script, ma in realtà non sono stato in grado di identificare quei posti. Qualcuno con più esperienza di programmazione probabilmente li troverà rapidamente.


5

Anch'io adoro i dizionari: usali sempre. Questo metodo ottiene alcune proprietà di riferimento spaziale e memorizza tutto in un dict:

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

Questo frammento di metodo estrae le geometrie dei punti da due bicchieri di vetro, quindi uso le geometrie in seguito per eseguire alcuni trig:

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

MOLTO di ciò su cui sto attualmente lavorando riguarda l'estrazione di coordinate e attributi da classi di caratteristiche vettoriali e raster in modo che i dati possano essere inseriti in un altro software che non sa nemmeno quali siano i dati GIS. Quindi, uso molto elenchi e dizionari per questo.


Grazie per la risposta. Perché un dizionario è una scelta migliore di un'altra struttura di dati in questi casi?
Fezter

Mi piace solo essere in grado di chiamare i miei valori con le mie chiavi.
Chad Cooper,

2
un altro motivo per cui i dicts possono essere preferibili è perché sono letti molto più velocemente degli elenchi perché non sono ordinati. pertanto, l'elaborazione di elenchi molto lunghi potrebbe richiedere un po 'più di tempo se contengono molte voci.
ndimhypervol,

@gotanuki Vero, e se hai bisogno di usare una grande lista, usa invece una tupla, poiché sono anche più veloci delle liste.
Chad Cooper,

2

Leggere questo mentre mettendo insieme una risposta e ha dovuto fare alcune modifiche ..

Non sono un esperto di Python, ma penso che l'idea alla base dell'utilizzo delle classi sia che è possibile creare un'istanza di un oggetto che ha un sacco di metodi pronti all'uso che si riferiscono alla struttura dei dati e alla centralizzazione dei metodi. Ci sono anche alcuni vantaggi di portata variabile con classi vs moduli, il link sopra arriva a questo punto in qualche modo.

Ho un corso chiamato featureLayer (probabilmente non chiamato pitone ... sto ancora imparando). posso fare

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)

La definizione per fare questo è un metodo di classe che itera semplicemente le caratteristiche, le parti e i vertici. Quindi posso trasformare il mio oggetto points in un'istanza featureLayer e fare altre cose della mia classe.

Penso che se le classi costruite correttamente dovrebbero incapusare la funzionalità. Ad esempio, presto inizierò il refactoring in modo da avere una classe featureLayer che abbia metodi e attributi che hanno tutti i feature layer. Quindi eredita da esso per creare un'istanza della classe featureLayerStrict che erediterà tutti gli attributi / metodi featureLayers ma creerà un'istanza con un tipo di geometria specifico come il poligono.


4
Consulta la guida allo stile di Python (aka PEP 8) per le convenzioni di denominazione.
blah238,

0

Lavoro principalmente in VB .net ma mi trovo sempre più ad usare Python e Arcpy. In VB mi piace e cerco di usare Enums in quanto rende più chiara la lettura del codice. Le versioni precedenti di Python non implementavano Enum, quindi un trucco consisteva nel creare una Classe che esponesse alcune proprietà, un mucchio di esempi sono discussi su Stack Overflow . Ora sembra che l'ultima versione di Python implementa questi, che è discussa qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.