Як знайти місця найвищих значень у растрі за допомогою ArcGIS Desktop?


12

Використовуючи ArcGIS 10, у мене є растр, де я хотів би знайти піксель з максимальним значенням у растрі та повернути його розташування (центр пікселя) у десяткових градусах. Я хотів би повторити цей процес, повертаючи місце розташування другого найвищого значення растру, потім третього, і так далі, щоб у підсумку у мене був список N розташувань, які мають найвищі значення в растрі.

Я думаю, що це може бути найпростіше зробити за допомогою сценарію Python, але я відкритий для інших ідей, якщо є кращий спосіб.


ви намагалися перетворити сітку в точки, потім додаючи поля X, Y і сортуючи?
Jakub Sisak GeoGraphics

Чи мають значення растрові чи цілі числа?
whuber

@Jakub - Ні, я ні. Мене, мабуть, цікавить лише верхня 1% або близько балів, тому я не знаю, чи варто додати поля x, y для всіх балів, а потім сортувати. Може, якщо немає більш ефективного варіанту?
МГА

@whuber - Растрові значення є плаваючими.
МГА

@mga, варто спробувати. Перетворення відбувається досить швидко, і додавання XY також є інструментом за замовчуванням. Видалення небажаних записів - це операція прямого руху вперед, і всі вони можуть бути об'єднані в одну модель. Просто ідея.
Jakub Sisak GeoGraphics

Відповіді:


5

Якщо ви раді використовувати R , є пакет, який називається растровим . Ви можете читати в растрі, використовуючи таку команду:

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
Завдяки вашій рекомендації я це закінчив. Використання растрового пакету в R було легким порівняно зі спробами цього в ArcGIS. Я також продовжував використовувати інші просторові аналізи в R і був дуже задоволений результатами. Чудова порада!
МГА

8

Відповідь можна отримати , поєднавши індикаторну сітку верхнього 1% значень із сітками широти та довготи. Хитрість полягає у створенні цієї індикаторної сітки, оскільки ArcGIS (все ще! Після 40 років!) Не має процедури ранжування растрових даних.

Одне рішення для растра з плаваючою комою є ітераційним, але милосердно швидким . Нехай n - кількість комірок даних. Емпіричне розподіл значень складається з усіх пар (г, п (г)) , де г являє собою значення в сітці і п (г) являє собою кількість осередків в сітці зі значеннями менше або дорівнює г . Ми отримуємо криву, що з'єднує (-інфініт, 0) до (+ нескінченність, n) із послідовності цих вершин, упорядкованих z . Тим самим вона визначає функцію f , де (z, f (z)) завжди лежить на кривій. На цій кривій потрібно знайти точку (z0, 0,99 * n).

Іншими словами, завдання - знайти нуль f (z) - (1-0.01) * n . Зробіть це за допомогою будь-якої рутинної функції пошуку нуля (яка може обробляти довільні функції: ця не відрізняється). Найпростіший, який часто ефективний, - це відгадування і перевірка: спочатку ви знаєте, що z0 лежить між мінімальним значенням zMin і максимальним zMax. Вгадайте будь-яке розумне значення строго між цими двома. Якщо здогад занадто низький, встановіть zMin = z0; інакше встановити zMax = z0. Тепер повторіть. Ви швидко перейдете до рішення; ви досить близькі, коли zMax і zMin досить близькі. Щоб бути консервативним, виберіть кінцеве значення zMin як рішення: воно може набрати кілька додаткових балів, які ви зможете відкинути пізніше. Більш досконалі підходи див. У Розділі 9 числових рецептів (посилання переходить на старішу безкоштовну версію).

Озирнувшись до цього алгоритму, видно, що вам потрібно виконати лише два види растрових операцій : (1) виділити всі комірки, менші або рівні деякому цільовому значенню, і (2) підрахувати вибрані комірки. Вони є одними з найпростіших і найшвидших операцій навколо. (2) може бути отримано як зональне підрахунок або, прочитавши один запис із таблиці атрибутів сітки вибору.


7

Я це робив деякий час тому, хоча моє рішення використовує GDAL (так, це не тільки для ArcGIS). Я думаю, ви можете отримати масив NumPy з растра в ArcGIS 10, але я не знаю точно. NumPy забезпечує просту та потужну індексацію масивів, як argsortі інші. Цей приклад не обробляє NODATA або перетворює координати з проектованого в lat / long (але це не складно зробити з osgeo.osr, що надається 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]))

Показує наступне для мого тестового растрового файлу:

[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 з аналізу, або просто просто пропустити повз них у циклі for, якщо вони NaN / замасковані.
Майк Т
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.