รักษาการอ้างอิงเชิงพื้นที่โดยใช้ 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 แต่ฉันจะตั้งพวกมันตามอินพุตแรสเตอร์ได้อย่างไร ฉันไม่สามารถคิดออก


รับคำตอบของลุคนี่คือวิธีแก้ปัญหาเบื้องต้นของฉัน

โซลูชันทั้งสองของลุคตั้งค่าการอ้างอิงขอบเขตและขนาดเซลล์อย่างถูกต้อง แต่วิธีแรกไม่ได้เก็บข้อมูลในอาเรย์อย่างถูกต้องและเอาท์พุทแรสเตอร์เต็มไปด้วยข้อมูลทั้งหมด วิธีที่สองของเขาใช้งานได้เป็นส่วนใหญ่ แต่ที่ฉันมีพื้นที่ขนาดใหญ่ของโนดาต้ามันเต็มไปด้วยศูนย์บล็อกและ 255s สิ่งนี้อาจเกี่ยวข้องกับวิธีที่ฉันจัดการเซลล์โนดาต้าและฉันก็ค่อนข้างแน่ใจว่าฉันกำลังทำมันอย่างไร (ควรเป็น 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) 

ภาพแสดงผลลัพธ์ ฉันทั้งสองกรณีเซลล์โนดาต้าแสดงเป็นสีเหลือง

วิธีที่สองของลุค วิธีที่สองของลุค

วิธีการชั่วคราวของฉัน วิธีการชั่วคราวของฉัน

คำตอบ:


15

ลองดูวิธีอธิบาย

สิ่งต่อไปนี้ควรใช้งานได้

#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 และฉันต้องการรักษาความสมบูรณ์เหล่านั้นไว้) การทดลองและข้อผิดพลาดบางอย่างทำให้ฉันคิดว่าฉันต้องใช้แนวทางที่สอง แต่ arcpy.env.outCoordinateSystem ทำให้ผลลัพธ์มีความสมเหตุสมผล ไม่ค่อยเข้าใจเท่าไหร่
yosukesabai

1
คุณไม่ได้ถามเกี่ยวกับ NoData คุณถามเกี่ยวกับการอ้างอิงเชิงพื้นที่และขนาดของเซลล์ กระบวนการarcpy.NumPyArrayToRasterวิธีใช้พารามิเตอร์ value_to_nodata
2856

ลุคขอบคุณสำหรับการแก้ไข ฉันลองวิธีการของคุณในการให้ข้อโต้แย้งที่ 5 (value_to_nodata) แต่ฉันยังคงให้รูปที่ด้านบน (เซลล์ nodata ที่เต็มไปด้วย 0 หรือ 255 และ nodata_value ไม่ได้ถูกตั้งค่าสำหรับเอาท์พุทแรสเตอร์) วิธีแก้ปัญหาเดียวที่ฉันพบคือตั้งค่า env.outputCoordinateSystem ก่อน NumPyArrayToRaster แทนที่จะใช้ DefineProject_management หลังจากนั้น มันไม่สมเหตุสมผลว่าทำไมมันถึงใช้ได้ แต่ฉันแค่ไปหาทางออก ขอบคุณสำหรับความช่วยเหลือทั้งหมด
yosukesabai

1

ฉันมีปัญหาในการรับ ArcGIS เพื่อจัดการค่า NoData อย่างถูกต้องด้วยตัวอย่างที่แสดงที่นี่ ฉันขยายตัวอย่างจากบล็อกreomtesensing.io (ซึ่งคล้ายกันมากขึ้นหรือน้อยลงคล้ายกับโซลูชันที่แสดงที่นี่) เพื่อจัดการ NoData ได้ดียิ่งขึ้น

เห็นได้ชัดว่า ArcGIS (10.1) ชอบค่า -3.40282347e + 38 เป็น NoData ดังนั้นฉันจึงแปลงกลับไปกลับมาระหว่าง NaN และ Numpy ที่ -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.