def testSimulatedDBManagerImport(self): uri = 'point?field=f1:int' uri += '&field=f2:double(6,4)' uri += '&field=f3:string(20)' lyr = QgsVectorLayer(uri, "x", "memory") self.assertTrue(lyr.isValid()) f = QgsFeature(lyr.fields()) f['f1'] = 1 f['f2'] = 123.456 f['f3'] = '12345678.90123456789' f2 = QgsFeature(lyr.fields()) f2['f1'] = 2 lyr.dataProvider().addFeatures([f, f2]) tmpfile = os.path.join(self.basetestpath, 'testSimulatedDBManagerImport.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) ds = None options = {} options['update'] = True options['driverName'] = 'GPKG' options['layerName'] = 'my_out_table' err = QgsVectorLayerImport.importLayer(lyr, tmpfile, "ogr", lyr.crs(), False, False, options) self.assertEqual(err[0], QgsVectorLayerImport.NoError, 'unexpected import error {0}'.format(err)) lyr = QgsVectorLayer(tmpfile + "|layername=my_out_table", "y", "ogr") self.assertTrue(lyr.isValid()) features = lyr.getFeatures() f = next(features) self.assertEqual(f['f1'], 1) self.assertEqual(f['f2'], 123.456) self.assertEqual(f['f3'], '12345678.90123456789') f = next(features) self.assertEqual(f['f1'], 2) features = None # Test overwriting without overwrite option err = QgsVectorLayerImport.importLayer(lyr, tmpfile, "ogr", lyr.crs(), False, False, options) self.assertEqual(err[0], QgsVectorLayerImport.ErrCreateDataSource) # Test overwriting lyr = QgsVectorLayer(uri, "x", "memory") self.assertTrue(lyr.isValid()) f = QgsFeature(lyr.fields()) f['f1'] = 3 lyr.dataProvider().addFeatures([f]) options['overwrite'] = True err = QgsVectorLayerImport.importLayer(lyr, tmpfile, "ogr", lyr.crs(), False, False, options) self.assertEqual(err[0], QgsVectorLayerImport.NoError, 'unexpected import error {0}'.format(err)) lyr = QgsVectorLayer(tmpfile + "|layername=my_out_table", "y", "ogr") self.assertTrue(lyr.isValid()) features = lyr.getFeatures() f = next(features) self.assertEqual(f['f1'], 3) features = None
def processAlgorithm(self, progress): connection = self.DB_CONNECTIONS[self.getParameterValue(self.DATABASE)] db = postgis.GeoDB.from_name(connection) schema = self.getParameterValue(self.SCHEMA) overwrite = self.getParameterValue(self.OVERWRITE) createIndex = self.getParameterValue(self.CREATEINDEX) convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES) dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH) forceSinglePart = self.getParameterValue(self.FORCE_SINGLEPART) primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) or "id" encoding = self.getParameterValue(self.ENCODING) layerUri = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(layerUri) table = self.getParameterValue(self.TABLENAME) if table: table.strip() if not table or table == "": table = layer.name() table = table.replace(".", "_") table = table.replace(" ", "").lower()[0:62] providerName = "postgres" geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN) if not geomColumn: geomColumn = "the_geom" options = {} if overwrite: options["overwrite"] = True if convertLowerCase: options["lowercaseFieldNames"] = True geomColumn = geomColumn.lower() if dropStringLength: options["dropStringConstraints"] = True if forceSinglePart: options["forceSinglePartGeometryType"] = True # Clear geometry column for non-geometry tables if not layer.hasGeometryType(): geomColumn = None uri = db.uri uri.setDataSource(schema, table, geomColumn, "", primaryKeyField) if encoding: layer.setProviderEncoding(encoding) (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, self.crs, False, False, options ) if ret != 0: raise GeoAlgorithmExecutionException(self.tr("Error importing to PostGIS\n%s" % errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, schema, geomColumn) db.vacuum_analyze(table, schema)
def testKey(lyr, key, kfnames): self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.import_test') uri = '%s table="qgis_test"."import_test" (g)' % self.dbconn if key is not None: uri += ' key=\'%s\'' % key err = QgsVectorLayerImport.importLayer(lyr, uri, "postgres", lyr.crs()) self.assertEqual(err[0], QgsVectorLayerImport.NoError, 'unexpected import error {0}'.format(err)) olyr = QgsVectorLayer(uri, "y", "postgres") self.assertTrue(olyr.isValid()) flds = lyr.fields() oflds = olyr.fields() if key is None: # if the pkey was not given, it will create a pkey self.assertEquals(oflds.size(), flds.size() + 1) self.assertEquals(oflds[0].name(), kfnames[0]) for i in range(flds.size()): self.assertEqual(oflds[i + 1].name(), flds[i].name()) else: # pkey was given, no extra field generated self.assertEquals(oflds.size(), flds.size()) for i in range(oflds.size()): self.assertEqual(oflds[i].name(), flds[i].name()) pks = olyr.pkAttributeList() self.assertEquals(len(pks), len(kfnames)) for i in range(0, len(kfnames)): self.assertEqual(oflds[pks[i]].name(), kfnames[i])
def testKey(lyr, key, kfnames): self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.import_test') uri = '%s table="qgis_test"."import_test" (g)' % self.dbconn if key is not None: uri += ' key=\'%s\'' % key err = QgsVectorLayerImport.importLayer(lyr, uri, "postgres", lyr.crs()) self.assertEqual(err[0], QgsVectorLayerImport.NoError, 'unexpected import error {0}'.format(err)) olyr = QgsVectorLayer(uri, "y", "postgres") self.assertTrue(olyr.isValid()) flds = lyr.fields() oflds = olyr.fields() if key is None: # if the pkey was not given, it will create a pkey self.assertEqual(oflds.size(), flds.size() + 1) self.assertEqual(oflds[0].name(), kfnames[0]) for i in range(flds.size()): self.assertEqual(oflds[i + 1].name(), flds[i].name()) else: # pkey was given, no extra field generated self.assertEqual(oflds.size(), flds.size()) for i in range(oflds.size()): self.assertEqual(oflds[i].name(), flds[i].name()) pks = olyr.pkAttributeList() self.assertEqual(len(pks), len(kfnames)) for i in range(0, len(kfnames)): self.assertEqual(oflds[pks[i]].name(), kfnames[i])
def testKey(lyr, key, kfnames): self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.import_test') uri = '%s table="qgis_test"."import_test" (g) key=\'%s\'' % (self.dbconn, key) err = QgsVectorLayerImport.importLayer(lyr, uri, "postgres", lyr.crs()) self.assertEqual(err[0], QgsVectorLayerImport.NoError, 'unexpected import error {0}'.format(err)) olyr = QgsVectorLayer(uri, "y", "postgres") self.assertTrue(olyr.isValid()) flds = lyr.fields() oflds = olyr.fields() self.assertEquals(oflds.size(), flds.size()) for i in range(0, oflds.size()): self.assertEqual(oflds[i].name(), flds[i].name()) pks = olyr.pkAttributeList() self.assertEquals(len(pks), len(kfnames)) for i in range(0, len(kfnames)): self.assertEqual(oflds[pks[i]].name(), kfnames[i])
def testKey(lyr, key, kfnames): self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.import_test') uri = '%s table="qgis_test"."import_test" (g) key=\'%s\'' % ( self.dbconn, key) err = QgsVectorLayerImport.importLayer(lyr, uri, "postgres", lyr.crs()) self.assertEqual(err[0], QgsVectorLayerImport.NoError, 'unexpected import error {0}'.format(err)) olyr = QgsVectorLayer(uri, "y", "postgres") self.assertTrue(olyr.isValid()) flds = lyr.fields() oflds = olyr.fields() self.assertEquals(oflds.size(), flds.size()) for i in range(0, oflds.size()): self.assertEqual(oflds[i].name(), flds[i].name()) pks = olyr.pkAttributeList() self.assertEquals(len(pks), len(kfnames)) for i in range(0, len(kfnames)): self.assertEqual(oflds[pks[i]].name(), kfnames[i])
def testNumericPrecision(self): uri = "point?field=f1:int" uri += "&field=f2:double(6,4)" uri += "&field=f3:string(20)" lyr = QgsVectorLayer(uri, "x", "memory") self.assertTrue(lyr.isValid()) f = QgsFeature(lyr.fields()) f["f1"] = 1 f["f2"] = 123.456 f["f3"] = "12345678.90123456789" lyr.dataProvider().addFeatures([f]) uri = '%s table="qgis_test"."b18155" (g) key=\'f1\'' % (self.dbconn) self.execSQLCommand("DROP TABLE IF EXISTS qgis_test.b18155") err = QgsVectorLayerImport.importLayer(lyr, uri, "postgres", lyr.crs()) self.assertEqual(err[0], QgsVectorLayerImport.NoError, "unexpected import error {0}".format(err)) lyr = QgsVectorLayer(uri, "y", "postgres") self.assertTrue(lyr.isValid()) f = next(lyr.getFeatures()) self.assertEqual(f["f1"], 1) self.assertEqual(f["f2"], 123.456) self.assertEqual(f["f3"], "12345678.90123456789")
def testNumericPrecision(self): uri = 'point?field=f1:int' uri += '&field=f2:double(6,4)' uri += '&field=f3:string(20)' lyr = QgsVectorLayer(uri, "x", "memory") self.assertTrue(lyr.isValid()) f = QgsFeature(lyr.fields()) f['f1'] = 1 f['f2'] = 123.456 f['f3'] = '12345678.90123456789' lyr.dataProvider().addFeatures([f]) uri = '%s table="qgis_test"."b18155" (g) key=\'f1\'' % (self.dbconn) self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.b18155') err = QgsVectorLayerImport.importLayer(lyr, uri, "postgres", lyr.crs()) self.assertEqual(err[0], QgsVectorLayerImport.NoError, 'unexpected import error {0}'.format(err)) lyr = QgsVectorLayer(uri, "y", "postgres") self.assertTrue(lyr.isValid()) f = next(lyr.getFeatures()) self.assertEqual(f['f1'], 1) self.assertEqual(f['f2'], 123.456) self.assertEqual(f['f3'], '12345678.90123456789')
uri = QgsDataSourceURI() uri.setConnection(host, str(port), database, username, password) newCrs = QgsCoordinateReferenceSystem() newCrs.createFromUserInput(u"EPSG:2154") #Gid = cle primaire par defaut uri.setDataSource(schema, table, geomColumn, '', "gid") progress.setInfo(u"Importation de la table vers PostgreSQL (cela peut prendre un moment)") #Import (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, newCrs, False, False, options, ) if ret != 0: raise GeoAlgorithmExecutionException( self.tr('Erreur importation dans PostGIS\n%s' % errMsg)) if primaryKeyField: sql2 ="""alter table "{schema}".{table} drop constraint {table}_pkey;""".format(schema=schema,table=table) sql2 +="""alter table "{schema}".{table} add primary key ({primaryKeyField});""".format(schema=schema,table=table,primaryKeyField=primaryKeyField) sql2 +="""COMMIT;""" try: db._exec_sql_and_commit(str(sql2))
def processAlgorithm(self, context, feedback): connection = self.getParameterValue(self.DATABASE) db = postgis.GeoDB.from_name(connection) schema = self.getParameterValue(self.SCHEMA) overwrite = self.getParameterValue(self.OVERWRITE) createIndex = self.getParameterValue(self.CREATEINDEX) convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES) dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH) forceSinglePart = self.getParameterValue(self.FORCE_SINGLEPART) primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) or 'id' encoding = self.getParameterValue(self.ENCODING) layerUri = self.getParameterValue(self.INPUT) layer = QgsProcessingUtils.mapLayerFromString(layerUri, context) table = self.getParameterValue(self.TABLENAME) if table: table.strip() if not table or table == '': table = layer.name() table = table.replace('.', '_') table = table.replace(' ', '').lower()[0:62] providerName = 'postgres' geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN) if not geomColumn: geomColumn = 'the_geom' options = {} if overwrite: options['overwrite'] = True if convertLowerCase: options['lowercaseFieldNames'] = True geomColumn = geomColumn.lower() if dropStringLength: options['dropStringConstraints'] = True if forceSinglePart: options['forceSinglePartGeometryType'] = True # Clear geometry column for non-geometry tables if not layer.hasGeometryType(): geomColumn = None uri = db.uri uri.setDataSource(schema, table, geomColumn, '', primaryKeyField) if encoding: layer.setProviderEncoding(encoding) (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, self.crs, False, False, options, ) if ret != 0: raise GeoAlgorithmExecutionException( self.tr('Error importing to PostGIS\n{0}').format(errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, schema, geomColumn) db.vacuum_analyze(table, schema)
def processAlgorithm(self, progress): connection = self.DB_CONNECTIONS[self.getParameterValue(self.DATABASE)] schema = self.getParameterValue(self.SCHEMA) overwrite = self.getParameterValue(self.OVERWRITE) createIndex = self.getParameterValue(self.CREATEINDEX) convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES) dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH) primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) settings = QSettings() mySettings = '/PostgreSQL/connections/' + connection try: database = settings.value(mySettings + '/database') username = settings.value(mySettings + '/username') host = settings.value(mySettings + '/host') port = settings.value(mySettings + '/port', type=int) password = settings.value(mySettings + '/password') except Exception as e: raise GeoAlgorithmExecutionException( self.tr('Wrong database connection name: %s' % connection)) layerUri = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(layerUri) table = self.getParameterValue(self.TABLENAME).strip() if table == '': table = layer.name() table = table.replace(' ', '').lower() providerName = 'postgres' try: db = postgis_utils.GeoDB(host=host, port=port, dbname=database, user=username, passwd=password) except postgis_utils.DbError as e: raise GeoAlgorithmExecutionException( self.tr("Couldn't connect to database:\n%s" % e.message)) geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN) if not geomColumn: geomColumn = 'the_geom' options = {} if overwrite: options['overwrite'] = True if convertLowerCase: options['lowercaseFieldNames'] = True geomColumn = geomColumn.lower() if dropStringLength: options['dropStringConstraints'] = True #clear geometry column for non-geometry tables if not layer.hasGeometryType(): geomColumn = None uri = QgsDataSourceURI() uri.setConnection(host, unicode(port), database, username, password) if primaryKeyField: uri.setDataSource(schema, table, geomColumn, '', primaryKeyField) else: uri.setDataSource(schema, table, geomColumn, '') (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, self.crs, False, False, options, ) if ret != 0: raise GeoAlgorithmExecutionException( self.tr('Error importing to PostGIS\n%s' % errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, schema, geomColumn) db.vacuum_analyze(table, schema)
def processAlgorithm(self, progress): database = self.getParameterValue(self.DATABASE) uri = QgsDataSourceUri(database) if uri.database() is '': if '|layerid' in database: database = database[:database.find('|layerid')] uri = QgsDataSourceUri('dbname=\'%s\'' % (database)) db = spatialite.GeoDB(uri) overwrite = self.getParameterValue(self.OVERWRITE) createIndex = self.getParameterValue(self.CREATEINDEX) convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES) dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH) forceSinglePart = self.getParameterValue(self.FORCE_SINGLEPART) primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) or 'id' encoding = self.getParameterValue(self.ENCODING) layerUri = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(layerUri) table = self.getParameterValue(self.TABLENAME) if table: table.strip() if not table or table == '': table = layer.name() table = table.replace(' ', '').lower() providerName = 'spatialite' geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN) if not geomColumn: geomColumn = 'the_geom' options = {} if overwrite: options['overwrite'] = True if convertLowerCase: options['lowercaseFieldNames'] = True geomColumn = geomColumn.lower() if dropStringLength: options['dropStringConstraints'] = True if forceSinglePart: options['forceSinglePartGeometryType'] = True # Clear geometry column for non-geometry tables if not layer.hasGeometryType(): geomColumn = None uri = db.uri uri.setDataSource('', table, geomColumn, '', primaryKeyField) if encoding: layer.setProviderEncoding(encoding) (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, self.crs, False, False, options, ) if ret != 0: raise GeoAlgorithmExecutionException( self.tr('Error importing to Spatialite\n%s' % errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, geomColumn)
def processAlgorithm(self, feedback): database = self.getParameterValue(self.DATABASE) uri = QgsDataSourceUri(database) if uri.database() is '': if '|layerid' in database: database = database[:database.find('|layerid')] uri = QgsDataSourceUri('dbname=\'%s\'' % (database)) db = spatialite.GeoDB(uri) overwrite = self.getParameterValue(self.OVERWRITE) createIndex = self.getParameterValue(self.CREATEINDEX) convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES) dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH) forceSinglePart = self.getParameterValue(self.FORCE_SINGLEPART) primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) or 'id' encoding = self.getParameterValue(self.ENCODING) layerUri = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(layerUri) table = self.getParameterValue(self.TABLENAME) if table: table.strip() if not table or table == '': table = layer.name() table = table.replace(' ', '').lower() providerName = 'spatialite' geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN) if not geomColumn: geomColumn = 'the_geom' options = {} if overwrite: options['overwrite'] = True if convertLowerCase: options['lowercaseFieldNames'] = True geomColumn = geomColumn.lower() if dropStringLength: options['dropStringConstraints'] = True if forceSinglePart: options['forceSinglePartGeometryType'] = True # Clear geometry column for non-geometry tables if not layer.hasGeometryType(): geomColumn = None uri = db.uri uri.setDataSource('', table, geomColumn, '', primaryKeyField) if encoding: layer.setProviderEncoding(encoding) (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, self.crs, False, False, options, ) if ret != 0: raise GeoAlgorithmExecutionException( self.tr('Error importing to Spatialite\n%s' % errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, geomColumn)
def accept(self): if self.mode == self.ASK_FOR_INPUT_MODE: # create the input layer (if not already done) and # update available options self.reloadInputLayer() # sanity checks if self.inLayer is None: QMessageBox.information( self, self.tr("Import to database"), self.tr("Input layer missing or not valid")) return if self.cboTable.currentText() == "": QMessageBox.information(self, self.tr("Import to database"), self.tr("Output table name is required")) return if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): try: sourceSrid = self.editSourceSrid.text() except ValueError: QMessageBox.information( self, self.tr("Import to database"), self.tr("Invalid source srid: must be an integer")) return if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): try: targetSrid = self.editTargetSrid.text() except ValueError: QMessageBox.information( self, self.tr("Import to database"), self.tr("Invalid target srid: must be an integer")) return # override cursor QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # store current input layer crs and encoding, so I can restore it prevInCrs = self.inLayer.crs() prevInEncoding = self.inLayer.dataProvider().encoding() try: schema = self.outUri.schema() if not self.cboSchema.isEnabled( ) else self.cboSchema.currentText() table = self.cboTable.currentText() # get pk and geom field names from the source layer or use the # ones defined by the user srcUri = QgsDataSourceURI(self.inLayer.source()) pk = srcUri.keyColumn() if not self.chkPrimaryKey.isChecked( ) else self.editPrimaryKey.text() if not pk: pk = self.default_pk if self.inLayer.hasGeometryType() and self.chkGeomColumn.isEnabled( ): geom = srcUri.geometryColumn( ) if not self.chkGeomColumn.isChecked( ) else self.editGeomColumn.text() if not geom: geom = self.default_geom else: geom = None options = {} if self.chkLowercaseFieldNames.isEnabled( ) and self.chkLowercaseFieldNames.isChecked(): pk = pk.lower() if geom: geom = geom.lower() options['lowercaseFieldNames'] = True # get output params, update output URI self.outUri.setDataSource(schema, table, geom, "", pk) typeName = self.db.dbplugin().typeName() providerName = self.db.dbplugin().providerName() if typeName == 'gpkg': uri = self.outUri.database() options['update'] = True options['driverName'] = 'GPKG' options['layerName'] = table else: uri = self.outUri.uri(False) if self.chkDropTable.isChecked(): options['overwrite'] = True if self.chkSinglePart.isEnabled() and self.chkSinglePart.isChecked( ): options['forceSinglePartGeometryType'] = True outCrs = None if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked( ): targetSrid = int(self.editTargetSrid.text()) outCrs = QgsCoordinateReferenceSystem(targetSrid) # update input layer crs and encoding if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked( ): sourceSrid = int(self.editSourceSrid.text()) inCrs = QgsCoordinateReferenceSystem(sourceSrid) self.inLayer.setCrs(inCrs) if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked(): enc = self.cboEncoding.currentText() self.inLayer.setProviderEncoding(enc) onlySelected = self.chkSelectedFeatures.isChecked() # do the import! ret, errMsg = QgsVectorLayerImport.importLayer( self.inLayer, uri, providerName, outCrs, onlySelected, False, options) except Exception as e: ret = -1 errMsg = unicode(e) finally: # restore input layer crs and encoding self.inLayer.setCrs(prevInCrs) self.inLayer.setProviderEncoding(prevInEncoding) # restore cursor QApplication.restoreOverrideCursor() if ret != 0: output = QgsMessageViewer() output.setTitle(self.tr("Import to database")) output.setMessageAsPlainText( self.tr("Error %d\n%s") % (ret, errMsg)) output.showMessage() return # create spatial index if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked( ): self.db.connector.createSpatialIndex((schema, table), geom) self.db.connection().reconnect() self.db.refresh() QMessageBox.information(self, self.tr("Import to database"), self.tr("Import was successful.")) return QDialog.accept(self)
def accept(self): if self.mode == self.ASK_FOR_INPUT_MODE: # create the input layer (if not already done) and # update available options self.reloadInputLayer() # sanity checks if self.inLayer is None: QMessageBox.information(self, self.tr("Import to database"), self.tr("Input layer missing or not valid")) return if self.cboTable.currentText() == "": QMessageBox.information(self, self.tr("Import to database"), self.tr("Output table name is required")) return if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): try: sourceSrid = self.editSourceSrid.text() except ValueError: QMessageBox.information(self, self.tr("Import to database"), self.tr("Invalid source srid: must be an integer")) return if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): try: targetSrid = self.editTargetSrid.text() except ValueError: QMessageBox.information(self, self.tr("Import to database"), self.tr("Invalid target srid: must be an integer")) return # override cursor QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # store current input layer crs and encoding, so I can restore it prevInCrs = self.inLayer.crs() prevInEncoding = self.inLayer.dataProvider().encoding() try: schema = self.outUri.schema() if not self.cboSchema.isEnabled() else self.cboSchema.currentText() table = self.cboTable.currentText() # get pk and geom field names from the source layer or use the # ones defined by the user srcUri = QgsDataSourceUri(self.inLayer.source()) pk = srcUri.keyColumn() if not self.chkPrimaryKey.isChecked() else self.editPrimaryKey.text() if not pk: pk = self.default_pk if self.inLayer.hasGeometryType() and self.chkGeomColumn.isEnabled(): geom = srcUri.geometryColumn() if not self.chkGeomColumn.isChecked() else self.editGeomColumn.text() if not geom: geom = self.default_geom else: geom = None options = {} if self.chkLowercaseFieldNames.isEnabled() and self.chkLowercaseFieldNames.isChecked(): pk = pk.lower() if geom: geom = geom.lower() options['lowercaseFieldNames'] = True # get output params, update output URI self.outUri.setDataSource(schema, table, geom, "", pk) uri = self.outUri.uri(False) providerName = self.db.dbplugin().providerName() if self.chkDropTable.isChecked(): options['overwrite'] = True if self.chkSinglePart.isEnabled() and self.chkSinglePart.isChecked(): options['forceSinglePartGeometryType'] = True outCrs = QgsCoordinateReferenceSystem() if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): targetSrid = int(self.editTargetSrid.text()) outCrs = QgsCoordinateReferenceSystem(targetSrid) # update input layer crs and encoding if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): sourceSrid = int(self.editSourceSrid.text()) inCrs = QgsCoordinateReferenceSystem(sourceSrid) self.inLayer.setCrs(inCrs) if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked(): enc = self.cboEncoding.currentText() self.inLayer.setProviderEncoding(enc) onlySelected = self.chkSelectedFeatures.isChecked() # do the import! ret, errMsg = QgsVectorLayerImport.importLayer(self.inLayer, uri, providerName, outCrs, onlySelected, False, options) except Exception as e: ret = -1 errMsg = str(e) finally: # restore input layer crs and encoding self.inLayer.setCrs(prevInCrs) self.inLayer.setProviderEncoding(prevInEncoding) # restore cursor QApplication.restoreOverrideCursor() if ret != 0: output = QgsMessageViewer() output.setTitle(self.tr("Import to database")) output.setMessageAsPlainText(self.tr("Error %d\n%s") % (ret, errMsg)) output.showMessage() return # create spatial index if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked(): self.db.connector.createSpatialIndex((schema, table), geom) QMessageBox.information(self, self.tr("Import to database"), self.tr("Import was successful.")) return QDialog.accept(self)
class QGisLayerImporter(Importer): def run(self): self.importThread = QGisLayerImporter.ImportThread( self.inLayer, self.outUri) QObject.connect(self.importThread, SIGNAL("importFinished"), self._importFinished) self.importThread.start() self.eventLoop.exec_() # cleanup self._cancelImport() return self._retCode == 0 def cancel(self): self._cancelImport() self.eventLoop.quit() def _importFinished(self, retCode, errorMsg): self._retCode = retCode self._errorMsg = u"Error %d\n%s" % (retCode, errorMsg) self.eventLoop.quit() def _cancelImport(self): if getattr(self, 'importThread', None): QObject.disconnect(self.importThread, SIGNAL("importFinished"), self._importFinished) self.importThread.terminate() self.importThread.wait() self.importThread.deleteLater() self.importThread = None class ImportThread(QThread): def __init__(self, inLayer, outUri): QThread.__init__(self) self.inLayer = inLayer self.outUri = outUri def run(self): try: self._run() except Exception, e: QgsMessageLog.instance().logMessage( u"Uncaught exception.\n%s" % unicode(e), "GEM-MT") self.emit(SIGNAL("importFinished"), -2, "An error occurred") def _run(self): path = self.outUri.database() # create the SL database if it doesn't exist f = QFile(path) if not f.exists(): from pyspatialite import dbapi2 as sqlite try: conn = sqlite.connect(unicode(path)) conn.cursor().execute("SELECT InitSpatialMetadata()") conn.commit() del conn except Exception, e: # if an error occurs, remove the database file if f.exists(): f.remove() msg = u"Unable to create the database %s. \nError was: %s" % ( path, unicode(e)) self.emit(SIGNAL("importFinished"), -1, msg) return # import the CSV data to the SL database from qgis.core import QgsVectorLayerImport ret, errMsg = QgsVectorLayerImport.importLayer( self.inLayer, self.outUri.uri(), 'spatialite', self.inLayer.crs(), False, False, {'overwrite': True}) self.emit(SIGNAL("importFinished"), ret, errMsg)
def accept(self): # sanity checks if self.editOutputFile.text() == "": QMessageBox.information(self, self.tr("Export to file"), self.tr("Output file name is required")) return if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): try: sourceSrid = int(self.editSourceSrid.text()) except ValueError: QMessageBox.information( self, self.tr("Export to file"), self.tr("Invalid source srid: must be an integer")) return if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): try: targetSrid = int(self.editTargetSrid.text()) except ValueError: QMessageBox.information( self, self.tr("Export to file"), self.tr("Invalid target srid: must be an integer")) return # override cursor QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # store current input layer crs, so I can restore it later prevInCrs = self.inLayer.crs() try: uri = self.editOutputFile.text() providerName = "ogr" options = {} # set the OGR driver will be used driverName = self.cboFileFormat.itemData( self.cboFileFormat.currentIndex()) options['driverName'] = driverName # set the output file encoding if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked(): enc = self.cboEncoding.currentText() options['fileEncoding'] = enc if self.chkDropTable.isChecked(): options['overwrite'] = True outCrs = None if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked( ): targetSrid = int(self.editTargetSrid.text()) outCrs = QgsCoordinateReferenceSystem(targetSrid) # update input layer crs if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked( ): sourceSrid = int(self.editSourceSrid.text()) inCrs = QgsCoordinateReferenceSystem(sourceSrid) self.inLayer.setCrs(inCrs) # do the export! ret, errMsg = QgsVectorLayerImport.importLayer( self.inLayer, uri, providerName, outCrs, False, False, options) except Exception as e: ret = -1 errMsg = unicode(e) finally: # restore input layer crs and encoding self.inLayer.setCrs(prevInCrs) # restore cursor QApplication.restoreOverrideCursor() if ret != 0: QMessageBox.warning(self, self.tr("Export to file"), self.tr("Error %d\n%s") % (ret, errMsg)) return # create spatial index # if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked(): # self.db.connector.createSpatialIndex( (schema, table), geom ) QMessageBox.information(self, self.tr("Export to file"), self.tr("Export finished.")) return QDialog.accept(self)
def accept(self): # sanity checks if self.editOutputFile.text() == "": QMessageBox.information(self, self.tr("Export to file"), self.tr("Output file name is required")) return if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): try: sourceSrid = int(self.editSourceSrid.text()) except ValueError: QMessageBox.information(self, self.tr("Export to file"), self.tr("Invalid source srid: must be an integer")) return if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): try: targetSrid = int(self.editTargetSrid.text()) except ValueError: QMessageBox.information(self, self.tr("Export to file"), self.tr("Invalid target srid: must be an integer")) return # override cursor QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # store current input layer crs, so I can restore it later prevInCrs = self.inLayer.crs() try: uri = self.editOutputFile.text() providerName = "ogr" options = {} # set the OGR driver will be used driverName = self.cboFileFormat.itemData(self.cboFileFormat.currentIndex()) options['driverName'] = driverName # set the output file encoding if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked(): enc = self.cboEncoding.currentText() options['fileEncoding'] = enc if self.chkDropTable.isChecked(): options['overwrite'] = True outCrs = None if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked(): targetSrid = int(self.editTargetSrid.text()) outCrs = QgsCoordinateReferenceSystem(targetSrid) # update input layer crs if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked(): sourceSrid = int(self.editSourceSrid.text()) inCrs = QgsCoordinateReferenceSystem(sourceSrid) self.inLayer.setCrs(inCrs) # do the export! ret, errMsg = QgsVectorLayerImport.importLayer(self.inLayer, uri, providerName, outCrs, False, False, options) except Exception as e: ret = -1 errMsg = unicode(e) finally: # restore input layer crs and encoding self.inLayer.setCrs(prevInCrs) # restore cursor QApplication.restoreOverrideCursor() if ret != 0: QMessageBox.warning(self, self.tr("Export to file"), self.tr("Error %d\n%s") % (ret, errMsg)) return # create spatial index # if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked(): # self.db.connector.createSpatialIndex( (schema, table), geom ) QMessageBox.information(self, self.tr("Export to file"), self.tr("Export finished.")) return QDialog.accept(self)
def open_file( dialog=None, osm_file=None, output_geom_types=None, white_list_column=None, output_format=None, layer_name="OsmFile", config_outputs=None, output_dir=None, prefix_file=None): """ open an osm file """ outputs = get_outputs(output_dir, output_format, prefix_file, layer_name) # Parsing the file osm_parser = OsmParser( osm_file=osm_file, layers=output_geom_types, white_list_column=white_list_column) osm_parser.signalText.connect(dialog.set_progress_text) osm_parser.signalPercentage.connect(dialog.set_progress_percentage) layers = osm_parser.parse() # Finishing the process with geojson or shapefile num_layers = 0 if output_format == "shape": dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile")) if output_format == "spatialite": dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to SpatiaLite")) # create spatialite DB conn = sqlitedb.connect(outputs['file']) cur = conn.cursor() cur.execute("SELECT initSpatialMetadata(1)") conn.close() for i, (layer, item) in enumerate(layers.iteritems()): dialog.set_progress_percentage(i / len(layers) * 100) QApplication.processEvents() if item['featureCount'] and layer in output_geom_types: final_layer_name = layer_name # If configOutputs is not None (from My Queries) if config_outputs: if config_outputs[layer]['namelayer']: final_layer_name = config_outputs[layer]['namelayer'] # Transforming the vector file osm_geometries = { 'points': QGis.WKBPoint, 'lines': QGis.WKBLineString, 'multilinestrings': QGis.WKBMultiLineString, 'multipolygons': QGis.WKBMultiPolygon} geojson_layer = QgsVectorLayer(item['geojsonFile'], "temp", "ogr") encoding = get_default_encoding() if output_format == "shape": provider = "ESRI Shapefile" elif output_format == "geojson": provider = "GeoJSON" if output_format == "spatialite": uri = QgsDataSourceURI() uri.setDatabase(outputs['file']) uri.setDataSource('', outputs[layer], 'geom') layer_source = uri.uri() layer_provider = 'spatialite' writer = QgsVectorLayerImport( layer_source, layer_provider, geojson_layer.pendingFields(), osm_geometries[layer], geojson_layer.crs()) else: layer_source = outputs[layer] layer_provider = 'ogr' writer = QgsVectorFileWriter( layer_source, encoding, geojson_layer.pendingFields(), osm_geometries[layer], geojson_layer.crs(), provider) for f in geojson_layer.getFeatures(): writer.addFeature(f) del writer # Loading the final vector file new_layer = QgsVectorLayer(layer_source, final_layer_name, layer_provider) # Try to set styling if defined if config_outputs and config_outputs[layer]['style']: new_layer.loadNamedStyle(config_outputs[layer]['style']) else: # Loading default styles if layer == "multilinestrings" or layer == "lines": if "colour" in item['tags']: new_layer.loadNamedStyle( join(dirname(dirname(abspath(__file__))), "styles", layer + "_colour.qml")) # Add action about OpenStreetMap actions = new_layer.actions() actions.addAction( QgsAction.OpenUrl, "OpenStreetMap Browser", 'http://www.openstreetmap.org/browse/' '[% "osm_type" %]/[% "osm_id" %]', False) actions.addAction( QgsAction.GenericPython, 'JOSM', 'from QuickOSM.CoreQuickOSM.Actions import Actions;' 'Actions.run("josm","[% "full_id" %]")', False) actions.addAction( QgsAction.OpenUrl, "User default editor", 'http://www.openstreetmap.org/edit?' '[% "osm_type" %]=[% "osm_id" %]', False) for link in ['url', 'website', 'wikipedia', 'ref:UAI']: if link in item['tags']: link = link.replace(":", "_") actions.addAction( QgsAction.GenericPython, link, 'from QuickOSM.core.actions import Actions;' 'Actions.run("' + link + '","[% "' + link + '" %]")', False) if 'network' in item['tags'] and 'ref' in item['tags']: actions.addAction( QgsAction.GenericPython, "Sketchline", 'from QuickOSM.core.actions import Actions;' 'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")', False) # Add index if possible if output_format == "shape" or output_format == "spatialite": new_layer.dataProvider().createSpatialIndex() QgsMapLayerRegistry.instance().addMapLayer(new_layer) num_layers += 1 return num_layers
#clear geometry column for non-geometry tables if not layer.hasGeometryType(): geomColumn = None uri = QgsDataSourceURI() uri.setConnection(host, str(port), database, username, password) if primaryKeyField: uri.setDataSource(schema, table, geomColumn, '', primaryKeyField) else: uri.setDataSource(schema, table, geomColumn, '') (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, self.crs, False, False, options, ) if ret != 0: raise GeoAlgorithmExecutionException( self.tr('Error importing to PostGIS\n%s' % errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, schema, geomColumn) db.vacuum_analyze(table, schema) def dbConnectionNames(self): settings = QSettings()
def open_file(dialog=None, osm_file=None, output_geom_types=None, white_list_column=None, output_format=None, layer_name="OsmFile", config_outputs=None, output_dir=None, prefix_file=None): """ open an osm file """ outputs = get_outputs(output_dir, output_format, prefix_file, layer_name) # Parsing the file osm_parser = OsmParser(osm_file=osm_file, layers=output_geom_types, white_list_column=white_list_column) osm_parser.signalText.connect(dialog.set_progress_text) osm_parser.signalPercentage.connect(dialog.set_progress_percentage) layers = osm_parser.parse() # Finishing the process with geojson or shapefile num_layers = 0 if output_format == "shape": dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to Shapefile")) if output_format == "spatialite": dialog.set_progress_text(tr("QuickOSM", u"From GeoJSON to SpatiaLite")) # create spatialite DB conn = sqlitedb.connect(outputs['file']) cur = conn.cursor() cur.execute("SELECT initSpatialMetadata(1)") conn.close() for i, (layer, item) in enumerate(layers.iteritems()): dialog.set_progress_percentage(i / len(layers) * 100) QApplication.processEvents() if item['featureCount'] and layer in output_geom_types: final_layer_name = layer_name # If configOutputs is not None (from My Queries) if config_outputs: if config_outputs[layer]['namelayer']: final_layer_name = config_outputs[layer]['namelayer'] # Transforming the vector file osm_geometries = { 'points': QGis.WKBPoint, 'lines': QGis.WKBLineString, 'multilinestrings': QGis.WKBMultiLineString, 'multipolygons': QGis.WKBMultiPolygon } geojson_layer = QgsVectorLayer(item['geojsonFile'], "temp", "ogr") encoding = get_default_encoding() if output_format == "shape": provider = "ESRI Shapefile" elif output_format == "geojson": provider = "GeoJSON" if output_format == "spatialite": uri = QgsDataSourceURI() uri.setDatabase(outputs['file']) uri.setDataSource('', outputs[layer], 'geom') layer_source = uri.uri() layer_provider = 'spatialite' writer = QgsVectorLayerImport(layer_source, layer_provider, geojson_layer.pendingFields(), osm_geometries[layer], geojson_layer.crs()) else: layer_source = outputs[layer] layer_provider = 'ogr' writer = QgsVectorFileWriter(layer_source, encoding, geojson_layer.pendingFields(), osm_geometries[layer], geojson_layer.crs(), provider) for f in geojson_layer.getFeatures(): writer.addFeature(f) del writer # Loading the final vector file new_layer = QgsVectorLayer(layer_source, final_layer_name, layer_provider) # Try to set styling if defined if config_outputs and config_outputs[layer]['style']: new_layer.loadNamedStyle(config_outputs[layer]['style']) else: # Loading default styles if layer == "multilinestrings" or layer == "lines": if "colour" in item['tags']: new_layer.loadNamedStyle( join(dirname(dirname(abspath(__file__))), "styles", layer + "_colour.qml")) # Add action about OpenStreetMap actions = new_layer.actions() actions.addAction( QgsAction.OpenUrl, "OpenStreetMap Browser", 'http://www.openstreetmap.org/browse/' '[% "osm_type" %]/[% "osm_id" %]', False) actions.addAction( QgsAction.GenericPython, 'JOSM', 'from QuickOSM.CoreQuickOSM.Actions import Actions;' 'Actions.run("josm","[% "full_id" %]")', False) actions.addAction( QgsAction.OpenUrl, "User default editor", 'http://www.openstreetmap.org/edit?' '[% "osm_type" %]=[% "osm_id" %]', False) for link in ['url', 'website', 'wikipedia', 'ref:UAI']: if link in item['tags']: link = link.replace(":", "_") actions.addAction( QgsAction.GenericPython, link, 'from QuickOSM.core.actions import Actions;' 'Actions.run("' + link + '","[% "' + link + '" %]")', False) if 'network' in item['tags'] and 'ref' in item['tags']: actions.addAction( QgsAction.GenericPython, "Sketchline", 'from QuickOSM.core.actions import Actions;' 'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")', False) # Add index if possible if output_format == "shape" or output_format == "spatialite": new_layer.dataProvider().createSpatialIndex() QgsMapLayerRegistry.instance().addMapLayer(new_layer) num_layers += 1 return num_layers