ArcGIS Desktop kullanarak rasterdeki en yüksek değerlerin yerlerini mi buldunuz?


12

ArcGIS 10'u kullanarak, rasterde maksimum değeri olan pikseli bulmak ve ondalık derecedeki konumunu (piksel merkezi) döndürmek istediğim bir rasterim var. Rasterin ikinci en yüksek değerinin, daha sonra üçüncü ve benzeri konumun döndürülmesini sağlayan bu süreçte tekrarlamak istiyorum, böylece sonunda rasterdeki en yüksek değerlere sahip N konumlarının bir listesine sahibim.

Bunun en kolay bir Python betiği kullanılarak yapılabileceğini hayal ediyorum, ancak daha iyi bir yol varsa diğer fikirlere açıkım.


ızgarayı noktalara dönüştürüp X, Y alanları ekleyip sıralamayı denediniz mi?
Jakub Sisak GeoGraphics

Raster değerleri yüzer mi, tamsayı mı?
whuber

@Jakub - Hayır. Ben muhtemelen sadece ilk% 1 ya da öylesine puan ilgilenen olacak, bu yüzden sıralama sonra tüm puanlar için x, y alanları eklemeye değer olup olmadığını bilmiyorum. Belki daha verimli bir seçenek yoksa?
dhe

@whuber - Raster değerleri değişkentir.
dhe

mga, denemeye değer. Dönüşüm oldukça hızlı ve XY eklemek de varsayılan bir araçtır. İstenmeyen kayıtları silmek basit bir işlemdir ve hepsi tek bir modelde toplanabilir. Sadece bir fikir.
Jakub Sisak GeoGraphics

Yanıtlar:


5

R'yi kullanmaktan memnunsanız , raster adı verilen bir paket var . Aşağıdaki komutu kullanarak bir taramada okuyabilirsiniz:

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

Ardından, ona baktığınızda (yazarak test), aşağıdaki bilgileri görebilirsiniz:

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 

Rasteri manipüle etmenin daha iyi yolları olabilir, ancak istediğiniz bilgiyi bulmanın bir yolu en yüksek değeri bulmak ve matris konumunu elde etmek ve daha sonra bunu alt uzantılara eklemek olabilir.


1
+1 Bu referans için. Rasteri okuduktan sonra R, hücre değerlerine erişmek için standart Rfonksiyonları veya getValuesyöntemi kullanabilirsiniz. Oradan en yüksek değerleri ve konumlarını tanımlamak kolaydır.
whuber

1
Tavsiyeniz sayesinde yaptığım şey bu. Rasster paketini R'de kullanmak, ArcGIS'te denemeye kıyasla bir esinti oldu. Ayrıca R'de diğer uzamsal analizleri kullanmaya devam ettim ve sonuçlardan çok memnun kaldım. Harika tavsiye!
dhe

8

Cevap elde edilebilir ile kombine enlem ve boylam ızgaraları ile değerlerinin üst% 1 arasında bir gösterge ızgara. Hile bu gösterge ızgarasını oluşturmada yatıyor, çünkü ArcGIS (hala! 40 yıl sonra!) Raster verilerini sıralamak için bir prosedürü yok.

Kayan noktalı rasterler için bir çözüm yinelemeli, ama çok hızlıdır . N veri hücresi sayısı olsun . Deneysel kümülatif dağılım değerleri her çiftlerinden oluşur (z, N (Z)) z ızgara ve bir değerdir , n (z) ' den az değerler ile ızgara hücrelerin sayısı ya da eşit z . Z tarafından sıralanan bu köşelerin sırasından (-fininity, 0) 'dan (+ infinity, n)' ya bağlanan bir eğri elde ederiz . Böylece f fonksiyonunu tanımlar , burada (z, f (z)) daima eğri üzerinde bulunur. Bu eğri üzerinde bir nokta (z0, 0.99 * n) bulmak istiyorsunuz.

Başka bir deyişle, görev f (z) - (1-0.01) * n'nin sıfırını bulmaktır . Bunu herhangi bir sıfır bulma rutini ile yapın (rastgele işlevleri işleyebilir: bu farklılaşamaz). Genellikle verimli olan en basit tahmin ve kontroldür: başlangıçta z0'ın minimum zMin değeri ile maksimum zMax değeri arasında olduğunu bilirsiniz. Bu ikisi arasında kesinlikle herhangi bir makul değeri tahmin edin. Tahmin çok düşükse, zMin = z0; aksi takdirde zMax = z0 değerini ayarlayın. Şimdi tekrar et. Hızlı bir şekilde çözüme kavuşacaksınız; zMax ve zMin yeterince yakın olduğunda yeterince yakınsınız. Muhafazakar olmak için, çözüm olarak zMin'in son değerini seçin: daha sonra atabileceğiniz birkaç ekstra nokta alabilir. Daha karmaşık yaklaşımlar için Sayısal Tarifler Bölüm 9'a bakınız. (bağlantı eski bir ücretsiz sürüme gider).

Bu algoritmaya geri baktığınızda yalnızca iki çeşit raster işlemi yapmanız gerekir : (1) bazı hedef değerlerden küçük veya eşit olan tüm hücreleri seçin ve (2) seçilen hücreleri sayın. Bunlar en basit ve en hızlı operasyonlar arasında. (2) bir bölge sayımı olarak veya seçim ızgarasının nitelik tablosundan bir kayıt okunarak elde edilebilir .


7

Bunu bir süre önce yaptım, ancak çözümüm GDAL kullanıyor olsa da (bu sadece ArcGIS için değil). ArcGIS 10'da bir rasterden NumPy dizisi alabileceğinizi düşünüyorum, ama emin değilim. NumPy, argsortdiğerleri gibi basit ve güçlü dizi indeksleme sağlar . Bu örnek NODATA'yı işlemez veya koordinatları yansıtılandan enlem / boyuta dönüştürmez (ancak GDAL ile sağlanan osgeo.osr ile bunu yapmak zor değildir)

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

Test tarama dosyam için aşağıdakileri gösterir:

[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 Bunu paylaştığınız için teşekkürler. NoData bir sınırlama olarak işlemek için bir yetersizlik görmüyorum: sadece devam etmeden önce tüm NoData son derece negatif değerlere dönüştürün. Not da herhangi yeniden projeksiyon eğer ızgara oluşur cevaplar olasılıkla nedeniyle, ızgaranın yeniden örnekleme değişecektir böylece normalde bir yeniden projeksiyon böyle bir hesaplama sırasında otomatik olarak gerçekleşmesi istemiyor. Bunun yerine, bildirilen koordinatlar daha sonra yeniden belirlenebilir. Böylece çözümünüz genel olarak mükemmeldir.
whuber

NODATA kullanımı önce değerden raster alındıktan NODATA = rast_band.GetNoDataValue()sonra bir NaN değeri ( rast[rast == NODATA] = np.nan) veya maskelenmiş bir dizi ( rast = np.ma.array(rast, mask=(rast == NODATA))) kullanılarak gerçekleştirilebilir. Daha karmaşık hile argsortNODATA değerlerini bir şekilde analizden kaldırmak veya sadece NaN / maskeli olmaları durumunda bunları for-loop'ta atlamaktır.
Mike T
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.