C'è una differenza tra gli algoritmi di riempimento della depressione Planchon & Darboux e Wang e Liu? Altro che velocità?


11

Qualcuno può dirmi, sulla base dell'esperienza analitica effettiva, se c'è una differenza tra questi due algoritmi di riempimento della depressione, oltre alla velocità con cui elaborano e riempiono le depressioni (pozzi) nei DEM?

Un algoritmo veloce, semplice e versatile per colmare le depressioni dei modelli digitali di elevazione

Olivier Planchon, Frederic Darboux

e

Un metodo efficiente per identificare e riempire le depressioni superficiali nei modelli digitali di elevazione per analisi e modellistica idrologiche

Wang e Liu

Grazie.

Risposte:


12

Da un punto di vista teorico il riempimento della depressione ha una sola soluzione, sebbene possano esserci numerosi modi per arrivare a quella soluzione, motivo per cui ci sono così tanti diversi algoritmi di riempimento della depressione. Pertanto, teoricamente un DEM che viene riempito con Planchon e Darboux o Wang e Liu, o con qualsiasi altro algoritmo di riempimento della depressione, dovrebbe apparire identico in seguito. È probabile che non lo facciano e ci sono alcuni motivi per cui. In primo luogo, mentre esiste solo una soluzione per riempire una depressione, ci sono molte diverse soluzioni per applicare un gradiente sulla superficie piana della depressione riempita. Cioè, di solito non vogliamo solo riempire una depressione, ma vogliamo anche forzare il flusso sulla superficie della depressione riempita. Ciò di solito comporta l'aggiunta di gradienti molto piccoli e 1) ci sono molte strategie diverse per farlo (molte delle quali sono integrate direttamente nei vari algoritmi di riempimento della depressione) e 2) trattare con numeri così piccoli spesso porta a piccoli errori di arrotondamento che possono manifestarsi in differenze tra i DEM compilati. Dai un'occhiata a questa immagine:

Differenze di elevazione nei DEM compilati

Mostra la "DEM di differenza" tra due DEM, entrambi generati dal DEM sorgente ma uno con depressioni riempite usando l'algoritmo Planchon e Darboux e l'altro con l'algoritmo Wang e Liu. Dovrei dire che gli algoritmi di riempimento della depressione erano entrambi strumenti all'interno del GAT di Whitebox e sono quindi implementazioni diverse degli algoritmi rispetto a quanto descritto nella risposta sopra. Si noti che le differenze nei DEM sono tutte inferiori a 0,008 m e che sono interamente contenute all'interno delle aree delle depressioni topografiche (vale a dire che le celle della griglia che non sono all'interno delle depressioni hanno esattamente gli stessi aumenti del DEM di input). Il piccolo valore di 8 mm riflette il minuscolo valore utilizzato per imporre il flusso sulle superfici piane lasciate indietro dall'operazione di riempimento ed è anche probabilmente influenzato dalla scala degli errori di arrotondamento quando si rappresentano numeri così piccoli con valori in virgola mobile. Non puoi vedere i due DEM pieni visualizzati nell'immagine sopra, ma dalla voce della legenda puoi dire che hanno anche lo stesso intervallo di valori di elevazione, come ti aspetteresti.

Quindi, perché dovresti osservare le differenze di elevazione lungo picchi e altre aree di non depressione nella DEM nella tua risposta sopra? Penso che potrebbe davvero dipendere solo dalla specifica implementazione dell'algoritmo. È probabile che stia succedendo qualcosa all'interno dello strumento per tenere conto di tali differenze ed è estraneo all'algoritmo reale. Ciò non è così sorprendente per me, dato il divario tra la descrizione di un algoritmo in un documento accademico e la sua effettiva attuazione combinata con la complessità di come i dati vengono gestiti internamente all'interno di GIS. Comunque, grazie per aver posto questa domanda molto interessante.

Saluti,

John


Grazie mille John !!! Informativo come sempre. Ora capisco finalmente la differenza importante tra il semplice riempimento di una depressione e l'applicazione di una pendenza minima per garantire il flusso. Prima stavo coagulando quelle due idee. Voglio che tu sappia che ho provato a usare Whitebox per questa analisi, ma ho continuato a imbattermi nell'errore relativo ai valori NoData che allineavano il limite dello spartiacque durante l'esecuzione del riempimento Planchon e Darboux - So che la correzione sta arrivando. Hai eseguito questa analisi su un DEM quadrato per evitarlo? Grazie ancora.
traggatmot,

1
+1 È un piacere leggere una risposta informativa, ponderata e ben informata come questa.
whuber

5

Tenterò di rispondere alla mia domanda: dun dun dun.

Ho usato SAGA GIS per esaminare le differenze nei bacini idrografici riempiti usando il loro strumento di riempimento basato su Planchon e Darboux (PD) (e il loro strumento di riempimento basato su Wang e Liu (WL) per 6 diversi bacini idrografici. (Qui mostro solo due casi di risultati - erano simili in tutti e 6 i bacini idrici) dico "basato", perché c'è sempre la domanda se le differenze siano dovute all'algoritmo o all'implementazione specifica dell'algoritmo.

I DEM di spartiacque sono stati generati ritagliando i dati NED a mosaico di 30 m utilizzando USGS forniti shapefile spartiacque. Per ogni DEM di base sono stati eseguiti i due strumenti; esiste solo un'opzione per ogni strumento, la pendenza minima forzata, impostata in entrambi gli strumenti su 0,01.

Dopo aver riempito i bacini idrografici, ho usato il calcolatore raster per determinare le differenze nelle griglie risultanti - queste differenze dovrebbero essere dovute solo ai diversi comportamenti dei due algoritmi.

Le immagini che rappresentano le differenze o la mancanza di differenze (sostanzialmente il raster delle differenze calcolate) sono presentate di seguito. La formula utilizzata nel calcolo delle differenze era: (((PD_Filled - WL_Filled) / PD_Filled) * 100) - indica la differenza percentuale su una cella per cella. Le celle di colore grigio mostrano ora una differenza, con celle di colore più rosso che indicano che l'elevazione PD risultante era maggiore e celle di colore più verde che indica l'elevazione WL risultante era maggiore.

1st Watershed: Clear Watershed, Wyoming inserisci qui la descrizione dell'immagine

Ecco la leggenda di queste immagini:

inserisci qui la descrizione dell'immagine

Le differenze vanno solo da -0,0915% a + 0,0910%. Le differenze sembrano concentrarsi su picchi e canali a flusso stretto, con l'algoritmo WL leggermente più alto nei canali e PD leggermente più alto attorno ai picchi localizzati.

Clear Watershed, Wyoming, Zoom 1 inserisci qui la descrizione dell'immagine

Clear Watershed, Wyoming, Zoom 2 inserisci qui la descrizione dell'immagine

2 ° spartiacque: fiume Winnipesaukee, NH

inserisci qui la descrizione dell'immagine

Ecco la leggenda di queste immagini:

inserisci qui la descrizione dell'immagine

Winnipesaukee River, NH, Zoom 1

inserisci qui la descrizione dell'immagine

Le differenze vanno solo da -0,323% a + 0,315%. Le differenze sembrano concentrarsi su picchi e canali a flusso stretto, con (come prima) l'algoritmo WL leggermente più alto nei canali e PD leggermente più alto attorno ai picchi localizzati.

Sooooooo, pensieri? A mio avviso, le differenze sembrano insignificanti e probabilmente non influenzeranno ulteriori calcoli; qualcuno è d'accordo? Sto verificando completando il mio flusso di lavoro per questi sei bacini idrografici.

Modifica: ulteriori informazioni. Sembra che l'algoritmo WL porti a canali più ampi e meno distinti, causando alti valori dell'indice topografico (il mio set di dati derivato finale). L'immagine a sinistra in basso è l'algoritmo PD, l'immagine a destra è l'algoritmo WL.

inserisci qui la descrizione dell'immagine

Queste immagini mostrano la differenza nell'indice topografico nelle stesse posizioni - aree più bagnate più ampie (più canale - più rosso, TI più alto) nella foto WL a destra; canali più stretti (meno area bagnata - meno rosso, area rossa più stretta, TI inferiore nell'area) nella foto PD a sinistra.

inserisci qui la descrizione dell'immagine

Inoltre, ecco come PD ha gestito (a sinistra) una depressione e come WL l'ha gestita (a destra) - nota il segmento / linea arancione sollevato (indice topografico inferiore) che attraversa la depressione nell'output riempito di WL?

inserisci qui la descrizione dell'immagine

Quindi le differenze, per quanto piccole, sembrano scorrere attraverso le analisi aggiuntive.

Ecco il mio script Python se qualcuno è interessato:

#! /usr/bin/env python

# ----------------------------------------------------------------------
# Create Fill Algorithm Comparison
# Author: T. Taggart
# ----------------------------------------------------------------------

import os, sys, subprocess, time



# function definitions
def runCommand_logged (cmd, logstd, logerr):
    p = subprocess.call(cmd, stdout=logstd, stderr=logerr)
# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# environmental variables/paths
if (os.name == "posix"):
    os.environ["PATH"] += os.pathsep + "/usr/local/bin"
else:
    os.environ["PATH"] += os.pathsep + "C:\program files (x86)\SAGA-GIS"
# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# global variables

WORKDIR    = "D:\TomTaggart\DepressionFillingTest\Ran_DEMs"

# This directory is the toplevel directoru (i.e. DEM_8)
INPUTDIR   = "D:\TomTaggart\DepressionFillingTest\Ran_DEMs"

STDLOG     = WORKDIR + os.sep + "processing.log"
ERRLOG     = WORKDIR + os.sep + "processing.error.log"
# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# open logfiles (append in case files are already existing)
logstd = open(STDLOG, "a")
logerr = open(ERRLOG, "a")
# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# initialize
t0      = time.time()
# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# loop over files, import them and calculate TWI

# this for loops walks through and identifies all the folder, sub folders, and so on.....and all the files, in the directory
# location that is passed to it - in this case the INPUTDIR
for dirname, dirnames, filenames in os.walk(INPUTDIR):
    # print path to all subdirectories first.
    #for subdirname in dirnames:
        #print os.path.join(dirname, subdirname)

    # print path to all filenames.
    for filename in filenames:
        #print os.path.join(dirname, filename)
        filename_front, fileext = os.path.splitext(filename)
        #print filename
        if filename_front == "w001001":
        #if fileext == ".adf":


            # Resetting the working directory to the current directory
            os.chdir(dirname)

            # Outputting the working directory
            print "\n\nCurrently in Directory: " + os.getcwd()

            # Creating new Outputs directory
            os.mkdir("Outputs")

            # Checks
            #print dirname + os.sep + filename_front
            #print dirname + os.sep + "Outputs" + os.sep + ".sgrd"

            # IMPORTING Files
            # --------------------------------------------------------------
            cmd = ['saga_cmd', '-f=q', 'io_gdal', 'GDAL: Import Raster',
                   '-FILES', filename,
                   '-GRIDS', dirname + os.sep + "Outputs" + os.sep + filename_front + ".sgrd",
                   #'-SELECT', '1',
                   '-TRANSFORM',
                   '-INTERPOL', '1'
                  ]

            print "Beginning to Import Files"

            try:
                runCommand_logged(cmd, logstd, logerr)

            except Exception, e:
                logerr.write("Exception thrown while processing file: " + filename + "\n")
                logerr.write("ERROR: %s\n" % e)

            print "Finished importing Files"

            # --------------------------------------------------------------


            # Resetting the working directory to the ouputs directory
            os.chdir(dirname + os.sep + "Outputs")



            # Depression Filling - Wang & Liu
            # --------------------------------------------------------------
            cmd = ['saga_cmd', '-f=q', 'ta_preprocessor', 'Fill Sinks (Wang & Liu)',
                   '-ELEV', filename_front + ".sgrd",
                   '-FILLED',  filename_front + "_WL_filled.sgrd",  # output - NOT optional grid
                   '-FDIR', filename_front + "_WL_filled_Dir.sgrd",  # output - NOT optional grid
                   '-WSHED', filename_front + "_WL_filled_Wshed.sgrd",  # output - NOT optional grid
                   '-MINSLOPE', '0.0100000', 
                               ]

            print "Beginning Depression Filling - Wang & Liu"

            try:
                runCommand_logged(cmd, logstd, logerr)

            except Exception, e:
                logerr.write("Exception thrown while processing file: " + filename + "\n")
                logerr.write("ERROR: %s\n" % e)

            print "Done Depression Filling - Wang & Liu"


            # Depression Filling - Planchon & Darboux
            # --------------------------------------------------------------
            cmd = ['saga_cmd', '-f=q', 'ta_preprocessor', 'Fill Sinks (Planchon/Darboux, 2001)',
                   '-DEM', filename_front + ".sgrd",
                   '-RESULT',  filename_front + "_PD_filled.sgrd",  # output - NOT optional grid
                   '-MINSLOPE', '0.0100000',
                               ]

            print "Beginning Depression Filling - Planchon & Darboux"

            try:
                runCommand_logged(cmd, logstd, logerr)

            except Exception, e:
                logerr.write("Exception thrown while processing file: " + filename + "\n")
                logerr.write("ERROR: %s\n" % e)

            print "Done Depression Filling - Planchon & Darboux"

            # Raster Calculator - DIff between Planchon & Darboux and Wang & Liu
            # --------------------------------------------------------------
            cmd = ['saga_cmd', '-f=q', 'grid_calculus', 'Grid Calculator',
                   '-GRIDS', filename_front + "_PD_filled.sgrd",
                   '-XGRIDS', filename_front + "_WL_filled.sgrd",
                   '-RESULT',  filename_front + "_DepFillDiff.sgrd",      # output - NOT optional grid
                   '-FORMULA', "(((g1-h1)/g1)*100)",
                   '-NAME', 'Calculation',
                   '-FNAME',
                   '-TYPE', '8',
                               ]

            print "Depression Filling - Diff Calc"

            try:
                runCommand_logged(cmd, logstd, logerr)

            except Exception, e:
                logerr.write("Exception thrown while processing file: " + filename + "\n")
                logerr.write("ERROR: %s\n" % e)

            print "Done Depression Filling - Diff Calc"

# ----------------------------------------------------------------------


# ----------------------------------------------------------------------
# finalize
logstd.write("\n\nProcessing finished in " + str(int(time.time() - t0)) + " seconds.\n")
logstd.close
logerr.close

# ----------------------------------------------------------------------

Hai contattato i manutentori SAGA in merito a questo problema?
reima,

3

A livello algoritmico, i due algoritmi produrranno gli stessi risultati.

Perché potresti riscontrare differenze?

Rappresentazione dei dati

Se uno dei tuoi algoritmi utilizza float(32 bit) e un altro utilizza double(64 bit), non dovresti aspettarti che producano lo stesso risultato. Allo stesso modo, alcune implementazioni rappresentano valori in virgola mobile che utilizzano tipi di dati interi, che possono anche comportare differenze.

Applicazione di drenaggio

Tuttavia, entrambi gli algoritmi produrranno aree piatte che non si esauriranno se si utilizza un metodo localizzato per determinare le direzioni del flusso.

Planchon e Darboux affrontano questo problema aggiungendo un piccolo incremento all'altezza dell'area piatta per imporre il drenaggio. Come discusso in Barnes et al. (2014) "Un'assegnazione efficiente della direzione del drenaggio su superfici piane nei modelli di elevazione digitale raster" l'aggiunta di questo incremento può effettivamente far deviare innaturalmente il drenaggio al di fuori di un'area piana se l'incremento è troppo grande. Una soluzione è utilizzare, ad esempio, la nextafterfunzione.

Altri pensieri

Wang e Liu (2006) è una variante dell'algoritmo Priority-Flood, come discusso nel mio documento "Priority-flood: un algoritmo ottimale di riempimento della depressione e di spartiacque per i modelli di elevazione digitale" .

Priority-Flood presenta complessità temporali sia per i dati interi sia per i dati in virgola mobile. Nel mio documento, ho notato che evitare di posizionare le celle nella coda prioritaria era un buon modo per aumentare le prestazioni dell'algoritmo. Altri autori come Zhou et al. (2016) e Wei et al. (2018) hanno utilizzato questa idea per aumentare ulteriormente l'efficienza dell'algoritmo. Il codice sorgente per tutti questi algoritmi è disponibile qui .

Con questo in mente, l'algoritmo Planchon e Darboux (2001) è la storia di un luogo in cui la scienza ha fallito. Mentre Priority-Flood funziona nel tempo O (N) sui dati interi e nel tempo O (N log N) sui dati in virgola mobile, P&D funziona nel tempo O (N 1.5 ). Ciò si traduce in un'enorme differenza di prestazioni che cresce esponenzialmente con la dimensione del DEM:

Jenson e Domingue contro Planchon e Darboux contro Wang e Liu per il riempimento della depressione da priorità-alluvione

Nel 2001, Ehlschlaeger, Vincent, Soille, Beucher, Meyer e Gratin avevano pubblicato collettivamente cinque articoli che descrivevano l'algoritmo Priority-Flood. Planchon e Darboux, e i loro recensori, persero tutto questo e inventarono un algoritmo che era più lento degli ordini di grandezza. È ora il 2018 e stiamo ancora costruendo algoritmi migliori, ma P&D è ancora in uso. Penso sia sfortunato.

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.