0

I have a problem with a pygis script.

This is a script to load in a shapefile layer from a WFS source and to add 4 extra fields to the attributes: Label, Legende1, Legende2 and PercId. In one of the fields (PercId) a small calculation needs to be done, to reformat an initial string value.

To add the 4 extra fields mentioned, the script apparantly uses Qvariant. Nevertheless, when I run the script the error message is that "Qvariant is not defined". Apparantly, you can add a small line of code at the start (from PyQt4.QtCore import *) to make it work with Qvariant but the script doesn't work. It wont even start in a QGIS 3.x standalone version.

Does anyone have a fix or alternative to add the 4 extra fields to the newly loaded en clipped layer? Because that is where the problem seems to be situated.

The script:

from qgis.core import *
from qgis.gui import *
from PyQt4.QtCore import *

# Define paths and URLs
rootAlgemeen = '//orbit/Orbit server/data/gemeente/44048/Achtergronden/'

# Load existing layers
boundingbox = QgsVectorLayer(rootAlgemeen + 'BoundingBox/Boundingbox44048.shp', 'boundingbox', 'ogr')
gemeentegrens = QgsVectorLayer(rootAlgemeen + 'Grenzen/Gemeentegrens/Apn_gemeentegrens.shp', 'gemeentegrens', 'ogr')
QgsProject.instance().addMapLayers([boundingbox, gemeentegrens])

# Define WFS URLs
WFSrootBB = '&SRSNAME=EPSG:31370&cql_filter=Intersects(SHAPE,POLYGON((91657.679 180064.905, 91657.679 186710.326, 101502.614 186710.326, 101502.614 180064.905, 91657.679 180064.905)))'
WFSrootGRB = 'https://geo.api.vlaanderen.be/GRB/wfs?request=GetFeature&service=wfs&version=2.0.2&typename='

# Load WFS layer
AdpWFS = QgsVectorLayer(WFSrootGRB + 'GRB:ADP' + WFSrootBB, 'WFS GRB Adp', 'wfs')
if not AdpWFS.isValid():
    print("Failed to load WFS layer.")
else:
    QgsProject.instance().addMapLayers([AdpWFS])

    # Start editing the layer
    AdpWFS.startEditing()

    # Define the field names
    percid_field_name = 'PercId'
    canu_field_name = 'CANU'
    
    # Add new fields if they do not already exist
    provider = AdpWFS.dataProvider()
    fields_to_add = [
        QgsField('Label', QVariant.String),
        QgsField('Legende1', QVariant.Int),
        QgsField('Legende2', QVariant.Int),
        QgsField(percid_field_name, QVariant.String)
    ]
    
    provider.addAttributes(fields_to_add)
    AdpWFS.updateFields()

    # Get indices for the new fields
    label_idx = AdpWFS.fields().indexOf('Label')
    legende1_idx = AdpWFS.fields().indexOf('Legende1')
    legende2_idx = AdpWFS.fields().indexOf('Legende2')
    percid_idx = AdpWFS.fields().indexOf(percid_field_name)
    
    # Get the field index for CANU
    canu_idx = AdpWFS.fields().indexOf(canu_field_name)
    
    if canu_idx == -1:
        print(f"Field {canu_field_name} not found.")
    else:
        # Apply the transformation and populate new fields
        for feature in AdpWFS.getFeatures():
            original_value = feature[canu_field_name]
            formatted_value = (
                original_value[:5] + '_' + original_value[5:6] + '_' +
                original_value[6:10] + '_' + original_value[10:12] + '_' +
                original_value[12:15] + '_' + original_value[15:17]
            )
            
            # Set attributes
            feature.setAttribute(percid_idx, formatted_value)
            feature.setAttribute(label_idx, feature[canu_idx])  # Copy value from CANU
            feature.setAttribute(legende1_idx, 0)  # Set Legende1 to 0
            feature.setAttribute(legende2_idx, 0)  # Set Legende2 to 0
            
            # Update feature with new attributes
            AdpWFS.updateFeature(feature)
        
        # Commit changes
        AdpWFS.commitChanges()
    
    # Define the path for saving the shapefile
    rootAdp = '//orbit/Orbit server/data/gemeente/44048/Achtergronden/GRB/GRB_MeestRecent/44048R250/'
    output_path = rootAdp + 'Adp44048B250.shp'
    
    # Save the layer as a shapefile
    error = QgsVectorFileWriter.writeAsVectorFormat(AdpWFS, output_path, 'utf-8', AdpWFS.crs(), 'ESRI Shapefile', onlySelected=False)
    
    if error == QgsVectorFileWriter.NoError:
        print(f'Shapefile saved successfully to {output_path}')
        # Load the saved shapefile into QGIS
        saved_layer = QgsVectorLayer(output_path, 'Adp44048B250', 'ogr')
        if saved_layer.isValid():
            QgsProject.instance().addMapLayer(saved_layer)
            print('Shapefile loaded successfully into QGIS.')
        else:
            print('Failed to load the saved shapefile.')
    else:
        print(f'Error saving shapefile: {error}')

    # Reload original layers
    boundingbox = QgsVectorLayer(rootAlgemeen + 'BoundingBox/Boundingbox44048.shp', 'boundingbox', 'ogr')
    gemeentegrens = QgsVectorLayer(rootAlgemeen + 'Grenzen/Gemeentegrens/Apn_gemeentegrens.shp', 'gemeentegrens', 'ogr')
    QgsProject.instance().addMapLayers([boundingbox, gemeentegrens])

# The script does not exit QGIS, so the layers remain open.
5
  • 2
    Make sure you use QVariant and not Qvariant
    – Bera
    Commented Aug 14 at 9:24
  • 1
    Also QGIS has not been built on Qt4 since version 2 (6+ years ago). Now PyQt5. Best is just use from qgis.PyQt.QtCore import QVariant (explicit import is better than wildcard imports).
    – Ben W
    Commented Aug 14 at 9:38
  • 1
    Also you have a feature collection/Layer from the WFS not a shapefile which is a specific and obsolete data format
    – Ian Turton
    Commented Aug 14 at 10:53
  • 1
    Also not sure you're able to edit this layer. If I load it in QGIS it's a read-only layer with no capabilities of edition.
    – YoLecomte
    Commented Aug 14 at 13:01
  • Considering the issues you are having, it looks like you have been using outdated QGIS2 resources for work done in QGIS3. Be sure to use the correct resources while you work, such as the PyQGIS developers cookbook for the version you are using docs.qgis.org/3.34/en/docs/pyqgis_developer_cookbook/index.html Commented Aug 22 at 10:38

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.