Tìm vị trí của các giá trị cao nhất trong raster bằng ArcGIS Desktop?


12

Sử dụng ArcGIS 10, tôi có một raster nơi tôi muốn tìm pixel có giá trị tối đa trong raster và trả về vị trí của nó (tâm pixel) theo độ thập phân. Tôi muốn lặp lại quá trình này trả về vị trí của giá trị cao thứ hai của raster, sau đó là thứ ba, và cuối cùng tôi có một danh sách N vị trí có giá trị cao nhất trong raster theo thứ tự.

Tôi tưởng tượng rằng điều này có thể được thực hiện dễ dàng nhất bằng cách sử dụng tập lệnh Python nhưng tôi sẽ mở cho các ý tưởng khác nếu có cách tốt hơn.


Bạn đã thử chuyển đổi lưới thành các điểm rồi thêm các trường X, Y và sắp xếp chưa?
Jakub Sisak GeoGraphics

Là các giá trị raster nổi hay số nguyên?
whuber

@Jakub - Không, tôi không có. Có lẽ tôi chỉ quan tâm đến 1% điểm hàng đầu hoặc hơn nên tôi không biết liệu có đáng để thêm các trường x, y cho tất cả các điểm hay không sau đó sắp xếp. Có lẽ nếu không có một lựa chọn hiệu quả hơn?
mga

@whuber - Các giá trị raster là float.
mga

@mga, nó đáng để thử. Việc chuyển đổi khá nhanh và thêm XY cũng là một công cụ mặc định. Xóa các bản ghi không mong muốn là một thao tác chuyển tiếp thẳng và tất cả có thể được gói thành một mô hình duy nhất. Chỉ là một ý tưởng.
Jakub Sisak GeoGraphics

Câu trả lời:


5

Nếu bạn hài lòng khi sử dụng R , có một gói được gọi là raster . Bạn có thể đọc trong raster bằng lệnh sau:

install.packages('raster')
library(raster)
test <- raster('F:/myraster')

Sau đó, khi bạn nhìn vào nó (bằng cách gõ test), bạn có thể thấy thông tin sau:

class       : RasterLayer 
dimensions  : 494, 427, 210938  (nrow, ncol, ncell)
resolution  : 200, 200  (x, y)
extent      : 1022155, 1107555, 1220237, 1319037  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs +towgs84=0,0,0 
values      : F:/myraster 
min value   : 0 
max value   : 1 

Có thể có nhiều cách tốt hơn để thao túng raster, nhưng một cách để tìm thông tin bạn muốn có thể là tìm giá trị cao nhất và lấy vị trí ma trận của nó, sau đó thêm nó vào phạm vi thấp hơn.


1
+1 Đối với tài liệu tham khảo này. Khi bạn đã đọc raster vào R, bạn có thể sử dụng các Rhàm tiêu chuẩn hoặc getValuesphương thức để truy cập các giá trị ô. Từ đó, đơn giản để xác định các giá trị cao nhất và vị trí của chúng.
whuber

1
Nhờ lời khuyên của bạn, đây là những gì tôi đã làm. Sử dụng gói raster trong R thật dễ dàng so với việc thử điều này trong ArcGIS. Tôi cũng đã tiếp tục sử dụng các phân tích không gian khác trong R và rất hài lòng với kết quả này. Lời khuyên tuyệt vời!
mga

8

Câu trả lời có thể nhận được bởi kết hợp lưới chỉ số của 1% giá trị hàng đầu với các lưới vĩ độ và kinh độ. Thủ thuật nằm ở việc tạo lưới chỉ số này, bởi vì ArcGIS (vẫn vậy! Sau 40 năm!) Không có quy trình xếp hạng dữ liệu raster.

Một giải pháp cho các raster dấu phẩy động là lặp đi lặp lại, nhưng nhanh chóng thương xót . Gọi n là số ô dữ liệu. Các phân phối tích lũy kinh nghiệm của các giá trị bao gồm tất cả các cặp (z, n (z)), nơi z là một giá trị trong lưới và n (z) là số ô trong lưới với giá trị nhỏ hơn hoặc bằng đến z . Chúng ta có một đường cong nối (-infinity, 0) đến (+ vô cực, n) trong chuỗi các đỉnh này theo thứ tự z . Từ đó xác định hàm f , trong đó (z, f (z)) luôn nằm trên đường cong. Bạn muốn tìm một điểm (z0, 0,99 * n) trên đường cong này.

Nói cách khác, nhiệm vụ là tìm một số 0 của f (z) - (1-0,01) * n . Làm điều này với bất kỳ thói quen tìm kiếm bằng không nào (có thể xử lý các hàm tùy ý: cái này không khác biệt). Đơn giản nhất, thường hiệu quả, là đoán và kiểm tra: ban đầu bạn biết z0 nằm giữa giá trị tối thiểu zMin và zMax tối đa. Đoán bất kỳ giá trị hợp lý nghiêm ngặt giữa hai. Nếu dự đoán quá thấp, đặt zMin = z0; mặt khác đặt zMax = z0. Bây giờ lặp lại. Bạn sẽ nhanh chóng hội tụ vào giải pháp; bạn đủ gần khi zMax và zMin đủ gần. Để thận trọng, hãy chọn giá trị cuối cùng của zMin làm giải pháp: nó có thể lấy thêm một vài điểm mà bạn có thể loại bỏ sau này. Để biết các cách tiếp cận tinh vi hơn, xem Chương 9 của Công thức toán số (liên kết đến phiên bản miễn phí cũ hơn).

Nhìn lại thuật toán này cho thấy bạn chỉ cần thực hiện hai loại hoạt động raster : (1) chọn tất cả các ô nhỏ hơn hoặc bằng một số giá trị đích và (2) đếm các ô đã chọn. Đó là một trong những hoạt động đơn giản và nhanh nhất xung quanh. (2) có thể được lấy dưới dạng đếm khu vực hoặc bằng cách đọc một bản ghi từ bảng thuộc tính của lưới lựa chọn.


7

Tôi đã làm điều này một thời gian trước, mặc dù giải pháp của tôi là sử dụng GDAL (vì vậy, đây không chỉ dành cho ArcGIS). Tôi nghĩ rằng bạn có thể nhận được một mảng NumPy từ một raster trong ArcGIS 10, nhưng tôi không biết chắc chắn. NumPy cung cấp lập chỉ mục mảng đơn giản và mạnh mẽ, như argsortvà những người khác. Ví dụ này không xử lý NODATA hoặc chuyển đổi tọa độ từ được chiếu sang lat / long (nhưng điều này không khó thực hiện với osgeo.osr, được cung cấp với GDAL)

import numpy as np
from osgeo import gdal

# Open raster file, and get GeoTransform
rast_src = gdal.Open(rast_fname)
rast_gt = rast_src.GetGeoTransform()

def get_xy(r, c):
    '''Get (x, y) raster centre coordinate at row, column'''
    x0, dx, rx, y0, ry, dy = rast_gt
    return(x0 + r*dx + dx/2.0, y0 + c*dy + dy/2.0)

# Get first raster band
rast_band = rast_src.GetRasterBand(1)

# Retrieve as NumPy array to do the serious work
rast = rast_band.ReadAsArray()

# Sort raster pixels from highest to lowest
sorted_ind = rast.argsort(axis=None)[::-1]

# Show highest top 10 values
for ind in sorted_ind[:10]:
    # Get row, column for index
    r, c = np.unravel_index(ind, rast.shape)
    # Get [projected] X and Y coordinates
    x, y = get_xy(r, c)
    print('[%3i, %3i] (%.3f, %.3f) = %.3f'%
          (r, c, x, y, rast[r, c]))

Hiển thị như sau cho tệp raster thử nghiệm của tôi:

[467, 169] (2813700.000, 6353100.000) = 844.538
[467, 168] (2813700.000, 6353200.000) = 841.067
[469, 168] (2813900.000, 6353200.000) = 840.705
[468, 168] (2813800.000, 6353200.000) = 840.192
[470, 167] (2814000.000, 6353300.000) = 837.063
[468, 169] (2813800.000, 6353100.000) = 837.063
[482, 166] (2815200.000, 6353400.000) = 833.038
[469, 167] (2813900.000, 6353300.000) = 832.825
[451, 181] (2812100.000, 6351900.000) = 828.064
[469, 169] (2813900.000, 6353100.000) = 827.514

+1 Cảm ơn bạn đã chia sẻ điều này. Tôi không thấy sự bất lực trong việc xử lý NoData là một hạn chế: chỉ cần chuyển đổi tất cả NoData thành các giá trị cực kỳ tiêu cực trước khi tiếp tục. Cũng lưu ý rằng, nếu có bất kỳ sự từ chối nào của lưới xảy ra, các câu trả lời sẽ có thể thay đổi do việc lấy lại lưới, do đó, thông thường người ta không muốn từ chối xảy ra tự động trong quá trình tính toán như thế này. Thay vào đó, các tọa độ được báo cáo có thể được xử lý lại sau đó. Do đó, giải pháp của bạn là hoàn toàn chung chung.
whuber

Việc xử lý NODATA có thể được thực hiện bằng cách trước tiên lấy giá trị từ raster NODATA = rast_band.GetNoDataValue(), sau đó bằng cách sử dụng giá trị NaN ( rast[rast == NODATA] = np.nan) hoặc bằng cách sử dụng mảng bị che ( rast = np.ma.array(rast, mask=(rast == NODATA))). Thủ thuật phức tạp hơn là argsortbằng cách nào đó loại bỏ các giá trị NODATA khỏi phân tích hoặc chỉ đơn giản là bỏ qua chúng trong vòng lặp for nếu chúng là NaN / bị che.
Mike T
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.