Lấy hình ảnh raster dưới dạng mảng trong Python với ArcGIS Desktop?


10

Khi bắt đầu làm việc với Python và ArcGIS 9.3, tôi đã giả định rằng sẽ có một cách đơn giản để đưa hình ảnh raster vào mảng Python để tôi có thể thao tác trước khi lưu trữ lại dưới dạng hình ảnh raster khác. Tuy nhiên, tôi dường như không thể tìm ra cách để làm điều này.

Nếu có thể thì làm sao?

Câu trả lời:


6

Tôi không nghĩ điều này là có thể với ArcGIS <= 9.3.1

Tôi sử dụng API GDAL mã nguồn mở cho các tác vụ như thế này.


Tuyệt quá! Trước đây tôi đã sử dụng các chương trình tiện ích GDAL, nhưng chưa bao giờ nghĩ đến việc sử dụng chúng để làm điều này.
robintw

3
Tôi đồng ý, mô-đun gdal Python cho phép bạn dễ dàng đọc raster và chuyển dữ liệu sang mảng Numpy. Chris Garrard có một khóa học về sử dụng OpenSource Python trong GIS, nó bao gồm chủ đề này. Bạn có thể tìm thấy nó tại: gis.usu.edu/~chrisg/python/2008
DavidF


6

fmark đã trả lời câu hỏi, nhưng đây là một số ví dụ mã Python của OSGEO mà tôi đã viết để đọc raster (tif) vào một mảng NumPy, phân loại lại dữ liệu và sau đó ghi nó ra một tệp tif mới. Bạn có thể đọc và viết bất kỳ định dạng hỗ trợ 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

Bạn có thể lưu raster của mình dưới dạng lưới ESRI ascii và đọc / thao tác tệp đó với numpy.

Điều này cung cấp một số điểm bắt đầu: http://sites.google.com.vn/site/davidpfinlayson2/esriasciigridformat

Nhưng xem ra - có vẻ như định dạng lưới ascii không phải lúc nào cũng tuân theo thông số kỹ thuật, vì vậy việc đọc chúng đúng cách mỗi lần có thể là một thách thức.


1

Tôi không chắc bạn có thể thao tác pixel raster theo pixel, nhưng bạn có thể sử dụng các đối tượng xử lý địa lý kết hợp với API python.

Bạn có thể sử dụng bất kỳ hộp công cụ nào cho loại thao tác đó. Một tập lệnh mẫu sẽ là:

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

Đây là một theo dõi về câu hỏi của bạn . Vẫn không thể. Không chắc chắn trên phiên bản 10.0.


Cảm ơn - điều đó rất hữu ích. Tuy nhiên, lý tưởng nhất là tôi muốn có thể lặp lại trên mảng raster làm nhiều việc khác nhau với nó. Tôi đã có thể nghĩ rằng sẽ có một cách trong ArcGIS để làm điều này, nhưng có lẽ là không!
robintw

robintw, đối với những gì tôi đã xem trong tài liệu tham khảo, không có cách nào để có được một pixel cụ thể của raster. Tôi không chắc chắn nếu trong ArcPy (có sẵn từ v10), bạn có thể tìm nạp các ô riêng lẻ này hay không, vì chúng đã mở rộng API python với nhiều chức năng mới.
George Silva

0

Cách dễ nhất là chuyển đổi raster sang netCDF và sau đó mở nó và đi qua lưới. Tôi đã làm rất nhiều điều tương tự cho một dự án liên quan đến việc biến raster thành dữ liệu tính năng dựa trên dữ liệu được gán cho các ô raster. Tôi đã xem xét điều này từ lâu và đi đến kết luận rằng việc đi lại dữ liệu lưới sẽ dễ dàng hơn từ netCDF.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.