1

I am trying to update a geometry using changeGeometryValues, it works fine when the layer is of type shp or geopakage, but when I use it in SpatialLite layer it gives me the following error.

This is part of the code that I use. How can I solve this error?


feats1 = [ feat for feat in QgsProject.instance().mapLayersByName('trapecio_lineal')[0].getFeatures() ]
 
feats2 = [ feat for feat in QgsProject.instance().mapLayersByName('malezas_areal')[0].getFeatures() ]
 
tempLayer = QgsVectorLayer('Polygon?crs=EPSG:3795', 'templayer', 'memory')
dptemp = tempLayer.dataProvider()
feattemp = QgsFeature()

for feats_trapecio in feats1:
    geom1 = feats_trapecio.geometry()
    iter = feats_trapecio.geometry().vertices() 
    listOfVertices = []
    while iter.hasNext():
        vertex = iter.next() 
        listOfVertices.append([vertex.x(), vertex.y()]) 
  
    poligonotrapecio = listOfVertices
    
    points =[]

    for i in range(len(poligonotrapecio)):
        point=QgsPointXY(float(poligonotrapecio[i][0]), float(poligonotrapecio[i][1]))
        points.append(point)

    polig = QgsGeometry.fromPolygonXY([points])
    feattemp.setGeometry(polig)
    
    tempLayer.dataProvider().addFeatures([feattemp])
    tempLayer.commitChanges()
    geomtemplayer = feattemp.geometry() 
    
    for feats in feats2:
        geom2 = feats.geometry()
        fid = feats.id()

        if geomtemplayer.intersects(geom2):
           
            geom4 = geom2.intersection(geomtemplayer)
           
            QgsProject.instance().mapLayersByName('malezas_areal')[0].dataProvider().changeGeometryValues({fid: geom4})

QgsProject.instance().mapLayersByName('malezas_areal')[0].commitChanges()
QgsProject.instance().addMapLayer(tempLayer)

QgsProject.instance().removeMapLayer(tempLayer.id())

This is the error that appears in the Qgis panel:

Error de SQLite: areas_verdes_y_terrenos.malezas_areal.GEOMETRY violates Geometry constraint [geom-type or SRID not allowed] SQL: UPDATE "areas_verdes_y_terrenos.malezas_areal" SET "geometry"=GeomFromWKB(?, 3795) WHERE "ogc_fid"=?

1 Answer 1

1

Problem solved: In the end I could not use the changeGeometryValues function, instead of that method, what I did was create the new geometry with the interception, obtain the fields and their values, delete the geometry that was modified and add the new feature. This is the code in case it is useful to someone with a similar problem.

import sqlite3

from qgis._core import QgsGeometry, QgsPointXY

layer = 'malezas_areal'

layer_int= QgsProject.instance().mapLayersByName(layer)[0]

layer_poli = QgsVectorLayer('MultiPolygon?crs=EPSG:3795', 'poligono', 'memory')

feats_trapecio =[ feat for feat in QgsProject.instance().mapLayersByName('trapecio_lineal')[0].getFeatures() ]
feats_capa = [feat for feat in QgsProject.instance().mapLayersByName(layer)[0].getFeatures()]

tempLayer = QgsVectorLayer('MultiPolygon?crs=EPSG:3795', 'templayer', 'memory')

feattemp = QgsFeature()
featurepoli = QgsFeature(layer_int.fields())
inFields = layer_int.dataProvider().fields() # Lista de campos de la capa de entrada

for feat_trapecio in feats_trapecio:
    geom_trapecio = feat_trapecio.geometry()
    iter = feat_trapecio.geometry().vertices()  # Se obtiene un objeto QgsVertexIterator
    listOfVertices = []
    while iter.hasNext():
        vertex = iter.next()  # Se obtiene un objeto QgsPoint
        listOfVertices.append([vertex.x(), vertex.y()])
    poligonotrapecio = listOfVertices

    # Creando el poligono del trapecio temporal

    points = []

    for i in range(len(poligonotrapecio)):
        point = QgsPointXY(float(poligonotrapecio[i][0]), float(poligonotrapecio[i][1]))
        points.append(point)
    polig = QgsGeometry.fromMultiPolygonXY([[points]])
    feattemp.setGeometry(polig)
    tempLayer.dataProvider().addFeatures([feattemp])
    tempLayer.commitChanges()

layerProvider = layer_int.dataProvider()
layerStorage = layerProvider.storageType()

uri = layerProvider.uri()

layer_int.startEditing()


for f2 in tempLayer.getFeatures():
 
    for f1 in feats_capa:
       
        if (f1.geometry().type()!=0):
            geom_layer = f1.geometry()
        
            if (geom_trapecio.crosses(f1.geometry())):
                    fid = f1.id()
                  
                    geom4 = geom_layer.intersection(f2.geometry())

                    geom = QgsGeometry.fromWkt(geom4.asWkt())
                   
                    featurepoli.setGeometry(geom)

                    # Aqui recorrer todos los campos para asignarle los valores al nuevo feature
                    for field in layer_int.fields():
                        featurepoli.setAttribute(field.name(), f1[field.name()]) 
                    
                    #OK esto es para sustituir el original por el interceptado
                    layer_int.deleteFeature(f1.id())
                    
                    layer_int.addFeature(featurepoli)
                    layer_int.updateFields()
                      
                    layer_int.triggerRepaint()
                    QgsProject.instance().removeMapLayer(tempLayer.id())

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.