class LoadByCategory(QtGui.QDialog, load_by_category_dialog.Ui_LoadByCategory): def __init__(self, parent=None): """Constructor.""" super(LoadByCategory, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.categories = [] self.selectedClasses = [] self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] #Sql factory generator self.isSpatialite = True self.setupUi(self) self.tabWidget.setCurrentIndex(0) self.factory = SqlGeneratorFactory() self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.utils = Utils() self.parentTreeNode = None self.comboBoxPostgis.setCurrentIndex(0) self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0,0,0,0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0,0,1,1) #Objects Connections QtCore.QObject.connect(self.pushButtonOpenFile, QtCore.SIGNAL(("clicked()")), self.loadDatabase) QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel) QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected) QtCore.QObject.connect(self.tabWidget,QtCore.SIGNAL(("currentChanged(int)")), self.restoreInitialState) QtCore.QObject.connect(self.pushButtonSelectAll, QtCore.SIGNAL(("clicked()")), self.selectAll) QtCore.QObject.connect(self.pushButtonDeselectAll, QtCore.SIGNAL(("clicked()")), self.deselectAll) QtCore.QObject.connect(self.pushButtonSelectOne, QtCore.SIGNAL(("clicked()")), self.selectOne) QtCore.QObject.connect(self.pushButtonDeselectOne, QtCore.SIGNAL(("clicked()")), self.deselectOne) QtCore.QObject.connect(self.checkBoxAll, QtCore.SIGNAL(("stateChanged(int)")), self.setAllGroup) self.db = None #populating the postgis combobox self.populatePostGISConnectionsCombo() def __del__(self): self.closeDatabase() def closeDatabase(self): if self.db: self.db.close() self.db = None def restoreInitialState(self): self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.categories = [] self.selectedClasses = [] self.spatialiteFileEdit.setText(self.filename) self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() self.point = [] self.line = [] self.polygon = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] self.parentTreeNode = None #Setting the database type if self.tabWidget.currentIndex() == 0: self.isSpatialite = True else: self.isSpatialite = False #getting the sql generator according to the database type self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.comboBoxPostgis.setCurrentIndex(0) self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) self.checkBoxAll.setCheckState(0) def updateBDField(self): if self.dbLoaded == True: self.spatialiteFileEdit.setText(self.filename) else: self.filename = "" self.spatialiteFileEdit.setText(self.filename) def getDatabaseVersion(self): self.dbVersion = self.utils.getDatabaseVersion(self.db) self.qmlPath = self.utils.getQmlDir(self.db) def listCategoriesFromDatabase(self): self.listWidgetCategoryFrom.clear() self.listWidgetCategoryTo.clear() sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) self.getDatabaseVersion() while query.next(): if self.isSpatialite: tableName = query.value(0) layerName = tableName split = tableName.split('_') if len(split) < 2: continue if self.dbVersion == '3.0' or self.dbVersion == '2.1.3': schema = split[0] category = split[1] categoryName = schema+'.'+category else: categoryName = split[0] #done this way to have back compatibility with spatialites already in production else: tableSchema = query.value(0) tableName = query.value(1) split = tableName.split('_') category = split[0] categoryName = tableSchema+'.'+category layerName = tableSchema+'.'+tableName if layerName.split("_")[-1] == "p": self.point.append(layerName) if layerName.split("_")[-1] == "l": self.line.append(layerName) if layerName.split("_")[-1] == "a": self.polygon.append(layerName) if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" \ or tableName.split("_")[-1] == "a": self.insertIntoListView(categoryName) self.listWidgetCategoryFrom.sortItems() self.setCRS() def insertIntoListView(self, item_name): found = self.listWidgetCategoryFrom.findItems(item_name, Qt.MatchExactly) if len(found) == 0: item = QtGui.QListWidgetItem(item_name) self.listWidgetCategoryFrom.addItem(item) def selectAll(self): tam = self.listWidgetCategoryFrom.__len__() for i in range(tam+1,1,-1): item = self.listWidgetCategoryFrom.takeItem(i-2) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectAll(self): tam = self.listWidgetCategoryTo.__len__() for i in range(tam+1,1,-1): item = self.listWidgetCategoryTo.takeItem(i-2) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def selectOne(self): listedItems = self.listWidgetCategoryFrom.selectedItems() for i in listedItems: item = self.listWidgetCategoryFrom.takeItem(self.listWidgetCategoryFrom.row(i)) self.listWidgetCategoryTo.addItem(item) self.listWidgetCategoryTo.sortItems() def deselectOne(self): listedItems = self.listWidgetCategoryTo.selectedItems() for i in listedItems: item = self.listWidgetCategoryTo.takeItem(self.listWidgetCategoryTo.row(i)) self.listWidgetCategoryFrom.addItem(item) self.listWidgetCategoryFrom.sortItems() def setAllGroup(self): if self.checkBoxAll.isChecked(): self.checkBoxPoint.setCheckState(2) self.checkBoxLine.setCheckState(2) self.checkBoxPolygon.setCheckState(2) else: self.checkBoxPoint.setCheckState(0) self.checkBoxLine.setCheckState(0) self.checkBoxPolygon.setCheckState(0) def setCRS(self): try: self.epsg = self.utils.findEPSG(self.db) if self.epsg == -1: self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): if self.comboBoxPostgis.currentIndex() > 0: self.loadDatabase() def loadDatabase(self): self.closeDatabase() if self.isSpatialite: (self.filename, self.db) = self.utils.getSpatialiteDatabase() if self.filename: self.spatialiteFileEdit.setText(self.filename) else: self.db = self.utils.getPostGISDatabase(self.comboBoxPostgis.currentText()) try: if not self.db.open(): QgsMessageLog.logMessage(self.db.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL) else: self.dbLoaded = True self.listCategoriesFromDatabase() except: pass def populatePostGISConnectionsCombo(self): self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem("Select Database") self.comboBoxPostgis.addItems(self.utils.getPostGISConnections()) def cancel(self): self.restoreInitialState() self.close() def getSelectedItems(self): lista = self.classesListWidget.selectedItems() self.selectedClasses = [] tam = len(lista) for i in range(tam): self.selectedClasses.append(lista[i].text()) self.selectedClasses.sort() def okSelected(self): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.checkBoxOnlyWithElements.isChecked(): self.setLayersWithElements() ponto = self.pointWithElement linha = self.lineWithElement area = self.polygonWithElement else: ponto = self.point linha = self.line area = self.polygon if self.db and self.crs and len(self.listWidgetCategoryTo)>0: categoriasSelecionadas = [] for i in range(self.listWidgetCategoryTo.__len__()): categoriasSelecionadas.append(self.listWidgetCategoryTo.item(i).text()) try: if self.checkBoxPoint.isChecked(): self.loadLayers('p',categoriasSelecionadas,ponto) if self.checkBoxLine.isChecked(): self.loadLayers('l',categoriasSelecionadas,linha) if self.checkBoxPolygon.isChecked(): self.loadLayers('a',categoriasSelecionadas,area) if self.checkBoxPoint.isChecked()== False and self.checkBoxLine.isChecked() == False and self.checkBoxPolygon.isChecked() == False: self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one type of layer!"), level=QgsMessageBar.WARNING) else: self.restoreInitialState() self.close() except: qgis.utils.iface.messageBar().pushMessage(self.tr("CRITICAL!"), self.tr("Problem loading the categories!"), level=QgsMessageBar.CRITICAL) pass else: if self.db and not self.crs: self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL) if not self.db and not self.crs: self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Database not loaded properly!"), level=QgsMessageBar.CRITICAL) self.bar.pushMessage(self.tr("CRITICAL!"), self.tr("Could not determine the coordinate reference system!"), level=QgsMessageBar.CRITICAL) if len(self.listWidgetCategoryTo)==0: self.bar.pushMessage(self.tr("WARNING!"), self.tr("Please, select at least one category!"), level=QgsMessageBar.WARNING) categoriasSelecionadas = [] self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] QApplication.restoreOverrideCursor() except: QApplication.restoreOverrideCursor() def loadLayers(self, type, categories, layer_names): if self.isSpatialite: self.loadSpatialiteLayers(type, categories, layer_names) else: self.loadPostGISLayers(type, categories, layer_names) def setLayersWithElements(self): self.pointWithElement = [] self.lineWithElement = [] self.polygonWithElement = [] pontoAux = self.countElements(self.point) linhaAux = self.countElements(self.line) areaAux = self.countElements(self.polygon) for i in pontoAux: if i[1] > 0: self.pointWithElement.append(i[0]) for i in linhaAux: if i[1] > 0: self.lineWithElement.append(i[0]) for i in areaAux: if i[1] > 0: self.polygonWithElement.append(i[0]) def countElements(self, layers): listaQuantidades = [] for layer in layers: sql = self.gen.getElementCountFromLayer(layer) query = QSqlQuery(sql,self.db) query.next() number = query.value(0) if not query.exec_(sql): QgsMessageLog.logMessage(self.tr("Problem counting elements: ")+query.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL) listaQuantidades.append([layer, number]) return listaQuantidades def loadPostGISLayers(self, type, categories, layer_names): (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText()) uri = QgsDataSourceURI() uri.setConnection(str(host),str(port), str(database), str(user), str(password)) geom_column = 'geom' if self.parentTreeNode is None: self.parentTreeNode = qgis.utils.iface.legendInterface (). addGroup (database, -1) if type == 'p': idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Ponto", True,self.parentTreeNode) for categoria in categories: self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'l': idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Linha", True,self.parentTreeNode) for categoria in categories: self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'a': idGrupo = qgis.utils.iface.legendInterface (). addGroup ("Area", True,self.parentTreeNode) for categoria in categories: self.preparePostGISToLoad(uri, categoria, layer_names, idGrupo, geom_column) def preparePostGISToLoad(self, uri, categoria, layer_names, idGrupo, geom_column): idSubgrupo = qgis.utils.iface.legendInterface().addGroup(categoria, True, idGrupo) layer_names.sort(reverse=True) for layer_name in layer_names: split = layer_name.split('_') category = split[0] schema = category.split('.')[0] name = layer_name.replace(schema+'.', '') if category == categoria: sql = self.gen.loadLayerFromDatabase(layer_name) uri.setDataSource(schema, name, geom_column, sql, 'id') uri.disableSelectAtId(True) self.loadEDGVLayer(uri, name, 'postgres', idSubgrupo) def prepareSpatialiteToLoad(self, uri, categoria, layer_names, idGrupo, geom_column): idSubgrupo = qgis.utils.iface.legendInterface().addGroup(categoria, True, idGrupo) layer_names.sort(reverse=True) for layer_name in layer_names: split = layer_name.split('_') if self.dbVersion == '3.0' or self.dbVersion == '2.1.3': category = split[0]+'.'+split[1] else: category = split[0] if category == categoria: uri.setDataSource('', layer_name, geom_column) self.loadEDGVLayer(uri, layer_name, 'spatialite', idSubgrupo) def loadSpatialiteLayers(self, type, categories, layer_names): uri = QgsDataSourceURI() uri.setDatabase(self.filename) geom_column = 'GEOMETRY' if self.parentTreeNode is None: self.parentTreeNode = qgis.utils.iface.legendInterface(). addGroup(self.filename.split('.sqlite')[0].split('/')[-1], -1) if type == 'p': idGrupo = qgis.utils.iface.legendInterface(). addGroup("Ponto", True, self.parentTreeNode) for categoria in categories: self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'l': idGrupo = qgis.utils.iface.legendInterface(). addGroup("Linha", True, self.parentTreeNode) for categoria in categories: self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column) if type == 'a': idGrupo = qgis.utils.iface.legendInterface(). addGroup("Area", True, self.parentTreeNode) for categoria in categories: self.prepareSpatialiteToLoad(uri, categoria, layer_names, idGrupo, geom_column) def loadEDGVLayer(self, uri, layer_name, provider, idSubgrupo): vlayer = QgsVectorLayer(uri.uri(), layer_name, provider) vlayer.setCrs(self.crs) QgsMapLayerRegistry.instance().addMapLayer(vlayer) #added due to api changes if self.isSpatialite and (self.dbVersion == '3.0' or self.dbVersion == '2.1.3'): lyr = '_'.join(layer_name.replace('\r', '').split('_')[1::]) else: lyr = layer_name.replace('\r','') vlayerQml = os.path.join(self.qmlPath, lyr+'.qml') vlayer.loadNamedStyle(vlayerQml, False) QgsMapLayerRegistry.instance().addMapLayer(vlayer) qgis.utils.iface.legendInterface().moveLayer(vlayer, idSubgrupo) if not vlayer.isValid(): QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
class CreateInomDialog(QtGui.QDialog, FORM_CLASS): def __init__(self, iface, parent=None): """Constructor.""" super(CreateInomDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) self.iface = iface #Sql factory generator self.isSpatialite = True self.tabWidget.setCurrentIndex(0) self.factory = SqlGeneratorFactory() self.gen = self.factory.createSqlGenerator(self.isSpatialite) QObject.connect(self.tabWidget, SIGNAL(("currentChanged(int)")), self.restoreInitialState) QObject.connect(self.pushButtonOpenFile, SIGNAL(("clicked()")), self.loadDatabase) self.restoreInitialState() self.db = None #populating the postgis combobox self.populatePostGISConnectionsCombo() self.map_index = UtmGrid() self.disableAll() self.setValidCharacters() self.setMask() def __del__(self): self.closeDatabase() @pyqtSlot() def on_okButton_clicked(self): if not self.dbLoaded: QMessageBox.warning(self, self.tr("Warning!"), self.tr('Please, select a database first.')) return if not self.validateMI(): QMessageBox.warning(self, self.tr("Warning!"), self.tr('Map name index not valid!')) return frame = self.map_index.getQgsPolygonFrame(self.inomLineEdit.text()) reprojected = self.reprojectFrame(frame) self.insertFrameIntoLayer(reprojected) self.done(1) def insertFrameIntoLayer(self,reprojected): self.utils = Utils() self.dbVersion = self.utils.getDatabaseVersion(self.db) self.qmlPath = self.utils.getQmlDir(self.db) layer = self.getFrameLayer() if not layer: return layer.startEditing() feat = QgsFeature() feat.setFields(layer.dataProvider().fields()) feat.setGeometry(reprojected) feat.setAttribute(2, self.inomLineEdit.text()) feat.setAttribute(3, self.scaleCombo.currentText()) layer.addFeatures([feat], makeSelected=True) layer.commitChanges() bbox = reprojected.boundingBox() for feature in layer.getFeatures(): bbox.combineExtentWith(feature.geometry().boundingBox()) bbox = self.iface.mapCanvas().mapSettings().layerToMapCoordinates(layer, bbox) self.iface.mapCanvas().setExtent(bbox) self.iface.mapCanvas().refresh() def getFrameLayer(self): for lyr in self.iface.legendInterface().layers(): if lyr.name() == 'public_aux_moldura_a' or lyr.name() == 'aux_moldura_a': dbname = self.getDBNameFromLayer(lyr) if self.isSpatialite and dbname == self.filename: return lyr if not self.isSpatialite: (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText()) if dbname == database: return lyr if self.isSpatialite: return self.loadSpatialiteFrame() else: return self.loadPostGISFrame() return None def getDBNameFromLayer(self, lyr): dbname = None splitUri = lyr.dataProvider().dataSourceUri().split(' ') if len(splitUri) > 0: dbsplit = splitUri[0].split('=') if len(dbsplit) > 1 and dbsplit[0] == 'dbname': dbnameInString = dbsplit[1] dbnameSplit = dbnameInString.split('\'') if len(dbnameSplit) > 1: dbname = dbnameSplit[1] return dbname def loadPostGISFrame(self): self.selectedClasses = ['public.aux_moldura_a'] (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText()) uri = QgsDataSourceURI() uri.setConnection(str(host),str(port), str(database), str(user), str(password)) if len(self.selectedClasses)>0: try: geom_column = 'geom' for layer in self.selectedClasses: split = layer.split('.') schema = split[0] layerName = split[1] sql = self.gen.loadLayerFromDatabase(layer) uri.setDataSource(schema, layerName, geom_column, sql,'id') uri.disableSelectAtId(True) return self.loadEDGVLayer(uri, layerName, 'postgres') except: self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the selected frame!"), level=QgsMessageBar.CRITICAL) else: self.bar.pushMessage(self.tr("Warning!"), self.tr("Please, select at least one class!"), level=QgsMessageBar.WARNING) def loadSpatialiteFrame(self): self.selectedClasses = ['public_aux_moldura_a'] uri = QgsDataSourceURI() uri.setDatabase(self.filename) schema = '' geom_column = 'GEOMETRY' if len(self.selectedClasses)>0: for layer_name in self.selectedClasses: uri.setDataSource(schema, layer_name, geom_column) return self.loadEDGVLayer(uri, layer_name, 'spatialite') def loadEDGVLayer(self, uri, layer_name, provider): vlayer = QgsVectorLayer(uri.uri(), layer_name, provider) vlayer.setCrs(self.crs) QgsMapLayerRegistry.instance().addMapLayer(vlayer) #added due to api changes if self.isSpatialite and (self.dbVersion == '3.0' or self.dbVersion == '2.1.3'): lyr = '_'.join(layer_name.replace('\r','').split('_')[1::]) else: lyr = layer_name.replace('\r','') vlayerQml = os.path.join(self.qmlPath, lyr+'.qml') vlayer.loadNamedStyle(vlayerQml,False) QgsMapLayerRegistry.instance().addMapLayer(vlayer) if not vlayer.isValid(): QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL) return None return vlayer @pyqtSlot() def on_cancelButton_clicked(self): self.done(0) @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): if self.comboBoxPostgis.currentIndex() > 0: self.loadDatabase() @pyqtSlot(str) def on_miLineEdit_textChanged(self,s): if (s!=''): self.inomen=self.map_index.getINomenFromMI(str(s)) self.inomLineEdit.setText(self.inomen) @pyqtSlot(str) def on_mirLineEdit_textChanged(self,s): if (s!=''): self.inomen=self.map_index.getINomenFromMIR(str(s)) self.inomLineEdit.setText(self.inomen) def reprojectFrame(self, poly): crsSrc = QgsCoordinateReferenceSystem(self.crs.geographicCRSAuthId()) coordinateTransformer = QgsCoordinateTransform(crsSrc, self.crs) polyline = poly.asMultiPolygon()[0][0] newPolyline = [] for point in polyline: newPolyline.append(coordinateTransformer.transform(point)) qgsPolygon = QgsGeometry.fromMultiPolygon([[newPolyline]]) return qgsPolygon def closeDatabase(self): if self.db: self.db.close() self.db = None def restoreInitialState(self): self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) if self.tabWidget.currentIndex() == 0: self.isSpatialite = True else: self.isSpatialite = False #getting the sql generator according to the database type self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.comboBoxPostgis.setCurrentIndex(0) def setCRS(self): try: self.epsg = self.findEPSG() print self.epsg if self.epsg == -1: self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass def loadDatabase(self): self.closeDatabase() if self.isSpatialite: fd = QtGui.QFileDialog() self.filename = fd.getOpenFileName(filter='*.sqlite') if self.filename: self.spatialiteFileEdit.setText(self.filename) self.db = QSqlDatabase("QSQLITE") self.db.setDatabaseName(self.filename) else: self.db = QSqlDatabase("QPSQL") (database, host, port, user, password) = self.getPostGISConnectionParameters(self.comboBoxPostgis.currentText()) self.db.setDatabaseName(database) self.db.setHostName(host) self.db.setPort(int(port)) self.db.setUserName(user) self.db.setPassword(password) try: if not self.db.open(): print self.db.lastError().text() else: self.dbLoaded = True self.setCRS() except: pass def getPostGISConnectionParameters(self, name): settings = QSettings() settings.beginGroup('PostgreSQL/connections/'+name) database = settings.value('database') host = settings.value('host') port = settings.value('port') user = settings.value('username') password = settings.value('password') settings.endGroup() return (database, host, port, user, password) def getPostGISConnections(self): settings = QSettings() settings.beginGroup('PostgreSQL/connections') currentConnections = settings.childGroups() settings.endGroup() return currentConnections def populatePostGISConnectionsCombo(self): self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem(self.tr("Select Database")) self.comboBoxPostgis.addItems(self.getPostGISConnections()) def findEPSG(self): sql = self.gen.getSrid() query = QSqlQuery(sql, self.db) srids = [] while query.next(): srids.append(query.value(0)) return srids[0] def setValidCharacters(self): self.chars = [] chars = 'NS' self.chars.append(chars) chars = 'ABCDEFGHIJKLMNOPQRSTUVZ' self.chars.append(chars) chars = ['01','02','03','04','05','06','07','08','09','10', '11','12','13','14','15','16','17','18','19','20', '21','22','23','24','25','26','27','28','29','30', '31','32','33','34','35','36','37','38','39','40', '41','42','43','44','45','46','47','48','49','50', '51','52','53','54','55','56','57','58','59','60'] self.chars.append(chars) chars = 'VXYZ' self.chars.append(chars) chars = 'ABCD' self.chars.append(chars) chars = ['I','II','III','IV','V','VI'] self.chars.append(chars) chars = '1234' self.chars.append(chars) chars = ['NO','NE','SO','SE'] self.chars.append(chars) chars = 'ABCDEF' self.chars.append(chars) chars = ['I','II','III','IV'] self.chars.append(chars) chars = '123456' self.chars.append(chars) chars = 'ABCD' self.chars.append(chars) def setMask(self): if self.scaleCombo.currentText() == '1000k': self.inomLineEdit.setInputMask('NN-NN') elif self.scaleCombo.currentText() == '500k': self.inomLineEdit.setInputMask('NN-NN-N') elif self.scaleCombo.currentText() == '250k': self.inomLineEdit.setInputMask('NN-NN-N-N') elif self.scaleCombo.currentText() == '100k': self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn') elif self.scaleCombo.currentText() == '50k': self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0') elif self.scaleCombo.currentText() == '25k': self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0-NN') elif self.scaleCombo.currentText() == '10k': self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0-NN-N') elif self.scaleCombo.currentText() == '5k': self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0-NN-N-Nnn') elif self.scaleCombo.currentText() == '2k': self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0-NN-N-Nnn-0') elif self.scaleCombo.currentText() == '1k': self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0-NN-N-Nnn-0-N') def validateMI(self): mi = self.inomLineEdit.text() split = mi.split('-') for i in range(len(split)): word = str(split[i]) if len(word) == 0: return False if i == 0: if word[0] not in self.chars[0]: print word return False if word[1] not in self.chars[1]: print word return False elif i == 1: if word not in self.chars[2]: print word return False elif i == 2: if word not in self.chars[3]: print word return False elif i == 3: if word not in self.chars[4]: print word return False elif i == 4: if word not in self.chars[5]: print word return False elif i == 5: if word not in self.chars[6]: print word return False elif i == 6: if word not in self.chars[7]: print word return False elif i == 7: if word not in self.chars[8]: print word return False elif i == 8: if word not in self.chars[9]: print word return False elif i == 9: if word not in self.chars[10]: print word return False elif i == 10: if word not in self.chars[11]: print word return False return True def disableAll(self): self.mirLineEdit.setEnabled(False) self.miLineEdit.setEnabled(False) self.inomLineEdit.setEnabled(False) @pyqtSlot(int) def on_scaleCombo_currentIndexChanged(self): self.setMask() @pyqtSlot(bool) def on_mirRadioButton_toggled(self, toggled): if toggled: self.mirLineEdit.setEnabled(True) else: self.mirLineEdit.setEnabled(False) @pyqtSlot(bool) def on_miRadioButton_toggled(self, toggled): if toggled: self.miLineEdit.setEnabled(True) else: self.miLineEdit.setEnabled(False) @pyqtSlot(bool) def on_inomRadioButton_toggled(self, toggled): if toggled: self.inomLineEdit.setEnabled(True) else: self.inomLineEdit.setEnabled(False)
class LoadByClass(QtGui.QDialog, load_by_class_base.Ui_LoadByClass): def __init__(self, parent=None): """Constructor.""" super(LoadByClass, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.selectedClasses = [] #Sql factory generator self.isSpatialite = True self.setupUi(self) self.tabWidget.setCurrentIndex(0) self.factory = SqlGeneratorFactory() self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.utils = Utils() self.bar = QgsMessageBar() self.setLayout(QtGui.QGridLayout(self)) self.layout().setContentsMargins(0,0,0,0) self.layout().setAlignment(QtCore.Qt.AlignTop) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) self.bar.setSizePolicy(sizePolicy) self.layout().addWidget(self.bar, 0,0,1,1) #Objects Connections QtCore.QObject.connect(self.pushButtonOpenFile, QtCore.SIGNAL(("clicked()")), self.loadDatabase) QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel) QtCore.QObject.connect(self.selectAllCheck, QtCore.SIGNAL(("stateChanged(int)")), self.selectAll) QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected) QtCore.QObject.connect(self.tabWidget,QtCore.SIGNAL(("currentChanged(int)")), self.restoreInitialState) self.db = None #populating the postgis combobox self.populatePostGISConnectionsCombo() def __del__(self): self.closeDatabase() def closeDatabase(self): if self.db: self.db.close() self.db = None def restoreInitialState(self): self.filename = "" self.dbLoaded = False self.epsg = 0 self.crs = None self.selectedClasses = [] self.spatialiteFileEdit.setText(self.filename) self.postGISCrsEdit.setText('') self.postGISCrsEdit.setReadOnly(True) self.spatialiteCrsEdit.setText('') self.spatialiteCrsEdit.setReadOnly(True) tam = self.classesListWidget.__len__() for i in range(tam+1,1,-1): item = self.classesListWidget.takeItem(i-2) self.selectAllCheck.setCheckState(0) #Setting the database type if self.tabWidget.currentIndex() == 0: self.isSpatialite = True else: self.isSpatialite = False #getting the sql generator according to the database type self.gen = self.factory.createSqlGenerator(self.isSpatialite) self.comboBoxPostgis.setCurrentIndex(0) def updateBDField(self): if self.dbLoaded == True: self.spatialiteFileEdit.setText(self.filename) else: self.filename = "" self.spatialiteFileEdit.setText(self.filename) def getDatabaseVersion(self): self.dbVersion = self.utils.getDatabaseVersion(self.db) self.qmlPath = self.utils.getQmlDir(self.db) def listClassesFromDatabase(self): self.classesListWidget.clear() self.getDatabaseVersion() sql = self.gen.getTablesFromDatabase() query = QSqlQuery(sql, self.db) while query.next(): if self.isSpatialite: tableName = query.value(0) layerName = tableName else: tableSchema = query.value(0) tableName = query.value(1) layerName = tableSchema+'.'+tableName if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" \ or tableName.split("_")[-1] == "a": item = QtGui.QListWidgetItem(layerName) self.classesListWidget.addItem(item) self.classesListWidget.sortItems() self.setCRS() def setCRS(self): try: self.epsg = self.utils.findEPSG(self.db) if self.epsg == -1: self.bar.pushMessage("", self.tr("Coordinate Reference System not set or invalid!"), level=QgsMessageBar.WARNING) else: self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId) if self.isSpatialite: self.spatialiteCrsEdit.setText(self.crs.description()) self.spatialiteCrsEdit.setReadOnly(True) else: self.postGISCrsEdit.setText(self.crs.description()) self.postGISCrsEdit.setReadOnly(True) except: pass @pyqtSlot(int) def on_comboBoxPostgis_currentIndexChanged(self): if self.comboBoxPostgis.currentIndex() > 0: self.loadDatabase() def loadDatabase(self): self.closeDatabase() if self.isSpatialite: (self.filename, self.db) = self.utils.getSpatialiteDatabase() if self.filename: self.spatialiteFileEdit.setText(self.filename) else: self.db = self.utils.getPostGISDatabase(self.comboBoxPostgis.currentText()) try: if not self.db.open(): QgsMessageLog.logMessage(self.db.lastError().text(), "DSG Tools Plugin", QgsMessageLog.CRITICAL) else: self.dbLoaded = True self.listClassesFromDatabase() except: pass def populatePostGISConnectionsCombo(self): self.comboBoxPostgis.clear() self.comboBoxPostgis.addItem(self.tr("Select Database")) self.comboBoxPostgis.addItems(self.utils.getPostGISConnections()) def cancel(self): self.restoreInitialState() self.close() def selectAll(self): if self.selectAllCheck.isChecked(): tam = self.classesListWidget.__len__() for i in range(tam+1): item = self.classesListWidget.item(i-1) self.classesListWidget.setItemSelected(item,2) else: tam = self.classesListWidget.__len__() for i in range(tam+1): item = self.classesListWidget.item(i-1) self.classesListWidget.setItemSelected(item,0) def getSelectedItems(self): lista = self.classesListWidget.selectedItems() self.selectedClasses = [] tam = len(lista) for i in range(tam): self.selectedClasses.append(lista[i].text()) self.selectedClasses.sort() def okSelected(self): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if self.isSpatialite: self.loadSpatialiteLayers() else: self.loadPostGISLayers() QApplication.restoreOverrideCursor() except: QApplication.restoreOverrideCursor() def loadPostGISLayers(self): self.getSelectedItems() (database, host, port, user, password) = self.utils.getPostGISConnectionParameters(self.comboBoxPostgis.currentText()) uri = QgsDataSourceURI() uri.setConnection(str(host),str(port), str(database), str(user), str(password)) if len(self.selectedClasses)>0: try: geom_column = 'geom' for layer in self.selectedClasses: split = layer.split('.') schema = split[0] layerName = split[1] sql = self.gen.loadLayerFromDatabase(layer) uri.setDataSource(schema, layerName, geom_column, sql,'id') uri.disableSelectAtId(True) self.loadEDGVLayer(uri, layerName, 'postgres') self.restoreInitialState() self.close() except: self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the selected classes!"), level=QgsMessageBar.CRITICAL) else: self.bar.pushMessage(self.tr("Warning!"), self.tr("Please, select at least one class!"), level=QgsMessageBar.WARNING) def loadSpatialiteLayers(self): self.getSelectedItems() uri = QgsDataSourceURI() uri.setDatabase(self.filename) schema = '' geom_column = 'GEOMETRY' if len(self.selectedClasses)>0: try: for layer_name in self.selectedClasses: uri.setDataSource(schema, layer_name, geom_column) self.loadEDGVLayer(uri, layer_name, 'spatialite') self.restoreInitialState() self.close() except: self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the layer(s)!"), level=QgsMessageBar.CRITICAL) else: self.bar.pushMessage(self.tr("Warning!"), self.tr("Please select at least one layer!"), level=QgsMessageBar.WARNING) def loadEDGVLayer(self, uri, layer_name, provider): vlayer = QgsVectorLayer(uri.uri(), layer_name, provider) vlayer.setCrs(self.crs) QgsMapLayerRegistry.instance().addMapLayer(vlayer) #added due to api changes if self.isSpatialite and (self.dbVersion == '3.0' or self.dbVersion == '2.1.3'): lyr = '_'.join(layer_name.replace('\r', '').split('_')[1::]) else: lyr = layer_name.replace('\r','') vlayerQml = os.path.join(self.qmlPath, lyr+'.qml') vlayer.loadNamedStyle(vlayerQml, False) QgsMapLayerRegistry.instance().addMapLayer(vlayer) if not vlayer.isValid(): QgsMessageLog.logMessage(vlayer.error().summary(), "DSG Tools Plugin", QgsMessageLog.CRITICAL)
class ManageComplexDialog(QDialog, Ui_Dialog): def __init__(self, iface, db, table): """Constructor. """ QDialog.__init__( self ) self.setupUi( self ) #qgis interface self.iface = iface #database conenction self.db = db #table name self.table = table #rows that are marked for removal self.toBeRemoved = [] #adjusting the table name to match the correspondent qml file fileName = table.replace('complexos_', '') fileName = fileName.split('.')[-1]+'.qml' #obtaining the qml file path self.utils = Utils() qmlDirPath = self.utils.getQmlDir(db) qmlPath = os.path.join(qmlDirPath, fileName) #getting the domain dictionary that will be used to generate the comboboxes try: parser = QmlParser(qmlPath) self.domainDict = parser.getDomainDict() except: self.domainDict = dict() pass QObject.connect(self.addRow, SIGNAL(("clicked()")), self.addComplex) QObject.connect(self.removeRow, SIGNAL(("clicked()")), self.removeComplex) QObject.connect(self.updateButton, SIGNAL(("clicked()")), self.updateTable) QObject.connect(self.cancelButton, SIGNAL(("clicked()")), self.cancel) self.updateTableView() def generateCombos(self): self.combos = [] for key in self.domainDict: self.generateCombo(key, self.domainDict[key]) def generateCombo(self, column, domainValues): combo = ComboBoxDelegate(self,domainValues, self.projectModel.fieldIndex(column)) self.tableView.setItemDelegateForColumn(self.projectModel.fieldIndex(column), combo) def updateTableView(self): #setting the model in the view self.projectModel = CustomTableModel(self.domainDict, None, self.db) #adjusting the table self.projectModel.setTable(self.table) #manual commit rule self.projectModel.setEditStrategy(QSqlTableModel.OnManualSubmit) #selecting all item from the table self.projectModel.select() #creating the comboboxes to map the domain values self.generateCombos() #case the first record is null we make some adjustments #this is not supposed to happen record = self.projectModel.record(0) if not record.value("id"): adjustedRecord = self.adjustRecord(record) self.projectModel.setRecord(0, adjustedRecord) self.tableView.setModel(self.projectModel) #Hiding columns that point to other complexes so that the user can't change them for i in range(self.projectModel.columnCount()): columnName = self.projectModel.headerData(i, Qt.Horizontal) if 'id_' in columnName: self.tableView.hideColumn(i) self.tableView.show() def addComplex(self): record = self.projectModel.record() adjustedRecord = self.adjustRecord(record) self.projectModel.insertRecord(self.projectModel.rowCount(), adjustedRecord) def adjustRecord(self,record): #insert a new record with an already determined uuid value record.setValue("id",str(uuid4())) record.setValue("nome", self.tr("edit this field")) for i in range(self.projectModel.columnCount()): columnName = self.projectModel.headerData(i, Qt.Horizontal) if self.domainDict.has_key(columnName): record.setValue(columnName, self.tr("edit this field")) return record def removeComplex(self): #getting the selected rows selectionModel = self.tableView.selectionModel() selectedRows = selectionModel.selectedRows() for row in selectedRows: #storing the complex to be removed record = self.projectModel.record(row.row()) uuid = str(record.value("id")) if uuid not in self.toBeRemoved: self.toBeRemoved.append(uuid) self.projectModel.removeRow(row.row()) def cancel(self): self.done(0) def checkComplexNameField(self): count = self.projectModel.rowCount() for i in range(count): record = self.projectModel.record(i) if record.isNull('nome'): QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr('The field: \'nome\' must be filled in all rows. Please, check and try again.')) return False return True def updateTable(self): #checking if the name field is filled #Now the database checks the field "nome", therefore the method checkComplexNameField() is no longer needed # if not self.checkComplexNameField(): # return #emit the signal to disassocite all features from the complexes marked for removal self.emit(SIGNAL("markedToRemove( PyQt_PyObject )"), self.toBeRemoved) #commmiting all pending changes if not self.projectModel.submitAll(): #In case something went wrong we show the message to the user QMessageBox.warning(self.iface.mainWindow(), self.tr("Error!"), self.projectModel.lastError().text()) #Emit the signal to update the complex tree self.emit( SIGNAL( "tableUpdated()" ))