Arcpy.RasterToNumPyArray kullanarak uzamsal başvuru tutuyor musunuz?


13

ArcGIS 10.1 kullanıyorum ve önceden varolan iki rasterden oluşan yeni bir raster oluşturmak istiyorum. RasterToNumPyArray Adapte istiyorum iyi bir örnek vardır.

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

Sorun uzamsal referansı ve aynı zamanda hücre büyüklüğünü çıkarmasıdır. Arcpy.env yapmak zorunda olduğunu düşündüm, ancak bunları giriş rasterine göre nasıl ayarlayabilirim? Ne olduğunu anlayamıyorum.


Luke'un cevabını alarak, bu benim geçici çözümüm.

Luke'un her iki çözümü de uzamsal referansı, kapsamı ve hücre boyutunu doğru şekilde ayarladı. Ancak ilk yöntem dizideki verileri doğru bir şekilde taşımadı ve çıktı raster her yerde nodata ile dolduruldu. İkinci yöntemi çoğunlukla işe yarıyor, ancak büyük nodata bölgesine sahip olduğumda, bloklu sıfırlar ve 255'ler ile dolduruyor. Bu nasıl nodata hücreleri ele ile ilgili olabilir ve ben nasıl (ben başka bir Q olsa olmalıdır) nasıl yaptığını tam olarak emin değilim. Bahsettiğim şeylerin resimlerini ekledim.

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

Sonuçları gösteren resim. Her iki durumda da nodata hücreleri sarı gösterilir.

Luke'un ikinci yöntemi Luke'un ikinci yöntemi

Geçici yöntemim Geçici yöntemim

Yanıtlar:


15

Tanımlama yöntemine göz atın .

Aşağıdaki gibi bir şey çalışması gerekir.

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

VEYA

#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: arcpy.NumPyArrayToRaster yöntemi bir value_to_nodata parametresi alır. Şöyle kullanın:

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, Cevabınız için teşekkür ederim. Bana öyle geliyor ki iki yönteminden karma bir şey yapmam gerekiyor? Her iki yöntem de kapsam, spref vb. Değerlerini doğru ayarlar, ancak verileri doğru bir şekilde sıralayamaz ... İlk yöntem tüm hücrenin nodata olmasını sağlar. İkinci yöntem daha iyi çalışır, ancak onlar myArray nodata hücreleri doğru işlemek gibi görünmüyor (üzgünüm benim hücre bazı nodata olduğunu söylemedim ve bu bozulmadan tutmak istiyorum). Bazı deneme yanılma, ikinci yaklaşımı benim almam gerektiğini düşündürdü, ancak arcpy.env.outCoordinateSystem çıktıların makul görünmesini sağlıyor. nasıl olsa çok fazla anlayış yok.
yosukesabai

1
NoData hakkında soru sormadınız, uzamsal referans ve hücre boyutu hakkında sorular sordunuz. Arcpy.NumPyArrayToRaster yöntemi value_to_nodata parametresini alır.
user2856

Luke, Düzenlediğiniz için teşekkürler. 5. bağımsız değişken (value_to_nodata) sağlama yönteminizi denedim, ancak yine de üstte rakam verdim (0 veya 255 ile dolu nodata hücresi ve nodata_value çıktı raster için ayarlanmadı). bulduğum tek geçici çözüm daha sonra DefineProjection_management kullanmak yerine, env.outputCoordinateSystem'ı NumPyArrayToRaster'dan önce ayarlamaktı. Bunun neden işe yaradığı mantıklı değil, ama sadece çözümümle devam ediyorum. tüm yardımlarınız için teşekkür ederim.
yosukesabai

1

Burada gösterilen örneklerle ArcGIS NoData değerlerini doğru işlemek için bazı sorunlar vardı. Daha iyi NoData işlemek için reomtesensing.io blog (burada gösterilen çözümlere az ya da çok benzer olan) örneği genişletti.

Görünüşe göre ArcGIS (10.1) -3.40282347e + 38 değerini NoData olarak seviyor. Bu yüzden, NaN ve -3.40282347e + 38 arasında ileri geri dönüş yapıyorum. Kod burada:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.