ArcView 3.x Avenue Bitmaps (Tabs?) Vs. ArcView 10 Python Cursors


9

Nota: sebbene questa domanda abbia una risposta, qualsiasi ulteriore consiglio per l'ottimizzazione di un processo del cursore sarebbe molto apprezzato. Monitorerò eventuali aggiornamenti.

Attualmente, il mio capo (che lavora in Avenue) e io (lavorando in Python) stiamo entrambi tentando di risolvere lo stesso problema. Piuttosto, l'abbiamo risolto entrambi, ma la velocità con cui operano le nostre soluzioni è ... a dir poco sconnessa. Ciò che il suo script elabora in 2 ore può portare il mio a 6. L'unica vera differenza nella sintassi e nell'implementazione nella logica viene dalle Bitmap 3.xe dai Cursori 10.x. Entrambi:

1) Memorizzare i valori dalla Tabella 1.
2) Utilizzare questi valori per eseguire una query su una riga nella Tabella 2.
3) Memorizzare i valori dalla Tabella 2 per l'inserimento nella Tabella 3 come nuova riga.

In entrambi gli script, questi processi sono completati in due cicli nidificati. Prima di iniziare a scavare nel meraviglioso mondo dell'ottimizzazione del codice, è questo un evento previsto quando si confrontano le prestazioni degli script Avenue con Python? Questa non è la prima volta che i suoi script superano notevolmente i miei in termini di tempo di operazione, quindi vorrei sapere se c'è qualcosa di cui dovrei essere consapevole prima di crocifiggermi per gli orribili script.

Ecco il mio script senza bit estranei:

import arcpy
import time
import sys
import os

def recordfindcopy(inFile,query,outFile):
    findRecord = arcpy.SearchCursor(inFile,query)
    for record in findRecord:
        copyRecord = arcpy.InsertCursor(outData) # <--- D'oh! (See answer)
        field = record.FIELD
        copy = copyRecord.newRow()
        copy.FIELD = field
        copyRecord.insertRow(copy)

StreetsFileList = [r"Path", 
                r"Path"]

for sfile in StreetsFileList:
    inStreets = sfile
    inTable = r"Path"
    outData = r"Path"
    fsaEntry = arcpy.SearchCursor(inTable)
    for row in fsaEntry:
        id = row.ID
        sQuery = "ID = %s " % (str(id))
        recordfindcopy(inStreets,sQuery,outData)

EDIT : Dato alcuni dei commenti finora, mi chiedo se potrebbe esserci un modo migliore per farlo tramite join, anche se sono dubbioso data la dimensione dei tavoli di brobdingnagian (parola del giorno!). Il cuore dell'elaborazione è aggiungere informazioni da una tabella a tutti i record corrispondenti in una seconda tabella e creare una terza tabella contenente solo i campi importanti. Volevo provare questo usando SDE, ma sembra non essere un'opzione disponibile. Pensieri? Mi scuso se le mie domande sono sempre così coinvolte , ma sto cercando di arrivare al fondo di una seccatura di vecchia data.

Risposta : il semplice suggerimento di Jakub da solo ha ridotto il tempo di elaborazione da 30 secondi per 500 record a 3 secondi per 500 record. Riavviare il cursore di inserimento su ogni inserimento ha rallentato notevolmente le cose (ovviamente). Anche se questo potrebbe non essere il massimo dell'ottimizzazione che si può fare per questo processo se confrontato con la velocità di ArcView 3.x, al momento è sufficiente per i miei scopi. Ulteriori suggerimenti sono molto graditi!


1
Vuoi pubblicare la tua sceneggiatura? Non conosco alcun avenue / python usando benchmark GP.
Derek Swingley,

I join e le query di tabella sono molto più veloci nel vecchio ArcView 3.2 (avenue) rispetto a qualsiasi ArcGIS da 8.xa 10. * arcpy / python. sostanzialmente a causa della quantità (molto di più) di codice nei prodotti ArcGIS.
Mapperz

2
@Mapperz Hai ragione. Tuttavia, l'elaborazione riga per riga in ArcView 3.x è tremendamente lenta a causa del sovraccarico interpretativo di 10.000X per ogni richiesta (ho analizzato questo parametro). Quando si possono evitare i loop - usando richieste "di alto livello" come join e query come si suggerisce - ArcView 3.x batterà i pantaloni da ArcGIS, ma è plausibile che in un test testa a testa che coinvolge loop espliciti sui record , uno dei due potrebbe vincere con un margine relativamente leggero.
whuber

@Whuber @Derek Thar essere.
Nathanus,

Risposte:


2

Non sono nuovo nella programmazione ma molto nuovo in Python, quindi prendilo con un pizzico di sale ...

copyRecord = arcpy.InsertCursor(outData)

Il cursore di inserimento non dovrebbe essere impostato prima del ciclo For Next? Mi sembra che se il percorso dei dati "out" è memorizzato nella variabile "outData", non è necessario ripristinarlo ogni volta che si esegue l'iterazione. Penserei che questo dovrebbe accelerare le cose in modo significativo.


Buona pesca. Ci proverò quando tornerò in ufficio la prossima settimana.
Nathanus,

5

Suppongo che stai usando ArcPy, o arcgisscripting circa 9.3. In entrambi i casi le tecniche qui accelereranno la tua elaborazione ... forse meglio dei tuoi capi.

La prima cosa da fare è cercare e gli inserimenti con qualsiasi mezzo diverso dalla memoria rallenteranno i processi. Avenue è ottimizzato per funzionare rapidamente e utilizza una base di codice C \ C ++ (correggimi se sbaglio) che è intrinsecamente più veloce in I / O rispetto alla maggior parte delle altre lingue. Anche Python è veloce (altrettanto rapido), tranne nel caso in cui ci siano sovraccarichi nell'aggancio alle librerie c per eseguire operazioni, come ArcPy o arcgisscripting.

Quindi prova prima questo:
1. Copia le tabelle che devi usare in memoria usando i metodi -

  • gp.CopyFeatures ("Path to featureclass \ FeatureclassName", "'in_memory' \ FeatureclassName") - per classi di caratteristiche e;
  • gp.CopyRow ("Path to featureclass \ FeatureTableName", "'in_memory' \ FeatureTableName") - per le tabelle in una classe o tabella di caratteristiche 'in_memory'.

    Ciò ti consentirà di utilizzare la memoria come il disco RAM e di risparmiare molto thrashing del disco. È inoltre possibile creare una classe di funzionalità o una tabella in memoria sostituendo il parametro FeatureDataset con 'in_memory'.

Usa il più possibile i contenitori Python. Ciò aumenterà anche la velocità.

Infine, l'ordine di efficienza nella lettura e scrittura delle informazioni per i formati ESRI è

  1. Shapefile (triste ma vero)
  2. Geodatabase personale
  3. File Geodatabase
  4. ArcSDE (anche con connessione diretta è più lento)

Prova questi suggerimenti, mentre sto cercando di compilare un elenco di cose che funzionano qui su gis.stackexchange.com, vedi qui


L'opzione di memoria sembra utile, ma la potenza combinata della tabella che sto interrogando contro gli orologi a quasi 1 GB. Credo di avere abbastanza RAM per renderlo possibile, ma le dimensioni del tavolo rischiano un incidente violento? Inoltre, cos'è un contenitore Python?
Nathanus,

Sono sorpreso che tu abbia posizionato gdb personale più velocemente del file gdb, in quanto ciò è stato invertito direttamente dalla mia esperienza. Sarebbe interessante esplorarlo da qualche parte / tempo.
matt wilkie,

Potrebbe essere il processo con cui sto attualmente lavorando, ma ho scoperto che un file gdb è più lento, ma solo giusto. Direi che sono alla pari, e sceglierei un file gdb su gdb personale a causa delle limitazioni dei file. Sono molto interessato a escogitare un punto di riferimento per questo. Sei interessato ad aiutarmi a definire alcuni test?
OptimizePrime,

Ho provato a mettere in memoria lo shapefile, e questo sembrava fare ben poco per aiutare ... anzi, lo script ha smesso di elaborare poco dopo.
Nathanus,

3

Scommetto che non è che Avenue è più veloce di Python, ma ArcView3 è più veloce di ArcGIS (in quello che stai cercando di fare).

Dal momento che dal suono di questo è essenzialmente un esercizio non spaziale, potresti voler sperimentare l'accesso diretto alle tabelle del database (ad es. Non usare arcpy) con qualcosa come dbfpy o odbc (non ho provato nessuno dei due). Personalmente ho trovato la linea di comando ogr2ogr della suite gdal / ogr per essere ordini di grandezza più veloci delle transazioni equivalenti in arcgis. Tuttavia, ho approfondito leggermente le capacità di query OGR e non ho creato nulla utilizzando solo i binding di Python, quindi non so se la velocità continui.


L'unico problema qui è che sto aggiungendo dati non spaziali a dati spaziali. IE Sto prendendo il Shapecampo insieme ad alcuni altri e creando un nuovo record che conterrà la geometria e i dati non spaziali aggiuntivi. Dpfpy e odbc spiegheranno i Shapescampi in movimento (e la loro geometria)?
Nathanus,

Non funzionerebbe con gli shapefile poiché Shapenon è archiviato nel file .dbf. Teoricamente potrebbe funzionare con un geodatabase personale (.mdb) usando odbc ma sono diffidente di questo approccio, soprattutto perché esiste già un percorso collaudato con OGR, che conosce già sia shapefile che gdb personale.
matt wilkie,

1

Questa non è una risposta particolarmente utile al momento, ma aspetta ArcGIS 10.1. Al summit esri dev di quest'anno ci è stato detto che il supporto del cursore arcpy 10.1 è stato completamente riscritto ed è significativamente più veloce. Durante la plenaria si è registrata una richiesta di miglioramenti della velocità di circa 8 volte.


Grazie per l'informazione. Qualcosa da guardare al futuro, se non altro.
Nathanus,
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.