Scalanie wielu wierszy według pola wartości

Dec 09 2020

Jak mogę dołączyć do tych linii w zależności od pola Trigger. Warunek jest następujący, pola muszą być uporządkowane rosnąco po polu fid od 1do 68. Dlatego chcę połączyć wszystkie moje wiersze, zaczynając od pierwszego, który ma wyzwalacz 1, i następne, które mają wartość, 0i kończą się na pierwszej wartości za pomocą 1i zaczynają od nowa.

Edycja: rozumiem. Ale jak mogę rozwiązać ten problem? Jak dołączyć do tych linii? Wyzwalacz odnosi się do kąta. Jeśli wynosi 0, to kąt między 2 segmentami jest mniejszy niż x stopni, a jeśli wynosi 1, kąt jest większy niż x stopni. Tak więc chcę, jeśli pierwsza linia nie jest wyzwalaczem, chcę połączyć ją z pierwszą linią, która jest wyzwalaczem.

Odpowiedzi

3 MrXsquared Dec 09 2020 at 19:48

Aby dać ci wyobrażenie, jak można to zrobić, oto rozwiązanie w Pythonie, aby dodać nowe pole groupid, którego możesz użyć do rozpuszczenia linii:

# 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

Wynik:

3 Babel Dec 09 2020 at 21:08

Istnieje sposób na bezpośrednie utworzenie wartości pola za pomocą wyrażenia QGIS w kalkulatorze pola, aby zgrupować wszystkie te cechy, które chcesz połączyć. Bazując na wartości tego pola, możesz użyć funkcji, Aggregateaby połączyć funkcje o tej samej wartości (zobacz drugi zrzut ekranu poniżej). Kroki botów powinny być łatwe do zautomatyzowania za pomocą modelu.

Biorąc pod uwagę strukturę danych i nazwy pól, wyrażenie wygląda następująco (poniżej znajdziesz wyjaśnienie, jak działa wyrażenie):

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

Następnie możesz użyć tego pola razem z funkcją Menu Processing / Toolbox / Aggregatedo łączenia tych funkcji razem.

Aby wyjaśnić ideę wyrażenia: dla lepszego zrozumienia nazwijmy „początkowy odcinek” łączonej linii, który w końcu chcemy uzyskać „ głowę ” - a kolejne segmenty, które są z nią połączone, „ ogonami ”.

  1. Zdobądź wartości fid głów , nazwijmy to „ identyfikatorami grup ”. Ostatecznym celem jest przypisanie każdego segmentu ogona do głowy (lub: każdemu ogonowi należy przypisać wartość identyfikatora grupy następnej mniejszej głowy : 2 i 3 należy przypisać do 1, 5 i 6 do 4 itd.) A) Jeśli wyzwalacz to 1 ( głowa ), uzyskaj wartość id: to jest identyfikator grupy . W przeciwnym razie (dla ogonów ) ustaw wartość 0. b) Agreguj te wartości, tworząc tablicę. c) Usuń wszystkie wartości 0 z tablicy. Otrzymujemy w ten sposób tablicę identyfikatorów grup (= fid głów ): [1,4,7,9,12]. W końcu chcemy przypisać każdą cechę do jednej z tych wartości z tablicy.

  2. Teraz iteruj po wszystkich cechach warstwy z każdym z tych identyfikatorów grup z tablicy z wyrażeniem array_foreach: a) Dla cech z wyzwalaczem = 1 ( głowy ) nie mamy problemu, te mają już właściwy identyfikator grupy (odpowiadający ich fid) b) W pozostałych przypadkach ( reszki , wyzwalacz = 0) musimy przypisać nowe wartości. W ten sposób porównujemy każdą wartość wejściową z tablicy (lista wszystkich identyfikatorów grup ) z fid i zachowujemy identyfikator grupy, jeśli jest mniejszy niż fid (jak chcemy przypisać do następnej mniejszej wartości). W przeciwnym razie ustawiamy ją na 0. Więc w żadnym przypadku z tablicy nie zostanie zwrócona wartość większa niż fid.

  3. Posortuj tablicę, aby upewnić się, że mamy wartości we właściwej kolejności (od najmniejszej do największej) - aby usunąć ostatnie zera z ostatniej pozycji (patrz zrzut ekranu poniżej). Bez ustawiania kolejności sortowania otrzymujemy wartość domyślną ascending=true.

  4. Uzyskaj ostatnią wartość z posortowanej tablicy, więc ostatni (największy) identyfikator grupy , czyli (pamiętaj o kroku 2b) w żadnym wypadku nie jest większy niż fid AND (w przypadku, gdy trigger = 1) jest równy fid (krok 2a) AND jest zawsze liczbą z tablicy, którą utworzyliśmy w 1.

Zobacz zrzut ekranu przedstawiający pośrednie wyniki kroków 1 i 2:

Teraz można łatwo używać funkcji agregującej z polem utworzonym w sposób opisany powyżej.