Ejemplo n.º 1
1
    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))'])
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
    def testReplaceLayerWhileOpen(self):
        ''' Replace an existing geopackage layer whilst it's open in the project'''
        tmpfile = os.path.join(self.basetestpath, 'testGeopackageReplaceOpenLayer.gpkg')
        ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('layer1', geom_type=ogr.wkbPoint)
        lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTInteger))
        lyr.CreateField(ogr.FieldDefn('attr2', ogr.OFTInteger))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 0)'))
        lyr.CreateFeature(f)
        f = None

        vl1 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1", u'layer1', u'ogr')
        p = QgsProject()
        p.addMapLayer(vl1)
        request = QgsFeatureRequest().setSubsetOfAttributes([0])
        features = [f for f in vl1.getFeatures(request)]
        self.assertEqual(len(features), 1)

        # now, overwrite the layer with a different geometry type and fields
        ds.DeleteLayer('layer1')
        lyr = ds.CreateLayer('layer1', geom_type=ogr.wkbLineString)
        lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTString))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('LineString(0 0, 1 1)'))
        lyr.CreateFeature(f)
        f = None
        vl2 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1", u'layer2', u'ogr')
        p.addMapLayer(vl2)

        features = [f for f in vl1.getFeatures(request)]
        self.assertEqual(len(features), 1)
Ejemplo n.º 4
0
    def testGeopackageLargeFID(self):

        tmpfile = os.path.join(self.basetestpath, 'testGeopackageLargeFID.gpkg')
        ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint)
        lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString))
        ds = None

        vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
        f = QgsFeature()
        f.setAttributes([1234567890123, None])
        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.dataProvider().addFeatures([f]))
        self.assertTrue(vl.commitChanges())

        got = [feat for feat in vl.getFeatures()][0]
        self.assertEqual(got['fid'], 1234567890123)

        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.changeGeometry(1234567890123, QgsGeometry.fromWkt('Point (3 50)')))
        self.assertTrue(vl.changeAttributeValue(1234567890123, 1, 'foo'))
        self.assertTrue(vl.commitChanges())

        got = [feat for feat in vl.getFeatures()][0]
        self.assertEqual(got['str_field'], 'foo')
        got_geom = got.geometry()
        self.assertIsNotNone(got_geom)

        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.deleteFeature(1234567890123))
        self.assertTrue(vl.commitChanges())
Ejemplo n.º 5
0
    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)'])
Ejemplo n.º 6
0
    def test_clip_by_polygon(self):
        """Test clip_by_polygon work"""
        line_before = QgsVectorLayer(
            self.line_before + '.shp', 'test', 'ogr')
        lines = QgsVectorLayer(
            self.line_after + '.shp', 'test', 'ogr')
        polygon_layer = QgsVectorLayer(
            self.polygon_base + '.shp', 'test', 'ogr')

        # Only one polygon is stored in the layer
        for feature in polygon_layer.getFeatures():
            polygon = feature.geometry()

        clipped_lines = clip_by_polygon(
            line_before,
            polygon)

        # Test the lines is not multipart
        for feature in clipped_lines.getFeatures():
            self.assertFalse(feature.geometry().isMultipart())

        # Lines with flooded=1 lie within the polygon
        for feature in clipped_lines.getFeatures():
            found = False
            for expected in lines.getFeatures():
                if (expected.attributes()[2] == 1) and \
                   (feature.geometry().isGeosEqual(expected.geometry())):
                    found = True
                    break
            self.assertTrue(found)
Ejemplo n.º 7
0
    def test_ExpressionFieldEllipsoidLengthCalculation(self):
        #create a temporary layer
        temp_layer = QgsVectorLayer("LineString?crs=epsg:3111&field=pk:int", "vl", "memory")
        self.assertTrue(temp_layer.isValid())
        f1 = QgsFeature(temp_layer.dataProvider().fields(), 1)
        f1.setAttribute("pk", 1)
        f1.setGeometry(QgsGeometry.fromPolyline([QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853)]))
        temp_layer.dataProvider().addFeatures([f1])

        # set project CRS and ellipsoid
        srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId)
        QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4())
        QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid())
        QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid())
        QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84")
        QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Meters))

        idx = temp_layer.addExpressionField('$length', QgsField('length', QVariant.Double))  # NOQA

        # check value
        f = temp_layer.getFeatures().next()
        expected = 26932.156
        self.assertAlmostEqual(f['length'], expected, 3)

        # change project length unit, check calculation respects unit
        QgsProject.instance().writeEntry("Measurement", "/DistanceUnits", QgsUnitTypes.encodeUnit(QGis.Feet))
        f = temp_layer.getFeatures().next()
        expected = 88360.0918635
        self.assertAlmostEqual(f['length'], expected, 3)
Ejemplo n.º 8
0
    def test_SplitFeature(self):
        """Test sqlite feature can be split"""
        tmpfile = os.path.join(self.basetestpath, 'testGeopackageSplitFeatures.sqlite')
        ds = ogr.GetDriverByName('SQlite').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbPolygon)
        lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON ((0 0,0 1,1 1,1 0,0 0))'))
        lyr.CreateFeature(f)
        f = None
        ds = None

        layer = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')

        # Check that pk field has unique constraint
        fields = layer.fields()
        pkfield = fields.at(0)
        self.assertTrue(pkfield.constraints().constraints() & QgsFieldConstraints.ConstraintUnique)

        self.assertTrue(layer.isValid())
        self.assertTrue(layer.isSpatial())
        self.assertEqual([f for f in layer.getFeatures()][0].geometry().asWkt(), 'Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))')
        layer.startEditing()
        self.assertEqual(layer.splitFeatures([QgsPointXY(0.5, 0), QgsPointXY(0.5, 1)], 0), 0)
        self.assertTrue(layer.commitChanges())
        self.assertEqual(layer.featureCount(), 2)

        layer = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual([f for f in layer.getFeatures()][0].geometry().asWkt(), 'Polygon ((0.5 0, 0.5 1, 1 1, 1 0, 0.5 0))')
        self.assertEqual([f for f in layer.getFeatures()][1].geometry().asWkt(), 'Polygon ((0.5 1, 0.5 0, 0 0, 0 1, 0.5 1))')
Ejemplo n.º 9
0
    def test_ExpressionFieldEllipsoidAreaCalculation(self):
        #create a temporary layer
        temp_layer = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory")
        self.assertTrue(temp_layer.isValid())
        f1 = QgsFeature(temp_layer.dataProvider().fields(), 1)
        f1.setAttribute("pk", 1)
        f1.setGeometry(QgsGeometry.fromPolygon([[QgsPoint(2484588, 2425722), QgsPoint(2482767, 2398853), QgsPoint(2520109, 2397715), QgsPoint(2520792, 2425494), QgsPoint(2484588, 2425722)]]))
        temp_layer.dataProvider().addFeatures([f1])

        # set project CRS and ellipsoid
        srs = QgsCoordinateReferenceSystem(3111, QgsCoordinateReferenceSystem.EpsgCrsId)
        QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSProj4String", srs.toProj4())
        QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCRSID", srs.srsid())
        QgsProject.instance().writeEntry("SpatialRefSys", "/ProjectCrs", srs.authid())
        QgsProject.instance().writeEntry("Measure", "/Ellipsoid", "WGS84")
        QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMeters))

        idx = temp_layer.addExpressionField('$area', QgsField('area', QVariant.Double))  # NOQA

        # check value
        f = temp_layer.getFeatures().next()
        expected = 1009089817.0
        self.assertAlmostEqual(f['area'], expected, delta=1.0)

        # change project area unit, check calculation respects unit
        QgsProject.instance().writeEntry("Measurement", "/AreaUnits", QgsUnitTypes.encodeUnit(QgsUnitTypes.SquareMiles))
        f = temp_layer.getFeatures().next()
        expected = 389.6117565069
        self.assertAlmostEqual(f['area'], expected, 3)
Ejemplo n.º 10
0
    def testRenameAttributes(self):
        layer = QgsVectorLayer("Point", "test", "memory")
        provider = layer.dataProvider()

        res = provider.addAttributes(
            [QgsField("name", QVariant.String), QgsField("age", QVariant.Int), QgsField("size", QVariant.Double)]
        )
        layer.updateFields()
        assert res, "Failed to add attributes"
        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
        ft.setAttributes(["Johny", 20, 0.3])
        res, t = provider.addFeatures([ft])

        # bad rename
        self.assertFalse(provider.renameAttributes({-1: "not_a_field"}))
        self.assertFalse(provider.renameAttributes({100: "not_a_field"}))
        # already exists
        self.assertFalse(provider.renameAttributes({1: "name"}))

        # rename one field
        self.assertTrue(provider.renameAttributes({1: "this_is_the_new_age"}))
        self.assertEqual(provider.fields().at(1).name(), "this_is_the_new_age")
        layer.updateFields()
        fet = next(layer.getFeatures())
        self.assertEqual(fet.fields()[1].name(), "this_is_the_new_age")

        # rename two fields
        self.assertTrue(provider.renameAttributes({1: "mapinfo_is_the_stone_age", 2: "super_size"}))
        self.assertEqual(provider.fields().at(1).name(), "mapinfo_is_the_stone_age")
        self.assertEqual(provider.fields().at(2).name(), "super_size")
        layer.updateFields()
        fet = next(layer.getFeatures())
        self.assertEqual(fet.fields()[1].name(), "mapinfo_is_the_stone_age")
        self.assertEqual(fet.fields()[2].name(), "super_size")
Ejemplo n.º 11
0
    def testGetFeaturesUniqueId(self):
        """
        Test tables with inheritance for unique ids
        """
        def test_unique(features, num_features):
            featureids = []
            for f in features:
                self.assertFalse(f.id() in featureids)
                featureids.append(f.id())
            self.assertEqual(len(features), num_features)

        vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (self.dbconn, 'someData'), "testgeom", "postgres")
        self.assertTrue(vl.isValid())
        # Test someData
        test_unique([f for f in vl.getFeatures()], 5)

        # Test base_table_bad: layer is invalid
        vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_bad'), "testgeom", "postgres")
        self.assertFalse(vl.isValid())
        # Test base_table_bad with use estimated metadata: layer is valid because the unique test is skipped
        vl = QgsVectorLayer('%s srid=4326 estimatedmetadata="true" table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_bad'), "testgeom", "postgres")
        self.assertTrue(vl.isValid())

        # Test base_table_good: layer is valid
        vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_good'), "testgeom", "postgres")
        self.assertTrue(vl.isValid())
        test_unique([f for f in vl.getFeatures()], 4)
        # Test base_table_good with use estimated metadata: layer is valid
        vl = QgsVectorLayer('%s srid=4326 estimatedmetadata="true" table="qgis_test".%s (geom) sql=' % (self.dbconn, 'base_table_good'), "testgeom", "postgres")
        self.assertTrue(vl.isValid())
        test_unique([f for f in vl.getFeatures()], 4)
Ejemplo n.º 12
0
    def test_Join(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "points.shp"), "points", "ogr", False)
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "points_relations.shp"), "points_relations", "ogr", False)
        self.assertEqual(l2.isValid(), True)
        QgsProject.instance().addMapLayer(l2)
        ref_sum = sum(f.attributes()[1] for f in l2.getFeatures())

        # use a temporary file
        query = toPercent(
            "select id,Pilots,vtab1.geometry from vtab1,vtab2 where intersects(vtab1.geometry,vtab2.geometry)"
        )
        l3 = QgsVectorLayer(
            "?layer_ref=%s&layer_ref=%s&uid=id&query=%s&geometry=geometry:1:4326" % (l1.id(), l2.id(), query),
            "vtab",
            "virtual",
            False,
        )
        self.assertEqual(l3.isValid(), True)
        self.assertEqual(l3.dataProvider().wkbType(), 1)
        self.assertEqual(l3.dataProvider().fields().count(), 2)
        ref_sum2 = sum(f.id() for f in l3.getFeatures())
        self.assertEqual(ref_sum, ref_sum2)

        QgsProject.instance().removeMapLayer(l1)
        QgsProject.instance().removeMapLayer(l2)
Ejemplo n.º 13
0
    def test_geometry_conversion(self):
        query = QUrl.toPercentEncoding("select geomfromtext('multipoint((0 0),(1 1))') as geom")
        l = QgsVectorLayer("?query=%s&geometry=geom:multipoint:0" % query, "tt", "virtual", False)
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().exportToWkt().lower().startswith("multipoint"), True)
            self.assertEqual("),(" in f.geometry().exportToWkt(), True)  # has two points

        query = QUrl.toPercentEncoding(
            "select geomfromtext('multipolygon(((0 0,1 0,1 1,0 1,0 0)),((0 1,1 1,1 2,0 2,0 1)))') as geom"
        )
        l = QgsVectorLayer("?query=%s&geometry=geom:multipolygon:0" % query, "tt", "virtual", False)
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().exportToWkt().lower().startswith("multipolygon"), True)
            self.assertEqual(")),((" in f.geometry().exportToWkt(), True)  # has two polygons

        query = QUrl.toPercentEncoding(
            "select geomfromtext('multilinestring((0 0,1 0,1 1,0 1,0 0),(0 1,1 1,1 2,0 2,0 1))') as geom"
        )
        l = QgsVectorLayer("?query=%s&geometry=geom:multilinestring:0" % query, "tt", "virtual", False)
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.geometry().exportToWkt().lower().startswith("multilinestring"), True)
            self.assertEqual("),(" in f.geometry().exportToWkt(), True)  # has two linestrings
Ejemplo n.º 14
0
 def testBoolFieldEvaluation(self):
     datasource = os.path.join(unitTestDataPath(), 'bool_geojson.json')
     vl = QgsVectorLayer(datasource, 'test', 'ogr')
     self.assertTrue(vl.isValid())
     self.assertEqual(vl.fields().at(0).name(), 'bool')
     self.assertEqual(vl.fields().at(0).type(), QVariant.Bool)
     self.assertEqual([f[0] for f in vl.getFeatures()], [True, False, NULL])
     self.assertEqual([f[0].__class__.__name__ for f in vl.getFeatures()], ['bool', 'bool', 'QVariant'])
Ejemplo n.º 15
0
    def testSelectSubsetString(self):

        tmpfile = os.path.join(self.basetestpath, 'testSelectSubsetString.gpkg')
        ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbMultiPolygon)
        lyr.CreateField(ogr.FieldDefn('foo', ogr.OFTString))
        f = ogr.Feature(lyr.GetLayerDefn())
        f['foo'] = 'bar'
        lyr.CreateFeature(f)
        f = None
        f = ogr.Feature(lyr.GetLayerDefn())
        f['foo'] = 'baz'
        lyr.CreateFeature(f)
        f = None
        ds = None

        vl = QgsVectorLayer('{}|layerid=0'.format(tmpfile), 'test', 'ogr')
        vl.setSubsetString("SELECT fid, foo FROM test WHERE foo = 'baz'")
        got = [feat for feat in vl.getFeatures()]
        self.assertEqual(len(got), 1)
        del vl

        testdata_path = unitTestDataPath('provider')
        shutil.copy(os.path.join(testdata_path, 'bug_19826.gpkg'), tmpfile)
        vl = QgsVectorLayer('{}|layerid=0'.format(tmpfile, 'test', 'ogr'))
        vl.setSubsetString("name = 'two'")
        got = [feat for feat in vl.getFeatures()]
        self.assertEqual(len(got), 1)

        attributes = got[0].attributes()
        self.assertEqual(got[0].id(), 2)
        self.assertEqual(attributes[0], 2)
        self.assertEqual(attributes[1], 'two')
        self.assertNotEqual(attributes[2], None)

        # Request by FeatureId on a subset layer
        got = [feat for feat in vl.getFeatures(QgsFeatureRequest(2))]
        self.assertEqual(len(got), 1)
        attributes = got[0].attributes()
        self.assertEqual(got[0].id(), 2)
        self.assertEqual(attributes[0], 2)
        self.assertEqual(attributes[1], 'two')
        self.assertNotEqual(attributes[2], None)

        request = QgsFeatureRequest(2).setSubsetOfAttributes([0])
        got = [feat for feat in vl.getFeatures(request)]
        self.assertEqual(len(got), 1)
        attributes = got[0].attributes()
        self.assertEqual(got[0].id(), 2)
        self.assertEqual(attributes[0], 2)
        self.assertEqual(attributes[1], None)
        self.assertEqual(attributes[2], None)

        # Request by FeatureId on a subset layer. The name = 'two' filter
        # only returns FID 2, so requesting on FID 1 should return nothing
        # but this is broken now.
        got = [feat for feat in vl.getFeatures(QgsFeatureRequest(1))]
        self.assertEqual(len(got), 1) # this is the current behavior, broken
Ejemplo n.º 16
0
    def test_split_by_polygon(self):
        """Test split_by_polygon work"""
        line_before = QgsVectorLayer(
            self.line_before + '.shp', 'test', 'ogr')
        expected_lines = QgsVectorLayer(
            self.line_after + '.shp', 'test', 'ogr')
        polygon_layer = QgsVectorLayer(
            self.polygon_base + '.shp', 'test', 'ogr')

        # Only one polygon is stored in the layer
        for feature in polygon_layer.getFeatures():
            polygon = feature.geometry()

        split_lines = split_by_polygon(
            line_before,
            polygon,
            mark_value=('flooded', 1))

        # Test the lines is not multipart
        for feature in split_lines.getFeatures():
            self.assertFalse(feature.geometry().isMultipart())

        self.assertEqual(expected_lines.featureCount(),
                         split_lines.featureCount())
        # Assert for every line from split_lines
        # we can find the same line
        for feature in split_lines.getFeatures():
            found = False
            for expected in expected_lines.getFeatures():
                if (feature.attributes() == expected.attributes()) and \
                   (feature.geometry().isGeosEqual(expected.geometry())):
                    found = True
                    break
            self.assertTrue(found)

        # Split by the extent (The result is the copy of the layer)
        line_before.updateExtents()
        # Expand extent to cover the lines (add epsilon to bounds)
        epsilon = 0.0001    # A small number
        extent = line_before.extent()
        new_extent = QgsRectangle(
            extent.xMinimum() - epsilon,
            extent.yMinimum() - epsilon,
            extent.xMaximum() + epsilon,
            extent.yMaximum() + epsilon
        )
        new_extent = QgsGeometry().fromRect(new_extent)
        split_lines = split_by_polygon(
            line_before,
            new_extent)
        for feature in split_lines.getFeatures():
            found = False
            for expected in line_before.getFeatures():
                if (feature.attributes() == expected.attributes()) and \
                   (feature.geometry().isGeosEqual(expected.geometry())):
                    found = True
                    break
            self.assertTrue(found)
Ejemplo n.º 17
0
 def test_invalid_iterator(self):
     """ Test invalid iterator """
     corrupt_dbname = self.dbname + '.corrupt'
     shutil.copy(self.dbname, corrupt_dbname)
     layer = QgsVectorLayer("dbname=%s table=test_pg (geometry)" % corrupt_dbname, "test_pg", "spatialite")
     # Corrupt the database
     open(corrupt_dbname, 'wb').write(b'')
     layer.getFeatures()
     layer = None
     os.unlink(corrupt_dbname)
Ejemplo n.º 18
0
    def testFieldsWithSpecialCharacters(self):
        ml = QgsVectorLayer("Point?srid=EPSG:4326&field=123:int", "mem_with_nontext_fieldnames", "memory")
        self.assertEqual(ml.isValid(), True)
        QgsProject.instance().addMapLayer(ml)

        ml.startEditing()
        self.assertTrue(ml.addAttribute(QgsField('abc:123', QVariant.String)))
        self.assertTrue(ml.addAttribute(QgsField('map', QVariant.String)))  # matches QGIS expression function name
        f1 = QgsFeature(ml.fields())
        f1.setGeometry(QgsGeometry.fromWkt('POINT(0 0)'))
        f1.setAttributes([1, 'a', 'b'])
        f2 = QgsFeature(ml.fields())
        f2.setGeometry(QgsGeometry.fromWkt('POINT(1 1)'))
        f2.setAttributes([2, 'c', 'd'])
        ml.addFeatures([f1, f2])
        ml.commitChanges()

        vl = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames", "vl", "virtual")
        self.assertEqual(vl.isValid(), True)
        self.assertEqual(vl.fields().at(0).name(), '123')
        self.assertEqual(vl.fields().at(1).name(), 'abc:123')

        self.assertEqual(vl.featureCount(), 2)

        features = [f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression('"abc:123"=\'c\''))]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [2, 'c', 'd'])

        features = [f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression('"map"=\'b\''))]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [1, 'a', 'b'])

        vl2 = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames where \"abc:123\"='c'", "vl", "virtual")
        self.assertEqual(vl2.isValid(), True)
        self.assertEqual(vl2.fields().at(0).name(), '123')
        self.assertEqual(vl2.fields().at(1).name(), 'abc:123')

        self.assertEqual(vl2.featureCount(), 1)

        features = [f for f in vl2.getFeatures()]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [2, 'c', 'd'])

        vl3 = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames where \"map\"='b'", "vl", "virtual")
        self.assertEqual(vl3.isValid(), True)
        self.assertEqual(vl3.fields().at(0).name(), '123')
        self.assertEqual(vl3.fields().at(1).name(), 'abc:123')

        self.assertEqual(vl3.featureCount(), 1)

        features = [f for f in vl3.getFeatures()]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [1, 'a', 'b'])

        QgsProject.instance().removeMapLayer(ml)
Ejemplo n.º 19
0
    def testSimulatedDBManagerImport(self):
        uri = 'point?field=f1:int'
        uri += '&field=f2:double(6,4)'
        uri += '&field=f3:string(20)'
        lyr = QgsVectorLayer(uri, "x", "memory")
        self.assertTrue(lyr.isValid())
        f = QgsFeature(lyr.fields())
        f['f1'] = 1
        f['f2'] = 123.456
        f['f3'] = '12345678.90123456789'
        f2 = QgsFeature(lyr.fields())
        f2['f1'] = 2
        lyr.dataProvider().addFeatures([f, f2])

        tmpfile = os.path.join(self.basetestpath, 'testSimulatedDBManagerImport.gpkg')
        ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
        ds = None
        options = {}
        options['update'] = True
        options['driverName'] = 'GPKG'
        options['layerName'] = 'my_out_table'
        err = QgsVectorLayerExporter.exportLayer(lyr, tmpfile, "ogr", lyr.crs(), False, options)
        self.assertEqual(err[0], QgsVectorLayerExporter.NoError,
                         'unexpected import error {0}'.format(err))
        lyr = QgsVectorLayer(tmpfile + "|layername=my_out_table", "y", "ogr")
        self.assertTrue(lyr.isValid())
        features = lyr.getFeatures()
        f = next(features)
        self.assertEqual(f['f1'], 1)
        self.assertEqual(f['f2'], 123.456)
        self.assertEqual(f['f3'], '12345678.90123456789')
        f = next(features)
        self.assertEqual(f['f1'], 2)
        features = None

        # Test overwriting without overwrite option
        err = QgsVectorLayerExporter.exportLayer(lyr, tmpfile, "ogr", lyr.crs(), False, options)
        self.assertEqual(err[0], QgsVectorLayerExporter.ErrCreateDataSource)

        # Test overwriting
        lyr = QgsVectorLayer(uri, "x", "memory")
        self.assertTrue(lyr.isValid())
        f = QgsFeature(lyr.fields())
        f['f1'] = 3
        lyr.dataProvider().addFeatures([f])
        options['overwrite'] = True
        err = QgsVectorLayerExporter.exportLayer(lyr, tmpfile, "ogr", lyr.crs(), False, options)
        self.assertEqual(err[0], QgsVectorLayerExporter.NoError,
                         'unexpected import error {0}'.format(err))
        lyr = QgsVectorLayer(tmpfile + "|layername=my_out_table", "y", "ogr")
        self.assertTrue(lyr.isValid())
        features = lyr.getFeatures()
        f = next(features)
        self.assertEqual(f['f1'], 3)
        features = None
    def test_refLayer(self):
        l1 = QgsVectorLayer( os.path.join(self.testDataDir_, "test.csv") + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual( l1.isValid(), True )
        QgsMapLayerRegistry.instance().addMapLayer(l1)

        l2 = QgsVectorLayer( "?layer_ref=" + l1.id(), "vtab", "virtual", False )
        self.assertEqual(l2.isValid(), True)
        print sum([f.id() for f in l2.getFeatures()])

        # now delete the layer
        QgsMapLayerRegistry.instance().removeMapLayer( l1.id() )
        # check that it does not crash
        print sum([f.id() for f in l2.getFeatures()])
    def test_encoding( self ):
        # changes encoding on a shapefile (the only provider supporting setEncoding)
        source = QUrl.toPercentEncoding(os.path.join(self.testDataDir_, "france_parts.shp"))
        l = QgsVectorLayer("?layer=ogr:%s:fp:latin1" % source, "vtab", "virtual", False)
        self.assertEqual( l.isValid(), True )

        for f in l.getFeatures():
            self.assertEqual(f.attributes()[8], u"Région")

        # use UTF-8 now
        l = QgsVectorLayer("?layer=ogr:%s:fp:UTF-8" % source, "vtab", "virtual", False)
        self.assertEqual( l.isValid(), True )
        for f in l.getFeatures():
            self.assertEqual(f.attributes()[8], u"R\ufffdgion") # invalid unicode character
Ejemplo n.º 22
0
    def testMultiGeomColumns(self):
        uri = '{} table="qgis_test"."multiGeomColumns" (geom1) sql='.format(self.dbconn)
        new_layer = QgsVectorLayer(uri, 'new', 'mssql')
        self.assertTrue(new_layer.isValid())

        geom = {f[0]: f.geometry().asWkt() for f in new_layer.getFeatures()}
        self.assertEqual(geom, {1: 'Point (2 3)', 2: 'Point (3 4)', 3: '', 4: 'Point (5 6)', 5: 'Point (1 2)'})

        uri = '{} table="qgis_test"."multiGeomColumns" (geom2) sql='.format(self.dbconn)
        new_layer2 = QgsVectorLayer(uri, 'new', 'mssql')
        self.assertTrue(new_layer2.isValid())

        geom = {f[0]: f.geometry().asWkt() for f in new_layer2.getFeatures()}
        self.assertEqual(geom, {1: 'LineString (2 3, 4 5)', 2: 'LineString (3 4, 5 6)', 3: 'LineString (1 2, 3 4)', 4: 'LineString (5 6, 7 8)', 5: ''})
Ejemplo n.º 23
0
    def test_encoding(self):
        # changes encoding on a shapefile (the only provider supporting setEncoding)
        source = toPercent(os.path.join(self.testDataDir, "shp_latin1.dbf"))
        l = QgsVectorLayer("?layer=ogr:%s:fp:latin1" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)

        for f in l.getFeatures():
            self.assertEqual(f.attributes()[1], "accents éàè")

        # use UTF-8 now
        l = QgsVectorLayer("?layer=ogr:%s:fp:UTF-8" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)
        for f in l.getFeatures():
            self.assertEqual(f.attributes()[1], "accents \ufffd\ufffd\ufffd")  # invalid unicode characters
Ejemplo n.º 24
0
    def __snap(self):

        self.report_message.emit(self.layer_id, 'preparing ...')
        orig_layer = QgsMapLayerRegistry.instance().mapLayer(self.layer_id)
        # create a copy of the layer just for editing
        layer = QgsVectorLayer(orig_layer.source(), orig_layer.name(), orig_layer.providerType())
        geom_type = layer.geometryType()
        # layer.wkbType() does not return reliable results
        wkb_type = layer.wkbType()

        if self.create_backup:
            self.report_message.emit(self.layer_id, 'creating backup ...')
            self.__create_backup_file(orig_layer)

        self.report_message.emit(self.layer_id, 'preparing ...')
        layer.startEditing()
        request = QgsFeatureRequest().setFilterRect(self.snap_extent)
        total_features = 0
        for feature in layer.getFeatures(request):
            total_features += 1

        QgsMessageLog.logMessage(self.plugin.tr('Features to be snapped in layer <{0}>: {1}').
                                 format(orig_layer.name(), total_features), self.plugin.tr('Vertex Tools'),
                                 QgsMessageLog.INFO)
        if total_features == 0:
            self.report_message.emit(self.layer_id, 'no features')

        count = 0
        for feature in layer.getFeatures(request):
            with QMutexLocker(self.mutex):
                if self.stopped:
                    layer.rollBack()
                    return

            if geom_type == QGis.Point:
                snapped_geom = self.__point_grid(feature, wkb_type)
            elif geom_type == QGis.Line:
                snapped_geom = self.__line_grid(feature, wkb_type)
            elif geom_type == QGis.Polygon:
                snapped_geom = self.__polygon_grid(feature, wkb_type)

            layer.changeGeometry(feature.id(), snapped_geom)

            count += 1
            self.run_progressed.emit(self.layer_id, count, total_features)

        layer.commitChanges()

        self.completed = True
Ejemplo n.º 25
0
    def test_FilterExpressionWithAccents(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'france_parts.shp')
        layer = QgsVectorLayer(myShpFile, 'poly', 'ogr')

        layer.setProviderEncoding("ISO-8859-1")
        ids = [feat.id() for feat in layer.getFeatures(QgsFeatureRequest().setFilterExpression("TYPE_1 = 'Région'"))]
        expectedIds = [0, 1, 2, 3]
        myMessage = '\nExpected: {0} features\nGot: {1} features'.format(repr(expectedIds), repr(ids))
        assert ids == expectedIds, myMessage

        layer.setProviderEncoding("UTF-8")
        ids = [feat.id() for feat in layer.getFeatures(QgsFeatureRequest().setFilterExpression("TYPE_1 = 'Région'"))]
        expectedIds = []
        myMessage = '\nExpected: {0} features\nGot: {1} features'.format(repr(expectedIds), repr(ids))
        assert ids == expectedIds, myMessage
Ejemplo n.º 26
0
    def test_reopen4(self):
        source = toPercent(os.path.join(self.testDataDir, "france_parts.shp"))
        tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString()
        query = toPercent("SELECT * FROM vtab")
        l = QgsVectorLayer("%s?layer=ogr:%s:vtab&query=%s&uid=objectid&nogeometry" % (tmp, source, query), "vtab2", "virtual", False)
        self.assertEqual(l.isValid(), True)

        l2 = QgsVectorLayer(tmp, "tt", "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 100)
        self.assertEqual(l2.dataProvider().featureCount(), 4)
        sumid = sum([f.id() for f in l2.getFeatures()])
        self.assertEqual(sumid, 10659)
        suma = sum([f.attributes()[1] for f in l2.getFeatures()])
        self.assertEqual(suma, 3064.0)
Ejemplo n.º 27
0
    def testEdit(self):
        """Test `with edit(layer):` code"""

        ml = QgsVectorLayer("Point?crs=epsg:4236&field=id:integer&field=value:double",
                            "test_data", "memory")
        # Data as list of x, y, id, value
        self.assertTrue(ml.isValid())
        fields = ml.fields()

        # Check insert
        with edit(ml):
            feat = QgsFeature(fields)
            feat['id'] = 1
            feat['value'] = 0.9
            self.assertTrue(ml.addFeature(feat))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 0.9)

        # Check update
        with edit(ml):
            f = next(ml.getFeatures())
            f['value'] = 9.9
            self.assertTrue(ml.updateFeature(f))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 9.9)

        # Check for rollBack after exceptions
        with self.assertRaises(NameError):
            with edit(ml):
                f = next(ml.getFeatures())
                f['value'] = 3.8
                crashycrash()  # NOQA

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 9.9)
        self.assertEqual(next(ml.getFeatures())['value'], 9.9)

        # Check for `as`
        with edit(ml) as l:
            f = next(l.getFeatures())
            f['value'] = 10
            self.assertTrue(l.updateFeature(f))

        self.assertEqual(next(ml.dataProvider().getFeatures())['value'], 10)

        # Check that we get a QgsEditError exception when the commit fails
        with self.assertRaises(QgsEditError):
            with edit(ml) as l:
                l.rollBack()
Ejemplo n.º 28
0
    def testNoDanglingFileDescriptorAfterCloseVariant2(self):
        ''' Test that when closing the provider all file handles are released '''

        datasource = os.path.join(self.basetestpath, 'testNoDanglingFileDescriptorAfterCloseVariant2.csv')
        with open(datasource, 'wt') as f:
            f.write('id,WKT\n')
            f.write('1,\n')
            f.write('2,POINT(2 49)\n')

        vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        self.assertTrue(vl.isValid())
        # Consume all features.
        myiter = vl.getFeatures()
        for feature in myiter:
            pass
        # The iterator is closed, but the corresponding connection still not closed
        if sys.platform.startswith('linux'):
            self.assertEqual(count_opened_filedescriptors(datasource), 2)

        # Should release one file descriptor
        del vl

        # Non portable, but Windows testing is done with trying to unlink
        if sys.platform.startswith('linux'):
            self.assertEqual(count_opened_filedescriptors(datasource), 0)

        # Check that deletion works well (can only fail on Windows)
        os.unlink(datasource)
        self.assertFalse(os.path.exists(datasource))
Ejemplo n.º 29
0
    def testStringArray(self):
        vl = QgsVectorLayer('%s table="qgis_test"."string_array" sql=' % (self.dbconn), "teststringarray", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName('value')).type(), QVariant.StringList)
        self.assertEqual(fields.at(fields.indexFromName('value')).subType(), QVariant.String)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField('value')
        self.assertIsInstance(f.attributes()[value_idx], list)
        self.assertEqual(f.attributes()[value_idx], ['a', 'b', 'c'])

        new_f = QgsFeature(vl.fields())
        new_f['pk'] = NULL
        new_f['value'] = ['simple', '"doubleQuote"', "'quote'", 'back\\slash']
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]['pk']
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back['pk'], new_pk)
            self.assertEqual(read_back['value'], new_f['value'])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Ejemplo n.º 30
0
    def load_layer(self):

        layers = self.iface.legendInterface().layers()

        #for layer in layers:

        #pop_feat, pop_attr = self.extract_features(layer.getFeatures())
        #print pop_feat

        celllayer = QgsVectorLayer("/home/kiran/Dropbox/cell.shp", "celltower",
                                   "ogr")
        cell_feat, cell_attr = self.extract_features(celllayer.getFeatures())
        cell_feat = [list(elem) for elem in cell_feat]
        attr_cell = []
        for attr in cell_attr:
            attr_cell.append(int(attr[1]))
        print cell_feat

        poplayer = QgsVectorLayer("/home/kiran/Dropbox/pop.shp", "population",
                                  "ogr")
        pop_feat, pop_attr = self.extract_features(poplayer.getFeatures())
        pop_feat = [list(elem) for elem in pop_feat]
        attr_pop = []
        for attr in pop_attr:
            attr_pop.append(int(attr[1]))
        print pop_feat

        elevlayer = QgsVectorLayer("/home/kiran/Dropbox/elev.shp", "elevation",
                                   "ogr")
        elev_feat, elev_attr = self.extract_features(elevlayer.getFeatures())
        elev_feat = [list(elem) for elem in elev_feat]
        attr_elev = []
        for attr in elev_attr:
            attr_elev.append(int(attr[1]))
        print elev_feat

        landlayer = QgsVectorLayer("/home/kiran/Dropbox/land.shp", "landcost",
                                   "ogr")
        land_feat, land_attr = self.extract_features(landlayer.getFeatures())
        attr_land = []
        for attr in land_attr:
            attr_land.append(int(attr[1]))

        cost_feat = []
        for each in land_feat:
            each = each[0]
            land_list = [list(elem) for elem in each]
            cost_feat.append(land_list)
        print cost_feat

        geomx = []
        geomy = []
        for geom in pop_feat:
            geomx.append(geom[0])
            geomy.append(geom[1])
        guess = [(sum(geomx) / len(geomx)), (sum(geomy) / len(geomy))]

        ret = optimize.minimize(guess, cell_feat, attr_cell, pop_feat,
                                attr_pop, elev_feat, attr_elev, cost_feat,
                                attr_land)
        #ret = optimize.testfun(guess)

        ##Draw the optimal location of cell tower
        newlayer = QgsVectorLayer("/home/kiran/Dropbox/new.shp",
                                  "optimal_tower", "ogr")
        self.draw_point(newlayer, ret)
        print "optimal location is"
        print ret
Ejemplo n.º 31
0
from qgis.core import QgsApplication, QgsVectorLayer, QgsProject
qgs = QgsApplication([], False)
qgs.initQgis()

data_dir = os.path.join(os.path.expanduser('~'), 'Downloads/pyqgis_in_a_day/')

filename = 'sf.gpkg|layername=zoning'
uri = os.path.join(data_dir, filename)
layer = QgsVectorLayer(uri, 'zoning', 'ogr')

output_name = 'output.csv'
output_path = os.path.join(data_dir, output_name)

with open(output_path, 'w') as output_file:
    fieldnames = [field.name() for field in layer.fields()]
    line = ','.join(name for name in fieldnames) + '\n'
    output_file.write(line)
    for f in layer.getFeatures():
        line = ','.join(str(f[name]) for name in fieldnames) + '\n'
        output_file.write(line)

print('Success: ', 'Output file written at' + output_path)

# Delete the layer object from memory
# Without this you may get a Segmentation Fault on exit
# when the exitQgis() method will try clearning the layer registry
# Alternatively, you can add the layer so it is present in the registry
# QgsProject.instance().addMapLayer(layer, False)
del (layer)
qgs.exitQgis()
Ejemplo n.º 32
0
    def testQueue(self):  # pylint: disable=too-many-statements
        """
        Test queue operations
        """
        district_layer = QgsVectorLayer(
            "Polygon?crs=EPSG:4326&field=fld1:string&field=estimated_pop:int&field=stats_nz_pop:int&field=stats_nz_var_20:int&field=stats_nz_var_23:int&field=invalid:int&field=invalid_reason:string",
            "source", "memory")
        d = QgsFeature()
        d.setAttributes(["test1", NULL, 11111, 12, 13, 1, 'x'])
        d.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 0, 10, 5)))
        d2 = QgsFeature()
        d2.setAttributes(["test2", NULL, 11112, 22, 23, 0, 'y'])
        d2.setGeometry(
            QgsGeometry.unaryUnion([
                QgsGeometry.fromRect(QgsRectangle(5, 5, 10, 10)),
                QgsGeometry.fromRect(QgsRectangle(0, 10, 10, 15))
            ]))
        d3 = QgsFeature()
        d3.setAttributes(["test3", NULL, 11113, 32, 33, 1, 'z'])
        d3.setGeometry(QgsGeometry.fromRect(QgsRectangle(0, 5, 5, 10)))
        d4 = QgsFeature()
        d4.setAttributes(["test4", NULL, 11114, 42, 43, 0, 'xx'])
        d4.setGeometry(QgsGeometry.fromRect(QgsRectangle(0, 0, 5, 5)))
        d5 = QgsFeature()
        d5.setAttributes(["aaa", NULL, 11115, 52, 53, 1, 'yy'])
        success, [d, d2, d3, d4,
                  d5] = district_layer.dataProvider().addFeatures(
                      [d, d2, d3, d4, d5])
        self.assertTrue(success)

        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['test1', NULL, 11111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((5 0, 10 0, 10 5, 5 5, 5 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        queue = ElectorateEditQueue(electorate_layer=district_layer)
        self.assertFalse(queue.back())
        self.assertFalse(queue.forward())

        queue.push_changes(
            {d.id(): {
                 0: 'xtest1',
                 2: 21111
             }}, {d.id(): QgsGeometry.fromRect(QgsRectangle(115, 0, 110, 5))})
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['xtest1', NULL, 21111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((110 0, 115 0, 115 5, 110 5, 110 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        queue.push_changes(
            {
                d2.id(): {
                    0: 'xtest2',
                    2: 31111
                },
                d3.id(): {
                    0: 'xtest3',
                    3: 42222
                }
            }, {
                d2.id(): QgsGeometry.fromRect(QgsRectangle(215, 0, 210, 25)),
                d3.id(): QgsGeometry.fromRect(QgsRectangle(110, 1, 150, 4))
            })
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['xtest1', NULL, 21111, 12, 13, 1, 'x'],
             ['xtest2', NULL, 31111, 22, 23, 0, 'y'],
             ['xtest3', NULL, 11113, 42222, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((110 0, 115 0, 115 5, 110 5, 110 0))',
                'Polygon ((210 0, 215 0, 215 25, 210 25, 210 0))',
                'Polygon ((110 1, 150 1, 150 4, 110 4, 110 1))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])
        self.assertFalse(queue.forward())

        self.assertTrue(queue.back())
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['xtest1', NULL, 21111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((110 0, 115 0, 115 5, 110 5, 110 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        self.assertTrue(queue.back())

        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['test1', NULL, 11111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((5 0, 10 0, 10 5, 5 5, 5 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        self.assertFalse(queue.back())

        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['test1', NULL, 11111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((5 0, 10 0, 10 5, 5 5, 5 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        self.assertTrue(queue.forward())
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['xtest1', NULL, 21111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((110 0, 115 0, 115 5, 110 5, 110 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        self.assertTrue(queue.forward())
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['xtest1', NULL, 21111, 12, 13, 1, 'x'],
             ['xtest2', NULL, 31111, 22, 23, 0, 'y'],
             ['xtest3', NULL, 11113, 42222, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((110 0, 115 0, 115 5, 110 5, 110 0))',
                'Polygon ((210 0, 215 0, 215 25, 210 25, 210 0))',
                'Polygon ((110 1, 150 1, 150 4, 110 4, 110 1))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        self.assertFalse(queue.forward())
        self.assertTrue(queue.back())
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['xtest1', NULL, 21111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((110 0, 115 0, 115 5, 110 5, 110 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])

        queue.forward()
        queue.rollback()
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['test1', NULL, 11111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((5 0, 10 0, 10 5, 5 5, 5 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])
        self.assertTrue(queue.forward())
        self.assertEqual(
            [f.attributes() for f in district_layer.getFeatures()],
            [['xtest1', NULL, 21111, 12, 13, 1, 'x'],
             ['test2', NULL, 11112, 22, 23, 0, 'y'],
             ['test3', NULL, 11113, 32, 33, 1, 'z'],
             ['test4', NULL, 11114, 42, 43, 0, 'xx'],
             ['aaa', NULL, 11115, 52, 53, 1, 'yy']])
        self.assertEqual(
            [f.geometry().asWkt() for f in district_layer.getFeatures()], [
                'Polygon ((110 0, 115 0, 115 5, 110 5, 110 0))',
                'Polygon ((10 10, 10 5, 5 5, 5 10, 0 10, 0 15, 10 15, 10 10))',
                'Polygon ((0 5, 5 5, 5 10, 0 10, 0 5))',
                'Polygon ((0 0, 5 0, 5 5, 0 5, 0 0))', ''
            ])
Ejemplo n.º 33
0
    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")
Ejemplo n.º 34
0
    def testSurfaces(self):
        vl = QgsVectorLayer(
            '%s table="QGIS"."POLY_DATA" (GEOM) srid=4326 type=POLYGON sql=' %
            (self.dbconn), "testpoly", "oracle")
        self.assertTrue(vl.isValid())

        features = {f['pk']: f for f in vl.getFeatures()}
        self.assertTrue(
            compareWkt(features[1].geometry().asWkt(),
                       'Polygon ((1 2, 11 2, 11 22, 1 22, 1 2))', 0.00001),
            features[1].geometry().asWkt())
        self.assertTrue(
            compareWkt(features[2].geometry().asWkt(),
                       'PolygonZ ((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3))',
                       0.00001), features[2].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[3].geometry().asWkt(),
                'Polygon ((1 2, 11 2, 11 22, 1 22, 1 2),(5 6, 8 9, 8 6, 5 6),(3 4, 5 6, 3 6, 3 4))',
                0.00001), features[3].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[4].geometry().asWkt(),
                'PolygonZ ((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3),(5 6 1, 8 9 -1, 8 6 2, 5 6 1))',
                0.00001), features[4].geometry().asWkt())
        self.assertTrue(
            compareWkt(features[5].geometry().asWkt(),
                       'Polygon ((1 2, 11 2, 11 22, 1 22, 1 2))', 0.00001),
            features[5].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[6].geometry().asWkt(),
                'CurvePolygon (CircularString (6.76923076923076916 22.82875364393326834, 17.98259979777942519 11.61538461538461497, 6.76923076923076916 0.40201558683595984, -4.44413825931788598 11.61538461538461497, 6.76923076923076916 22.82875364393326834))',
                0.00001), features[6].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[7].geometry().asWkt(),
                'MultiPolygon (((1 2, 11 2, 11 22, 1 22, 1 2)),((1 2, 11 2, 11 22, 1 22, 1 2),(5 6, 8 9, 8 6, 5 6),(3 4, 5 6, 3 6, 3 4)))',
                0.00001), features[7].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[8].geometry().asWkt(),
                'MultiPolygonZ (((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3)),((1 2 3, 11 2 13, 11 22 15, 1 22 7, 1 2 3),(5 6 1, 8 9 -1, 8 6 2, 5 6 1)))',
                0.00001), features[8].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[9].geometry().asWkt(),
                'CurvePolygon (CircularString (1 3, 3 5, 4 7, 7 3, 1 3))',
                0.00001), features[9].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[10].geometry().asWkt(),
                'CurvePolygon (CircularString (1 3, 3 5, 4 7, 7 3, 1 3),CircularString (3.1 3.3, 3.3 3.5, 3.4 3.7, 3.7 3.3, 3.1 3.3))',
                0.00001), features[10].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[11].geometry().asWkt(),
                'CurvePolygon(CompoundCurve ((-1 -5, 1 2),CircularString (1 2, 5 4, 7 2.20, 10 0.1, 13 4),(13 4, 17 -6),CircularString (17 -6, 5 -7, -1 -5)))',
                0.00001), features[11].geometry().asWkt())
        self.assertTrue(
            compareWkt(
                features[12].geometry().asWkt(),
                'MultiSurface (CurvePolygon (CircularString (1 3, 3 5, 4 7, 7 3, 1 3)),CurvePolygon (CircularString (11 3, 13 5, 14 7, 17 3, 11 3)))',
                0.00001), features[12].geometry().asWkt())
Ejemplo n.º 35
0
    def test_sql2(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"),
                            "france_parts", "ogr",
                            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        QgsProject.instance().addMapLayer(l2)

        query = toPercent("SELECT * FROM france_parts")
        l4 = QgsVectorLayer("?query=%s&uid=ObjectId" % query, "tt", "virtual")
        self.assertEqual(l4.isValid(), True)

        self.assertEqual(l4.dataProvider().wkbType(), 6)
        self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326)

        n = 0
        r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086))
        for f in l4.getFeatures(r):
            self.assertEqual(f.geometry() is not None, True)
            self.assertEqual(f.attributes()[0], 2661)
            n += 1
        self.assertEqual(n, 1)

        # use uid
        query = toPercent("SELECT * FROM france_parts")
        l5 = QgsVectorLayer(
            "?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query,
            "tt", "virtual")
        self.assertEqual(l5.isValid(), True)

        idSum = sum(f.id() for f in l5.getFeatures())
        self.assertEqual(idSum, 10659)

        r = QgsFeatureRequest(2661)
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)

        r = QgsFeatureRequest()
        r.setFilterFids([2661, 2664])
        self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664)

        # test attribute subset
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.SubsetOfAttributes)
        r.setSubsetOfAttributes([1])
        s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)]
        self.assertEqual(sum([x[0] for x in s]), 10659)
        self.assertEqual(sum([x[1] for x in s]), 3064.0)

        # test NoGeometry
        # by request flag
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.NoGeometry)
        self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]),
                         True)

        # test subset
        self.assertEqual(l5.dataProvider().featureCount(), 4)
        l5.setSubsetString("ObjectId = 2661")
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)
        self.assertEqual(l5.dataProvider().featureCount(), 1)
Ejemplo n.º 36
0
 def test_table(dbconn, table_name, wkt):
     vl = QgsVectorLayer('%s srid=4326 table="qgis_test".%s (geom) sql=' % (dbconn, table_name), "testgeom", "postgres")
     self.assertTrue(vl.isValid())
     for f in vl.getFeatures():
         self.assertEqual(f.geometry().asWkt(), wkt)
Ejemplo n.º 37
0
    def test_Query(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"),
                            "france_parts", "ogr", False)
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)
        ref_sum = sum(f.attributes()[0] for f in l1.getFeatures())

        query = toPercent("SELECT * FROM vtab1")
        l2 = QgsVectorLayer(
            "?layer_ref=%s&geometry=geometry:3:4326&query=%s&uid=OBJECTID" %
            (l1.id(), query), "vtab", "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 3)

        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is ok
        self.assertEqual(ref_sum, ref_sum3)

        # the same, without specifying the geometry column name
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&uid=OBJECTID" % (l1.id(), query), "vtab",
            "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 3)
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is ok
        self.assertEqual(ref_sum, ref_sum3)

        # with two geometry columns
        query = toPercent("SELECT *,geometry as geom FROM vtab1")
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&uid=OBJECTID&geometry=geom:3:4326" %
            (l1.id(), query), "vtab", "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 3)
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is ok
        self.assertEqual(ref_sum, ref_sum3)

        # with two geometry columns, but no geometry column specified (will take the first)
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&uid=OBJECTID" % (l1.id(), query), "vtab",
            "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 3)
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        # check we have the same rows
        self.assertEqual(ref_sum, ref_sum2)
        # check the id is ok
        self.assertEqual(ref_sum, ref_sum3)

        # the same, without geometry
        query = toPercent("SELECT * FROM ww")
        l2 = QgsVectorLayer(
            "?layer_ref=%s:ww&query=%s&uid=ObJeCtId&nogeometry" %
            (l1.id(), query), "vtab", "virtual", False)
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 100)  # NoGeometry
        ref_sum2 = sum(f.attributes()[0] for f in l2.getFeatures())
        ref_sum3 = sum(f.id() for f in l2.getFeatures())
        self.assertEqual(ref_sum, ref_sum2)
        self.assertEqual(ref_sum, ref_sum3)

        # check that it fails when a query has a wrong geometry column
        l2 = QgsVectorLayer(
            "?layer_ref=%s&query=%s&geometry=geo" % (l1.id(), query), "vtab",
            "virtual", False)
        self.assertEqual(l2.isValid(), False)

        QgsProject.instance().removeMapLayer(l1.id())
Ejemplo n.º 38
0
    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')
Ejemplo n.º 39
0
    def test_sql_field_types(self):
        query = toPercent(
            "SELECT 42 as t, 'ok'||'ok' as t2, GeomFromText('') as t3, 3.14*2 as t4"
        )
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "t")
        self.assertEqual(l4.dataProvider().fields().at(0).type(), QVariant.Int)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2")
        self.assertEqual(l4.dataProvider().fields().at(1).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(2).name(), "t3")
        self.assertEqual(l4.dataProvider().fields().at(2).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(3).name(), "t4")
        self.assertEqual(l4.dataProvider().fields().at(3).type(),
                         QVariant.Double)

        # with type annotations
        query = toPercent(
            "SELECT '42.0' as t /*:real*/, 3 as t2/*:text  */, GeomFromText('') as t3 /*:multiPoInT:4326 */, 3.14*2 as t4/*:int*/"
        )
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "t")
        self.assertEqual(l4.dataProvider().fields().at(0).type(),
                         QVariant.Double)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "t2")
        self.assertEqual(l4.dataProvider().fields().at(1).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(2).name(), "t4")
        self.assertEqual(l4.dataProvider().fields().at(2).type(), QVariant.Int)
        self.assertEqual(l4.dataProvider().wkbType(), 4)  # multipoint

        # test value types (!= from declared column types)
        for f in l4.getFeatures():
            self.assertEqual(f.attributes()[0], "42.0")
            self.assertEqual(f.attributes()[1], 3)
            self.assertEqual(f.attributes()[2], 6.28)

        # with type annotations and url options
        query = toPercent(
            "SELECT 1 as id /*:int*/, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/"
        )
        l4 = QgsVectorLayer("?query=%s&geometry=geometry" % query, "tt",
                            "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().wkbType(), 1)  # point

        # with type annotations and url options (2)
        query = toPercent(
            "SELECT 1 as id /*:int*/, 3.14 as f, geomfromtext('point(0 0)',4326) as geometry/*:point:4326*/"
        )
        l4 = QgsVectorLayer(
            "?query=%s&geometry=geometry&field=id:text" % query, "tt",
            "virtual", False)
        self.assertEqual(l4.isValid(), True)
        self.assertEqual(l4.dataProvider().fields().at(0).name(), "id")
        self.assertEqual(l4.dataProvider().fields().at(0).type(),
                         QVariant.String)
        self.assertEqual(l4.dataProvider().fields().at(1).name(), "f")
        self.assertEqual(l4.dataProvider().fields().at(1).type(),
                         QVariant.Double)
        self.assertEqual(l4.dataProvider().wkbType(), 1)  # point
Ejemplo n.º 40
0
    def testDateTimeWriteShapefile(self):
        """Check writing date and time fields to an ESRI shapefile."""
        ml = QgsVectorLayer(
            ('Point?crs=epsg:4326&field=id:int&'
             'field=date_f:date&field=time_f:time&field=dt_f:datetime'),
            'test', 'memory')

        self.assertTrue(ml.isValid())
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
        ft.setAttributes([
            1,
            QDate(2014, 3, 5),
            QTime(13, 45, 22),
            QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22))
        ])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp')
        crs = QgsCoordinateReferenceSystem()
        crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile')
        self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                         error_message)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')

        fields = created_layer.dataProvider().fields()
        self.assertEqual(
            fields.at(fields.indexFromName('date_f')).type(), QVariant.Date)
        # shapefiles do not support time types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('time_f')).type(), QVariant.String)
        # shapefiles do not support datetime types, result should be string
        self.assertEqual(
            fields.at(fields.indexFromName('dt_f')).type(), QVariant.String)

        f = next(created_layer.getFeatures(QgsFeatureRequest()))

        date_idx = created_layer.fields().lookupField('date_f')
        self.assertIsInstance(f.attributes()[date_idx], QDate)
        self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5))
        time_idx = created_layer.fields().lookupField('time_f')
        # shapefiles do not support time types
        self.assertIsInstance(f.attributes()[time_idx], str)
        self.assertEqual(f.attributes()[time_idx], '13:45:22')
        # shapefiles do not support datetime types
        datetime_idx = created_layer.fields().lookupField('dt_f')
        self.assertIsInstance(f.attributes()[datetime_idx], str)
        self.assertEqual(
            f.attributes()[datetime_idx],
            QDateTime(QDate(2014, 3, 5),
                      QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
Ejemplo n.º 41
0
    def __calculateWK(self,
                      layer: QgsVectorLayer,
                      layer2: QgsVectorLayer,
                      translate=False):
        """MapCurve calculation using Wilkerstat method.
        
        :param layer QgsVectorLayer: The First layer
        :param layer2 QgsVevtorLayer: The Second Layer
        :param translate bool: calculate with translating the geometry
        
        """
        # print("executed function wk")
        progress = 0
        # print("progress initialized")
        attrName = layer.dataProvider().fields().names()
        # print("attrnName initialized")
        attrName2 = layer2.dataProvider().fields().names()
        # print("attrnName initialized")
        score = float(0)
        for i in layer.getFeatures():
            # Querying for matching attribute
            # print(self.killed)
            if self.killed is True:
                # kill request received, exit loop early
                break
            # print("iterated i : "+str(i.id()))
            # que = QgsQueryBuilder(layer2)
            # print("query builder" )
            # print("key cek")
            # print("PROVNO" in attrName)
            # print("provno" in attrName)
            # print("KABKOTNO" in attrName)
            # print("kabkotno" in attrName)
            # print("KECNO" in attrName)
            # print("kecno" in attrName)
            # print("DESANO" in attrName)
            # print("desano" in attrName)
            # print("PROVNO" in attrName2)
            # print("provno" in attrName2)
            # print("KABKOTNO" in attrName2)
            # print("kabkotno" in attrName2)
            # print("KECNO" in attrName2)
            # print("kecno" in attrName2)
            # print("DESANO" in attrName2)
            # print("desano" in attrName2)
            # print("key ceked")
            queText = ""
            try:
                # print("trying..")
                if ("PROVNO" in attrName2):
                    # print("PROVNO passed")
                    if ("PROVNO" in attrName):
                        queText += '"PROVNO"' + " LIKE '"
                        # print(("PROVNO" in attrName))
                        queText += i.attribute("PROVNO")
                        queText += "'"
                    elif "kdprov" in attrName:
                        queText += '"PROVNO"' + " LIKE '"
                        queText += i.attribute("kdprov")
                        # print("kdprov" in attrName)
                        queText += "'"
                    else:
                        queText += '"PROVNO"' + " LIKE '"
                        # print("provno" in attrName)
                        queText += i.attribute("provno")
                        queText += "'"
                elif ("provno" in attrName2):
                    # print("provno" in attrName)
                    if ("PROVNO" in attrName):
                        queText += '"provno"' + " LIKE '"
                        # print(("PROVNO" in attrName))
                        queText += i.attribute("PROVNO")
                        queText += "'"
                    elif "kdprov" in attrName:
                        queText += '"provno"' + " LIKE '"
                        queText += i.attribute("kdprov")
                        # print("kdprov" in attrName)
                        queText += "'"
                    else:
                        queText += '"provno"' + " LIKE '"
                        # print("provno" in attrName)
                        queText += i.attribute("provno")
                        queText += "'"
                elif "kdprov" in attrName2:
                    if ("PROVNO" in attrName):
                        # print(("PROVNO" in attrName))
                        queText += '"kdprov"' + " LIKE '"
                        queText += i.attribute("PROVNO")
                        queText += "'"
                    elif "kdprov" in attrName:
                        queText += '"kdprov"' + " LIKE '"
                        queText += i.attribute("kdprov")
                        # print("kdprov" in attrName)
                        queText += "'"
                    else:
                        queText += '"kdprov"' + " LIKE '"
                        # print("provno" in attrName)
                        queText += i.attribute("provno")
                        queText += "'"
                else:
                    # show error message
                    self.error.emit(
                        "It might be not Wilkerstat, PROVNO, KABKOTNO, KECNO, and/or DESANO is required"
                    )
                    # print("error emit")
                    self.kill()
                    # print("kill task")

                if ("KABKOTNO" in attrName2):
                    # print("kabkotno checked")
                    if ("KABKOTNO" in attrName):
                        queText += ' AND "KABKOTNO" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "KABKOTNO" ' + " LIKE '")
                        queText += i.attribute("KABKOTNO")
                        # print("query str build add KABKOTNO")
                        queText += "'"
                    elif "kdkab" in attrName:
                        queText += ' AND "KABKOTNO" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "KABKOTNO" ' + " LIKE '")
                        queText += i.attribute("kdkab")
                        # print("query str build add kdkab")
                        queText += "'"
                    else:
                        queText += ' AND "KABKOTNO" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "KABKOTNO" ' + " LIKE '")
                        queText += i.attribute("kabkotno")
                        # print("query str build kabkotno")
                        queText += "'"
                elif ("kabkotno" in attrName2):
                    # print("kabkotno checked")
                    if ("KABKOTNO" in attrName):
                        queText += ' AND "kabkotno" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "kabkotno" ' + " LIKE '")
                        queText += i.attribute("KABKOTNO")
                        # print("query str build add KABKOTNO")
                    elif "kdkab" in attrName:
                        queText += ' AND "kabkotno" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "kabkotno" ' + " LIKE '")
                        queText += i.attribute("kdkab")
                        # print("query str build add kdkab")
                        queText += "'"
                    else:
                        queText += ' AND "kabkotno" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "kabkotno" ' + " LIKE '")
                        queText += i.attribute("kabkotno")
                        # print("query str build kabkotno")
                        queText += "'"
                elif "kdkab" in attrName2:
                    if ("KABKOTNO" in attrName):
                        queText += ' AND "kdkab" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "kdkab" ' + " LIKE '")
                        queText += i.attribute("KABKOTNO")
                        # print("query str build add KABKOTNO")
                        queText += "'"
                    elif "kdkab" in attrName:
                        queText += ' AND "kdkab" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "kdkab" ' + " LIKE '")
                        queText += i.attribute("kdkab")
                        # print("query str build add kdkab")
                        queText += "'"
                    else:
                        queText += ' AND "kdkab" ' + " LIKE '"
                        # print("query str build "+"'"+' AND "kdkab" ' + " LIKE '")
                        queText += i.attribute("kabkotno")
                        # print("query str build kabkotno")
                        queText += "'"

                if ("KECNO" in attrName2):
                    # print("KECNO cheked")
                    if ("KECNO" in attrName):
                        queText += ' AND "KECNO" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "KECNO" ' + "LIKE '")
                        queText += i.attribute("KECNO")
                        # print("query str build add KECNO")
                        queText += "'"
                    elif ("kdkec" in attrName):
                        queText += ' AND "KECNO" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "KECNO" ' + "LIKE '")
                        queText += i.attribute("kdkec")
                        # print("query str build add kdkec")
                        queText += "'"
                    else:
                        queText += ' AND "KECNO" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "KECNO" ' + "LIKE '")
                        queText += i.attribute("kecno")
                        # print("query str build add kecno")
                        queText += "'"
                elif ("kecno" in attrName2):
                    # print("kecno cheked")
                    if ("KECNO" in attrName):
                        queText += ' AND "kecno" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "kecno" ' + "LIKE '")
                        queText += i.attribute("KECNO")
                        # print("query str build add KECNO")
                        queText += "'"
                    elif ("kdkec" in attrName):
                        queText += ' AND "kecno" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "kecno" ' + "LIKE '")
                        queText += i.attribute("kdkec")
                        # print("query str build add kdkec")
                        queText += "'"
                    else:
                        queText += ' AND "kecno" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "kecno" ' + "LIKE '")
                        queText += i.attribute("kecno")
                        # print("query str build add kecno")
                        queText += "'"
                elif "kdkec" in attrName2:
                    if ("KECNO" in attrName):
                        # print("kdkec cheked")
                        queText += ' AND "kdkec" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "kecno" ' + "LIKE '")
                        queText += i.attribute("KECNO")
                        # print("query str build add KECNO")
                        queText += "'"
                    elif ("kdkec" in attrName):
                        # print("kdkec cheked")
                        queText += ' AND "kdkec" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "kecno" ' + "LIKE '")
                        queText += i.attribute("kdkec")
                        # print("query str build add kdkec")
                        queText += "'"
                    else:
                        # print("kdkec cheked")
                        queText += ' AND "kdkec" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "kecno" ' + "LIKE '")
                        queText += i.attribute("kecno")
                        # print("query str build add kecno")
                        queText += "'"

                if ('DESANO' in attrName2):
                    # print("DESANO cheked")
                    if ('DESANO' in attrName):
                        queText += ' AND "DESANO" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "DESANO" ' + "LIKE '")
                        queText += i.attribute("DESANO")
                        # print("query add DESANO")
                        queText += "'"
                    elif 'kddesa' in attrName:
                        queText += ' AND "DESANO" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "DESANO" ' + "LIKE '")
                        queText += i.attribute("kddesa")
                        # print("query add kddesa")
                        queText += "'"
                    else:
                        queText += ' AND "DESANO" ' + "LIKE '"
                        # print("query str build "+"'"+' AND "DESANO" ' + "LIKE '")
                        queText += i.attribute("desano")
                        # print("query add desano")
                        queText += "'"
                elif ("desano" in attrName2):
                    # print("kddesa cheked")
                    if ('DESANO' in attrName):
                        queText += ' AND "desano" ' + "LIKE '"
                        # print("query build "+"'"+' AND "desano" ' + "LIKE '")
                        queText += i.attribute("DESANO")
                        # print("query add DESANO")
                        queText += "'"
                    elif 'kddesa' in attrName:
                        queText += ' AND "desano" ' + "LIKE '"
                        # print("query build "+"'"+' AND "desano" ' + "LIKE '")
                        queText += i.attribute("kddesa")
                        # print("query add kddesa")
                        queText += "'"
                    else:
                        queText += ' AND "desano" ' + "LIKE '"
                        # print("query build "+"'"+' AND "desano" ' + "LIKE '")
                        queText += i.attribute("desano")
                        # print("query add desano")
                        # print("id checked")
                        queText += "'"
                elif ("kddesa" in attrName2):
                    if ('DESANO' in attrName):
                        queText += ' AND "kddesa" ' + "LIKE '"
                        # print("query build "+"'"+' AND "desano" ' + "LIKE '")
                        queText += i.attribute("DESANO")
                        # print("query add DESANO")
                        queText += "'"
                    elif 'kddesa' in attrName:
                        queText += ' AND "kddesa" ' + "LIKE '"
                        # print("query build "+"'"+' AND "desano" ' + "LIKE '")
                        queText += i.attribute("kddesa")
                        # print("query add kddesa")
                        queText += "'"
                    else:
                        queText += ' AND "kddesa" ' + "LIKE '"
                        # print("query build "+"'"+' AND "desano" ' + "LIKE '")
                        queText += i.attribute("desano")
                        # print("query add desano")
                        # print("id checked")
                        queText += "'"
                # print(queText)
                # print(len([j for j in layer2.getFeatures(queText)]))
                for j in layer2.getFeatures(queText):
                    self.__calcMapCurves(i, j)
            except KeyError as identifier:
                # show error message
                self.error.emit(
                    "It might be not Wilkerstat, PROVNO, KABKOTNO, KECNO, DESANO is required"
                )
                print("error emit")
                self.kill()
                # print("kill task")
            except ValueError as identifier:
                # show error message
                self.error.emit("Value error")
                print("error emit")
                self.kill()
                # print("kill task")
            except:
                self.error.emit("Unexpected error")
                # print("error emit")
                self.kill()
                # print("kill task")
            progress = progress + ((1 / layer.featureCount()) * 100)
            # print("progress calculated")
            # iterL = iterL+1
            # print(iterL)
            # print("progress "+str(progress))
            self.progress.emit(progress)

            # print("progress emitted")
        return self.similarLayer
Ejemplo n.º 42
0
    def testStatistics(self):
        """Test zonal stats"""
        TEST_DATA_DIR = unitTestDataPath() + "/zonalstatistics/"
        myTempPath = QDir.tempPath() + "/"
        testDir = QDir(TEST_DATA_DIR)
        for f in testDir.entryList(QDir.Files):
            QFile.remove(myTempPath + f)
            QFile.copy(TEST_DATA_DIR + f, myTempPath + f)

        myVector = QgsVectorLayer(myTempPath + "polys.shp", "poly", "ogr")
        myRaster = QgsRasterLayer(myTempPath + "edge_problem.asc", "raster",
                                  "gdal")
        zs = QgsZonalStatistics(myVector, myRaster, "", 1,
                                QgsZonalStatistics.All)
        zs.calculateStatistics(None)

        feat = QgsFeature()
        # validate statistics for each feature
        request = QgsFeatureRequest().setFilterFid(0)
        feat = next(myVector.getFeatures(request))
        myMessage = ('Expected: %f\nGot: %f\n' % (12.0, feat[1]))
        assert feat[1] == 12.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (8.0, feat[2]))
        assert feat[2] == 8.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.666666666666667, feat[3]))
        assert abs(feat[3] - 0.666666666666667) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4]))
        assert feat[4] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' %
                     (0.47140452079103201, feat[5]))
        assert abs(feat[5] - 0.47140452079103201) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6]))
        assert feat[6] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7]))
        assert feat[7] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8]))
        assert feat[8] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9]))
        assert feat[9] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10]))
        assert feat[10] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11]))
        assert feat[11] == 2.0, myMessage

        request.setFilterFid(1)
        feat = next(myVector.getFeatures(request))
        myMessage = ('Expected: %f\nGot: %f\n' % (9.0, feat[1]))
        assert feat[1] == 9.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2]))
        assert feat[2] == 5.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.555555555555556, feat[3]))
        assert abs(feat[3] - 0.555555555555556) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4]))
        assert feat[4] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' %
                     (0.49690399499995302, feat[5]))
        assert abs(feat[5] - 0.49690399499995302) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6]))
        assert feat[6] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7]))
        assert feat[7] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8]))
        assert feat[8] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9]))
        assert feat[9] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10]))
        assert feat[10] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11]))
        assert feat[11] == 2.0, myMessage

        request.setFilterFid(2)
        feat = next(myVector.getFeatures(request))
        myMessage = ('Expected: %f\nGot: %f\n' % (6.0, feat[1]))
        assert feat[1] == 6.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2]))
        assert feat[2] == 5.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.833333333333333, feat[3]))
        assert abs(feat[3] - 0.833333333333333) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4]))
        assert feat[4] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.372677996249965, feat[5]))
        assert abs(feat[5] - 0.372677996249965) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6]))
        assert feat[6] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7]))
        assert feat[7] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8]))
        assert feat[8] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9]))
        assert feat[9] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10]))
        assert feat[10] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11]))
        assert feat[11] == 2.0, myMessage
Ejemplo n.º 43
0
    def testBadMultiPoints(self):
        """
        Test invalid server response where a layer's type is multipoint but single point geometries
        are returned. Thanks Jack. Thack.
        """
        endpoint = self.basetestpath + '/multipoint_fake_qgis_http_endpoint'
        with open(sanitize(endpoint, '?f=json'), 'wb') as f:
            f.write("""
        {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description":
        "QGIS Provider Test Layer.\n","geometryType":"esriGeometryMultipoint","copyrightText":"","parentLayer":{"id":0,"name":"QGIS Tests"},"subLayers":[],
        "minScale":72225,"maxScale":0,
        "defaultVisibility":true,
        "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3,
        "spatialReference":{"wkid":4326,"latestWkid":4326}},
        "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText",
        "displayField":"LABEL","typeIdField":null,
        "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null}],
        "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false,
        "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true,
        "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF",
        "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}"""
                    .encode('UTF-8'))

        with open(
                sanitize(endpoint,
                         '/query?f=json_where=1=1&returnIdsOnly=true'),
                'wb') as f:
            f.write("""
        {
         "objectIdFieldName": "OBJECTID",
         "objectIds": [
          1,
          2,
          3
         ]
        }
        """.encode('UTF-8'))

        # Create test layer
        vl = QgsVectorLayer("url='http://" + endpoint + "' crs='epsg:4326'",
                            'test', 'arcgisfeatureserver')

        self.assertTrue(vl.isValid())
        with open(
                sanitize(
                    endpoint,
                    '/query?f=json&objectIds=1,2,3&inSR=4326&outSR=4326&returnGeometry=true&outFields=OBJECTID&returnM=false&returnZ=false'
                ), 'wb') as f:
            f.write("""
        {
         "displayFieldName": "name",
         "fieldAliases": {
          "name": "name"
         },
         "geometryType": "esriGeometryMultipoint",
         "spatialReference": {
          "wkid": 4326,
          "latestWkid": 4326
         },
         "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null},
        {"name":"Shape","type":"esriFieldTypeGeometry","alias":"Shape","domain":null}],
         "features": [
          {
           "attributes": {
            "OBJECTID": 1
           },
           "geometry": {
            "x": -70,
            "y": 66
           }
          },
          {
           "attributes": {
            "OBJECTID": 2
           },
           "geometry": null
          },
          {
           "attributes": {
            "OBJECTID": 3
           },
           "geometry":
           {"points" :[[-68,70],
           [-22,21]]
           }
          }
         ]
        }""".encode('UTF-8'))

        features = [f for f in vl.getFeatures()]
        self.assertEqual(len(features), 3)
        self.assertEqual(
            [f.geometry().asWkt() for f in features],
            ['MultiPoint ((-70 66))', '', 'MultiPoint ((-68 70),(-22 21))'])
Ejemplo n.º 44
0
    def testWriteShapefileWithAttributeSubsets(self):
        """Tests writing subsets of attributes to files."""
        ml = QgsVectorLayer((
            'Point?crs=epsg:4326&field=id:int&field=field1:int&field=field2:int&field=field3:int'
        ), 'test', 'memory')

        self.assertIsNotNone(ml, 'Provider not initialized')
        self.assertTrue(ml.isValid(), 'Source layer not valid')
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromWkt('Point (1 2)'))
        ft.setAttributes([1, 11, 12, 13])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        # first write out with all attributes
        dest_file_name = os.path.join(str(QDir.tempPath()),
                                      'all_attributes.shp')
        crs = QgsCoordinateReferenceSystem()
        crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[])
        self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                         error_message)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')
        self.assertEqual(created_layer.fields().count(), 4)
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        self.assertEqual(f['id'], 1)
        self.assertEqual(f['field1'], 11)
        self.assertEqual(f['field2'], 12)
        self.assertEqual(f['field3'], 13)

        # now test writing out only a subset of attributes
        dest_file_name = os.path.join(str(QDir.tempPath()),
                                      'subset_attributes.shp')
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            ml,
            dest_file_name,
            'utf-8',
            crs,
            'ESRI Shapefile',
            attributes=[1, 3])
        self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                         error_message)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')
        self.assertEqual(created_layer.fields().count(), 2)
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        self.assertEqual(f['field1'], 11)
        self.assertEqual(f['field3'], 13)

        # finally test writing no attributes
        dest_file_name = os.path.join(str(QDir.tempPath()),
                                      'no_attributes.shp')
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            ml,
            dest_file_name,
            'utf-8',
            crs,
            'ESRI Shapefile',
            skipAttributeCreation=True)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                         error_message)

        # Open result and check
        created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name),
                                       'test', 'ogr')
        # expect only a default 'FID' field for shapefiles
        self.assertEqual(created_layer.fields().count(), 1)
        self.assertEqual(created_layer.fields()[0].name(), 'FID')
        # in this case we also check that the geometry exists, to make sure feature has been correctly written
        # even without attributes
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        g = f.geometry()
        wkt = g.asWkt()
        expWkt = 'Point (1 2)'
        self.assertTrue(
            compareWkt(expWkt, wkt),
            "geometry not saved correctly when saving without attributes : mismatch Expected:\n%s\nGot:\n%s\n"
            % (expWkt, wkt))
        self.assertEqual(f['FID'], 0)
Ejemplo n.º 45
0
    def testDateTime(self):
        """ Test that datetime fields work correctly """

        endpoint = self.basetestpath + '/oid_fake_qgis_http_endpoint'
        with open(sanitize(endpoint, '?f=json'), 'wb') as f:
            f.write("""
        {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description":
        "QGIS Provider Test Layer.\n","geometryType":"esriGeometryPoint","copyrightText":"","parentLayer":{"id":0,"name":"QGIS Tests"},"subLayers":[],
        "minScale":72225,"maxScale":0,
        "defaultVisibility":true,
        "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3,
        "spatialReference":{"wkid":4326,"latestWkid":4326}},
        "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText",
        "displayField":"LABEL","typeIdField":null,
        "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null},
        {"name":"pk","type":"esriFieldTypeInteger","alias":"pk","domain":null},
        {"name":"dt","type":"esriFieldTypeDate","alias":"dt","length":8,"domain":null}],
        "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false,
        "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true,
        "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF",
        "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}"""
                    .encode('UTF-8'))

        with open(
                sanitize(endpoint,
                         '/query?f=json_where=1=1&returnIdsOnly=true'),
                'wb') as f:
            f.write("""
        {
         "objectIdFieldName": "OBJECTID",
         "objectIds": [
          1,
          2
         ]
        }
        """.encode('UTF-8'))

        # Create test layer
        vl = QgsVectorLayer("url='http://" + endpoint + "' crs='epsg:4326'",
                            'test', 'arcgisfeatureserver')

        self.assertTrue(vl.isValid())
        with open(
                sanitize(
                    endpoint,
                    '/query?f=json&objectIds=1,2&inSR=4326&outSR=4326&returnGeometry=true&outFields=OBJECTID,pk,dt&returnM=false&returnZ=false'
                ), 'wb') as f:
            f.write("""
        {
         "displayFieldName": "name",
         "fieldAliases": {
          "name": "name"
         },
         "geometryType": "esriGeometryPoint",
         "spatialReference": {
          "wkid": 4326,
          "latestWkid": 4326
         },
         "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null},
        {"name":"pk","type":"esriFieldTypeInteger","alias":"pk","domain":null},
        {"name":"dt","type":"esriFieldTypeDate","alias":"dt","domain":null},
        {"name":"Shape","type":"esriFieldTypeGeometry","alias":"Shape","domain":null}],
         "features": [
          {
           "attributes": {
            "OBJECTID": 1,
            "pk": 1,
            "dt":1493769600000
           },
           "geometry": {
            "x": -70.332,
            "y": 66.33
           }
          },
          {
           "attributes": {
            "OBJECTID": 2,
            "pk": 2,
            "dt":null
           },
           "geometry": {
            "x": -68.2,
            "y": 70.8
           }
          }
         ]
        }""".encode('UTF-8'))

        features = [f for f in vl.getFeatures()]
        self.assertEqual(len(features), 2)
        self.assertEqual([f['dt'] for f in features],
                         [QDate(2017, 5, 3), NULL])
Ejemplo n.º 46
0
    def testFidSupport(self):

        # We do not use @unittest.expectedFailure since the test might actually succeed
        # on Linux 64bit with GDAL 1.11, where "long" is 64 bit...
        # GDAL 2.0 is guaranteed to properly support it on all platforms
        version_num = int(gdal.VersionInfo('VERSION_NUM'))
        if version_num < GDAL_COMPUTE_VERSION(2, 0, 0):
            return

        tmpfile = os.path.join(self.basetestpath, 'testFidSupport.sqlite')
        ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test',
                             geom_type=ogr.wkbPoint,
                             options=['FID=fid'])
        lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString))
        lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(12)
        f.SetField(0, 'foo')
        f.SetField(1, 123)
        lyr.CreateFeature(f)
        f = None
        ds = None

        vl = QgsVectorLayer('{}'.format(tmpfile), 'test', 'ogr')
        self.assertEqual(len(vl.fields()), 3)
        got = [(f.attribute('fid'), f.attribute('strfield'),
                f.attribute('intfield')) for f in vl.getFeatures()]
        self.assertEqual(got, [(12, 'foo', 123)])

        got = [(f.attribute('fid'), f.attribute('strfield'))
               for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                   "strfield = 'foo'"))]
        self.assertEqual(got, [(12, 'foo')])

        got = [(f.attribute('fid'), f.attribute('strfield'))
               for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                   "fid = 12"))]
        self.assertEqual(got, [(12, 'foo')])

        result = [
            f['strfield']
            for f in vl.dataProvider().getFeatures(QgsFeatureRequest(
            ).setSubsetOfAttributes(['strfield'],
                                    vl.dataProvider().fields()))
        ]
        self.assertEqual(result, ['foo'])

        result = [
            f['fid'] for f in vl.dataProvider().getFeatures(QgsFeatureRequest(
            ).setSubsetOfAttributes(['fid'],
                                    vl.dataProvider().fields()))
        ]
        self.assertEqual(result, [12])

        # Test that when the 'fid' field is not set, regular insertion is done
        f = QgsFeature()
        f.setFields(vl.fields())
        f.setAttributes([None, 'automatic_id'])
        (res, out_f) = vl.dataProvider().addFeatures([f])
        self.assertEqual(out_f[0].id(), 13)
        self.assertEqual(out_f[0].attribute('fid'), 13)
        self.assertEqual(out_f[0].attribute('strfield'), 'automatic_id')

        # Test that when the 'fid' field is set, it is really used to set the id
        f = QgsFeature()
        f.setFields(vl.fields())
        f.setAttributes([9876543210, 'bar'])
        (res, out_f) = vl.dataProvider().addFeatures([f])
        self.assertEqual(out_f[0].id(), 9876543210)
        self.assertEqual(out_f[0].attribute('fid'), 9876543210)
        self.assertEqual(out_f[0].attribute('strfield'), 'bar')

        got = [(f.attribute('fid'), f.attribute('strfield'))
               for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                   "fid = 9876543210"))]
        self.assertEqual(got, [(9876543210, 'bar')])

        self.assertTrue(vl.dataProvider().changeAttributeValues(
            {9876543210: {
                1: 'baz'
            }}))

        got = [(f.attribute('fid'), f.attribute('strfield'))
               for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                   "fid = 9876543210"))]
        self.assertEqual(got, [(9876543210, 'baz')])

        self.assertTrue(vl.dataProvider().changeAttributeValues(
            {9876543210: {
                0: 9876543210,
                1: 'baw'
            }}))

        got = [(f.attribute('fid'), f.attribute('strfield'))
               for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                   "fid = 9876543210"))]
        self.assertEqual(got, [(9876543210, 'baw')])

        # Not allowed: changing the fid regular field
        self.assertTrue(vl.dataProvider().changeAttributeValues(
            {9876543210: {
                0: 12,
                1: 'baw'
            }}))

        got = [(f.attribute('fid'), f.attribute('strfield'))
               for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                   "fid = 9876543210"))]
        self.assertEqual(got, [(9876543210, 'baw')])

        # Cannot delete fid
        self.assertFalse(vl.dataProvider().deleteAttributes([0]))

        # Delete first "genuine" attribute
        self.assertTrue(vl.dataProvider().deleteAttributes([1]))

        got = [(f.attribute('fid'), f.attribute('intfield'))
               for f in vl.dataProvider().getFeatures(
                   QgsFeatureRequest().setFilterExpression("fid = 12"))]
        self.assertEqual(got, [(12, 123)])
Ejemplo n.º 47
0
    def testUpdateMode(self):
        """ Test that on-the-fly re-opening in update/read-only mode works """

        tmpdir = tempfile.mkdtemp()
        self.dirs_to_cleanup.append(tmpdir)
        srcpath = os.path.join(TEST_DATA_DIR, 'provider')
        for file in glob.glob(os.path.join(srcpath, 'shapefile.*')):
            shutil.copy(os.path.join(srcpath, file), tmpdir)
        datasource = os.path.join(tmpdir, 'shapefile.shp')

        vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        caps = vl.dataProvider().capabilities()
        self.assertTrue(caps & QgsVectorDataProvider.AddFeatures)
        self.assertTrue(caps & QgsVectorDataProvider.DeleteFeatures)
        self.assertTrue(caps & QgsVectorDataProvider.ChangeAttributeValues)
        self.assertTrue(caps & QgsVectorDataProvider.AddAttributes)
        self.assertTrue(caps & QgsVectorDataProvider.DeleteAttributes)
        self.assertTrue(caps & QgsVectorDataProvider.CreateSpatialIndex)
        self.assertTrue(caps & QgsVectorDataProvider.SelectAtId)
        self.assertTrue(caps & QgsVectorDataProvider.ChangeGeometries)
        # self.assertTrue(caps & QgsVectorDataProvider.ChangeFeatures)

        # We should be really opened in read-only mode even if write capabilities are declared
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-only")

        # Unbalanced call to leaveUpdateMode()
        self.assertFalse(vl.dataProvider().leaveUpdateMode())

        # Test that startEditing() / commitChanges() plays with enterUpdateMode() / leaveUpdateMode()
        self.assertTrue(vl.startEditing())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-write")
        self.assertTrue(vl.dataProvider().isValid())

        self.assertTrue(vl.commitChanges())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-only")
        self.assertTrue(vl.dataProvider().isValid())

        # Manual enterUpdateMode() / leaveUpdateMode() with 2 depths
        self.assertTrue(vl.dataProvider().enterUpdateMode())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-write")
        caps = vl.dataProvider().capabilities()
        self.assertTrue(caps & QgsVectorDataProvider.AddFeatures)

        f = QgsFeature()
        f.setAttributes([200])
        f.setGeometry(QgsGeometry.fromWkt('Point (2 49)'))
        (ret, feature_list) = vl.dataProvider().addFeatures([f])
        self.assertTrue(ret)
        fid = feature_list[0].id()

        features = [
            f_iter
            for f_iter in vl.getFeatures(QgsFeatureRequest().setFilterFid(fid))
        ]
        values = [f_iter['pk'] for f_iter in features]
        self.assertEqual(values, [200])

        got_geom = [f_iter.geometry() for f_iter in features][0].constGet()
        self.assertEqual((got_geom.x(), got_geom.y()), (2.0, 49.0))

        self.assertTrue(vl.dataProvider().changeGeometryValues(
            {fid: QgsGeometry.fromWkt('Point (3 50)')}))
        self.assertTrue(vl.dataProvider().changeAttributeValues(
            {fid: {
                0: 100
            }}))

        features = [
            f_iter
            for f_iter in vl.getFeatures(QgsFeatureRequest().setFilterFid(fid))
        ]
        values = [f_iter['pk'] for f_iter in features]

        got_geom = [f_iter.geometry() for f_iter in features][0].constGet()
        self.assertEqual((got_geom.x(), got_geom.y()), (3.0, 50.0))

        self.assertTrue(vl.dataProvider().deleteFeatures([fid]))

        # Check that it has really disappeared
        osgeo.gdal.PushErrorHandler('CPLQuietErrorHandler')
        features = [
            f_iter
            for f_iter in vl.getFeatures(QgsFeatureRequest().setFilterFid(fid))
        ]
        osgeo.gdal.PopErrorHandler()
        self.assertEqual(features, [])

        self.assertTrue(vl.dataProvider().addAttributes(
            [QgsField("new_field", QVariant.Int, "integer")]))
        self.assertTrue(vl.dataProvider().deleteAttributes(
            [len(vl.dataProvider().fields()) - 1]))

        self.assertTrue(vl.startEditing())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-write")

        self.assertTrue(vl.commitChanges())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-write")

        self.assertTrue(vl.dataProvider().enterUpdateMode())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-write")

        self.assertTrue(vl.dataProvider().leaveUpdateMode())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-write")

        self.assertTrue(vl.dataProvider().leaveUpdateMode())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-only")

        # Test that update mode will be implictly enabled if doing an action
        # that requires update mode
        (ret, _) = vl.dataProvider().addFeatures([QgsFeature()])
        self.assertTrue(ret)
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"),
                         "read-write")
Ejemplo n.º 48
0
    def testFeatureSourceInput(self):
        # create a memory layer and add to project and context
        layer = QgsVectorLayer(
            "Point?crs=epsg:3857&field=fldtxt:string&field=fldint:integer",
            "testmem", "memory")
        self.assertTrue(layer.isValid())
        pr = layer.dataProvider()
        f = QgsFeature()
        f.setAttributes(["test", 123])
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200)))
        f2 = QgsFeature()
        f2.setAttributes(["test2", 457])
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(110, 200)))
        self.assertTrue(pr.addFeatures([f, f2]))
        self.assertEqual(layer.featureCount(), 2)

        # select first feature
        layer.selectByIds([next(layer.getFeatures()).id()])
        self.assertEqual(len(layer.selectedFeatureIds()), 1)

        QgsProject.instance().addMapLayer(layer)
        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())

        alg = QgsApplication.processingRegistry().createAlgorithmById(
            'grass7:v.buffer')
        self.assertIsNotNone(alg)
        temp_file = os.path.join(self.temp_dir, 'grass_output_sel.shp')
        parameters = {
            'input': QgsProcessingFeatureSourceDefinition('testmem', True),
            'cats': '',
            'where': '',
            'type': [0, 1, 4],
            'distance': 1,
            'minordistance': None,
            'angle': 0,
            'column': None,
            'scale': 1,
            'tolerance': 0.01,
            '-s': False,
            '-c': False,
            '-t': False,
            'output': temp_file,
            'GRASS_REGION_PARAMETER': None,
            'GRASS_SNAP_TOLERANCE_PARAMETER': -1,
            'GRASS_MIN_AREA_PARAMETER': 0.0001,
            'GRASS_OUTPUT_TYPE_PARAMETER': 0,
            'GRASS_VECTOR_DSCO': '',
            'GRASS_VECTOR_LCO': ''
        }
        feedback = QgsProcessingFeedback()

        results, ok = alg.run(parameters, context, feedback)
        self.assertTrue(ok)
        self.assertTrue(os.path.exists(temp_file))

        # make sure that layer has correct features
        res = QgsVectorLayer(temp_file, 'res')
        self.assertTrue(res.isValid())
        self.assertEqual(res.featureCount(), 1)

        QgsProject.instance().removeMapLayer(layer)
Ejemplo n.º 49
0
    def test_postgis_geometry_filter(self):
        """Make sure the postgres provider only returns one matching geometry record and no polygons etc."""
        vl = QgsVectorLayer(self.postgres_conn + ' srid=4326 type=POINT table="qgis_test"."geometries_table" (geom) sql=', 'test', 'postgres')

        ids = [f.id() for f in vl.getFeatures()]
        self.assertEqual(ids, [2])
Ejemplo n.º 50
0
    def testFieldsWithSpecialCharacters(self):
        ml = QgsVectorLayer("Point?srid=EPSG:4326&field=123:int",
                            "mem_with_nontext_fieldnames", "memory")
        self.assertEqual(ml.isValid(), True)
        QgsProject.instance().addMapLayer(ml)

        ml.startEditing()
        self.assertTrue(ml.addAttribute(QgsField('abc:123', QVariant.String)))
        self.assertTrue(ml.addAttribute(QgsField(
            'map', QVariant.String)))  # matches QGIS expression function name
        f1 = QgsFeature(ml.fields())
        f1.setGeometry(QgsGeometry.fromWkt('POINT(0 0)'))
        f1.setAttributes([1, 'a', 'b'])
        f2 = QgsFeature(ml.fields())
        f2.setGeometry(QgsGeometry.fromWkt('POINT(1 1)'))
        f2.setAttributes([2, 'c', 'd'])
        ml.addFeatures([f1, f2])
        ml.commitChanges()

        vl = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames",
                            "vl", "virtual")
        self.assertEqual(vl.isValid(), True)
        self.assertEqual(vl.fields().at(0).name(), '123')
        self.assertEqual(vl.fields().at(1).name(), 'abc:123')

        self.assertEqual(vl.featureCount(), 2)

        features = [
            f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                '"abc:123"=\'c\''))
        ]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [2, 'c', 'd'])

        features = [
            f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression(
                '"map"=\'b\''))
        ]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [1, 'a', 'b'])

        vl2 = QgsVectorLayer(
            "?query=select * from mem_with_nontext_fieldnames where \"abc:123\"='c'",
            "vl", "virtual")
        self.assertEqual(vl2.isValid(), True)
        self.assertEqual(vl2.fields().at(0).name(), '123')
        self.assertEqual(vl2.fields().at(1).name(), 'abc:123')

        self.assertEqual(vl2.featureCount(), 1)

        features = [f for f in vl2.getFeatures()]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [2, 'c', 'd'])

        vl3 = QgsVectorLayer(
            "?query=select * from mem_with_nontext_fieldnames where \"map\"='b'",
            "vl", "virtual")
        self.assertEqual(vl3.isValid(), True)
        self.assertEqual(vl3.fields().at(0).name(), '123')
        self.assertEqual(vl3.fields().at(1).name(), 'abc:123')

        self.assertEqual(vl3.featureCount(), 1)

        features = [f for f in vl3.getFeatures()]
        self.assertEqual(len(features), 1)
        self.assertEqual(features[0].attributes(), [1, 'a', 'b'])

        QgsProject.instance().removeMapLayer(ml)
Ejemplo n.º 51
0
def main():
    """reads in a pre-processed groundwater layer, with recharge-discharge (CSV) and returns tif
    
    Args:
        state(str): state for which well elevations must be obtained
        season(str): e.g. rech-96, disc-96
        
    Returns:
        None: well elevations with locations stored in CSV as SHP
    
    """
    state = sys.argv[1]
    season = sys.argv[2]
    dataPath = root.joinpath("data","groundwater")
    metaPath = root.joinpath("outputs","groundwater","csv",state+"_metadata.log")
    outputsPath = root.joinpath("outputs","groundwater")
    
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(message)s',
                        datefmt='%m/%d/%Y %I:%M:%S %p',
                        handlers=[logging.FileHandler(str(metaPath))],
                       )
    
    logging.info("get Recharge-Discharge for '%s' dataset",state)

    # Initialize QGIS Application
    QgsApplication.setPrefixPath("G:\\Users\\Craig\\miniconda3\\envs\\geo_env\\Library\\python\\qgis", True)
    qgs = QgsApplication([], False)
    qgs.initQgis()
    
    # Append the path where QGIS processing plugin can be found
    sys.path.append('G:\\Users\\Craig\\miniconda3\\envs\\geo_env\\Library\\python\\plugins')
    import processing
    from processing.core.Processing import Processing
    Processing.initialize()
    feedback = QgsProcessingFeedback()
    
    QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())

    # Get file with recharge-discharge values from previous step
    vectorPath = outputsPath.joinpath("shapefiles",state+"_processed_wRD.shp")
    print(vectorPath,vectorPath.exists())
    vLayer = QgsVectorLayer(str(vectorPath), 'well_rech_disc_layer', 'ogr') #.setSubsetString(season + " IS NOT NULL")
    print("islayer valid:", vLayer.isValid())
    
    # subset layer for the chosen season and choose only non null values
    filter = "\"" + season + "\"" + " IS NOT NULL"
    expr = QgsExpression(filter)
    subset = vLayer.getFeatures(QgsFeatureRequest(expr))
    vLayer.selectByIds([k.id() for k in subset])  # why didn't direct selection work? addFeature (false)
    print(vLayer.selectedFeatureCount())
    
    # write subsetted layer to shapefile
    subsetPath = outputsPath.joinpath("shapefiles","noNulls",state+"_"+season+"_noNulls.shp")
    _writer = QgsVectorFileWriter.writeAsVectorFormat(vLayer, str(subsetPath), "utf-8", vLayer.crs(), "ESRI Shapefile", onlySelected=True)
    
    # import subsetted layer
    subLayer = QgsVectorLayer(str(subsetPath), 'well_rech_disc_layer_nonulls', 'ogr') 
    print("is sub layer valid:", subLayer.isValid())
    
    # declare params for grid layer 
    # https://gdal.org/tutorials/gdal_grid_tut.html
    params = {
        'INPUT':subLayer,
        'POWER':2,    # FOR gridinversedistance
#         'RADIUS':0.25,    # FOR gridinversedistancenearestneighbor / gridlinear
#         'RADIUS_1':0.25,    # FOR gridinversedistance / gridnearestneighbor / gridaverage
#         'RADIUS_2':0.25,    # FOR gridinversedistance  /  gridnearestneighbor / gridaverage
        'MAX_POINTS':12,    # FOR gridinversedistance 
        'MIN_POINTS':1,    # FOR gridinversedistance / gridaverage
        'NODATA': -9999,
        'Z_FIELD':season,
        'OUTPUT':str(outputsPath.joinpath("tif","idw",state+"_"+season+"_grid_id_min_1_max_12_nonulls.tif"))
    }
    
    res = processing.run("gdal:gridinversedistance",params,feedback=feedback)
    print(res['OUTPUT'])
Ejemplo n.º 52
0
    def testGeopackageTwoLayerEdition(self):
        ''' test https://issues.qgis.org/issues/17034 '''
        tmpfile = os.path.join(self.basetestpath,
                               'testGeopackageTwoLayerEdition.gpkg')
        ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('layer1', geom_type=ogr.wkbPoint)
        lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTInteger))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 0)'))
        lyr.CreateFeature(f)
        f = None
        lyr = ds.CreateLayer('layer2', geom_type=ogr.wkbPoint)
        lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTInteger))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(1 1)'))
        lyr.CreateFeature(f)
        f = None
        ds = None

        vl1 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1",
                             u'layer1', u'ogr')
        vl2 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer2",
                             u'layer2', u'ogr')

        # Edit vl1, vl2 multiple times
        self.assertTrue(vl1.startEditing())
        self.assertTrue(vl2.startEditing())
        self.assertTrue(
            vl1.changeGeometry(1, QgsGeometry.fromWkt('Point (2 2)')))
        self.assertTrue(
            vl2.changeGeometry(1, QgsGeometry.fromWkt('Point (3 3)')))
        self.assertTrue(vl1.commitChanges())
        self.assertTrue(vl2.commitChanges())

        self.assertTrue(vl1.startEditing())
        self.assertTrue(vl2.startEditing())
        self.assertTrue(vl1.changeAttributeValue(1, 1, 100))
        self.assertTrue(vl2.changeAttributeValue(1, 1, 101))
        self.assertTrue(vl1.commitChanges())
        self.assertTrue(vl2.commitChanges())

        self.assertTrue(vl1.startEditing())
        self.assertTrue(vl2.startEditing())
        self.assertTrue(
            vl1.changeGeometry(1, QgsGeometry.fromWkt('Point (4 4)')))
        self.assertTrue(
            vl2.changeGeometry(1, QgsGeometry.fromWkt('Point (5 5)')))
        self.assertTrue(vl1.commitChanges())
        self.assertTrue(vl2.commitChanges())

        vl1 = None
        vl2 = None

        # Check everything is as expected after re-opening
        vl1 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1",
                             u'layer1', u'ogr')
        vl2 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer2",
                             u'layer2', u'ogr')

        got = [feat for feat in vl1.getFeatures()][0]
        got_geom = got.geometry()
        self.assertEqual(got['attr'], 100)
        reference = QgsGeometry.fromWkt('Point (4 4)')
        self.assertEqual(
            got_geom.asWkb(), reference.asWkb(),
            'Expected {}, got {}'.format(reference.asWkt(), got_geom.asWkt()))

        got = [feat for feat in vl2.getFeatures()][0]
        got_geom = got.geometry()
        self.assertEqual(got['attr'], 101)
        reference = QgsGeometry.fromWkt('Point (5 5)')
        self.assertEqual(
            got_geom.asWkb(), reference.asWkb(),
            'Expected {}, got {}'.format(reference.asWkt(), got_geom.asWkt()))
Ejemplo n.º 53
0
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES,
                                           context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD,
                                           context)
        geometry_field = self.parameterAsString(parameters,
                                                self.INPUT_GEOMETRY_FIELD,
                                                context)
        geometry_type = self.parameterAsEnum(parameters,
                                             self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS,
                                           context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):
            df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.
                tr('Empty SQL. Please enter valid SQL expression and try again.'
                   ))
        else:
            localContext = self.createExpressionContext(parameters, context)
            expandedQuery = QgsExpression.replaceExpressionText(
                query, localContext)
            df.setQuery(expandedQuery)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(
                vLayer.dataProvider().error().message())

        (sink, dest_id) = self.parameterAsSink(
            parameters, self.OUTPUT, context, vLayer.fields(),
            vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        features = vLayer.getFeatures()
        total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}
Ejemplo n.º 54
0
    def start_progress(self):
        import datetime
        start = datetime.datetime.now()
        # Check OS and dep
        if sys.platform == 'darwin':
            gdal_os_dep = '/Library/Frameworks/GDAL.framework/Versions/Current/Programs/'
        else:
            gdal_os_dep = ''

        if self.dlg.canvasButton.isChecked():
            # Map Canvas
            extentCanvasCRS = self.iface.mapCanvas()
            srs = extentCanvasCRS.mapSettings().destinationCrs()
            crs = str(srs.authid())
            # old_crs = osr.SpatialReference()
            # old_crs.ImportFromEPSG(int(crs[5:]))
            can_crs = QgsCoordinateReferenceSystem(int(crs[5:]))
            # can_wkt = extentCanvasCRS.mapRenderer().destinationCrs().toWkt()
            # can_crs = osr.SpatialReference()
            # can_crs.ImportFromWkt(can_wkt)
            # Raster Layer
            dem_layer = self.layerComboManagerDEM.currentLayer()
            dem_prov = dem_layer.dataProvider()
            dem_path = str(dem_prov.dataSourceUri())
            dem_raster = gdal.Open(dem_path)
            projdsm = osr.SpatialReference(wkt=dem_raster.GetProjection())
            projdsm.AutoIdentifyEPSG()
            projdsmepsg = int(projdsm.GetAttrValue('AUTHORITY', 1))
            dem_crs = QgsCoordinateReferenceSystem(projdsmepsg)

            # dem_wkt = dem_raster.GetProjection()
            # dem_crs = osr.SpatialReference()
            # dem_crs.ImportFromWkt(dem_wkt)
            if can_crs != dem_crs:
                extentCanvas = self.iface.mapCanvas().extent()
                extentDEM = dem_layer.extent()

                transformExt = QgsCoordinateTransform(can_crs, dem_crs)
                # transformExt = osr.CoordinateTransformation(can_crs, dem_crs)

                canminx = extentCanvas.xMinimum()
                canmaxx = extentCanvas.xMaximum()
                canminy = extentCanvas.yMinimum()
                canmaxy = extentCanvas.yMaximum()

                canxymin = transformExt.TransformPoint(canminx, canminy)
                canxymax = transformExt.TransformPoint(canmaxx, canmaxy)

                extDiffminx = canxymin[0] - extentDEM.xMinimum(
                )  # If smaller than zero = warning
                extDiffminy = canxymin[1] - extentDEM.yMinimum(
                )  # If smaller than zero = warning
                extDiffmaxx = canxymax[0] - extentDEM.xMaximum(
                )  # If larger than zero = warning
                extDiffmaxy = canxymax[0] - extentDEM.yMaximum(
                )  # If larger than zero = warning

                if extDiffminx < 0 or extDiffminy < 0 or extDiffmaxx > 0 or extDiffmaxy > 0:
                    QMessageBox.warning(
                        None,
                        "Warning! Extent of map canvas is larger than raster extent.",
                        "Change to an extent equal to or smaller than the raster extent."
                    )
                    return

        # Extent
        self.yMax = self.dlg.lineEditNorth.text()
        self.yMin = self.dlg.lineEditSouth.text()
        self.xMin = self.dlg.lineEditWest.text()
        self.xMax = self.dlg.lineEditEast.text()

        if not self.DSMoutputfile:
            QMessageBox.critical(None, "Error", "Specify a raster output file")
            return

        if self.dlg.checkBoxPolygon.isChecked() and not self.OSMoutputfile:
            QMessageBox.critical(None, "Error",
                                 "Specify an output file for OSM data")
            return

        # Acquiring geodata and attributes
        dem_layer = self.layerComboManagerDEM.currentLayer()
        if dem_layer is None:
            QMessageBox.critical(None, "Error",
                                 "No valid raster layer is selected")
            return
        else:
            provider = dem_layer.dataProvider()
            filepath_dem = str(provider.dataSourceUri())
        demRaster = gdal.Open(filepath_dem)
        dem_layer_crs = osr.SpatialReference()
        dem_layer_crs.ImportFromWkt(demRaster.GetProjection())
        self.dem_layer_unit = dem_layer_crs.GetAttrValue("UNIT")
        posUnits = [
            'metre', 'US survey foot', 'meter', 'm', 'ft', 'feet', 'foot',
            'ftUS', 'International foot'
        ]  # Possible units
        if not self.dem_layer_unit in posUnits:
            QMessageBox.critical(
                None, "Error",
                "Raster projection is not in metre or foot. Please reproject.")
            return

        polygon_layer = self.layerComboManagerPolygon.currentLayer()
        osm_layer = self.dlg.checkBoxOSM.isChecked()
        if polygon_layer is None and osm_layer is False:
            QMessageBox.critical(None, "Error",
                                 "No valid building height layer is selected")
            return
        elif polygon_layer:
            vlayer = QgsVectorLayer(polygon_layer.source(), "buildings", "ogr")
            fileInfo = QFileInfo(polygon_layer.source())
            polygon_ln = fileInfo.baseName()

            polygon_field = self.layerComboManagerPolygonField.currentField()
            idx = vlayer.fieldNameIndex(polygon_field)
            flname = vlayer.attributeDisplayName(idx)

            if idx == -1:
                QMessageBox.critical(
                    None, "Error",
                    "An attribute with unique fields must be selected")
                return

        ### main code ###

        self.dlg.progressBar.setRange(0, 5)

        self.dlg.progressBar.setValue(1)

        if self.dlg.checkBoxOSM.isChecked():
            # TODO replace osr.CoordinateTransformation with QgsCoordinateTransform
            dem_original = gdal.Open(filepath_dem)
            dem_wkt = dem_original.GetProjection()
            ras_crs = osr.SpatialReference()
            ras_crs.ImportFromWkt(dem_wkt)
            rasEPSG = ras_crs.GetAttrValue("PROJCS|AUTHORITY", 1)
            if self.dlg.layerButton.isChecked():
                old_crs = ras_crs
            elif self.dlg.canvasButton.isChecked():
                canvasCRS = self.iface.mapCanvas()
                outputWkt = canvasCRS.mapRenderer().destinationCrs().toWkt()
                old_crs = osr.SpatialReference()
                old_crs.ImportFromWkt(outputWkt)

            wgs84_wkt = """
            GEOGCS["WGS 84",
                DATUM["WGS_1984",
                    SPHEROID["WGS 84",6378137,298.257223563,
                        AUTHORITY["EPSG","7030"]],
                    AUTHORITY["EPSG","6326"]],
                PRIMEM["Greenwich",0,
                    AUTHORITY["EPSG","8901"]],
                UNIT["degree",0.01745329251994328,
                    AUTHORITY["EPSG","9122"]],
                AUTHORITY["EPSG","4326"]]"""

            new_crs = osr.SpatialReference()
            new_crs.ImportFromWkt(wgs84_wkt)

            transform = osr.CoordinateTransformation(old_crs, new_crs)

            minx = float(self.xMin)
            miny = float(self.yMin)
            maxx = float(self.xMax)
            maxy = float(self.yMax)
            lonlatmin = transform.TransformPoint(minx, miny)
            lonlatmax = transform.TransformPoint(maxx, maxy)

            if ras_crs != old_crs:
                rasTrans = osr.CoordinateTransformation(old_crs, ras_crs)
                raslonlatmin = rasTrans.TransformPoint(float(self.xMin),
                                                       float(self.yMin))
                raslonlatmax = rasTrans.TransformPoint(float(self.xMax),
                                                       float(self.yMax))
                #else:
                #raslonlatmin = [float(self.xMin), float(self.yMin)]
                #raslonlatmax = [float(self.xMax), float(self.yMax)]

                self.xMin = raslonlatmin[0]
                self.yMin = raslonlatmin[1]
                self.xMax = raslonlatmax[0]
                self.yMax = raslonlatmax[1]

            # Make data queries to overpass-api
            urlStr = 'http://overpass-api.de/api/map?bbox=' + str(
                lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str(
                    lonlatmax[0]) + ',' + str(lonlatmax[1])
            osmXml = urllib.urlopen(urlStr).read()
            #print urlStr

            # Make OSM building file
            osmPath = self.plugin_dir + '/temp/OSM_building.osm'
            osmFile = open(osmPath, 'w')
            osmFile.write(osmXml)
            if os.fstat(osmFile.fileno()).st_size < 1:
                urlStr = 'http://api.openstreetmap.org/api/0.6/map?bbox=' + str(
                    lonlatmin[0]) + ',' + str(lonlatmin[1]) + ',' + str(
                        lonlatmax[0]) + ',' + str(lonlatmax[1])
                osmXml = urllib.urlopen(urlStr).read()
                osmFile.write(osmXml)
                #print 'Open Street Map'
                if os.fstat(osmFile.fileno()).st_size < 1:
                    QMessageBox.critical(None, "Error",
                                         "No OSM data available")
                    return

            osmFile.close()

            outputshp = self.plugin_dir + '/temp/'

            osmToShape = gdal_os_dep + 'ogr2ogr --config OSM_CONFIG_FILE "' + self.plugin_dir + '/osmconf.ini" -skipfailures -t_srs EPSG:' + str(
                rasEPSG
            ) + ' -overwrite -nlt POLYGON -f "ESRI Shapefile" "' + outputshp + '" "' + osmPath + '"'

            if sys.platform == 'win32':
                si = subprocess.STARTUPINFO()
                si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                subprocess.call(osmToShape, startupinfo=si)
            else:
                os.system(osmToShape)

            driver = ogr.GetDriverByName('ESRI Shapefile')
            driver.DeleteDataSource(outputshp + 'lines.shp')
            driver.DeleteDataSource(outputshp + 'multilinestrings.shp')
            driver.DeleteDataSource(outputshp + 'other_relations.shp')
            driver.DeleteDataSource(outputshp + 'points.shp')

            osmPolygonPath = outputshp + 'multipolygons.shp'
            vlayer = QgsVectorLayer(osmPolygonPath, 'multipolygons', 'ogr')
            polygon_layer = vlayer
            fileInfo = QFileInfo(polygon_layer.source())
            polygon_ln = fileInfo.baseName()

            def renameField(srcLayer, oldFieldName, newFieldName):
                ds = gdal.OpenEx(srcLayer.source(),
                                 gdal.OF_VECTOR | gdal.OF_UPDATE)
                ds.ExecuteSQL('ALTER TABLE {} RENAME COLUMN {} TO {}'.format(
                    srcLayer.name(), oldFieldName, newFieldName))
                srcLayer.reload()

            vlayer.startEditing()
            renameField(vlayer, 'building_l', 'bld_levels')
            renameField(vlayer, 'building_h', 'bld_hght')
            renameField(vlayer, 'building_c', 'bld_colour')
            renameField(vlayer, 'building_m', 'bld_materi')
            renameField(vlayer, 'building_u', 'bld_use')
            vlayer.commitChanges()

            vlayer.startEditing()
            vlayer.dataProvider().addAttributes(
                [QgsField('bld_height', QVariant.Double, 'double', 3, 2)])
            vlayer.updateFields()
            bld_lvl = vlayer.fieldNameIndex('bld_levels')
            hght = vlayer.fieldNameIndex('height')
            bld_hght = vlayer.fieldNameIndex('bld_hght')
            bld_height = vlayer.fieldNameIndex('bld_height')

            bldLvlHght = float(self.dlg.doubleSpinBoxBldLvl.value())
            illegal_chars = string.ascii_letters + "!#$%&'*+^_`|~:" + " "
            counterNone = 0
            counter = 0
            #counterWeird = 0
            for feature in vlayer.getFeatures():
                if feature[hght]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[hght])))
                        feature[bld_height] = float(
                            str(feature[hght]).translate(None, illegal_chars))
                    except:
                        counterNone += 1
                elif feature[bld_hght]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", ".", str(feature[bld_hght])))
                        feature[bld_height] = float(
                            str(feature[bld_hght]).translate(
                                None, illegal_chars))
                    except:
                        counterNone += 1
                elif feature[bld_lvl]:
                    try:
                        #feature[bld_height] = float(re.sub("[^0-9]", "", str(feature[bld_lvl])))*bldLvlHght
                        feature[bld_height] = float(
                            str(feature[bld_lvl]).translate(
                                None, illegal_chars)) * bldLvlHght
                    except:
                        counterNone += 1
                else:
                    counterNone += 1
                vlayer.updateFeature(feature)
                counter += 1
            vlayer.commitChanges()
            flname = vlayer.attributeDisplayName(bld_height)
            counterDiff = counter - counterNone

        # Zonal statistics
        vlayer.startEditing()
        zoneStat = QgsZonalStatistics(vlayer, filepath_dem, "stat_", 1,
                                      QgsZonalStatistics.Mean)
        zoneStat.calculateStatistics(None)
        vlayer.dataProvider().addAttributes(
            [QgsField('height_asl', QVariant.Double)])
        vlayer.updateFields()
        e = QgsExpression('stat_mean + ' + flname)
        e.prepare(vlayer.pendingFields())
        idx = vlayer.fieldNameIndex('height_asl')

        for f in vlayer.getFeatures():
            f[idx] = e.evaluate(f)
            vlayer.updateFeature(f)

        vlayer.commitChanges()

        vlayer.startEditing()
        idx2 = vlayer.fieldNameIndex('stat_mean')
        vlayer.dataProvider().deleteAttributes([idx2])
        vlayer.updateFields()
        vlayer.commitChanges()

        self.dlg.progressBar.setValue(2)

        # Convert polygon layer to raster

        # Define pixel_size and NoData value of new raster
        pixel_size = self.dlg.spinBox.value()  # half picture size

        # Create the destination data source

        gdalrasterize = gdal_os_dep + 'gdal_rasterize -a ' + 'height_asl' + ' -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\
                        ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + ' -l "' + str(polygon_ln) + '" "' \
                         + str(polygon_layer.source()) + '" "' + self.plugin_dir + '/temp/clipdsm.tif"'

        # gdalclipdem = gdal_os_dep + 'gdalwarp -dstnodata -9999 -q -overwrite -te ' + str(self.xMin) + ' ' + str(self.yMin) + ' ' + str(self.xMax) + ' ' + str(self.yMax) +\
        #               ' -tr ' + str(pixel_size) + ' ' + str(pixel_size) + \
        #               ' -of GTiff ' + '"' + filepath_dem + '" "' + self.plugin_dir + '/temp/clipdem.tif"'

        # Rasterize
        if sys.platform == 'win32':
            si = subprocess.STARTUPINFO()
            si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            subprocess.call(gdalrasterize, startupinfo=si)
            # subprocess.call(gdalclipdem, startupinfo=si)
            gdal.Warp(self.plugin_dir + '/temp/clipdem.tif',
                      filepath_dem,
                      xRes=pixel_size,
                      yRes=pixel_size)
        else:
            os.system(gdalrasterize)
            # os.system(gdalclipdem)
            gdal.Warp(self.plugin_dir + '/temp/clipdem.tif',
                      filepath_dem,
                      xRes=pixel_size,
                      yRes=pixel_size)

        # Remove gdalwarp with gdal.Translate
        # bigraster = gdal.Open(filepath_dem)
        # bbox = (self.xMin, self.yMax, self.xMax, self.yMin)
        # gdal.Translate(self.plugin_dir + '/data/clipdem.tif', bigraster, projWin=bbox)

        self.dlg.progressBar.setValue(3)

        # Adding DSM to DEM
        # Read DEM
        dem_raster = gdal.Open(self.plugin_dir + '/temp/clipdem.tif')
        dem_array = np.array(dem_raster.ReadAsArray().astype(np.float))
        dsm_raster = gdal.Open(self.plugin_dir + '/temp/clipdsm.tif')
        dsm_array = np.array(dsm_raster.ReadAsArray().astype(np.float))

        indx = dsm_array.shape
        for ix in range(0, int(indx[0])):
            for iy in range(0, int(indx[1])):
                if int(dsm_array[ix, iy]) == 0:
                    dsm_array[ix, iy] = dem_array[ix, iy]

        if self.dlg.checkBoxPolygon.isChecked():
            vlayer.startEditing()
            idxHght = vlayer.fieldNameIndex('height_asl')
            idxBld = vlayer.fieldNameIndex('building')
            features = vlayer.getFeatures()
            #for f in vlayer.getFeatures():
            for f in features:
                geom = f.geometry()
                posUnitsMetre = ['metre', 'meter', 'm']  # Possible metre units
                posUnitsFt = [
                    'US survey foot', 'ft', 'feet', 'foot', 'ftUS',
                    'International foot'
                ]  # Possible foot units
                if self.dem_layer_unit in posUnitsMetre:
                    sqUnit = 1
                elif self.dem_layer_unit in posUnitsFt:
                    sqUnit = 10.76
                if int(geom.area()) > 50000 * sqUnit:
                    vlayer.deleteFeature(f.id())

                #if not f[idxHght]:
                #vlayer.deleteFeature(f.id())
                #elif not f[idxBld]:
                #vlayer.deleteFeature(f.id())
            vlayer.updateFields()
            vlayer.commitChanges()
            QgsVectorFileWriter.writeAsVectorFormat(vlayer,
                                                    str(self.OSMoutputfile),
                                                    "UTF-8", None,
                                                    "ESRI Shapefile")

        else:
            vlayer.startEditing()
            idx3 = vlayer.fieldNameIndex('height_asl')
            vlayer.dataProvider().deleteAttributes([idx3])
            vlayer.updateFields()
            vlayer.commitChanges()

        self.dlg.progressBar.setValue(4)

        # Save raster
        def saveraster(
            gdal_data, filename, raster
        ):  # gdal_data = raster extent, filename = output filename, raster = numpy array (raster to be saved)
            rows = gdal_data.RasterYSize
            cols = gdal_data.RasterXSize

            outDs = gdal.GetDriverByName("GTiff").Create(
                filename, cols, rows, int(1), gdal.GDT_Float32)
            outBand = outDs.GetRasterBand(1)

            # write the data
            outBand.WriteArray(raster, 0, 0)
            # flush data to disk, set the NoData value and calculate stats
            outBand.FlushCache()
            outBand.SetNoDataValue(-9999)

            # georeference the image and set the projection
            outDs.SetGeoTransform(gdal_data.GetGeoTransform())
            outDs.SetProjection(gdal_data.GetProjection())

        saveraster(dsm_raster, self.DSMoutputfile, dsm_array)

        # Load result into canvas
        rlayer = self.iface.addRasterLayer(self.DSMoutputfile)

        # Trigger a repaint
        if hasattr(rlayer, "setCacheImage"):
            rlayer.setCacheImage(None)
        rlayer.triggerRepaint()

        self.dlg.progressBar.setValue(5)

        #runTime = datetime.datetime.now() - start

        if self.dlg.checkBoxOSM.isChecked():
            QMessageBox.information(
                self.dlg, 'DSM Generator', 'Operation successful! ' +
                str(counterDiff) + ' building polygons out of ' +
                str(counter) + ' contained height values.')
            #self.iface.messageBar().pushMessage("DSM Generator. Operation successful! " + str(counterDiff) + " buildings out of " + str(counter) + " contained height values.", level=QgsMessageBar.INFO, duration=5)
        else:
            #self.iface.messageBar().pushMessage("DSM Generator. Operation successful!", level=QgsMessageBar.INFO, duration=5)
            QMessageBox.information(self.dlg, 'DSM Generator',
                                    'Operation successful!')

        self.resetPlugin()
Ejemplo n.º 55
0
    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()
class StartOutofBoundsAngles:
    def __init__(self, iface):

        self.iface = iface

        self.tableSchema = 'edgv'
        self.geometryColumn = 'geom'
        self.keyColumn = 'id'
        self.angle = 10

    def initGui(self):
        # cria uma ação que iniciará a configuração do plugin
        pai = self.iface.mainWindow()
        icon_path = ':/plugins/StartOutofBoundsAngles/icon.png'
        self.action = QAction(
            QIcon(icon_path),
            u"Acessa banco de dados para encontrar anglos fechados.", pai)
        self.action.setObjectName("Start database")
        self.action.setStatusTip(None)
        self.action.setWhatsThis(None)
        self.action.triggered.connect(self.run)
        # Adicionar o botão icone
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        # remove o item de ícone do QGIS GUI.
        self.iface.removeToolBarIcon(self.action)

    def run(self):

        ##################################
        ###### PEGA A LAYER ATIVA ########
        ##################################

        layer = self.iface.activeLayer()

        if not layer:
            self.iface.messageBar().pushMessage("Erro",
                                                u"Esperando uma Active Layer!",
                                                level=QgsMessageBar.CRITICAL,
                                                duration=4)
            return
        if layer.featureCount() == 0:
            self.iface.messageBar().pushMessage(
                "Erro",
                u"a camada não possui feições!",
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

        parametros = layer.source().split(
            " "
        )  # recebe todos os parametros em uma lista ( senha, porta, password etc..)

        ####################################
        ###### INICIANDO CONEXÃO DB ########
        ####################################

        # Outra opção para isso, seria usar ex: self.dbname.. self.host.. etc.. direto dentro do laço for.
        dbname = ""
        host = ""
        port = 0
        user = ""
        password = ""

        for i in parametros:
            part = i.split("=")

            # Recebe os parametros guardados na própria Layer

            if "dbname" in part[0]:
                dbname = part[1].replace("'", "")

            elif "host" in part[0]:
                host = part[1].replace("'", "")

            elif "port" in part[0]:
                port = int(part[1].replace("'", ""))

            elif "user" in part[0]:
                user = part[1].replace("'", "")

            elif "password" in part[0]:
                password = part[1].split("|")[0].replace("'", "")

        print dbname, host, port, user, password

        # Testa se os parametros receberam os valores pretendidos, caso não, apresenta a mensagem informando..
        if len(dbname) == 0 or len(host) == 0 or port == 0 or len(
                user) == 0 or len(password) == 0:
            self.iface.messageBar().pushMessage(
                "Erro",
                u'Um dos parametros não foram devidamente recebidos!',
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

    ####################################
    #### SETA VALORES DE CONEXÃO DB ####
    ####################################

        connection = QSqlDatabase.addDatabase('QPSQL')
        connection.setHostName(host)
        connection.setPort(port)
        connection.setUserName(user)
        connection.setPassword(password)
        connection.setDatabaseName(dbname)

        if not connection.isOpen(
        ):  # Testa se a conexão esta recebendo os parametros adequadamente.
            if not connection.open():
                print 'Error connecting to database!'
                self.iface.messageBar().pushMessage(
                    "Erro",
                    u'Error connecting to database!',
                    level=QgsMessageBar.CRITICAL,
                    duration=4)
                print connection.lastError().text()
                return

    ####################################
    ###### CRIAÇÃO DE MEMORY LAYER #####
    ####################################

        layerCrs = layer.crs().authid()  # Passa o formato (epsg: numeros)

        flagsLayerName = layer.name() + "_flags"
        flagsLayerExists = False

        for l in QgsMapLayerRegistry.instance().mapLayers().values(
        ):  # Recebe todas as camadas que estão abertas
            if l.name() == flagsLayerName:  # ao encontrar o nome pretendido..
                self.flagsLayer = l  # flagslayer vai receber o nome..
                self.flagsLayerProvider = l.dataProvider()
                flagsLayerExists = True  # se encontrado os parametros buscados, recebe True.
                break

        if flagsLayerExists == False:  # se não encontrado os parametros buscados, recebe False.
            tempString = "Point?crs="
            tempString += str(layerCrs)

            self.flagsLayer = QgsVectorLayer(tempString, flagsLayerName,
                                             "memory")
            self.flagsLayerProvider = self.flagsLayer.dataProvider()
            self.flagsLayerProvider.addAttributes([
                QgsField("flagId", QVariant.Int),
                QgsField("geomId", QVariant.String),
                QgsField("motivo", QVariant.String)
            ])
            self.flagsLayer.updateFields()

        self.flagsLayer.startEditing()
        ids = [feat.id() for feat in self.flagsLayer.getFeatures()]
        self.flagsLayer.deleteFeatures(ids)
        self.flagsLayer.commitChanges()

        lista_fid = []  # Iniciando lista
        for f in layer.getFeatures():
            lista_fid.append(
                str(f.id())
            )  # Guarda na lista. A lista de Feature ids passa tipo "int", foi convertido e guardado como "str".

        source = layer.source().split(" ")
        self.tableName = ""  # Inicia vazio
        layerExistsInDB = False

        for i in source:

            if "table=" in i or "layername=" in i:  # Se encontrar os atributos pretendidos dentre todos do for
                self.tableName = source[source.index(i)].split(".")[
                    1]  # Faz split em ponto e pega a segunda parte.
                self.tableName = self.tableName.replace('"', '')
                layerExistsInDB = True
                break

        if layerExistsInDB == False:
            self.iface.messageBar().pushMessage(
                "Erro",
                u"Provedor da camada corrente não provem do banco de dados!",
                level=QgsMessageBar.CRITICAL,
                duration=4)
            return

        geomType = layer.geometryType()

        if geomType == QGis.Line:

            # Busca através do SQL
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-2)) as pt1, 
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")-1)) as anchor,
                              ST_PointN("{3}", generate_series(3, ST_NPoints("{3}"))) as pt2,
                              linestrings."{4}" as "{4}" 
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump("{3}")).geom as "{3}"
                               FROM only "{0}"."{1}"
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format(
                self.tableSchema, self.tableName, self.angle,
                self.geometryColumn, self.keyColumn, ",".join(lista_fid))

        elif geomType == QGis.Polygon:
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1)) as pt1,
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1) %  (ST_NPoints("{3}")-1)+1) as anchor,
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")) %  (ST_NPoints("{3}")-1)+1) as pt2,
                              linestrings."{4}" as "{4}"
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump(ST_Boundary(ST_ForceRHR((ST_Dump("{3}")).geom)))).geom as "{3}"
                               FROM only "{0}"."{1}" 
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format(
                self.tableSchema, self.tableName, self.angle,
                self.geometryColumn, self.keyColumn, ",".join(lista_fid))
        query = QSqlQuery(sql)

        self.flagsLayer.startEditing()
        flagCount = 0  # iniciando contador que será referência para os IDs da camada de memória.

        listaFeatures = []
        while query.next():
            id = query.value(0)
            local = query.value(1)
            angulo = query.value(2)
            flagId = flagCount

            print id, local, angulo

            flagFeat = QgsFeature()
            flagGeom = QgsGeometry.fromWkt(
                local)  # passa o local onde foi localizado o erro.
            flagFeat.setGeometry(flagGeom)
            flagFeat.initAttributes(3)
            flagFeat.setAttribute(
                0, flagId
            )  # insere o id definido para a coluna 0 da layer de memória.
            flagFeat.setAttribute(
                1, id
            )  # insere o id da geometria  para a coluna 1 da layer de memória.
            flagFeat.setAttribute(
                2, u"Ângulo para os vértices adjacentes inferior à tolerância")

            # TypeError: fromWkt(QString): argument 1 has unexpected type 'long'
            #     Traceback (most recent call last):
            #     File "/home/piangers/.qgis2/python/plugins/StartDuplic/StartDuplic.py", line 177, in run
            #     flagGeom = QgsGeometry.fromWkt(local) # passa o local onde foi localizado o erro.

            listaFeatures.append(flagFeat)

            flagCount += 1  # incrementando o contador a cada iteração

        self.flagsLayerProvider.addFeatures(listaFeatures)
        self.flagsLayer.commitChanges()  # Aplica as alterações à camada.

        QgsMapLayerRegistry.instance().addMapLayer(
            self.flagsLayer)  # Adicione a camada no mapa

        if flagCount == 0:

            QgsMapLayerRegistry.instance().removeMapLayer(self.flagsLayer.id())
            self.iface.messageBar().pushMessage(
                "Aviso",
                u"Não foi encontrado Flags em \"" + layer.name() + "\" !",
                level=QgsMessageBar.CRITICAL,
                duration=4)

            return
        if len(query.lastError().text()) == 1:
            self.iface.messageBar().pushMessage(
                "Aviso",
                "foram geradas " + str(flagCount) + " flags para a camada \"" +
                layer.name() + "\" !",
                level=QgsMessageBar.INFO,
                duration=4)
        else:
            self.iface.messageBar().pushMessage("Erro",
                                                u"a geração de flags falhou!",
                                                level=QgsMessageBar.CRITICAL,
                                                duration=4)
            print query.lastError().text()
Ejemplo n.º 57
0
    def processAlgorithm(self, progress):
        inLayers = self.getParameterValue(self.LAYERS)
        paths = inLayers.split(';')

        layers = []
        fields = QgsFields()
        totalFeatureCount = 0
        for x in range(len(paths)):
            layer = QgsVectorLayer(paths[x], str(x), 'ogr')

            if (len(layers) > 0):
                if (layer.wkbType() != layers[0].wkbType()):
                    raise GeoAlgorithmExecutionException(
                        self.tr('All layers must have same geometry type!'))

            layers.append(layer)
            totalFeatureCount += layer.featureCount()

            for sindex, sfield in enumerate(layer.fields()):
                found = None
                for dfield in fields:
                    if (dfield.name().upper() == sfield.name().upper()):
                        found = dfield
                        if (dfield.type() != sfield.type()):
                            raise GeoAlgorithmExecutionException(
                                self.tr('{} field in layer {} has different '
                                        'data type than in other layers.'))

                if not found:
                    fields.append(sfield)

        total = 100.0 / totalFeatureCount
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields.toList(), layers[0].wkbType(), layers[0].crs())

        featureCount = 0
        for layer in layers:
            for feature in layer.getFeatures():
                sattributes = feature.attributes()
                dattributes = []
                for dindex, dfield in enumerate(fields):
                    if (dfield.type() == QVariant.Int, QVariant.UInt,
                            QVariant.LongLong, QVariant.ULongLong):
                        dattribute = 0
                    elif (dfield.type() == QVariant.Double):
                        dattribute = 0.0
                    else:
                        dattribute = ''

                    for sindex, sfield in enumerate(layer.fields()):
                        if (sfield.name().upper() == dfield.name().upper()):
                            if (sfield.type() != dfield.type()):
                                raise GeoAlgorithmExecutionException(
                                    self.tr('Attribute type mismatch'))
                            dattribute = sattributes[sindex]
                            break

                    dattributes.append(dattribute)

                feature.setAttributes(dattributes)
                writer.addFeature(feature)
                featureCount += 1
                progress.setPercentage(int(featureCount * total))

        del writer
Ejemplo n.º 58
0
def polygonize(layer, callback=None):
    """Polygonize a raster layer into a vector layer using GDAL.

    Issue https://github.com/inasafe/inasafe/issues/3183

    :param layer: The layer to reproject.
    :type layer: QgsRasterLayer

    :param callback: A function to all to indicate progress. The function
        should accept params 'current' (int) and 'maximum' (int). Defaults to
        None.
    :type callback: function

    :return: Reprojected memory layer.
    :rtype: QgsRasterLayer

    .. versionadded:: 4.0
    """
    output_layer_name = polygonize_steps['output_layer_name']
    processing_step = polygonize_steps['step_name']  # NOQA
    output_layer_name = output_layer_name % layer.keywords['layer_purpose']
    gdal_layer_name = polygonize_steps['gdal_layer_name']

    if layer.keywords.get('layer_purpose') == 'exposure':
        output_field = exposure_type_field
    else:
        output_field = hazard_value_field

    input_raster = gdal.Open(layer.source(), gdal.GA_ReadOnly)

    srs = osr.SpatialReference()
    srs.ImportFromWkt(input_raster.GetProjectionRef())

    temporary_dir = temp_dir(sub_dir='pre-process')
    out_shapefile = unique_filename(suffix='-%s.shp' % output_layer_name,
                                    dir=temporary_dir)

    driver = ogr.GetDriverByName("ESRI Shapefile")
    destination = driver.CreateDataSource(out_shapefile)

    output_layer = destination.CreateLayer(gdal_layer_name, srs)

    # We have no other way to use a shapefile. We need only the first 10 chars.
    field_name = output_field['field_name'][0:10]
    fd = ogr.FieldDefn(field_name, ogr.OFTInteger)
    output_layer.CreateField(fd)

    active_band = layer.keywords.get('active_band', 1)
    input_band = input_raster.GetRasterBand(active_band)
    # Fixme : add our own callback to Polygonize
    gdal.Polygonize(input_band, None, output_layer, 0, [], callback=None)
    destination.Destroy()

    vector_layer = QgsVectorLayer(out_shapefile, output_layer_name, 'ogr')

    # Let's remove polygons which were no data
    request = QgsFeatureRequest()
    expression = '"%s" = %s' % (field_name, no_data_value)
    request.setFilterExpression(expression)
    vector_layer.startEditing()
    for feature in vector_layer.getFeatures(request):
        vector_layer.deleteFeature(feature.id())
    vector_layer.commitChanges()

    # We transfer keywords to the output.
    vector_layer.keywords = layer.keywords.copy()
    vector_layer.keywords[
        layer_geometry['key']] = layer_geometry_polygon['key']

    vector_layer.keywords['title'] = output_layer_name
    # We just polygonized the raster layer. inasafe_fields do not exist.
    vector_layer.keywords['inasafe_fields'] = {output_field['key']: field_name}

    check_layer(vector_layer)
    return vector_layer
Ejemplo n.º 59
0
    def testWriteShapefileWithZ(self):
        """Check writing geometries with Z dimension to an ESRI shapefile."""

        # start by saving a memory layer and forcing z
        ml = QgsVectorLayer(('Point?crs=epsg:4326&field=id:int'), 'test',
                            'memory')

        self.assertIsNotNone(ml, 'Provider not initialized')
        self.assertTrue(ml.isValid(), 'Source layer not valid')
        provider = ml.dataProvider()
        self.assertIsNotNone(provider)

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromWkt('PointZ (1 2 3)'))
        ft.setAttributes([1])
        res, features = provider.addFeatures([ft])
        self.assertTrue(res)
        self.assertTrue(features)

        # check with both a standard PointZ and 25d style Point25D type
        for t in [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D]:
            dest_file_name = os.path.join(
                str(QDir.tempPath()),
                'point_{}.shp'.format(QgsWkbTypes.displayString(t)))
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
                ml,
                dest_file_name,
                'utf-8',
                crs,
                'ESRI Shapefile',
                overrideGeometryType=t)
            self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                             error_message)

            # Open result and check
            created_layer = QgsVectorLayer(
                '{}|layerid=0'.format(dest_file_name), 'test', 'ogr')
            f = next(created_layer.getFeatures(QgsFeatureRequest()))
            g = f.geometry()
            wkt = g.asWkt()
            expWkt = 'PointZ (1 2 3)'
            self.assertTrue(
                compareWkt(expWkt, wkt),
                "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n"
                % (expWkt, wkt))

            # also try saving out the shapefile version again, as an extra test
            # this tests that saving a layer with z WITHOUT explicitly telling the writer to keep z values,
            # will stay retain the z values
            dest_file_name = os.path.join(
                str(QDir.tempPath()),
                'point_{}_copy.shp'.format(QgsWkbTypes.displayString(t)))
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
                created_layer, dest_file_name, 'utf-8', crs, 'ESRI Shapefile')
            self.assertEqual(write_result, QgsVectorFileWriter.NoError,
                             error_message)

            # Open result and check
            created_layer_from_shp = QgsVectorLayer(
                '{}|layerid=0'.format(dest_file_name), 'test', 'ogr')
            f = next(created_layer_from_shp.getFeatures(QgsFeatureRequest()))
            g = f.geometry()
            wkt = g.asWkt()
            self.assertTrue(
                compareWkt(expWkt, wkt),
                "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n"
                % (expWkt, wkt))
Ejemplo n.º 60
-1
    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)))'])