QGIS 3.0 ile bir python işleme komut dosyası yazma


17

QGIS 3.0 güncellemesinin ardından, QGIS 3.0'da işleme komut dosyalarının yazılmasıyla ilgili herhangi bir bilgi bulmak çok zor hale geldi.

@Underdark ( buraya bakın ) iskelet için bir temel oluşturdu. Bu kod, şablondan yeni bir komut dosyası yazarken QGIS'e de eklenmiş gibi görünüyor (QGIS 3.0.2).

Ancak, benim gibi Python yeni başlayanlar, özellikle giriş ve çıkış katmanları için bu kodu değiştirmek için nasıl anlamak için herhangi bir yol bulamadık.

Amacım girdi olarak 2 raster katman ve bir double alarak iki katman çıktısı yapan bir senaryo yazmak.

Buna izin vermek için örnek kodda yapılması gereken değişiklikler nelerdir?

QGIS 2.x için aşağıdaki sözdizimini kullanırdım:

##Layer1=raster
##Layer2=raster 
##myDouble=Double
##OutLayer1=output raster
##OutLayer2=output raster   

Anladığım kadarıyla, aşağıdaki prosedürde değişiklikler yapılması gerekiyor, ancak ne koyacağından emin değilim.

def initAlgorithm(self, config=None):
    self.addParameter(QgsProcessingParameterFeatureSource(
        self.INPUT,
        self.tr("Input layer"),
        [QgsProcessing.TypeVectorAnyGeometry]))
    self.addParameter(QgsProcessingParameterFeatureSink(
        self.OUTPUT,
        self.tr("Output layer"),
        QgsProcessing.TypeVectorAnyGeometry))

16 Mayıs'ta QGIS Python API belgeleri yayınlandı. Bununla birlikte, burada nasıl kullanılacağı hala net değil. (Bu Python bilgisi eksikliği olabilir)


1
Aynı amaç için kullandığınız kod örneğini qgis 2.xx'de verebilir misiniz qgis 3.x ile ilgili dokümantasyona buradan ulaşabilirsiniz: docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/… en kısa sürede güncellenmiş. Doküman sorunları burada izlenir: github.com/qgis/QGIS-Documentation/issues
Nono

Yanıt, kod örneği ile düzenlendi. Linkler için teşekkürler, zaten yemek kitabı takip ediyordum ama ne yazık ki cevabımı orada bulamadım!
Kantan

Qgis API belgeleri hakkında okudum, ancak bu ve @Underdark'ın kodu arasında ilişki kuramıyorum. (bağlantılar için düzenlemeye bakın)
Kantan

Yanıtlar:


29

QGIS2.x'ten QGIS3.x'e geçiş ile tüm işleme çerçevesi yeniden işlendi ve büyük bölümleri şimdi Python kullanarak etkileşime girebileceğiniz C ++ sınıfları olarak çalışıyor. Maalesef veri / veri kümesi ES'si için basit parametre sözdizimi artık geçerli değil. Yeni parametre yapısı, araç kutusuna önceden kurulmuş olarak bulduğunuz yerleşik (Python-) İşleme algoritmalarından sonra çok daha yönlendirilir.

Gördüğüm gibi, zaten yeni algoritma yapısının açıklamasını @underdark izlediniz. Ancak bu yapıyı gereksinimlerinize göre ayarlamak için (raster katmanları, çift giriş, vb.) Koddaki birden çok konumdaki kodu değiştirmeniz gerekir. Sizin için kısa bir açıklama ile kaba bir örnek kodladım (sadece @underdarks örneğine dayanan bir algoritma iskeleti):

from qgis.PyQt.QtCore import QCoreApplication, QVariant
from qgis.core import (QgsProcessing, QgsProcessingAlgorithm, 
QgsProcessingParameterRasterLayer,QgsProcessingParameterNumber, 
QgsProcessingParameterRasterDestination)

class RasterAlg(QgsProcessingAlgorithm):
    INPUT_RASTER_A = 'INPUT_RASTER_A'
    INPUT_RASTER_B = 'INPUT_RASTER_B'
    INPUT_DOUBLE = 'INPUT_DOUBLE'
    OUTPUT_RASTER_A = 'OUTPUT_RASTER_A'
    OUTPUT_RASTER_B = 'OUTPUT_RASTER_B'

    def __init__(self):
        super().__init__()

    def name(self):
        return "RasterAlg"

    def tr(self, text):
        return QCoreApplication.translate("RasterAlg", text)

    def displayName(self):
        return self.tr("RasterAlg script")

    def group(self):
        return self.tr("RasterAlgs")

    def groupId(self):
        return "RasterAlgs"

    def shortHelpString(self):
        return self.tr("RasterAlg script without logic")

    def helpUrl(self):
        return "https://qgis.org"

    def createInstance(self):
        return type(self)()

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterRasterLayer(
            self.INPUT_RASTER_A,
            self.tr("Input Raster A"), None, False))
        self.addParameter(QgsProcessingParameterRasterLayer(
            self.INPUT_RASTER_B,
            self.tr("Input Raster B"), None, False))
        self.addParameter(QgsProcessingParameterNumber(
            self.INPUT_DOUBLE, 
            self.tr("Input Double"), 
            QgsProcessingParameterNumber.Double,
            QVariant(1.0)))
        self.addParameter(QgsProcessingParameterRasterDestination(
            self.OUTPUT_RASTER_A,
            self.tr("Output Raster A"),
            None, False))
        self.addParameter(QgsProcessingParameterRasterDestination(
            self.OUTPUT_RASTER_B,
            self.tr("Output Raster B"),
            None, False))

    def processAlgorithm(self, parameters, context, feedback):
        raster_a = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER_A, context)
        raster_b = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER_B, context)
        double_val = self.parameterAsDouble(parameters, self.INPUT_DOUBLE,context)
        output_path_raster_a = self.parameterAsOutputLayer(parameters, self.OUTPUT_RASTER_A, context)
        output_path_raster_b = self.parameterAsOutputLayer(parameters, self.OUTPUT_RASTER_B, context)

        #DO SOME CALCULATION

        results = {}
        results[self.OUTPUT_RASTER_A] = output_path_raster_a
        results[self.OUTPUT_RASTER_B] = output_path_raster_b
        return results

Hangi adımlar yapılıyor?

  1. Gerekli tüm sınıfları içe aktarın.
  2. Algoritmayı bir miras olarak sınıf olarak tanımlayın QgsProcessingAlgorithm.
  3. Öncelikle, algoritmanıza INPUT_RASTER_A = 'INPUT_RASTER_A'işlem çerçevesi tarafından sağlanan parametrelerle referans vermek için giriş ve çıkış parametrelerinin adlarını algoritma sınıfının (parametre adları) dize değişkenleri (parametre adları) olarak bildirmeniz gerekir.
  4. Algoritmanızı işleme araç kutusu gui'sine bağlayan ve yardım dizeleri vb. Sağlayan yöntemleri ekleyin.
  5. Sonra işleme çerçevesinin parametrelerini ekleyin. Bunlar çocuk sınıfları olarak tanımlanmıştır QgsProcessingParameterType- senin algoritmanın durumunda: QgsProcessingParameterRasterLayer, QgsProcessingParameterNumber, vb. QgsProcessingParameterRasterLayerDoğru argümanları iletmek ve parametre nesnelerini oluşturmak için API girişlerine (örn. ) Başvurabilirsiniz.
  6. Parametreleri contextve feedbacknesneleri processAlgorithm(), çalışma zamanında parametrelerden giriş veri kümelerini aldığınız parameterAsRasterLayer()yönteme iletin (bu durumda, yöntemi kullanarak QgsRasterLayer nesneleri ).
  7. Hesaplamanızı yapın.
  8. Çıktıları sonuç sözlüğüne ekleyin ve çağrı sonucunda döndürün processAlgorithm().

Umarım QGIS3'te python algoritmalarınızı nasıl tasarlayacağınıza dair bazı bilgiler verebilirim. Sıkıştığınız zaman, işleme çerçevesinin mevcut algoritmalarının parametreleri nasıl işlediğine bakmak her zaman yararlıdır. Onlara buradan bakabilirsiniz .



Eğer qgis belgelerine eklerseniz onur duyarım. Lütfen yap! Qgis3 için daha fazla python belgesine katkıda bulunmak için herhangi bir önkoşul var mı? Bence bu daha geniş bir kullanıcı tabanı için betik ve programcılar açısından önemlidir.
root676

1
Önkoşul yok. GitHub çekme istekleri aracılığıyla resmi python yemek kitabına eklemek oldukça kolaydır (tüm düzenlemeler GitHub sitesinde bile yapılabilir: github.com/qgis/QGIS-Documentation/tree/master/source/docs/… ). Resmi dokümanlara daha fazla örnek eklemek de çok hoş olurdu!
ndawson

1
Cevabınız için teşekkürler! Bugün meşguldüm, ama yarın kazmaya çalışacağım. Gerçekten umut verici görünüyor.
Kantan

2
Bu kesinlikle harika bir cevap, detaylar ve referanslar için teşekkürler. GitHub'daki betiklerin bağlantısı gerçek bir altın madeni! İlk başta QVariant bildirimi bana bir hata verdi, ancak editörde tekrar yazdığımda ve otomatik tamamlamayı kullandığımda hata kayboldu. Şimdi senaryolara dalmak için gerçekten büyük bir adım atıyor, umarım yeni programcıları cesaretlendirmez. Daha fazla dokümantasyon mevcut olduğundan, umarım daha açık hale gelir!
Kantan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.