1

I was doing Tin interpolation using pyqgis, and this algorithm has this complex param called INTERPOLATION_DATA, where I'm stuck to create a valid string by the documentation described.

From what the documentation described: https://docs.qgis.org/3.22/en/docs/user_manual/processing_algs/qgis/interpolation.html?highlight=tininterpolation#tin-interpolation

Vector layer(s) and field(s) to use for the interpolation, coded in a string (see the ParameterInterpolationData class in InterpolationWidgets for more details).
The following GUI elements are provided to compose the interpolation data string:

Vector layer [vector: any]
Interpolation attribute [tablefield: numeric]: Attribute to use in the interpolation
Use Z-coordinate for interpolation [boolean]: Uses the layer’s stored Z values (Default: False)
For each of the added layer-field combinations, a type can be chosen:

> Points
> Structured lines
> Break lines

In the string, the layer-field elements are separated by '::|::'. The sub-elements of the layer-field elements are separated by '::~::'.

Then I checked the source code on GitHub:

class ParameterInterpolationData(QgsProcessingParameterDefinition):

    def __init__(self, name='', description=''):
        super().__init__(name, description)
        self.setMetadata({
            'widget_wrapper': 'processing.algs.qgis.ui.InterpolationWidgets.InterpolationDataWidgetWrapper'
        })

    def type(self):
        return 'idw_interpolation_data'

    def clone(self):
        return ParameterInterpolationData(self.name(), self.description())

    @staticmethod
    def parseValue(value):
        if value is None:
            return None

        if value == '':
            return None

        if isinstance(value, str):
            return value if value != '' else None
        else:
            return ParameterInterpolationData.dataToString(value)

    @staticmethod
    def dataToString(data):
        s = ''
        for c in data:
            s += '{}::~::{}::~::{:d}::~::{:d};'.format(c[0],
                                                       c[1],
                                                       c[2],
                                                       c[3])
        return s[:-1]

I tried to run the algorithm directly from built-in panel and checked how it would look like. This is the INTERPOLATION_DATA param I got for log history.

# I've beautified it for better readability
{
    'INTERPOLATION_DATA':
        'Point?crs=EPSG:4326&
        field=fid:long(0,0)&field=SiteName:string(0,0)&            # Looks like it's just field name parsed to differet encoding from here
        field=1110416%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&  
        field=1110601%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&    
        field=1110401%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110616%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110216%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110201%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110501%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110516%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110301%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110116%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110316%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&
        field=1110101%E6%97%A5%E5%B9%B3%E5%9D%87:double(0,0)&       # until here 
        uid={a0d8c6d8-b18d-4208-96a7-07921ff9f6c3}::~::0::~::2::~::0' 
}

I believe the the only 2 between ::~:: is where the index of field I want to use for interpolation field, which is 2. However, I'm definitely not hard coding the field in string (#comments parts).

In short, back to the question, if given layer(type=QgsVectorLayer), how do I get the INTERPOLATION_DATA from the layer?


p.s. The solution I came up with is by

  1. defining QgsInterpolator
    layer_data = QgsInterpolator.LayerData()
    layer_data.source = ob
    layer_data.zCoordInterpolation = False
    layer_data.interpolationAttribute = 2
    layer_data.sourceType = QgsInterpolator.SourcePoints
    interpolation_method = QgsTinInterpolator.Linear
    ncols, nrows = 100, 100
    extent = ob.extent()

    tin_interpolator = QgsTinInterpolator([layer_data], interpolation_method)
  1. Export to tif and load it back
    export_path = f'{path}.tif'
    output = QgsGridFileWriter(tin_interpolator, 
                               export_path, 
                               extent, 
                               ncols,
                               nrows)
    output.writeFile()
    
    rlayer = QgsRasterLayer(uri, 'name')

That... seems like an extra steps. The ideal way should be getting the output from algorithm output, right? (rlayer = processing.run("algorithm_id", {parameter_dictionary})['OUTPUT'])

1
  • Whats your question? You search for a answer how to get the index of a field?
    – fsg
    Commented Feb 2, 2023 at 8:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.