Yanıtlar:
Seçim , bunun gibi sorunlar için oluşturuldu. Bunu, "if ... else" nin harita cebir uygulaması olan "con" un "switch" (veya "case") sürümü olarak düşünün.
Örneğin, 3 çakışan raster varsa, (Python) sözdizimi şöyle görünür
inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])
pick
Dizine eklemenin 0 değil 1'de başladığını unutmayın .
(yorum başlığına bakın)
NoData değerleriyle başa çıkmak için, önce ArcGIS'in NoData işlemesini kapatmanız gerekir. 99999 (veya her neyse: gibi NoData yerine özel (ancak geçerli) bir değere sahip ızgaralar oluşturarak bunu yapın, ancak görüntülenebilecek herhangi bir geçerli sayıdan daha büyük bir değer seçtiğinizden emin olun : bu daha sonra kullanışlı olacaktır) . Bu , olduğu gibi IsNull isteğinin kullanılmasını gerektirir
p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)
Örneğin, bu tek satırlı ızgaraların durumunu göz önünde bulundurun (NoData "*" olarak gösterilir):
inRas01: 1 2 19 4 * * * *
inRas02: 9 2 * * 13 14 * *
inRas03: 17 * 3 * 21 * 23 *
Sonuç, her "*" yerine 99999 konulmasıdır.
Daha sonra, tüm bu rasterleri, eksik bloklara (deliklere) karşılık gelen NoData ile ahşap blokların düz dizileri olarak hayal edin. Bu rasterleri dikey olarak istiflediğinizde, bloklar altındaki deliklere düşecektir. NoData değerlerini seçmekten kaçınmak için bu davranışa ihtiyacımız var: blok yığınlarında dikey boşluk istemiyoruz. Her kuledeki blokların sırası gerçekten önemli değil. Bu amaçla, her bir kuleyi verileri sıralayarak elde edebiliriz :
q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])
Örnekte,
q01: 1 2 3 4 13 14 23 99999
q02: 9 2 19 99999 21 99999 99999 99999
q03: 17 99999 99999 99999 99999 99999 99999 99999
Sıraların en düşükten en yükseğe doğru olduğunu unutmayın, böylece q01 her konumdaki en düşük değerleri içerir, q02 ikinci en düşük değeri içerir, vb. NoData kodları geçerli tüm sayılar toplanana kadar görünmez. Hangi büyük herhangi bir geçerli sayılar daha.
Rastgele seçim sırasında bu NoData kodlarını seçmekten kaçınmak için, her bir konumda kaç blok istiflendiğini bilmeniz gerekir: bu bize kaç geçerli değerin oluştuğunu gösterir. Bunu işlemenin bir yolu , NoData kodlarının sayısını saymak ve toplam seçim ızgarası sayısından çıkarmaktır:
n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])
Bu,
n0: 3 2 2 1 2 1 1 0
N = 0 olan durumları işlemek için (böylece seçilebilecek hiçbir şey yoktur), bunları NoData olarak ayarlayın:
n = SetNull(n0 == 0, n0)
şimdi
n: 3 2 2 1 2 1 1 *
Bu aynı zamanda (geçici) NoData kodlarınızın son hesaplamada kaybolmasını garanti eder. 1 ve n arasında rasgele değerler oluşturun:
inPositionRaster = 1 + int(n * CreateRandomRaster())
Örneğin, bu tarama
inPositionRaster: 3 2 1 1 2 1 1 *
Tüm değerleri 1 ile [n] 'deki karşılık gelen değer arasındadır.
Değerleri aynen önceki gibi seçin:
selection = Pick(inPositionRaster, [q01, q02, q03])
Bu sonuç
selection: 17 2 3 4 21 14 23 *
Her şeyin yolunda olduğunu kontrol etmek için, NoData koduna sahip tüm çıkış hücrelerini seçmeyi deneyin (bu örnekte 99999): herhangi bir öğe olmamalıdır.
Bu çalışan örnek, seçim için yalnızca üç ızgara kullanıyor olsa da, herhangi bir sayıda ızgaraya kolayca genelleştirilecek şekilde yazdım. Çok sayıda ızgara olduğunda, bir komut dosyası yazmak (tekrarlanan işlemler üzerinde döngü yapmak için) çok değerli olacaktır.
pick
: inPositionRaster ve seçilen raster her ikisi de bir hücrede geçerli değerler varsa, daha sonra sonuç çünkü bu hücre, diğer rasterlerin neler içerdiğine bakılmaksızın seçilen raster değeri olmalıdır). Hangi alternatif davranışı düşünüyorsunuz?
Python ve ArcGIS 10 kullanarak ve aşağıdaki sözdizimine sahip con işlevini kullanarak :
Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})
Buradaki fikir, rastgele taramadaki değerin 0,5'ten düşük olup olmadığını, raster1'i seçiyorsa, aksi takdirde raster2'yi seçmektir. NoData
+ data = NoData
bu yüzden önce bu değerleri NoData
0 ile yeniden sınıflandırır :
import arcpy
from arcpy import env
from arcpy.sa import *
env.workspace = "C:/sapyexamples/data"
ras1_NoNull = Con(IsNull("elevation1"),0, "elevation1") # remove NoData
ras2_NoNull = Con(IsNull("elevation2"),0, "elevation2") # remove NoData
randRaster = CreateRandomRaster(100, 2, Extent(0, 0, 150, 150)) # raster generated between 0 and 1; 100 is seed value
outCon = Con(randRaster < 0.5, ras1_NoNull, ras2_NoNull)
outCon.save("C:/outcon.img") # save raster
DÜZENLEME: NoData
Değerleri eklemediğinizden fark ettiniz, böylece parça dışarıda bırakılabilir.
Con(IsNull(ras1), 0, ras2)
NoData
? Sadece rastgele seçerken seçilmemelerini sağlamak mı?
Ben sadece aynı ölçüde ve hücre boyutunda rastgele bir tarama ( yardım ) yaratacağım . Daha sonra CON ( yardım ) kullanarak , randomize taramadan alınan hücrenin değeri <128 ise (rastgele tarama 0 - 255 ise) 1. taramadan değer almaya ayarlayın, aksi takdirde 2. taramadan bir değer seçin.
Umarım mantıklıdır :)