Lihat tautan ini untuk lebih jelasnya.
Masalah:
Saya ingin mengulang melalui raster berkelanjutan (yang tidak memiliki tabel atribut), sel demi sel, dan mendapatkan nilai sel. Saya ingin mengambil nilai-nilai itu dan menjalankan persyaratannya, meniru langkah-langkah aljabar peta yang dirinci di bawah ini tanpa benar-benar menggunakan kalkulator raster.
Per permintaan komentar di bawah ini, saya telah menambahkan detail yang memberikan latar belakang masalah dan membenarkan perlunya menerapkan metode seperti pada bagian di bawah ini yang disebut "Analisis yang diperlukan:".
Analisis yang diajukan di bawah ini, meskipun relevan dengan masalah saya dengan memberikan latar belakang, tidak perlu diimplementasikan dalam jawaban. Ruang lingkup pertanyaan hanya berkaitan dengan iterasi melalui raster berkelanjutan untuk mendapatkan / menetapkan nilai sel.
Analisis yang dibutuhkan:
Jika salah satu dari kondisi berikut terpenuhi, berikan sel output nilai 1. Hanya beri sel output nilai 0 jika tidak ada kondisi yang terpenuhi.
Kondisi 1: Jika nilai sel lebih besar dari sel atas dan bawah, beri nilai 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Di mana file kernel terlihat seperti ini:
3 3
0 1 0
0 0 0
0 1 0
Kondisi 2: Jika nilai sel lebih besar dari sel kiri dan kanan, beri nilai 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Di mana file kernel terlihat seperti ini:
3 3
0 0 0
1 0 1
0 0 0
Kondisi 3: Jika nilai sel lebih besar dari sel topleft dan bottomright, beri nilai 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Di mana file kernel terlihat seperti ini:
3 3
1 0 0
0 0 0
0 0 1
Kondisi 4: Jika nilai sel lebih besar dari bottomleft dan sel topright, beri nilai 1:
Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)
Di mana file kernel terlihat seperti ini:
3 3
0 0 1
0 0 0
1 0 0
Kondisi 5: Jika salah satu sel yang berdekatan memiliki nilai EQUAL untuk sel pusat, berikan nilai raster nilai 1 ( menggunakan varietas fokus dengan dua perhitungan lingkungan terdekat )
Mengapa tidak menggunakan aljabar peta?
Telah dicatat di bawah ini bahwa masalah saya dapat diselesaikan dengan menggunakan aljabar peta tetapi seperti yang terlihat di atas ini adalah total dari enam perhitungan raster, ditambah satu untuk menggabungkan semua raster yang dibuat bersama-sama. Menurut saya, jauh lebih efisien untuk melakukan sel demi sel dan melakukan semua perbandingan sekaligus di setiap sel daripada mengulangi masing-masing secara terpisah tujuh kali dan menggunakan sedikit memori untuk membuat tujuh raster.
Bagaimana seharusnya masalah diserang?
Tautan di atas menyarankan untuk menggunakan antarmuka IPixelBlock, namun tidak jelas dari dokumentasi ESRI apakah Anda benar-benar mengakses nilai sel tunggal itu sendiri melalui IPixelBlock, atau jika Anda mengakses beberapa nilai sel dari ukuran IPixelBlock yang Anda atur. Sebuah jawaban yang baik harus menyarankan metode untuk mengakses nilai-nilai sel raster terus menerus dan memberikan penjelasan tentang metodologi di balik kode, jika tidak jelas.
Singkatnya:
Apa metode terbaik untuk loop melalui setiap sel dalam raster TERUS-MENERUS (yang tidak memiliki tabel atribut ) untuk mengakses nilai selnya?
Jawaban yang baik tidak perlu mengimplementasikan langkah-langkah analisis yang dijelaskan di atas, hanya perlu menyediakan metodologi untuk mengakses nilai sel raster.
Jawaban:
Saya melihat ini telah dipecahkan oleh Original Poster (OP), tetapi saya akan memposting solusi sederhana dengan python kalau-kalau ada orang di masa depan yang tertarik pada berbagai cara untuk menyelesaikan masalah ini. Saya sebagian menggunakan perangkat lunak sumber terbuka, jadi inilah solusi menggunakan GDAL dalam python:
Terapkan fungsi seperti ini:
Kemudian, ulangi data Anda dengan loop bersarang:
Atau mungkin Anda ingin meratakan array 2-D Anda dengan pemahaman daftar:
Bagaimanapun, saat iterasi melalui data pada sel-demi-sel itu mungkin untuk melemparkan beberapa kondisional ke dalam loop Anda untuk mengubah / mengedit nilai. Lihat skrip yang saya tulis untuk berbagai cara mengakses data: https://github.com/azgs/hazards-viewer/blob/master/python/zonal_stats.py .
sumber
Memperbarui! Solusi numpy:
Jadi, mendapatkan array yang sudah selesai kembali ke raster menggunakan arcpy merepotkan. arcpy.NumPyArrayToRaster tupai dan cenderung mendefinisikan ulang luasan bahkan jika Anda memberi makan koordinat LL Anda.
Saya lebih suka menyimpan sebagai teks.
Saya menjalankan Python sebagai 64 bit untuk kecepatan - pada saat ini ini berarti saya tidak dapat memberi makan numpy.savetxt header. Jadi saya harus membuka output dan menambahkan header ASCII yang diinginkan Arc sebelum mengubah ASCII ke Raster
Versi numpy menjalankan raster shift, perkalian, dan penambahan saya jauh lebih cepat (1000 iterations dalam 2 menit) daripada versi arcpy (1000 iterations dalam 15 menit)
VERSI LAMA Saya dapat menghapus ini nanti saya hanya menulis skrip yang sama. Saya mencoba mengonversi ke titik dan menggunakan kursor pencarian. Saya hanya mendapatkan 5.000 iterasi dalam 12 jam. Jadi, saya mencari cara lain.
Cara saya melakukan ini adalah beralih melalui koordinat pusat sel dari setiap sel. Saya mulai di sudut kiri atas dan bergerak ke kanan ke kiri. Di akhir baris saya bergerak ke bawah baris dan mulai lagi di sebelah kiri. Saya memiliki raster 240 m dengan 2603 kolom dan 2438 baris sehingga total total 6111844 sel. Saya menggunakan variabel iterator dan loop sementara. Lihat di bawah
Beberapa catatan: 1 - Anda perlu mengetahui koordinat sejauh ini
2 - jalankan dengan koordinat titik untuk pusat sel - pindahkan 1/2 ukuran sel dari nilai batas
3 - Skrip saya menggunakan nilai sel untuk menarik raster nilai tertentu, lalu menggeser raster ini ke pusat pada sel asli. Ini menambah raster nol untuk memperluas jangkauan sebelum menambahkan ke raster akhir. Ini hanya sebuah contoh. Anda bisa meletakkan pernyataan kondisional Anda di sini (pernyataan if kedua dalam loop while).
4 - Skrip ini mengasumsikan semua nilai raster dapat digunakan sebagai bilangan bulat. Ini berarti Anda harus menyingkirkan no data terlebih dahulu. Con IsNull.
6 - Saya masih tidak senang dengan ini dan saya berusaha untuk mengambil ini sepenuhnya dari arcpy. Saya lebih suka berperan sebagai array numpy dan melakukan matematika di sana kemudian membawanya kembali ke Arc.
sumber
Coba gunakan IGridTable, ICursor, IRow. Cuplikan kode ini untuk memperbarui nilai sel raster, namun ini menunjukkan dasar-dasar pengulangan:
Bagaimana saya bisa menambahkan bidang baru dalam tabel atribut raster dan mengulanginya?
Setelah Anda melintasi tabel, Anda bisa mendapatkan nilai baris bidang tertentu dengan menggunakan
row.get_Value(yourfieldIndex)
. Jika Anda GoogleAnda harus bisa mendapatkan banyak contoh yang menunjukkan ini.
Semoga itu bisa membantu.
sumber
Bagaimana ini sebagai ide radikal, Anda harus memprogram dalam python atau ArcObjects.
sumber
Sebuah solusi:
Saya menyelesaikan ini sebelumnya hari ini. Kode ini merupakan adaptasi dari metode ini . Konsep di balik ini tidak terlalu sulit setelah saya menemukan apa objek yang digunakan untuk berinteraksi dengan raster sebenarnya. Metode di bawah ini mengambil dua dataset input (inRasterDS dan outRasterDS). Keduanya merupakan dataset yang sama, saya baru saja membuat salinan inRasterDS dan meneruskannya ke metode seperti outRasterDS. Dengan cara ini mereka berdua memiliki tingkat yang sama, referensi spasial, dll. Metode ini membaca nilai-nilai dari dalamRasterDS, sel demi sel, dan melakukan perbandingan tetangga terdekat pada mereka. Ia menggunakan hasil perbandingan tersebut sebagai nilai yang disimpan di outRasterDS.
Proses:
Saya menggunakan IRasterCursor -> IPixelBlock -> SafeArray untuk mendapatkan nilai pixel dan IRasterEdit untuk menulis yang baru ke raster. Saat Anda membuat IPixelBlock, Anda memberi tahu mesin ukuran dan lokasi area yang ingin Anda baca / tulis. Jika Anda hanya ingin mengedit bagian bawah raster, Anda menetapkannya sebagai parameter IPixelBlock Anda. Jika Anda ingin mengulang seluruh raster, Anda harus mengatur IPixelBlock sama dengan ukuran seluruh raster. Saya melakukan ini dalam metode di bawah ini dengan mengirimkan ukuran ke IRasterCursor (pSize) kemudian mendapatkan PixelBlock dari kursor raster.
Kunci lainnya adalah Anda harus menggunakan SafeArray untuk berinteraksi dengan nilai-nilai dalam metode ini. Anda mendapatkan IPixelBlock dari IRasterCursor, lalu SafeArray dari IPixelBlock. Kemudian Anda membaca dan menulis ke SafeArray. Ketika Anda selesai membaca / menulis ke SafeArray, tulis seluruh SafeArray Anda kembali ke IPixelBlock, lalu tulis IPixelBlock Anda ke IRasterCursor, lalu akhirnya gunakan IRasterCursor untuk mengatur lokasi untuk mulai menulis dan IRasterEdit untuk melakukan penulisan itu sendiri. Langkah terakhir ini adalah tempat Anda benar-benar mengedit nilai dataset.
sumber
Data raster AFAIK dapat dibaca dalam tiga cara:
Tanpa menciptakan kembali roda, saya sarankan untuk membaca slide Chris Garrard yang mencerahkan ini .
Jadi metode yang paling efisien adalah membaca data dengan blok, namun ini akan menyebabkan hilangnya data dalam korespondensi piksel yang terletak di atas batas blok saat menerapkan filter. Jadi cara alternatif yang aman harus terdiri dari membaca seluruh gambar sekaligus dan menggunakan pendekatan numpy.
Di sisi komputasi, sebagai gantinya, saya harus menggunakan gdalfilter.py dan secara implisit pendekatan VRT KernelFilteredSource untuk menerapkan filter yang diperlukan dan, di atas semua itu, hindari perhitungan yang berat.
sumber