def layerData(self, layer, request={}, offset=0): # Retrieve the data for a layer first = True data = {} fields = [] fieldTypes = [] fr = QgsFeatureRequest() if request: if 'exact' in request and request['exact']: fr.setFlags(QgsFeatureRequest.ExactIntersect) if 'nogeom' in request and request['nogeom']: fr.setFlags(QgsFeatureRequest.NoGeometry) if 'fid' in request: fr.setFilterFid(request['fid']) elif 'extents' in request: fr.setFilterRect(QgsRectangle(*request['extents'])) if 'attributes' in request: fr.setSubsetOfAttributes(request['attributes']) # IMPORTANT - we do not use `for f in layer.getFeatures(fr):` as we need # to verify that existing attributes and geometry are correctly cleared # from the feature when calling nextFeature() it = layer.getFeatures(fr) f = QgsFeature() while it.nextFeature(f): if first: first = False for field in f.fields(): fields.append(str(field.name())) fieldTypes.append(str(field.typeName())) if sys.version_info.major == 2: fielddata = dict((name, str(f[name])) for name in fields) else: fielddata = dict((name, str(f[name])) for name in fields) g = f.geometry() if not g.isEmpty(): fielddata[geomkey] = str(g.exportToWkt()) else: fielddata[geomkey] = "None" fielddata[fidkey] = f.id() id = fielddata[fields[0]] description = fielddata[fields[1]] fielddata['id'] = id fielddata['description'] = description data[f.id() + offset] = fielddata if 'id' not in fields: fields.insert(0, 'id') if 'description' not in fields: fields.insert(1, 'description') fields.append(fidkey) fields.append(geomkey) return fields, fieldTypes, data
def testMinMaxAfterChanges(self): """ Tests retrieving field min and max value after making changes to the provider's features """ if not getattr(self, 'getEditableLayer', None): return vl = self.getEditableLayer() self.assertTrue(vl.isValid()) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # add feature f6 = QgsFeature() f6.setAttributes([15, 1400]) res, [f6] = vl.dataProvider().addFeatures([f6]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) f7 = QgsFeature() f7.setAttributes([0, -1400]) res, [f7] = vl.dataProvider().addFeatures([f7]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 0) self.assertEqual(vl.dataProvider().minimumValue(1), -1400) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) # change attribute values self.assertTrue(vl.dataProvider().changeAttributeValues({f6.id(): {1: 150}, f7.id(): {1: -100}})) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # delete features f1 = [f for f in vl.getFeatures() if f['pk'] == 5][0] f3 = [f for f in vl.getFeatures() if f['pk'] == 3][0] self.assertTrue(vl.dataProvider().deleteFeatures([f6.id(), f7.id()])) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteAttributes: # delete attributes if vl.dataProvider().deleteAttributes([0]): # may not be possible, e.g. if it's a primary key self.assertEqual(vl.dataProvider().minimumValue(0), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 400)
def testGetFeaturesFidsTests(self): fids = [f.id() for f in self.source.getFeatures()] self.assertEqual(len(fids), 5) # empty list = no features request = QgsFeatureRequest().setFilterFids([]) result = set([f.id() for f in self.source.getFeatures(request)]) self.assertFalse(result) request = QgsFeatureRequest().setFilterFids([fids[0], fids[2]]) result = set([f.id() for f in self.source.getFeatures(request)]) all_valid = (all(f.isValid() for f in self.source.getFeatures(request))) expected = set([fids[0], fids[2]]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result) self.assertTrue(all_valid) # test that results match QgsFeatureRequest.acceptFeature for f in self.source.getFeatures(): self.assertEqual(request.acceptFeature(f), f.id() in expected) result = set([f.id() for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]]))]) expected = set([fids[1], fids[3], fids[4]]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result) #sources should ignore non-existent fids result = set([f.id() for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids([-101, fids[1], -102, fids[3], -103, fids[4], -104]))]) expected = set([fids[1], fids[3], fids[4]]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result) result = set([f.id() for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids([]))]) expected = set([]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result) # Rewind mid-way request = QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]]) feature_it = self.source.getFeatures(request) feature = QgsFeature() feature.setValid(True) self.assertTrue(feature_it.nextFeature(feature)) self.assertIn(feature.id(), [fids[1], fids[3], fids[4]]) first_feature = feature self.assertTrue(feature.isValid()) # rewind self.assertTrue(feature_it.rewind()) self.assertTrue(feature_it.nextFeature(feature)) self.assertEqual(feature.id(), first_feature.id()) self.assertTrue(feature.isValid()) # grab all features self.assertTrue(feature_it.nextFeature(feature)) self.assertTrue(feature_it.nextFeature(feature)) # none left self.assertFalse(feature_it.nextFeature(feature)) self.assertFalse(feature.isValid())
def testGetFeaturesFidsTests(self): fids = [f.id() for f in self.provider.getFeatures()] self.assertEqual(len(fids), 5) request = QgsFeatureRequest().setFilterFids([fids[0], fids[2]]) result = set([f.id() for f in self.provider.getFeatures(request)]) all_valid = all(f.isValid() for f in self.provider.getFeatures(request)) expected = set([fids[0], fids[2]]) assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result) self.assertTrue(all_valid) result = set( [f.id() for f in self.provider.getFeatures(QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]]))] ) expected = set([fids[1], fids[3], fids[4]]) assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result) # providers should ignore non-existant fids result = set( [ f.id() for f in self.provider.getFeatures( QgsFeatureRequest().setFilterFids([-101, fids[1], -102, fids[3], -103, fids[4], -104]) ) ] ) expected = set([fids[1], fids[3], fids[4]]) assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result) result = set([f.id() for f in self.provider.getFeatures(QgsFeatureRequest().setFilterFids([]))]) expected = set([]) assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result) # Rewind mid-way request = QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]]) feature_it = self.provider.getFeatures(request) feature = QgsFeature() feature.setValid(True) self.assertTrue(feature_it.nextFeature(feature)) self.assertIn(feature.id(), [fids[1], fids[3], fids[4]]) first_feature = feature self.assertTrue(feature.isValid()) # rewind self.assertTrue(feature_it.rewind()) self.assertTrue(feature_it.nextFeature(feature)) self.assertEqual(feature.id(), first_feature.id()) self.assertTrue(feature.isValid()) # grab all features self.assertTrue(feature_it.nextFeature(feature)) self.assertTrue(feature_it.nextFeature(feature)) # none left self.assertFalse(feature_it.nextFeature(feature)) self.assertFalse(feature.isValid())
def select_feature(self, point): '''Method to select feature from map canvas based on point location.''' # Select Features function from # http://www.qgisworkshop.org/html/workshop/plugins_tutorial.html # setup the provider select to filter results based on a rectangle pntGeom = QgsGeometry.fromPoint(point) # scale-dependent buffer of 3 pixels-worth of map units pntBuff = pntGeom.buffer( (self.canvas.mapUnitsPerPixel() * 3), 0) rect = pntBuff.boundingBox() layers = qgis.utils.iface.mapCanvas().layers() nodes = str(self.ui.comboBoxInputNodes.currentText()) for layer in layers: if layer.name() == nodes: provider = layer.dataProvider() if layer.geometryType() == QGis.Point: feat = QgsFeature() # create the select statement provider.select([], rect) # the arguments mean no attributes returned and do a bbox # filter with our buffered rectangle to limit the amount #of features. while provider.nextFeature(feat): # if the feat geom returned from the selection #intersects our point then put it in selection list. if feat.geometry().intersects(rect): self.selected_nodes[self.nodetype] = feat.id() self.output.clear() self.output.insert( str(feat.geometry().asPoint().x())+',' +str(feat.geometry().asPoint().y())) layer.removeSelection() for featid in self.selected_nodes.itervalues(): if featid is not None: layer.select(featid) break # stop here to select one point only.
def gotFeatureForIdentification(self, pos): """Show a dialog with road information """ #pos is a rectangle self.mem_layer_obj.select() ftr = QgsFeature() ftr_ids = [] while self.mem_layer_obj.nextFeature(ftr): if ftr.geometry().intersects(pos): ftr_ids.append(ftr.id()) self.chosenFOIGeoms = [] self.info = QgsMessageViewer() if ftr_ids != []: f = QgsFeature() foi_type = self.foi_type.lower() if foi_type == 'areaofinterestdefiner': ftrData = "You have selected the following feature(s) for use as an Area of Interest:\n\n" if foi_type == 'lineofinterestdefiner': ftrData = "You have selected the following feature(s) for use as a Line of Interest:\n\n" if foi_type == 'pointofinterestdefiner': ftrData = "You have selected the following feature(s) for use as a Point of Interest:\n\n" for fid in ftr_ids: self.mem_layer_obj.dataProvider().featureAtId(fid, f, True) ftrData += f.attributeMap()[0].toString() ftrData += "\n_____________________________\n" self.chosenFOIGeoms.append(f.geometry()) id_fid = self.addGeomToMemoryLayer(f.geometry()) self.info.setMessageAsPlainText(ftrData) else: self.info.setMessageAsPlainText("no data to show") self.info.show() return
def testClear(self): s = QgsAuxiliaryStorage() self.assertTrue(s.isValid()) # Create a new auxiliary layer with 'pk' as key vl = createLayer() pkf = vl.fields().field(vl.fields().indexOf('pk')) al = s.createAuxiliaryLayer(pkf, vl) self.assertTrue(al.isValid()) vl.setAuxiliaryLayer(al) # Add a field in auxiliary layer p = QgsPropertyDefinition('myprop', QgsPropertyDefinition.DataTypeNumeric, '', '', 'me') self.assertFalse(al.exists(p)) self.assertTrue(al.addAuxiliaryField(p)) self.assertTrue(al.exists(p)) # Count auxiliary features self.assertEqual(al.featureCount(), 0) # Set value for auxiliary fields req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) afName = QgsAuxiliaryLayer.nameFromProperty(p, True) index = vl.fields().indexOf(afName) vl.changeAttributeValue(f.id(), index, 333) # Count auxiliary features self.assertEqual(al.featureCount(), 1) # Clear and count al.clear() self.assertEqual(al.featureCount(), 0)
def testEditGeoJsonAddFieldAndThenAddFeatures(self): """ Test bugfix of https://issues.qgis.org/issues/18596 (adding a new field)""" datasource = os.path.join(self.basetestpath, 'testEditGeoJsonAddField.json') with open(datasource, 'wt') as f: f.write("""{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "x": 1 }, "geometry": { "type": "Point", "coordinates": [ 0, 0 ] } } ] }""") vl = QgsVectorLayer(datasource, 'test', 'ogr') self.assertTrue(vl.isValid()) self.assertTrue(vl.startEditing()) self.assertTrue(vl.addAttribute(QgsField('strfield', QVariant.String))) self.assertTrue(vl.commitChanges()) self.assertEqual(len(vl.dataProvider().fields()), 1 + 1) self.assertEqual([f.name() for f in vl.dataProvider().fields()], ['x', 'strfield']) f = QgsFeature() self.assertTrue(vl.getFeatures(QgsFeatureRequest()).nextFeature(f)) self.assertIsNone(f['strfield']) self.assertEqual([field.name() for field in f.fields()], ['x', 'strfield']) self.assertTrue(vl.startEditing()) vl.changeAttributeValue(f.id(), 1, 'x') self.assertTrue(vl.commitChanges()) f = QgsFeature() self.assertTrue(vl.getFeatures(QgsFeatureRequest()).nextFeature(f)) self.assertEqual(f['strfield'], 'x') self.assertEqual([field.name() for field in f.fields()], ['x', 'strfield']) # Completely reload file vl = QgsVectorLayer(datasource, 'test', 'ogr') self.assertEqual(len(vl.fields()), 2)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) buf = self.getParameterValue(self.BUFFER) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields().toList(), QGis.WKBPolygon, layer.crs()) inFeat = QgsFeature() outFeat = QgsFeature() extent = layer.extent() extraX = extent.height() * (buf / 100.0) extraY = extent.width() * (buf / 100.0) height = extent.height() width = extent.width() c = voronoi.Context() pts = [] ptDict = {} ptNdx = -1 features = vector.features(layer) for inFeat in features: geom = QgsGeometry(inFeat.geometry()) point = geom.asPoint() x = point.x() - extent.xMinimum() y = point.y() - extent.yMinimum() pts.append((x, y)) ptNdx += 1 ptDict[ptNdx] = inFeat.id() if len(pts) < 3: raise GeoAlgorithmExecutionException( self.tr('Input file should contain at least 3 points. Choose ' 'another file and try again.')) uniqueSet = Set(item for item in pts) ids = [pts.index(item) for item in uniqueSet] sl = voronoi.SiteList([voronoi.Site(i[0], i[1], sitenum=j) for (j, i) in enumerate(uniqueSet)]) voronoi.voronoi(sl, c) inFeat = QgsFeature() current = 0 total = 100.0 / float(len(c.polygons)) for (site, edges) in c.polygons.iteritems(): request = QgsFeatureRequest().setFilterFid(ptDict[ids[site]]) inFeat = layer.getFeatures(request).next() lines = self.clip_voronoi(edges, c, width, height, extent, extraX, extraY) geom = QgsGeometry.fromMultiPoint(lines) geom = QgsGeometry(geom.convexHull()) outFeat.setGeometry(geom) outFeat.setAttributes(inFeat.attributes()) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def poly2nb(self): lst = [] index = QgsSpatialIndex() featsA = self.lyr.getFeatures() featsB = self.lyr.getFeatures() for ft in featsA: index.insertFeature(ft) featB = QgsFeature() prv = self.lyr.dataProvider() while featsB.nextFeature(featB): geomB = featB.constGeometry() idb = featB.id() idxs = index.intersects(geomB.boundingBox()) sor = [] for idx in idxs: rqst = QgsFeatureRequest().setFilterFid(idx) featA = prv.getFeatures(rqst).next() ida = featA.id() geomA = QgsGeometry(featA.geometry()) if idb!=ida: if geomB.touches(geomA)==True: sor.append(ida) lst.append(sor) return lst
def control(self): self.ids = [] self.polynum = self.ml.featureCount() feat = QgsFeature() provider = self.ml.dataProvider() feats = provider.getFeatures() self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0) self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, self.polynum)) ne = 0 while feats.nextFeature(feat): ne += 1 self.emit(SIGNAL("runStatus(PyQt_PyObject)"), ne) geom = QgsGeometry(feat.geometry()) if geom.isMultipart(): multi_polygon = geom.asMultiPolygon() for polygon in multi_polygon: for ring in polygon: for v in ring: self.cintlen(str(v.x())) self.cintlen(str(v.y())) else: polygon = geom.asPolygon() for ring in polygon: for v in ring: self.cintlen(str(v.x())) self.cintlen(str(v.y())) self.ids.append(feat.id())
def compute(self, inVect, inField, value, perc, progressBar): mlayer = ftools_utils.getMapLayerByName(inVect) mlayer.removeSelection() vlayer = ftools_utils.getVectorLayerByName(inVect) vprovider = vlayer.dataProvider() index = vprovider.fieldNameIndex(inField) unique = ftools_utils.getUniqueValues(vprovider, int(index)) inFeat = QgsFeature() selran = [] nFeat = vprovider.featureCount() * len(unique) nElement = 0 self.progressBar.setValue(0) self.progressBar.setRange(0, nFeat) if not len(unique) == mlayer.featureCount(): for i in unique: fit = vprovider.getFeatures() FIDs= [] while fit.nextFeature(inFeat): atMap = inFeat.attributes() if atMap[index] == i: FID = inFeat.id() FIDs.append(FID) nElement += 1 self.progressBar.setValue(nElement) if perc: selVal = int(round((value / 100.0000) * len(FIDs), 0)) else: selVal = value if selVal >= len(FIDs): selFeat = FIDs else: selFeat = random.sample(FIDs, selVal) selran.extend(selFeat) mlayer.setSelectedFeatures(selran) else: mlayer.setSelectedFeatures(range(0, mlayer.featureCount()))
def nbWithinDist(self): dlg = xdist.Dialog() dlg.setModal(True) dlg.setWindowTitle("Between two objects") if dlg.exec_() == QDialog.Accepted: lDist = float(dlg.lineEdit.text()) if lDist==0: return feat = QgsFeature() provider = self.ml.dataProvider() e = provider.featureCount() self.settings() for ne in range(self.mod, e + self.mod): feat = QgsFeature() geom = QgsGeometry() fiter = self.ml.getFeatures(QgsFeatureRequest(ne)) if fiter.nextFeature(feat): geom = QgsGeometry(feat.geometry()) neighbours = self.hdist(feat, lDist) row = feat.id()-self.mod self.model.setData(self.model.index(row, 0, QModelIndex()), neighbours) self.progressBar.setValue(100*ne/e)
def processAlgorithm(self, parameters, context, feedback): filename = self.getParameterValue(self.INPUT) layer = QgsProcessingUtils.mapLayerFromString(filename, context) field = self.getParameterValue(self.FIELD) method = self.getParameterValue(self.METHOD) layer.removeSelection() index = layer.fields().lookupField(field) unique = QgsProcessingUtils.uniqueValues(layer, index, context) featureCount = layer.featureCount() value = int(self.getParameterValue(self.NUMBER)) if method == 0: if value > featureCount: raise GeoAlgorithmExecutionException( self.tr('Selected number is greater that feature count. ' 'Choose lesser value and try again.')) else: if value > 100: raise GeoAlgorithmExecutionException( self.tr("Percentage can't be greater than 100. Set a " "different value and try again.")) value = value / 100.0 selran = [] inFeat = QgsFeature() current = 0 total = 100.0 / (featureCount * len(unique)) if not len(unique) == featureCount: for i in unique: features = QgsProcessingUtils.getFeatures(layer, context) FIDs = [] for inFeat in features: attrs = inFeat.attributes() if attrs[index] == i: FIDs.append(inFeat.id()) current += 1 feedback.setProgress(int(current * total)) if method == 1: selValue = int(round(value * len(FIDs), 0)) else: selValue = value if selValue >= len(FIDs): selFeat = FIDs else: selFeat = random.sample(FIDs, selValue) selran.extend(selFeat) layer.selectByIds(selran) else: layer.selectByIds(list(range(featureCount))) # FIXME: implies continuous feature ids self.setOutputValue(self.OUTPUT, filename)
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) field = self.getParameterValue(self.FIELD) method = self.getParameterValue(self.METHOD) layer.removeSelection() index = layer.fieldNameIndex(field) unique = vector.getUniqueValues(layer, index) featureCount = layer.featureCount() value = int(self.getParameterValue(self.NUMBER)) if method == 0: if value > featureCount: raise GeoAlgorithmExecutionException( self.tr('Selected number is greater that feature count. ' 'Choose lesser value and try again.')) else: if value > 100: raise GeoAlgorithmExecutionException( self.tr("Percentage can't be greater than 100. Set a " "different value and try again.")) value = value / 100.0 selran = [] inFeat = QgsFeature() current = 0 total = 100.0 / float(featureCount * len(unique)) if not len(unique) == featureCount: for i in unique: features = vector.features(layer) FIDs = [] for inFeat in features: attrs = inFeat.attributes() if attrs[index] == i: FIDs.append(inFeat.id()) current += 1 progress.setPercentage(int(current * total)) if method == 1: selValue = int(round(value * len(FIDs), 0)) else: selValue = value if selValue >= len(FIDs): selFeat = FIDs else: selFeat = random.sample(FIDs, selValue) selran.extend(selFeat) layer.setSelectedFeatures(selran) else: layer.setSelectedFeatures(range(0, featureCount)) self.setOutputValue(self.OUTPUT, filename)
def test_CreateFeature(self): feat = QgsFeature() feat.addAttribute(1, "text") feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(123,456))) myId = feat.id() myExpectedId = 0 myMessage = '\nExpected: %s\nGot: %s' % (myExpectedId, myId) assert myId == myExpectedId, myMessage
def hintersect(self, feata): geoma = QgsGeometry(feata.geometry()) feat = QgsFeature() provider = self.ml.dataProvider() feats = provider.getFeatures() self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0) self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, provider.featureCount())) ne = 0 neighbours = "" while feats.nextFeature(feat): ne += 1 self.emit(SIGNAL("runStatus(PyQt_PyObject)"), ne) geomb = QgsGeometry(feat.geometry()) if feata.id()!=feat.id(): if geoma.intersects(geomb)==True: neighbours = neighbours + '%s,' % (feat.id()+self.p) return neighbours[:-1]
def accept(self): def updatefeautrefields(feature): for key, value in values.iteritems(): try: feature[key] = value except KeyError: continue return feature if not self.featureform.allpassing: self.bar.pushMessage("Missing fields", "Some fields are still required.", QgsMessageBar.WARNING, duration=2) return if not self.featureform: return if not self.featureform.accept(): return layer = self.featureform.form.QGISLayer before = QgsFeature(self.feature) before.setFields(self.fields, initAttributes=False) values, savedvalues = self.featureform.getvalues() after = QgsFeature(self.feature) after.setFields(self.fields, initAttributes=False) after = updatefeautrefields(after) layer.startEditing() if after.id() > 0: if self.project.historyenabled(layer): # Mark the old one as history before['status'] = 'H' after['status'] = 'C' after['dateedited'] = QDateTime.currentDateTime() after['editedby'] = getpass.getuser() layer.addFeature(after) layer.updateFeature(before) else: layer.updateFeature(after) else: layer.addFeature(after) featureform.savevalues(layer, savedvalues) saved = layer.commitChanges() if not saved: self.failedsave.emit(layer.commitErrors()) map(error, layer.commitErrors()) else: self.featureform.featuresaved(after, values) self.featuresaved.emit() self.accepted.emit() self.featureform = None
def checkAfter(): # check select+nextFeature f = QgsFeature() layer.select([]) assert layer.nextFeature(f) assert f.geometry().asPoint() == QgsPoint(300,400) # check feature at id f2 = QgsFeature() assert layer.featureAtId(f.id(), f2) assert f2.geometry().asPoint() == QgsPoint(300,400)
def checkAfter(): # check select+nextFeature f = QgsFeature() layer.select([0,1]) assert layer.nextFeature(f) assert f.attributes()[0].toString() == "good" # check feature at id f2 = QgsFeature() assert layer.featureAtId(f.id(), f2) assert f2.attributes()[0].toString() == "good"
def checkAfter(): assert len(layer.pendingFields()) == 2 # check feature f = QgsFeature() layer.select(layer.pendingAllAttributesList()) assert layer.nextFeature(f) assert f.geometry().asPoint() == QgsPoint(2,2) # check feature at id f2 = QgsFeature() assert layer.featureAtId(f.id(), f2) assert f2.geometry().asPoint() == QgsPoint(2,2)
def test_join(self): joinLayer = createJoinLayer() joinLayer2 = createJoinLayer() QgsMapLayerRegistry.instance().addMapLayers([joinLayer, joinLayer2]) layer = createLayerWithOnePoint() join = QgsVectorJoinInfo() join.targetFieldName = "fldint" join.joinLayerId = joinLayer.id() join.joinFieldName = "y" join.memoryCache = True layer.addJoin(join) join2 = QgsVectorJoinInfo() join2.targetFieldName = "fldint" join2.joinLayerId = joinLayer2.id() join2.joinFieldName = "y" join2.memoryCache = True join2.prefix = "custom-prefix_" layer.addJoin(join2) flds = layer.pendingFields() assert len(flds) == 6 assert flds[2].name() == "joinlayer_x" assert flds[3].name() == "joinlayer_z" assert flds[4].name() == "custom-prefix_x" assert flds[5].name() == "custom-prefix_z" assert flds.fieldOrigin(0) == QgsFields.OriginProvider assert flds.fieldOrigin(2) == QgsFields.OriginJoin assert flds.fieldOrigin(3) == QgsFields.OriginJoin assert flds.fieldOriginIndex(0) == 0 assert flds.fieldOriginIndex(2) == 0 assert flds.fieldOriginIndex(3) == 2 f = QgsFeature() fi = layer.getFeatures() assert fi.nextFeature(f) attrs = f.attributes() assert len(attrs) == 6 assert attrs[0] == "test" assert attrs[1] == 123 assert attrs[2] == "foo" assert attrs[3] == 321 assert not fi.nextFeature(f) f2 = layer.getFeatures(QgsFeatureRequest(f.id())).next() assert len(f2.attributes()) == 6 assert f2[2] == "foo" assert f2[3] == 321
def test_join(self): joinLayer = createJoinLayer() joinLayer2 = createJoinLayer() QgsMapLayerRegistry.instance().addMapLayers([joinLayer, joinLayer2]) layer = createLayerWithOnePoint() join = QgsVectorJoinInfo() join.targetFieldName = "fldint" join.joinLayerId = joinLayer.id() join.joinFieldName = "y" join.memoryCache = True layer.addJoin(join) join2 = QgsVectorJoinInfo() join2.targetFieldName = "fldint" join2.joinLayerId = joinLayer2.id() join2.joinFieldName = "y" join2.memoryCache = True join2.prefix = "custom-prefix_" layer.addJoin(join2) flds = layer.pendingFields() self.assertEquals(len(flds), 6) self.assertEquals(flds[2].name(), "joinlayer_x") self.assertEquals(flds[3].name(), "joinlayer_z") self.assertEquals(flds[4].name(), "custom-prefix_x") self.assertEquals(flds[5].name(), "custom-prefix_z") self.assertEquals(flds.fieldOrigin(0), QgsFields.OriginProvider) self.assertEquals(flds.fieldOrigin(2), QgsFields.OriginJoin) self.assertEquals(flds.fieldOrigin(3), QgsFields.OriginJoin) self.assertEquals(flds.fieldOriginIndex(0), 0) self.assertEquals(flds.fieldOriginIndex(2), 0) self.assertEquals(flds.fieldOriginIndex(3), 2) f = QgsFeature() fi = layer.getFeatures() self.assertTrue(fi.nextFeature(f)) attrs = f.attributes() self.assertEquals(len(attrs), 6) self.assertEquals(attrs[0], "test") self.assertEquals(attrs[1], 123) self.assertEquals(attrs[2], "foo") self.assertEquals(attrs[3], 321) self.assertFalse(fi.nextFeature(f)) f2 = layer.getFeatures(QgsFeatureRequest(f.id())).next() self.assertEquals(len(f2.attributes()), 6) self.assertEquals(f2[2], "foo") self.assertEquals(f2[3], 321)
def addGeomToLayer(self,geom,layer): """ Add a geometry to a layer as a new feature No attributes are set """ fet = QgsFeature() fet.setGeometry(geom) area=geom.area()#/1000000 if self.debug: print "Area of geom added to layer:", str(area) layer.dataProvider().addFeatures([fet]) layer.dataProvider().changeAttributeValues({fet.id(): { 0: area}}); layer.updateExtents()
def cloneAsMemoryLayer(layer, name, styleURI=None, symbology=None): if (layer is not None and layer.isValid() and layer.type() == QgsMapLayer.VectorLayer): if styleURI is None and symbology is None: symbology = getSymbology(layer) mem = createMemoryLayer(name, layer.wkbType(), layer.crs(), layer.dataProvider().fields(), styleURI, symbology) # Hack required to keep fields defined! mem.startEditing() ft = QgsFeature(layer.dataProvider().fields()) mem.addFeature(ft) mem.deleteFeature(ft.id()) mem.commitChanges() return mem return QgsVectorLayer()
def checkAfter(): assert layer.pendingFeatureCount() == 1 # check select+nextFeature layer.select([]) f = QgsFeature() assert layer.nextFeature(f) assert f.geometry().asPoint() == QgsPoint(1,2) # check feature at id f2 = QgsFeature() assert layer.featureAtId(f.id(), f2) assert f2.geometry().asPoint() == QgsPoint(1,2)
def test_ChangeAttributeAfterAddFeature(self): layer = createLayerWithOnePoint() layer.dataProvider().deleteFeatures([1]) # no need for this feature newF = QgsFeature() newF.setGeometry( QgsGeometry.fromPoint(QgsPoint(1,1)) ) newF.setAttributes( [ QVariant("hello"), QVariant(42) ] ) def checkAfter(): assert len(layer.pendingFields()) == 2 # check feature f = QgsFeature() layer.select(layer.pendingAllAttributesList()) assert layer.nextFeature(f) attrs = f.attributes() assert len(attrs) == 2 assert attrs[0].toString() == "hello" assert attrs[1].toInt()[0] == 12 assert not layer.nextFeature(f) # check feature at id f2 = QgsFeature() assert layer.featureAtId(f.id(), f2) assert f2[0].toString() == "hello" assert f2[1].toInt()[0] == 12 def checkBefore(): # check feature f = QgsFeature() layer.select(layer.pendingAllAttributesList()) assert not layer.nextFeature(f) checkBefore() layer.startEditing() layer.beginEditCommand("AddFeature + ChangeAttribute") assert layer.addFeature(newF) assert layer.changeAttributeValue(newF.id(), 1, QVariant(12)) layer.endEditCommand() checkAfter() # now try undo/redo layer.undoStack().undo() checkBefore() layer.undoStack().redo() checkAfter() assert layer.commitChanges() checkAfter()
def search(self): project = QgsProject.instance() layerId, ok = project.readEntry(self.pluginName, 'layerId') fieldName, ok = project.readEntry(self.pluginName, 'fieldName') pattern = self.searchText.text() self.layer = QgsMapLayerRegistry.instance().mapLayer(layerId) if self.layer is None: self.iface.messageBar().pushMessage(self.name, self.tr("Choose a layer first in settings dialog."), QgsMessageBar.WARNING, 3) self.showSettings() return if fieldName == "": self.iface.messageBar().pushMessage(self.name, self.tr("Choose a field first in settings dialog."), QgsMessageBar.WARNING, 3) self.showSettings() return fields = self.layer.dataProvider().fields() fieldIndex = fields.indexFromName(fieldName) # create feature request featReq = QgsFeatureRequest() featReq.setFlags(QgsFeatureRequest.NoGeometry) featReq.setSubsetOfAttributes([fieldIndex]) iterator = self.layer.getFeatures(featReq) # process search f = QgsFeature() results = [] self.continueSearch = True while iterator.nextFeature(f) and self.continueSearch: if self.evaluate(f[fieldName], pattern): results.append(f.id()) QCoreApplication.processEvents() # process results if self.continueSearch: msg = self.tr("{} features found").format(len(results)) legend = self.iface.legendInterface() if (not legend.isLayerVisible(self.layer)): msg += self.tr(' - The layer named {} is not visible').format(self.layer.name()) self.iface.messageBar().pushMessage(self.name, msg, QgsMessageBar.INFO, 2) self.processResults(results)
def testFiltersWithoutUid(self): ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem_no_uid", "memory") self.assertEqual(ml.isValid(), True) QgsProject.instance().addMapLayer(ml) # a memory layer with 10 features ml.startEditing() for i in range(10): f = QgsFeature(ml.fields()) f.setGeometry(QgsGeometry.fromWkt('POINT({} 0)'.format(i))) f.setAttributes([i]) ml.addFeatures([f]) ml.commitChanges() df = QgsVirtualLayerDefinition() df.setQuery('select * from mem_no_uid') vl = QgsVectorLayer(df.toString(), "vl", "virtual") self.assertEqual(vl.isValid(), True) # make sure the returned id with a filter is the same as # if there is no filter req = QgsFeatureRequest().setFilterRect(QgsRectangle(4.5, -1, 5.5, 1)) fids = [f.id() for f in vl.getFeatures(req)] self.assertEqual(fids, [5]) req = QgsFeatureRequest().setFilterExpression("a = 5") fids = [f.id() for f in vl.getFeatures(req)] self.assertEqual(fids, [5]) req = QgsFeatureRequest().setFilterFid(5) a = [(f.id(), f['a']) for f in vl.getFeatures(req)] self.assertEqual(a, [(5, 5)]) req = QgsFeatureRequest().setFilterFids([5, 6, 8]) a = [(f.id(), f['a']) for f in vl.getFeatures(req)] self.assertEqual(a, [(5, 5), (6, 6), (8, 8)]) QgsProject.instance().removeMapLayer(ml)
def test_getFeatures(self): layer = createLayerWithOnePoint() f = QgsFeature() fi = layer.getFeatures() assert fi.nextFeature(f) == True assert f.isValid() == True assert f.id() == 1 assert f.geometry().asPoint() == QgsPoint(100,200) assert f["fldtxt"] == "test" assert f["fldint"] == 123 assert fi.nextFeature(f) == False
class NEDOriginDrawer: def __init__(self, proj, vehicle_info): self.proj = proj self.vehicle_info = vehicle_info self.ned_origin_layer = QgsVectorLayer("Point?crs=epsg:4326", "NED Origin", "memory") self.feat = QgsFeature() self.ned_origin_layer.dataProvider().addFeature(self.feat) self.ned_origin_layer.setRenderer(self.ned_origin_renderer()) self.ned_origin_layer.setCustomProperty("ned_origin", "NED Origin") self.ned_lat = None self.ned_lon = None def ned_origin_renderer(self): symbol = QgsSymbol.defaultSymbol(self.ned_origin_layer.geometryType()) svg_style = { 'fill': '# 0000ff', 'name': ':/resources/Star2.svg', 'outline': '#000000', 'outline - width': '6.8', 'size': '6' } # create svg symbol layer sym_lyr1 = QgsSvgMarkerSymbolLayer.create(svg_style) # Replace the default layer with our custom layer symbol.deleteSymbolLayer(0) symbol.appendSymbolLayer(sym_lyr1) # Replace the renderer of the current layer renderer = QgsSingleSymbolRenderer(symbol) return renderer def update_ned_point(self): try: self.ned_lat = float( cola2_interface.get_ros_param( self.vehicle_info.get_vehicle_ip(), 9091, self.vehicle_info.get_vehicle_namespace() + '/navigator/ned_latitude')['value']) self.ned_lon = float( cola2_interface.get_ros_param( self.vehicle_info.get_vehicle_ip(), 9091, self.vehicle_info.get_vehicle_namespace() + '/navigator/ned_longitude')['value']) # layer is not yet in the project, add it if len(self.proj.mapLayersByName('NED Origin')) == 0: self.feat.setGeometry( QgsGeometry.fromPointXY( QgsPointXY(self.ned_lon, self.ned_lat))) self.ned_origin_layer.dataProvider().addFeatures([self.feat]) self.proj.addMapLayer(self.ned_origin_layer, True) else: self.ned_origin_layer.startEditing() self.ned_origin_layer.moveVertex(self.ned_lon, self.ned_lat, self.feat.id() + 1, 0) self.ned_origin_layer.commitChanges() except: QMessageBox.warning(None, "NED Origin update", "Could not read NED origin topic.", QMessageBox.Close)
def test_invalidGeometryFilter(self): layer = QgsVectorLayer("Polygon?field=x:string", "joinlayer", "memory") # add some features, one has invalid geometry pr = layer.dataProvider() f1 = QgsFeature(1) f1.setAttributes(["a"]) f1.setGeometry( QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))')) # valid f2 = QgsFeature(2) f2.setAttributes(["b"]) f2.setGeometry( QgsGeometry.fromWkt( 'Polygon((0 0, 1 0, 0 1, 1 1, 0 0))')) # invalid f3 = QgsFeature(3) f3.setAttributes(["c"]) f3.setGeometry( QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))')) # valid self.assertTrue(pr.addFeatures([f1, f2, f3])) res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)) ] self.assertEqual(res, ['a', 'b', 'c']) res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid)) ] self.assertEqual(res, ['a', 'c']) res = [ f['x'] for f in layer.getFeatures( QgsFeatureRequest().setInvalidGeometryCheck( QgsFeatureRequest.GeometryAbortOnInvalid)) ] self.assertEqual(res, ['a']) # with callback self.callback_feature_val = None def callback(feature): self.callback_feature_val = feature['x'] res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid ).setInvalidGeometryCallback(callback)) ] self.assertEqual(res, ['a']) self.assertEqual(self.callback_feature_val, 'b') # clear callback res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid ).setInvalidGeometryCallback(None)) ] self.assertEqual(res, ['a']) # check with filter fids res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(f2.id( )).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)) ] self.assertEqual(res, ['b']) res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(f2.id( )).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid)) ] self.assertEqual(res, []) res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest().setFilterFid( f2.id()).setInvalidGeometryCheck( QgsFeatureRequest.GeometryAbortOnInvalid)) ] self.assertEqual(res, []) f4 = QgsFeature(4) f4.setAttributes(["d"]) f4.setGeometry( QgsGeometry.fromWkt( 'Polygon((0 0, 1 0, 0 1, 1 1, 0 0))')) # invalid # check with added features layer.startEditing() self.assertTrue(layer.addFeatures([f4])) res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)) ] self.assertEqual(set(res), {'a', 'b', 'c', 'd'}) res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid)) ] self.assertEqual(set(res), {'a', 'c'}) res = [ f['x'] for f in layer.getFeatures( QgsFeatureRequest().setInvalidGeometryCheck( QgsFeatureRequest.GeometryAbortOnInvalid)) ] self.assertEqual(res, ['a']) # check with features with changed geometry layer.rollBack() layer.startEditing() layer.changeGeometry( 2, QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))')) # valid layer.changeGeometry( 3, QgsGeometry.fromWkt( 'Polygon((0 0, 1 0, 0 1, 1 1, 0 0))')) # invalid res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)) ] self.assertEqual(set(res), {'a', 'b', 'c'}) res = [ f['x'] for f in layer.getFeatures(QgsFeatureRequest( ).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid)) ] self.assertEqual(set(res), {'a', 'b'}) res = [ f['x'] for f in layer.getFeatures( QgsFeatureRequest().setInvalidGeometryCheck( QgsFeatureRequest.GeometryAbortOnInvalid)) ] self.assertEqual(res, ['a', 'b']) layer.rollBack()
def processAlgorithm(self, parameters, context, feedback): inLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context) boundary = self.parameterAsEnum(parameters, self.MODE, context) == self.MODE_BOUNDARY smallestArea = self.parameterAsEnum(parameters, self.MODE, context) == self.MODE_SMALLEST_AREA if inLayer.selectedFeatureCount() == 0: feedback.reportError(self.tr('{0}: (No selection in input layer "{1}")').format(self.displayName(), parameters[self.INPUT])) featToEliminate = [] selFeatIds = inLayer.selectedFeatureIds() (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, inLayer.fields(), inLayer.wkbType(), inLayer.sourceCrs()) if sink is None: raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) for aFeat in inLayer.getFeatures(): if feedback.isCanceled(): break if aFeat.id() in selFeatIds: # Keep references to the features to eliminate featToEliminate.append(aFeat) else: # write the others to output sink.addFeature(aFeat, QgsFeatureSink.FastInsert) # Delete all features to eliminate in processLayer processLayer = QgsProcessingUtils.mapLayerFromString(dest_id, context) processLayer.startEditing() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 feedback.setProgress(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): if feedback.isCanceled(): break feat = featToEliminate.pop() geom2Eliminate = feat.geometry() bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect(bbox).setSubsetOfAttributes([])) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(geom2Eliminate.constGet()) engine.prepareGeometry() while fit.nextFeature(selFeat): if feedback.isCanceled(): break selGeom = selFeat.geometry() if engine.intersects(selGeom.constGet()): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if not iGeom: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise QgsProcessingException( self.tr('Could not replace geometry of feature with id {0}').format(mergeWithFid)) start = start + add feedback.setProgress(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while if not processLayer.commitChanges(): raise QgsProcessingException(self.tr('Could not commit changes')) for feature in featNotEliminated: if feedback.isCanceled(): break sink.addFeature(feature, QgsFeatureSink.FastInsert) return {self.OUTPUT: dest_id}
def evaluate(self): #Write parameters to GIS bfeat = QgsFeature() featreq = QgsFeatureRequest() i = 0 attr = {} for featid in self.bfeatids: i += 1 attr.clear() bfeat = next( self.sim.blayer.getFeatures(featreq.setFilterFid(featid))) for key in sorted(self.ofile.OptAttributes.keys()): bfindx = self.sim.bprovider.fieldNameIndex( self.ofile.OptAttributes[key][0]) ftype = str(self.sim.bprovider.fields()[bfindx].typeName()) if ftype in ['Integer', 'Integer64']: value = int(self.current.x[key]) elif ftype in ['Real', 'Double']: value = float(self.current.x[key]) if int(self.ofile.OptAttributes[key][4]) in [0, i]: attr.update({bfindx: value}) result = self.sim.bprovider.changeAttributeValues( {bfeat.id(): attr}) if not result: self.setCursor(Qt.ArrowCursor) QMessageBox.critical(self, 'Simulation Optimizer', 'Could not change attribute value1.') return #Can't get attribute table repainting to work for all conditions. self.sim.blayer.selectByIds(self.bfeatids) QApplication.processEvents() #Run simulations for featid in self.bfeatids: self.sim.ui.cbxOnlySelected.setChecked(1) self.sim.blayer.selectByIds([featid]) self.sim.on_btnRun_clicked() self.ui.textSimulation.append(self.sim.p.stdout) self.ui.textSimulation.append(self.sim.p.stderr) #Calculate error sqrerr = [] for featid in self.bfeatids: bfeat = next( self.sim.blayer.getFeatures(featreq.setFilterFid(featid))) for key in sorted(self.ofile.ObjAttributes.keys()): measured = float( bfeat.attribute(self.ofile.ObjAttributes[key][0])) simulated = float( bfeat.attribute(self.ofile.ObjAttributes[key][1])) factor = float(self.ofile.ObjAttributes[key][2]) error = (simulated - measured) * factor #error = (simulated - measured) / measured #error = (simulated - measured) sqrerr.append(error * error) sumsq = sum(sqrerr) / len(sqrerr) rmse = math.sqrt(sumsq) #Output string = '%4d ' % self.iterat string += '%11.5f ' % self.T string += '%5d ' % self.feval string += '%5.3f ' % self.p string += '%4d ' % self.accepted string += '%4d ' % self.declined if self.best.cost: string += ('%10.4f ' % self.best.cost) else: string += ('%10.4f ' % rmse) string += ('%10.4f ' % rmse) for i in self.best.x: string += '%10.4f ' % i for i in self.current.x: string += '%10.4f ' % i self.ui.textOptimization.append(string) f = open(self.logfile, 'a') f.write(string + '\n') f.close() return rmse
def run_checks(): self.assertEqual([f.name() for f in vl.fields()], ['fid', 'type', 'value']) # expression req = QgsFeatureRequest() req.setFilterExpression("value=16") it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter fid req = QgsFeatureRequest() req.setFilterFid(5) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter fids req = QgsFeatureRequest() req.setFilterFids([5]) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # check with subset of attributes req = QgsFeatureRequest() req.setFilterFids([5]) req.setSubsetOfAttributes([2]) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes()[2], 16) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter rect and expression req = QgsFeatureRequest() req.setFilterExpression("value=16 or value=14") req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5)) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # filter rect and fids req = QgsFeatureRequest() req.setFilterFids([3, 5]) req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5)) it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertEqual(f.id(), 5) self.assertEqual(f.attributes(), [5, 2, 16]) self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value']) self.assertEqual(f.geometry().asWkt(), 'Point (5 5)') # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed req = QgsFeatureRequest() req.setSubsetOfAttributes([]) it = vl.getFeatures(req) ids = [] geoms = {} while it.nextFeature(f): ids.append(f.id()) geoms[f.id()] = f.geometry().asWkt() self.assertCountEqual(ids, [3, 4, 5]) self.assertEqual(geoms, { 3: 'Point (3 3)', 4: 'Point (4 4)', 5: 'Point (5 5)' })
def testGetFeaturesFidsTests(self): fids = [f.id() for f in self.source.getFeatures()] self.assertEqual(len(fids), 5) # empty list = no features request = QgsFeatureRequest().setFilterFids([]) result = set([f.id() for f in self.source.getFeatures(request)]) self.assertFalse(result) request = QgsFeatureRequest().setFilterFids([fids[0], fids[2]]) result = set([f.id() for f in self.source.getFeatures(request)]) all_valid = (all(f.isValid() for f in self.source.getFeatures(request))) expected = set([fids[0], fids[2]]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format( expected, result) self.assertTrue(all_valid) # test that results match QgsFeatureRequest.acceptFeature for f in self.source.getFeatures(): self.assertEqual(request.acceptFeature(f), f.id() in expected) result = set([ f.id() for f in self.source.getFeatures( QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]])) ]) expected = set([fids[1], fids[3], fids[4]]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format( expected, result) #sources should ignore non-existent fids result = set([ f.id() for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids( [-101, fids[1], -102, fids[3], -103, fids[4], -104])) ]) expected = set([fids[1], fids[3], fids[4]]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format( expected, result) result = set([ f.id() for f in self.source.getFeatures( QgsFeatureRequest().setFilterFids([])) ]) expected = set([]) assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format( expected, result) # Rewind mid-way request = QgsFeatureRequest().setFilterFids( [fids[1], fids[3], fids[4]]) feature_it = self.source.getFeatures(request) feature = QgsFeature() feature.setValid(True) self.assertTrue(feature_it.nextFeature(feature)) self.assertIn(feature.id(), [fids[1], fids[3], fids[4]]) first_feature = feature self.assertTrue(feature.isValid()) # rewind self.assertTrue(feature_it.rewind()) self.assertTrue(feature_it.nextFeature(feature)) self.assertEqual(feature.id(), first_feature.id()) self.assertTrue(feature.isValid()) # grab all features self.assertTrue(feature_it.nextFeature(feature)) self.assertTrue(feature_it.nextFeature(feature)) # none left self.assertFalse(feature_it.nextFeature(feature)) self.assertFalse(feature.isValid())
def run(self): # Converter escala textual para numérica (denominador) escala = self.escalaAvaliacao.currentText() # '1:100.000' escalaAval = escala.split(':')[1].replace('.','') escalaAval = int(escalaAval) self.canvas.zoomScale(escalaAval) listaHomologosXY = {} # dicionario yx. listaHomologosZ = {} # dicionario z. # Raio definido raio = self.spinBox.value() # Layers selecionados layer1 = self.referenciaComboBox.currentLayer() layer2 = self.avaliacaoComboBox.currentLayer() # Teste para identificar se esta setado. XY = False Z = False if self.xy.isChecked(): XY = True if self.z.isChecked(): Z = True # Troca de referência CRS para uma que utiliza medição em metros (3857). source1 = layer1.crs() source2 = layer2.crs() dest = QgsCoordinateReferenceSystem(3857) tr1 = QgsCoordinateTransform(source1, dest) tr2 = QgsCoordinateTransform(source2, dest) lista1 = [feat1 for feat1 in layer1.getFeatures()] lista2 = [feat2 for feat2 in layer2.getFeatures()] lista3 = [] spIndex1 = QgsSpatialIndex() neighbour = QgsFeature() for feat1 in lista1: spIndex1.insertFeature(feat1) # transforma features em indices espaciais geom1 = QgsGeometry(feat1.geometry()) geom1.transform(tr1) raioTeste = raio neighbour = None encontrado = False for feat2 in lista2: pt = feat2.geometry().asPoint() nearestid = spIndex1.nearestNeighbor(pt, 2)[0] # realiza a analise do vizinho mais próximo, numero de vizinhos é definido no segundo argumento. #print nearestid request = QgsFeatureRequest().setFilterFid(nearestid) geom2 = QgsGeometry(feat2.geometry()) geom2.transform(tr2) if geom1.buffer (raioTeste, 20 ) .contains (geom2): raioTeste = sqrt (geom1.asPoint (). sqrDist (geom2.asPoint ())) neighbour = feat2 encontrado = True # apenas pra descobrir se não foi encontrado. if encontrado == False: #print u'\nHouve pontos nao encontrados dentro do raio definido.' frase = ("<span style='color:purple'>HOUVE PONTOS NAO ENCONTRADOS.</span>") lista3.append(frase) else: if XY: listaHomologosXY[int(feat1.id()), int(neighbour.id())] = (raioTeste) if Z: listaHomologosZ[int(feat1.id()), int(neighbour.id())] = feat1.geometry().geometry().z() - neighbour.geometry().geometry().z() lista2.remove(neighbour) if XY or Z: #print '\nHomologos: \n', listaHomologosXY.keys() distAcum = 0 resultado2 = "<span style='color:orange'>DISTANCIA ENTRE PONTOS: </span>",[ round(v, 2) for v in listaHomologosXY.values()] resultado1 = "<span style='color:orange'>PONTOS HOMOLOGOS: </span>",listaHomologosXY.keys() #print '\nDistancia entre pontos Homologados:\n',resultado2 lista3.append(resultado1) lista3.append(resultado2) if XY: distAcum = 0 for valorXY in listaHomologosXY.values(): distAcum += valorXY resultado = int(distAcum / len(listaHomologosXY)) #print '\nDistancia media:\n', round(resultado,2) b = "<span style='color:orange'>DISTANCIA MEDIA: </span>", round(resultado,2) lista3.append(b) if Z: zAcum = 0 for valorZ in listaHomologosZ.values(): zAcum += valorZ resultado = int(zAcum / len(listaHomologosZ)) #print '\nDiferenca media de elevacao: \n', round(resultado,3) a = "<span style='color:orange'>DISTANCIA MEDIA DE ELEVACAO: </span>", round(resultado,3) lista3.append(a) # Formatação para apresentar QmessageBox de forma bem distribuida. message = u"" one_data = u"<p>{0}</p>" two_data = u"<p>{0} {1}</p>" for data in lista3: message += one_data.format(data) if type(data) == str else two_data.format(data[0], data[1]) QMessageBox.about(self, "RESULTADO: ", message )
def testProjectStorage(self): # New project without fileName p0 = QgsProject() self.assertTrue(p0.auxiliaryStorage().isValid()) # Create new layers with key otherwise auxiliary layers are not # automacially created when added in project vl0 = createLayer() vl0Shp = writeShape(vl0, 'vl0.shp') vl1 = createLayer() vl1Shp = writeShape(vl1, 'vl1.shp') vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr') self.assertTrue(vl0.isValid()) vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr') self.assertTrue(vl1.isValid()) # Add layers to project and check underlying auxiliary layers p0.addMapLayers([vl0, vl1]) self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk')) self.assertTrue(vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char')) al0 = vl0.auxiliaryLayer() al1 = vl1.auxiliaryLayer() self.assertEqual(al0.joinInfo().targetFieldName(), 'pk') self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char') # Add a field in auxiliary layers pdef0 = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut') self.assertTrue(al0.addAuxiliaryField(pdef0)) pdef1 = QgsPropertyDefinition('propname1', QgsPropertyDefinition.DataTypeString, '', '', 'ut') self.assertTrue(al1.addAuxiliaryField(pdef1)) # Check auxiliary fields names af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False) self.assertEqual(af0Name, 'ut_propname') af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False) self.assertEqual(af1Name, 'ut_propname1') # Set value for auxiliary fields req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl0.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True) index0 = vl0.fields().indexOf(af0Name) vl0.changeAttributeValue(f.id(), index0, 333) req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True) index1 = vl1.fields().indexOf(af1Name) vl1.changeAttributeValue(f.id(), index0, 'myvalue') req = QgsFeatureRequest().setFilterExpression("name = 'Orange'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) vl1.changeAttributeValue(f.id(), index0, 'myvalue1') # Save the project in a zip file f = tmpPath() + '.qgz' p0.write(f) # Open the zip file with embedded auxiliary storage p1 = QgsProject() p1.read(f) # Check that auxiliary fields are well loaded in layers self.assertEqual(len(p1.mapLayers().values()), 2) for vl in p1.mapLayers().values(): al = vl.auxiliaryLayer() self.assertEqual(len(al.auxiliaryFields()), 1) af = al.auxiliaryFields()[0] afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af) self.assertEqual(afPropDef.origin(), 'ut') if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk': self.assertEqual(afPropDef.name(), 'propname') self.assertEqual(al.featureCount(), 1) req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index0], 333.0) else: # num_char self.assertEqual(al.featureCount(), 2) self.assertEqual(afPropDef.name(), 'propname1') req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue') req = QgsFeatureRequest().setFilterExpression("name = 'Orange'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue1')
def buffering(progress, writer, distance, field, useField, layer, dissolve, segments): if useField: field = layer.fieldNameIndex(field) outFeat = QgsFeature() inFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() current = 0 features = vector.features(layer) total = 100.0 / len(features) if len(features) > 0 else 1 # With dissolve if dissolve: first = True for inFeat in features: attrs = inFeat.attributes() if useField: value = attrs[field] else: value = distance inGeom = QgsGeometry(inFeat.geometry()) if inGeom.isGeosEmpty(): ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has empty geometry. Skipping...'.format(inFeat.id())) continue if not inGeom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has invalid geometry. Skipping...'.format(inFeat.id())) continue outGeom = inGeom.buffer(float(value), segments) if first: tempGeom = QgsGeometry(outGeom) first = False else: tempGeom = tempGeom.combine(outGeom) current += 1 progress.setPercentage(int(current * total)) outFeat.setGeometry(tempGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) else: # Without dissolve for inFeat in features: attrs = inFeat.attributes() if useField: value = attrs[field] else: value = distance inGeom = QgsGeometry(inFeat.geometry()) if inGeom.isGeosEmpty(): ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has empty geometry. Skipping...'.format(inFeat.id())) continue if not inGeom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has invalid geometry. Skipping...'.format(inFeat.id())) continue outGeom = inGeom.buffer(float(value), segments) outFeat.setGeometry(outGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): inLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue( self.MODE) == self.MODE_SMALLEST_AREA keepSelection = self.getParameterValue(self.KEEPSELECTION) processLayer = vector.duplicateInMemory(inLayer) if not keepSelection: # Make a selection with the values provided attribute = self.getParameterValue(self.ATTRIBUTE) comparison = self.comparisons[self.getParameterValue( self.COMPARISON)] comparisonvalue = self.getParameterValue(self.COMPARISONVALUE) selectindex = vector.resolveFieldIndex(processLayer, attribute) selectType = processLayer.fields()[selectindex].type() selectionError = False if selectType in [ QVariant.Int, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong ]: try: y = int(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to integer' % str(comparisonvalue)) elif selectType == QVariant.Double: try: y = float(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to float' % str(comparisonvalue)) elif selectType == QVariant.String: # 10: string, boolean try: y = str(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to unicode' % str(comparisonvalue)) elif selectType == QVariant.Date: # date dateAndFormat = comparisonvalue.split(' ') if len(dateAndFormat) == 1: # QDate object y = QLocale.system().toDate(dateAndFormat[0]) if y.isNull(): msg = self.tr( 'Cannot convert "%s" to date with system date format %s' % (str(dateAndFormat), QLocale.system().dateFormat())) elif len(dateAndFormat) == 2: y = QDate.fromString(dateAndFormat[0], dateAndFormat[1]) if y.isNull(): msg = self.tr( 'Cannot convert "%s" to date with format string "%s"' % (str(dateAndFormat[0]), dateAndFormat[1])) else: y = QDate() msg = '' if y.isNull(): # Conversion was unsuccessfull selectionError = True msg += self.tr( 'Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".' ) if (comparison == 'begins with' or comparison == 'contains') \ and selectType != QVariant.String: selectionError = True msg = self.tr('"%s" can only be used with string fields' % comparison) selected = [] if selectionError: raise GeoAlgorithmExecutionException( self.tr('Error in selection input: %s' % msg)) else: for feature in processLayer.getFeatures(): aValue = feature.attributes()[selectindex] if aValue is None: continue if selectType in [ QVariant.Int, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong ]: x = int(aValue) elif selectType == QVariant.Double: x = float(aValue) elif selectType == QVariant.String: # 10: string, boolean x = str(aValue) elif selectType == QVariant.Date: # date x = aValue # should be date match = False if comparison == '==': match = x == y elif comparison == '!=': match = x != y elif comparison == '>': match = x > y elif comparison == '>=': match = x >= y elif comparison == '<': match = x < y elif comparison == '<=': match = x <= y elif comparison == 'begins with': match = x.startswith(y) elif comparison == 'contains': match = x.find(y) >= 0 if match: selected.append(feature.id()) processLayer.selectByIds(selected) if processLayer.selectedFeatureCount() == 0: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('%s: (No selection in input layer "%s")' % (self.commandLineName(), self.getParameterValue(self.INPUT)))) # Keep references to the features to eliminate featToEliminate = [] for aFeat in processLayer.selectedFeatures(): featToEliminate.append(aFeat) # Delete all features to eliminate in processLayer (we won't save this) processLayer.startEditing() processLayer.deleteSelectedFeatures() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 progress.setPercentage(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): feat = featToEliminate.pop() geom2Eliminate = feat.geometry() bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect( bbox).setSubsetOfAttributes([])) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine( geom2Eliminate.geometry()) engine.prepareGeometry() while fit.nextFeature(selFeat): selGeom = selFeat.geometry() if engine.intersects(selGeom.geometry()): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if not iGeom: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise GeoAlgorithmExecutionException( self. tr('Could not replace geometry of feature with id %s' % mergeWithFid)) start = start + add progress.setPercentage(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while # Create output output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(processLayer.fields(), processLayer.wkbType(), processLayer.crs()) # Write all features that are left over to output layer iterator = processLayer.getFeatures() for feature in iterator: writer.addFeature(feature) # Leave processLayer untouched processLayer.rollBack() for feature in featNotEliminated: writer.addFeature(feature)
def testMinMaxAfterChanges(self): """ Tests retrieving field min and max value after making changes to the provider's features """ if not getattr(self, 'getEditableLayer', None): return vl = self.getEditableLayer() self.assertTrue(vl.isValid()) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # add feature f6 = QgsFeature() f6.setAttributes([15, 1400]) res, [f6] = vl.dataProvider().addFeatures([f6]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) f7 = QgsFeature() f7.setAttributes([0, -1400]) res, [f7] = vl.dataProvider().addFeatures([f7]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 0) self.assertEqual(vl.dataProvider().minimumValue(1), -1400) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) # change attribute values self.assertTrue(vl.dataProvider().changeAttributeValues({ f6.id(): { 1: 150 }, f7.id(): { 1: -100 } })) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # delete features f1 = [f for f in vl.getFeatures() if f['pk'] == 5][0] f3 = [f for f in vl.getFeatures() if f['pk'] == 3][0] self.assertTrue(vl.dataProvider().deleteFeatures([f6.id(), f7.id()])) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) if vl.dataProvider().capabilities( ) & QgsVectorDataProvider.DeleteAttributes: # delete attributes if vl.dataProvider().deleteAttributes([0]): # may not be possible, e.g. if it's a primary key self.assertEqual(vl.dataProvider().minimumValue(0), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 400)
def eliminate(self, inLayer, boundary, progressBar, outFileName): # keep references to the features to eliminate fidsToEliminate = inLayer.selectedFeaturesIds() if outFileName: # user wants a new shape file to be created as result provider = inLayer.dataProvider() error = QgsVectorFileWriter.writeAsVectorFormat( inLayer, outFileName, provider.encoding(), inLayer.crs(), "ESRI Shapefile") if error != QgsVectorFileWriter.NoError: QMessageBox.warning(self, self.tr("Eliminate"), self.tr("Error creating output file")) return None outLayer = QgsVectorLayer( outFileName, QFileInfo(outFileName).completeBaseName(), "ogr") else: QMessageBox.information(self, self.tr("Eliminate"), self.tr("Please specify output shapefile")) return None # delete features to be eliminated in outLayer outLayer.setSelectedFeatures(fidsToEliminate) outLayer.startEditing() if outLayer.deleteSelectedFeatures(): if self.saveChanges(outLayer): outLayer.startEditing() else: QMessageBox.warning(self, self.tr("Eliminate"), self.tr("Could not delete features")) return None # ANALYZE start = 20.00 progressBar.setValue(start) add = 80.00 / len(fidsToEliminate) lastLen = 0 # we go through the list and see if we find any polygons we can merge the selected with # if we have no success with some we merge and then restart the whole story while (lastLen != inLayer.selectedFeatureCount() ): # check if we made any progress lastLen = inLayer.selectedFeatureCount() fidsToDeselect = [] #iterate over the polygons to eliminate for fid2Eliminate in inLayer.selectedFeaturesIds(): feat = QgsFeature() if inLayer.getFeatures(QgsFeatureRequest().setFilterFid( fid2Eliminate).setSubsetOfAttributes( [])).nextFeature(feat): geom2Eliminate = feat.geometry() bbox = geom2Eliminate.boundingBox() fit = outLayer.getFeatures( QgsFeatureRequest().setFilterRect(bbox)) mergeWithFid = None mergeWithGeom = None max = 0 selFeat = QgsFeature() while fit.nextFeature(selFeat): selGeom = selFeat.geometry() if geom2Eliminate.intersects( selGeom): # we have a candidate iGeom = geom2Eliminate.intersection(selGeom) if boundary: selValue = iGeom.length() else: # we need a common boundary if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = 0 if selValue > max: max = selValue mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry( selGeom) # deep copy of the geometry if mergeWithFid is not None: # a successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if outLayer.changeGeometry(mergeWithFid, newGeom): # write change back to disc if self.saveChanges(outLayer): outLayer.startEditing() else: return None # mark feature as eliminated in inLayer fidsToDeselect.append(fid2Eliminate) else: QMessageBox.warning( self, self.tr("Eliminate"), self. tr("Could not replace geometry of feature with id %s" ) % (mergeWithFid)) return None start = start + add progressBar.setValue(start) # end for fid2Eliminate # deselect features that are already eliminated in inLayer inLayer.deselect(fidsToDeselect) #end while if inLayer.selectedFeatureCount() > 0: # copy all features that could not be eliminated to outLayer if outLayer.addFeatures(inLayer.selectedFeatures()): # inform user fidList = "" for fid in inLayer.selectedFeaturesIds(): if not fidList == "": fidList += ", " fidList += unicode(fid) QErrorMessage(self).showMessage( self.tr("Could not eliminate features with these ids:\n%s") % (fidList)) else: QMessageBox.warning(self, self.tr("Eliminate"), self.tr("Could not add features")) # stop editing outLayer and commit any pending changes if not self.saveChanges(outLayer): return None if outFileName: if self.addToCanvasCheck.isChecked(): ftools_utils.addShapeToCanvas(outFileName) else: QMessageBox.information( self, self.tr("Eliminate"), self.tr("Created output shapefile:\n%s") % (outFileName)) self.iface.mapCanvas().refresh()
def runDensify(self): self.mutex.lock() self.stopMe = 0 self.mutex.unlock() interrupted = False shapeFileWriter = None isPolygon = self.inputLayer.geometryType() == QGis.Polygon if self.writeShape: # prepare writer vProvider = self.inputLayer.dataProvider() shapeFields = vProvider.fields() crs = vProvider.crs() wkbType = self.inputLayer.wkbType() if not crs.isValid(): crs = None shapeFileWriter = QgsVectorFileWriter(self.outputFileName, self.outputEncoding, shapeFields, wkbType, crs) featureId = 0 if self.useSelection: selection = self.inputLayer.selectedFeatures() self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"), len(selection)) for f in selection: featGeometry = QgsGeometry(f.geometry()) attrMap = f.attributes() newGeometry = densifyGeometry(featGeometry, int(self.tolerance), isPolygon) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrMap) shapeFileWriter.addFeature(feature) featureId += 1 self.emit(SIGNAL("featureProcessed()")) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break else: self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"), vProvider.featureCount()) f = QgsFeature() fit = vProvider.getFeatures() while fit.nextFeature(f): featGeometry = QgsGeometry(f.geometry()) attrMap = f.attributes() newGeometry = densifyGeometry(featGeometry, int(self.tolerance), isPolygon) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrMap) shapeFileWriter.addFeature(feature) featureId += 1 self.emit(SIGNAL("featureProcessed()")) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break else: # modify existing shapefile if not self.inputLayer.isEditable(): self.inputLayer.startEditing() self.inputLayer.beginEditCommand("Densify line(s)") if self.useSelection: selection = self.inputLayer.selectedFeatures() self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"), len(selection)) for f in selection: featureId = f.id() featGeometry = QgsGeometry(f.geometry()) newGeometry = densifyGeometry(featGeometry, int(self.tolerance), isPolygon) self.inputLayer.changeGeometry(featureId, newGeometry) self.emit(SIGNAL("featureProcessed()")) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break else: vProvider = self.inputLayer.dataProvider() self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"), vProvider.featureCount()) f = QgsFeature() fit = vProvider.getFeatures() while fit.nextFeature(f): featureId = f.id() featGeometry = QgsGeometry(f.geometry()) newGeometry = densifyGeometry(featGeometry, int(self.tolerance), isPolygon) self.inputLayer.changeGeometry(featureId, newGeometry) self.emit(SIGNAL("featureProcessed()")) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break # cleanup if self.inputLayer.isEditable(): self.inputLayer.endEditCommand() if shapeFileWriter is not None: del shapeFileWriter if not interrupted: self.emit(SIGNAL("processingFinished( PyQt_PyObject )"), None) else: self.emit(SIGNAL("processingInterrupted()"))
def testMinMaxCache(self): """ Test that min/max cache is appropriately cleared :return: """ vl = QgsVectorLayer( 'Point?crs=epsg:4326&field=f1:integer&field=f2:integer', 'test', 'memory') self.assertTrue(vl.isValid()) f1 = QgsFeature() f1.setAttributes([5, -200]) f2 = QgsFeature() f2.setAttributes([3, 300]) f3 = QgsFeature() f3.setAttributes([1, 100]) f4 = QgsFeature() f4.setAttributes([2, 200]) f5 = QgsFeature() f5.setAttributes([4, 400]) res, [f1, f2, f3, f4, f5] = vl.dataProvider().addFeatures([f1, f2, f3, f4, f5]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # add feature f6 = QgsFeature() f6.setAttributes([15, 1400]) res, [f6] = vl.dataProvider().addFeatures([f6]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) f7 = QgsFeature() f7.setAttributes([-1, -1400]) res, [f7] = vl.dataProvider().addFeatures([f7]) self.assertTrue(res) self.assertEqual(vl.dataProvider().minimumValue(0), -1) self.assertEqual(vl.dataProvider().minimumValue(1), -1400) self.assertEqual(vl.dataProvider().maximumValue(0), 15) self.assertEqual(vl.dataProvider().maximumValue(1), 1400) # change attribute values self.assertTrue(vl.dataProvider().changeAttributeValues({ f6.id(): { 0: 3, 1: 150 }, f7.id(): { 0: 4, 1: -100 } })) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -200) self.assertEqual(vl.dataProvider().maximumValue(0), 5) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # delete features self.assertTrue(vl.dataProvider().deleteFeatures([f4.id(), f1.id()])) self.assertEqual(vl.dataProvider().minimumValue(0), 1) self.assertEqual(vl.dataProvider().minimumValue(1), -100) self.assertEqual(vl.dataProvider().maximumValue(0), 4) self.assertEqual(vl.dataProvider().maximumValue(1), 400) # delete attributes self.assertTrue(vl.dataProvider().deleteAttributes([0])) self.assertEqual(vl.dataProvider().minimumValue(0), -100) self.assertEqual(vl.dataProvider().maximumValue(0), 400)
def testSubsetStringFids(self): """ - tests that feature ids are stable even if a subset string is set - tests that the subset string is correctly set on the ogr layer event when reloading the data source (issue #17122) """ tmpfile = os.path.join(self.basetestpath, 'subsetStringFids.sqlite') ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid']) lyr.CreateField(ogr.FieldDefn('type', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('value', ogr.OFTInteger)) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(0) f.SetField(0, 1) f.SetField(1, 11) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(1) f.SetField(0, 1) f.SetField(1, 12) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(2) f.SetField(0, 1) f.SetField(1, 13) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(3) f.SetField(0, 2) f.SetField(1, 14) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(4) f.SetField(0, 2) f.SetField(1, 15) lyr.CreateFeature(f) f = ogr.Feature(lyr.GetLayerDefn()) f.SetFID(5) f.SetField(0, 2) f.SetField(1, 16) lyr.CreateFeature(f) f = None ds = None vl = QgsVectorLayer(tmpfile + "|subset=type=2", 'test', 'ogr') self.assertTrue(vl.isValid()) self.assertTrue(vl.fields().at(vl.fields().count() - 1).name() == "orig_ogc_fid") req = QgsFeatureRequest() req.setFilterExpression("value=16") it = vl.getFeatures(req) f = QgsFeature() self.assertTrue(it.nextFeature(f)) self.assertTrue(f.id() == 5) # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed req = QgsFeatureRequest() req.setSubsetOfAttributes([]) it = vl.getFeatures(req) ids = [] while it.nextFeature(f): ids.append(f.id()) self.assertTrue(len(ids) == 3) self.assertTrue(3 in ids) self.assertTrue(4 in ids) self.assertTrue(5 in ids) # Check that subset string is correctly set on reload vl.reload() self.assertTrue(vl.fields().at(vl.fields().count() - 1).name() == "orig_ogc_fid")
def setSelectFeatures(canvas, selectGeometry, doContains, doDifference, singleSelect=None): """ QgsMapCanvas* canvas, QgsGeometry* selectGeometry, bool doContains, bool doDifference, bool singleSelect """ if selectGeometry.type() != QGis.Polygon: return vlayer = getCurrentVectorLayer(canvas) if vlayer == None: return #toLayerCoordinates will throw an exception for any 'invalid' points in #the rubber band. #For example, if you project a world map onto a globe using EPSG 2163 #and then click somewhere off the globe, an exception will be thrown. selectGeomTrans = QgsGeometry(selectGeometry) if canvas.mapSettings().hasCrsTransformEnabled(): try: ct = QgsCoordinateTransform(canvas.mapSettings().destinationCrs(), vlayer.crs()) selectGeomTrans.transform(ct) except QgsCsException as cse: Q_UNUSED(cse) #catch exception for 'invalid' point and leave existing selection unchanged """ QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); QgisApp::instance()->messageBar()->pushMessage( QObject::tr( "CRS Exception" ), QObject::tr( "Selection extends beyond layer's coordinate system" ), QgsMessageBar::WARNING, QgisApp::instance()->messageTimeout() ); """ return QApplication.setOverrideCursor(Qt.WaitCursor) """ QgsDebugMsg( "Selection layer: " + vlayer->name() ); QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() ); QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) ); QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) ); """ context = QgsRenderContext().fromMapSettings(canvas.mapSettings()) r = vlayer.rendererV2() if r: r.startRender(context, vlayer.pendingFields()) request = QgsFeatureRequest() request.setFilterRect(selectGeomTrans.boundingBox()) request.setFlags(QgsFeatureRequest.ExactIntersect) if r: request.setSubsetOfAttributes(r.usedAttributes(), vlayer.pendingFields()) else: request.setSubsetOfAttributes(QgsAttributeList) fit = vlayer.getFeatures(request) newSelectedFeatures = [] #QgsFeatureIds f = QgsFeature() closestFeatureId = 0 #QgsFeatureId foundSingleFeature = False #double closestFeatureDist = std::numeric_limits<double>::max(); closestFeatureDist = sys.float_info.max while fit.nextFeature(f): # make sure to only use features that are visible if r and not r.willRenderFeature(f): continue g = QgsGeometry(f.geometry()) if doContains: if not selectGeomTrans.contains(g): continue else: if not selectGeomTrans.intersects(g): continue if singleSelect: foundSingleFeature = True distance = float(g.distance(selectGeomTrans)) if (distance <= closestFeatureDist): closestFeatureDist = distance closestFeatureId = f.id() else: newSelectedFeatures.insert(0, f.id()) if singleSelect and foundSingleFeature: newSelectedFeatures.insert(0, closestFeatureId) if r: r.stopRender(context) #QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) if doDifference: layerSelectedFeatures = vlayer.selectedFeaturesIds() selectedFeatures = [] #QgsFeatureIds deselectedFeatures = [] # QgsFeatureIds # i = QgsFeatureIds.const_iterator(newSelectedFeatures.constEnd()) # while i != newSelectedFeatures.constBegin(): # i = i - 1 # if layerSelectedFeatures.contains(i): # deselectedFeatures.insert(0, i) # else: # selectedFeatures.insert(0, i) for item in newSelectedFeatures: if item in layerSelectedFeatures: deselectedFeatures.insert(0, item) else: selectedFeatures.insert(0, item) vlayer.modifySelection(selectedFeatures, deselectedFeatures) else: vlayer.setSelectedFeatures(newSelectedFeatures) QApplication.restoreOverrideCursor() """
def processAlgorithm(self, feedback): inLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue( self.MODE) == self.MODE_SMALLEST_AREA if inLayer.selectedFeatureCount() == 0: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('%s: (No selection in input layer "%s")' % (self.commandLineName(), self.getParameterValue(self.INPUT)))) featToEliminate = [] selFeatIds = inLayer.selectedFeatureIds() output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(inLayer.fields(), inLayer.wkbType(), inLayer.crs()) for aFeat in inLayer.getFeatures(): if aFeat.id() in selFeatIds: # Keep references to the features to eliminate featToEliminate.append(aFeat) else: # write the others to output writer.addFeature(aFeat) # Delete all features to eliminate in processLayer processLayer = output.layer processLayer.startEditing() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 feedback.setProgress(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): feat = featToEliminate.pop() geom2Eliminate = feat.geometry() bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect( bbox).setSubsetOfAttributes([])) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine( geom2Eliminate.geometry()) engine.prepareGeometry() while fit.nextFeature(selFeat): selGeom = selFeat.geometry() if engine.intersects(selGeom.geometry()): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if not iGeom: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise GeoAlgorithmExecutionException( self. tr('Could not replace geometry of feature with id %s' % mergeWithFid)) start = start + add feedback.setProgress(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while if not processLayer.commitChanges(): raise GeoAlgorithmExecutionException( self.tr('Could not commit changes')) for feature in featNotEliminated: writer.addFeature(feature)