Giữ tham chiếu không gian bằng arcpy.RasterToNumPyArray?


13

Tôi đang sử dụng ArcGIS 10.1 và muốn tạo một raster mới dựa trên hai raster đã có từ trước. Các RasterToNumPyArray có một ví dụ điển hình mà tôi muốn thích nghi.

import arcpy
import numpy 
myArray = arcpy.RasterToNumPyArray('C:/data/inRaster')
myArraySum = myArray.sum(1)
myArraySum.shape = (myArray.shape[0],1)
myArrayPerc = (myArray * 1.0)/ myArraySum
newRaster = arcpy.NumPyArrayToRaster(myArrayPerc)
newRaster.save("C:/output/fgdb.gdb/PercentRaster")

Vấn đề là nó tước tham chiếu không gian và kích thước ô. Tôi hình dung nó phải làm arcpy.env, nhưng làm cách nào để đặt chúng dựa trên raster đầu vào? Tôi không thể hình dung nó ra.


Lấy câu trả lời của Luke, đây là giải pháp dự kiến ​​của tôi.

Cả hai giải pháp của Luke đều đặt tham chiếu không gian, phạm vi và kích thước ô chính xác. Nhưng phương pháp đầu tiên không mang dữ liệu trong mảng một cách chính xác và raster đầu ra được lấp đầy bằng nốt ở khắp mọi nơi. Phương pháp thứ hai của anh ấy hoạt động chủ yếu, nhưng nơi tôi có vùng hạch lớn, nó lấp đầy với các số 0 và 255 khối. Điều này có thể phải làm với cách tôi xử lý các tế bào nốt, và tôi không chắc là tôi đã làm như thế nào (nên là một Q khác). Tôi bao gồm những hình ảnh về những gì tôi đang nói về.

#Setting the raster properties directly 
import arcpy 
import numpy 

inRaster0='C:/workspace/test0.tif' 
inRaster1='C:/workspace/test1.tif' 
outRaster='C:/workspace/test2.tif' 

dsc=arcpy.Describe(inRaster0) 
sr=dsc.SpatialReference 
ext=dsc.Extent 
ll=arcpy.Point(ext.XMin,ext.YMin) 

# sorry that i modify calculation from my original Q.  
# This is what I really wanted to do, taking two uint8 rasters, calculate 
# the ratio, express the results as percentage and then save it as uint8 raster.
tmp = [ np.ma.masked_greater(arcpy.RasterToNumPyArray(_), 100) for _ in inRaster0, inRaster1]
tmp = [ np.ma.masked_array(_, dtype=np.float32) for _ in tmp]
tmp = ((tmp[1] ) / tmp[0] ) * 100
tmp = np.ma.array(tmp, dtype=np.uint8)
# i actually am not sure how to properly carry the nodata back to raster...  
# but that's another Q
tmp = np.ma.filled(tmp, 255)

# without this, nodata cell may be filled with zero or 255?
arcpy.env.outCoordinateSystem = sr

newRaster = arcpy.NumPyArrayToRaster(myArrayPerc,ll,dsc.meanCellWidth,dsc.meanCellHeight) 

newRaster.save(outRaster) 

Hình ảnh hiển thị kết quả. Tôi cả hai tế bào nốt sần được hiển thị màu vàng.

Phương pháp thứ hai của Luke Phương pháp thứ hai của Luke

Phương pháp dự kiến ​​của tôi Phương pháp dự kiến ​​của tôi

Câu trả lời:


15

Kiểm tra phương pháp Mô tả .

Một cái gì đó như sau nên làm việc.

#Using arcpy.env
import arcpy
import numpy

inRaster='C:/workspace/test1.tif'
outRaster='C:/workspace/test2.tif'

dsc=arcpy.Describe(inRaster)
arcpy.env.extent=dsc.Extent
arcpy.env.outputCoordinateSystem=dsc.SpatialReference
arcpy.env.cellSize=dsc.meanCellWidth

myArray = arcpy.RasterToNumPyArray(r)
myArraySum = myArray.sum(1)
myArraySum.shape = (myArray.shape[0],1)
myArrayPerc = (myArray * 1.0)/ myArraySum

newRaster = arcpy.NumPyArrayToRaster(myArrayPerc)
newRaster.save(outRaster)

HOẶC LÀ

#Setting the raster properties directly
import arcpy
import numpy

inRaster='C:/workspace/test1.tif'
outRaster='C:/workspace/test2.tif'

dsc=arcpy.Describe(inRaster)
sr=dsc.SpatialReference
ext=dsc.Extent
ll=arcpy.Point(ext.XMin,ext.YMin)

myArray = arcpy.RasterToNumPyArray(inRaster)
myArraySum = myArray.sum(1)
myArraySum.shape = (myArray.shape[0],1)
myArrayPerc = (myArray * 1.0)/ myArraySum

newRaster = arcpy.NumPyArrayToRaster(myArrayPerc,ll,dsc.meanCellWidth,dsc.meanCellHeight)
arcpy.DefineProjection_management(newRaster, sr)

newRaster.save(outRaster)

EDIT: Phương thức arcpy.NumPyArrayToRaster lấy tham số value_to_nodata. Sử dụng nó như vậy:

try:
    noDataValue=dsc.noDataValue
    arcpy.NumPyArrayToRaster(myArrayPerc,ll,dsc.meanCellWidth,dsc.meanCellHeight,noDataValue)
except AttributeError: #no data is not defined
    arcpy.NumPyArrayToRaster(myArrayPerc,ll,dsc.meanCellWidth,dsc.meanCellHeight)

Luke, cảm ơn bạn đã trả lời. Tôi nhận thấy rằng tôi cần phải làm một cái gì đó lai giữa hai phương pháp của bạn? Cả hai phương thức đều đặt phạm vi, spref, v.v. đúng, nhưng không thể sắp xếp dữ liệu chính xác ... Phương thức đầu tiên làm cho tất cả các ô là nốt. Phương pháp thứ hai hoạt động tốt hơn, nhưng dường như chúng không xử lý chính xác các tế bào nốt trong myArray (xin lỗi vì tôi không nói với tế bào của mình có một số nốt và tôi muốn giữ nguyên các ô đó). Một số thử nghiệm và lỗi khiến tôi nghĩ rằng tôi phải thực hiện phương pháp thứ hai nhưng arcpy.env.outCoordinateSystem làm cho đầu ra trông hợp lý. không hiểu nhiều về làm thế nào
yosukesabai

1
Bạn đã không hỏi về NoData, bạn đã hỏi về tham chiếu không gian và kích thước ô. Các arcpy.NumPyArrayToRaster phương pháp có một tham số value_to_nodata.
dùng2856

Luke, cảm ơn bạn đã chỉnh sửa. Tôi đã thử phương pháp của bạn để cung cấp đối số thứ 5 (value_to_nodata), nhưng tôi vẫn mang lại con số ở trên cùng (ô gật đầu chứa 0 hoặc 255 và không được đặt cho raster đầu ra). cách giải quyết duy nhất tôi tìm thấy là đặt env.outputCoordinateSystem trước NumPyArrayToRaster, thay vì sử dụng DefineProjection_man quản lý sau đó. Nó không có ý nghĩa tại sao điều này hoạt động, nhưng tôi chỉ đi với giải pháp của tôi. Cảm ơn bạn vì tất cả sự giúp đỡ.
yosukesabai

1

Tôi gặp một số vấn đề khi nhận ArcGIS để xử lý các giá trị NoData một cách chính xác với các ví dụ được hiển thị ở đây. Tôi đã mở rộng ví dụ từ blog reomtesensing.io (ít nhiều giống với các giải pháp được hiển thị ở đây) để xử lý tốt hơn NoData.

Rõ ràng ArcGIS (10.1) thích giá trị -3.40282347e + 38 là NoData. Vì vậy, tôi chuyển đổi qua lại giữa NaN numpy và -3.40282347e + 38. Mã ở đây:

import arcpy
import numpy as np

infile  = r'C:\data.gdb\test_in'
outfile = r'C:\data.gdb\test_out'

# read raster with No Data as numpy NaN
in_arr  = arcpy.RasterToNumPyArray(infile,nodata_to_value = np.nan)

# processing
out_arr = in_arr * 10

# convert numpy NaN to -3.40282347e+38
out_arr[np.isnan(out_arr)] = -3.40282347e+38

# information on input raster
spatialref = arcpy.Describe(infile).spatialReference
cellsize1  = arcpy.Describe(infile).meanCellHeight
cellsize2  = arcpy.Describe(infile).meanCellWidth
extent     = arcpy.Describe(infile).Extent
pnt        = arcpy.Point(extent.XMin,extent.YMin)

# save raster
out_ras = arcpy.NumPyArrayToRaster(out_arr,pnt,cellsize1,cellsize2, -3.40282347e+38)
out_ras.save(outfile)
arcpy.DefineProjection_management(outfile, spatialref)
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.