ArcGIS 10을 사용하여 래스터에서 최대 값을 가진 픽셀을 찾고 그 위치 (픽셀 중심)를 십진수로 반환하려는 래스터가 있습니다. 이 과정을 반복하여 래스터의 두 번째로 높은 값의 위치를 반환 한 다음 세 번째로 반복하여 마지막으로 래스터에서 가장 높은 값을 갖는 N 개의 위치 목록을 순서대로 반환하고 싶습니다.
나는 이것이 파이썬 스크립트를 사용하여 가장 쉽게 수행 될 수 있다고 생각하지만 더 좋은 방법이 있다면 다른 아이디어에 개방적입니다.
답변
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 %의 지표 격자. 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)는 구역 수로 또는 선택 표의 속성 테이블에서 하나의 레코드를 읽음으로써 얻을 수 있습니다 .
답변
내 솔루션에서 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