ArcGIS Desktop을 사용하여 래스터에서 가장 높은 값의 위치를 ​​찾으십니까?


12

ArcGIS 10을 사용하여 래스터에서 최대 값을 가진 픽셀을 찾고 그 위치 (픽셀 중심)를 십진수로 반환하려는 래스터가 있습니다. 이 과정을 반복하여 래스터의 두 번째로 높은 값의 위치를 ​​반환 한 다음 세 번째로 반복하여 마지막으로 래스터에서 가장 높은 값을 갖는 N 개의 위치 목록을 순서대로 반환하고 싶습니다.

나는 이것이 파이썬 스크립트를 사용하여 가장 쉽게 수행 될 수 있다고 생각하지만 더 좋은 방법이 있다면 다른 아이디어에 개방적입니다.


그리드를 점으로 변환 한 다음 X, Y 필드를 추가하고 정렬을 시도 했습니까?
Jakub Sisak GeoGraphics

래스터 값이 부동 또는 정수입니까?
whuber

@Jakub-아니요. 나는 아마도 1 % 정도의 포인트에만 관심이 있기 때문에 모든 포인트에 x, y 필드를 추가하고 정렬 할 가치가 있는지 모르겠습니다. 더 효율적인 옵션이 없다면?
mga

@whuber-래스터 값은 실수입니다.
mga

@mga, 시도해 볼 가치가 있습니다. 변환은 매우 빠르며 XY를 추가하는 것도 기본 도구입니다. 원치 않는 레코드를 삭제하는 것은 간단한 작업이며 모두 단일 모델로 묶을 수 있습니다. 그냥 생각이야
Jakub Sisak GeoGraphics

답변:


5

R 을 사용하고 싶다면 raster 라는 패키지가있다 . 다음 명령을 사용하여 래스터를 읽을 수 있습니다.

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

그런 다음 살펴보면 (을 입력하여 test) 다음 정보를 볼 수 있습니다.

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 

래스터를 조작하는 더 좋은 방법이있을 수 있지만 원하는 정보를 찾는 한 가지 방법은 가장 높은 값을 찾아서 매트릭스 위치를 얻은 다음 더 낮은 범위에 추가하는 것입니다.


1
이 참조를 위해 +1. 래스터를로 읽은 후에는 R표준 R함수 또는 getValues방법을 사용하여 셀 값에 액세스 할 수 있습니다 . 거기에서 가장 높은 값과 위치를 식별하는 것이 간단합니다.
whuber

1
귀하의 추천 덕분에 이것이 내가 한 일입니다. RGI에서 래스터 패키지를 사용하는 것은 ArcGIS에서 이것을 시도하는 것에 비해 산들 바람입니다. 또한 R에서 다른 공간 분석을 계속 사용했으며 그 결과에 매우 만족했습니다. 좋은 충고!
mga

8

답을 얻을 수 에 의해 조합 위도 및 경도 값과 그리드의 상부 1 %의 지표 격자. ArcGIS (여전히 40 년 후!)에는 래스터 데이터 순위를 매기는 절차가 없기 때문에이 지표 그리드를 만드는 것이 요령입니다.

부동 소수점 래스터에 대한 한 가지 솔루션은 반복적이지만 자비 롭게 빠릅니다 . n 은 데이터 셀의 수라고 하자 . 값 의 경험적 누적 분포 는 모든 쌍 (z, n (z))으로 구성되며, 여기서 z 는 그리드의 값이고 n (z) 는 그리드의 셀 수이며 z 이하의 값 입니다. z로 정렬 된 정점 순서에서 (-무한, 0)을 (+ 무한, n)으로 연결하는 곡선을 얻습니다 . 따라서 함수 f 를 정의합니다. 여기서 (z, f (z))는 항상 곡선 위에 있습니다. 이 곡선에서 점 (z0, 0.99 * n)을 찾으려고합니다.

다시 말해서, f (z)-(1-0.01) * n의 0을 찾는 작업입니다 . 임의의 기능을 처리 할 수있는 제로 찾기 루틴을 사용하여이를 수행하십시오. 가장 효율적인 방법은 종종 추측하여 확인하는 것입니다. 처음에는 z0이 최소값 zMin과 최대 zMax 사이에 있다는 것을 알고 있습니다. 이 둘 사이의 모든 합리적인 가치를 엄격하게 추측하십시오. 추측이 너무 낮 으면 zMin = z0을 설정하십시오. 그렇지 않으면 zMax = z0으로 설정하십시오. 이제 반복하십시오. 솔루션으로 빠르게 수렴됩니다. zMax와 zMin이 충분히 가까워지면 충분히 가까워집니다. 보수적으로 유지하려면 솔루션으로 zMin의 최종 값을 선택하십시오. 나중에 버릴 수있는 몇 가지 추가 포인트가있을 수 있습니다. 보다 정교한 접근 방법은 수치 레시피 9 장을 참조하십시오. (링크는 이전 무료 버전으로 이동).

이 알고리즘을 되돌아 보면 두 가지 종류의 래스터 작업 만 수행하면됩니다 . (1) 일부 대상 값 이하의 모든 셀을 선택하고 (2) 선택한 셀을 계산합니다. 이것들은 가장 간단하고 빠른 작업 중 하나입니다. (2)는 구역 수로 또는 선택 표의 속성 테이블에서 하나의 레코드를 읽음으로써 얻을 수 있습니다 .


7

내 솔루션에서 GDAL을 사용하고 있지만 얼마 전에이 작업을 수행 했으므로 ArcGIS 전용이 아닙니다. ArcGIS 10의 래스터에서 NumPy 배열을 얻을 수 있다고 생각하지만 확실하지 않습니다. NumPy는 단순하고 강력한 배열 인덱싱 argsort등을 제공합니다. 이 예제는 NODATA를 처리하지 않거나 좌표를 투영에서 위도 / 경도로 변환하지 않습니다 (그러나 GDAL과 함께 제공되는 osgeo.osr로는 어렵지 않습니다)

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]))

테스트 래스터 파일에 대해 다음을 보여줍니다.

[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 공유해 주셔서 감사합니다. NoData를 제한 사항으로 처리 할 수 ​​없다고 생각합니다. 계속하기 전에 모든 NoData를 매우 음수 값으로 변환하십시오. 또한 그리드의 재 투영이 발생 하면 그리드의 리샘플링으로 인해 답변이 변경 될 가능성이 있으므로 일반적으로 이와 같은 계산 중에 재 투영이 자동으로 수행되는 것을 원하지 않습니다. 대신에보고 된 좌표를 나중에 다시 투영 할 수 있습니다. 따라서 귀하의 솔루션은 완벽하게 일반적입니다.
whuber

NODATA 처리는 먼저 래스터에서 값을 가져온 NODATA = rast_band.GetNoDataValue()다음 NaN 값 ( rast[rast == NODATA] = np.nan)을 사용하거나 마스크 배열 ( rast = np.ma.array(rast, mask=(rast == NODATA))) 을 사용하여 구현할 수 있습니다 . 더 복잡한 트릭은 argsort어떻게 든 분석에서 NODATA 값을 제거하거나 NaN / 마스크 된 경우 for 루프에서 건너 뛰기 만하면됩니다.
Mike T
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.