使用arcpy.RasterToNumPyArray保持空间参考?


13

我正在使用ArcGIS 10.1,并想基于两个现有的栅格创建一个新栅格。该RasterToNumPyArray有,我要适应一个很好的例子。

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

问题在于它会剥夺空间参考以及像元大小。我认为它必须做arcpy.env,但是如何根据输入栅格设置它们呢?我想不明白。


接受卢克的回答,这是我的解决方案。

Luke的两种解决方案都可以正确设置空间参考,范围和像元大小。但是第一种方法不能正确地在数组中传送数据,并且输出栅格到处都填充有nodata。他的第二种方法大多数情况下都有效,但是在我的无数据区域很大的地方,它填充有块状零和255。这可能与我处理nodata单元的方式有关,而且我不太确定自己的操作方式(尽管应该是另一个Q)。我包括了我正在谈论的图像。

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

该图显示了结果。两种情况下,无数据单元均显示为黄色。

路加的第二种方法 路加的第二种方法

我的尝试方法 我的尝试方法

Answers:


15

查看Describe方法。

像下面这样的东西应该起作用。

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

要么

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

编辑:arcpy.NumPyArrayToRaster方法采用value_to_nodata参数。像这样使用它:

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)

卢克,谢谢你的回答。在我看来,我需要将您的两种方法混合使用吗?两种方法都可以设置范围,spref等正确,但是无法正确排列数据...第一种方法使所有单元格均为无数据。第二种方法效果更好,但是它们似乎无法正确处理myArray中的nodata单元格(抱歉,我没有告诉我的单元格具有一些nodata,我想保持它们不变)。一些尝试和错误使我认为我必须采取第二种方法,但是arcpy.env.outCoordinateSystem使输出看起来合理。虽然怎么做的了解不多。
yosukesabai 2012年

1
您没有询问NoData,而是询问了空间参考和像元大小。该arcpy.NumPyArrayToRaster方法接受value_to_nodata参数。
user2856

卢克,谢谢编辑。我尝试了提供第5个参数(value_to_nodata)的方法,但仍在顶部生成了该图(nodata像元填充了0或255,并且未为输出栅格设置nodata_value)。我发现的唯一解决方法是在NumPyArrayToRaster之前设置env.outputCoordinateSystem,而不是在之后使用DefineProjection_management。它为什么行不通没有道理,但我只是采用我的解决方案。感谢您的所有帮助。
yosukesabai 2012年

1

使用此处显示的示例,在使ArcGIS正确处理NoData值时遇到一些问题。我将示例从reomtesensing.io博客(或多或少与此处显示的解决方案类似)扩展为更好地处理NoData。

显然,ArcGIS(10.1)喜欢将值-3.40282347e + 38用作NoData。所以我在numpy NaN和-3.40282347e + 38之间来回转换。代码在这里:

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.