QGIS Modeler warunek if / else, niestandardowy skrypt dla Modelera

10

Chcę stworzyć prostą funkcję if / else w moim Modelu i chciałem wiedzieć, czy jest to możliwe, czy nie.

wprowadź opis zdjęcia tutaj

Chcę, aby to zrobić, jeśli wybrano dane wejściowe dla „Segment Layer”, że nie musi ono wykonywać „Segmentation (średnich zmian)” i zamiast tego używa „Segment Layer” jako danych wejściowych dla następnego procesu.

Dane wejściowe dla „segmentacji (przesunięcia środków)” są następujące

wprowadź opis zdjęcia tutaj

Zaktualizuj po próbie zaimplementowania odpowiedzi Josepha: Użyłem następującego kodu i otrzymałem ten błąd wprowadź opis zdjęcia tutaj

Aktualizacja 2, po wymianie parametrów pojawia się błąd w wierszu 28, to jest „else:” oznacza

##Example=name
##BGREN=optional raster
##Segment_Layer=optional vector
##output=output vector

if BGREN is not None:
    processing.runalg('otb:segmentationmeanshift', \
    -BGREN\
    -0\
    -70\
    -70\
    -0.1\
    -100\
    -100\
    -0\
    -0\
    -0\
    -'True'\
    -'False'\
    -1\
    -0.1\
    -'Layer'\
    -'DN'\
    -1024\
    -1\
    -0\
    -output)
else:
    output=Segment_Layer

wprowadź opis zdjęcia tutaj

Aktualizacja działa :) po kilku próbach i przy pomocy Josepha ten kod działa teraz jak urok, ostatnia sztuczka polegała na zamianie dwóch opcjonalnych wartości na „Brak”.

##Example=name
##BGREN=optional raster
##Segment_Layer=optional vector
##output=output vector

if BGREN is not None:
    processing.runalg('otb:segmentationmeanshift', \
    BGREN, \
    0, \
    70, \
    70, \
    0.1, \
    100, \
    100, \
    0, \
    0, \
    None, \
    True, \
    False, \
    1, \
    0.1, \
    'Layer', \
    'DN', \
    1024, \
    1, \
    None, \
    output)
else:
    output=Segment_Layer
Andreas
źródło
3
Myślę, że będziesz musiał użyć niestandardowego skryptu w swoim modelerze, aby poprawnie używać instrukcji if / else .
Joseph
1
@Joseph, tak też myślałem, problem w tym, że nie jestem tak dobry w pisaniu skryptów, jak bym chciał, właściwie nie mam żadnego doświadczenia ...
Andreas
1
@Andreas Potwierdzam to, co napisał Józef w swoim komentarzu. Myślę jednak, że możesz uzyskać więcej pomocy od społeczności, jeśli edytujesz swoje pytanie i dajesz możliwość uzyskania wskazówek w Pythonie (dodając również odpowiedni tag) ...
mgri
1
@Andreas - Edytowałem mój post. Powinieneś także zaakceptować odpowiedzi po rozwiązaniu problemu;)
Józef
1
@Joseph Zredagowałem mój post z działającym teraz kodem, twoja pomoc była bardzo potrzebna i naprawdę się cieszę, że poświęciłeś mi swój cenny czas, aby mi w tym pomóc :) w tej chwili wykonuje on algorytm i muszę czekać za wyniki, ale wygląda naprawdę obiecująco, jeszcze raz dziękuję :)
Andreas

Odpowiedzi:

8

Jak wspomniano w moim komentarzu, niestandardowy skrypt może być dobrym rozwiązaniem w tej sytuacji. Możesz utworzyć jeden z:

Processing Toolbox > Scripts > Tools > Create new script

Poniższy skrypt ustawia parametry wejściowe jako opcjonalne wraz z instrukcją if / else w zależności od tego, który parametr zawiera warstwę. Jeśli więc wybrano warstwę BGREN, wykona ona narzędzie do segmentacji i ustawi dane wyjściowe; w przeciwnym razie wynikiem będzie warstwa wybrana z Segment_Layer.

Oto możliwy skrypt:

##Example=name
##BGREN=optional raster
##Segment_Layer=optional vector
##output=output vector

if BGREN is not None:
    processing.runalg('otb:segmentationmeanshift', \
    -BGREN, \
    -filter, \
    -filter.meanshift.spatialr, \
    -filter.meanshift.ranger, \
    -filter.meanshift.thres, \
    -filter.meanshift.maxiter, \
    -filter.meanshift.minsize, \
    -mode, \
    -mode.vector.outmode, \
    -mode.vector.inmask, \
    -mode.vector.neighbor, \
    -mode.vector.stitch, \
    -mode.vector.minsize, \
    -mode.vector.simplify, \
    -mode.vector.layername, \
    -mode.vector.fieldname, \
    -mode.vector.tilesize, \
    -mode.vector.startlabel, \
    -mode.vector.ogroptions, \
    -output)
else:
    output=Segment_Layer

Parametry otb:segmentationmeanshiftwyglądają przerażająco! Niestety nie mam zainstalowanego oprogramowania Orfeo, więc nie mogę przetestować tego narzędzia. Jednak parametry są pokazane tutaj , wystarczy je wpisać zamiast używać GUI. Po zakończeniu dodaj skrypt do modelera za pomocą BGRENi Segment_Layerjako warstw wejściowych:

Parametry skryptu

Ponadto w modelarzu może być konieczna zmiana definicji wymaganego parametru BGRENi Segment_Layer:

Definicja parametru

Następnie podłącz wyjście skryptu do narzędzia NDVI.


Przetestowałem to do pewnego stopnia przy użyciu innych narzędzi, które działały w zależności od wybranej warstwy wejściowej, więc mam nadzieję, że zadziała dla twojego modelarza!



EDYTOWAĆ:

Oto nieco zmodyfikowany kod (potrzebujesz przecinków, aby oddzielić parametry, Truea Falseinstrukcje nie wymagają cudzysłowów wokół nich, ukośnik wstecz jest tylko dla czytelności, ale będzie zawierać jako jednowierszowy):

##Example=name
##BGREN=optional raster
##Segment_Layer=optional vector
##output=output vector

if BGREN is not None:
    processing.runalg('otb:segmentationmeanshift', \
    BGREN, \
    0, \
    70, \
    70, \
    0.1, \
    100, \
    100, \
    0, \
    0, \
    0, \
    True, \
    False, \
    1, \
    0.1, \
    'Layer', \
    'DN', \
    1024, \
    1, \
    0, \
    output)
else:
    output=Segment_Layer

Lub jako jedna linijka:

##Example=name
##BGREN=optional raster
##Segment_Layer=optional vector
##output=output vector

if BGREN is not None:
    processing.runalg('otb:segmentationmeanshift',BGREN,0,70,70,0.1,100,100,0,0,0,True,False,1,0.1,'Layer','DN',1024,1,0,output)
else:
    output=Segment_Layer
Joseph
źródło
1
Dodałem komentarz, aby zachęcić @Andreas do edycji pytania i dać możliwość uzyskania wskazówek w Pythonie na temat otrzymywania dodatkowej pomocy, ale byłeś szybszy!
mgri
1
@mgri - zachęcam do opublikowania tego komentarza, ponieważ OP może chcieć edytować niektóre szczegóły i mam nadzieję zachęcić innych do opublikowania możliwego rozwiązania :)
Joseph
1
@ Joseph, cholera, to o wiele więcej, niż myślałem: O, w każdym razie postaram się to odtworzyć i zostawić opinię, jeśli go uruchomię, z góry dziękuję :)
Andreas
1
Mile widziane! Prawdopodobnie zastanowiłem się nad tym, więc może być dobrym pomysłem edytowanie pytania zgodnie z sugestią @mgri, aby można było opublikować bardziej odpowiednie rozwiązanie w języku Python =)
Joseph
1
@Andreas - wcale nie głupie, wszyscy muszą uczyć się od samego początku =)
Joseph