I'm creating a custom QGIS Processing plugin. I've created a tool that is basically supposed to copy features from an input PostGIS layer to a new PostGIS layer. My routine runs without errors and successfully creates the new table in the database, but when I load the new layer into QGIS no features are copied over. I can't figure out what I'm missing.
Code is copied below. At this point I'm testing by simply copying the feature geometries, although in the future I would also be copying attribute information.
from PyQt4.QtCore import QSettings, QVariantfrom qgis.core import QgsDataSourceURI, QgsVectorLayerImport, QGis, QgsFeature, QgsGeometryimport processingfrom processing.core.GeoAlgorithm import GeoAlgorithmfrom processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionExceptionfrom processing.core.parameters import ParameterVectorfrom processing.core.parameters import ParameterStringfrom processing.core.parameters import ParameterTableFieldfrom processing.core.parameters import ParameterBooleanfrom processing.core.parameters import ParameterSelectionfrom processing.tools import dataobjects, vectorfrom processing.algs.qgis import postgis_utilsfrom dbutils import LayerDbInfoclass StandardizeRoadNetwork(GeoAlgorithm): TABLE_NAME = 'TABLE_NAME' ROADS_LAYER = 'ROADS_LAYER' def defineCharacteristics(self): self.name = 'Create standardized road layer' self.group = 'Algorithms for vector layers' self.addParameter(ParameterString(self.TABLE_NAME, self.tr('Name of table to be created'), optional=False)) self.addParameter(ParameterVector(self.ROADS_LAYER, self.tr('Roads layer'), [ParameterVector.VECTOR_TYPE_LINE], optional=False)) def processAlgorithm(self, progress): # Retrieve the values of the parameters entered by the user tableName = self.getParameterValue(self.TABLE_NAME).strip().lower() inLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.ROADS_LAYER)) roadsDb = LayerDbInfo(inLayer.source()) dbHost = roadsDb.getHost() dbPort = roadsDb.getPort() dbName = roadsDb.getDBName() dbUser = roadsDb.getUser() dbPass = roadsDb.getPassword() dbSchema = roadsDb.getSchema() dbType = roadsDb.getType() dbSRID = roadsDb.getSRID() try: db = postgis_utils.GeoDB(host=dbHost, port=dbPort, dbname=dbName, user=dbUser, passwd=dbPass) except postgis_utils.DbError, e: raise GeoAlgorithmExecutionException( self.tr("Couldn't connect to database:\n%s" % e.message)) # create new table, starting with new fields fieldList = [ {'name': 'id', 'pgtype': 'serial'}, {'name': 'road_name', 'pgtype': 'text'} ] dbFields = [] for f in fieldList: dbFields.append(postgis_utils.TableField(f['name'],f['pgtype'])) db.create_table(tableName, dbFields, pkey='id', schema=dbSchema) db.add_geometry_column(tableName, dbType, schema=dbSchema, geom_column='geom', srid=dbSRID) db.create_spatial_index(tableName, schema=dbSchema, geom_column='geom') # set up the new table's uri and get new object uri = QgsDataSourceURI() uri.setConnection(dbHost, str(dbPort), dbName, dbUser, dbPass) uri.setDataSource(dbSchema, tableName, 'geom', 'id') outLayer = dataobjects.getObjectFromUri(uri.uri(),forceLoad=True) # iterate features and add to new table outFields = outLayer.dataProvider().fields() inGeom = QgsGeometry() for feature in vector.features(inLayer): outFeat = QgsFeature(outFields) inGeom = feature.geometry() outFeat.setGeometry(inGeom) outLayer.addFeature(outFeat) del outFeat outLayer.commitChanges()
أكثر...
Code is copied below. At this point I'm testing by simply copying the feature geometries, although in the future I would also be copying attribute information.
from PyQt4.QtCore import QSettings, QVariantfrom qgis.core import QgsDataSourceURI, QgsVectorLayerImport, QGis, QgsFeature, QgsGeometryimport processingfrom processing.core.GeoAlgorithm import GeoAlgorithmfrom processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionExceptionfrom processing.core.parameters import ParameterVectorfrom processing.core.parameters import ParameterStringfrom processing.core.parameters import ParameterTableFieldfrom processing.core.parameters import ParameterBooleanfrom processing.core.parameters import ParameterSelectionfrom processing.tools import dataobjects, vectorfrom processing.algs.qgis import postgis_utilsfrom dbutils import LayerDbInfoclass StandardizeRoadNetwork(GeoAlgorithm): TABLE_NAME = 'TABLE_NAME' ROADS_LAYER = 'ROADS_LAYER' def defineCharacteristics(self): self.name = 'Create standardized road layer' self.group = 'Algorithms for vector layers' self.addParameter(ParameterString(self.TABLE_NAME, self.tr('Name of table to be created'), optional=False)) self.addParameter(ParameterVector(self.ROADS_LAYER, self.tr('Roads layer'), [ParameterVector.VECTOR_TYPE_LINE], optional=False)) def processAlgorithm(self, progress): # Retrieve the values of the parameters entered by the user tableName = self.getParameterValue(self.TABLE_NAME).strip().lower() inLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.ROADS_LAYER)) roadsDb = LayerDbInfo(inLayer.source()) dbHost = roadsDb.getHost() dbPort = roadsDb.getPort() dbName = roadsDb.getDBName() dbUser = roadsDb.getUser() dbPass = roadsDb.getPassword() dbSchema = roadsDb.getSchema() dbType = roadsDb.getType() dbSRID = roadsDb.getSRID() try: db = postgis_utils.GeoDB(host=dbHost, port=dbPort, dbname=dbName, user=dbUser, passwd=dbPass) except postgis_utils.DbError, e: raise GeoAlgorithmExecutionException( self.tr("Couldn't connect to database:\n%s" % e.message)) # create new table, starting with new fields fieldList = [ {'name': 'id', 'pgtype': 'serial'}, {'name': 'road_name', 'pgtype': 'text'} ] dbFields = [] for f in fieldList: dbFields.append(postgis_utils.TableField(f['name'],f['pgtype'])) db.create_table(tableName, dbFields, pkey='id', schema=dbSchema) db.add_geometry_column(tableName, dbType, schema=dbSchema, geom_column='geom', srid=dbSRID) db.create_spatial_index(tableName, schema=dbSchema, geom_column='geom') # set up the new table's uri and get new object uri = QgsDataSourceURI() uri.setConnection(dbHost, str(dbPort), dbName, dbUser, dbPass) uri.setDataSource(dbSchema, tableName, 'geom', 'id') outLayer = dataobjects.getObjectFromUri(uri.uri(),forceLoad=True) # iterate features and add to new table outFields = outLayer.dataProvider().fields() inGeom = QgsGeometry() for feature in vector.features(inLayer): outFeat = QgsFeature(outFields) inGeom = feature.geometry() outFeat.setGeometry(inGeom) outLayer.addFeature(outFeat) del outFeat outLayer.commitChanges()
أكثر...