def testCreateLayerMultiPoint(self): layer = QgsVectorLayer("MultiPoint?crs=epsg:3111&field=id:integer&field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() f = QgsFeature() f.setAttributes([1, "test", 1]) f.setGeometry(QgsGeometry.fromWkt('MultiPoint(1 2, 3 4)')) f2 = QgsFeature() f2.setAttributes([2, "test2", 3]) f3 = QgsFeature() f3.setAttributes([3, "test2", NULL]) f3.setGeometry(QgsGeometry.fromWkt('MultiPoint(7 8)')) pr.addFeatures([f, f2, f3]) uri = '{} table="qgis_test"."new_table_multipoint" sql='.format(self.dbconn) error, message = QgsVectorLayerExporter.exportLayer(layer, uri, 'mssql', QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual(error, QgsVectorLayerExporter.NoError) new_layer = QgsVectorLayer(uri, 'new', 'mssql') self.assertTrue(new_layer.isValid()) self.assertEqual(new_layer.wkbType(), QgsWkbTypes.MultiPoint) self.assertEqual(new_layer.crs().authid(), 'EPSG:3111') self.assertEqual([f.name() for f in new_layer.fields()], ['qgs_fid', 'id', 'fldtxt', 'fldint']) features = [f.attributes() for f in new_layer.getFeatures()] self.assertEqual(features, [[1, 1, 'test', 1], [2, 2, 'test2', 3], [3, 3, 'test2', NULL]]) geom = [f.geometry().asWkt() for f in new_layer.getFeatures()] self.assertEqual(geom, ['MultiPoint ((1 2),(3 4))', '', 'MultiPoint ((7 8))'])
def testCreateLayer(self): layer = QgsVectorLayer("Point?field=id:integer&field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() f = QgsFeature() f.setAttributes([1, "test", 1]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2))) f2 = QgsFeature() f2.setAttributes([2, "test2", 3]) f3 = QgsFeature() f3.setAttributes([3, "test2", NULL]) f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(3, 2))) f4 = QgsFeature() f4.setAttributes([4, NULL, 3]) f4.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(4, 3))) pr.addFeatures([f, f2, f3, f4]) uri = '{} table="qgis_test"."new_table" sql='.format(self.dbconn) error, message = QgsVectorLayerExporter.exportLayer(layer, uri, 'mssql', QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(error, QgsVectorLayerExporter.NoError) new_layer = QgsVectorLayer(uri, 'new', 'mssql') self.assertTrue(new_layer.isValid()) self.assertEqual(new_layer.wkbType(), QgsWkbTypes.Point) self.assertEqual([f.name() for f in new_layer.fields()], ['qgs_fid', 'id', 'fldtxt', 'fldint']) features = [f.attributes() for f in new_layer.getFeatures()] self.assertEqual(features, [[1, 1, 'test', 1], [2, 2, 'test2', 3], [3, 3, 'test2', NULL], [4, 4, NULL, 3]]) geom = [f.geometry().asWkt() for f in new_layer.getFeatures()] self.assertEqual(geom, ['Point (1 2)', '', 'Point (3 2)', 'Point (4 3)'])
def __init__(self, xmin, ymin, xmax, ymax, x_segments, y_segments): self.vbands = [] self.hbands = [] self.vidx = QgsSpatialIndex() self.hidx = QgsSpatialIndex() xres = (xmax - xmin) / x_segments yres = (ymax - ymin) / y_segments self.xmin, self.ymax, self.xres, self.yres = xmin, ymax, xres, yres def addVBand(idx, geom): f = QgsFeature(idx) f.setGeometry(geom) self.vbands.append(f) self.vidx.insertFeature(f) def addHBand(idx, geom): f = QgsFeature(idx) f.setGeometry(geom) self.hbands.append(f) self.hidx.insertFeature(f) for x in range(x_segments): addVBand(x, QgsGeometry.fromRect(QgsRectangle(xmin + x * xres, ymin, xmin + (x + 1) * xres, ymax))) for y in range(y_segments): addHBand(y, QgsGeometry.fromRect(QgsRectangle(xmin, ymax - (y + 1) * yres, xmax, ymax - y * yres)))
def test_check_validity(self): """Test that the output invalid contains the error reason""" polygon_layer = self._make_layer('Polygon') self.assertTrue(polygon_layer.startEditing()) f = QgsFeature(polygon_layer.fields()) f.setAttributes([1]) # Flake! f.setGeometry(QgsGeometry.fromWkt( 'POLYGON ((0 0, 2 2, 0 2, 2 0, 0 0))')) self.assertTrue(f.isValid()) f2 = QgsFeature(polygon_layer.fields()) f2.setAttributes([1]) f2.setGeometry(QgsGeometry.fromWkt( 'POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))')) self.assertTrue(f2.isValid()) self.assertTrue(polygon_layer.addFeatures([f, f2])) polygon_layer.commitChanges() polygon_layer.rollBack() self.assertEqual(polygon_layer.featureCount(), 2) QgsProject.instance().addMapLayers([polygon_layer]) alg = self.registry.createAlgorithmById('qgis:checkvalidity') context = QgsProcessingContext() context.setProject(QgsProject.instance()) feedback = ConsoleFeedBack() self.assertIsNotNone(alg) parameters = {} parameters['INPUT_LAYER'] = polygon_layer.id() parameters['VALID_OUTPUT'] = 'memory:' parameters['INVALID_OUTPUT'] = 'memory:' parameters['ERROR_OUTPUT'] = 'memory:' # QGIS method parameters['METHOD'] = 1 ok, results = execute( alg, parameters, context=context, feedback=feedback) self.assertTrue(ok) invalid_layer = QgsProcessingUtils.mapLayerFromString( results['INVALID_OUTPUT'], context) self.assertEqual(invalid_layer.fields().names()[-1], '_errors') self.assertEqual(invalid_layer.featureCount(), 1) f = next(invalid_layer.getFeatures()) self.assertEqual(f.attributes(), [ 1, 'segments 0 and 2 of line 0 intersect at 1, 1']) # GEOS method parameters['METHOD'] = 2 ok, results = execute( alg, parameters, context=context, feedback=feedback) self.assertTrue(ok) invalid_layer = QgsProcessingUtils.mapLayerFromString( results['INVALID_OUTPUT'], context) self.assertEqual(invalid_layer.fields().names()[-1], '_errors') self.assertEqual(invalid_layer.featureCount(), 1) f = next(invalid_layer.getFeatures()) self.assertEqual(f.attributes(), [1, 'Self-intersection'])
def layerOmmb(self, layer, writer, feedback): req = QgsFeatureRequest().setSubsetOfAttributes([]) features = vector.features(layer, req) total = 100.0 / len(features) newgeometry = QgsGeometry() first = True for current, inFeat in enumerate(features): if first: newgeometry = inFeat.geometry() first = False else: newgeometry = newgeometry.combine(inFeat.geometry()) feedback.setProgress(int(current * total)) geometry, area, angle, width, height = newgeometry.orientedMinimumBoundingBox() if geometry: outFeat = QgsFeature() outFeat.setGeometry(geometry) outFeat.setAttributes([area, width * 2 + height * 2, angle, width, height]) writer.addFeature(outFeat)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) tolerance = self.getParameterValue(self.TOLERANCE) pointsBefore = 0 pointsAfter = 0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields().toList(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): featGeometry = QgsGeometry(f.geometry()) attrs = f.attributes() pointsBefore += self.geomVertexCount(featGeometry) newGeometry = featGeometry.simplify(tolerance) pointsAfter += self.geomVertexCount(newGeometry) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrs) writer.addFeature(feature) progress.setPercentage(int(current * total)) del writer ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Simplify: Input geometries have been simplified from %s to %s points' % (pointsBefore, pointsAfter)))
def _rectangleGridLine(self, writer, width, height, originX, originY, hSpacing, vSpacing): ft = QgsFeature() columns = int(math.floor(float(width) / hSpacing)) rows = int(math.floor(float(height) / vSpacing)) # Longitude lines for col in xrange(0, columns + 1): polyline = [] x = originX + (col * hSpacing) for row in xrange(0, rows + 1): y = originY + (row * vSpacing) polyline.append(QgsPoint(x, y)) ft.setGeometry(QgsGeometry.fromPolyline(polyline)) ft.setAttributes([x, originY, x, originY + (rows * vSpacing)]) writer.addFeature(ft) # Latitude lines for row in xrange(0, rows + 1): polyline = [] y = originY + (row * vSpacing) for col in xrange(0, columns + 1): x = originX + (col * hSpacing) polyline.append(QgsPoint(x, y)) ft.setGeometry(QgsGeometry.fromPolyline(polyline)) ft.setAttributes([originX, y, originX + (col * hSpacing), y]) writer.addFeature(ft)
def ovals(self, writer, features, width, height, rotation, segments): ft = QgsFeature() xOffset = width / 2.0 yOffset = height / 2.0 if rotation is not None: phi = rotation * math.pi / 180 for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft) else: for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append((xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft)
def diamonds(self, writer, features, width, height, rotation): ft = QgsFeature() xOffset = width / 2.0 yOffset = height / 2.0 if rotation is not None: phi = rotation * math.pi / 180 for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft) else: for current, feat in enumerate(features): point = feat.geometry().asPoint() x = point.x() y = point.y() points = [(0.0, -yOffset), (-xOffset, 0.0), (0.0, yOffset), (xOffset, 0.0)] polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft)
def processAlgorithm(self, parameters, context, feedback): layerA = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Difference.INPUT), context) layerB = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Difference.OVERLAY), context) geomType = QgsWkbTypes.multiType(layerA.wkbType()) writer = self.getOutputFromName( Difference.OUTPUT).getVectorWriter(layerA.fields(), geomType, layerA.crs(), context) outFeat = QgsFeature() index = QgsProcessingUtils.createSpatialIndex(layerB, context) selectionA = QgsProcessingUtils.getFeatures(layerA, context) total = 100.0 / layerA.featureCount() if layerA.featureCount() else 0 for current, inFeatA in enumerate(selectionA): geom = inFeatA.geometry() diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(intersections).setSubsetOfAttributes([]) for inFeatB in layerB.getFeatures(request): tmpGeom = inFeatB.geometry() if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat, QgsFeatureSink.FastInsert) except: QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'), self.tr('Processing'), QgsMessageLog.WARNING) continue feedback.setProgress(int(current * total)) del writer
def test_snappointstogrid(self): """Check that this runs correctly""" polygon_layer = self._make_layer('Polygon') f1 = QgsFeature(polygon_layer.fields()) f1.setAttributes([1]) f1.setGeometry(QgsGeometry.fromWkt('POLYGON((1.2 1.2, 1.2 2.2, 2.2 2.2, 2.2 1.2, 1.2 1.2))')) f2 = QgsFeature(polygon_layer.fields()) f2.setAttributes([2]) f2.setGeometry(QgsGeometry.fromWkt('POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))')) self.assertTrue(f2.isValid()) self.assertTrue(polygon_layer.startEditing()) self.assertTrue(polygon_layer.addFeatures([f1, f2])) self.assertEqual(polygon_layer.featureCount(), 2) polygon_layer.commitChanges() self.assertEqual(polygon_layer.featureCount(), 2) QgsProject.instance().addMapLayers([polygon_layer]) polygon_layer.selectByIds([next(polygon_layer.getFeatures()).id()]) self.assertEqual(polygon_layer.selectedFeatureCount(), 1) old_features, new_features = self._alg_tester( 'native:snappointstogrid', polygon_layer, { 'HSPACING': 0.5, 'VSPACING': 0.5, } ) g = [f.geometry() for f in new_features][0] self.assertEqual(g.asWkt(), 'Polygon ((1 1, 1 2, 2 2, 2 1, 1 1))') # Check selected self.assertEqual(polygon_layer.selectedFeatureIds(), [1])
def linearMatrix(self, writer, provider1, provider2, index1, index2, nearest, distArea, matType, sindex, progressBar): inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() start = 15.00 add = 85.00 / provider1.featureCount() fit1 = provider1.getFeatures() while fit1.nextFeature(inFeat): inGeom = inFeat.geometry() inID = inFeat.attributes()[index1] featList = sindex.nearestNeighbor(inGeom.asPoint(), nearest) distList = [] vari = 0.00 for i in featList: provider2.getFeatures(QgsFeatureRequest().setFilterFid(int(i)).setSubsetOfAttributes([index2])).nextFeature(outFeat) outID = outFeat.attributes()[index2] outGeom = outFeat.geometry() dist = distArea.measureLine(inGeom.asPoint(), outGeom.asPoint()) if dist > 0: if matType == "Linear": writer.writerow([unicode(inID), unicode(outID), unicode(dist)]) else: distList.append(float(dist)) if matType == "Summary": mean = sum(distList) / len(distList) for i in distList: vari = vari + ((i - mean) * (i - mean)) vari = sqrt(vari / len(distList)) writer.writerow([unicode(inID), unicode(mean), unicode(vari), unicode(min(distList)), unicode(max(distList))]) start = start + add progressBar.setValue(start) del writer
def getSource(self): # create temporary table for edit tests self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.edit_data') self.execSQLCommand( """CREATE TABLE qgis_test.edit_data (pk INTEGER PRIMARY KEY,cnt integer, name nvarchar(max), name2 nvarchar(max), num_char nvarchar(max), geom geometry)""") vl = QgsVectorLayer( self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POINT table="qgis_test"."edit_data" (geom) sql=', 'test', 'mssql') self.assertTrue(vl.isValid(), vl.dataProvider().error().message()) f1 = QgsFeature() f1.setAttributes([5, -200, NULL, 'NuLl', '5']) f1.setGeometry(QgsGeometry.fromWkt('Point (-71.123 78.23)')) f2 = QgsFeature() f2.setAttributes([3, 300, 'Pear', 'PEaR', '3']) f3 = QgsFeature() f3.setAttributes([1, 100, 'Orange', 'oranGe', '1']) f3.setGeometry(QgsGeometry.fromWkt('Point (-70.332 66.33)')) f4 = QgsFeature() f4.setAttributes([2, 200, 'Apple', 'Apple', '2']) f4.setGeometry(QgsGeometry.fromWkt('Point (-68.2 70.8)')) f5 = QgsFeature() f5.setAttributes([4, 400, 'Honey', 'Honey', '4']) f5.setGeometry(QgsGeometry.fromWkt('Point (-65.32 78.3)')) self.assertTrue(vl.dataProvider().addFeatures([f1, f2, f3, f4, f5])) return vl
def testWFSPointsMultipleEdits(self): """ Adds some points, then check. Modify 2 points, then checks and clear all """ layer_name = 'test_point' layer = self._getLayer(layer_name) wfs_layer = self._getWFSLayer(layer_name) feat1 = QgsFeature(wfs_layer.pendingFields()) feat1['id'] = 11 feat1['name'] = 'name 11' feat1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(9, 45))) feat2 = QgsFeature(wfs_layer.pendingFields()) feat2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(9.5, 45.5))) feat2['id'] = 12 feat2['name'] = 'name 12' old_features = [feat1, feat2] # Change feat1 and feat2 new_feat1 = QgsFeature(wfs_layer.pendingFields()) new_feat1['id'] = 121 new_feat1['name'] = 'name 121' new_feat1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 46))) new_feat2 = QgsFeature(wfs_layer.pendingFields()) new_feat2['id'] = 122 new_feat2['name'] = 'name 122' new_feat2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10.5, 47))) new_features = [new_feat1, new_feat2] self._testLayer(wfs_layer, layer, old_features, new_features)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields().toList(), QGis.WKBPoint, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, input_feature in enumerate(features): output_feature = input_feature if input_feature.constGeometry(): input_geometry = QgsGeometry(input_feature.geometry()) output_geometry = input_geometry.pointOnSurface() if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating point on surface')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) progress.setPercentage(int(current * total)) del writer
def createLayer(cls): vl = QgsVectorLayer( 'Point?crs=epsg:4326&field=pk:integer&field=cnt:integer&field=name:string(0)&field=name2:string(0)&field=num_char:string&key=pk', 'test', 'pythonprovider') assert (vl.isValid()) f1 = QgsFeature() f1.setAttributes([5, -200, NULL, 'NuLl', '5']) f1.setGeometry(QgsGeometry.fromWkt('Point (-71.123 78.23)')) f2 = QgsFeature() f2.setAttributes([3, 300, 'Pear', 'PEaR', '3']) f3 = QgsFeature() f3.setAttributes([1, 100, 'Orange', 'oranGe', '1']) f3.setGeometry(QgsGeometry.fromWkt('Point (-70.332 66.33)')) f4 = QgsFeature() f4.setAttributes([2, 200, 'Apple', 'Apple', '2']) f4.setGeometry(QgsGeometry.fromWkt('Point (-68.2 70.8)')) f5 = QgsFeature() f5.setAttributes([4, 400, 'Honey', 'Honey', '4']) f5.setGeometry(QgsGeometry.fromWkt('Point (-65.32 78.3)')) vl.dataProvider().addFeatures([f1, f2, f3, f4, f5]) return vl
def testNoSliverPolygons(self): # create a layer with some polygons that will be used as a source for "avoid intersections" l = QgsVectorLayer('MultiPolygon', 'test_layer', 'memory') assert l.isValid() QgsProject.instance().addMapLayer(l) QgsProject.instance().writeEntry("Digitizing", "/AvoidIntersectionsList", [l.id()]) features = [] for i, wkt in enumerate(feat_wkt): f = QgsFeature(i + 1) f.setGeometry(QgsGeometry.fromWkt(wkt)) features.append(f) l.dataProvider().addFeatures(features) assert l.pendingFeatureCount() == 7 # create a geometry and remove its intersections with other geometries g = QgsGeometry.fromWkt(newg_wkt) assert g.avoidIntersections() == 0 # the resulting multi-polygon must have exactly three parts # (in QGIS 2.0 it has one more tiny part that appears at the border between two of the original polygons) mpg = g.asMultiPolygon() assert len(mpg) == 3
def loopThruPolygons(self, inLayer, numRand, design): sProvider = inLayer.dataProvider() sFeat = QgsFeature() sGeom = QgsGeometry() sPoints = [] if design == self.tr("field"): index = sProvider.fieldNameIndex(numRand) count = 10.00 add = 60.00 / sProvider.featureCount() sFit = sProvider.getFeatures() featureErrors = [] while sFit.nextFeature(sFeat): sGeom = sFeat.geometry() if design == self.tr("density"): sDistArea = QgsDistanceArea() value = int(round(numRand * sDistArea.measure(sGeom))) elif design == self.tr("field"): sAtMap = sFeat.attributes() try: value = int(sAtMap[index]) except (ValueError,TypeError): featureErrors.append(sFeat) continue else: value = numRand sExt = sGeom.boundingBox() sPoints.extend(self.simpleRandom(value, sGeom, sExt.xMinimum(), sExt.xMaximum(), sExt.yMinimum(), sExt.yMaximum())) count = count + add self.progressBar.setValue(count) return sPoints, featureErrors
def setUpClass(cls): """Run before all tests""" # Register the provider r = QgsProviderRegistry.instance() metadata = QgsProviderMetadata(PyProvider.providerKey(), PyProvider.description(), PyProvider.createProvider) assert r.registerProvider(metadata) assert r.providerMetadata(PyProvider.providerKey()) == metadata # Create test layer cls.vl = cls.createLayer() assert (cls.vl.isValid()) cls.source = cls.vl.dataProvider() # poly layer cls.poly_vl = QgsVectorLayer('Polygon?crs=epsg:4326&field=pk:integer&key=pk', 'test', 'pythonprovider') assert (cls.poly_vl.isValid()) cls.poly_provider = cls.poly_vl.dataProvider() f1 = QgsFeature() f1.setAttributes([1]) f1.setGeometry(QgsGeometry.fromWkt('Polygon ((-69.03664108 81.35818902, -69.09237722 80.24346619, -73.718477 80.1319939, -73.718477 76.28620011, -74.88893598 76.34193625, -74.83319983 81.35818902, -69.03664108 81.35818902))')) f2 = QgsFeature() f2.setAttributes([2]) f2.setGeometry(QgsGeometry.fromWkt('Polygon ((-67.58750139 81.1909806, -66.30557012 81.24671674, -66.30557012 76.89929767, -67.58750139 76.89929767, -67.58750139 81.1909806))')) f3 = QgsFeature() f3.setAttributes([3]) f3.setGeometry(QgsGeometry.fromWkt('Polygon ((-68.36780737 75.78457483, -67.53176524 72.60761475, -68.64648808 73.66660144, -70.20710006 72.9420316, -68.36780737 75.78457483))')) f4 = QgsFeature() f4.setAttributes([4]) cls.poly_provider.addFeatures([f1, f2, f3, f4])
def testAddMultipleFeatures(self): # test adding multiple features to an edit buffer layer = createEmptyLayer() self.assertTrue(layer.startEditing()) self.assertEqual(layer.editBuffer().addedFeatures(), {}) self.assertFalse(layer.editBuffer().isFeatureAdded(1)) self.assertFalse(layer.editBuffer().isFeatureAdded(3)) # add two features f1 = QgsFeature(layer.fields(), 1) f1.setGeometry(QgsGeometry.fromPoint(QgsPointXY(1, 2))) f1.setAttributes(["test", 123]) f2 = QgsFeature(layer.fields(), 2) f2.setGeometry(QgsGeometry.fromPoint(QgsPointXY(2, 4))) f2.setAttributes(["test2", 246]) self.assertTrue(layer.addFeatures([f1, f2])) # test contents of buffer added = layer.editBuffer().addedFeatures() new_feature_ids = list(added.keys()) self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2') self.assertEqual(added[new_feature_ids[0]]['fldint'], 246) self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test') self.assertEqual(added[new_feature_ids[1]]['fldint'], 123) self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0])) self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))
def testDeleteMultipleFeatures(self): # test deleting multiple features from an edit buffer # make a layer with two features layer = createEmptyLayer() self.assertTrue(layer.startEditing()) # add two features f1 = QgsFeature(layer.fields(), 1) f1.setGeometry(QgsGeometry.fromPoint(QgsPointXY(1, 2))) f1.setAttributes(["test", 123]) self.assertTrue(layer.addFeature(f1)) f2 = QgsFeature(layer.fields(), 2) f2.setGeometry(QgsGeometry.fromPoint(QgsPointXY(2, 4))) f2.setAttributes(["test2", 246]) self.assertTrue(layer.addFeature(f2)) layer.commitChanges() layer.startEditing() self.assertEqual(layer.editBuffer().deletedFeatureIds(), []) self.assertFalse(layer.editBuffer().isFeatureDeleted(1)) self.assertFalse(layer.editBuffer().isFeatureDeleted(2)) # delete features layer.deleteFeatures([1, 2]) # test contents of buffer self.assertEqual(set(layer.editBuffer().deletedFeatureIds()), set([1, 2])) self.assertTrue(layer.editBuffer().isFeatureDeleted(1)) self.assertTrue(layer.editBuffer().isFeatureDeleted(2))
def testChangeGeometries(self): if not getattr(self, 'getEditableLayer', None): return l = self.getEditableLayer() self.assertTrue(l.isValid()) # find 2 features to change features = [f for f in l.dataProvider().getFeatures()] to_change = [f for f in features if f.attributes()[0] == 1] to_change.extend([f for f in features if f.attributes()[0] == 3]) # changes by feature id, for changeGeometryValues call changes = {to_change[0].id(): QgsGeometry.fromWkt('Point (10 20)'), to_change[1].id(): QgsGeometry()} # changes by pk, for testing after retrieving changed features new_geom_map = {1: QgsGeometry.fromWkt('Point ( 10 20 )'), 3: QgsGeometry()} if l.dataProvider().capabilities() & QgsVectorDataProvider.ChangeGeometries: # expect success result = l.dataProvider().changeGeometryValues(changes) self.assertTrue(result, 'Provider reported ChangeGeometries capability, but returned False to changeGeometryValues') # check result self.testGetFeatures(l.dataProvider(), changed_geometries=new_geom_map) # change empty list, should return true for consistency self.assertTrue(l.dataProvider().changeGeometryValues({})) else: # expect fail self.assertFalse(l.dataProvider().changeGeometryValues(changes), 'Provider reported no ChangeGeometries capability, but returned true to changeGeometryValues')
def testProxyFeatureSink(self): fields = QgsFields() fields.append(QgsField('fldtxt', QVariant.String)) fields.append(QgsField('fldint', QVariant.Int)) store = QgsFeatureStore(fields, QgsCoordinateReferenceSystem()) proxy = QgsProxyFeatureSink(store) self.assertEqual(proxy.destinationSink(), store) self.assertEqual(len(store), 0) f = QgsFeature() f.setAttributes(["test", 123]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) proxy.addFeature(f) self.assertEqual(len(store), 1) self.assertEqual(store.features()[0]['fldtxt'], 'test') f2 = QgsFeature() f2.setAttributes(["test2", 457]) f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(200, 200))) f3 = QgsFeature() f3.setAttributes(["test3", 888]) f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(300, 200))) proxy.addFeatures([f2, f3]) self.assertEqual(len(store), 3) self.assertEqual(store.features()[1]['fldtxt'], 'test2') self.assertEqual(store.features()[2]['fldtxt'], 'test3')
def layerOmmb(self, layer, writer, progress): current = 0 fit = layer.getFeatures() inFeat = QgsFeature() total = 100.0 / layer.featureCount() newgeometry = QgsGeometry() first = True while fit.nextFeature(inFeat): if first: newgeometry = inFeat.geometry() first = False else: newgeometry = newgeometry.combine(inFeat.geometry()) current += 1 progress.setPercentage(int(current * total)) geometry, area, perim, angle, width, height = self.OMBBox(newgeometry) if geometry: outFeat = QgsFeature() outFeat.setGeometry(geometry) outFeat.setAttributes([area, perim, angle, width, height]) writer.addFeature(outFeat)
def processAlgorithm(self, parameters, context, feedback): spacing = self.parameterAsDouble(parameters, self.SPACING, context) inset = self.parameterAsDouble(parameters, self.INSET, context) randomize = self.parameterAsBool(parameters, self.RANDOMIZE, context) isSpacing = self.parameterAsBool(parameters, self.IS_SPACING, context) crs = self.parameterAsCrs(parameters, self.CRS, context) extent = self.parameterAsExtent(parameters, self.EXTENT, context, crs) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, crs) if sink is None: raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) if randomize: seed() area = extent.width() * extent.height() if isSpacing: pSpacing = spacing else: pSpacing = sqrt(area / spacing) f = QgsFeature() f.initAttributes(1) f.setFields(fields) count = 0 total = 100.0 / (area / pSpacing) y = extent.yMaximum() - inset extent_geom = QgsGeometry.fromRect(extent) extent_engine = QgsGeometry.createGeometryEngine(extent_geom.constGet()) extent_engine.prepareGeometry() while y >= extent.yMinimum(): x = extent.xMinimum() + inset while x <= extent.xMaximum(): if feedback.isCanceled(): break if randomize: geom = QgsGeometry().fromPointXY(QgsPointXY( uniform(x - (pSpacing / 2.0), x + (pSpacing / 2.0)), uniform(y - (pSpacing / 2.0), y + (pSpacing / 2.0)))) else: geom = QgsGeometry().fromPointXY(QgsPointXY(x, y)) if extent_engine.intersects(geom.constGet()): f.setAttribute('id', count) f.setGeometry(geom) sink.addFeature(f, QgsFeatureSink.FastInsert) x += pSpacing count += 1 feedback.setProgress(int(count * total)) y = y - pSpacing return {self.OUTPUT: dest_id}
def testPartNum(self): # test geometry_part_num variable s = QgsLineSymbol() s.deleteSymbolLayer(0) sym_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'segments_to_lines($geometry)'}) sym_layer.setSymbolType(QgsSymbol.Line) s.appendSymbolLayer(sym_layer) marker_line = QgsMarkerLineSymbolLayer(False) marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex) f = QgsFontUtils.getStandardTestFont('Bold', 24) marker = QgsFontMarkerSymbolLayer(f.family(), 'x', 24, QColor(255, 255, 0)) marker.setDataDefinedProperty(QgsSymbolLayer.PropertyCharacter, QgsProperty.fromExpression('@geometry_part_num')) marker_symbol = QgsMarkerSymbol() marker_symbol.changeSymbolLayer(0, marker) marker_line.setSubSymbol(marker_symbol) marker_line.setAverageAngleLength(0) line_symbol = QgsLineSymbol() line_symbol.changeSymbolLayer(0, marker_line) sym_layer.setSubSymbol(line_symbol) # rendering test g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') rendered_image = self.renderGeometry(s, g, buffer=4) assert self.imageCheck('part_num_variable', 'part_num_variable', rendered_image) marker.setDataDefinedProperty(QgsSymbolLayer.PropertyCharacter, QgsProperty.fromExpression('@geometry_part_count')) # rendering test g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)') rendered_image = self.renderGeometry(s, g, buffer=4) assert self.imageCheck('part_count_variable', 'part_count_variable', rendered_image)
def union_geometry(vector, request=QgsFeatureRequest()): """Return union of the vector geometries regardless of the attributes. (If request is specified, filter the objects before union). If all geometries in the vector are invalid, return None. The boundaries will be dissolved during the operation. :param vector: Vector layer :type vector: QgsVectorLayer :param request: Filter for vector objects :type request: QgsFeatureRequest :return: Union of the geometry :rtype: QgsGeometry or None """ result_geometry = None for feature in vector.getFeatures(request): if result_geometry is None: result_geometry = QgsGeometry(feature.geometry()) else: # But some feature.geometry() may be invalid, skip them tmp_geometry = result_geometry.combine(feature.geometry()) try: if tmp_geometry.isGeosValid(): result_geometry = tmp_geometry except AttributeError: pass return result_geometry
def densifyGeometry(self, geometry, pointsNumber, isPolygon): output = [] if isPolygon: if geometry.isMultipart(): polygons = geometry.asMultiPolygon() for poly in polygons: p = [] for ring in poly: p.append(self.densify(ring, pointsNumber)) output.append(p) return QgsGeometry.fromMultiPolygon(output) else: rings = geometry.asPolygon() for ring in rings: output.append(self.densify(ring, pointsNumber)) return QgsGeometry.fromPolygon(output) else: if geometry.isMultipart(): lines = geometry.asMultiPolyline() for points in lines: output.append(self.densify(points, pointsNumber)) return QgsGeometry.fromMultiPolyline(output) else: points = geometry.asPolyline() output = self.densify(points, pointsNumber) return QgsGeometry.fromPolyline(output)
def regularMatrix(self, writer, provider1, provider2, index1, index2, nearest, distArea, sindex, progressBar): inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() first = True start = 15.00 add = 85.00 / provider1.featureCount() fit1 = provider1.getFeatures() while fit1.nextFeature(inFeat): inGeom = inFeat.geometry() inID = inFeat.attributes()[index1] if first: featList = sindex.nearestNeighbor(inGeom.asPoint(), nearest) first = False data = ["ID"] for i in featList: provider2.getFeatures(QgsFeatureRequest().setFilterFid(int(i)).setSubsetOfAttributes([index2])).nextFeature(outFeat) data.append(unicode(outFeat.attributes()[index2])) writer.writerow(data) data = [unicode(inID)] for j in featList: provider2.getFeatures(QgsFeatureRequest().setFilterFid(int(j))).nextFeature(outFeat) outGeom = outFeat.geometry() dist = distArea.measureLine(inGeom.asPoint(), outGeom.asPoint()) data.append(unicode(float(dist))) writer.writerow(data) start = start + add progressBar.setValue(start) del writer
def testInsertPolygonInMultiPolygon(self): layer = QgsVectorLayer("MultiPolygon?crs=epsg:4326&field=id:integer", "addfeat", "memory") pr = layer.dataProvider() f = QgsFeature() f.setAttributes([1]) f.setGeometry(QgsGeometry.fromWkt('MultiPolygon(((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))')) pr.addFeatures([f]) uri = '{} table="qgis_test"."new_table_multipolygon" sql='.format(self.dbconn) error, message = QgsVectorLayerExporter.exportLayer(layer, uri, 'mssql', QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(error, QgsVectorLayerExporter.NoError) new_layer = QgsVectorLayer(uri, 'new', 'mssql') self.assertTrue(new_layer.isValid()) self.assertEqual(new_layer.wkbType(), QgsWkbTypes.MultiPolygon) geom = [f.geometry().asWkt() for f in new_layer.getFeatures()] self.assertEqual(geom, ['MultiPolygon (((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))']) # add single part f2 = QgsFeature() f2.setAttributes([2]) f2.setGeometry(QgsGeometry.fromWkt('Polygon((30 0, 31 0, 31 1, 30 1, 30 0))')) self.assertTrue(new_layer.dataProvider().addFeatures([f2])) # should become multipart geom = [f.geometry().asWkt() for f in new_layer.getFeatures()] self.assertEqual(geom, ['MultiPolygon (((0 0, 1 0, 1 1, 0 1, 0 0)),((10 0, 11 0, 11 1, 10 1, 10 0)))', 'MultiPolygon (((30 0, 31 0, 31 1, 30 1, 30 0)))'])