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가있는 곳에서는 블록 0과 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) 

결과를 보여주는 이미지. 두 경우 모두 nodata 셀이 노란색으로 표시됩니다.

누가의 두 번째 방법 누가의 두 번째 방법

나의 잠정적 인 방법 나의 잠정적 인 방법

답변:


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 등을 올바르게 설정하지만 데이터를 올바르게 배열하지 못합니다 ... 첫 번째 방법은 모든 셀을 nodata로 만듭니다. 두 번째 방법은 더 잘 작동하지만 myArray의 nodata 셀을 올바르게 처리하지 못하는 것 같습니다 (죄송합니다. 내 셀에 nodata가 있다고 말하지 않았으며 그대로 유지하려고합니다). 일부 시행 착오로 인해 두 번째 접근 방식을 취해야한다고 생각했지만 arcpy.env.outCoordinateSystem은 출력을 합리적으로 보입니다. 어떻게 그렇게 많이 이해하지 못합니다.
yosukesabai

1
NoData에 대해서는 묻지 않았으며 공간 참조 및 셀 크기에 대해 문의했습니다. arcpy.NumPyArrayToRaster의 방법은 value_to_nodata 파라미터 걸린다.
user2856

루크, 편집 해줘서 고마워 나는 다섯 번째 인수 (value_to_nodata)를 제공하는 방법을 시도했지만 여전히 맨 위에 그림을 산출했습니다 (0 또는 255로 채워진 nodata 셀은 출력 래스터에 대해 nodata_value가 설정되지 않았습니다). 내가 찾은 유일한 해결 방법은 나중에 DefineProjection_management를 사용하는 대신 NumPyArrayToRaster보다 env.outputCoordinateSystem을 설정하는 것입니다. 왜 이것이 효과가 있는지 이해가되지 않지만 나는 단지 내 해결책을 따라갑니다. 모든 도움에 감사드립니다.
yosukesabai

1

여기에 표시된 예제를 사용하여 ArcGIS가 NoData 값을 올바르게 처리하는 데 문제가있었습니다. NoData 를 더 잘 처리하기 위해 reomtesensing.io 블로그 (여기에 표시된 솔루션과 다소 유사) 의 예제를 확장했습니다 .

분명히 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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.