arcpy.RasterToNumPyArrayを使用して空間参照を保持しますか?


13

ArcGIS 10.1を使用していて、2つの既存のラスターに基づいて新しいラスターを作成したい。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が入力されます。彼の2番目の方法はほとんど動作しますが、nodataの大きな領域がある場合は、ブロック状のゼロと255で埋められます。これは、nodataセルをどのように処理したかに関係している可能性があります。私が話していることの画像を含めました。

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

結果を示す画像。どちらの場合も、nodataセルは黄色で表示されます。

ルークの2番目の方法 ルークの2番目の方法

私の仮の方法 私の仮の方法

回答:


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)

ルーク、答えてくれてありがとう。私はあなたの2つの方法のハイブリッドをする必要があるように見えますか?どちらの方法もエクステントやsprefなどを正しく設定しますが、データを正しく配列できません...最初の方法では、すべてのセルがnodataになります。2番目の方法はよりうまく機能しますが、myArrayのnodataセルを正しく処理しないようです(セルにnodataがあることを伝えなかったので、そのままにしておきたい)。試行錯誤の結果、2番目のアプローチをとる必要があると思われましたが、arcpy.env.outCoordinateSystemは出力を合理的に見せます。ただし、その方法はあまり理解されていません。
ヨスケサバイ

1
NoDataについては質問せず、空間参照とセルサイズについて質問しました。arcpy.NumPyArrayToRasterの方法はvalue_to_nodataパラメータを取ります。
user2856

ルーク、編集ありがとうございます。5番目の引数(value_to_nodata)を指定する方法を試してみましたが、それでも上部に数字が表示されました(0または255で塗りつぶされたnodataセル、および出力ラスターにnodata_valueが設定されていません)。私が見つけた唯一の回避策は、後でDefineProjection_managementを使用する代わりに、NumPyArrayToRasterの前にenv.outputCoordinateSystemを設定することでした。なぜこれが機能するのか理解できませんが、私は自分のソリューションを採用しています。すべての助けてくれてありがとう。
ヨスケサバイ

1

ここに示す例では、ArcGISでNoData値を正しく処理するのに問題がありました。reomtesensing.ioブログ(ここに示すソリューションに多少似ています)の例を拡張して、NoDataの処理を改善しました。

どうやらArcGIS(10.1)はNoDataとして値-3.40282347e + 38を好みます。したがって、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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.