Membuat raster dengan secara acak memilih nilai sel dari beberapa raster yang tumpang tindih?

10

Saya menggunakan ArcGIS Desktop 10 dengan ekstensi Spatial Analyst-nya.

Bagaimana cara menggabungkan beberapa raster menjadi satu, selalu memilih secara acak dari nilai sel yang tumpang tindih?

Saya memiliki gambar yang dapat menjelaskan hal ini dengan lebih baik:

contoh

Sam
sumber

Jawaban:

7

Pilih dibuat untuk masalah seperti ini. Anggap saja sebagai "switch" (atau "case") versi "con", yang merupakan implementasi aljabar peta "jika ... yang lain."

Jika ada 3 raster yang tumpang tindih, misalnya, sintaks (Python) akan terlihat seperti

inPositionRaster = 1 + int(3 * CreateRandomRaster())
Pick(inPositionRaster, [inRas01, inRas02, inRas03])

Perhatikan bahwa pickmulai mengindeks pada 1, bukan 0.


Edit

(lihat utas komentar)

Untuk mengatasi nilai-nilai NoData, pertama-tama Anda harus mematikan penanganan NoData ArcGIS. Lakukan ini dengan membuat kisi-kisi yang memiliki nilai khusus (tetapi valid) sebagai pengganti NoData, seperti 99999 (atau apa pun: tetapi pastikan untuk memilih nilai yang lebih besar daripada angka valid apa pun yang dapat muncul: ini akan berguna nanti) . Ini membutuhkan penggunaan permintaan IsNull, seperti pada

p01 = Con(IsNull(inRas01), 99999, inRas01)
p02 = Con(IsNull(inRas02), 99999, inRas01)
p03 = Con(IsNull(inRas03), 99999, inRas01)

Sebagai contoh, perhatikan kasus kisi-kisi satu baris ini (NoData ditampilkan sebagai "*"):

inRas01:  1  2 19  4  *  *  *  *
inRas02:  9  2  *  * 13 14  *  *
inRas03: 17  *  3  * 21  * 23  *

Hasilnya adalah menempatkan 99999 di tempat masing-masing "*".

Selanjutnya, bayangkan semua raster ini sebagai susunan datar balok kayu dengan NoData yang sesuai dengan blok yang hilang (lubang). Ketika Anda menumpuk raster ini secara vertikal, blok akan jatuh ke lubang di bawahnya. Kita memerlukan perilaku itu untuk menghindari memilih nilai NoData: kita tidak ingin ada celah vertikal di tumpukan blok. Urutan blok di setiap menara tidak terlalu penting. Untuk tujuan ini, kami dapat memperoleh setiap menara dengan memberi peringkat data :

q01 = Rank(1, [p01, p02, p03])
q02 = Rank(2, [p01, p02, p03])
q03 = Rank(3, [p01, p02, p03])

Dalam contoh, kita memperoleh

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

Perhatikan bahwa peringkat berasal dari terendah ke tertinggi, sehingga q01 berisi nilai terendah di setiap lokasi, q02 berisi terendah kedua, dll. Kode NoData tidak mulai muncul sampai semua angka yang valid dikumpulkan, karena kode-kode itu yang lebih besar daripada angka yang valid.

Untuk menghindari mengambil kode NoData ini selama pemilihan acak, Anda perlu tahu berapa banyak blok yang ditumpuk di setiap lokasi: ini memberi tahu kami berapa banyak nilai yang valid terjadi. Salah satu cara untuk mengatasinya adalah dengan menghitung jumlah kode NoData dan kurangi dari jumlah total kisi pilihan:

n0 = 3 - EqualToFrequency(99999, [q01, q02, q03])

Ini menghasilkan

n0:       3 2 2 1 2 1 1 0

Untuk menangani case di mana n = 0 (jadi tidak ada yang tersedia untuk dipilih), atur ke NoData:

n = SetNull(n0 == 0, n0)

Sekarang

n:        3 2 2 1 2 1 1 *

Ini juga akan menjamin bahwa kode NoData (sementara) Anda hilang dalam perhitungan akhir. Hasilkan nilai acak antara 1 dan n:

inPositionRaster = 1 + int(n * CreateRandomRaster())

Misalnya, raster ini mungkin terlihat seperti

inPositionRaster: 3 2 1 1 2 1 1 *

Semua nilainya terletak di antara 1 dan nilai yang sesuai di [n].

Pilih nilai persis seperti sebelumnya:

selection = Pick(inPositionRaster, [q01, q02, q03])

Ini akan menghasilkan

selection:       17  2  3  4 21 14 23  *

Untuk memeriksa apakah semuanya baik-baik saja, coba pilih semua sel keluaran yang memiliki kode NoData (99999 dalam contoh ini): seharusnya tidak ada.

Meskipun contoh yang sedang berjalan ini hanya menggunakan tiga kisi untuk dipilih, saya telah menulisnya dengan cara yang mudah digeneralisasikan ke sejumlah kisi. Dengan banyak kisi, menulis skrip (untuk mengulangi operasi yang diulang) akan sangat berharga.

whuber
sumber
Apakah Anda tahu bagaimana saya bisa mengabaikan nilai NoData dari perhitungan (dengan Raster Calculator dan Python)?
Sam
Sam, "Abaikan" bagaimana, tepatnya? Saya percaya perilaku default adalah untuk mengeluarkan NoData di mana pun satu atau lebih raster input adalah NoData (tapi saya tidak sepenuhnya yakin tentang hal itu dalam kasus pick: jika inPositionRaster dan raster yang dipilih keduanya memiliki nilai yang valid di dalam sel, maka masuk akal hasilnya untuk sel itu haruslah nilai dari raster yang dipilih, terlepas dari apa pun yang mengandung raster lain). Apa perilaku alternatif yang Anda pikirkan?
whuber
Saya hanya perlu memilih dari seluruh nilai angka. Katakanlah saya punya tiga raster. Untuk sel, nilainya adalah sebagai berikut: 4,5, NoData. Saya ingin outraster memiliki 4 atau 5 di sel itu tetapi tidak pernah NoData.
Sam
Saya mengalami masalah untuk membuat 1 + Int (n * CreateRandomRaster ()) ini berfungsi.
Sam
"Masalah" dalam arti apa? Harap spesifik!
Whuber
4

Menggunakan python dan ArcGIS 10 dan menggunakan fungsi con yang memiliki sintaks berikut:

Con (in_conditional_raster, in_true_raster_or_constant, {in_false_raster_or_constant}, {where_clause})

Idenya di sini adalah untuk melihat apakah nilai dalam raster acak kurang dari 0,5, jika pilih raster1, jika tidak pilih raster2. NoData+ data = NoDatajadi pertama-tama atur ini, reklasifikasi nilai apa saja dengan NoDatake 0:

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

EDIT: Baru sadar bahwa Anda tidak menambahkan NoDatanilai sehingga potongan itu bisa ditinggalkan.

djq
sumber
Saya masih mengerjakan keterampilan Python saya. Apakah ada cara untuk memasukkan ini ke dalam Kalkulator Raster yang juga akan mengecualikan nilai NoData dari proses? Saya memiliki 10 raster dan beberapa memiliki NoData di mana orang lain memiliki nilai.
Sam
Saya pikir Anda dapat membuat kondisi menggunakan sesuatu seperti ini di kalkulator rasterCon(IsNull(ras1), 0, ras2)
djq
Sayangnya, ini tidak mengecualikan nilai-nilai NoData: itu hanya menggantikannya dengan nol. Dalam beberapa kasus yang mungkin sesuai, tetapi mungkin tidak di sini!
Whuber
hmm, poin bagus @whuber. Jadi apa artinya tidak termasuk NoData? Apakah hanya untuk memastikan bahwa mereka tidak dipilih ketika memilih secara acak?
djq
Begitulah cara saya menafsirkannya (lihat jawaban saya yang diedit di utas ini), tetapi itu tetap merupakan pertanyaan yang bagus. Mengabaikan nilai ND dengan cara ini menyebabkan grid yang tersisa dipilih dengan probabilitas lebih besar, yang mungkin merupakan efek samping yang tidak diinginkan. Itu semua tergantung pada tujuan perhitungan.
whuber
1

Saya hanya akan membuat raster acak ( bantuan ) dengan tingkat dan ukuran sel yang sama. Kemudian menggunakan CON ( help ) atur untuk memilih nilai dari raster 1 jika sel dari raster acak memiliki nilai <128 (jika raster acak bernilai 0 - 255) jika tidak pilih nilai dari raster ke-2.

Harapan itu masuk akal :)

jareks
sumber
Apakah Anda tahu cara memilih dari raster dengan nilai saja? Misalnya dalam gambar saya ada empat 2 dan dua 3 yang tumpang tindih dengan NoData. Saya ingin memastikan itu hanya memilih dari raster dengan nilai pada sel dan bukan pada NoData.
Sam
Maaf karena tidak merespons. Apakah Anda masih berjuang dengan masalah NoData?
jareks