Отримання растрового зображення як масиву в Python за допомогою ArcGIS Desktop?


10

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

Якщо це можливо, то як?

Відповіді:


6

Я не думаю, що це можливо для ArcGIS <= 9.3.1

Я використовую API GDAL з відкритим кодом для таких завдань.


Чудово! У минулому я використовував утилітні програми GDAL, але ніколи не думав використовувати їх для цього.
robintw

3
Я погоджуюсь, що модуль gdal Python дозволяє легко зчитувати растр і скидати дані до масиву Numpy. Кріс Гаррард має курс на використання OpenSource Python в ГІС, він висвітлює цю тему. Ви можете знайти його за адресою: gis.usu.edu/~chrisg/python/2008
DavidF


6

fmark вже відповів на питання, але ось приклад коду OSGEO Python, який я написав, щоб прочитати растр (tif) в масив NumPy, перекладати дані і потім записати їх у новий файл tif. Ви можете читати та писати будь-який формат, підтримуваний gdal.

"""
Example of raster reclassification using OpenSource Geo Python

"""
import numpy, sys
from osgeo import gdal
from osgeo.gdalconst import *


# register all of the GDAL drivers
gdal.AllRegister()

# open the image
inDs = gdal.Open("c:/workshop/examples/raster_reclass/data/cropland_40.tif")
if inDs is None:
  print 'Could not open image file'
  sys.exit(1)

# read in the crop data and get info about it
band1 = inDs.GetRasterBand(1)
rows = inDs.RasterYSize
cols = inDs.RasterXSize

cropData = band1.ReadAsArray(0,0,cols,rows)

listAg = [1,5,6,22,23,24,41,42,28,37]
listNotAg = [111,195,141,181,121,122,190,62]

# create the output image
driver = inDs.GetDriver()
#print driver
outDs = driver.Create("c:/workshop/examples/raster_reclass/output/reclass_40.tif", cols, rows, 1, GDT_Int32)
if outDs is None:
  print 'Could not create reclass_40.tif'
  sys.exit(1)

outBand = outDs.GetRasterBand(1)
outData = numpy.zeros((rows,cols), numpy.int16)


for i in range(0, rows):
  for j in range(0, cols):

    if cropData[i,j] in listAg:
        outData[i,j] = 100
    elif cropData[i,j] in listNotAg:
        outData[i,j] = -100
    else:
        outData[i,j] = 0


# write the data
outBand.WriteArray(outData, 0, 0)

# flush data to disk, set the NoData value and calculate stats
outBand.FlushCache()
outBand.SetNoDataValue(-99)

# georeference the image and set the projection
outDs.SetGeoTransform(inDs.GetGeoTransform())
outDs.SetProjection(inDs.GetProjection())

del outData

2

Доступ до ArcObjects з Python? обговорюється інтеграція аркобектів з пітоном.

Можливо, код у цьому зразку міг би бути адаптований так, щоб його можна було викликати з python.

Я не впевнений, чи є спосіб передати масив byref назад до python. Якщо є, то IPixelBlock.PixelDatabyRef варто спробувати.


1

Ви можете зберегти растр у вигляді сітки ESRI ascii та прочитати / маніпулювати цим файлом нумером.

Це дає деякі вихідні точки: http://sites.google.com/site/davidpfinlayson2/esriasciigridformat

Але будьте уважні - схоже, формат сітки ascii не завжди відповідає специфікаціям, тому читання їх кожного разу може бути складним завданням.


1

Я не впевнений, що ви можете маніпулювати растровим пікселем за пікселем, але ви можете використовувати об’єкти геообробки разом із API python.

Ви можете використовувати будь-яку панель інструментів для такого роду маніпуляцій. Приклад сценарію буде:

#import arcgisscripting

gp = arcgisscripting.create(9.3)

gp.AddToolbox("SA") # addint spatial analyst toolbox

rasterA = @"C:\rasterA.tif"
rasterB = @"C:\rasterB.tif"

rasterC = @"C:\rasterC.tif" # this raster does not yet exist
rasterD = @"C:\rasterD.tif" # this raster does not yet exist

gp.Minus_SA(rasterA,rasterB,rasterC)

gp.Times_SA(rasterA,rasterB,rasterD)

# lets try to use more complex functions

# lets build and expression first

expression1 = "slope( " + rasterC + ")"
expression2 = "(" + rasterC " + " rasterD + ") - " + rasterA 

gp.SingleOutputMapAlgebra_SA(expression1,@"C:\result_exp1.tif")
gp.SingleOutputMapAlgebra_SA(expression2,@"C:\result_exp2.tif")

Ось подальше запитання щодо вашого питання . Досі неможливо. Не впевнений у версії 10.0.


Спасибі - це дуже корисно. Однак в ідеалі я хотів би мати можливість перебирати растровий масив, роблячи йому різні речі. Я б міг подумати, що в ArcGIS є спосіб зробити це, але, можливо, ні!
robintw

robintw, тому що я шукав у посиланні, немає способу отримати конкретний піксель растра. Я не впевнений, що в ArcPy (доступний з v10) ви можете отримати ці окремі комірки, оскільки вони розширили API python з великою кількістю нових функціональних можливостей.
Джордж Сільва

0

Найпростішим способом було б перетворити растр на netCDF, а потім відкрити його і пройти через сітку. Я зробив дуже те ж саме для проекту, який включав перетворення растрових даних у функції даних на основі даних, призначених для растрових комірок. Я дивився на це століттями, і прийти до висновку, що проходити дані сітки було б простіше з NetCDF.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.