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.
QVariant
and notQvariant
from qgis.PyQt.QtCore import QVariant
(explicit import is better than wildcard imports).