QGIS Modeler if / else Bedingung, benutzerdefiniertes Skript für Modeler

10

Ich möchte eine einfache if / else-Funktion in meinem Modell erstellen und wollte wissen, ob dies möglich ist oder nicht.

Geben Sie hier die Bildbeschreibung ein

Ich möchte, dass dies so ist, wenn eine Eingabe für 'Segmentebene' ausgewählt ist, dass sie nicht die 'Segmentierung (Mittelwertverschiebung)' ausführen muss und stattdessen 'Segmentebene' als Eingabe für den nächsten Prozess verwendet.

Die Eingaben für die 'Segmentierung (Mittelwertverschiebung)' lauten wie folgt

Geben Sie hier die Bildbeschreibung ein

Update nach dem Versuch, Josephs Antwort zu implementieren: Ich habe den folgenden Code verwendet und diesen Fehler erhalten Geben Sie hier die Bildbeschreibung ein

Update 2, nach dem Ersetzen der Parameter erhalte ich eine Fehlermeldung in Zeile 28, hier steht 'else:'

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

Geben Sie hier die Bildbeschreibung ein

Update es funktioniert :) Nach ein paar Versuchen und mit Josephs Hilfe funktioniert dieser Code jetzt wie ein Zauber. Der letzte Trick bestand darin, zwei optionale Werte durch 'Keine' zu ersetzen.

##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
quelle
3
Ich denke, Sie müssen ein benutzerdefiniertes Skript in Ihrem Modellierer verwenden, um if / else- Anweisungen korrekt zu verwenden.
Joseph
1
@ Joseph das habe ich auch gedacht, das Problem ist, dass ich nicht so gut in Skripten bin, wie ich es gerne hätte, ich habe so ziemlich keine Erfahrung ...
Andreas
1
@Andreas Ich bestätige, was Joseph in seinem Kommentar geschrieben hat. Ich denke jedoch, dass Sie möglicherweise mehr Hilfe von der Community erhalten, wenn Sie Ihre Frage bearbeiten und die Möglichkeit geben, einige Hinweise mit Python zu erhalten (indem Sie auch ein geeignetes Tag hinzufügen) ...
Mgri
1
@Andreas - Bearbeitet meinen Beitrag. Sie sollten auch Antworten akzeptieren, nachdem sie Ihr Problem gelöst haben;)
Joseph
1
@Joseph Ich habe meinen Beitrag mit dem jetzt funktionierenden Code bearbeitet, Ihre Hilfe wurde dringend benötigt und ich bin wirklich froh, dass Sie sich etwas Zeit genommen haben, um mir dabei zu helfen :) Ab sofort wird der Algorithmus ausgeführt und ich muss warten für die Ergebnisse, aber es sieht wirklich vielversprechend aus, nochmals vielen Dank :)
Andreas

Antworten:

8

Wie in meinem Kommentar erwähnt, kann in dieser Situation ein benutzerdefiniertes Skript der richtige Weg sein. Sie können eine erstellen aus:

Processing Toolbox > Scripts > Tools > Create new script

Das folgende Skript legt die Eingabeparameter zusammen mit einer if / else- Anweisung als optional fest, je nachdem, welcher Parameter eine Ebene enthält. Wenn also eine Ebene ausgewählt wurde , führt sie das Segmentierungswerkzeug aus und legt die Ausgabe fest. Andernfalls ist die Ausgabe die Ebene, aus der ausgewählt wurde .BGRENSegment_Layer

Hier ist ein mögliches Skript:

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

Die Parameter für das otb:segmentationmeanshiftAussehen sind beängstigend! Leider habe ich Orfeo nicht installiert und kann dieses Tool daher nicht testen. Die Parameter werden hier jedoch angezeigt . Sie müssen sie nur eingeben, anstatt die GUI zu verwenden. Fügen Sie anschließend das Skript mithilfe von BGRENund Segment_Layerals Eingabeebenen zu Ihrem Modellierer hinzu :

Skriptparameter

Außerdem müssen Sie in Ihrem Modellierer möglicherweise die erforderliche Parameterdefinition von BGRENund ändern Segment_Layer:

Parameterdefinition

Verbinden Sie dann die Ausgabe des Skripts mit Ihrem NDVI-Tool.


Ich habe dies bis zu einem gewissen Grad mit anderen Tools getestet, die je nach ausgewählter Eingabeebene funktionierten. Hoffentlich funktioniert es für Ihren Modellierer!



BEARBEITEN:

Hier ist der Code, den Sie leicht modifiziert verwendet haben (Sie benötigen die Kommas, um die Parameter zu trennen, Trueund FalseAnweisungen erfordern keine Anführungszeichen, der Schrägstrich dient nur der Lesbarkeit, enthält ihn jedoch als Einzeiler):

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

Oder als Einzeiler:

##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
quelle
1
Ich habe einen Kommentar hinzugefügt, um @Andreas zu ermutigen, seine Frage zu bearbeiten und die Möglichkeit zu geben, mit Python einige Hinweise zu erhalten, um mehr Hilfe zu erhalten, aber Sie waren schneller!
Mgri
1
@mgri - Ich würde Sie ermutigen, diesen Kommentar zu posten, da das OP einige Details in bearbeiten und hoffentlich andere ermutigen möchte, eine mögliche Lösung zu posten :)
Joseph
1
@ Joseph verdammt, das ist viel mehr als ich dachte: O sowieso werde ich versuchen, dies neu zu erstellen und ein Feedback zu hinterlassen, wenn ich es zum Laufen bringen würde, danke im Voraus :)
Andreas
1
Herzlich willkommen! Ich habe das wahrscheinlich überlegt, daher ist es möglicherweise eine gute Idee, Ihre Frage so zu bearbeiten, wie @mgri vorgeschlagen hat, damit eine geeignetere Python-Lösung oder ähnliches veröffentlicht werden kann =)
Joseph
1
@ Andreas - Überhaupt nicht dumm, jeder muss von Anfang an lernen =)
Joseph