def sel(self): """ enable/disable selected features only checkbox """ self.ui.selectedBox.setEnabled(False) self.ui.selectedBox.setCheckState(QtCore.Qt.Unchecked) l = util.getMapLayerByName(self.ui.layerBox.currentText()) if l is not None: sf = l.selectedFeatures() if sf is not None and len(sf): self.ui.selectedBox.setEnabled(True) self.ui.selectedBox.setCheckState(QtCore.Qt.Checked)
def fillColumnNames(self): """ Fill column name combo from current layer """ self.ColumnCombo.clear() lname = self.LayerCombo.currentText() if len(lname): vlayer = util.getMapLayerByName(lname) # String, Integer for shapes # INTEGER, TEXT for spatialite # int4, int8, text for postgis self.ColumnCombo.addItems(util.getFieldNames(vlayer, ["String", "Integer", "INTEGER", "TEXT", "int4", "int8", "text"]))
def showEvent(self, event): # remove previous entries from layer list self.ui.layerBox.clear() # remove previous shape path self.ui.pointEdit.clear() # add polygon layers to list names = util.getLayerNames([QGis.Polygon]) self.ui.layerBox.addItems(names) if iface.activeLayer(): # set active item in list to the active layer i = 0 for name in names: l = util.getMapLayerByName(name) if l == iface.activeLayer(): self.ui.layerBox.setCurrentIndex(i) break i += 1
def run(self): """ Do the job """ # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result and len(self.dlg.LayerCombo.currentText()) and len(self.dlg.ColumnCombo.currentText()): vlayer = util.getMapLayerByName(self.dlg.LayerCombo.currentText()) vprovider = vlayer.dataProvider() field = self.dlg.ColumnCombo.currentText() fields = vprovider.fields() id = fields.indexFromName(field) # unique values of selected field uniquevalues = vprovider.uniqueValues(id) if len(uniquevalues) > 25: if ( QMessageBox.warning( None, QApplication.translate("@default", "Warning"), str(len(uniquevalues)) + " " + QApplication.translate("@default", " unique values! Continue?"), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Cancel, ) == QMessageBox.Cancel ): return base = os.path.join(self.dlg.DirectoryEdit.text(), self.dlg.BaseEdit.text()) for uniquevalue in uniquevalues: # create new shape file for each unique value writer = QgsVectorFileWriter( base + str(uniquevalue), vprovider.encoding(), fields, vprovider.geometryType(), vprovider.crs() ) # set up filter expression exptext = field + " = '" + str(uniquevalue) + "'" exp = QgsExpression(exptext) request = QgsFeatureRequest(exp) # pyqtRemoveInputHook() # pdb.set_trace() for feature in vlayer.getFeatures(request): writer.addFeature(feature) # flush and close del writer
def centroids(self): vlayer = util.getMapLayerByName(self.dlg.ui.layerBox.currentText()) vprovider = vlayer.dataProvider() writer = QgsVectorFileWriter(self.dlg.shapefileName, self.dlg.encoding, vprovider.fields(), QGis.WKBPoint, vprovider.crs()) inFeat = QgsFeature() outFeat = QgsFeature() if self.dlg.ui.selectedBox.isChecked(): features = vlayer.selectedFeatures() else: features = vlayer.getFeatures() for inFeat in features: #nElement += 1 inGeom = inFeat.geometry() if inGeom.isMultipart(): # find largest part in case of multipart maxarea = 0 tmpGeom = QgsGeometry() for part in inGeom.asGeometryCollection(): area = part.area() if area > maxarea: tmpGeom = part maxarea = area inGeom = tmpGeom atMap = inFeat.attributes() if QGis.QGIS_VERSION > '2.4': outGeom = inGeom.pointOnSurface() else: outGeom = inGeom.centroid() if not inGeom.contains(outGeom): # weight point outside the polygon # find intersection of horizontal line through the weight pont rect = inGeom.boundingBox() horiz = QgsGeometry.fromPolyline([ QgsPoint(rect.xMinimum(), outGeom.asPoint()[1]), QgsPoint(rect.xMaximum(), outGeom.asPoint()[1]) ]) line = horiz.intersection(inGeom) if line.isMultipart(): # find longest intersection mline = line.asMultiPolyline() l = 0 for i in range(len(mline)): d = sqrt((mline[i][0][0] - mline[i][1][0])**2 + (mline[i][0][1] - mline[i][1][1])**2) if d > l: l = d xMid = (mline[i][0][0] + mline[i][1][0]) / 2.0 yMid = (mline[i][0][1] + mline[i][1][1]) / 2.0 else: xMid = (line.vertexAt(0).x() + line.vertexAt(1).x()) / 2.0 yMid = (line.vertexAt(0).y() + line.vertexAt(1).y()) / 2.0 outGeom = QgsGeometry.fromPoint(QgsPoint(xMid, yMid)) outFeat.setAttributes(atMap) outFeat.setGeometry(outGeom) writer.addFeature(outFeat) del writer # add centroid shape to canvas if self.dlg.ui.addBox.checkState() == Qt.Checked: if not util.addShape(self.dlg.shapefileName): QMessageBox.warning(self, "RealCentroid", \ QApplication.translate("RealCentroid", \ "Error loading shapefile:\n", None, \ QApplication.UnicodeUTF8) + self.dlg.shapefileName)
def centroids(self): vlayer = util.getMapLayerByName(self.dlg.ui.layerBox.currentText()) vprovider = vlayer.dataProvider() writer = QgsVectorFileWriter(self.dlg.shapefileName, self.dlg.encoding, vprovider.fields(), QGis.WKBPoint, vprovider.crs()) inFeat = QgsFeature() outFeat = QgsFeature() if self.dlg.ui.selectedBox.isChecked(): features = vlayer.selectedFeatures() else: features = vlayer.getFeatures() nElement = 0 nError = 0 for inFeat in features: nElement += 1 inGeom = inFeat.geometry() if inGeom is None or inGeom.isGeosEmpty() or not inGeom.isGeosValid(): QgsMessageLog.logMessage("Feature %d skipped (empty or invalid geometry)" % nElement, 'realcentroid') nError += 1 continue if inGeom.isMultipart(): # find largest part in case of multipart maxarea = 0 tmpGeom = QgsGeometry() for part in inGeom.asGeometryCollection(): area = part.area() if area > maxarea: tmpGeom = part maxarea = area inGeom = tmpGeom atMap = inFeat.attributes() if QGis.QGIS_VERSION > '2.4': outGeom = inGeom.pointOnSurface() if outGeom is None: # pointOnSurface failed outGeom = inGeom.centroid() else: outGeom = inGeom.centroid() if not inGeom.contains(outGeom): # weight point outside the polygon # find intersection of horizontal line through the weight pont rect = inGeom.boundingBox() horiz = QgsGeometry.fromPolyline([QgsPoint(rect.xMinimum(), outGeom.asPoint()[1]), QgsPoint(rect.xMaximum(), outGeom.asPoint()[1])]) line = horiz.intersection(inGeom) if line is None: # skip invalid geometry QgsMessageLog.logMessage("Feature %d skipped (empty or invalid geometry)" % nElement, 'realcentroid') nError += 1 continue elif line.isMultipart(): # find longest intersection mline = line.asMultiPolyline() l = 0 for i in range(len(mline)): d = sqrt((mline[i][0][0] - mline[i][1][0])**2 + (mline[i][0][1] - mline[i][1][1])**2) if d > l: l = d xMid = (mline[i][0][0] + mline[i][1][0]) / 2.0 yMid = (mline[i][0][1] + mline[i][1][1]) / 2.0 else: xMid = (line.vertexAt(0).x() + line.vertexAt(1).x()) / 2.0 yMid = (line.vertexAt(0).y() + line.vertexAt(1).y()) / 2.0 outGeom = QgsGeometry.fromPoint(QgsPoint(xMid, yMid)) outFeat.setAttributes(atMap) outFeat.setGeometry(outGeom) writer.addFeature(outFeat) del writer # add centroid shape to canvas if self.dlg.ui.addBox.checkState() == Qt.Checked: if not util.addShape(self.dlg.shapefileName): QMessageBox.warning(None, "RealCentroid", \ QApplication.translate("RealCentroid", \ "Error loading shapefile:\n", None, \ QApplication.UnicodeUTF8) + self.dlg.shapefileName) if nError > 0: QMessageBox.warning(None, "RealCentroid", \ QApplication.translate("RealCentroid", \ "Invalid or empty geometries found, see log messages"))