Menggabungkan beberapa baris dengan bidang nilai

Dec 09 2020

Bagaimana saya bisa menggabungkan baris ini tergantung pada bidang Pemicu. Syaratnya adalah sebagai berikut, field harus diurutkan dalam urutan menaik setelah field dari 1ke 68. Jadi, saya ingin menggabungkan semua baris saya dimulai dengan yang pertama yang memiliki pemicu 1 dan yang berikutnya yang memiliki nilai 0dan berhenti pada nilai pertama dengan 1dan mulai lagi.

Edit: Saya mengerti. Tapi bagaimana saya bisa mengatasi masalah ini? Bagaimana cara menggabungkan garis-garis ini? Trigger mengacu pada sudut. Jika 0 maka sudut antara 2 segmen kurang dari x derajat, dan jika 1 sudutnya lebih besar dari x derajat. Jadi, saya ingin jika baris pertama bukan pemicu, saya ingin menggabungkannya dengan baris pertama yang menjadi pemicu.

Jawaban

3 MrXsquared Dec 09 2020 at 19:48

Untuk memberi Anda gambaran bagaimana ini bisa dilakukan, berikut adalah solusi dengan Python untuk menambahkan bidang groupid baru, Anda dapat menggunakan untuk membubarkan baris Anda:

# Change your settings here:
layername = 'line' 
triggerfield = 'Trigger' # field must already exist
groupfieldname = 'mygroup' # will be added if does not exist
newlineindicator = 1

#####
# no changes needed below #
#####
layer = QgsProject.instance().mapLayersByName(layername)[0] # get the layer
layer.startEditing() # start editing the layer
layer.dataProvider().addAttributes([QgsField(groupfieldname,QVariant.Int)]) # add a group field
layer.commitChanges() # save new added field to prevent crash when searching for it later
layer.startEditing() # start editing the layer again
groupid = 0 # initialize groupid
fieldindex = layer.fields().indexFromName(groupfieldname) # get fieldindex of groupfield

for feat in layer.getFeatures(): # itereate over layer
    if feat[triggerfield] == newlineindicator: # if a new trigger appears, increase groupcounter
        groupid += 1
    attrs = { fieldindex : groupid } # prepare attributes
    layer.dataProvider().changeAttributeValues({ feat.id() : attrs }) # assign current groupid to current feature
layer.commitChanges() # save changes

Hasil:

3 Babel Dec 09 2020 at 21:08

Ada cara untuk membuat nilai bidang secara langsung menggunakan ekspresi QGIS di kalkulator bidang untuk mengelompokkan semua fitur yang ingin Anda gabungkan. Berdasarkan nilai bidang ini, Anda dapat menggunakan fungsi Aggregateuntuk menggabungkan fitur dengan nilai yang sama (lihat gambar kedua di bawah). Langkah bot harus mudah diotomatiskan dengan model.

Mengambil struktur data dan nama bidang Anda, ekspresi terlihat seperti ini (lihat di bawah untuk penjelasan cara kerja ekspresi):

array_last (
    array_sort (
        array_foreach (
            array_remove_all ( 
                array_agg ( 
                    if ( 
                        "trigger" = 1, 
                        "fid" , 
                        0
                    ) 
                ) ,
            0) ,
        if (
            if ( 
                "trigger" = 1, 
                "fid" , 
                0 
                ) = @element, 
                @element, 
                if (
                    "fid" > @element ,  
                    @element,0
                )
        )
        ) 
    )
)

Kemudian Anda dapat menggunakan bidang ini bersama dengan fungsi Menu Processing / Toolbox / Aggregateuntuk menggabungkan fitur-fitur ini.

Untuk menjelaskan ide di balik ekspresi: untuk pemahaman yang lebih baik, sebut saja "segmen-awal" dari garis yang digabungkan, Anda akhirnya ingin mendapatkan " kepala " - dan segmen berikutnya yang digabungkan dengannya sebagai " ekor ".

  1. Dapatkan nilai fid dari head , sebut saja " group-ids ". Tujuan akhirnya adalah untuk menetapkan setiap tail -segment ke head (atau: setiap ekor harus diberi nilai group-id dari head yang lebih kecil berikutnya : 2 dan 3 harus ditetapkan ke 1, 5 dan 6 ke 4 dll.) A) Jika pemicunya adalah 1 ( head ), dapatkan nilai id: ini adalah group-id . Lain (untuk ekor ) tetapkan nilai 0. b) Gabungkan nilai-nilai ini membuat sebuah larik. c) Hapus semua 0 nilai dari array. Jadi kita mendapatkan sebuah array group-id (= fid of heads ): [1,4,7,9,12]. Kami akhirnya ingin menetapkan setiap fitur ke salah satu nilai ini dari array.

  2. Sekarang lakukan iterasi pada semua fitur layer dengan masing-masing group-id ini dari array dengan ekspresi array_foreach: a) Untuk fitur dengan trigger = 1 ( heads ) kita tidak punya masalah, ini sudah memiliki group-id yang tepat (sesuai dengan fid mereka) b) Dalam kasus lain ( ekor , pemicu = 0), kita harus menetapkan nilai baru. Dengan demikian, kami membandingkan setiap nilai input dari array (daftar semua grup-id ) dengan fid dan mempertahankan grup-id jika lebih kecil dari fid (karena kami ingin menetapkan ke nilai yang lebih kecil berikutnya). Jika tidak, kita atur ke 0. Jadi tidak akan ada nilai dari array yang lebih besar dari fid.

  3. Urutkan array untuk memastikan kita memiliki nilai dalam urutan yang benar (terkecil ke terbesar) - untuk menghapus angka nol terakhir dari posisi terakhir (lihat gambar di bawah). Tanpa mengatur urutan sortir, kami mendapatkan nilai default ascending=true.

  4. Dapatkan nilai terakhir dari array yang diurutkan, sehingga group-id terakhir (terbesar) yaitu (ingat langkah 2b) dalam hal apapun lebih besar dari fid AND (dalam kasus trigger = 1) sama dengan fid (langkah 2a) AND selalu berupa angka dari larik yang kita buat di 1.

Lihat tangkapan layar untuk hasil antara langkah 1 dan 2:

Sekarang mudah untuk menggunakan fungsi agregat dengan bidang yang dibuat seperti dijelaskan di atas.