dlg_export_vector.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. """
  2. /***************************************************************************
  3. Name : DB Manager
  4. Description : Database manager plugin for QGIS
  5. Date : Oct 13, 2011
  6. copyright : (C) 2011 by Giuseppe Sucameli
  7. email : brush.tyler@gmail.com
  8. The content of this file is based on
  9. - PG_Manager by Martin Dobias (GPLv2 license)
  10. ***************************************************************************/
  11. /***************************************************************************
  12. * *
  13. * This program is free software; you can redistribute it and/or modify *
  14. * it under the terms of the GNU General Public License as published by *
  15. * the Free Software Foundation; either version 2 of the License, or *
  16. * (at your option) any later version. *
  17. * *
  18. ***************************************************************************/
  19. """
  20. from qgis.PyQt.QtCore import Qt, QFileInfo
  21. from qgis.PyQt.QtWidgets import QDialog, QFileDialog, QMessageBox, QApplication
  22. from qgis.PyQt.QtGui import QCursor
  23. from qgis.core import (QgsVectorFileWriter,
  24. QgsVectorDataProvider,
  25. QgsCoordinateReferenceSystem,
  26. QgsVectorLayerExporter,
  27. QgsSettings)
  28. from qgis.utils import OverrideCursor
  29. from .ui.ui_DlgExportVector import Ui_DbManagerDlgExportVector as Ui_Dialog
  30. class DlgExportVector(QDialog, Ui_Dialog):
  31. def __init__(self, inLayer, inDb, parent=None):
  32. QDialog.__init__(self, parent)
  33. self.inLayer = inLayer
  34. self.db = inDb
  35. self.setupUi(self)
  36. vectorFilterName = "lastVectorFileFilter" # "lastRasterFileFilter"
  37. self.lastUsedVectorFilterSettingsKey = "/UI/{}".format(vectorFilterName)
  38. self.lastUsedVectorDirSettingsKey = "/UI/{}Dir".format(vectorFilterName)
  39. # update UI
  40. self.setupWorkingMode()
  41. self.populateFileFilters()
  42. self.populateEncodings()
  43. def setupWorkingMode(self):
  44. # set default values
  45. inCrs = self.inLayer.crs()
  46. srid = inCrs.postgisSrid() if inCrs.isValid() else 4236
  47. self.editSourceSrid.setText("%s" % srid)
  48. self.editTargetSrid.setText("%s" % srid)
  49. self.btnChooseOutputFile.clicked.connect(self.chooseOutputFile)
  50. self.checkSupports()
  51. def checkSupports(self):
  52. """ update options available for the current input layer """
  53. allowSpatial = self.db.connector.hasSpatialSupport()
  54. hasGeomType = self.inLayer and self.inLayer.isSpatial()
  55. self.chkSourceSrid.setEnabled(allowSpatial and hasGeomType)
  56. self.chkTargetSrid.setEnabled(allowSpatial and hasGeomType)
  57. # self.chkSpatialIndex.setEnabled(allowSpatial and hasGeomType)
  58. def chooseOutputFile(self):
  59. # get last used dir
  60. settings = QgsSettings()
  61. lastUsedDir = settings.value(self.lastUsedVectorDirSettingsKey, ".")
  62. # get selected filter
  63. selected_driver = self.cboFileFormat.currentData()
  64. selected_filter = QgsVectorFileWriter.filterForDriver(selected_driver)
  65. # ask for a filename
  66. filename, filter = QFileDialog.getSaveFileName(self, self.tr("Choose where to save the file"), lastUsedDir,
  67. selected_filter)
  68. if filename == "":
  69. return
  70. ext = selected_filter[selected_filter.find('.'):]
  71. ext = ext[:ext.find(' ')]
  72. if not filename.lower().endswith(ext):
  73. filename += ext
  74. # store the last used dir
  75. settings.setValue(self.lastUsedVectorDirSettingsKey, QFileInfo(filename).filePath())
  76. self.editOutputFile.setText(filename)
  77. def populateEncodings(self):
  78. # populate the combo with supported encodings
  79. self.cboEncoding.addItems(QgsVectorDataProvider.availableEncodings())
  80. # set the last used encoding
  81. enc = self.inLayer.dataProvider().encoding()
  82. idx = self.cboEncoding.findText(enc)
  83. if idx < 0:
  84. self.cboEncoding.insertItem(0, enc)
  85. idx = 0
  86. self.cboEncoding.setCurrentIndex(idx)
  87. def populateFileFilters(self):
  88. # populate the combo with supported vector file formats
  89. for driver in QgsVectorFileWriter.ogrDriverList():
  90. self.cboFileFormat.addItem(driver.longName, driver.driverName)
  91. # set the last used filter
  92. settings = QgsSettings()
  93. filt = settings.value(self.lastUsedVectorFilterSettingsKey, "GPKG")
  94. idx = self.cboFileFormat.findText(filt)
  95. if idx < 0:
  96. idx = 0
  97. self.cboFileFormat.setCurrentIndex(idx)
  98. def accept(self):
  99. # sanity checks
  100. if self.editOutputFile.text() == "":
  101. QMessageBox.information(self, self.tr("Export to file"), self.tr("Output file name is required"))
  102. return
  103. if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
  104. try:
  105. sourceSrid = int(self.editSourceSrid.text())
  106. except ValueError:
  107. QMessageBox.information(self, self.tr("Export to file"),
  108. self.tr("Invalid source srid: must be an integer"))
  109. return
  110. if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
  111. try:
  112. targetSrid = int(self.editTargetSrid.text())
  113. except ValueError:
  114. QMessageBox.information(self, self.tr("Export to file"),
  115. self.tr("Invalid target srid: must be an integer"))
  116. return
  117. with OverrideCursor(Qt.WaitCursor):
  118. # store current input layer crs, so I can restore it later
  119. prevInCrs = self.inLayer.crs()
  120. try:
  121. uri = self.editOutputFile.text()
  122. providerName = "ogr"
  123. options = {}
  124. # set the OGR driver will be used
  125. driverName = self.cboFileFormat.currentData()
  126. options['driverName'] = driverName
  127. # set the output file encoding
  128. if self.chkEncoding.isEnabled() and self.chkEncoding.isChecked():
  129. enc = self.cboEncoding.currentText()
  130. options['fileEncoding'] = enc
  131. if self.chkDropTable.isChecked():
  132. options['overwrite'] = True
  133. outCrs = QgsCoordinateReferenceSystem()
  134. if self.chkTargetSrid.isEnabled() and self.chkTargetSrid.isChecked():
  135. targetSrid = int(self.editTargetSrid.text())
  136. outCrs = QgsCoordinateReferenceSystem(targetSrid)
  137. # update input layer crs
  138. if self.chkSourceSrid.isEnabled() and self.chkSourceSrid.isChecked():
  139. sourceSrid = int(self.editSourceSrid.text())
  140. inCrs = QgsCoordinateReferenceSystem(sourceSrid)
  141. self.inLayer.setCrs(inCrs)
  142. # do the export!
  143. ret, errMsg = QgsVectorLayerExporter.exportLayer(self.inLayer, uri, providerName, outCrs,
  144. False, options)
  145. except Exception as e:
  146. ret = -1
  147. errMsg = str(e)
  148. finally:
  149. # restore input layer crs and encoding
  150. self.inLayer.setCrs(prevInCrs)
  151. if ret != 0:
  152. QMessageBox.warning(self, self.tr("Export to file"), self.tr("Error {0}\n{1}").format(ret, errMsg))
  153. return
  154. # create spatial index
  155. # if self.chkSpatialIndex.isEnabled() and self.chkSpatialIndex.isChecked():
  156. # self.db.connector.createSpatialIndex( (schema, table), geom )
  157. QMessageBox.information(self, self.tr("Export to file"), self.tr("Export finished."))
  158. return QDialog.accept(self)