Ottenere un'immagine raster come array in Python con ArcGIS Desktop?


10

Quando ho iniziato a lavorare con Python e ArcGIS 9.3, ho pensato che ci sarebbe stato un modo semplice per ottenere un'immagine raster in un array Python in modo da poterla manipolare prima di salvarla come un'altra immagine raster. Tuttavia, non riesco a scoprire come farlo.

Se è possibile, allora come?

Risposte:


6

Non credo sia possibile con ArcGIS <= 9.3.1

Uso l' API GDAL open source per attività come questa.


Grande! Ho usato i programmi di utilità GDAL in passato, ma non ho mai pensato di usarli per farlo.
Robintw,

3
Sono d'accordo, il modulo gdal Python consente di leggere facilmente un raster e scaricare i dati su un array Numpy. Chris Garrard ha un corso sull'uso di OpenSource Python in GIS, che tratta questo argomento. Puoi trovarlo su: gis.usu.edu/~chrisg/python/2008
DavidF


6

fmark ha già risposto alla domanda, ma ecco alcuni esempi di codice OSGEO Python che ho scritto per leggere un raster (tif) in un array NumPy, riclassificare i dati e quindi scriverli in un nuovo file tif. Puoi leggere e scrivere qualsiasi formato supportato da 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



1

Non sono sicuro che puoi manipolare il pixel raster per pixel, ma puoi usare gli oggetti di geoprocessing in congiunzione con l'API python.

Puoi usare qualsiasi toolbox per quel tipo di manipolazione. Uno script di esempio sarebbe:

#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")

Ecco un seguito alla tua domanda . Ancora impossibile. Non sono sicuro sulla versione 10.0.


Grazie - è molto utile. Tuttavia, idealmente mi piacerebbe essere in grado di iterare attraverso l'array raster facendo varie cose. Avrei pensato che in ArcGIS ci sarebbe stato un modo per farlo, ma forse no!
robintw,

robintw, per quello che ho cercato nel riferimento, non c'è modo di ottenere un pixel specifico di un raster. Non sono sicuro che in ArcPy (disponibile dalla v10) è possibile recuperare queste singole celle, poiché hanno esteso l'API python con molte nuove funzionalità.
George Silva,

0

Il modo più semplice sarebbe convertire il raster in netCDF, quindi aprirlo e attraversare la griglia. Ho fatto la stessa cosa per un progetto che prevedeva la trasformazione di raster in dati di funzionalità basati su dati assegnati alle celle raster. Ho esaminato questo aspetto per anni e sono giunto alla conclusione che i dati della griglia sarebbero più facili da netCDF.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.