17. كتابة إضافة معالجة (Processing)

بحسب نوع الإضافة التي ستطوّرها، قد يكون من الأفضل إضافة وظيفتها على شكل خوارزمية معالجة (أو مجموعة منها). سيوفر ذلك تكاملًا أفضل داخل QGIS، ووظائف إضافية (لأنه يمكن تشغيلها ضمن مكوّنات المعالجة، مثل مصمّم النماذج أو واجهة المعالجة الدفعية)، ووقت تطوير أقصر (لأن إطار المعالجة سيتولى جزءًا كبيرًا من العمل).

لتوزيع تلك الخوارزميات، عليك إنشاء إضافة جديدة تضيفها إلى صندوق أدوات المعالجة. يجب أن تحتوي الإضافة على مزوّد خوارزميات، يجب تسجيله عند إنشاء نسخة من الإضافة.

17.1. تحديث إضافة

إن أردت إضافة إضافتك الموجودة إلى إطار المعالجة، فعليك إضافة بعض الشيفرة.

  1. في ملف metadata.txt عليك إضافة متغير:

    hasProcessingProvider=yes
    
  2. في ملف Python الذي تُعَدّ فيه إضافتك بالدالة initGui، عليك تعديل بعض الأسطر على النحو التالي:

     1from qgis.core import QgsApplication
     2from .processing_provider.provider import Provider
     3
     4class YourPluginName:
     5
     6    def __init__(self):
     7        self.provider = None
     8
     9    def initProcessing(self):
    10        self.provider = Provider()
    11        QgsApplication.processingRegistry().addProvider(self.provider)
    12
    13    def initGui(self):
    14        self.initProcessing()
    15
    16    def unload(self):
    17        QgsApplication.processingRegistry().removeProvider(self.provider)
    
  3. يمكنك إنشاء مجلد processing_provider يحتوي على ثلاثة ملفات:

    • __init__.py فارغ. وهو ضروري لإنشاء حزمة Python صالحة.

    • provider.py الذي سينشئ مزوّد المعالجة ويعرض خوارزمياتك.

       1from qgis.core import QgsProcessingProvider
       2from qgis.PyQt.QtGui import QIcon
       3
       4from .example_processing_algorithm import ExampleProcessingAlgorithm
       5
       6class Provider(QgsProcessingProvider):
       7
       8    """ The provider of our plugin. """
       9
      10    def loadAlgorithms(self):
      11        """ Load each algorithm into the current provider. """
      12        self.addAlgorithm(ExampleProcessingAlgorithm())
      13        # add additional algorithms here
      14        # self.addAlgorithm(MyOtherAlgorithm())
      15
      16    def id(self) -> str:
      17        """The ID of your plugin, used for identifying the provider.
      18
      19        This string should be a unique, short, character only string,
      20        eg "qgis" or "gdal". This string should not be localised.
      21        """
      22        return 'yourplugin'
      23
      24    def name(self) -> str:
      25        """The human friendly name of your plugin in Processing.
      26
      27        This string should be as short as possible (e.g. "Lastools", not
      28        "Lastools version 1.0.1 64-bit") and localised.
      29        """
      30        return self.tr('Your plugin')
      31
      32    def icon(self) -> QIcon:
      33        """Should return a QIcon which is used for your provider inside
      34        the Processing toolbox.
      35        """
      36        return QgsProcessingProvider.icon(self)
      
    • example_processing_algorithm.py الذي يحتوي على ملف الخوارزمية المثال. انسخ محتوى script template file (ملف قالب السكربت) والصقه، ثم حدّثه وفق احتياجاتك.

    يُفترض أن تكون لديك شجرة مشابهة لما يلي:

    1└── your_plugin_root_folder
    2   ├── __init__.py
    3   ├── LICENSE
    4   ├── metadata.txt
    5   └── processing_provider
    6         ├── example_processing_algorithm.py
    7         ├── __init__.py
    8         └── provider.py
    
  4. الآن يمكنك إعادة تحميل إضافتك في QGIS، ويُفترض أن ترى سكربتك المثال في صندوق أدوات المعالجة ومصمّم النماذج.

17.1.1. إنشاء خوارزمية مخصصة

إليك مثالًا بسيطًا على خوارزمية نطاق عازل مخصصة:

 1from qgis.core import (
 2    QgsProcessingAlgorithm,
 3    QgsProcessingParameterFeatureSource,
 4    QgsProcessingParameterNumber,
 5    QgsProcessingParameterFeatureSink,
 6    QgsFeatureSink,
 7)
 8
 9class BufferAlgorithm(QgsProcessingAlgorithm):
10
11    INPUT = 'INPUT'
12    DISTANCE = 'DISTANCE'
13    OUTPUT = 'OUTPUT'
14
15    def initAlgorithm(self, config=None):
16        self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, 'Input layer'))
17        self.addParameter(QgsProcessingParameterNumber(self.DISTANCE, 'Buffer distance', defaultValue=100.0))
18        self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, 'Output layer'))
19
20    def processAlgorithm(self, parameters, context, feedback):
21        source = self.parameterAsSource(parameters, self.INPUT, context)
22        distance = self.parameterAsDouble(parameters, self.DISTANCE, context)
23        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
24                                               source.fields(), source.wkbType(), source.sourceCrs())
25
26        for f in source.getFeatures():
27            f.setGeometry(f.geometry().buffer(distance, 5))
28            sink.addFeature(f, QgsFeatureSink.FastInsert)
29
30        return {self.OUTPUT: dest_id}
31
32    def name(self):
33        return 'buffer'
34
35    def displayName(self):
36        return 'Buffer Features'
37
38    def group(self):
39        return 'Examples'
40
41    def groupId(self):
42        return 'examples'
43
44    def createInstance(self):
45        return BufferAlgorithm()