Exemple #1
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
    def testReadExtentOnTable(self):
        # vector layer based on a standard table
        vl0 = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'postgres')
        self.assertTrue(vl0.isValid())
        self.assertTrue(vl0.dataProvider().hasMetadata())

        # set a custom extent
        originalExtent = vl0.extent()

        customExtent = QgsRectangle(-80, 80, -70, 90)
        vl0.setExtent(customExtent)

        # write xml
        doc = QDomDocument("testdoc")
        elem = doc.createElement("maplayer")
        self.assertTrue(vl0.writeLayerXml(elem, doc, QgsReadWriteContext()))

        # read xml with the custom extent. It should not be used by default
        vl1 = QgsVectorLayer()
        vl1.readLayerXml(elem, QgsReadWriteContext())
        self.assertTrue(vl1.isValid())

        self.assertEqual(vl1.extent(), originalExtent)

        # read xml with custom extent with readExtent option. Extent read from
        # xml document should NOT be used because we don't have a view or a
        # materialized view
        vl2 = QgsVectorLayer()
        vl2.setReadExtentFromXml(True)
        vl2.readLayerXml(elem, QgsReadWriteContext())
        self.assertTrue(vl2.isValid())

        self.assertEqual(vl2.extent(), originalExtent)
    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)
Exemple #4
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)
    def testWriteWithBinaryField(self):
        """
        Test writing with a binary field
        :return:
        """
        basetestpath = tempfile.mkdtemp()

        tmpfile = os.path.join(basetestpath, 'binaryfield.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))
        lyr.CreateField(ogr.FieldDefn('binfield', ogr.OFTBinary))
        lyr.CreateField(ogr.FieldDefn('binfield2', ogr.OFTBinary))
        f = None
        ds = None

        vl = QgsVectorLayer(tmpfile)
        self.assertTrue(vl.isValid())

        # check that 1 of its fields is a bool
        fields = vl.fields()
        self.assertEqual(fields.at(fields.indexFromName('binfield')).type(), QVariant.ByteArray)

        dp = vl.dataProvider()
        f = QgsFeature(fields)
        bin_1 = b'xxx'
        bin_2 = b'yyy'
        bin_val1 = QByteArray(bin_1)
        bin_val2 = QByteArray(bin_2)
        f.setAttributes([1, 'str', 100, bin_val1, bin_val2])
        self.assertTrue(dp.addFeature(f))

        # write a gpkg package with a binary field
        filename = os.path.join(str(QDir.tempPath()), 'with_bin_field')
        rc, errmsg = QgsVectorFileWriter.writeAsVectorFormat(vl,
                                                             filename,
                                                             'utf-8',
                                                             vl.crs(),
                                                             'GPKG')

        self.assertEqual(rc, QgsVectorFileWriter.NoError)

        # open the resulting geopackage
        vl = QgsVectorLayer(filename + '.gpkg', '', 'ogr')
        self.assertTrue(vl.isValid())
        fields = vl.fields()

        # test type of converted field
        idx = fields.indexFromName('binfield')
        self.assertEqual(fields.at(idx).type(), QVariant.ByteArray)
        idx2 = fields.indexFromName('binfield2')
        self.assertEqual(fields.at(idx2).type(), QVariant.ByteArray)

        # test values
        self.assertEqual(vl.getFeature(1).attributes()[idx], bin_val1)
        self.assertEqual(vl.getFeature(1).attributes()[idx2], bin_val2)

        del vl
        os.unlink(filename + '.gpkg')
    def testAddZ(self):
        """Check adding z values to non z input."""
        input = QgsVectorLayer(
            'Point?crs=epsg:4326&field=name:string(20)',
            'test',
            'memory')

        self.assertTrue(input.isValid(), 'Provider not initialized')

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10)))
        myResult, myFeatures = input.dataProvider().addFeatures([ft])
        self.assertTrue(myResult)
        self.assertTrue(myFeatures)

        dest_file_name = os.path.join(str(QDir.tempPath()), 'add_z.geojson')
        options = QgsVectorFileWriter.SaveVectorOptions()
        options.overrideGeometryType = QgsWkbTypes.PointZ
        options.driverName = 'GeoJSON'
        write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat(
            input,
            dest_file_name,
            options)
        self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message)

        # Open result and check
        created_layer = QgsVectorLayer(dest_file_name, 'test', 'ogr')
        self.assertTrue(created_layer.isValid())
        f = next(created_layer.getFeatures(QgsFeatureRequest()))
        self.assertEqual(f.geometry().asWkt(), 'PointZ (10 10 0)')
Exemple #7
0
 def testExportLayerToExistingDatabase(self):
     fields = QgsFields()
     fields.append(QgsField('f1', QVariant.Int))
     tmpfile = os.path.join(self.basetestpath, 'testCreateNewGeopackage.gpkg')
     options = {}
     options['update'] = True
     options['driverName'] = 'GPKG'
     options['layerName'] = 'table1'
     exporter = QgsVectorLayerExporter(tmpfile, "ogr", fields, QgsWkbTypes.Polygon, QgsCoordinateReferenceSystem(3111), False, options)
     self.assertFalse(exporter.errorCode(),
                      'unexpected export error {}: {}'.format(exporter.errorCode(), exporter.errorMessage()))
     options['layerName'] = 'table2'
     exporter = QgsVectorLayerExporter(tmpfile, "ogr", fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(3113), False, options)
     self.assertFalse(exporter.errorCode(),
                      'unexpected export error {} : {}'.format(exporter.errorCode(), exporter.errorMessage()))
     del exporter
     # make sure layers exist
     lyr = QgsVectorLayer('{}|layername=table1'.format(tmpfile), "lyr1", "ogr")
     self.assertTrue(lyr.isValid())
     self.assertEqual(lyr.crs().authid(), 'EPSG:3111')
     self.assertEqual(lyr.wkbType(), QgsWkbTypes.Polygon)
     lyr2 = QgsVectorLayer('{}|layername=table2'.format(tmpfile), "lyr2", "ogr")
     self.assertTrue(lyr2.isValid())
     self.assertEqual(lyr2.crs().authid(), 'EPSG:3113')
     self.assertEqual(lyr2.wkbType(), QgsWkbTypes.Point)
Exemple #8
0
    def testSetupProxy(self):
        """Test proxy setup"""
        settings = QgsSettings()
        settings.setValue("proxy/proxyEnabled", True)
        settings.setValue("proxy/proxyPort", '1234')
        settings.setValue("proxy/proxyHost", 'myproxyhostname.com')
        settings.setValue("proxy/proxyUser", 'username')
        settings.setValue("proxy/proxyPassword", 'password')
        settings.setValue("proxy/proxyExcludedUrls", "http://www.myhost.com|http://www.myotherhost.com")
        QgsNetworkAccessManager.instance().setupDefaultProxyAndCache()
        vl = QgsVectorLayer(TEST_DATA_DIR + '/' + 'lines.shp', 'proxy_test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXY"), "myproxyhostname.com:1234")
        self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXYUSERPWD"), "username:password")

        settings.setValue("proxy/proxyEnabled", True)
        settings.remove("proxy/proxyPort")
        settings.setValue("proxy/proxyHost", 'myproxyhostname.com')
        settings.setValue("proxy/proxyUser", 'username')
        settings.remove("proxy/proxyPassword")
        settings.setValue("proxy/proxyExcludedUrls", "http://www.myhost.com|http://www.myotherhost.com")
        QgsNetworkAccessManager.instance().setupDefaultProxyAndCache()
        vl = QgsVectorLayer(TEST_DATA_DIR + '/' + 'lines.shp', 'proxy_test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXY"), "myproxyhostname.com")
        self.assertEqual(gdal.GetConfigOption("GDAL_HTTP_PROXYUSERPWD"), "username")
Exemple #9
0
    def testStringListField(self):
        source = os.path.join(TEST_DATA_DIR, 'stringlist.gml')
        vl = QgsVectorLayer(source)
        self.assertTrue(vl.isValid())

        fields = vl.fields()
        descriptive_group_field = fields[fields.lookupField('descriptiveGroup')]
        self.assertEqual(descriptive_group_field.type(), QVariant.List)
        self.assertEqual(descriptive_group_field.typeName(), 'StringList')
        self.assertEqual(descriptive_group_field.subType(), QVariant.String)

        feature = vl.getFeature(1000002717654)
        self.assertEqual(feature['descriptiveGroup'], ['Building'])
        self.assertEqual(feature['reasonForChange'], ['Reclassified', 'Attributes'])

        tmpfile = os.path.join(self.basetestpath, 'newstringlistfield.gml')
        ds = ogr.GetDriverByName('GML').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint)
        lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString))
        lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger))
        lyr.CreateField(ogr.FieldDefn('strlistfield', ogr.OFTStringList))
        ds = None

        vl = QgsVectorLayer(tmpfile)
        self.assertTrue(vl.isValid())

        dp = vl.dataProvider()
        fields = dp.fields()
        list_field = fields[fields.lookupField('strlistfield')]
        self.assertEqual(list_field.type(), QVariant.List)
        self.assertEqual(list_field.typeName(), 'StringList')
        self.assertEqual(list_field.subType(), QVariant.String)
    def test_queries(self):
        """Test loading of query-based layers"""

        # a query with a geometry, but no unique id
        # this allows to load a query without unique id
        # however, functions relying on such a unique id would fail
        l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry)" % self.dbname, "test_pg_query1", "spatialite")
        assert(l.isValid())
        # the id() is not consistent
        sum_id1 = sum(f.id() for f in l.getFeatures())
        # the attribute 'id' works
        sum_id2 = sum(f.attributes()[0] for f in l.getFeatures())
        assert(sum_id1 == 0)
        assert(sum_id2 == 3)

        # and now with an id declared
        l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry) key='id'" % self.dbname, "test_pg_query1", "spatialite")
        assert(l.isValid())
        sum_id1 = sum(f.id() for f in l.getFeatures())
        sum_id2 = sum(f.attributes()[0] for f in l.getFeatures())
        assert(sum_id1 == 3)
        assert(sum_id2 == 3)

        # a query, but no geometry
        l = QgsVectorLayer("dbname=%s table='(select id,name from test_q)' key='id'" % self.dbname, "test_pg_query1", "spatialite")
        assert(l.isValid())
        sum_id1 = sum(f.id() for f in l.getFeatures())
        sum_id2 = sum(f.attributes()[0] for f in l.getFeatures())
        assert(sum_id1 == 3)
        assert(sum_id2 == 3)
    def testSubSetStringEditable_bug17795_but_with_modified_behavior(self):
        """Test that a layer is editable after setting a subset"""

        tmpfile = os.path.join(self.basetestpath, 'testSubSetStringEditable_bug17795.gpkg')
        shutil.copy(TEST_DATA_DIR + '/' + 'provider/bug_17795.gpkg', tmpfile)

        isEditable = QgsVectorDataProvider.ChangeAttributeValues
        testPath = tmpfile + '|layername=bug_17795'

        vl = QgsVectorLayer(testPath, 'subset_test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.dataProvider().capabilities() & isEditable)

        vl = QgsVectorLayer(testPath, 'subset_test', 'ogr')
        vl.setSubsetString('')
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.dataProvider().capabilities() & isEditable)

        vl = QgsVectorLayer(testPath, 'subset_test', 'ogr')
        vl.setSubsetString('"category" = \'one\'')
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.dataProvider().capabilities() & isEditable)

        vl.setSubsetString('')
        self.assertTrue(vl.dataProvider().capabilities() & isEditable)
Exemple #12
0
    def testSubsetStringExtent_bug17863(self):
        """Check that the extent is correct when applied in the ctor and when
        modified after a subset string is set """

        def _lessdigits(s):
            return re.sub(r'(\d+\.\d{3})\d+', r'\1', s)

        testPath = TEST_DATA_DIR + '/' + 'points.shp'
        subSetString = '"Class" = \'Biplane\''
        subSet = '|layerid=0|subset=%s' % subSetString

        # unfiltered
        vl = QgsVectorLayer(testPath, 'test', 'ogr')
        self.assertTrue(vl.isValid())
        unfiltered_extent = _lessdigits(vl.extent().toString())
        del(vl)

        # filter after construction ...
        subSet_vl2 = QgsVectorLayer(testPath, 'test', 'ogr')
        self.assertEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent)
        # ... apply filter now!
        subSet_vl2.setSubsetString(subSetString)
        self.assertEqual(subSet_vl2.subsetString(), subSetString)
        self.assertNotEqual(_lessdigits(subSet_vl2.extent().toString()), unfiltered_extent)
        filtered_extent = _lessdigits(subSet_vl2.extent().toString())
        del(subSet_vl2)

        # filtered in constructor
        subSet_vl = QgsVectorLayer(testPath + subSet, 'subset_test', 'ogr')
        self.assertEqual(subSet_vl.subsetString(), subSetString)
        self.assertTrue(subSet_vl.isValid())

        # This was failing in bug 17863
        self.assertEqual(_lessdigits(subSet_vl.extent().toString()), filtered_extent)
        self.assertNotEqual(_lessdigits(subSet_vl.extent().toString()), unfiltered_extent)
Exemple #13
0
    def test_source_escaping2(self):
        def create_test_db(dbfile):
            if os.path.exists(dbfile):
                os.remove(dbfile)
            con = spatialite_connect(dbfile)
            cur = con.cursor()
            cur.execute("SELECT InitSpatialMetadata(1)")
            cur.execute("CREATE TABLE test (id INTEGER, name TEXT)")
            cur.execute("SELECT AddGeometryColumn('test', 'geometry', 4326, 'POINT', 'XY')")
            sql = "INSERT INTO test (id, name, geometry) "
            sql += "VALUES (1, 'toto',GeomFromText('POINT(0 0)',4326))"
            cur.execute(sql)
            con.close()

        # the source contains ',' and single quotes
        fn = os.path.join(tempfile.gettempdir(), "test,.db")
        create_test_db(fn)
        source = "dbname='%s' table=\"test\" (geometry) sql=" % fn
        d = QgsVirtualLayerDefinition()
        d.addSource("t", source, "spatialite")
        l = QgsVectorLayer(d.toString(), "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)

        # the source contains ':' and single quotes
        fn = os.path.join(tempfile.gettempdir(), "test:.db")
        create_test_db(fn)
        source = "dbname='%s' table=\"test\" (geometry) sql=" % fn
        d = QgsVirtualLayerDefinition()
        d.addSource("t", source, "spatialite")
        l = QgsVectorLayer(d.toString(), "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)
Exemple #14
0
    def testUpdatedFields(self):
        """Test when referenced layer update its fields
        https://issues.qgis.org/issues/20893
        """

        ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem", "memory")
        self.assertEqual(ml.isValid(), True)
        QgsProject.instance().addMapLayer(ml)

        ml.startEditing()
        f1 = QgsFeature(ml.fields())
        f1.setGeometry(QgsGeometry.fromWkt('POINT(2 3)'))
        ml.addFeatures([f1])
        ml.commitChanges()

        vl = QgsVectorLayer("?query=select a, geometry from mem", "vl", "virtual")
        self.assertEqual(vl.isValid(), True)

        # add one more field
        ml.dataProvider().addAttributes([QgsField('newfield', QVariant.Int)])
        ml.updateFields()

        self.assertEqual(ml.featureCount(), vl.featureCount())
        self.assertEqual(vl.fields().count(), 1)

        geometry = next(vl.getFeatures()).geometry()
        self.assertTrue(geometry)

        point = geometry.asPoint()
        self.assertEqual(point.x(), 2)
        self.assertEqual(point.y(), 3)

        QgsProject.instance().removeMapLayer(ml)
Exemple #15
0
    def test_embeddedLayer(self):
        source = toPercent(os.path.join(self.testDataDir, "france_parts.shp"))
        l = QgsVectorLayer("?layer=ogr:%s" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)

        l = QgsVectorLayer("?layer=ogr:%s:nn" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)
Exemple #16
0
    def test_geometryTypes(self):

        geo = [(1, "POINT", "(0 0)"),
               (2, "LINESTRING", "(0 0,1 0)"),
               (3, "POLYGON", "((0 0,1 0,1 1,0 0))"),
               (4, "MULTIPOINT", "((1 1))"),
               (5, "MULTILINESTRING", "((0 0,1 0),(0 1,1 1))"),
               (6, "MULTIPOLYGON", "(((0 0,1 0,1 1,0 0)),((2 2,3 0,3 3,2 2)))")]
        for wkb_type, wkt_type, wkt in geo:
            l = QgsVectorLayer("%s?crs=epsg:4326" % wkt_type, "m1", "memory", False)
            self.assertEqual(l.isValid(), True)
            QgsProject.instance().addMapLayer(l)

            f1 = QgsFeature(1)
            g = QgsGeometry.fromWkt(wkt_type + wkt)
            self.assertEqual(g is None, False)
            f1.setGeometry(g)
            l.dataProvider().addFeatures([f1])

            l2 = QgsVectorLayer("?layer_ref=%s" % l.id(), "vtab", "virtual", False)
            self.assertEqual(l2.isValid(), True)
            self.assertEqual(l2.dataProvider().featureCount(), 1)
            self.assertEqual(l2.dataProvider().wkbType(), wkb_type)

            QgsProject.instance().removeMapLayer(l.id())
 def _loadLogLayer(self, sourceLayer, layerPath, layerName):
     layer = None
     layerId = ''
     layerList = QgsMapLayerRegistry.instance().mapLayersByName(layerName)
     if (len(layerList) > 0):
         layer = layerList[0]
         self._iface.legendInterface().moveLayer(layer, self._bufferGroupIndex)
     else:
         fullLayerPath = self.projectPath + '/' + layerPath
         if (layerName and layerPath and sourceLayer and sourceLayer.isValid()):
             if not QFile.exists(fullLayerPath):
                 # If the layer doesn't exist, clone from the source layer
                 layer = layers.cloneAsShapefile(sourceLayer, fullLayerPath, layerName)
                 if layer and layer.isValid():
                     layer.dataProvider().addAttributes([QgsField('timestamp', QVariant.String, '', 10, 0, 'timestamp')])
                     layer.dataProvider().addAttributes([QgsField('event', QVariant.String, '', 6, 0, 'event')])
             else:
                 # If the layer does exist, then load it and copy the style
                 layer = QgsVectorLayer(fullLayerPath, layerName, 'ogr')
                 if layer and layer.isValid():
                     layers.loadStyle(layer, fromLayer=sourceLayer)
     if layer and layer.isValid():
         layerId = layer.id()
         layer.setFeatureFormSuppress(QgsVectorLayer.SuppressOn)
         self._iface.legendInterface().setLayerExpanded(layer, False)
     else:
         layer = None
     return layer, layerId
    def test_queries(self):
        """Test loading of query-based layers"""

        # a query with a geometry, but no unique id
        # the id will be autoincremented
        l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry)" % self.dbname, "test_pg_query1", "spatialite")
        self.assertTrue(l.isValid())
        # the id() is autoincremented
        sum_id1 = sum(f.id() for f in l.getFeatures())
        # the attribute 'id' works
        sum_id2 = sum(f.attributes()[0] for f in l.getFeatures())
        self.assertEqual(sum_id1, 32)  # 11 + 21
        self.assertEqual(sum_id2, 32)  # 11 + 21

        # and now with an id declared
        l = QgsVectorLayer("dbname=%s table='(select * from test_q)' (geometry) key='id'" % self.dbname, "test_pg_query1", "spatialite")
        self.assertTrue(l.isValid())
        sum_id1 = sum(f.id() for f in l.getFeatures())
        sum_id2 = sum(f.attributes()[0] for f in l.getFeatures())
        self.assertEqual(sum_id1, 32)
        self.assertEqual(sum_id2, 32)

        # a query, but no geometry
        l = QgsVectorLayer("dbname=%s table='(select id,name from test_q)' key='id'" % self.dbname, "test_pg_query1", "spatialite")
        self.assertTrue(l.isValid())
        sum_id1 = sum(f.id() for f in l.getFeatures())
        sum_id2 = sum(f.attributes()[0] for f in l.getFeatures())
        self.assertEqual(sum_id1, 32)
        self.assertEqual(sum_id2, 32)
    def test_embeddedLayer( self ):
        source = QUrl.toPercentEncoding(os.path.join(self.testDataDir_, "france_parts.shp"))
        l = QgsVectorLayer("?layer=ogr:%s" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)

        l = QgsVectorLayer("?layer=ogr:%s:nn" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)
        print sum([f.id() for f in l.getFeatures()])
    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)
    def testPkLessQuery(self):
        """Test if features in queries with/without pk can be retrieved by id"""
        # create test db
        dbname = os.path.join(tempfile.gettempdir(), "test_pkless.sqlite")
        if os.path.exists(dbname):
            os.remove(dbname)
        con = spatialite_connect(dbname, isolation_level=None)
        cur = con.cursor()
        cur.execute("BEGIN")
        sql = "SELECT InitSpatialMetadata()"
        cur.execute(sql)

        # simple table with primary key
        sql = "CREATE TABLE test_pk (id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL)"
        cur.execute(sql)

        sql = "SELECT AddGeometryColumn('test_pk', 'geometry', 4326, 'POINT', 'XY')"
        cur.execute(sql)

        for i in range(11, 21):
            sql = "INSERT INTO test_pk (id, name, geometry) "
            sql += "VALUES ({id}, 'name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i)
            cur.execute(sql)

        # simple table without primary key
        sql = "CREATE TABLE test_no_pk (name TEXT NOT NULL)"
        cur.execute(sql)

        sql = "SELECT AddGeometryColumn('test_no_pk', 'geometry', 4326, 'POINT', 'XY')"
        cur.execute(sql)

        for i in range(11, 21):
            sql = "INSERT INTO test_no_pk (name, geometry) "
            sql += "VALUES ('name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i)
            cur.execute(sql)

        cur.execute("COMMIT")
        con.close()

        def _check_features(vl, offset):
            self.assertEqual(vl.featureCount(), 10)
            i = 11
            for f in vl.getFeatures():
                self.assertTrue(f.isValid())
                self.assertTrue(vl.getFeature(i - offset).isValid())
                self.assertEqual(vl.getFeature(i - offset)['name'], 'name {id}'.format(id=i))
                self.assertEqual(f.id(), i - offset)
                self.assertEqual(f['name'], 'name {id}'.format(id=i))
                self.assertEqual(f.geometry().asWkt(), 'Point ({id} {id})'.format(id=i))
                i += 1

        vl_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from test_pk)" (geometry) sql=' % dbname, 'pk', 'spatialite')
        self.assertTrue(vl_pk.isValid())
        _check_features(vl_pk, 0)

        vl_no_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from test_no_pk)" (geometry) sql=' % dbname, 'pk', 'spatialite')
        self.assertTrue(vl_no_pk.isValid())
        _check_features(vl_no_pk, 10)
    def testVectorLayerInput(self):
        alg = QgsApplication.processingRegistry().createAlgorithmById('grass7:v.buffer')
        self.assertIsNotNone(alg)
        self.assertFalse(alg.commands)

        def get_command(alg):
            command = alg.commands[-1]
            command = re.sub(r'output=".*?"', 'output="###"', command)
            command = command.replace(testDataPath, 'testdata')
            return command

        # GML source
        source = os.path.join(testDataPath, 'points.gml')
        vl = QgsVectorLayer(source)
        self.assertTrue(vl.isValid())
        alg.loadVectorLayer('test_layer', vl, external=False)
        self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/points.gml" output="###" --overwrite -o')
        # try with external -- not support for GML, so should fall back to v.in.ogr
        alg.loadVectorLayer('test_layer', vl, external=True)
        self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/points.gml" output="###" --overwrite -o')

        # SHP source
        source = os.path.join(testDataPath, 'lines_z.shp')
        vl = QgsVectorLayer(source)
        self.assertTrue(vl.isValid())
        alg.loadVectorLayer('test_layer', vl, external=False)
        self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/lines_z.shp" output="###" --overwrite -o')
        # try with external -- should work for shapefile
        alg.loadVectorLayer('test_layer', vl, external=True)
        self.assertEqual(get_command(alg), 'v.external input="testdata/lines_z.shp" output="###" --overwrite -o')

        # GPKG source
        source = os.path.join(testDataPath, 'custom/pol.gpkg')
        vl = QgsVectorLayer(source + '|layername=pol2')
        self.assertTrue(vl.isValid())
        alg.loadVectorLayer('test_layer', vl, external=False)
        self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/custom/pol.gpkg" layer="pol2" output="###" --overwrite -o')
        # try with external -- should work for Geopackage (although grass itself tends to crash here!)
        alg.loadVectorLayer('test_layer', vl, external=True)
        self.assertEqual(get_command(alg), 'v.external input="testdata/custom/pol.gpkg" layer="pol2" output="###" --overwrite -o')

        # different layer
        source = os.path.join(testDataPath, 'custom/pol.gpkg')
        vl = QgsVectorLayer(source + '|layername=pol3')
        self.assertTrue(vl.isValid())
        alg.loadVectorLayer('test_layer', vl, external=False)
        self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/custom/pol.gpkg" layer="pol3" output="###" --overwrite -o')
        alg.loadVectorLayer('test_layer', vl, external=True)
        self.assertEqual(get_command(alg), 'v.external input="testdata/custom/pol.gpkg" layer="pol3" output="###" --overwrite -o')

        # GPKG no layer: you get what you get and you don't get upset
        source = os.path.join(testDataPath, 'custom/pol.gpkg')
        vl = QgsVectorLayer(source)
        self.assertTrue(vl.isValid())
        alg.loadVectorLayer('test_layer', vl, external=False)
        self.assertEqual(get_command(alg), 'v.in.ogr min_area=None snap=None input="testdata/custom/pol.gpkg" output="###" --overwrite -o')
        alg.loadVectorLayer('test_layer', vl, external=True)
        self.assertEqual(get_command(alg), 'v.external input="testdata/custom/pol.gpkg" output="###" --overwrite -o')
Exemple #23
0
    def test_CsvNoGeometry(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        l2 = QgsVectorLayer("?layer_ref=" + l1.id(), "vtab", "virtual", False)
        self.assertEqual(l2.isValid(), True)

        QgsProject.instance().removeMapLayer(l1.id())
Exemple #24
0
    def test_sql2(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", 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(), 3)
        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)
    def testHasMetadata(self):
        # views don't have metadata
        vl = QgsVectorLayer('{} table="qgis_test"."{}" key="pk" sql='.format(self.dbconn, 'bikes_view'), "bikes_view", "postgres")
        self.assertTrue(vl.isValid())
        self.assertFalse(vl.dataProvider().hasMetadata())

        # ordinary tables have metadata
        vl = QgsVectorLayer('%s table="qgis_test"."someData" sql=' % (self.dbconn), "someData", "postgres")
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.dataProvider().hasMetadata())
Exemple #26
0
    def test_recursiveLayer(self):
        source = toPercent(os.path.join(self.testDataDir, "france_parts.shp"))
        l = QgsVectorLayer("?layer=ogr:%s" % source, "vtab", "virtual", False)
        self.assertEqual(l.isValid(), True)
        QgsProject.instance().addMapLayer(l)

        l2 = QgsVectorLayer("?layer_ref=" + l.id(), "vtab2", "virtual", False)
        self.assertEqual(l2.isValid(), True)

        QgsProject.instance().removeMapLayer(l.id())
Exemple #27
0
    def test_refLayers2(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        # referenced layers cannot be stored !
        tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString()
        l2 = QgsVectorLayer("%s?layer_ref=%s" % (tmp, l1.id()), "tt", "virtual", False)
        self.assertEqual(l2.isValid(), False)
        self.assertEqual("Cannot store referenced layers" in l2.dataProvider().error().message(), True)
Exemple #28
0
    def test_sql(self):
        l1 = QgsVectorLayer(QUrl.fromLocalFile(os.path.join(self.testDataDir, "delimitedtext/test.csv")).toString() + "?type=csv&geomType=none&subsetIndex=no&watchFile=no", "test", "delimitedtext", False)
        self.assertEqual(l1.isValid(), True)
        QgsProject.instance().addMapLayer(l1)

        l3 = QgsVectorLayer("?query=SELECT * FROM test", "tt", "virtual")

        self.assertEqual(l3.isValid(), True)
        s = sum(f.id() for f in l3.getFeatures())
        self.assertEqual(s, 15)
Exemple #29
0
    def test_sql4(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False)
        self.assertEqual(l2.isValid(), True)
        QgsProject.instance().addMapLayer(l2)

        query = toPercent("SELECT OBJECTId from france_parts")
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False)
        self.assertEqual(l4.isValid(), True)
        s = sum(f.attributes()[0] for f in l4.getFeatures())
        self.assertEqual(s, 10659)
Exemple #30
0
    def test_reopen2(self):
        source = toPercent(os.path.join(self.testDataDir, "france_parts.shp"))
        tmp = QUrl.fromLocalFile(os.path.join(tempfile.gettempdir(), "t.sqlite")).toString()
        l = QgsVectorLayer("%s?layer=ogr:%s:vtab&nogeometry" % (tmp, source), "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)
Exemple #31
0
class TestQgsMapLayerAction(unittest.TestCase):

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        self.vector_layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime",
                                           "test_layer", "memory")
        assert self.vector_layer.isValid()
        self.vector_layer2 = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime",
                                            "test_layer", "memory")
        assert self.vector_layer2.isValid()
        raster_path = os.path.join(unitTestDataPath(), 'landsat.tif')
        self.raster_layer = QgsRasterLayer(raster_path, 'raster')
        assert self.raster_layer.isValid()

    def testCanRunUsingLayer(self):
        """
        Test that actions correctly indicate when they can run for a layer
        """
        action_all_layers = QgsMapLayerAction('action1', None)
        self.assertTrue(action_all_layers.canRunUsingLayer(None))
        self.assertTrue(action_all_layers.canRunUsingLayer(self.vector_layer))
        self.assertTrue(action_all_layers.canRunUsingLayer(self.raster_layer))

        action_vector_layers_only = QgsMapLayerAction('action2', None, QgsMapLayer.VectorLayer)
        self.assertFalse(action_vector_layers_only.canRunUsingLayer(None))
        self.assertTrue(action_vector_layers_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_vector_layers_only.canRunUsingLayer(self.raster_layer))

        action_raster_layers_only = QgsMapLayerAction('action3', None, QgsMapLayer.RasterLayer)
        self.assertFalse(action_raster_layers_only.canRunUsingLayer(None))
        self.assertFalse(action_raster_layers_only.canRunUsingLayer(self.vector_layer))
        self.assertTrue(action_raster_layers_only.canRunUsingLayer(self.raster_layer))

        action_specific_layer_only = QgsMapLayerAction('action4', None, self.vector_layer)
        self.assertFalse(action_specific_layer_only.canRunUsingLayer(None))
        self.assertTrue(action_specific_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.raster_layer))

        action_specific_raster_layer_only = QgsMapLayerAction('action4', None, self.raster_layer)
        self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(None))
        self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertTrue(action_specific_raster_layer_only.canRunUsingLayer(self.raster_layer))

        action_editable_layer_only = QgsMapLayerAction('action1', None, flags=QgsMapLayerAction.EnabledOnlyWhenEditable)
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(None))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
        self.vector_layer.startEditing()
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(None))
        self.assertTrue(action_editable_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
        self.vector_layer.commitChanges()
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(None))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
    def test_joined_layers_conversion(self):
        v1 = QgsVectorLayer("Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string", "A", "memory")
        self.assertEqual(v1.isValid(), True)
        v2 = QgsVectorLayer("Point?field=id:integer&field=bname:string&field=bfield:integer", "B", "memory")
        self.assertEqual(v2.isValid(), True)
        v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C", "memory")
        self.assertEqual(v3.isValid(), True)
        tl1 = QgsVectorLayer("NoGeometry?field=id:integer&field=e_id:integer&field=0name:string", "D", "memory")
        self.assertEqual(tl1.isValid(), True)
        tl2 = QgsVectorLayer("NoGeometry?field=id:integer&field=ena me:string", "E", "memory")
        self.assertEqual(tl2.isValid(), True)
        QgsProject.instance().addMapLayers([v1, v2, v3, tl1, tl2])
        joinInfo = QgsVectorLayerJoinInfo()
        joinInfo.setTargetFieldName("b_id")
        joinInfo.setJoinLayer(v2)
        joinInfo.setJoinFieldName("id")
        #joinInfo.setPrefix("B_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)

        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))

        # with a field subset
        v1.removeJoin(v2.id())
        joinInfo.setJoinFieldNamesSubset(["bname"])
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 5)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))
        joinInfo.setJoinFieldNamesSubset(None)

        # add a table prefix to the join
        v1.removeJoin(v2.id())
        joinInfo.setPrefix("BB_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), 'SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "BB_bname", j1."bfield" AS "BB_bfield" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id"'.format(v1.id(), v2.id()))
        joinInfo.setPrefix("")
        v1.removeJoin(v2.id())
        v1.addJoin(joinInfo)

        # add another join
        joinInfo2 = QgsVectorLayerJoinInfo()
        joinInfo2.setTargetFieldName("c_id")
        joinInfo2.setJoinLayer(v3)
        joinInfo2.setJoinFieldName("id")
        v1.addJoin(joinInfo2)
        self.assertEqual(len(v1.fields()), 7)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), ('SELECT t.geometry, t.rowid AS uid, t."id", t."b_id", t."c_id", t."name", j1."bname" AS "B_bname", j1."bfield" AS "B_bfield", j2."cname" AS "C_cname" FROM "{}" AS t '
                                      + 'LEFT JOIN "{}" AS j1 ON t."b_id"=j1."id" '
                                      + 'LEFT JOIN "{}" AS j2 ON t."c_id"=j2."id"').format(v1.id(), v2.id(), v3.id()))

        # test NoGeometry joined layers with field names starting with a digit or containing white spaces
        joinInfo3 = QgsVectorLayerJoinInfo()
        joinInfo3.setTargetFieldName("e_id")
        joinInfo3.setJoinLayer(tl2)
        joinInfo3.setJoinFieldName("id")
        tl1.addJoin(joinInfo3)
        self.assertEqual(len(tl1.fields()), 4)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(tl1)
        self.assertEqual(df.query(), 'SELECT t.rowid AS uid, t."id", t."e_id", t."0name", j1."ena me" AS "E_ena me" FROM "{}" AS t LEFT JOIN "{}" AS j1 ON t."e_id"=j1."id"'.format(tl1.id(), tl2.id()))

        QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id(), tl1.id(), tl2.id()])
Exemple #33
0
    def testMinMaxCache(self):
        """
        Test that min/max cache is appropriately cleared
        :return:
        """
        vl = QgsVectorLayer(
            'Point?crs=epsg:4326&field=f1:integer&field=f2:integer',
            'test', 'memory')
        self.assertTrue(vl.isValid())

        f1 = QgsFeature()
        f1.setAttributes([5, -200])
        f2 = QgsFeature()
        f2.setAttributes([3, 300])
        f3 = QgsFeature()
        f3.setAttributes([1, 100])
        f4 = QgsFeature()
        f4.setAttributes([2, 200])
        f5 = QgsFeature()
        f5.setAttributes([4, 400])
        res, [f1, f2, f3, f4, f5] = vl.dataProvider().addFeatures([f1, f2, f3, f4, f5])
        self.assertTrue(res)

        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # add feature
        f6 = QgsFeature()
        f6.setAttributes([15, 1400])
        res, [f6] = vl.dataProvider().addFeatures([f6])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)
        f7 = QgsFeature()
        f7.setAttributes([-1, -1400])
        res, [f7] = vl.dataProvider().addFeatures([f7])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), -1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -1400)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)

        # change attribute values
        self.assertTrue(vl.dataProvider().changeAttributeValues({f6.id(): {0: 3, 1: 150}, f7.id(): {0: 4, 1: -100}}))
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # delete features
        self.assertTrue(vl.dataProvider().deleteFeatures([f4.id(), f1.id()]))
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -100)
        self.assertEqual(vl.dataProvider().maximumValue(0), 4)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # delete attributes
        self.assertTrue(vl.dataProvider().deleteAttributes([0]))
        self.assertEqual(vl.dataProvider().minimumValue(0), -100)
        self.assertEqual(vl.dataProvider().maximumValue(0), 400)
Exemple #34
0
    def test_exceptions(self):
        ml = QgsVectorLayer(
            "Point?crs=epsg:4236&field=id:integer&field=value:double",
            "test_data", "memory")
        assert ml.isValid()
        fields = ml.fields()

        # check no error
        fields.remove(1)
        # check exceptions raised
        with self.assertRaises(KeyError):
            fields.remove(-1)
        with self.assertRaises(KeyError):
            fields.remove(111)

        fields = ml.fields()

        # check no error
        self.assertEqual("value", fields[1].name())
        self.assertEqual("value", fields[-1].name())
        # check exceptions raised
        with self.assertRaises(IndexError):
            fields[111]

        # check no error
        fields.at(1)
        # check exceptions raised
        with self.assertRaises(KeyError):
            fields.at(-1)
        with self.assertRaises(KeyError):
            fields.at(111)

        # check no error
        fields.field(1)
        # check exceptions raised
        with self.assertRaises(KeyError):
            fields.field(-1)
        with self.assertRaises(KeyError):
            fields.field(111)

        # check no error
        fields.field('value')
        # check exceptions raised
        with self.assertRaises(KeyError):
            fields.field('bad')

        # check no error
        fields.fieldOrigin(1)
        # check exceptions raised
        with self.assertRaises(KeyError):
            fields.fieldOrigin(-1)
        with self.assertRaises(KeyError):
            fields.fieldOrigin(111)

        # check no error
        fields.fieldOriginIndex(1)
        # check exceptions raised
        with self.assertRaises(KeyError):
            fields.fieldOriginIndex(-1)
        with self.assertRaises(KeyError):
            fields.fieldOriginIndex(111)

        # check no error
        fields.iconForField(1)
        # check exceptions raised
        with self.assertRaises(KeyError):
            fields.iconForField(-1)
        with self.assertRaises(KeyError):
            fields.iconForField(111)
    def testIteration(self):
        p = QgsProject()
        vectorFileInfo = QFileInfo(unitTestDataPath() + "/france_parts.shp")
        vector_layer = QgsVectorLayer(vectorFileInfo.filePath(),
                                      vectorFileInfo.completeBaseName(), "ogr")
        self.assertTrue(vector_layer.isValid())
        p.addMapLayer(vector_layer)

        l = QgsPrintLayout(p)
        atlas = l.atlas()
        atlas.setEnabled(True)
        atlas.setCoverageLayer(vector_layer)

        atlas_feature_changed_spy = QSignalSpy(atlas.featureChanged)
        context_changed_spy = QSignalSpy(l.reportContext().changed)

        self.assertTrue(atlas.beginRender())
        self.assertTrue(atlas.first())
        self.assertEqual(len(atlas_feature_changed_spy), 1)
        self.assertEqual(len(context_changed_spy), 1)
        self.assertEqual(atlas.currentFeatureNumber(), 0)
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertEqual(l.reportContext().layer(), vector_layer)
        f1 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 2)
        self.assertEqual(len(context_changed_spy), 2)
        self.assertEqual(atlas.currentFeatureNumber(), 1)
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        f2 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 3)
        self.assertEqual(len(context_changed_spy), 3)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        f3 = l.reportContext().feature()

        self.assertTrue(atlas.next())
        self.assertEqual(len(atlas_feature_changed_spy), 4)
        self.assertEqual(len(context_changed_spy), 4)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        f4 = l.reportContext().feature()

        self.assertFalse(atlas.next())
        self.assertTrue(atlas.seekTo(2))
        self.assertEqual(len(atlas_feature_changed_spy), 5)
        self.assertEqual(len(context_changed_spy), 5)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.last())
        self.assertEqual(len(atlas_feature_changed_spy), 6)
        self.assertEqual(len(context_changed_spy), 6)
        self.assertEqual(atlas.currentFeatureNumber(), 3)
        self.assertEqual(l.reportContext().feature()[4], 'Centre')

        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 7)
        self.assertEqual(len(context_changed_spy), 7)
        self.assertEqual(atlas.currentFeatureNumber(), 2)
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')

        self.assertTrue(atlas.previous())
        self.assertTrue(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)
        self.assertFalse(atlas.previous())
        self.assertEqual(len(atlas_feature_changed_spy), 9)

        self.assertTrue(atlas.endRender())
        self.assertEqual(len(atlas_feature_changed_spy), 10)

        self.assertTrue(atlas.seekTo(f1))
        self.assertEqual(l.reportContext().feature()[4], 'Basse-Normandie')
        self.assertTrue(atlas.seekTo(f4))
        self.assertEqual(l.reportContext().feature()[4], 'Centre')
        self.assertTrue(atlas.seekTo(f3))
        self.assertEqual(l.reportContext().feature()[4], 'Pays de la Loire')
        self.assertTrue(atlas.seekTo(f2))
        self.assertEqual(l.reportContext().feature()[4], 'Bretagne')
        self.assertFalse(atlas.seekTo(QgsFeature(5)))
    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)
Exemple #37
0
 def create_file(self):
     layer = QgsVectorLayer(PROFILE_LINES_PATH, "profiles", "ogr")
     assert layer.isValid()
     return PreCourlisFileLine(layer)
Exemple #38
0
 def testCtors(self):
     testVectors = ["Point", "LineString", "Polygon", "MultiPoint", "MultiLineString", "MultiPolygon", "None"]
     for v in testVectors:
         layer = QgsVectorLayer(v, "test", "memory")
         assert layer.isValid(), "Failed to create valid %s memory layer" % (v)
    def test_project_roundtrip(self):
        """Tests that a project with bad layers can be saved and restored"""

        p = QgsProject.instance()
        temp_dir = QTemporaryDir()
        for ext in ('shp', 'dbf', 'shx', 'prj'):
            copyfile(os.path.join(TEST_DATA_DIR, 'lines.%s' % ext),
                     os.path.join(temp_dir.path(), 'lines.%s' % ext))
        copyfile(
            os.path.join(TEST_DATA_DIR, 'raster',
                         'band1_byte_ct_epsg4326.tif'),
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'))
        copyfile(
            os.path.join(TEST_DATA_DIR, 'raster',
                         'band1_byte_ct_epsg4326.tif'),
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'))
        l = QgsVectorLayer(os.path.join(temp_dir.path(), 'lines.shp'), 'lines',
                           'ogr')
        self.assertTrue(l.isValid())

        rl = QgsRasterLayer(
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'),
            'raster', 'gdal')
        self.assertTrue(rl.isValid())
        rl_copy = QgsRasterLayer(
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'),
            'raster_copy', 'gdal')
        self.assertTrue(rl_copy.isValid())
        self.assertTrue(p.addMapLayers([l, rl, rl_copy]))

        # Save project
        project_path = os.path.join(temp_dir.path(), 'project.qgs')
        self.assertTrue(p.write(project_path))

        # Re-load the project, checking for the XML properties
        p.removeAllMapLayers()
        self.assertTrue(p.read(project_path))
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.originalXmlProperties() != '')
        self.assertTrue(raster.originalXmlProperties() != '')
        self.assertTrue(raster_copy.originalXmlProperties() != '')
        # Test setter
        raster.setOriginalXmlProperties('pippo')
        self.assertEqual(raster.originalXmlProperties(), 'pippo')

        # Now create and invalid project:
        bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs')
        with open(project_path, 'r') as infile:
            with open(bad_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace(
                    './lines.shp', './lines-BAD_SOURCE.shp').replace(
                        'band1_byte_ct_epsg4326_copy.tif',
                        'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif'))

        # Load the bad project
        p.removeAllMapLayers()
        self.assertTrue(p.read(bad_project_path))
        # Check layer is invalid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertIsNotNone(vector.dataProvider())
        self.assertIsNotNone(raster.dataProvider())
        self.assertIsNotNone(raster_copy.dataProvider())
        self.assertFalse(vector.isValid())
        self.assertFalse(raster_copy.isValid())
        # Try a getFeatures
        self.assertEqual([f for f in vector.getFeatures()], [])
        self.assertTrue(raster.isValid())
        self.assertEqual(vector.providerType(), 'ogr')

        # Save the project
        bad_project_path2 = os.path.join(temp_dir.path(), 'project_bad2.qgs')
        p.write(bad_project_path2)
        # Re-save the project, with fixed paths
        good_project_path = os.path.join(temp_dir.path(), 'project_good.qgs')
        with open(bad_project_path2, 'r') as infile:
            with open(good_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace(
                    './lines-BAD_SOURCE.shp', './lines.shp').replace(
                        'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif',
                        'band1_byte_ct_epsg4326_copy.tif'))

        # Load the good project
        p.removeAllMapLayers()
        self.assertTrue(p.read(good_project_path))
        # Check layer is valid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.isValid())
        self.assertTrue(raster.isValid())
        self.assertTrue(raster_copy.isValid())
Exemple #40
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))
Exemple #41
0
def create_layer():
    layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer",
                           "addfeat", "memory")
    assert layer.isValid()
    return layer
    def testProjectStorage(self):
        # New project without fileName
        p0 = QgsProject()
        self.assertTrue(p0.auxiliaryStorage().isValid())

        # Create new layers with key otherwise auxiliary layers are not
        # automacially created when added in project
        vl0 = createLayer()
        vl0Shp = writeShape(vl0, 'vl0.shp')

        vl1 = createLayer()
        vl1Shp = writeShape(vl1, 'vl1.shp')

        vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr')
        self.assertTrue(vl0.isValid())

        vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr')
        self.assertTrue(vl1.isValid())

        # Add layers to project and check underlying auxiliary layers
        p0.addMapLayers([vl0, vl1])

        self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk'))
        self.assertTrue(
            vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char'))

        al0 = vl0.auxiliaryLayer()
        al1 = vl1.auxiliaryLayer()

        self.assertEqual(al0.joinInfo().targetFieldName(), 'pk')
        self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char')

        # Add a field in auxiliary layers
        pdef0 = QgsPropertyDefinition('propname',
                                      QgsPropertyDefinition.DataTypeNumeric,
                                      '', '', 'ut')
        self.assertTrue(al0.addAuxiliaryField(pdef0))

        pdef1 = QgsPropertyDefinition('propname1',
                                      QgsPropertyDefinition.DataTypeString, '',
                                      '', 'ut')
        self.assertTrue(al1.addAuxiliaryField(pdef1))

        # Check auxiliary fields names
        af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False)
        self.assertEqual(af0Name, 'ut_propname')
        af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False)
        self.assertEqual(af1Name, 'ut_propname1')

        # Set value for auxiliary fields
        req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
        f = QgsFeature()
        vl0.getFeatures(req).nextFeature(f)
        self.assertTrue(f.isValid())
        af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True)
        index0 = vl0.fields().indexOf(af0Name)
        vl0.changeAttributeValue(f.id(), index0, 333)

        req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
        f = QgsFeature()
        vl1.getFeatures(req).nextFeature(f)
        self.assertTrue(f.isValid())
        af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True)
        index1 = vl1.fields().indexOf(af1Name)
        vl1.changeAttributeValue(f.id(), index0, 'myvalue')

        req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
        f = QgsFeature()
        vl1.getFeatures(req).nextFeature(f)
        self.assertTrue(f.isValid())
        vl1.changeAttributeValue(f.id(), index0, 'myvalue1')

        # Save the project in a zip file
        f = tmpPath() + '.qgz'
        p0.write(f)

        # Open the zip file with embedded auxiliary storage
        p1 = QgsProject()
        p1.read(f)

        # Check that auxiliary fields are well loaded in layers
        self.assertEqual(len(p1.mapLayers().values()), 2)

        for vl in p1.mapLayers().values():
            al = vl.auxiliaryLayer()
            self.assertEqual(len(al.auxiliaryFields()), 1)

            af = al.auxiliaryFields()[0]
            afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af)
            self.assertEqual(afPropDef.origin(), 'ut')

            if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk':
                self.assertEqual(afPropDef.name(), 'propname')
                self.assertEqual(al.featureCount(), 1)

                req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
                f = QgsFeature()
                vl.getFeatures(req).nextFeature(f)
                self.assertTrue(f.isValid())
                self.assertEqual(f.attributes()[index0], 333.0)
            else:  # num_char
                self.assertEqual(al.featureCount(), 2)
                self.assertEqual(afPropDef.name(), 'propname1')

                req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
                f = QgsFeature()
                vl.getFeatures(req).nextFeature(f)
                self.assertTrue(f.isValid())
                self.assertEqual(f.attributes()[index1], 'myvalue')

                req = QgsFeatureRequest().setFilterExpression(
                    "name = 'Orange'")
                f = QgsFeature()
                vl.getFeatures(req).nextFeature(f)
                self.assertTrue(f.isValid())
                self.assertEqual(f.attributes()[index1], 'myvalue1')
    def testInvalidGeometries(self):
        """ Test what happens when SQL Server is a POS and throws an exception on encountering an invalid geometry """
        vl = QgsVectorLayer(
            '%s srid=4167 type=POLYGON table="qgis_test"."invalid_polys" (ogr_geometry) sql='
            % (self.dbconn), "testinvalid", "mssql")
        self.assertTrue(vl.isValid())

        self.assertEqual(
            vl.dataProvider().extent().toString(1),
            QgsRectangle(173.953, -41.513, 173.967, -41.502).toString(1))

        #burn through features - don't want SQL server to trip up on the invalid ones
        count = 0
        for f in vl.dataProvider().getFeatures():
            count += 1
        self.assertEqual(count, 39)

        count = 0

        for f in vl.dataProvider().getFeatures(
                QgsFeatureRequest(QgsRectangle(173, -42, 174, -41))):
            count += 1
        # two invalid geometry features
        self.assertEqual(count, 37)
        # sorry... you get NO chance to see these features exist and repair them... because SQL server. Use PostGIS instead and live a happier life!

        # with estimated metadata
        vl = QgsVectorLayer(
            '%s srid=4167 type=POLYGON  estimatedmetadata=true table="qgis_test"."invalid_polys" (ogr_geometry) sql='
            % (self.dbconn), "testinvalid", "mssql")
        self.assertTrue(vl.isValid())
        self.assertEqual(
            vl.dataProvider().extent().toString(1),
            QgsRectangle(173.954, -41.513, 173.967, -41.502).toString(1))

        # Now, play on the edge! Let's disable invalid geometry handling and watch things crash and burn
        vl = QgsVectorLayer(
            '%s srid=4167 type=POLYGON table="qgis_test"."invalid_polys" (ogr_geometry) disableInvalidGeometryHandling="1" sql='
            % (self.dbconn), "testinvalid", "mssql")
        self.assertTrue(vl.isValid())

        self.assertEqual(vl.dataProvider().extent().toString(1),
                         'Empty')  # HAHA - you asked for it
        #burn through features - don't expect anything wrong here yet
        count = 0
        for f in vl.dataProvider().getFeatures():
            count += 1
        self.assertEqual(count, 39)
        count = 0

        for f in vl.dataProvider().getFeatures(
                QgsFeatureRequest(QgsRectangle(173, -42, 174, -41))):
            count += 1
        # now you only get 1 feature *sad trumpet*
        self.assertEqual(count, 1)
        count = 0

        # same, with estimated metadata
        vl = QgsVectorLayer(
            '%s srid=4167 type=POLYGON  estimatedmetadata=true table="qgis_test"."invalid_polys" (ogr_geometry) disableInvalidGeometryHandling="1" sql='
            % (self.dbconn), "testinvalid", "mssql")
        self.assertTrue(vl.isValid())
        self.assertEqual(vl.dataProvider().extent().toString(1), 'Empty')
Exemple #44
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",
                            QgsVectorLayer.LayerOptions(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",
                            QgsVectorLayer.LayerOptions(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", QgsVectorLayer.LayerOptions(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", QgsVectorLayer.LayerOptions(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
Exemple #45
0
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase):

    @classmethod
    def setUpClass(cls):
        cls.item_class = QgsLayoutItemMap

    def setUp(self):
        self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n"

    def tearDown(self):
        report_file_path = "%s/qgistest.html" % QDir.tempPath()
        with open(report_file_path, 'a') as report_file:
            report_file.write(self.report)

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

        myPath = os.path.join(TEST_DATA_DIR, 'points.shp')
        vector_file_info = QFileInfo(myPath)
        self.vector_layer = QgsVectorLayer(vector_file_info.filePath(),
                                           vector_file_info.completeBaseName(), 'ogr')
        assert self.vector_layer.isValid()
        QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer])

        # create layout with layout map
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()
        self.map = QgsLayoutItemMap(self.layout)
        self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        self.map.setFrameEnabled(True)
        self.map.setLayers([self.raster_layer])
        self.layout.addLayoutItem(self.map)

    def testOverviewMap(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        checker = QgsLayoutChecker('composermap_overview', self.layout)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testOverviewMapBlend(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply)
        checker = QgsLayoutChecker('composermap_overview_blending', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testOverviewMapInvert(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(True)
        checker = QgsLayoutChecker('composermap_overview_invert', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testOverviewMapCenter(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(192, -288, 320, -224)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(False)
        overviewMap.overview().setCentered(True)
        checker = QgsLayoutChecker('composermap_overview_center', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testAsMapLayer(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        l.addLayoutItem(map)

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(map)

        layer = overviewMap.overview().asMapLayer()
        self.assertIsNotNone(layer)
        self.assertTrue(layer.isValid())
        self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        # check that layer has correct renderer
        fill_symbol = QgsFillSymbol.createSimple({'color': '#00ff00', 'outline_color': '#ff0000', 'outline_width': '10'})
        overviewMap.overview().setFrameSymbol(fill_symbol)
        layer = overviewMap.overview().asMapLayer()
        self.assertIsInstance(layer.renderer(), QgsSingleSymbolRenderer)
        self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['color'], '0,255,0,255')
        self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['outline_color'], '255,0,0,255')

        # test layer blend mode
        self.assertEqual(layer.blendMode(), QPainter.CompositionMode_SourceOver)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Clear)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual(layer.blendMode(), QPainter.CompositionMode_Clear)

        # should have no effect
        overviewMap.setMapRotation(45)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        map.setMapRotation(15)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 155 -112, 163 -143, 101 -160, 93 -129))'])

        # with reprojection
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3875'))
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 96 -128, 99 -127, 102 -126, 105 -126, 108 -125, 111 -124, 114 -123, 116 -123, 119 -122, 122 -121, 125 -120, 128 -119, 131 -119, 134 -118, 137 -117, 140 -116, 143 -115, 146 -115, 149 -114, 152 -113, 155 -112, 155 -114, 156 -115, 156 -117, 156 -118, 157 -120, 157 -121, 158 -123, 158 -124, 158 -126, 159 -127, 159 -128, 160 -130, 160 -131, 160 -133, 161 -134, 161 -136, 161 -137, 162 -139, 162 -140, 163 -142, 163 -143, 160 -144, 157 -145, 154 -146, 151 -146, 148 -147, 145 -148, 142 -149, 140 -149, 137 -150, 134 -151, 131 -152, 128 -153, 125 -153, 122 -154, 119 -155, 116 -156, 113 -157, 110 -157, 107 -158, 104 -159, 101 -160, 101 -158, 100 -157, 100 -155, 100 -154, 99 -152, 99 -151, 98 -149, 98 -148, 98 -146, 97 -145, 97 -144, 96 -142, 96 -141, 96 -139, 95 -138, 95 -136, 95 -135, 94 -133, 94 -132, 93 -130, 93 -129))'])

        map.setCrs(overviewMap.crs())
        # with invert
        overviewMap.overview().setInverted(True)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((-53 -128, 128 53, 309 -128, 128 -309, -53 -128),(93 -129, 101 -160, 163 -143, 155 -112, 93 -129))'])

    def test_StackingPosition(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
        self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMap)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
        self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMapLayer)

        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(), self.raster_layer)
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(), self.vector_layer)
        overviewMap.overview().setStackingLayer(None)
        self.assertIsNone(overviewMap.overview().stackingLayer())

    def test_ModifyMapLayerList(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        l.addLayoutItem(map)

        self.assertFalse(overviewMap.overviews().modifyMapLayerList([]))
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer])
        overviewMap.overview().setLinkedMap(map)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer])
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer)
        overviewMap.overview().setStackingLayer(None)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLabels)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer])

        # two overviews
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
        overviewMap.overviews().addOverview(QgsLayoutItemMapOverview('x', overviewMap))
        overviewMap.overviews().overview(1).setLinkedMap(map)
        overviewMap.overviews().overview(1).setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [overviewMap.overviews().overview(1).asMapLayer(), self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])

    def testOverviewStacking(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        map.setFrameEnabled(True)
        map.setLayers([self.raster_layer])
        l.addLayoutItem(map)

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(-20, -276, 276, 20)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(map)
        overviewMap.overview().setInverted(True)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
        overviewMap.overview().setStackingLayer(self.raster_layer)

        checker = QgsLayoutChecker('composermap_overview_belowmap', l)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)

        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer)
        overviewMap.overview().setStackingLayer(self.raster_layer)

        checker = QgsLayoutChecker('composermap_overview_abovemap', l)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)
Exemple #46
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)
Exemple #47
0
class TestQgsComposerMap(unittest.TestCase):
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

        myPath = os.path.join(TEST_DATA_DIR, 'points.shp')
        vector_file_info = QFileInfo(myPath)
        self.vector_layer = QgsVectorLayer(vector_file_info.filePath(),
                                           vector_file_info.completeBaseName(),
                                           'ogr')
        assert self.vector_layer.isValid()

        # pipe = mRasterLayer.pipe()
        # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer'
        QgsProject.instance().addMapLayers(
            [self.raster_layer, self.vector_layer])

        # create composition with composer map
        self.mComposition = QgsComposition(QgsProject.instance())
        self.mComposition.setPaperSize(297, 210)
        self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100)
        self.mComposerMap.setFrameEnabled(True)
        self.mComposerMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(self.mComposerMap)

    def testOverviewMap(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        checker = QgsCompositionChecker('composermap_overview',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapBlend(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply)
        checker = QgsCompositionChecker('composermap_overview_blending',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapInvert(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        overviewMap.overview().setInverted(True)
        checker = QgsCompositionChecker('composermap_overview_invert',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapCenter(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(192, -288, 320, -224)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        overviewMap.overview().setInverted(False)
        overviewMap.overview().setCentered(True)
        checker = QgsCompositionChecker('composermap_overview_center',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testMapCrs(self):
        # create composition with composer map
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        composition = QgsComposition(QgsProject.instance())
        composition.setPaperSize(297, 210)

        # check that new maps inherit project CRS
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsComposerMap(composition, 20, 20, 200, 100)
        map.setFrameEnabled(True)
        rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909)
        map.setNewExtent(rectangle)
        map.setLayers([self.vector_layer])
        composition.addComposerMap(map)

        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        self.assertEqual(map.crs().authid(), 'EPSG:3857')
        self.assertEqual(map.presetCrs().authid(), 'EPSG:3857')
        checker = QgsCompositionChecker('composermap_crs3857', composition)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testComposition()
        self.assertTrue(result, message)

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(map.presetCrs().authid(), 'EPSG:4326')
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        rectangle = QgsRectangle(-124, 17, -78, 52)
        map.zoomToExtent(rectangle)
        checker = QgsCompositionChecker('composermap_crs4326', composition)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testComposition()
        self.assertTrue(result, message)

        # change back to project CRS
        map.setCrs(QgsCoordinateReferenceSystem())
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

    def testuniqueId(self):
        doc = QDomDocument()
        documentElement = doc.createElement('ComposerItemClipboard')
        self.mComposition.writeXml(documentElement, doc)
        self.mComposition.addItemsFromXml(documentElement, doc)

        # test if both composer maps have different ids
        newMap = QgsComposerMap(self.mComposition, 0, 0, 10, 10)
        mapList = self.mComposition.composerMapItems()

        for mapIt in mapList:
            if mapIt != self.mComposerMap:
                newMap = mapIt
                break

        oldId = self.mComposerMap.id()
        newId = newMap.id()

        self.mComposition.removeComposerItem(newMap)
        myMessage = 'old: %s new: %s' % (oldId, newId)
        assert oldId != newId, myMessage

    def testWorldFileGeneration(self):
        myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375,
                                   3345223.125)
        self.mComposerMap.setNewExtent(myRectangle)
        self.mComposerMap.setMapRotation(30.0)

        self.mComposition.setGenerateWorldFile(True)
        self.mComposition.setReferenceMap(self.mComposerMap)

        p = self.mComposition.computeWorldFileParameters()
        pexpected = (4.180480199790922, 2.4133064516129026, 779443.7612381146,
                     2.4136013686911886, -4.179969388427311, 3342408.5663611)
        ptolerance = (0.001, 0.001, 1, 0.001, 0.001, 1e+03)
        for i in range(0, 6):
            assert abs(p[i] - pexpected[i]) < ptolerance[i]
Exemple #48
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)
    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"))
Exemple #50
0
    def test_joined_layers_conversion(self):
        v1 = QgsVectorLayer(
            "Point?field=id:integer&field=b_id:integer&field=c_id:integer&field=name:string",
            "A", "memory")
        self.assertEqual(v1.isValid(), True)
        v2 = QgsVectorLayer(
            "Point?field=id:integer&field=bname:string&field=bfield:integer",
            "B", "memory")
        self.assertEqual(v2.isValid(), True)
        v3 = QgsVectorLayer("Point?field=id:integer&field=cname:string", "C",
                            "memory")
        self.assertEqual(v3.isValid(), True)
        QgsProject.instance().addMapLayers([v1, v2, v3])
        joinInfo = QgsVectorLayerJoinInfo()
        joinInfo.setTargetFieldName("b_id")
        joinInfo.setJoinLayer(v2)
        joinInfo.setJoinFieldName("id")
        #joinInfo.setPrefix("B_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)

        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))

        # with a field subset
        v1.removeJoin(v2.id())
        joinInfo.setJoinFieldNamesSubset(["bname"])
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 5)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))
        joinInfo.setJoinFieldNamesSubset(None)

        # add a table prefix to the join
        v1.removeJoin(v2.id())
        joinInfo.setPrefix("BB_")
        v1.addJoin(joinInfo)
        self.assertEqual(len(v1.fields()), 6)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(
            df.query(),
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS BB_bname, j1.bfield AS BB_bfield FROM {} AS t LEFT JOIN {} AS j1 ON t."b_id"=j1."id"'
            .format(v1.id(), v2.id()))
        joinInfo.setPrefix("")
        v1.removeJoin(v2.id())
        v1.addJoin(joinInfo)

        # add another join
        joinInfo2 = QgsVectorLayerJoinInfo()
        joinInfo2.setTargetFieldName("c_id")
        joinInfo2.setJoinLayer(v3)
        joinInfo2.setJoinFieldName("id")
        v1.addJoin(joinInfo2)
        self.assertEqual(len(v1.fields()), 7)
        df = QgsVirtualLayerDefinitionUtils.fromJoinedLayer(v1)
        self.assertEqual(df.query(), (
            'SELECT t.rowid AS uid, t.id, t.b_id, t.c_id, t.name, j1.bname AS B_bname, j1.bfield AS B_bfield, j2.cname AS C_cname FROM {} AS t '
            + 'LEFT JOIN {} AS j1 ON t."b_id"=j1."id" ' +
            'LEFT JOIN {} AS j2 ON t."c_id"=j2."id"').format(
                v1.id(), v2.id(), v3.id()))

        QgsProject.instance().removeMapLayers([v1.id(), v2.id(), v3.id()])
Exemple #51
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())
    def test_read_write_project(self):
        """
        Test saving/restoring dialog state in project
        """
        # print('read write project test')
        p = QgsProject.instance()
        dialog = DataPlotlyPanelWidget(None, override_iface=IFACE)
        dialog.set_plot_type('violin')

        # first, disable saving to project
        dialog.read_from_project = False
        dialog.save_to_project = False

        path = os.path.join(tempfile.gettempdir(), 'test_dataplotly_project.qgs')
        layer_path = os.path.join(
            os.path.dirname(__file__), 'test_layer.geojson')

        # create QgsVectorLayer from path and test validity
        vl = QgsVectorLayer(layer_path, 'test_layer', 'ogr')
        self.assertTrue(vl.isValid())

        # print(dialog.layer_combo.currentLayer())

        self.assertTrue(p.write(path))

        res = PlotSettings()

        # def read(doc):
        #    self.assertTrue(res.read_from_project(doc))
        #    self.assertEqual(res.plot_type, 'violin')
        #    self.read_triggered = True

        p.clear()
        for _ in range(100):
            QCoreApplication.processEvents()

        self.assertTrue(p.read(path))
        self.assertEqual(res.plot_type, 'scatter')

        # TODO - enable when dialog can restore properties and avoid this fragile test
        # # enable saving to project
        # dialog.save_to_project = True
        # dialog.read_from_project = True
        # self.assertTrue(p.write(path))
        # for _ in range(100):
        #     QCoreApplication.processEvents()

        # p.clear()

        # p.readProject.connect(read)
        # self.assertTrue(p.read(path))
        # for _ in range(100):
        #     QCoreApplication.processEvents()

        # self.assertTrue(self.read_triggered)

        # todo - test that dialog can restore properties, but requires the missing set_settings method
        dialog.x_combo.setExpression('"Ca"')
        dialog.layer_combo.setLayer(vl)

        dialog.x_combo.currentText()

        self.assertTrue(dialog.x_combo.expression(), '"Ca"')
Exemple #53
0
    def testDuplicateFeature(self):
        """ test duplicating a feature """

        project = QgsProject().instance()

        # LAYERS
        # - add first layer (parent)
        layer1 = QgsVectorLayer("Point?field=fldtxt:string&field=pkid:integer",
                                "parentlayer", "memory")
        # > check first layer (parent)
        self.assertTrue(layer1.isValid())
        # -  set the value for the copy
        layer1.setDefaultValueDefinition(1, QgsDefaultValue("rand(1000,2000)"))
        # > check first layer (parent)
        self.assertTrue(layer1.isValid())
        # - add second layer (child)
        layer2 = QgsVectorLayer(
            "Point?field=fldtxt:string&field=id:integer&field=foreign_key:integer",
            "childlayer", "memory")
        # > check second layer (child)
        self.assertTrue(layer2.isValid())
        # - add layers
        project.addMapLayers([layer1, layer2])

        # FEATURES
        # - add 2 features on layer1 (parent)
        l1f1orig = QgsFeature()
        l1f1orig.setFields(layer1.fields())
        l1f1orig.setAttributes(["F_l1f1", 100])
        l1f2orig = QgsFeature()
        l1f2orig.setFields(layer1.fields())
        l1f2orig.setAttributes(["F_l1f2", 101])
        # > check by adding features
        self.assertTrue(layer1.dataProvider().addFeatures([l1f1orig,
                                                           l1f2orig]))
        # add 4 features on layer2 (child)
        l2f1orig = QgsFeature()
        l2f1orig.setFields(layer2.fields())
        l2f1orig.setAttributes(["F_l2f1", 201, 100])
        l2f2orig = QgsFeature()
        l2f2orig.setFields(layer2.fields())
        l2f2orig.setAttributes(["F_l2f2", 202, 100])
        l2f3orig = QgsFeature()
        l2f3orig.setFields(layer2.fields())
        l2f3orig.setAttributes(["F_l2f3", 203, 100])
        l2f4orig = QgsFeature()
        l2f4orig.setFields(layer2.fields())
        l2f4orig.setAttributes(["F_l2f4", 204, 101])
        # > check by adding features
        self.assertTrue(layer2.dataProvider().addFeatures(
            [l2f1orig, l2f2orig, l2f3orig, l2f4orig]))

        # RELATION
        # - create the relationmanager
        relMgr = project.relationManager()
        # - create the relation
        rel = QgsRelation()
        rel.setId('rel1')
        rel.setName('childrel')
        rel.setReferencingLayer(layer2.id())
        rel.setReferencedLayer(layer1.id())
        rel.addFieldPair('foreign_key', 'pkid')
        rel.setStrength(QgsRelation.Composition)
        # > check relation
        self.assertTrue(rel.isValid())
        # - add relation
        relMgr.addRelation(rel)
        # > check if referencedLayer is layer1
        self.assertEqual(rel.referencedLayer(), layer1)
        # > check if referencingLayer is layer2
        self.assertEqual(rel.referencingLayer(), layer2)
        # > check if the layers are correct in relation when loading from relationManager
        relations = project.relationManager().relations()
        relation = relations[list(relations.keys())[0]]
        # > check if referencedLayer is layer1
        self.assertEqual(relation.referencedLayer(), layer1)
        # > check if referencingLayer is layer2
        self.assertEqual(relation.referencingLayer(), layer2)
        # > check the relatedfeatures
        '''
        # testoutput 1
        print( "\nAll Features and relations")
        featit=layer1.getFeatures()
        f=QgsFeature()
        while featit.nextFeature(f):
            print( f.attributes())
            childFeature = QgsFeature()
            relfeatit=rel.getRelatedFeatures(f)
            while relfeatit.nextFeature(childFeature):
                 print( childFeature.attributes() )
        print( "\n--------------------------")

        print( "\nFeatures on layer1")
        for f in layer1.getFeatures():
            print( f.attributes() )

        print( "\nFeatures on layer2")
        for f in layer2.getFeatures():
            print( f.attributes() )
        '''

        # DUPLICATION
        # - duplicate feature l1f1orig with children
        layer1.startEditing()
        results = QgsVectorLayerUtils.duplicateFeature(layer1, l1f1orig,
                                                       project, 0)

        # > check if name is name of duplicated (pk is different)
        result_feature = results[0]
        self.assertEqual(result_feature.attribute('fldtxt'),
                         l1f1orig.attribute('fldtxt'))
        # > check duplicated child layer
        result_layer = results[1].layers()[0]
        self.assertEqual(result_layer, layer2)
        #  > check duplicated child features
        self.assertTrue(results[1].duplicatedFeatures(result_layer))
        '''
        # testoutput 2
        print( "\nFeatures on layer1 (after duplication)")
        for f in layer1.getFeatures():
            print( f.attributes() )

        print( "\nFeatures on layer2 (after duplication)")
        for f in layer2.getFeatures():
            print( f.attributes() )
            
        print( "\nAll Features and relations")
        featit=layer1.getFeatures()
        f=QgsFeature()
        while featit.nextFeature(f):
            print( f.attributes())
            childFeature = QgsFeature()
            relfeatit=rel.getRelatedFeatures(f)
            while relfeatit.nextFeature(childFeature):
                 print( childFeature.attributes() )
        '''

        # > compare text of parent feature
        self.assertEqual(result_feature.attribute('fldtxt'),
                         l1f1orig.attribute('fldtxt'))

        # - create copyValueList
        childFeature = QgsFeature()
        relfeatit = rel.getRelatedFeatures(result_feature)
        copyValueList = []
        while relfeatit.nextFeature(childFeature):
            copyValueList.append(childFeature.attribute('fldtxt'))
        # - create origValueList
        childFeature = QgsFeature()
        relfeatit = rel.getRelatedFeatures(l1f1orig)
        origValueList = []
        while relfeatit.nextFeature(childFeature):
            origValueList.append(childFeature.attribute('fldtxt'))

        # - check if the ids are still the same
        self.assertEqual(copyValueList, origValueList)
Exemple #54
0
    def testRelativePaths(self):
        """
        Test whether paths to layer sources are stored as relative to the project path
        """
        tmpDir = QTemporaryDir()
        tmpFile = "{}/project.qgs".format(tmpDir.path())
        copyfile(os.path.join(TEST_DATA_DIR, "points.shp"),
                 os.path.join(tmpDir.path(), "points.shp"))
        copyfile(os.path.join(TEST_DATA_DIR, "points.dbf"),
                 os.path.join(tmpDir.path(), "points.dbf"))
        copyfile(os.path.join(TEST_DATA_DIR, "points.shx"),
                 os.path.join(tmpDir.path(), "points.shx"))
        copyfile(os.path.join(TEST_DATA_DIR, "lines.shp"),
                 os.path.join(tmpDir.path(), "lines.shp"))
        copyfile(os.path.join(TEST_DATA_DIR, "lines.dbf"),
                 os.path.join(tmpDir.path(), "lines.dbf"))
        copyfile(os.path.join(TEST_DATA_DIR, "lines.shx"),
                 os.path.join(tmpDir.path(), "lines.shx"))
        copyfile(os.path.join(TEST_DATA_DIR, "landsat_4326.tif"),
                 os.path.join(tmpDir.path(), "landsat_4326.tif"))

        project = QgsProject()

        l0 = QgsVectorLayer(os.path.join(tmpDir.path(), "points.shp"),
                            "points", "ogr")
        l1 = QgsVectorLayer(os.path.join(tmpDir.path(), "lines.shp"), "lines",
                            "ogr")
        l2 = QgsRasterLayer(os.path.join(tmpDir.path(), "landsat_4326.tif"),
                            "landsat", "gdal")
        self.assertTrue(l0.isValid())
        self.assertTrue(l1.isValid())
        self.assertTrue(l2.isValid())
        self.assertTrue(project.addMapLayers([l0, l1, l2]))
        self.assertTrue(project.write(tmpFile))
        del project

        with open(tmpFile, 'r') as f:
            content = ''.join(f.readlines())
            self.assertTrue('source="./lines.shp"' in content)
            self.assertTrue('source="./points.shp"' in content)
            self.assertTrue('source="./landsat_4326.tif"' in content)

        # Re-read the project and store absolute
        project = QgsProject()
        self.assertTrue(project.read(tmpFile))
        store = project.layerStore()
        self.assertEquals(set([l.name() for l in store.mapLayers().values()]),
                          set(['lines', 'landsat', 'points']))
        project.writeEntryBool('Paths', '/Absolute', True)
        tmpFile2 = "{}/project2.qgs".format(tmpDir.path())
        self.assertTrue(project.write(tmpFile2))

        with open(tmpFile2, 'r') as f:
            content = ''.join(f.readlines())
            self.assertTrue(
                'source="{}/lines.shp"'.format(tmpDir.path()) in content)
            self.assertTrue(
                'source="{}/points.shp"'.format(tmpDir.path()) in content)
            self.assertTrue('source="{}/landsat_4326.tif"'.format(
                tmpDir.path()) in content)

        del project
    def testPkLessQuery(self):
        """Test if features in queries with/without pk can be retrieved by id"""
        # create test db
        dbname = os.path.join(tempfile.gettempdir(), "test_pkless.sqlite")
        if os.path.exists(dbname):
            os.remove(dbname)
        con = spatialite_connect(dbname, isolation_level=None)
        cur = con.cursor()
        cur.execute("BEGIN")
        sql = "SELECT InitSpatialMetadata()"
        cur.execute(sql)

        # simple table with primary key
        sql = "CREATE TABLE \"test pk\" (id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL)"
        cur.execute(sql)

        sql = "SELECT AddGeometryColumn('test pk', 'geometry', 4326, 'POINT', 'XY')"
        cur.execute(sql)

        for i in range(11, 21):
            sql = "INSERT INTO \"test pk\" (id, name, geometry) "
            sql += "VALUES ({id}, 'name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i)
            cur.execute(sql)

        def _make_table(table_name):
            # simple table without primary key
            sql = "CREATE TABLE \"%s\" (name TEXT NOT NULL)" % table_name
            cur.execute(sql)

            sql = "SELECT AddGeometryColumn('%s', 'geom', 4326, 'POINT', 'XY')" % table_name
            cur.execute(sql)

            for i in range(11, 21):
                sql = "INSERT INTO \"%s\" (name, geom) " % table_name
                sql += "VALUES ('name {id}', GeomFromText('POINT({id} {id})', 4326))".format(id=i)
                cur.execute(sql)

        _make_table("somedata")
        _make_table("some data")

        sql = "CREATE VIEW \"some view\" AS SELECT * FROM \"somedata\""
        cur.execute(sql)

        cur.execute("COMMIT")
        con.close()

        def _check_features(vl, offset):
            self.assertEqual(vl.featureCount(), 10)
            i = 11
            for f in vl.getFeatures():
                self.assertTrue(f.isValid())
                self.assertTrue(vl.getFeature(i - offset).isValid())
                self.assertEqual(vl.getFeature(i - offset)['name'], 'name {id}'.format(id=i))
                self.assertEqual(f.id(), i - offset)
                self.assertEqual(f['name'], 'name {id}'.format(id=i))
                self.assertEqual(f.geometry().asWkt(), 'Point ({id} {id})'.format(id=i))
                i += 1

        vl_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from \\"test pk\\")" (geometry) sql=' % dbname, 'pk', 'spatialite')
        self.assertTrue(vl_pk.isValid())
        _check_features(vl_pk, 0)

        vl_no_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from somedata)" (geom) sql=' % dbname, 'pk', 'spatialite')
        self.assertTrue(vl_no_pk.isValid())
        _check_features(vl_no_pk, 10)

        vl_no_pk = QgsVectorLayer('dbname=\'%s\' table="(select * from \\"some data\\")" (geom) sql=' % dbname, 'pk', 'spatialite')
        self.assertTrue(vl_no_pk.isValid())
        _check_features(vl_no_pk, 10)

        # Test regression when sending queries with aliased tables from DB manager
        self._aliased_sql_helper(dbname)
    def test_Query(self):
        l1 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", QgsVectorLayer.LayerOptions(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", QgsVectorLayer.LayerOptions(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", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 6)
        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", QgsVectorLayer.LayerOptions(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", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        self.assertEqual(l2.dataProvider().wkbType(), 6)
        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", QgsVectorLayer.LayerOptions(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", QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), False)

        QgsProject.instance().removeMapLayer(l1.id())
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase):
    @classmethod
    def setUpClass(cls):
        cls.item_class = QgsLayoutItemMap

    def setUp(self):
        self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n"

    def tearDown(self):
        report_file_path = "%s/qgistest.html" % QDir.tempPath()
        with open(report_file_path, 'a') as report_file:
            report_file.write(self.report)

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

        myPath = os.path.join(TEST_DATA_DIR, 'points.shp')
        vector_file_info = QFileInfo(myPath)
        self.vector_layer = QgsVectorLayer(vector_file_info.filePath(),
                                           vector_file_info.completeBaseName(),
                                           'ogr')
        assert self.vector_layer.isValid()

        # pipe = mRasterLayer.pipe()
        # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer'
        QgsProject.instance().addMapLayers(
            [self.raster_layer, self.vector_layer])

        # create layout with layout map
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()
        self.map = QgsLayoutItemMap(self.layout)
        self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        self.map.setFrameEnabled(True)
        self.map.setLayers([self.raster_layer])
        self.layout.addLayoutItem(self.map)

    def testOverviewMap(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        checker = QgsLayoutChecker('composermap_overview', self.layout)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapBlend(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply)
        checker = QgsLayoutChecker('composermap_overview_blending',
                                   self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapInvert(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(True)
        checker = QgsLayoutChecker('composermap_overview_invert', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapCenter(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(192, -288, 320, -224)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(False)
        overviewMap.overview().setCentered(True)
        checker = QgsLayoutChecker('composermap_overview_center', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testMapCrs(self):
        # create layout with layout map
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        layout = QgsLayout(QgsProject.instance())
        layout.initializeDefaults()

        # check that new maps inherit project CRS
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        map.setFrameEnabled(True)
        rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909)
        map.setExtent(rectangle)
        map.setLayers([self.vector_layer])
        layout.addLayoutItem(map)

        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        self.assertEqual(map.crs().authid(), 'EPSG:3857')
        self.assertEqual(map.presetCrs().authid(), 'EPSG:3857')

        checker = QgsLayoutChecker('composermap_crs3857', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(map.presetCrs().authid(), 'EPSG:4326')
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        rectangle = QgsRectangle(-124, 17, -78, 52)
        map.zoomToExtent(rectangle)
        checker = QgsLayoutChecker('composermap_crs4326', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # change back to project CRS
        map.setCrs(QgsCoordinateReferenceSystem())
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

    def testContainsAdvancedEffects(self):
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        layout = QgsLayout(QgsProject.instance())
        map = QgsLayoutItemMap(layout)

        self.assertFalse(map.containsAdvancedEffects())
        self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken)
        result = map.containsAdvancedEffects()
        self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
        self.assertTrue(result)

    def testRasterization(self):
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        layout = QgsLayout(QgsProject.instance())
        map = QgsLayoutItemMap(layout)

        self.assertFalse(map.requiresRasterization())
        self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken)
        self.assertFalse(map.requiresRasterization())
        self.assertTrue(map.containsAdvancedEffects())

        map.setBackgroundEnabled(False)
        self.assertTrue(map.requiresRasterization())
        map.setBackgroundEnabled(True)
        map.setBackgroundColor(QColor(1, 1, 1, 1))
        self.assertTrue(map.requiresRasterization())

        self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
Exemple #58
0
    def testStyle(self):

        # First test with invalid URI
        vl = QgsVectorLayer('/idont/exist.gpkg', 'test', 'ogr')

        self.assertFalse(
            vl.dataProvider().isSaveAndLoadStyleToDatabaseSupported())

        related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase(
        )
        self.assertEqual(related_count, -1)
        self.assertEqual(idlist, [])
        self.assertEqual(namelist, [])
        self.assertEqual(desclist, [])
        self.assertNotEqual(errmsg, "")

        qml, errmsg = vl.getStyleFromDatabase("1")
        self.assertEqual(qml, "")
        self.assertNotEqual(errmsg, "")

        qml, success = vl.loadNamedStyle('/idont/exist.gpkg')
        self.assertFalse(success)

        errorMsg = vl.saveStyleToDatabase("name", "description", False, "")
        self.assertNotEqual(errorMsg, "")

        # Now with valid URI
        tmpfile = os.path.join(self.basetestpath, 'testStyle.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
        lyr = ds.CreateLayer('test2', geom_type=ogr.wkbMultiPolygon)
        lyr.CreateField(ogr.FieldDefn('foo', ogr.OFTString))
        f = ogr.Feature(lyr.GetLayerDefn())
        f['foo'] = 'bar'
        lyr.CreateFeature(f)
        f = None
        ds = None

        vl = QgsVectorLayer('{}|layername=test'.format(tmpfile), 'test', 'ogr')
        self.assertTrue(vl.isValid())

        vl2 = QgsVectorLayer('{}|layername=test2'.format(tmpfile), 'test2',
                             'ogr')
        self.assertTrue(vl2.isValid())

        self.assertTrue(
            vl.dataProvider().isSaveAndLoadStyleToDatabaseSupported())

        related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase(
        )
        self.assertEqual(related_count, 0)
        self.assertEqual(idlist, [])
        self.assertEqual(namelist, [])
        self.assertEqual(desclist, [])
        self.assertNotEqual(errmsg, "")

        qml, errmsg = vl.getStyleFromDatabase("not_existing")
        self.assertEqual(qml, "")
        self.assertNotEqual(errmsg, "")

        qml, success = vl.loadNamedStyle('{}|layerid=0'.format(tmpfile))
        self.assertFalse(success)

        errorMsg = vl.saveStyleToDatabase("name", "description", False, "")
        self.assertEqual(errorMsg, "")

        qml, errmsg = vl.getStyleFromDatabase("not_existing")
        self.assertEqual(qml, "")
        self.assertNotEqual(errmsg, "")

        related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase(
        )
        self.assertEqual(related_count, 1)
        self.assertEqual(errmsg, "")
        self.assertEqual(idlist, ['1'])
        self.assertEqual(namelist, ['name'])
        self.assertEqual(desclist, ['description'])

        qml, errmsg = vl.getStyleFromDatabase("100")
        self.assertEqual(qml, "")
        self.assertNotEqual(errmsg, "")

        qml, errmsg = vl.getStyleFromDatabase("1")
        self.assertTrue(qml.startswith('<!DOCTYPE qgis'), qml)
        self.assertEqual(errmsg, "")

        # Try overwrite it but simulate answer no
        settings = QgsSettings()
        settings.setValue("/qgis/overwriteStyle", False)
        errorMsg = vl.saveStyleToDatabase("name", "description_bis", False, "")
        self.assertNotEqual(errorMsg, "")

        related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase(
        )
        self.assertEqual(related_count, 1)
        self.assertEqual(errmsg, "")
        self.assertEqual(idlist, ['1'])
        self.assertEqual(namelist, ['name'])
        self.assertEqual(desclist, ['description'])

        # Try overwrite it and simulate answer yes
        settings = QgsSettings()
        settings.setValue("/qgis/overwriteStyle", True)
        errorMsg = vl.saveStyleToDatabase("name", "description_bis", False, "")
        self.assertEqual(errorMsg, "")

        related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase(
        )
        self.assertEqual(related_count, 1)
        self.assertEqual(errmsg, "")
        self.assertEqual(idlist, ['1'])
        self.assertEqual(namelist, ['name'])
        self.assertEqual(desclist, ['description_bis'])

        errorMsg = vl2.saveStyleToDatabase("name_test2", "description_test2",
                                           True, "")
        self.assertEqual(errorMsg, "")

        errorMsg = vl.saveStyleToDatabase("name2", "description2", True, "")
        self.assertEqual(errorMsg, "")

        errorMsg = vl.saveStyleToDatabase("name3", "description3", True, "")
        self.assertEqual(errorMsg, "")

        related_count, idlist, namelist, desclist, errmsg = vl.listStylesInDatabase(
        )
        self.assertEqual(related_count, 3)
        self.assertEqual(errmsg, "")
        self.assertEqual(idlist, ['1', '3', '4', '2'])
        self.assertEqual(namelist, ['name', 'name2', 'name3', 'name_test2'])
        self.assertEqual(
            desclist,
            ['description_bis', 'description2', 'description3', 'name_test2'])

        # Check that layers_style table is not list in subLayers()
        vl = QgsVectorLayer(tmpfile, 'test', 'ogr')
        sublayers = vl.dataProvider().subLayers()
        self.assertEqual(len(sublayers), 2, sublayers)
    def testRequestRepaintMultiple(self):
        """ test requesting repaint with multiple dependent layers """
        layer1 = QgsVectorLayer("Point?field=fldtxt:string", "layer1",
                                "memory")
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        QgsProject.instance().addMapLayers([layer1, layer2])
        self.assertTrue(layer1.isValid())
        self.assertTrue(layer2.isValid())

        # add image to cache - no dependent layers
        cache = QgsMapRendererCache()
        im1 = QImage(200, 200, QImage.Format_RGB32)
        cache.setCacheImage('nolayer', im1)
        self.assertFalse(cache.cacheImage('nolayer').isNull())
        self.assertTrue(cache.hasCacheImage('nolayer'))

        # trigger repaint on layer
        layer1.triggerRepaint()
        layer1.triggerRepaint(
        )  # do this a couple of times - we don't want errors due to multiple disconnects, etc
        layer2.triggerRepaint()
        layer2.triggerRepaint()
        # cache image should still exist - it's not dependent on layers
        self.assertFalse(cache.cacheImage('nolayer').isNull())
        self.assertTrue(cache.hasCacheImage('nolayer'))

        # image depends on 1 layer
        im_l1 = QImage(200, 200, QImage.Format_RGB32)
        cache.setCacheImage('im1', im_l1, [layer1])

        # image depends on 2 layers
        im_l1_l2 = QImage(200, 200, QImage.Format_RGB32)
        cache.setCacheImage('im1_im2', im_l1_l2, [layer1, layer2])

        # image depends on 2nd layer alone
        im_l2 = QImage(200, 200, QImage.Format_RGB32)
        cache.setCacheImage('im2', im_l2, [layer2])

        self.assertFalse(cache.cacheImage('im1').isNull())
        self.assertTrue(cache.hasCacheImage('im1'))
        self.assertFalse(cache.cacheImage('im1_im2').isNull())
        self.assertTrue(cache.hasCacheImage('im1_im2'))
        self.assertFalse(cache.cacheImage('im2').isNull())
        self.assertTrue(cache.hasCacheImage('im2'))

        # trigger repaint layer 1 (check twice - don't want disconnect errors)
        for i in range(2):
            layer1.triggerRepaint()
            # should be cleared
            self.assertTrue(cache.cacheImage('im1').isNull())
            self.assertFalse(cache.hasCacheImage('im1'))
            self.assertTrue(cache.cacheImage('im1_im2').isNull())
            self.assertFalse(cache.hasCacheImage('im1_im2'))
            # should be retained
            self.assertTrue(cache.hasCacheImage('im2'))
            self.assertFalse(cache.cacheImage('im2').isNull())
            self.assertEqual(cache.cacheImage('im2'), im_l2)
            self.assertTrue(cache.hasCacheImage('nolayer'))
            self.assertFalse(cache.cacheImage('nolayer').isNull())
            self.assertEqual(cache.cacheImage('nolayer'), im1)

        # trigger repaint layer 2
        for i in range(2):
            layer2.triggerRepaint()
            # should be cleared
            self.assertFalse(cache.hasCacheImage('im1'))
            self.assertTrue(cache.cacheImage('im1').isNull())
            self.assertFalse(cache.hasCacheImage('im1_im2'))
            self.assertTrue(cache.cacheImage('im1_im2').isNull())
            self.assertFalse(cache.hasCacheImage('im2'))
            self.assertTrue(cache.cacheImage('im2').isNull())
            # should be retained
            self.assertTrue(cache.hasCacheImage('nolayer'))
            self.assertFalse(cache.cacheImage('nolayer').isNull())
            self.assertEqual(cache.cacheImage('nolayer'), im1)
    def test_valid_import_geom_2d_to_db_gpkg(self):
        print(
            '\nINFO: Validating ETL-Model from [ Point, PointZ, PointM, PointZM ] to Point geometries...'
        )

        # Layer in LADM for test
        test_layer = self.qgis_utils.get_layer(self.db_connection,
                                               BOUNDARY_POINT_TABLE,
                                               load=True)

        # Point To Point
        print("Validating Point to Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        run_etl_model(point_layer, out_layer=test_layer)
        test_layer.startEditing()
        print("Info: Validating geometry Point...")
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.Point, point_layer.wkbType())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()

        # PointZ To Point
        print("Validating PointZ to Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points_Z')
        point_layer = QgsVectorLayer(uri, 'points_Z', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        self.assertIn(point_layer.wkbType(),
                      [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D])
        output = run_etl_model(point_layer, out_layer=test_layer)
        print("Info: Validating geometry PointZ...", test_layer.wkbType())
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()

        # PointM To Point
        print("Validating PointM To Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points_M')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        run_etl_model(point_layer, out_layer=test_layer)
        print("Info: Validating geometry PointZ...", test_layer.wkbType())
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.PointM, point_layer.wkbType())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()

        # PointZM To Point
        print("Validating PointZM To Point")
        uri = self.gpkg_path + '|layername={layername}'.format(
            layername='points_ZM')
        point_layer = QgsVectorLayer(uri, 'points', 'ogr')
        print("Is Valid layer :", point_layer.isValid())
        run_etl_model(point_layer, out_layer=test_layer)
        print("Info: Validating geometry PointZ...", test_layer.wkbType())
        self.assertEqual(QgsWkbTypes.PointGeometry, test_layer.type())
        self.assertEqual(QgsWkbTypes.PointZM, point_layer.wkbType())
        self.assertEqual(QgsWkbTypes.Point, test_layer.wkbType())
        self.assertEqual(test_layer.featureCount(), 51)
        clean_table('test_ladm_col', BOUNDARY_POINT_TABLE)
        test_layer.dataProvider().truncate()