Відповіді:
Я не думаю, що це можливо для ArcGIS <= 9.3.1
Я використовую API GDAL з відкритим кодом для таких завдань.
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/RasterToNumPyArray/000v0000012z000000/
ArcGIS 10 має можливість запису та читання масивів numPy.
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
Доступ до ArcObjects з Python? обговорюється інтеграція аркобектів з пітоном.
Можливо, код у цьому зразку міг би бути адаптований так, щоб його можна було викликати з python.
Я не впевнений, чи є спосіб передати масив byref назад до python. Якщо є, то IPixelBlock.PixelDatabyRef варто спробувати.
Ви можете зберегти растр у вигляді сітки ESRI ascii та прочитати / маніпулювати цим файлом нумером.
Це дає деякі вихідні точки: http://sites.google.com/site/davidpfinlayson2/esriasciigridformat
Але будьте уважні - схоже, формат сітки ascii не завжди відповідає специфікаціям, тому читання їх кожного разу може бути складним завданням.
Я не впевнений, що ви можете маніпулювати растровим пікселем за пікселем, але ви можете використовувати об’єкти геообробки разом із 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.
Найпростішим способом було б перетворити растр на netCDF, а потім відкрити його і пройти через сітку. Я зробив дуже те ж саме для проекту, який включав перетворення растрових даних у функції даних на основі даних, призначених для растрових комірок. Я дивився на це століттями, і прийти до висновку, що проходити дані сітки було б простіше з NetCDF.