def testNoDanglingFileDescriptorAfterCloseVariant2(self):
        ''' Test that when closing the provider all file handles are released '''

        temp_dbname = self.dbname + '.no_dangling_test2'
        shutil.copy(self.dbname, temp_dbname)

        vl = QgsVectorLayer("dbname=%s table=test_n (geometry)" % temp_dbname, "test_n", "spatialite")
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.isValid())
        # Consume all features.
        myiter = vl.getFeatures()
        for feature in myiter:
            pass
        # The iterator is closed
        if sys.platform.startswith('linux'):
            self.assertEqual(count_opened_filedescriptors(temp_dbname), 2)

        # Should release one file descriptor
        del vl

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

        # Check that deletion works well (can only fail on Windows)
        os.unlink(temp_dbname)
        self.assertFalse(os.path.exists(temp_dbname))
示例#2
0
    def testCreateUniqueValue(self):
        """ test creating a unique value """
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double",
                               "addfeat", "memory")
        # add a bunch of features
        f = QgsFeature()
        f.setAttributes(["test", 123, 1.0])
        f1 = QgsFeature(2)
        f1.setAttributes(["test_1", 124, 1.1])
        f2 = QgsFeature(3)
        f2.setAttributes(["test_2", 125, 2.4])
        f3 = QgsFeature(4)
        f3.setAttributes(["test_3", 126, 1.7])
        f4 = QgsFeature(5)
        f4.setAttributes(["superpig", 127, 0.8])
        self.assertTrue(layer.dataProvider().addFeatures([f, f1, f2, f3, f4]))

        # bad field indices
        self.assertFalse(QgsVectorLayerUtils.createUniqueValue(layer, -10))
        self.assertFalse(QgsVectorLayerUtils.createUniqueValue(layer, 10))

        # integer field
        self.assertEqual(QgsVectorLayerUtils.createUniqueValue(layer, 1), 128)

        # double field
        self.assertEqual(QgsVectorLayerUtils.createUniqueValue(layer, 2), 3.0)

        # string field
        self.assertEqual(QgsVectorLayerUtils.createUniqueValue(layer, 0), 'test_4')
        self.assertEqual(QgsVectorLayerUtils.createUniqueValue(layer, 0, 'test_1'), 'test_4')
        self.assertEqual(QgsVectorLayerUtils.createUniqueValue(layer, 0, 'seed'), 'seed')
        self.assertEqual(QgsVectorLayerUtils.createUniqueValue(layer, 0, 'superpig'), 'superpig_1')
示例#3
0
    def testNoDanglingFileDescriptorAfterCloseVariant2(self):
        ''' Test that when closing the provider all file handles are released '''

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

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

        # Should release one file descriptor
        del vl

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

        # Check that deletion works well (can only fail on Windows)
        os.unlink(datasource)
        self.assertFalse(os.path.exists(datasource))
    def testSkipConstraintCheck(self):
        vl = QgsVectorLayer("dbname=%s table=test_autoincrement" % self.dbname, "test_autoincrement",
                            "spatialite")
        self.assertTrue(vl.isValid())

        self.assertTrue(vl.dataProvider().skipConstraintCheck(0, QgsFieldConstraints.ConstraintUnique, str("Autogenerate")))
        self.assertFalse(vl.dataProvider().skipConstraintCheck(0, QgsFieldConstraints.ConstraintUnique, 123))
示例#5
0
    def checkRepaintNonLabeledLayerDoesNotInvalidateLabelCache(self, job_type):
        layer = QgsVectorLayer("Point?field=fldtxt:string",
                               "layer1", "memory")
        settings = QgsMapSettings()
        settings.setExtent(QgsRectangle(5, 25, 25, 45))
        settings.setOutputSize(QSize(600, 400))
        settings.setLayers([layer])

        # with cache - first run should populate cache
        cache = QgsMapRendererCache()
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertFalse(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(cache.hasCacheImage(layer.id()))
        self.assertEqual(cache.dependentLayers('_labels_'), [])

        # trigger repaint on layer - should not invalidate label cache because layer is not labeled
        layer.triggerRepaint()
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertFalse(cache.hasCacheImage(layer.id()))
        self.assertTrue(job.takeLabelingResults())

        # second job should still use label cache
        job = job_type(settings)
        job.setCache(cache)
        job.start()
        job.waitForFinished()
        self.assertTrue(job.usedCachedLabels())
        self.assertTrue(cache.hasCacheImage('_labels_'))
        self.assertTrue(job.takeLabelingResults())
示例#6
0
    def test_ValueMap_representValue(self):
        layer = QgsVectorLayer("none?field=number1:integer&field=number2:double&field=text1:string&field=number3:integer&field=number4:double&field=text2:string",
                               "layer", "memory")
        assert layer.isValid()
        QgsMapLayerRegistry.instance().addMapLayer(layer)
        f = QgsFeature()
        f.setAttributes([2, 2.5, 'NULL', None, None, None])
        assert layer.dataProvider().addFeatures([f])
        reg = QgsEditorWidgetRegistry.instance()
        factory = reg.factory("ValueMap")
        self.assertIsNotNone(factory)

        # Tests with different value types occurring in the value map
        config = {'two': '2', 'twoandhalf': '2.5', 'NULL text': 'NULL',
                  'nothing': self.VALUEMAP_NULL_TEXT}
        self.assertEqual(factory.representValue(layer, 0, config, None, 2), 'two')
        self.assertEqual(factory.representValue(layer, 1, config, None, 2.5), 'twoandhalf')
        self.assertEqual(factory.representValue(layer, 2, config, None, 'NULL'), 'NULL text')
        # Tests with null values of different types, if value map contains null
        self.assertEqual(factory.representValue(layer, 3, config, None, None), 'nothing')
        self.assertEqual(factory.representValue(layer, 4, config, None, None), 'nothing')
        self.assertEqual(factory.representValue(layer, 5, config, None, None), 'nothing')
        # Tests with fallback display for different value types
        config = {}
        self.assertEqual(factory.representValue(layer, 0, config, None, 2), '(2)')
        self.assertEqual(factory.representValue(layer, 1, config, None, 2.5), '(2.50000)')
        self.assertEqual(factory.representValue(layer, 2, config, None, 'NULL'), '(NULL)')
        # Tests with fallback display for null in different types of fields
        self.assertEqual(factory.representValue(layer, 3, config, None, None), '(NULL)')
        self.assertEqual(factory.representValue(layer, 4, config, None, None), '(NULL)')
        self.assertEqual(factory.representValue(layer, 5, config, None, None), '(NULL)')

        QgsMapLayerRegistry.instance().removeAllMapLayers()
示例#7
0
 def testKey(lyr, key, kfnames):
     self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.import_test')
     uri = '%s table="qgis_test"."import_test" (g)' % self.dbconn
     if key is not None:
         uri += ' key=\'%s\'' % key
     err = QgsVectorLayerExporter.exportLayer(lyr, uri, "postgres", lyr.crs())
     self.assertEqual(err[0], QgsVectorLayerExporter.NoError,
                      'unexpected import error {0}'.format(err))
     olyr = QgsVectorLayer(uri, "y", "postgres")
     self.assertTrue(olyr.isValid())
     flds = lyr.fields()
     oflds = olyr.fields()
     if key is None:
         # if the pkey was not given, it will create a pkey
         self.assertEqual(oflds.size(), flds.size() + 1)
         self.assertEqual(oflds[0].name(), kfnames[0])
         for i in range(flds.size()):
             self.assertEqual(oflds[i + 1].name(), flds[i].name())
     else:
         # pkey was given, no extra field generated
         self.assertEqual(oflds.size(), flds.size())
         for i in range(oflds.size()):
             self.assertEqual(oflds[i].name(), flds[i].name())
     pks = olyr.pkAttributeList()
     self.assertEqual(len(pks), len(kfnames))
     for i in range(0, len(kfnames)):
         self.assertEqual(oflds[pks[i]].name(), kfnames[i])
    def testFilter(self):
        """ test calculating aggregate with filter """

        layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
        pr = layer.dataProvider()

        int_values = [4, 2, 3, 2, 5, None, 8]

        features = []
        for v in int_values:
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([v])
            features.append(f)
        assert pr.addFeatures(features)

        agg = QgsAggregateCalculator(layer)

        filter_string = "fldint > 2"
        agg.setFilter(filter_string)
        self.assertEqual(agg.filter(), filter_string)

        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint')
        self.assertTrue(ok)
        self.assertEqual(val, 20)

        # remove filter and retest
        agg.setFilter(None)
        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint')
        self.assertTrue(ok)
        self.assertEqual(val, 24)
示例#9
0
    def createLayer(cls):
        vl = QgsVectorLayer(
            'Point?crs=epsg:4326&field=pk:integer&field=cnt:integer&field=name:string(0)&field=name2:string(0)&field=num_char:string&key=pk',
            'test', 'pythonprovider')
        assert (vl.isValid())

        f1 = QgsFeature()
        f1.setAttributes([5, -200, NULL, 'NuLl', '5'])
        f1.setGeometry(QgsGeometry.fromWkt('Point (-71.123 78.23)'))

        f2 = QgsFeature()
        f2.setAttributes([3, 300, 'Pear', 'PEaR', '3'])

        f3 = QgsFeature()
        f3.setAttributes([1, 100, 'Orange', 'oranGe', '1'])
        f3.setGeometry(QgsGeometry.fromWkt('Point (-70.332 66.33)'))

        f4 = QgsFeature()
        f4.setAttributes([2, 200, 'Apple', 'Apple', '2'])
        f4.setGeometry(QgsGeometry.fromWkt('Point (-68.2 70.8)'))

        f5 = QgsFeature()
        f5.setAttributes([4, 400, 'Honey', 'Honey', '4'])
        f5.setGeometry(QgsGeometry.fromWkt('Point (-65.32 78.3)'))

        vl.dataProvider().addFeatures([f1, f2, f3, f4, f5])
        return vl
    def testSaveLoadProject(self):

        schema_uri = encode_uri(self.ds_uri, 'qgis_test')
        project_uri = encode_uri(self.ds_uri, 'qgis_test', 'abc')

        self.dropProjectsTable()  # make sure we have a clean start

        prj = QgsProject()
        uri = self.vl.source()
        vl1 = QgsVectorLayer(uri, 'test', 'postgres')
        self.assertEqual(vl1.isValid(), True)
        prj.addMapLayer(vl1)

        prj_storage = QgsApplication.projectStorageRegistry().projectStorageFromType("postgresql")
        self.assertTrue(prj_storage)

        lst0 = prj_storage.listProjects(schema_uri)
        self.assertEqual(lst0, [])

        # try to save project in the database

        prj.setFileName(project_uri)
        res = prj.write()
        self.assertTrue(res)

        lst1 = prj_storage.listProjects(schema_uri)
        self.assertEqual(lst1, ["abc"])

        # now try to load the project back

        prj2 = QgsProject()
        prj2.setFileName(project_uri)
        res = prj2.read()
        self.assertTrue(res)

        self.assertEqual(len(prj2.mapLayers()), 1)

        self.assertEqual(prj2.baseName(), "abc")
        self.assertEqual(prj2.absoluteFilePath(), "")  # path not supported for project storages
        self.assertTrue(abs(prj2.lastModified().secsTo(QDateTime.currentDateTime())) < 10)

        # try to see project's metadata

        res, metadata = prj_storage.readProjectStorageMetadata(project_uri)
        self.assertTrue(res)
        self.assertEqual(metadata.name, "abc")
        time_project = metadata.lastModified
        time_now = QDateTime.currentDateTime()
        time_diff = time_now.secsTo(time_project)
        self.assertTrue(abs(time_diff) < 10)

        # try to remove the project

        res = prj_storage.removeProject(project_uri)
        self.assertTrue(res)

        lst2 = prj_storage.listProjects(schema_uri)
        self.assertEqual(lst2, [])

        self.dropProjectsTable()  # make sure we have a clean finish... "leave no trace"
 def aoiExtent(cls):
     """Area of interest extent, which matches output aspect ratio"""
     uri = QgsDataSourceUri()
     uri.setDatabase(cls._PalFeaturesDb)
     uri.setDataSource('', 'aoi', 'geometry')
     aoilayer = QgsVectorLayer(uri.uri(), 'aoi', 'spatialite')
     return aoilayer.extent()
示例#12
0
    def runTestForLayer(self, layer, testname):
        tempdir = tempfile.mkdtemp()

        layer = QgsVectorLayer(layer, 'Layer', 'ogr')
        QgsProject.instance().addMapLayer(layer)
        self.iface.mapCanvas().setExtent(layer.extent())

        geom = next(layer.getFeatures()).geometry()

        highlight = QgsHighlight(self.iface.mapCanvas(), geom, layer)
        color = QColor(Qt.red)
        highlight.setColor(color)
        highlight.setWidth(2)
        color.setAlpha(50)
        highlight.setFillColor(color)
        highlight.show()

        image = QImage(QSize(400, 400), QImage.Format_ARGB32)
        image.fill(Qt.white)
        painter = QPainter()
        painter.begin(image)
        self.iface.mapCanvas().render(painter)
        painter.end()
        control_image = os.path.join(tempdir, 'highlight_{}.png'.format(testname))
        image.save(control_image)
        checker = QgsRenderChecker()
        checker.setControlPathPrefix("highlight")
        checker.setControlName("expected_highlight_{}".format(testname))
        checker.setRenderedImage(control_image)
        self.assertTrue(checker.compareImages("highlight_{}".format(testname)))
        shutil.rmtree(tempdir)
    def setUp(self):
        self.iface = get_iface()

        polys_shp = os.path.join(TEST_DATA_DIR, 'polys.shp')
        points_shp = os.path.join(TEST_DATA_DIR, 'points.shp')
        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.polys_layer = QgsVectorLayer(polys_shp, 'Polygons', 'ogr')
        self.points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr')
        self.lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsProject.instance().addMapLayer(self.polys_layer)
        QgsProject.instance().addMapLayer(self.lines_layer)
        QgsProject.instance().addMapLayer(self.points_layer)

        # Create style
        sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'})
        sym2 = QgsLineSymbol.createSimple({'color': '#fdbf6f'})
        sym3 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'})

        self.polys_layer.setRenderer(QgsSingleSymbolRenderer(sym1))
        self.lines_layer.setRenderer(QgsSingleSymbolRenderer(sym2))
        self.points_layer.setRenderer(QgsSingleSymbolRenderer(sym3))

        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-133, 22, -70, 52))
示例#14
0
文件: parameters.py 项目: ndavid/QGIS
    def __init__(self, name='', description='', options=[], default=None, isSource=False,
                 multiple=False, optional=False):
        Parameter.__init__(self, name, description, default, optional)
        self.multiple = multiple
        isSource = parseBool(isSource)
        self.options = options
        if isSource:
            self.options = []
            layer = QgsVectorLayer(options[0], "layer", "ogr")
            if layer.isValid():
                try:
                    index = resolveFieldIndex(layer, options[1])
                    feats = QgsProcessingUtils.getFeatures(layer, dataobjects.createContext())
                    for feature in feats:
                        self.options.append(str(feature.attributes()[index]))
                except ValueError:
                    pass
        elif isinstance(self.options, str):
            self.options = self.options.split(";")

        # compute options as (value, text)
        options = []
        for i, option in enumerate(self.options):
            if option is None or isinstance(option, basestring):
                options.append((i, option))
            else:
                options.append((option[0], option[1]))
        self.options = options
        self.values = [option[0] for option in options]

        self.value = None
示例#15
0
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp')
        layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(layer)

        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'})
        sym2 = QgsFillSymbol.createSimple({'color': '#71bd6c', 'outline_color': 'black'})
        sym3 = QgsFillSymbol.createSimple({'color': '#1f78b4', 'outline_color': 'black'})

        self.r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1')
        self.r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2')
        self.r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE')

        rootrule = QgsRuleBasedRenderer.Rule(None)
        rootrule.appendChild(self.r1)
        rootrule.appendChild(self.r2)
        rootrule.appendChild(self.r3)

        layer.setRenderer(QgsRuleBasedRenderer(rootrule))
        self.mapsettings = QgsMapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))

        rendered_layers = [layer]
        self.mapsettings.setLayers(rendered_layers)
示例#16
0
        def _round_trip(value, field, version='1.1.0'):
            """Set a value on fid 22 and field and check it back"""

            encoded_data = post_data.format(field=field, value=value, version=version).encode('utf8')
            # Strip the field if NULL
            if value is None:
                encoded_data = encoded_data.replace(b'<wfs:Value>None</wfs:Value>', b'')

            header, body = self._execute_request("?MAP=%s&SERVICE=WFS&VERSION=%s" % (
                self.testdata_path + 'test_project_wms_grouped_layers.qgs', version), QgsServerRequest.PostMethod, encoded_data)
            if version == '1.0.0':
                self.assertTrue(b'<SUCCESS/>' in body, body)
            else:
                self.assertTrue(b'<TotalUpdated>1</TotalUpdated>' in body, body)
            header, body = self._execute_request("?MAP=%s&SERVICE=WFS&REQUEST=GetFeature&TYPENAME=cdb_lines&FEATUREID=cdb_lines.22" % (
                self.testdata_path + 'test_project_wms_grouped_layers.qgs'))
            if value is not None:
                xml_value = '<qgs:{0}>{1}</qgs:{0}>'.format(field, value).encode('utf8')
                self.assertTrue(xml_value in body, "%s not found in body" % xml_value)
            else:
                xml_value = '<qgs:{0}>'.format(field).encode('utf8')
                self.assertFalse(xml_value in body)
            # Check the backend
            vl = QgsVectorLayer(
                self.testdata_path + 'test_project_wms_grouped_layers.gpkg|layername=cdb_lines', 'vl', 'ogr')
            self.assertTrue(vl.isValid())
            self.assertEqual(
                str(vl.getFeature(22)[field]), value if value is not None else 'NULL')
示例#17
0
    def test_expressionRequiresFormScope(self):

        res = list(QgsValueRelationFieldFormatter.expressionFormAttributes("current_value('ONE') AND current_value('TWO')"))
        res = sorted(res)
        self.assertEqual(res, ['ONE', 'TWO'])

        res = list(QgsValueRelationFieldFormatter.expressionFormVariables("@current_geometry"))
        self.assertEqual(res, ['current_geometry'])

        self.assertFalse(QgsValueRelationFieldFormatter.expressionRequiresFormScope(""))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value('TWO')"))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value ( 'TWO' )"))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("@current_geometry"))

        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("", QgsFeature()))
        self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry", QgsFeature()))
        self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", QgsFeature()))

        layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string",
                               "layer", "memory")
        self.assertTrue(layer.isValid())
        QgsProject.instance().addMapLayer(layer)
        f = QgsFeature(layer.fields())
        f.setAttributes([1, 'value'])
        point = QgsGeometry.fromPointXY(QgsPointXY(123, 456))
        f.setGeometry(point)
        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_geometry", f))
        self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", f))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'pkid' )", f))
        self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry current_value ( 'pkid' )", f))

        QgsProject.instance().removeMapLayer(layer.id())
示例#18
0
    def testUniqueValues(self):
        ProcessingConfig.initialize()

        # disable check for geometry validity
        prevInvalidGeoms = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES)
        ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, 0)

        test_data = points()
        test_layer = QgsVectorLayer(test_data, 'test', 'ogr')

        # field by index
        v = vector.uniqueValues(test_layer, 2)
        self.assertEqual(len(v), len(set(v)))
        self.assertEqual(set(v), set([2, 1, 0]))

        # field by name
        v = vector.uniqueValues(test_layer, 'id2')
        self.assertEqual(len(v), len(set(v)))
        self.assertEqual(set(v), set([2, 1, 0]))

        # test with selected features
        previous_value = ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)
        ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True)
        test_layer.selectByIds([2, 4, 6])
        v = vector.uniqueValues(test_layer, 'id')
        self.assertEqual(len(v), len(set(v)))
        self.assertEqual(set(v), set([5, 7, 3]))

        ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value)
        ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, prevInvalidGeoms)
示例#19
0
    def test_representValue(self):
        QgsSettings().setValue("qgis/nullValue", "NULL")
        layer = QgsVectorLayer("none?field=number1:integer&field=number2:double&field=text1:string&field=number3:integer&field=number4:double&field=text2:string",
                               "layer", "memory")
        self.assertTrue(layer.isValid())
        QgsProject.instance().addMapLayer(layer)
        f = QgsFeature()
        f.setAttributes([2, 2.5, 'NULL', None, None, None])
        layer.dataProvider().addFeatures([f])
        fieldFormatter = QgsValueMapFieldFormatter()

        # Tests with different value types occurring in the value map
        config = {'map': {'two': '2', 'twoandhalf': '2.5', 'NULL text': 'NULL',
                          'nothing': self.VALUEMAP_NULL_TEXT}}
        self.assertEqual(fieldFormatter.representValue(layer, 0, config, None, 2), 'two')
        self.assertEqual(fieldFormatter.representValue(layer, 1, config, None, 2.5), 'twoandhalf')
        self.assertEqual(fieldFormatter.representValue(layer, 2, config, None, 'NULL'), 'NULL text')
        # Tests with null values of different types, if value map contains null
        self.assertEqual(fieldFormatter.representValue(layer, 3, config, None, None), 'nothing')
        self.assertEqual(fieldFormatter.representValue(layer, 4, config, None, None), 'nothing')
        self.assertEqual(fieldFormatter.representValue(layer, 5, config, None, None), 'nothing')
        # Tests with fallback display for different value types
        config = {}
        self.assertEqual(fieldFormatter.representValue(layer, 0, config, None, 2), '(2)')
        self.assertEqual(fieldFormatter.representValue(layer, 1, config, None, 2.5), '(2.50000)')
        self.assertEqual(fieldFormatter.representValue(layer, 2, config, None, 'NULL'), '(NULL)')
        # Tests with fallback display for null in different types of fields
        self.assertEqual(fieldFormatter.representValue(layer, 3, config, None, None), '(NULL)')
        self.assertEqual(fieldFormatter.representValue(layer, 4, config, None, None), '(NULL)')
        self.assertEqual(fieldFormatter.representValue(layer, 5, config, None, None), '(NULL)')

        QgsProject.instance().removeAllMapLayers()
    def testSettingFeature(self):
        """ test that feature is set when item moves """
        a = QgsTextAnnotation()
        a.setFrameSizeMm(QSizeF(300 / 3.7795275, 200 / 3.7795275))
        a.setFrameOffsetFromReferencePointMm(QPointF(40 / 3.7795275, 50 / 3.7795275))
        a.setHasFixedMapPosition(True)
        a.setMapPosition(QgsPointXY(12, 34))
        a.setMapPositionCrs(QgsCoordinateReferenceSystem(4326))

        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)

        canvas.setExtent(QgsRectangle(10, 30, 20, 35))

        i = QgsMapCanvasAnnotationItem(a, canvas)  # NOQA

        layer = QgsVectorLayer("Point?crs=EPSG:4326&field=station:string&field=suburb:string",
                               'test', "memory")
        canvas.setLayers([layer])
        f = QgsFeature(layer.fields())
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(14, 31)))
        f.setValid(True)
        f.setAttributes(['hurstbridge', 'somewhere'])
        self.assertTrue(layer.dataProvider().addFeatures([f]))
        a.setMapLayer(layer)
        self.assertFalse(a.associatedFeature().isValid())

        a.setMapPosition(QgsPointXY(14, 31))
        self.assertTrue(a.associatedFeature().isValid())
        self.assertEqual(a.associatedFeature().attributes()[0], 'hurstbridge')

        a.setMapPosition(QgsPointXY(17, 31))
        self.assertFalse(a.associatedFeature().isValid())
示例#21
0
    def __init__(self, name='', description='', options=[], default=None, isSource=False,
                 optional=False):
        Parameter.__init__(self, name, description, default, optional)
        isSource = parseBool(isSource)
        self.options = options
        if isSource:
            self.options = []
            layer = QgsVectorLayer(options[0], "layer", "ogr")
            if layer.isValid():
                try:
                    index = resolveFieldIndex(layer, options[1])
                    feats = features(layer)
                    for feature in feats:
                        self.options.append(unicode(feature.attributes()[index]))
                except ValueError:
                    pass
        elif isinstance(self.options, basestring):
            self.options = self.options.split(";")

        if default is not None:
            try:
                self.default = int(default)
            except:
                self.default = 0
            self.value = self.default
示例#22
0
    def testTriangleTINPolyhedralSurface(self):
        """ Test support for Triangles (mapped to Polygons) """
        testsets = (
            ("Triangle((0 0, 0 1, 1 1, 0 0))", QgsWkbTypes.Triangle, "Triangle ((0 0, 0 1, 1 1, 0 0))"),
            ("Triangle Z((0 0 1, 0 1 2, 1 1 3, 0 0 1))", QgsWkbTypes.TriangleZ, "TriangleZ ((0 0 1, 0 1 2, 1 1 3, 0 0 1))"),
            ("Triangle M((0 0 4, 0 1 5, 1 1 6, 0 0 4))", QgsWkbTypes.TriangleM, "TriangleM ((0 0 4, 0 1 5, 1 1 6, 0 0 4))"),
            ("Triangle ZM((0 0 0 1, 0 1 2 3, 1 1 4 5, 0 0 0 1))", QgsWkbTypes.TriangleZM, "TriangleZM ((0 0 0 1, 0 1 2 3, 1 1 4 5, 0 0 0 1))"),

            ("TIN (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))", QgsWkbTypes.MultiPolygon, "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))"),
            ("TIN Z(((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))", QgsWkbTypes.MultiPolygonZ, "MultiPolygonZ (((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))"),
            ("TIN M(((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))", QgsWkbTypes.MultiPolygonM, "MultiPolygonM (((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))"),
            ("TIN ZM(((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))", QgsWkbTypes.MultiPolygonZM, "MultiPolygonZM (((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))"),

            ("PolyhedralSurface (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))", QgsWkbTypes.MultiPolygon, "MultiPolygon (((0 0, 0 1, 1 1, 0 0)),((0 0, 1 0, 1 1, 0 0)))"),
            ("PolyhedralSurface Z(((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))", QgsWkbTypes.MultiPolygonZ, "MultiPolygonZ (((0 0 0, 0 1 1, 1 1 1, 0 0 0)),((0 0 0, 1 0 0, 1 1 1, 0 0 0)))"),
            ("PolyhedralSurface M(((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))", QgsWkbTypes.MultiPolygonM, "MultiPolygonM (((0 0 0, 0 1 2, 1 1 3, 0 0 0)),((0 0 0, 1 0 4, 1 1 3, 0 0 0)))"),
            ("PolyhedralSurface ZM(((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))", QgsWkbTypes.MultiPolygonZM, "MultiPolygonZM (((0 0 0 0, 0 1 1 2, 1 1 1 3, 0 0 0 0)),((0 0 0 0, 1 0 0 4, 1 1 1 3, 0 0 0 0)))")
        )
        for row in testsets:
            datasource = os.path.join(self.basetestpath, 'test.csv')
            with open(datasource, 'wt') as f:
                f.write('id,WKT\n')
                f.write('1,"%s"' % row[0])

            vl = QgsVectorLayer(datasource, 'test', 'ogr')
            self.assertTrue(vl.isValid())
            self.assertEqual(vl.wkbType(), row[1])

            f = QgsFeature()
            self.assertTrue(vl.getFeatures(QgsFeatureRequest(1)).nextFeature(f))
            self.assertTrue(f.geometry())
            self.assertEqual(f.geometry().constGet().asWkt(), row[2])
    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')
示例#24
0
    def getSource(self):
        # create temporary table for edit tests
        self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.edit_data')
        self.execSQLCommand(
            """CREATE TABLE qgis_test.edit_data (pk INTEGER PRIMARY KEY,cnt integer, name nvarchar(max), name2 nvarchar(max), num_char nvarchar(max), geom geometry)""")

        vl = QgsVectorLayer(
            self.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POINT table="qgis_test"."edit_data" (geom) sql=',
            'test', 'mssql')

        self.assertTrue(vl.isValid(), vl.dataProvider().error().message())

        f1 = QgsFeature()
        f1.setAttributes([5, -200, NULL, 'NuLl', '5'])
        f1.setGeometry(QgsGeometry.fromWkt('Point (-71.123 78.23)'))

        f2 = QgsFeature()
        f2.setAttributes([3, 300, 'Pear', 'PEaR', '3'])

        f3 = QgsFeature()
        f3.setAttributes([1, 100, 'Orange', 'oranGe', '1'])
        f3.setGeometry(QgsGeometry.fromWkt('Point (-70.332 66.33)'))

        f4 = QgsFeature()
        f4.setAttributes([2, 200, 'Apple', 'Apple', '2'])
        f4.setGeometry(QgsGeometry.fromWkt('Point (-68.2 70.8)'))

        f5 = QgsFeature()
        f5.setAttributes([4, 400, 'Honey', 'Honey', '4'])
        f5.setGeometry(QgsGeometry.fromWkt('Point (-65.32 78.3)'))

        self.assertTrue(vl.dataProvider().addFeatures([f1, f2, f3, f4, f5]))

        return vl
示例#25
0
    def testUniqueValues(self):
        ProcessingConfig.initialize()

        test_data = points()
        test_layer = QgsVectorLayer(test_data, 'test', 'ogr')

        # field by index
        v = vector.uniqueValues(test_layer, 2)
        self.assertEqual(len(v), len(set(v)))
        self.assertEqual(set(v), set([2, 1, 0]))

        # field by name
        v = vector.uniqueValues(test_layer, 'id2')
        self.assertEqual(len(v), len(set(v)))
        self.assertEqual(set(v), set([2, 1, 0]))

        # test with selected features
        previous_value = ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)
        ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, True)
        test_layer.selectByIds([2, 4, 6])
        v = vector.uniqueValues(test_layer, 'id')
        self.assertEqual(len(v), len(set(v)))
        self.assertEqual(set(v), set([5, 7, 3]))

        ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value)
示例#26
0
    def testBool(self):
        vl = QgsVectorLayer(
            'Point?crs=epsg:4326&field=f1:integer&field=f2:bool',
            'test', 'memory')
        self.assertTrue(vl.isValid())

        dp = vl.dataProvider()
        fields = dp.fields()
        self.assertEqual([f.name() for f in fields], ['f1', 'f2'])
        self.assertEqual([f.type() for f in fields], [QVariant.Int, QVariant.Bool])
        self.assertEqual([f.typeName() for f in fields], ['integer', 'boolean'])

        f = QgsFeature(dp.fields())
        f.setAttributes([1, True])
        f2 = QgsFeature(dp.fields())
        f2.setAttributes([2, False])
        f3 = QgsFeature(dp.fields())
        f3.setAttributes([3, NULL])
        self.assertTrue(dp.addFeatures([f, f2, f3]))

        self.assertEqual([f.attributes() for f in dp.getFeatures()], [[1, True], [2, False], [3, NULL]])

        # add boolean field
        self.assertTrue(dp.addAttributes([QgsField('boolfield2', QVariant.Bool, 'Boolean')]))

        fields = dp.fields()
        bool2_field = fields[fields.lookupField('boolfield2')]
        self.assertEqual(bool2_field.type(), QVariant.Bool)
        self.assertEqual(bool2_field.typeName(), 'Boolean')

        f = QgsFeature(fields)
        f.setAttributes([2, NULL, True])
        self.assertTrue(dp.addFeature(f))

        self.assertEqual([f.attributes() for f in dp.getFeatures()], [[1, True, NULL], [2, False, NULL], [3, NULL, NULL], [2, NULL, True]])
示例#27
0
def get_layer(layer_path):
    """Get layer from path.

    .. versionadded:: 3.2

    :param layer_path: User inputs.
    :type layer_path: CommandLineArguments

    :returns: Vector or Raster layer depending on input arguments.
    :rtype: QgsVectorLayer, QgsRasterLayer

    :raises: Exception
    """
    layer = None
    try:
        if os.path.splitext(layer_path)[1] == ".shp":
            layer_base = join_if_relative(layer_path)
            layer = QgsVectorLayer(layer_base, "cli_vector_hazard", "ogr")
        elif os.path.splitext(layer_path)[1] in [".asc", ".tif", ".tiff"]:
            layer_base = join_if_relative(layer_path)
            layer = QgsRasterLayer(layer_base, "cli_raster_hazard")
        else:
            print "Unknown filetype " + layer_path
        if layer is not None and layer.isValid():
            print "layer is VALID"
        else:
            print "layer is NOT VALID"
            print "Perhaps run-env-linux.sh /usr"
        return layer
    except Exception as exception:
        print exception.message
        print exception.__doc__
示例#28
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())
示例#29
0
    def testReplaceLayerWhileOpen(self):
        ''' Replace an existing geopackage layer whilst it's open in the project'''
        tmpfile = os.path.join(self.basetestpath, 'testGeopackageReplaceOpenLayer.gpkg')
        ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('layer1', geom_type=ogr.wkbPoint)
        lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTInteger))
        lyr.CreateField(ogr.FieldDefn('attr2', ogr.OFTInteger))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 0)'))
        lyr.CreateFeature(f)
        f = None

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

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

        features = [f for f in vl1.getFeatures(request)]
        self.assertEqual(len(features), 1)
示例#30
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")
class TestQgsPointDisplacementRenderer(unittest.TestCase):
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        self.layer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(self.layer)

        self.renderer = QgsPointDisplacementRenderer()
        sym1 = QgsMarkerSymbol.createSimple({
            'color': '#ff00ff',
            'size': '3',
            'outline_style': 'no'
        })
        renderer = QgsSingleSymbolRenderer(sym1)
        self.renderer.setEmbeddedRenderer(renderer)
        self.renderer.setCircleRadiusAddition(2)
        self.renderer.setCircleWidth(1)
        self.renderer.setCircleColor(QColor(0, 0, 0))
        self.renderer.setCenterSymbol(
            QgsMarkerSymbol.createSimple({
                'color': '#ffff00',
                'size': '3',
                'outline_style': 'no'
            }))
        self.layer.setRenderer(self.renderer)

        rendered_layers = [self.layer]
        self.mapsettings = QgsMapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-123, 18, -70, 52))
        self.mapsettings.setLayers(rendered_layers)

    def tearDown(self):
        QgsProject.instance().removeAllMapLayers()

    def _setProperties(self, r):
        """ set properties for a renderer for testing with _checkProperties"""
        r.setLabelAttributeName('name')
        f = QgsFontUtils.getStandardTestFont('Bold Oblique', 14)
        r.setLabelFont(f)
        r.setMinimumLabelScale(50000)
        r.setLabelColor(QColor(255, 0, 0))
        r.setTolerance(5)
        r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
        r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
        r.setCircleWidth(15)
        r.setCircleColor(QColor(0, 255, 0))
        r.setCircleRadiusAddition(2.5)
        r.setPlacement(QgsPointDisplacementRenderer.ConcentricRings)
        m = QgsMarkerSymbol()
        m.setColor(QColor(0, 255, 0))
        r.setCenterSymbol(m)
        sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
        renderer = QgsSingleSymbolRenderer(sym1)
        r.setEmbeddedRenderer(renderer)

    def _checkProperties(self, r):
        """ test properties of renderer against expected"""
        self.assertEqual(r.labelAttributeName(), 'name')
        f = QgsFontUtils.getStandardTestFont('Bold Oblique', 14)
        self.assertEqual(r.labelFont().styleName(), f.styleName())
        self.assertEqual(r.minimumLabelScale(), 50000)
        self.assertEqual(r.labelColor(), QColor(255, 0, 0))
        self.assertEqual(r.tolerance(), 5)
        self.assertEqual(r.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
        self.assertEqual(r.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
        self.assertEqual(r.circleWidth(), 15)
        self.assertEqual(r.circleColor(), QColor(0, 255, 0))
        self.assertEqual(r.circleRadiusAddition(), 2.5)
        self.assertEqual(r.placement(),
                         QgsPointDisplacementRenderer.ConcentricRings)
        self.assertEqual(r.centerSymbol().color(), QColor(0, 255, 0))
        self.assertEqual(r.embeddedRenderer().symbol().color().name(),
                         '#fdbf6f')

    def testGettersSetters(self):
        """ test getters and setters """
        r = QgsPointDisplacementRenderer()
        self._setProperties(r)
        self._checkProperties(r)

    def testClone(self):
        """ test cloning renderer """
        r = QgsPointDisplacementRenderer()
        self._setProperties(r)
        c = r.clone()
        self._checkProperties(c)

    def testSaveCreate(self):
        """ test saving and recreating from XML """
        r = QgsPointDisplacementRenderer()
        self._setProperties(r)
        doc = QDomDocument("testdoc")
        elem = r.save(doc, QgsReadWriteContext())
        c = QgsPointDisplacementRenderer.create(elem, QgsReadWriteContext())
        self._checkProperties(c)

    def testConvert(self):
        """ test renderer conversion """

        # same type, should clone
        r = QgsPointDisplacementRenderer()
        self._setProperties(r)
        c = QgsPointDisplacementRenderer.convertFromRenderer(r)
        self._checkProperties(c)

        # test conversion from cluster renderer
        r = QgsPointClusterRenderer()
        r.setTolerance(5)
        r.setToleranceUnit(QgsUnitTypes.RenderMapUnits)
        r.setToleranceMapUnitScale(QgsMapUnitScale(5, 15))
        m = QgsMarkerSymbol()
        m.setColor(QColor(0, 255, 0))
        r.setClusterSymbol(m)
        sym1 = QgsMarkerSymbol.createSimple({'color': '#fdbf6f'})
        renderer = QgsSingleSymbolRenderer(sym1)
        r.setEmbeddedRenderer(renderer)

        # want to keep as many settings as possible when converting between cluster and displacement renderer
        d = QgsPointDisplacementRenderer.convertFromRenderer(r)
        self.assertEqual(d.tolerance(), 5)
        self.assertEqual(d.toleranceUnit(), QgsUnitTypes.RenderMapUnits)
        self.assertEqual(d.toleranceMapUnitScale(), QgsMapUnitScale(5, 15))
        self.assertEqual(d.centerSymbol().color(), QColor(0, 255, 0))
        self.assertEqual(d.embeddedRenderer().symbol().color().name(),
                         '#fdbf6f')

    def testRenderNoCluster(self):
        self.layer.renderer().setTolerance(1)
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('displacement_renderer')
        renderchecker.setControlName('expected_displacement_no_cluster')
        self.assertTrue(renderchecker.runTest('displacement_no_cluster'))

    def testRenderWithin(self):
        self.layer.renderer().setTolerance(10)
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('displacement_renderer')
        renderchecker.setControlName('expected_displacement_cluster')
        self.assertTrue(renderchecker.runTest('expected_displacement_cluster'))

    def testRenderVariables(self):
        """ test rendering with expression variables in marker """
        self.layer.renderer().setTolerance(10)

        old_marker = self.layer.renderer().centerSymbol().clone()

        new_marker = QgsMarkerSymbol.createSimple({
            'color': '#ffff00',
            'size': '3',
            'outline_style': 'no'
        })
        new_marker.symbolLayer(0).setDataDefinedProperty(
            QgsSymbolLayer.PropertyFillColor,
            QgsProperty.fromExpression('@cluster_color'))
        new_marker.symbolLayer(0).setDataDefinedProperty(
            QgsSymbolLayer.PropertySize,
            QgsProperty.fromExpression('@cluster_size*2'))
        self.layer.renderer().setCenterSymbol(new_marker)
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('displacement_renderer')
        renderchecker.setControlName('expected_displacement_variables')
        result = renderchecker.runTest('expected_displacement_variables')
        self.layer.renderer().setCenterSymbol(old_marker)
        self.assertTrue(result)

    def testRenderGrid(self):
        self.layer.renderer().setTolerance(10)
        self.layer.renderer().setPlacement(QgsPointDisplacementRenderer.Grid)
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('displacement_renderer')
        renderchecker.setControlName('expected_displacement_grid')
        self.assertTrue(renderchecker.runTest('expected_displacement_grid'))

    def testRenderGridAdjust(self):
        self.layer.renderer().setTolerance(10)
        self.layer.renderer().setCircleRadiusAddition(5)
        self.layer.renderer().setPlacement(QgsPointDisplacementRenderer.Grid)
        self.layer.renderer().setCircleColor(QColor())
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlPathPrefix('displacement_renderer')
        renderchecker.setControlName('expected_displacement_adjust_grid')
        self.assertTrue(
            renderchecker.runTest('expected_displacement_adjust_grid'))
示例#32
0
    def test_signalConnection(self):
        # remove all layers
        QgsProject.instance().removeAllMapLayers()
        # set dependencies and add back layers
        self.pointsLayer = QgsVectorLayer(
            "dbname='%s' table=\"node\" (geom) sql=" % self.fn, "points",
            "spatialite")
        assert (self.pointsLayer.isValid())
        self.linesLayer = QgsVectorLayer(
            "dbname='%s' table=\"section\" (geom) sql=" % self.fn, "lines",
            "spatialite")
        assert (self.linesLayer.isValid())
        self.pointsLayer2 = QgsVectorLayer(
            "dbname='%s' table=\"node2\" (geom) sql=" % self.fn, "_points2",
            "spatialite")
        assert (self.pointsLayer2.isValid())
        self.pointsLayer.setDependencies(
            [QgsMapLayerDependency(self.linesLayer.id())])
        self.pointsLayer2.setDependencies(
            [QgsMapLayerDependency(self.pointsLayer.id())])
        # this should update connections between layers
        QgsProject.instance().addMapLayers([self.pointsLayer])
        QgsProject.instance().addMapLayers([self.linesLayer])
        QgsProject.instance().addMapLayers([self.pointsLayer2])

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(100, 100))
        ms.setExtent(QgsRectangle(0, 0, 1, 1))
        self.assertTrue(ms.hasValidSettings())

        u = QgsSnappingUtils()
        u.setMapSettings(ms)
        cfg = u.config()
        cfg.setEnabled(True)
        cfg.setMode(QgsSnappingConfig.AdvancedConfiguration)
        cfg.setIndividualLayerSettings(
            self.pointsLayer,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        cfg.setIndividualLayerSettings(
            self.pointsLayer2,
            QgsSnappingConfig.IndividualLayerSettings(True,
                                                      QgsSnappingConfig.Vertex,
                                                      20, QgsTolerance.Pixels))
        u.setConfig(cfg)
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(4)
        geom = QgsGeometry.fromWkt("LINESTRING(0.5 0.2,0.6 0)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the second snapped point is OK
        m = u.snapToMap(QPoint(75, 100 - 0))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(0.8, 0.0))

        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
示例#33
0
class TestQgsRangeWidget(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        QgsGui.editorWidgetRegistry().initEditors()

    def setUp(self):
        """
        create a layer with one feature
        """
        self.layer = QgsVectorLayer(
            "Point?crs=EPSG:21781&field=fldtxt:string&field=fldint:integer",
            "addfeat", "memory")
        pr = self.layer.dataProvider()  # NOQA
        f = QgsFeature()
        f.setAttributes(["Hello World", 123])
        f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(600000, 200000)))

    def __createRangeWidget(self, allownull=False):
        """
        create a range widget
        """
        reg = QgsGui.editorWidgetRegistry()
        configWdg = reg.createConfigWidget('Range', self.layer, 1, None)
        config = configWdg.config()
        config["Min"] = 0

        # if null shall be allowed
        if allownull:
            config["AllowNull"] = allownull

        rangewidget = reg.create('Range', self.layer, 1, config, None, None)
        return rangewidget

    def test_range_widget_numbers(self):
        """
        are the numbers being returned correctly
        """
        rangewidget = self.__createRangeWidget()

        rangewidget.setValue(1)
        assert rangewidget.value() == 1

        rangewidget.setValue(0)
        assert rangewidget.value() == 0

    def test_range_widget_no_null(self):
        """
        are None and NULL being returned as expected
        """
        rangewidget = self.__createRangeWidget()

        rangewidget.setValue(NULL)
        assert rangewidget.value() == 0

        rangewidget.setValue(None)
        assert rangewidget.value() == 0

    def test_range_widget_null_allowed(self):
        """
        are None and NULL being returned as expected
        """
        rangewidget = self.__createRangeWidget(True)

        rangewidget.setValue(NULL)
        self.assertEqual(rangewidget.value(), NULL)

        rangewidget.setValue(None)
        self.assertEqual(rangewidget.value(), NULL)

        rangewidget.setValue(0)
        self.assertEqual(rangewidget.value(), 0)
示例#34
0
    def testProjectStorage(self):
        # New project without fileName
        p0 = QgsProject()
        self.assertTrue(p0.auxiliaryStorage().isValid())

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
                f = QgsFeature()
                vl.getFeatures(req).nextFeature(f)
                self.assertTrue(f.isValid())
                self.assertEqual(f.attributes()[index1], 'myvalue1')
示例#35
0
    def testNumeric(self):
        """ Test calculation of aggregates on numeric fields"""

        layer = QgsVectorLayer("Point?field=fldint:integer&field=flddbl:double",
                               "layer", "memory")
        pr = layer.dataProvider()

        # must be same length:
        int_values = [4, 2, 3, 2, 5, None, 8]
        dbl_values = [5.5, 3.5, 7.5, 5, 9, None, 7]
        self.assertEqual(len(int_values), len(dbl_values))

        features = []
        for i in range(len(int_values)):
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([int_values[i], dbl_values[i]])
            features.append(f)
        assert pr.addFeatures(features)

        tests = [[QgsAggregateCalculator.Count, 'fldint', 6],
                 [QgsAggregateCalculator.Count, 'flddbl', 6],
                 [QgsAggregateCalculator.Sum, 'fldint', 24],
                 [QgsAggregateCalculator.Sum, 'flddbl', 37.5],
                 [QgsAggregateCalculator.Mean, 'fldint', 4],
                 [QgsAggregateCalculator.Mean, 'flddbl', 6.25],
                 [QgsAggregateCalculator.StDev, 'fldint', 2.0816],
                 [QgsAggregateCalculator.StDev, 'flddbl', 1.7969],
                 [QgsAggregateCalculator.StDevSample, 'fldint', 2.2803],
                 [QgsAggregateCalculator.StDevSample, 'flddbl', 1.9685],
                 [QgsAggregateCalculator.Min, 'fldint', 2],
                 [QgsAggregateCalculator.Min, 'flddbl', 3.5],
                 [QgsAggregateCalculator.Max, 'fldint', 8],
                 [QgsAggregateCalculator.Max, 'flddbl', 9],
                 [QgsAggregateCalculator.Range, 'fldint', 6],
                 [QgsAggregateCalculator.Range, 'flddbl', 5.5],
                 [QgsAggregateCalculator.Median, 'fldint', 3.5],
                 [QgsAggregateCalculator.Median, 'flddbl', 6.25],
                 [QgsAggregateCalculator.CountDistinct, 'fldint', 5],
                 [QgsAggregateCalculator.CountDistinct, 'flddbl', 6],
                 [QgsAggregateCalculator.CountMissing, 'fldint', 1],
                 [QgsAggregateCalculator.CountMissing, 'flddbl', 1],
                 [QgsAggregateCalculator.FirstQuartile, 'fldint', 2],
                 [QgsAggregateCalculator.FirstQuartile, 'flddbl', 5.0],
                 [QgsAggregateCalculator.ThirdQuartile, 'fldint', 5.0],
                 [QgsAggregateCalculator.ThirdQuartile, 'flddbl', 7.5],
                 [QgsAggregateCalculator.InterQuartileRange, 'fldint', 3.0],
                 [QgsAggregateCalculator.InterQuartileRange, 'flddbl', 2.5],
                 [QgsAggregateCalculator.ArrayAggregate, 'fldint', int_values],
                 [QgsAggregateCalculator.ArrayAggregate, 'flddbl', dbl_values],
                 ]

        agg = QgsAggregateCalculator(layer)
        for t in tests:
            val, ok = agg.calculate(t[0], t[1])
            self.assertTrue(ok)
            if isinstance(t[2], (int, list)):
                self.assertEqual(val, t[2])
            else:
                self.assertAlmostEqual(val, t[2], 3)

        # bad tests - the following stats should not be calculatable for numeric fields
        for t in [QgsAggregateCalculator.StringMinimumLength,
                  QgsAggregateCalculator.StringMaximumLength]:
            val, ok = agg.calculate(t, 'fldint')
            self.assertFalse(ok)
            val, ok = agg.calculate(t, 'flddbl')
            self.assertFalse(ok)
示例#36
0
    def testExpression(self):
        """ test aggregate calculation using an expression """

        # numeric
        layer = QgsVectorLayer("Point?field=fldint:integer", "layer", "memory")
        pr = layer.dataProvider()

        int_values = [4, 2, 3, 2, 5, None, 8]

        features = []
        for v in int_values:
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([v])
            features.append(f)
        assert pr.addFeatures(features)

        # int
        agg = QgsAggregateCalculator(layer)
        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 2')
        self.assertTrue(ok)
        self.assertEqual(val, 48)

        # double
        val, ok = agg.calculate(QgsAggregateCalculator.Sum, 'fldint * 1.5')
        self.assertTrue(ok)
        self.assertEqual(val, 36)

        # datetime
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "to_date('2012-05-04') + to_interval( fldint || ' day' )")
        self.assertTrue(ok)
        self.assertEqual(val, QDateTime(QDate(2012, 5, 12), QTime(0, 0, 0)))

        # date
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "to_date(to_date('2012-05-04') + to_interval( fldint || ' day' ))")
        self.assertTrue(ok)
        self.assertEqual(val, QDateTime(QDate(2012, 5, 6), QTime(0, 0, 0)))

        # string
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "fldint || ' oranges'")
        self.assertTrue(ok)
        self.assertEqual(val, '8 oranges')

        # geometry
        val, ok = agg.calculate(QgsAggregateCalculator.GeometryCollect, "make_point( coalesce(fldint,0), 2 )")
        self.assertTrue(ok)
        self.assertTrue(val.exportToWkt(), 'MultiPoint((4 2, 2 2, 3 2, 2 2,5 2, 0 2,8 2))')

        # try a bad expression
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "not_a_field || ' oranges'")
        self.assertFalse(ok)
        val, ok = agg.calculate(QgsAggregateCalculator.Max, "5+")
        self.assertFalse(ok)

        # test expression context

        # check default context first
        # should have layer variables:
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "@layer_name")
        self.assertTrue(ok)
        self.assertEqual(val, 'layer')
        # but not custom variables:
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var")
        self.assertTrue(ok)
        self.assertEqual(val, NULL)

        # test with manual expression context
        scope = QgsExpressionContextScope()
        scope.setVariable('my_var', 5)
        context = QgsExpressionContext()
        context.appendScope(scope)
        val, ok = agg.calculate(QgsAggregateCalculator.Min, "@my_var", context)
        self.assertTrue(ok)
        self.assertEqual(val, 5)
示例#37
0
    def testDateTime(self):
        """ Test calculation of aggregates on date/datetime fields"""

        layer = QgsVectorLayer("Point?field=flddate:date&field=flddatetime:datetime", "layer", "memory")
        pr = layer.dataProvider()

        # must be same length:
        datetime_values = [QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                           QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
                           QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                           QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
                           QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
                           QDateTime(),
                           QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
                           QDateTime(),
                           QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))]
        date_values = [QDate(2015, 3, 4),
                       QDate(2015, 3, 4),
                       QDate(2019, 12, 28),
                       QDate(),
                       QDate(1998, 1, 2),
                       QDate(),
                       QDate(2011, 1, 5),
                       QDate(2011, 1, 5),
                       QDate(2011, 1, 5)]
        self.assertEqual(len(datetime_values), len(date_values))

        features = []
        for i in range(len(datetime_values)):
            f = QgsFeature()
            f.setFields(layer.fields())
            f.setAttributes([date_values[i], datetime_values[i]])
            features.append(f)
        assert pr.addFeatures(features)

        tests = [[QgsAggregateCalculator.Count, 'flddatetime', 9],
                 [QgsAggregateCalculator.Count, 'flddate', 9],
                 [QgsAggregateCalculator.CountDistinct, 'flddatetime', 6],
                 [QgsAggregateCalculator.CountDistinct, 'flddate', 5],
                 [QgsAggregateCalculator.CountMissing, 'flddatetime', 2],
                 [QgsAggregateCalculator.CountMissing, 'flddate', 2],
                 [QgsAggregateCalculator.Min, 'flddatetime', QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54))],
                 [QgsAggregateCalculator.Min, 'flddate', QDateTime(QDate(1998, 1, 2), QTime(0, 0, 0))],
                 [QgsAggregateCalculator.Max, 'flddatetime', QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1))],
                 [QgsAggregateCalculator.Max, 'flddate', QDateTime(QDate(2019, 12, 28), QTime(0, 0, 0))],

                 [QgsAggregateCalculator.Range, 'flddatetime', QgsInterval(693871147)],
                 [QgsAggregateCalculator.Range, 'flddate', QgsInterval(693792000)],

                 [QgsAggregateCalculator.ArrayAggregate, 'flddatetime', [None if v.isNull() else v for v in datetime_values]],
                 [QgsAggregateCalculator.ArrayAggregate, 'flddate', [None if v.isNull() else v for v in date_values]],
                 ]

        agg = QgsAggregateCalculator(layer)
        for t in tests:
            val, ok = agg.calculate(t[0], t[1])
            self.assertTrue(ok)
            self.assertEqual(val, t[2])

        # bad tests - the following stats should not be calculatable for string fields
        for t in [QgsAggregateCalculator.Sum,
                  QgsAggregateCalculator.Mean,
                  QgsAggregateCalculator.Median,
                  QgsAggregateCalculator.StDev,
                  QgsAggregateCalculator.StDevSample,
                  QgsAggregateCalculator.Minority,
                  QgsAggregateCalculator.Majority,
                  QgsAggregateCalculator.FirstQuartile,
                  QgsAggregateCalculator.ThirdQuartile,
                  QgsAggregateCalculator.InterQuartileRange,
                  QgsAggregateCalculator.StringMinimumLength,
                  QgsAggregateCalculator.StringMaximumLength,
                  ]:
            val, ok = agg.calculate(t, 'flddatetime')
            self.assertFalse(ok)
示例#38
0
def createReferencingLayer():
    layer = QgsVectorLayer("Point?field=fldtxt:string&field=foreignkey:integer",
                           "referencinglayer", "memory")
    return layer
示例#39
0
    def testFidSupport(self):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        got = [(f.attribute('fid'), f.attribute('intfield'))
               for f in vl.dataProvider().getFeatures(
                   QgsFeatureRequest().setFilterExpression("fid = 12"))]
        self.assertEqual(got, [(12, 123)])
示例#40
0
def createReferencedLayer():
    layer = QgsVectorLayer(
        "Point?field=x:string&field=y:integer&field=z:integer",
        "referencedlayer", "memory")
    return layer
    def testCreateExpression(self):
        """ Test creating an expression using the widget"""
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime",
                               "test", "memory")

        parent = QWidget()
        w = QgsDefaultSearchWidgetWrapper(layer, 0)
        w.initWidget(parent)

        line_edit = w.lineEdit()
        line_edit.setText('test')
        case_sensitive = w.caseSensitiveCheckBox()

        case_sensitive.setChecked(False)
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), 'lower("fldtxt")=lower(\'test\')')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), 'lower("fldtxt")<>lower(\'test\')')
        case_sensitive.setChecked(True)
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'test\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'test\'')
        case_sensitive.setChecked(False)
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.Contains), '"fldtxt" ILIKE \'%test%\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.DoesNotContain), 'NOT ("fldtxt" ILIKE \'%test%\')')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.StartsWith), '"fldtxt" ILIKE \'test%\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EndsWith), '"fldtxt" ILIKE \'%test\'')
        case_sensitive.setChecked(True)
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.Contains), '"fldtxt" LIKE \'%test%\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.DoesNotContain), 'NOT ("fldtxt" LIKE \'%test%\')')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.StartsWith), '"fldtxt" LIKE \'test%\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EndsWith), '"fldtxt" LIKE \'%test\'')
        case_sensitive.setChecked(False)

        # numeric field
        parent = QWidget()
        w = QgsDefaultSearchWidgetWrapper(layer, 1)
        w.initWidget(parent)

        # may need updating if widget layout changes:
        line_edit = w.lineEdit()
        line_edit.setText('5.5')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=5.5')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>5.5')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.GreaterThan), '"fldint">5.5')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.LessThan), '"fldint"<5.5')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo), '"fldint">=5.5')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo), '"fldint"<=5.5')

        # date/time/datetime
        parent = QWidget()
        w = QgsDefaultSearchWidgetWrapper(layer, 2)
        w.initWidget(parent)

        # may need updating if widget layout changes:
        line_edit = w.lineEdit()
        line_edit.setText('2015-06-03')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"flddate"=\'2015-06-03\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"flddate"<>\'2015-06-03\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.GreaterThan), '"flddate">\'2015-06-03\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.LessThan), '"flddate"<\'2015-06-03\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.GreaterThanOrEqualTo), '"flddate">=\'2015-06-03\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.LessThanOrEqualTo), '"flddate"<=\'2015-06-03\'')
    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())
    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)
示例#44
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 testDeleteShapes(self):
        ''' Test fix for #11007 '''

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

        vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        feature_count = vl.featureCount()
        # Start an iterator that will open a new connection
        iterator = vl.getFeatures()
        next(iterator)

        # Delete a feature
        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.deleteFeature(1))
        self.assertTrue(vl.commitChanges())

        # Test the content of the shapefile while it is still opened
        ds = osgeo.ogr.Open(datasource)
        # Test repacking has been done
        self.assertTrue(ds.GetLayer(0).GetFeatureCount() == feature_count - 1)
        ds = None

        # Delete another feature while in update mode
        self.assertTrue(2 == 2)
        vl.dataProvider().enterUpdateMode()
        vl.dataProvider().deleteFeatures([0])

        # Test that repacking has not been done (since in update mode)
        ds = osgeo.ogr.Open(datasource)
        self.assertTrue(ds.GetLayer(0).GetFeatureCount() == feature_count - 1)
        ds = None

        # Test that repacking was performed when leaving updateMode
        vl.dataProvider().leaveUpdateMode()
        ds = osgeo.ogr.Open(datasource)
        self.assertTrue(ds.GetLayer(0).GetFeatureCount() == feature_count - 2)
        ds = None

        vl = None
    def testCreateExpression(self):
        """ Test creating an expression using the widget"""
        layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "test", "memory")
        # setup value relation
        parent_layer = QgsVectorLayer("Point?field=stringkey:string&field=intkey:integer&field=display:string", "parent", "memory")
        f1 = QgsFeature(parent_layer.fields(), 1)
        f1.setAttributes(['a', 1, 'value a'])
        f2 = QgsFeature(parent_layer.fields(), 2)
        f2.setAttributes(['b', 2, 'value b'])
        f3 = QgsFeature(parent_layer.fields(), 3)
        f3.setAttributes(['c', 3, 'value c'])
        parent_layer.dataProvider().addFeatures([f1, f2, f3])
        QgsProject.instance().addMapLayers([layer, parent_layer])

        config = {"Layer": parent_layer.id(),
                  "Key": 'stringkey',
                  "Value": 'display'}

        w = QgsValueRelationSearchWidgetWrapper(layer, 0)
        w.setConfig(config)
        c = w.widget()

        # first, set it to the "select value" item
        c.setCurrentIndex(0)

        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '')

        c.setCurrentIndex(1)
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'a\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'a\'')
        c.setCurrentIndex(2)
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'b\'')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'b\'')

        # try with numeric field
        w = QgsValueRelationSearchWidgetWrapper(layer, 1)
        config['Key'] = 'intkey'
        w.setConfig(config)
        c = w.widget()
        c.setCurrentIndex(c.findText('value c'))
        self.assertEqual(c.currentIndex(), 3)
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=3')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>3')

        # try with allow null set
        w = QgsValueRelationSearchWidgetWrapper(layer, 1)
        config['AllowNull'] = True
        w.setConfig(config)
        c = w.widget()
        c.setCurrentIndex(c.findText('value c'))
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=3')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>3')

        # try with line edit
        w = QgsValueRelationSearchWidgetWrapper(layer, 1)
        config['UseCompleter'] = True
        w.setConfig(config)
        l = w.widget()
        l.setText('value b')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=2')
        self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>2')
    def testreloadData(self):
        ''' Test reloadData() '''

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

        vl1 = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        vl2 = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        self.assertTrue(vl1.startEditing())
        self.assertTrue(vl1.deleteAttributes([1]))
        self.assertTrue(vl1.commitChanges())
        self.assertEqual(len(vl1.fields()) + 1, len(vl2.fields()))
        # Reload
        vl2.reload()
        # And now check that fields are up-to-date
        self.assertEqual(len(vl1.fields()), len(vl2.fields()))
    def testSubSetStringEditable_bug17795_but_with_modified_behavior(self):
        """Test that a layer is still editable after setting a subset"""

        testPath = TEST_DATA_DIR + '/' + 'lines.shp'
        isEditable = QgsVectorDataProvider.ChangeAttributeValues

        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('"Name" = \'Arterial\'')
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.dataProvider().capabilities() & isEditable)

        vl.setSubsetString('')
        self.assertTrue(vl.dataProvider().capabilities() & isEditable)
    def testUpdateMode(self):
        """ Test that on-the-fly re-opening in update/read-only mode works """

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # Test that update mode will be implictly enabled if doing an action
        # that requires update mode
        (ret, _) = vl.dataProvider().addFeatures([QgsFeature()])
        self.assertTrue(ret)
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write")
    def testRenameAttributes(self):
        ''' Test renameAttributes() '''

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

        vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        provider = vl.dataProvider()

        # bad rename
        self.assertFalse(provider.renameAttributes({-1: 'not_a_field'}))
        self.assertFalse(provider.renameAttributes({100: 'not_a_field'}))
        # already exists
        self.assertFalse(provider.renameAttributes({2: 'cnt'}))

        # rename one field
        self.assertTrue(provider.renameAttributes({2: 'newname'}))
        self.assertEqual(provider.fields().at(2).name(), 'newname')
        vl.updateFields()
        fet = next(vl.getFeatures())
        self.assertEqual(fet.fields()[2].name(), 'newname')

        # rename two fields
        self.assertTrue(provider.renameAttributes({2: 'newname2', 3: 'another'}))
        self.assertEqual(provider.fields().at(2).name(), 'newname2')
        self.assertEqual(provider.fields().at(3).name(), 'another')
        vl.updateFields()
        fet = next(vl.getFeatures())
        self.assertEqual(fet.fields()[2].name(), 'newname2')
        self.assertEqual(fet.fields()[3].name(), 'another')

        # close file and reopen, then recheck to confirm that changes were saved to file
        del vl
        vl = None
        vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')
        provider = vl.dataProvider()
        self.assertEqual(provider.fields().at(2).name(), 'newname2')
        self.assertEqual(provider.fields().at(3).name(), 'another')
        fet = next(vl.getFeatures())
        self.assertEqual(fet.fields()[2].name(), 'newname2')
        self.assertEqual(fet.fields()[3].name(), 'another')
    def test_SplitFeature(self):
        """Test sqlite feature can be split"""
        tmpfile = os.path.join(self.basetestpath, 'testGeopackageSplitFeatures.sqlite')
        ds = ogr.GetDriverByName('SQlite').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbPolygon)
        lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON ((0 0,0 1,1 1,1 0,0 0))'))
        lyr.CreateFeature(f)
        f = None
        ds = None

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

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

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

        layer = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr')
        self.assertEqual(layer.featureCount(), 2)
        self.assertEqual([f for f in layer.getFeatures()][0].geometry().asWkt(), 'Polygon ((0.5 0, 0.5 1, 1 1, 1 0, 0.5 0))')
        self.assertEqual([f for f in layer.getFeatures()][1].geometry().asWkt(), 'Polygon ((0.5 1, 0.5 0, 0 0, 0 1, 0.5 1))')
    def testUpdateModeFailedReopening(self):
        ''' Test that methods on provider don't crash after a failed reopening '''

        # Windows doesn't like removing files opened by OGR, whatever
        # their open mode, so that makes it hard to test
        if sys.platform == 'win32':
            return

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

        vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr')

        os.unlink(datasource)

        self.assertFalse(vl.dataProvider().enterUpdateMode())
        self.assertFalse(vl.dataProvider().enterUpdateMode())
        self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "invalid")

        self.assertFalse(vl.dataProvider().isValid())
        self.assertEqual(len([f for f in vl.dataProvider().getFeatures()]), 0)
        self.assertEqual(len(vl.dataProvider().subLayers()), 0)
        self.assertFalse(vl.dataProvider().setSubsetString('TRUE'))
        (ret, _) = vl.dataProvider().addFeatures([QgsFeature()])
        self.assertFalse(ret)
        self.assertFalse(vl.dataProvider().deleteFeatures([1]))
        self.assertFalse(vl.dataProvider().addAttributes([QgsField()]))
        self.assertFalse(vl.dataProvider().deleteAttributes([1]))
        self.assertFalse(vl.dataProvider().changeGeometryValues({0: QgsGeometry.fromWkt('Point (3 50)')}))
        self.assertFalse(vl.dataProvider().changeAttributeValues({0: {0: 0}}))
        self.assertFalse(vl.dataProvider().createSpatialIndex())
        self.assertFalse(vl.dataProvider().createAttributeIndex(0))
示例#53
0
class TestQgsSymbolExpressionVariables(unittest.TestCase):
    def setUp(self):
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.layer = QgsVectorLayer(myShpFile, 'Polys', 'ogr')
        QgsProject.instance().addMapLayer(self.layer)

        self.iface = get_iface()
        rendered_layers = [self.layer]
        self.mapsettings = self.iface.mapCanvas().mapSettings()
        self.mapsettings.setOutputSize(QSize(400, 400))
        self.mapsettings.setOutputDpi(96)
        self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52))
        self.mapsettings.setLayers(rendered_layers)

    def tearDown(self):
        QgsProject.instance().removeAllMapLayers()

    def testPartNum(self):
        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })

        renderer = QgsSingleSymbolRenderer(sym1)
        renderer.symbols(
            QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty(
                QgsSymbolLayer.PropertyFillColor,
                QgsProperty.fromExpression(
                    'color_rgb( (@geometry_part_num - 1) * 200, 0, 0 )'))
        self.layer.setRenderer(renderer)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_geometry_part_num')
        result = renderchecker.runTest('part_geometry_part_num')

        self.assertTrue(result)

    def testPartCount(self):
        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#fdbf6f',
            'outline_color': 'black'
        })

        renderer = QgsSingleSymbolRenderer(sym1)
        renderer.symbols(
            QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty(
                QgsSymbolLayer.PropertyFillColor,
                QgsProperty.fromExpression(
                    'color_rgb( (@geometry_part_count - 1) * 200, 0, 0 )'))
        self.layer.setRenderer(renderer)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_geometry_part_count')
        result = renderchecker.runTest('part_geometry_part_count')

        self.assertTrue(result)

    def testSymbolColor(self):
        # Create rulebased style
        sym1 = QgsFillSymbol.createSimple({
            'color': '#ff0000',
            'outline_color': 'black'
        })

        renderer = QgsSingleSymbolRenderer(sym1)
        renderer.symbols(
            QgsRenderContext())[0].symbolLayers()[0].setDataDefinedProperty(
                QgsSymbolLayer.PropertyFillColor,
                QgsProperty.fromExpression(
                    'set_color_part( @symbol_color, \'value\', "Value" * 4)'))
        self.layer.setRenderer(renderer)

        # Setup rendering check
        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(self.mapsettings)
        renderchecker.setControlName('expected_symbol_color_variable')
        result = renderchecker.runTest('symbol_color_variable', 50)

        self.assertTrue(result)
    def testRepack(self):
        vl = QgsVectorLayer('{}|layerid=0'.format(self.repackfile), 'test', 'ogr')

        ids = [f.id() for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression('pk=1'))]
        vl.selectByIds(ids)
        self.assertEqual(vl.selectedFeatureIds(), ids)
        self.assertEqual(vl.featureCount(), 5)
        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.deleteFeature(3))
        self.assertTrue(vl.commitChanges())
        self.assertTrue(vl.selectedFeatureCount() == 0 or vl.selectedFeatures()[0]['pk'] == 1)
def create_shapefile_full_layer_data_provider(path, name, srid, attributes, types, values, coords):
    """
    Creates a shapefile using the Shapefile Data Provider

    Parameters
    ----------
    path : `str`
        folder where the shapefile is to be saved
    name : `str`
        name of the shapefile
    srid : `str`
        CRS of the newly created shapefile
    attributes: array_like
        list of attribute (field) names
    types : array_like
        list of types (field) types, in sync with the `attributes` parameter
    values : array_like
        coordinates and attribute data, one array for each feature (F, C + A),
        F for features, C for coordinates and A for attribute data
    coords : array_like
        indices of the coordinate values within the `values` array

    Returns
    -------
    vl : `QgsVectorLayer`
        the newly-created layer

    """
    # create new layer with given attributes
    filename = path + "/" + name + ".shp"

    # create an instance of vector file writer, which will create the vector file.
    writer = None
    options = QgsVectorFileWriter.SaveVectorOptions()
    options.driverName = "ESRI Shapefile"
    options.fileEncoding = 'utf-8'
    if len(coords) == 2:
        type = 'point'
        writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.Point, srid,
                                            QgsCoordinateTransformContext(), options)
    elif len(coords) == 4:
        type = 'line'
        writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.LineString, srid,
                                            QgsCoordinateTransformContext(), options)
    if writer.hasError() != QgsVectorFileWriter.NoError:
        print("Error when creating shapefile: ", writer.hasError())
        return None
    del writer
    # open the newly created file
    vl = QgsVectorLayer(filename, name, "ogr")

    pr = vl.dataProvider()

    # create the required fields
    for i, attr in enumerate(attributes):
        pr.addAttributes([QgsField(attr, types[i])])
    vl.commitChanges()
    # add features by iterating the values
    feat = QgsFeature()
    for i, val in enumerate(values):
        # add geometry
        try:
            if type == 'point':
                geometry = QgsGeometry.fromPoint([QgsPoint(float(val[coords[0]]),
                                                           float(val[coords[1]]))])
            elif type == 'line':
                geometry = QgsGeometry.fromPolyline([QgsPoint(float(val[coords[0]]),
                                                              float(val[coords[1]])),
                                                     QgsPoint(float(val[coords[2]]),
                                                              float(val[coords[3]]))])
            feat.setGeometry(geometry)
        except:
            pass
        # add attributes
        attrs = []
        for j, attr in enumerate(attributes):
            attrs.append(val[j])
        feat.setAttributes(attrs)
        pr.addFeature(feat)
    vl.updateExtents()

    vl = QgsVectorLayer(filename, name, "ogr")

    if not vl.isValid():
        raise IOError("Layer could not be created")
        return None
    return vl
    def testSubsetStringFids(self):
        """
          - tests that feature ids are stable even if a subset string is set
          - tests that the subset string is correctly set on the ogr layer event when reloading the data source (issue #17122)
        """

        tmpfile = os.path.join(self.basetestpath, 'subsetStringFids.sqlite')
        ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid'])
        lyr.CreateField(ogr.FieldDefn('type', ogr.OFTInteger))
        lyr.CreateField(ogr.FieldDefn('value', ogr.OFTInteger))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(0)
        f.SetField(0, 1)
        f.SetField(1, 11)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(1)
        f.SetField(0, 1)
        f.SetField(1, 12)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(2)
        f.SetField(0, 1)
        f.SetField(1, 13)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(3)
        f.SetField(0, 2)
        f.SetField(1, 14)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(4)
        f.SetField(0, 2)
        f.SetField(1, 15)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(5)
        f.SetField(0, 2)
        f.SetField(1, 16)
        lyr.CreateFeature(f)
        f = None
        ds = None

        vl = QgsVectorLayer(tmpfile + "|subset=type=2", 'test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.fields().at(vl.fields().count() - 1).name() == "orig_ogc_fid")

        req = QgsFeatureRequest()
        req.setFilterExpression("value=16")
        it = vl.getFeatures(req)
        f = QgsFeature()
        self.assertTrue(it.nextFeature(f))
        self.assertTrue(f.id() == 5)

        # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed
        req = QgsFeatureRequest()
        req.setSubsetOfAttributes([])
        it = vl.getFeatures(req)
        ids = []
        while it.nextFeature(f):
            ids.append(f.id())
        self.assertTrue(len(ids) == 3)
        self.assertTrue(3 in ids)
        self.assertTrue(4 in ids)
        self.assertTrue(5 in ids)

        # Check that subset string is correctly set on reload
        vl.reload()
        self.assertTrue(vl.fields().at(vl.fields().count() - 1).name() == "orig_ogc_fid")
示例#57
0
class TestQgsBlendModes(TestCase):
    def __init__(self, methodName):
        """Run once on class initialisation."""
        unittest.TestCase.__init__(self, methodName)

        # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL
        self.mMapRegistry = QgsMapLayerRegistry.instance()

        # create point layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.mMapRegistry.addMapLayer(self.mPointLayer)

        self.mSimplifyMethod = QgsVectorSimplifyMethod()
        self.mSimplifyMethod.setSimplifyHints(
            QgsVectorSimplifyMethod.NoSimplification)

        # create polygon layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
        self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod)
        self.mMapRegistry.addMapLayer(self.mPolygonLayer)

        # create line layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr')
        self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod)
        self.mMapRegistry.addMapLayer(self.mLineLayer)

        # create two raster layers
        myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif')
        self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1")
        self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2")
        myMultiBandRenderer1 = QgsMultiBandColorRenderer(
            self.mRasterLayer1.dataProvider(), 2, 3, 4)
        self.mRasterLayer1.setRenderer(myMultiBandRenderer1)
        self.mMapRegistry.addMapLayer(self.mRasterLayer1)
        myMultiBandRenderer2 = QgsMultiBandColorRenderer(
            self.mRasterLayer2.dataProvider(), 2, 3, 4)
        self.mRasterLayer2.setRenderer(myMultiBandRenderer2)
        self.mMapRegistry.addMapLayer(self.mRasterLayer2)

        # to match blend modes test comparisons background
        self.mCanvas = CANVAS
        self.mCanvas.setCanvasColor(QColor(152, 219, 249))
        self.mMap = self.mCanvas.map()
        self.mMap.resize(QSize(400, 400))
        self.mapSettings = self.mCanvas.mapSettings()
        self.mapSettings.setOutputSize(QSize(400, 400))

    def testVectorBlending(self):
        """Test that blend modes work for vector layers."""

        #Add vector layers to map
        myLayers = []
        myLayers.append(self.mLineLayer.id())
        myLayers.append(self.mPolygonLayer.id())
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.mPointLayer.extent())

        #Set blending modes for both layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_blendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_blendmodes", 20)
        myMessage = ('vector blending failed')
        assert myResult, myMessage

        #Reset layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver)

    def testVectorFeatureBlending(self):
        """Test that feature blend modes work for vector layers."""

        #Add vector layers to map
        myLayers = []
        myLayers.append(self.mLineLayer.id())
        myLayers.append(self.mPolygonLayer.id())
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.mPointLayer.extent())

        #Set feature blending for line layer
        self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_featureblendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_featureblendmodes", 20)
        myMessage = ('vector feature blending failed')
        assert myResult, myMessage

        #Reset layers
        self.mLineLayer.setFeatureBlendMode(
            QPainter.CompositionMode_SourceOver)

    def testVectorLayerTransparency(self):
        """Test that layer transparency works for vector layers."""

        #Add vector layers to map
        myLayers = []
        myLayers.append(self.mLineLayer.id())
        myLayers.append(self.mPolygonLayer.id())
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.mPointLayer.extent())

        #Set feature blending for line layer
        self.mLineLayer.setLayerTransparency(50)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_layertransparency")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_layertransparency", 20)
        myMessage = ('vector layer transparency failed')
        assert myResult, myMessage

    def testRasterBlending(self):
        """Test that blend modes work for raster layers."""
        #Add raster layers to map
        myLayers = []
        myLayers.append(self.mRasterLayer1.id())
        myLayers.append(self.mRasterLayer2.id())
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.mRasterLayer1.extent())

        #Set blending mode for top layer
        self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus)
        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_raster_blendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)
        checker.setColorTolerance(1)

        myResult = checker.runTest("raster_blendmodes", 20)
        myMessage = ('raster blending failed')
        assert myResult, myMessage
示例#58
0
def create_layer(name):
    layer = QgsVectorLayer("Point?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer",
                           name, "memory")
    return layer
示例#59
0
def load(fileName, name=None, crs=None, style=None):
    """Loads a layer/table into the current project, given its file.
    """

    if fileName is None:
        return
    prjSetting = None
    settings = QgsSettings()
    if crs is not None:
        prjSetting = settings.value('/Projections/defaultBehavior')
        settings.setValue('/Projections/defaultBehavior', '')
    if name is None:
        name = os.path.split(fileName)[1]
    qgslayer = QgsVectorLayer(fileName, name, 'ogr')
    if qgslayer.isValid():
        if crs is not None and qgslayer.crs() is None:
            qgslayer.setCrs(crs, False)
        if style is None:
            if qgslayer.geometryType() == QgsWkbTypes.PointGeometry:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_POINT_STYLE)
            elif qgslayer.geometryType() == QgsWkbTypes.LineGeometry:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_LINE_STYLE)
            else:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_POLYGON_STYLE)
        qgslayer.loadNamedStyle(style)
        QgsProject.instance().addMapLayers([qgslayer])
    else:
        qgslayer = QgsRasterLayer(fileName, name)
        if qgslayer.isValid():
            if crs is not None and qgslayer.crs() is None:
                qgslayer.setCrs(crs, False)
            if style is None:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.RASTER_STYLE)
            qgslayer.loadNamedStyle(style)
            QgsProject.instance().addMapLayers([qgslayer])
        else:
            if prjSetting:
                settings.setValue('/Projections/defaultBehavior', prjSetting)
            raise RuntimeError(
                'Could not load layer: ' + str(fileName) +
                '\nCheck the processing framework log to look for errors')
    if prjSetting:
        settings.setValue('/Projections/defaultBehavior', prjSetting)

    return qgslayer
示例#60
0
    def testEdit(self):
        """Test `with edit(layer):` code"""

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

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

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

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

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

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

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

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

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

        # Check that we get a QgsEditError exception when the commit fails
        with self.assertRaises(QgsEditError):
            with edit(ml) as l:
                l.rollBack()