Có sự khác biệt giữa thuật toán lấp đầy trầm cảm Planchon & Darboux và Wang và Liu không? Khác với tốc độ?


11

Ai đó có thể cho tôi biết, dựa trên kinh nghiệm phân tích thực tế, nếu có sự khác biệt giữa hai thuật toán lấp đầy trầm cảm này, ngoài tốc độ chúng xử lý và lấp đầy các vết lõm (chìm) trong DEM không?

Một thuật toán nhanh, đơn giản và linh hoạt để lấp đầy sự suy giảm của các mô hình độ cao kỹ thuật số

Olivier Planchon, Frederic Darboux

Một phương pháp hiệu quả để xác định và lấp đầy áp suất bề mặt trong các mô hình độ cao kỹ thuật số để phân tích và mô hình thủy văn

Vương và Lưu

Cảm ơn.

Câu trả lời:


12

Từ quan điểm lý thuyết, việc lấp đầy trầm cảm chỉ có một giải pháp, mặc dù có thể có nhiều cách để đi đến giải pháp đó, đó là lý do tại sao có rất nhiều thuật toán lấp đầy trầm cảm khác nhau. Do đó, về mặt lý thuyết, một DEM chứa đầy Planchon và Darboux hoặc Wang và Liu, hoặc bất kỳ thuật toán lấp đầy trầm cảm nào khác, sẽ trông giống hệt nhau sau đó. Tuy nhiên, có vẻ như họ sẽ không và có một vài lý do tại sao. Đầu tiên, trong khi chỉ có một giải pháp để lấp đầy trầm cảm, có nhiều giải pháp khác nhau để áp dụng một gradient trên bề mặt phẳng của trầm cảm được lấp đầy. Đó là, thông thường chúng ta không chỉ muốn lấp đầy trầm cảm, mà chúng ta cũng muốn buộc dòng chảy trên bề mặt của trầm cảm đầy. Điều đó thường liên quan đến việc thêm độ dốc rất nhỏ và 1) có rất nhiều chiến lược khác nhau để thực hiện điều này (nhiều trong số đó được tích hợp trực tiếp vào các thuật toán lấp đầy trầm cảm khác nhau) và 2) xử lý các số nhỏ như vậy thường dẫn đến các lỗi làm tròn nhỏ có thể gây ra các lỗi làm tròn nhỏ được biểu hiện trong sự khác biệt giữa các DEM đầy. Hãy nhìn vào hình ảnh này:

Sự khác biệt về độ cao trong các DEM đầy

Nó cho thấy 'DEM của sự khác biệt' giữa hai DEM, cả hai được tạo ra từ DEM nguồn nhưng một với các áp lực được lấp đầy bằng thuật toán Planchon và Darboux và cái còn lại với thuật toán Wang và Liu. Tôi nên nói rằng các thuật toán lấp đầy trầm cảm là cả hai công cụ từ Whitebox GAT và do đó là các triển khai thuật toán khác nhau so với những gì bạn mô tả trong câu trả lời của bạn ở trên. Lưu ý rằng sự khác biệt trong các DEM đều nhỏ hơn 0,008 m và chúng hoàn toàn được chứa trong các khu vực áp thấp địa hình (tức là các ô lưới không nằm trong vùng áp thấp có độ cao chính xác như DEM đầu vào). Giá trị nhỏ 8 mm phản ánh giá trị nhỏ được sử dụng để thực thi dòng chảy trên các bề mặt phẳng bị bỏ lại sau thao tác điền và cũng có khả năng bị ảnh hưởng phần nào bởi thang đo các lỗi làm tròn khi biểu thị các số nhỏ như vậy với các giá trị dấu phẩy động. Bạn không thể thấy hai DEM đầy được hiển thị trong hình trên, nhưng bạn có thể nói từ các mục chú thích của chúng rằng chúng cũng có cùng một phạm vi giá trị độ cao, như bạn mong đợi.

Vì vậy, tại sao bạn sẽ quan sát sự khác biệt độ cao dọc theo các đỉnh và các khu vực không trầm cảm khác trong DEM trong câu trả lời của bạn ở trên? Tôi nghĩ rằng nó thực sự chỉ có thể đi xuống để thực hiện cụ thể của thuật toán. Có khả năng một cái gì đó đang diễn ra bên trong công cụ để giải thích cho những khác biệt đó và nó không liên quan đến thuật toán thực tế. Điều này không gây ngạc nhiên cho tôi khi đưa ra khoảng cách giữa mô tả thuật toán trong một bài báo học thuật và việc triển khai thực tế của nó kết hợp với sự phức tạp của cách dữ liệu được xử lý bên trong GIS. Nhưng dù sao, cảm ơn vì đã hỏi câu hỏi rất thú vị này.

Chúc mừng

John


Cảm ơn rất nhiều John !!! Thông tin như mọi khi. Bây giờ tôi cuối cùng cũng hiểu được sự khác biệt quan trọng giữa việc đơn giản là lấp đầy một chỗ trũng và thực thi một độ dốc tối thiểu để đảm bảo dòng chảy. Tôi đã lên án hai ý tưởng đó trước đây. Tôi muốn bạn biết rằng tôi đã cố gắng sử dụng Whitebox cho phân tích này, nhưng tôi vẫn gặp phải lỗi liên quan đến các giá trị NoData nằm trong ranh giới đầu nguồn khi chạy Planchon và Darboux - Tôi biết rằng bản sửa lỗi đang đến. Bạn đã thực hiện phân tích này trên một DEM vuông để tránh điều đó? Cảm ơn một lần nữa.
traggatmot

1
+1 Rất vui được đọc một câu trả lời nhiều thông tin, chu đáo, có hiểu biết như câu trả lời này.
whuber

5

Tôi sẽ cố gắng trả lời câu hỏi của riêng tôi - dun dun dun.

Tôi đã sử dụng SAGA GIS để kiểm tra sự khác biệt trong các lưu vực được lấp đầy bằng cách sử dụng công cụ làm đầy dựa trên Planchon và Darboux (PD) của họ (và công cụ làm đầy dựa trên Wang và Liu (WL) của họ cho 6 lưu vực khác nhau (Ở đây tôi chỉ trình bày trường hợp hai bộ kết quả - chúng giống nhau trên tất cả 6 lưu vực sông) Tôi nói "dựa", bởi vì luôn có câu hỏi là liệu sự khác biệt là do thuật toán hoặc việc thực hiện cụ thể của thuật toán.

Các DEM đầu nguồn được tạo ra bằng cách cắt dữ liệu NED 30 m được khảm bằng USGS được cung cấp các shapefile đầu nguồn. Đối với mỗi DEM cơ sở, hai công cụ đã được chạy; chỉ có một tùy chọn cho mỗi công cụ, độ dốc được thi hành tối thiểu, được đặt trong cả hai công cụ là 0,01.

Sau khi các lưu vực được lấp đầy, tôi đã sử dụng máy tính raster để xác định sự khác biệt trong các lưới kết quả - những khác biệt này chỉ nên do các hành vi khác nhau của hai thuật toán.

Hình ảnh đại diện cho sự khác biệt hoặc thiếu khác biệt (về cơ bản là raster chênh lệch được tính toán) được trình bày dưới đây. Công thức được sử dụng để tính toán sự khác biệt là: (((PD_Fills - WL_Fills) / PD_Fills) * 100) - đưa ra mức chênh lệch phần trăm trên một ô theo cơ sở tế bào. Các ô màu xám hiện có sự khác biệt, với các ô có màu đỏ hơn biểu thị độ cao PD kết quả là lớn hơn và các ô màu xanh hơn cho thấy độ cao của kết quả là lớn hơn.

Đầu nguồn thứ 1: Đầu nguồn rõ ràng, bang Utah nhập mô tả hình ảnh ở đây

Đây là huyền thoại cho những hình ảnh này:

nhập mô tả hình ảnh ở đây

Sự khác biệt chỉ nằm trong khoảng từ -0,0915% đến + 0,0910%. Sự khác biệt dường như được tập trung xung quanh các đỉnh và các kênh luồng hẹp, với thuật toán WL cao hơn một chút trong các kênh và PD cao hơn một chút xung quanh các đỉnh cục bộ.

Đầu nguồn rõ ràng, bang Utah, Zoom 1 nhập mô tả hình ảnh ở đây

Đầu nguồn rõ ràng, bang Utah, Zoom 2 nhập mô tả hình ảnh ở đây

Lưu vực thứ 2: Sông Winnipes Bolog, NH

nhập mô tả hình ảnh ở đây

Đây là huyền thoại cho những hình ảnh này:

nhập mô tả hình ảnh ở đây

Winnipes Bolog River, NH, Zoom 1

nhập mô tả hình ảnh ở đây

Sự khác biệt chỉ nằm trong khoảng từ -0.323% đến + 0.315%. Sự khác biệt dường như được tập trung xung quanh các đỉnh và các kênh luồng hẹp, với (như trước) thuật toán WL cao hơn một chút trong các kênh và PD cao hơn một chút xung quanh các đỉnh cục bộ.

Sooooooo, suy nghĩ? Đối với tôi, sự khác biệt có vẻ tầm thường có lẽ không ảnh hưởng đến các tính toán tiếp theo; có ai đồng ý không Tôi đang kiểm tra bằng cách hoàn thành quy trình làm việc của mình cho sáu lưu vực sông này.

Chỉnh sửa: Thêm thông tin. Dường như thuật toán WL dẫn đến các kênh ít khác biệt hơn, gây ra các giá trị chỉ số địa hình cao (bộ dữ liệu phái sinh cuối cùng của tôi). Hình ảnh bên trái là thuật toán PD, hình ảnh bên phải là thuật toán WL.

nhập mô tả hình ảnh ở đây

Những hình ảnh này cho thấy sự khác biệt về chỉ số địa hình tại cùng một vị trí - các khu vực ẩm ướt rộng hơn (nhiều kênh hơn - đỏ hơn, TI cao hơn) trong ảnh WL ở bên phải; các kênh hẹp hơn (khu vực ít ướt hơn - ít màu đỏ hơn, khu vực màu đỏ hẹp hơn, diện tích TI thấp hơn) trong ảnh PD bên trái.

nhập mô tả hình ảnh ở đây

Ngoài ra, đây là cách PD xử lý (trái) trầm cảm và cách xử lý WL (phải) - chú ý phân đoạn / đường màu cam (chỉ số địa hình thấp hơn) vượt qua suy thoái trong đầu ra được lấp đầy WL?

nhập mô tả hình ảnh ở đây

Vì vậy, sự khác biệt, tuy nhỏ, dường như nhỏ giọt qua các phân tích bổ sung.

Đây là kịch bản Python của tôi nếu có ai quan tâm:

#! /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

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

Bạn đã liên hệ với những người bảo trì SAGA về vấn đề này?
reima

3

Ở cấp độ thuật toán, hai thuật toán sẽ tạo ra kết quả như nhau.

Tại sao bạn có thể nhận được sự khác biệt?

Sự miêu tả dữ liệu

Nếu một trong các thuật toán của bạn sử dụng float(32 bit) và sử dụng thuật toán khác double(64 bit), bạn không nên mong đợi chúng tạo ra kết quả tương tự. Tương tự, một số triển khai biểu thị các giá trị dấu phẩy động sử dụng các kiểu dữ liệu số nguyên, điều này cũng có thể dẫn đến sự khác biệt.

Thực thi thoát nước

Tuy nhiên, cả hai thuật toán sẽ tạo ra các vùng phẳng sẽ không thoát nếu sử dụng phương pháp cục bộ để xác định hướng dòng chảy.

Planchon và Darboux giải quyết điều này bằng cách thêm một mức tăng nhỏ vào chiều cao của khu vực bằng phẳng để thực thi thoát nước. Như đã thảo luận trong Barnes et al. (2014) Bài viết "Sự phân công hướng thoát nước hiệu quả trên các bề mặt phẳng trong các mô hình độ cao kỹ thuật số raster", việc bổ sung mức tăng này thực sự có thể khiến hệ thống thoát nước bên ngoài một khu vực bằng phẳng được định tuyến lại một cách bất thường nếu độ tăng quá lớn. Một giải pháp là sử dụng, ví dụ, nextafterchức năng.

Những suy nghĩ khác

Wang và Liu (2006) là một biến thể của thuật toán Ưu tiên Lũ lụt, như đã thảo luận trong bài báo của tôi "Lũ lụt ưu tiên: Thuật toán dán nhãn và lấp đầy vùng tối ưu cho các mô hình độ cao số" .

Ưu tiên-Lũ có độ phức tạp thời gian cho cả dữ liệu số nguyên và dấu phẩy động. Trong bài báo của mình, tôi lưu ý rằng việc tránh đặt các ô trong hàng ưu tiên là một cách tốt để tăng hiệu suất của thuật toán. Các tác giả khác như Zhou et al. (2016)Wei et al. (2018) đã sử dụng ý tưởng này để tăng thêm hiệu quả của thuật toán. Mã nguồn cho tất cả các thuật toán có sẵn ở đây .

Với ý nghĩ này, thuật toán Planchon và Darboux (2001) là một câu chuyện về một nơi mà khoa học thất bại. Trong khi Lũ ưu tiên hoạt động theo thời gian O (N) trên dữ liệu số nguyên và thời gian O (N log N) trên dữ liệu dấu phẩy động, P & D hoạt động trong thời gian O (N 1.5 ). Điều này chuyển thành sự khác biệt hiệu suất rất lớn, tăng theo cấp số nhân với quy mô của DEM:

Jenson và Sebastue so với Planchon và Darboux so với Wang và Liu cho việc lấp đầy trầm cảm ưu tiên

Đến năm 2001, Ehlschlaeger, Vincent, Soille, Beucher, Meyer và Gratin đã cùng nhau xuất bản năm bài báo chi tiết về thuật toán ưu tiên lũ lụt. Planchon và Darboux, và những người đánh giá của họ, đã bỏ lỡ tất cả những điều này và đã phát minh ra một thuật toán có độ lớn chậm hơn. Bây giờ là năm 2018 và chúng tôi vẫn đang xây dựng các thuật toán tốt hơn, nhưng P & D vẫn đang được sử dụng. Tôi nghĩ đó là điều không may.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.