Example #1
2
    def testRenderLineLayerDataDefined(self):
        """ test that rendering a line symbol with data defined enabled layer works"""

        lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp')
        lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr')
        QgsProject.instance().addMapLayer(lines_layer)

        layer = QgsSimpleLineSymbolLayer()
        layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Name='Highway'"))
        layer.setColor(QColor(100, 150, 150))
        layer.setWidth(5)

        symbol = QgsLineSymbol()
        symbol.changeSymbolLayer(0, layer)
        lines_layer.setRenderer(QgsSingleSymbolRenderer(symbol))

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(400, 400))
        ms.setOutputDpi(96)
        ms.setExtent(QgsRectangle(-133, 22, -70, 52))
        ms.setLayers([lines_layer])

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(ms)
        renderchecker.setControlPathPrefix('symbol_layer')
        renderchecker.setControlName('expected_linelayer_ddenabled')
        self.assertTrue(renderchecker.runTest('linelayer_ddenabled'))
        QgsProject.instance().removeMapLayer(lines_layer)
Example #2
0
    def load_layer(self, id, param):
        """
        Loads a layer which was specified as parameter.
        """

        filepath = self.filepath_from_param(param)

        if 'in_place' in param and param['in_place']:
            # check if alg modifies layer in place
            tmpdir = tempfile.mkdtemp()
            self.cleanup_paths.append(tmpdir)
            path, file_name = os.path.split(filepath)
            base, ext = os.path.splitext(file_name)
            for file in glob.glob(os.path.join(path, '{}.*'.format(base))):
                shutil.copy(os.path.join(path, file), tmpdir)
            filepath = os.path.join(tmpdir, file_name)
            self.in_place_layers[id] = filepath

        if param['type'] in ('vector', 'table'):
            if filepath in self.vector_layer_params:
                return self.vector_layer_params[filepath]

            options = QgsVectorLayer.LayerOptions()
            options.loadDefaultStyle = False
            lyr = QgsVectorLayer(filepath, param['name'], 'ogr', options)
            self.vector_layer_params[filepath] = lyr
        elif param['type'] == 'raster':
            options = QgsRasterLayer.LayerOptions()
            options.loadDefaultStyle = False
            lyr = QgsRasterLayer(filepath, param['name'], 'gdal', options)

        self.assertTrue(lyr.isValid(), 'Could not load layer "{}" from param {}'.format(filepath, param))
        QgsProject.instance().addMapLayer(lyr)
        return lyr
Example #3
0
    def testValidRelationAfterChangingStyle(self):
        # load project
        myPath = os.path.join(unitTestDataPath(), 'relations.qgs')
        QgsProject.instance().read(myPath)

        # get referenced layer
        relations = QgsProject.instance().relationManager().relations()
        relation = relations[list(relations.keys())[0]]
        referencedLayer = relation.referencedLayer()

        # check that the relation is valid
        valid = False
        for tab in referencedLayer.editFormConfig().tabs():
            for t in tab.children():
                if (t.type() == QgsAttributeEditorElement.AeTypeRelation):
                    valid = t.relation().isValid()
        self.assertTrue(valid)

        # update style
        referencedLayer.styleManager().setCurrentStyle("custom")

        # check that the relation is still valid
        referencedLayer = relation.referencedLayer()
        valid = False
        for tab in referencedLayer.editFormConfig().tabs():
            for t in tab.children():
                if (t.type() == QgsAttributeEditorElement.AeTypeRelation):
                    valid = t.relation().isValid()
        self.assertTrue(valid)
Example #4
0
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

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

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

        # create layout with layout map
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()
        self.map = QgsLayoutItemMap(self.layout)
        self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        self.map.setFrameEnabled(True)
        self.map.setLayers([self.raster_layer])
        self.layout.addLayoutItem(self.map)
Example #5
0
    def testUpdatedFields(self):
        """Test when referenced layer update its fields
        https://issues.qgis.org/issues/20893
        """

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

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

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

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

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

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

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

        QgsProject.instance().removeMapLayer(ml)
Example #6
0
    def testNoSliverPolygons(self):

        # create a layer with some polygons that will be used as a source for "avoid intersections"
        l = QgsVectorLayer('MultiPolygon', 'test_layer', 'memory')
        assert l.isValid()
        QgsProject.instance().addMapLayer(l)
        QgsProject.instance().writeEntry("Digitizing", "/AvoidIntersectionsList", [l.id()])

        features = []
        for i, wkt in enumerate(feat_wkt):
            f = QgsFeature(i + 1)
            f.setGeometry(QgsGeometry.fromWkt(wkt))
            features.append(f)

        l.dataProvider().addFeatures(features)
        assert l.pendingFeatureCount() == 7

        # create a geometry and remove its intersections with other geometries

        g = QgsGeometry.fromWkt(newg_wkt)
        assert g.avoidIntersections() == 0

        # the resulting multi-polygon must have exactly three parts
        # (in QGIS 2.0 it has one more tiny part that appears at the border between two of the original polygons)
        mpg = g.asMultiPolygon()
        assert len(mpg) == 3
Example #7
0
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

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

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

        # create composition with composer map
        self.mComposition = QgsComposition(QgsProject.instance())
        self.mComposition.setPaperSize(297, 210)
        self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100)
        self.mComposerMap.setFrameEnabled(True)
        self.mComposerMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(self.mComposerMap)
Example #8
0
    def execute(self):
        model = self.itemData
        if model is None:
            return # shouldn't happen, but let's be safe

        project_provider = model.provider().id() == PROJECT_PROVIDER_ID

        if project_provider:
            msg = self.tr('Are you sure you want to delete this model from the current project?', 'DeleteModelAction')
        else:
            msg = self.tr('Are you sure you want to delete this model?', 'DeleteModelAction')

        reply = QMessageBox.question(
            None,
            self.tr('Delete Model', 'DeleteModelAction'),
            msg,
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No)

        if reply == QMessageBox.Yes:
            if project_provider:
                provider = QgsApplication.processingRegistry().providerById(PROJECT_PROVIDER_ID)
                provider.remove_model(model)
                QgsProject.instance().setDirty(True)
            else:
                os.remove(model.sourceFilePath())
                QgsApplication.processingRegistry().providerById('model').refreshAlgorithms()
Example #9
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)
Example #10
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 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())
Example #12
0
    def getAsString(self, value):
        if self.datatype == dataobjects.TYPE_RASTER:
            if isinstance(value, QgsRasterLayer):
                return str(value.dataProvider().dataSourceUri())
            else:
                s = str(value)
                layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
                for layer in layers:
                    if layer.name() == s:
                        return str(layer.dataProvider().dataSourceUri())
                return s

        if self.datatype == dataobjects.TYPE_FILE:
            return str(value)
        else:
            if isinstance(value, QgsVectorLayer):
                return str(value.source())
            else:
                s = str(value)
                if self.datatype != dataobjects.TYPE_VECTOR_ANY:
                    layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.datatype], False)
                else:
                    layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
                for layer in layers:
                    if layer.name() == s:
                        return str(layer.source())
                return s
    def testLayers(self):
        """ check that layers are shown in widget model"""
        p = QgsProject.instance()
        layer = QgsVectorLayer("Point", "layer1", "memory")
        layer2 = QgsVectorLayer("Point", "layer2", "memory")
        p.addMapLayers([layer, layer2])

        w = QgsExpressionBuilderWidget()
        m = w.model()

        # check that layers are shown
        items = m.findItems('layer1', Qt.MatchRecursive)
        self.assertEqual(len(items), 1)
        items = m.findItems('layer2', Qt.MatchRecursive)
        self.assertEqual(len(items), 1)

        # change project
        p2 = QgsProject()
        layer3 = QgsVectorLayer("Point", "layer3", "memory")
        p2.addMapLayers([layer3])
        w.setProject(p2)
        m = w.model()
        items = m.findItems('layer1', Qt.MatchRecursive)
        self.assertEqual(len(items), 0)
        items = m.findItems('layer2', Qt.MatchRecursive)
        self.assertEqual(len(items), 0)
        items = m.findItems('layer3', Qt.MatchRecursive)
        self.assertEqual(len(items), 1)
Example #14
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()
Example #15
0
    def setUp(self):
        self.iface = get_iface()
        QgsProject.instance().removeAllMapLayers()

        self.iface.mapCanvas().viewport().resize(400, 400)
        # For some reason the resizeEvent is not delivered, fake it
        self.iface.mapCanvas().resizeEvent(QResizeEvent(QSize(400, 400), self.iface.mapCanvas().size()))
 def _set_up_composition(self, width, height, dpi, engine_settings):
     # set up composition and add map
     self._c = QgsComposition(QgsProject.instance())
     """:type: QgsComposition"""
     # self._c.setUseAdvancedEffects(False)
     self._c.setPrintResolution(dpi)
     # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi
     paperw = width * 25.4 / dpi
     paperh = height * 25.4 / dpi
     self._c.setPaperSize(paperw, paperh)
     # NOTE: do not use QgsComposerMap(self._c, 0, 0, paperw, paperh) since
     # it only takes integers as parameters and the composition will grow
     # larger based upon union of item scene rectangles and a slight buffer
     #   see end of QgsComposition::compositionBounds()
     # add map as small graphics item first, then set its scene QRectF later
     self._cmap = QgsComposerMap(self._c, 10, 10, 10, 10)
     """:type: QgsComposerMap"""
     self._cmap.setFrameEnabled(False)
     self._cmap.setLayers(self._TestMapSettings.layers())
     self._c.addComposerMap(self._cmap)
     # now expand map to fill page and set its extent
     self._cmap.setSceneRect(QRectF(0, 0, paperw, paperw))
     self._cmap.setNewExtent(self.aoiExtent())
     # self._cmap.updateCachedImage()
     self._c.setPlotStyle(QgsComposition.Print)
     # composition takes labeling engine settings from project
     QgsProject.instance().setLabelingEngineSettings(engine_settings)
    def __init__(self, snapLayer, parent=None):
        super(LayerSnappingEnabledAction, self).__init__(parent)

        self._layerId = ''
        self._iface = None  # QgisInteface

        if isinstance(snapLayer, QgisInterface):
            self._iface = snapLayer
        elif isinstance(snapLayer, QgsVectorLayer):
            self._layerId = snapLayer.id()
        elif isinstance(snapLayer, str) or isinstance(snapLayer, unicode):
            self._layerId = snapLayer

        self.setCheckable(True)
        self.setText('Toggle Layer Snapping')
        self.setStatusTip('Toggle snapping on this layer')
        self.setIcon(QIcon(':/plugins/ark/snapEnable.png'))

        self._refresh()
        self.triggered.connect(self._triggered)

        # Make sure we catch changes in the main snapping dialog
        QgsProject.instance().snapSettingsChanged.connect(self._refresh)
        # If using current layer, make sure we update when it changes
        if self._iface:
            self._iface.legendInterface().currentLayerChanged.connect(self._refresh)
        # If the layer is removed then disable the button
        QgsMapLayerRegistry.instance().layerRemoved.connect(self._layerRemoved)
        # If we change the settings, make such others are told
        self.snappingEnabledChanged.connect(QgsProject.instance().snapSettingsChanged)
 def _layerRemoved(self, layerId):
     if self._layerId and layerId == self._layerId:
         self._layerId = ''
         self.setEnabled(False)
         QgsProject.instance().snapSettingsChanged.disconnect(self._refresh)
         QgsMapLayerRegistry.instance().layerRemoved.disconnect(self._layerRemoved)
         self.snappingEnabledChanged.disconnect(QgsProject.instance().snapSettingsChanged)
Example #19
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)
Example #20
0
    def test_check_validity(self):
        """Test that the output invalid contains the error reason"""

        polygon_layer = self._make_layer('Polygon')
        self.assertTrue(polygon_layer.startEditing())
        f = QgsFeature(polygon_layer.fields())
        f.setAttributes([1])
        # Flake!
        f.setGeometry(QgsGeometry.fromWkt(
            'POLYGON ((0 0, 2 2, 0 2, 2 0, 0 0))'))
        self.assertTrue(f.isValid())
        f2 = QgsFeature(polygon_layer.fields())
        f2.setAttributes([1])
        f2.setGeometry(QgsGeometry.fromWkt(
            'POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))'))
        self.assertTrue(f2.isValid())
        self.assertTrue(polygon_layer.addFeatures([f, f2]))
        polygon_layer.commitChanges()
        polygon_layer.rollBack()
        self.assertEqual(polygon_layer.featureCount(), 2)

        QgsProject.instance().addMapLayers([polygon_layer])

        alg = self.registry.createAlgorithmById('qgis:checkvalidity')

        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())
        feedback = ConsoleFeedBack()

        self.assertIsNotNone(alg)
        parameters = {}
        parameters['INPUT_LAYER'] = polygon_layer.id()
        parameters['VALID_OUTPUT'] = 'memory:'
        parameters['INVALID_OUTPUT'] = 'memory:'
        parameters['ERROR_OUTPUT'] = 'memory:'

        # QGIS method
        parameters['METHOD'] = 1
        ok, results = execute(
            alg, parameters, context=context, feedback=feedback)
        self.assertTrue(ok)
        invalid_layer = QgsProcessingUtils.mapLayerFromString(
            results['INVALID_OUTPUT'], context)
        self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
        self.assertEqual(invalid_layer.featureCount(), 1)
        f = next(invalid_layer.getFeatures())
        self.assertEqual(f.attributes(), [
                         1, 'segments 0 and 2 of line 0 intersect at 1, 1'])

        # GEOS method
        parameters['METHOD'] = 2
        ok, results = execute(
            alg, parameters, context=context, feedback=feedback)
        self.assertTrue(ok)
        invalid_layer = QgsProcessingUtils.mapLayerFromString(
            results['INVALID_OUTPUT'], context)
        self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
        self.assertEqual(invalid_layer.featureCount(), 1)
        f = next(invalid_layer.getFeatures())
        self.assertEqual(f.attributes(), [1, 'Self-intersection'])
Example #21
0
    def testCheckStateRole(self):
        l1 = create_layer('l1')
        l2 = create_layer('l2')
        QgsProject.instance().addMapLayers([l1, l2])
        m = QgsMapLayerModel()

        # not checkable
        self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole))
        self.assertFalse(m.data(m.index(1, 0), Qt.CheckStateRole))
        m.setAllowEmptyLayer(True)
        self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole))
        self.assertFalse(m.data(m.index(1, 0), Qt.CheckStateRole))
        self.assertFalse(m.data(m.index(2, 0), Qt.CheckStateRole))
        m.setAllowEmptyLayer(False)

        # checkable
        m.setItemsCheckable(True)
        m.checkAll(Qt.Checked)
        self.assertTrue(m.data(m.index(0, 0), Qt.CheckStateRole))
        self.assertTrue(m.data(m.index(1, 0), Qt.CheckStateRole))
        m.setAllowEmptyLayer(True)
        self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole))
        self.assertTrue(m.data(m.index(1, 0), Qt.CheckStateRole))
        self.assertTrue(m.data(m.index(2, 0), Qt.CheckStateRole))

        m.setAdditionalItems(['a'])
        self.assertFalse(m.data(m.index(3, 0), Qt.CheckStateRole))

        QgsProject.instance().removeMapLayers([l1.id(), l2.id()])
Example #22
0
    def testFlags(self):
        l1 = create_layer('l1')
        l2 = create_layer('l2')
        QgsProject.instance().addMapLayers([l1, l2])
        m = QgsMapLayerModel()

        # not checkable
        self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable)
        self.assertFalse(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable)
        m.setAllowEmptyLayer(True)
        self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable)
        self.assertFalse(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable)
        self.assertFalse(m.flags(m.index(2, 0)) & Qt.ItemIsUserCheckable)
        m.setAllowEmptyLayer(False)

        # checkable
        m.setItemsCheckable(True)
        self.assertTrue(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable)
        self.assertTrue(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable)
        m.setAllowEmptyLayer(True)
        self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable)
        self.assertTrue(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable)
        self.assertTrue(m.flags(m.index(2, 0)) & Qt.ItemIsUserCheckable)

        m.setAdditionalItems(['a'])
        self.assertFalse(m.flags(m.index(3, 0)) & Qt.ItemIsUserCheckable)

        QgsProject.instance().removeMapLayers([l1.id(), l2.id()])
    def testFilterString(self):
        """ test filtering by string"""
        QgsProject.instance().clear()
        m = QgsMapLayerProxyModel()
        l1 = QgsVectorLayer("Point?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer",
                            'layer 1', "memory")
        QgsProject.instance().addMapLayer(l1)
        l2 = QgsVectorLayer("Polygon?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer",
                            'lAyEr 2', "memory")
        QgsProject.instance().addMapLayer(l2)
        l3 = QgsVectorLayer("None?field=fldtxt:string&field=fldint:integer",
                            'another', "memory")
        QgsProject.instance().addMapLayer(l3)
        l4 = QgsVectorLayer("LineString?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer",
                            'final layer', "memory")
        QgsProject.instance().addMapLayer(l4)

        m.setFilterString('layer')
        self.assertEqual(m.rowCount(), 3)
        self.assertEqual(m.data(m.index(0, 0)), 'final layer')
        self.assertEqual(m.data(m.index(1, 0)), 'layer 1')
        self.assertEqual(m.data(m.index(2, 0)), 'lAyEr 2')

        m.setFilterString('')
        self.assertEqual(m.rowCount(), 4)
Example #24
0
    def test_geometryTypes(self):

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

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

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

            QgsProject.instance().removeMapLayer(l.id())
 def _set_up_composition(self, width, height, dpi, engine_settings):
     # set up layout and add map
     self._c = QgsLayout(QgsProject.instance())
     """:type: QgsLayout"""
     # self._c.setUseAdvancedEffects(False)
     self._c.renderContext().setDpi(dpi)
     # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi
     paperw = width * 25.4 / dpi
     paperh = height * 25.4 / dpi
     page = QgsLayoutItemPage(self._c)
     page.attemptResize(QgsLayoutSize(paperw, paperh))
     self._c.pageCollection().addPage(page)
     # NOTE: do not use QgsLayoutItemMap(self._c, 0, 0, paperw, paperh) since
     # it only takes integers as parameters and the composition will grow
     # larger based upon union of item scene rectangles and a slight buffer
     #   see end of QgsComposition::compositionBounds()
     # add map as small graphics item first, then set its scene QRectF later
     self._cmap = QgsLayoutItemMap(self._c)
     self._cmap.attemptSetSceneRect(QRectF(10, 10, 10, 10))
     """:type: QgsLayoutItemMap"""
     self._cmap.setFrameEnabled(False)
     self._cmap.setLayers(self._TestMapSettings.layers())
     if self._TestMapSettings.labelingEngineSettings().flags() & QgsLabelingEngineSettings.UsePartialCandidates:
         self._cmap.setMapFlags(QgsLayoutItemMap.ShowPartialLabels)
     self._c.addLayoutItem(self._cmap)
     # now expand map to fill page and set its extent
     self._cmap.attemptSetSceneRect(QRectF(0, 0, paperw, paperw))
     self._cmap.setExtent(self.aoiExtent())
     # self._cmap.updateCachedImage()
     # composition takes labeling engine settings from project
     QgsProject.instance().setLabelingEngineSettings(engine_settings)
Example #26
0
    def loadSqlLayer(self):
        with OverrideCursor(Qt.WaitCursor):
            layer = self._getSqlLayer(self.filter)
            if layer is None:
                return

            QgsProject.instance().addMapLayers([layer], True)
Example #27
0
    def testGettersSetters(self):
        """ test model getters/setters """
        m = QgsMapLayerProxyModel()
        l1 = create_layer('l1')
        QgsProject.instance().addMapLayer(l1)
        l2 = create_layer('l2')
        QgsProject.instance().addMapLayer(l2)

        m.setFilters(QgsMapLayerProxyModel.LineLayer | QgsMapLayerProxyModel.WritableLayer)
        self.assertEqual(m.filters(), QgsMapLayerProxyModel.LineLayer | QgsMapLayerProxyModel.WritableLayer)

        m.setExceptedLayerIds([l2.id()])
        self.assertEqual(m.exceptedLayerIds(), [l2.id()])

        m.setExceptedLayerList([l2])
        self.assertEqual(m.exceptedLayerList(), [l2])

        m.setLayerWhitelist([l2])
        self.assertEqual(m.layerWhitelist(), [l2])

        m.setExcludedProviders(['a', 'b'])
        self.assertEqual(m.excludedProviders(), ['a', 'b'])

        m.setFilterString('c')
        self.assertEqual(m.filterString(), 'c')
    def test_snappointstogrid(self):
        """Check that this runs correctly"""

        polygon_layer = self._make_layer('Polygon')
        f1 = QgsFeature(polygon_layer.fields())
        f1.setAttributes([1])
        f1.setGeometry(QgsGeometry.fromWkt('POLYGON((1.2 1.2, 1.2 2.2, 2.2 2.2, 2.2 1.2, 1.2 1.2))'))
        f2 = QgsFeature(polygon_layer.fields())
        f2.setAttributes([2])
        f2.setGeometry(QgsGeometry.fromWkt('POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))'))
        self.assertTrue(f2.isValid())
        self.assertTrue(polygon_layer.startEditing())
        self.assertTrue(polygon_layer.addFeatures([f1, f2]))
        self.assertEqual(polygon_layer.featureCount(), 2)
        polygon_layer.commitChanges()
        self.assertEqual(polygon_layer.featureCount(), 2)
        QgsProject.instance().addMapLayers([polygon_layer])

        polygon_layer.selectByIds([next(polygon_layer.getFeatures()).id()])
        self.assertEqual(polygon_layer.selectedFeatureCount(), 1)

        old_features, new_features = self._alg_tester(
            'native:snappointstogrid',
            polygon_layer,
            {
                'HSPACING': 0.5,
                'VSPACING': 0.5,
            }
        )

        g = [f.geometry() for f in new_features][0]
        self.assertEqual(g.asWkt(), 'Polygon ((1 1, 1 2, 2 2, 2 1, 1 1))')
        # Check selected
        self.assertEqual(polygon_layer.selectedFeatureIds(), [1])
Example #29
0
    def testAdditionalItems(self):
        l1 = create_layer('l1')
        l2 = create_layer('l2')
        QgsProject.instance().addMapLayers([l1, l2])
        m = QgsMapLayerModel()
        self.assertEqual(m.rowCount(QModelIndex()), 2)

        m.setAdditionalItems(['a', 'b'])
        self.assertEqual(m.rowCount(QModelIndex()), 4)
        self.assertEqual(m.data(m.index(0, 0), Qt.DisplayRole), 'l1')
        self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l2')
        self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'a')
        self.assertEqual(m.data(m.index(3, 0), Qt.DisplayRole), 'b')

        m.setAllowEmptyLayer(True)
        self.assertEqual(m.rowCount(QModelIndex()), 5)
        self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole))
        self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l1')
        self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'l2')
        self.assertEqual(m.data(m.index(3, 0), Qt.DisplayRole), 'a')
        self.assertEqual(m.data(m.index(4, 0), Qt.DisplayRole), 'b')

        QgsProject.instance().removeMapLayers([l1.id(), l2.id()])

        self.assertEqual(m.rowCount(QModelIndex()), 3)
        self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole))
        self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'a')
        self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'b')
Example #30
0
    def testRenderMarkerLayerDataDefined(self):
        """ test that rendering a marker symbol with data defined enabled layer works"""

        points_shp = os.path.join(TEST_DATA_DIR, 'points.shp')
        points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr')
        QgsProject.instance().addMapLayer(points_layer)

        layer = QgsSimpleMarkerSymbolLayer()
        layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Class='Biplane'"))
        layer.setColor(QColor(100, 150, 150))
        layer.setSize(5)
        layer.setStrokeStyle(Qt.NoPen)

        symbol = QgsMarkerSymbol()
        symbol.changeSymbolLayer(0, layer)
        points_layer.setRenderer(QgsSingleSymbolRenderer(symbol))

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(400, 400))
        ms.setOutputDpi(96)
        ms.setExtent(QgsRectangle(-133, 22, -70, 52))
        ms.setLayers([points_layer])

        renderchecker = QgsMultiRenderChecker()
        renderchecker.setMapSettings(ms)
        renderchecker.setControlPathPrefix('symbol_layer')
        renderchecker.setControlName('expected_markerlayer_ddenabled')
        self.assertTrue(renderchecker.runTest('markerlayer_ddenabled'))
        QgsProject.instance().removeMapLayer(points_layer)
    def testSnapPointToGrid(self):
        p = QgsProject()
        l = QgsLayout(p)
        # need a page to snap to grid
        page = QgsLayoutItemPage(l)
        page.setPageSize('A4')
        l.pageCollection().addPage(page)
        s = QgsLayoutSnapper(l)

        l.gridSettings().setResolution(
            QgsLayoutMeasurement(5, QgsUnitTypes.LayoutMillimeters))

        s.setSnapToGrid(True)
        s.setSnapTolerance(1)

        point, snappedX, snappedY = s.snapPointToGrid(QPointF(1, 1), 1)
        self.assertTrue(snappedX)
        self.assertTrue(snappedY)
        self.assertEqual(point, QPointF(0, 0))

        point, snappedX, snappedY = s.snapPointToGrid(QPointF(9, 1), 1)
        self.assertTrue(snappedX)
        self.assertTrue(snappedY)
        self.assertEqual(point, QPointF(10, 0))

        point, snappedX, snappedY = s.snapPointToGrid(QPointF(1, 11), 1)
        self.assertTrue(snappedX)
        self.assertTrue(snappedY)
        self.assertEqual(point, QPointF(0, 10))

        point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 11), 1)
        self.assertFalse(snappedX)
        self.assertTrue(snappedY)
        self.assertEqual(point, QPointF(13, 10))

        point, snappedX, snappedY = s.snapPointToGrid(QPointF(11, 13), 1)
        self.assertTrue(snappedX)
        self.assertFalse(snappedY)
        self.assertEqual(point, QPointF(10, 13))

        point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 23), 1)
        self.assertFalse(snappedX)
        self.assertFalse(snappedY)
        self.assertEqual(point, QPointF(13, 23))

        # grid disabled
        s.setSnapToGrid(False)
        point, nappedX, snappedY = s.snapPointToGrid(QPointF(1, 1), 1)
        self.assertFalse(nappedX)
        self.assertFalse(snappedY)
        self.assertEqual(point, QPointF(1, 1))
        s.setSnapToGrid(True)

        # with different pixel scale
        point, snappedX, snappedY = s.snapPointToGrid(QPointF(0.5, 0.5), 1)
        self.assertTrue(snappedX)
        self.assertTrue(snappedY)
        self.assertEqual(point, QPointF(0, 0))
        point, snappedX, snappedY = s.snapPointToGrid(QPointF(0.5, 0.5), 3)
        self.assertFalse(snappedX)
        self.assertFalse(snappedY)
        self.assertEqual(point, QPointF(0.5, 0.5))

        # with offset grid
        l.gridSettings().setOffset(QgsLayoutPoint(2, 0))
        point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 23), 1)
        self.assertTrue(snappedX)
        self.assertFalse(snappedY)
        self.assertEqual(point, QPointF(12, 23))
    def testPages(self):
        """
        Test adding/retrieving/deleting pages from the collection
        """
        p = QgsProject()
        l = QgsLayout(p)
        collection = l.pageCollection()

        self.assertEqual(collection.pageCount(), 0)
        self.assertFalse(collection.pages())
        self.assertFalse(collection.page(-1))
        self.assertFalse(collection.page(0))
        self.assertFalse(collection.page(1))

        # add a page
        page = QgsLayoutItemPage(l)
        page.setPageSize('A4')
        self.assertEqual(collection.pageNumber(page), -1)

        collection.addPage(page)

        self.assertTrue(page in l.items())

        self.assertEqual(collection.pageCount(), 1)
        self.assertEqual(collection.pages(), [page])
        self.assertFalse(collection.page(-1))
        self.assertEqual(collection.page(0), page)
        self.assertFalse(collection.page(1))
        self.assertEqual(collection.pageNumber(page), 0)

        # add a second page
        page2 = QgsLayoutItemPage(l)
        page2.setPageSize('A5')
        collection.addPage(page2)

        self.assertEqual(collection.pageCount(), 2)
        self.assertEqual(collection.pages(), [page, page2])
        self.assertFalse(collection.page(-1))
        self.assertEqual(collection.page(0), page)
        self.assertEqual(collection.page(1), page2)
        self.assertEqual(collection.pageNumber(page2), 1)

        # insert a page
        page3 = QgsLayoutItemPage(l)
        page3.setPageSize('A3')
        collection.insertPage(page3, 1)
        self.assertTrue(page3 in l.items())

        self.assertEqual(collection.pageCount(), 3)
        self.assertEqual(collection.pages(), [page, page3, page2])
        self.assertEqual(collection.page(0), page)
        self.assertEqual(collection.page(1), page3)
        self.assertEqual(collection.page(2), page2)
        self.assertEqual(collection.pageNumber(page3), 1)

        # delete page
        collection.deletePage(-1)
        self.assertEqual(collection.pageCount(), 3)
        self.assertEqual(collection.pages(), [page, page3, page2])
        collection.deletePage(100)
        self.assertEqual(collection.pageCount(), 3)
        self.assertEqual(collection.pages(), [page, page3, page2])
        collection.deletePage(1)
        self.assertEqual(collection.pageCount(), 2)
        self.assertEqual(collection.pages(), [page, page2])

        # make sure page was deleted
        QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
        self.assertTrue(sip.isdeleted(page3))

        del l
        QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
        self.assertTrue(sip.isdeleted(page))
        self.assertTrue(sip.isdeleted(page2))
Example #33
0
 def tearDown(self):
     QgsProject.instance().removeAllMapLayers()
Example #34
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(), QgsPoint(0.8, 0.0))

        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
Example #35
0
    def testDistance(self):
        self.checkConstructWrapper(QgsProcessingParameterDistance('test'),
                                   DistanceWidgetWrapper)

        alg = QgsApplication.processingRegistry().algorithmById(
            'native:centroids')
        dlg = AlgorithmDialog(alg)
        param = QgsProcessingParameterDistance('test')
        wrapper = DistanceWidgetWrapper(param, dlg)
        widget = wrapper.createWidget()

        # test units
        widget.show()

        # crs values
        widget.setUnitParameterValue('EPSG:3111')
        self.assertEqual(widget.label.text(), 'meters')
        self.assertFalse(widget.warning_label.isVisible())
        self.assertTrue(widget.units_combo.isVisible())
        self.assertFalse(widget.label.isVisible())
        self.assertEqual(widget.units_combo.currentData(),
                         QgsUnitTypes.DistanceMeters)

        widget.setUnitParameterValue('EPSG:4326')
        self.assertEqual(widget.label.text(), 'degrees')
        self.assertTrue(widget.warning_label.isVisible())
        self.assertFalse(widget.units_combo.isVisible())
        self.assertTrue(widget.label.isVisible())

        widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:3111'))
        self.assertEqual(widget.label.text(), 'meters')
        self.assertFalse(widget.warning_label.isVisible())
        self.assertTrue(widget.units_combo.isVisible())
        self.assertFalse(widget.label.isVisible())
        self.assertEqual(widget.units_combo.currentData(),
                         QgsUnitTypes.DistanceMeters)

        widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(widget.label.text(), 'degrees')
        self.assertTrue(widget.warning_label.isVisible())
        self.assertFalse(widget.units_combo.isVisible())
        self.assertTrue(widget.label.isVisible())

        # layer values
        vl = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl",
                            "memory")
        widget.setUnitParameterValue(vl)
        self.assertEqual(widget.label.text(), 'meters')
        self.assertFalse(widget.warning_label.isVisible())
        self.assertTrue(widget.units_combo.isVisible())
        self.assertFalse(widget.label.isVisible())
        self.assertEqual(widget.units_combo.currentData(),
                         QgsUnitTypes.DistanceMeters)

        vl2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=pk:int", "vl",
                             "memory")
        widget.setUnitParameterValue(vl2)
        self.assertEqual(widget.label.text(), 'degrees')
        self.assertTrue(widget.warning_label.isVisible())
        self.assertFalse(widget.units_combo.isVisible())
        self.assertTrue(widget.label.isVisible())

        # unresolvable values
        widget.setUnitParameterValue(vl.id())
        self.assertEqual(widget.label.text(), '<unknown>')
        self.assertFalse(widget.warning_label.isVisible())
        self.assertFalse(widget.units_combo.isVisible())
        self.assertTrue(widget.label.isVisible())

        # resolvable text value
        QgsProject.instance().addMapLayer(vl)
        widget.setUnitParameterValue(vl.id())
        self.assertEqual(widget.label.text(), 'meters')
        self.assertFalse(widget.warning_label.isVisible())
        self.assertTrue(widget.units_combo.isVisible())
        self.assertFalse(widget.label.isVisible())
        self.assertEqual(widget.units_combo.currentData(),
                         QgsUnitTypes.DistanceMeters)

        widget.setValue(5)
        self.assertEqual(widget.getValue(), 5)
        widget.units_combo.setCurrentIndex(
            widget.units_combo.findData(QgsUnitTypes.DistanceKilometers))
        self.assertEqual(widget.getValue(), 5000)
        widget.setValue(2)
        self.assertEqual(widget.getValue(), 2000)

        widget.setUnitParameterValue(vl.id())
        self.assertEqual(widget.getValue(), 2)
        widget.setValue(5)
        self.assertEqual(widget.getValue(), 5)

        widget.deleteLater()
    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 testResizeToContents(self):
        p = QgsProject()
        l = QgsLayout(p)

        shape1 = QgsLayoutItemShape(l)
        shape1.attemptResize(QgsLayoutSize(90, 50))
        shape1.attemptMove(QgsLayoutPoint(90, 50))
        shape1.setItemRotation(45, False)
        l.addLayoutItem(shape1)
        shape2 = QgsLayoutItemShape(l)
        shape2.attemptResize(QgsLayoutSize(110, 50))
        shape2.attemptMove(QgsLayoutPoint(100, 150), True, False, 0)
        l.addLayoutItem(shape2)
        shape3 = QgsLayoutItemShape(l)
        l.addLayoutItem(shape3)
        shape3.attemptResize(QgsLayoutSize(50, 100))
        shape3.attemptMove(QgsLayoutPoint(210, 250), True, False, 0)
        shape4 = QgsLayoutItemShape(l)
        l.addLayoutItem(shape4)
        shape4.attemptResize(QgsLayoutSize(50, 30))
        shape4.attemptMove(QgsLayoutPoint(10, 340), True, False, 0)
        shape4.setVisibility(False)

        # resize with no existing pages
        l.pageCollection().resizeToContents(QgsMargins(1, 2, 3, 4), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(l.pageCollection().pageCount(), 1)

        self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().width(), 290.3, 2)
        self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().height(), 380.36, 2)
        self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().units(), QgsUnitTypes.LayoutMillimeters)

        self.assertAlmostEqual(shape1.positionWithUnits().x(), 90.15, 2)
        self.assertAlmostEqual(shape1.positionWithUnits().y(), 20.21, 2)
        self.assertAlmostEqual(shape2.positionWithUnits().x(), 100.15, 2)
        self.assertAlmostEqual(shape2.positionWithUnits().y(), 120.21, 2)
        self.assertAlmostEqual(shape3.positionWithUnits().x(), 210.15, 2)
        self.assertAlmostEqual(shape3.positionWithUnits().y(), 220.21, 2)
        self.assertAlmostEqual(shape4.positionWithUnits().x(), 10.15, 2)
        self.assertAlmostEqual(shape4.positionWithUnits().y(), 310.21, 2)

        # add a second page
        page2 = QgsLayoutItemPage(l)
        page2.setPageSize("A4", QgsLayoutItemPage.Landscape)
        l.pageCollection().addPage(page2)

        # add some guides
        g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(2.5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0))
        l.guides().addGuide(g1)
        g2 = QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(4.5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0))
        l.guides().addGuide(g2)

        # second page should be removed
        l.pageCollection().resizeToContents(QgsMargins(0, 0, 0, 0), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(l.pageCollection().pageCount(), 1)

        self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().width(), 250.3, 2)
        self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().height(), 320.36, 2)
        self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().units(), QgsUnitTypes.LayoutMillimeters)

        self.assertAlmostEqual(g1.position().length(), 0.5, 2)
        self.assertAlmostEqual(g2.position().length(), 3.5, 2)
Example #38
0
    def testThemeChanged(self):
        """
        Test that the mapTheme(s)Changed signals are correctly emitted in all relevant situations
        """
        project = QgsProject()
        collection = QgsMapThemeCollection(project)

        record = QgsMapThemeCollection.MapThemeRecord()

        theme_changed_spy = QSignalSpy(collection.mapThemeChanged)
        themes_changed_spy = QSignalSpy(collection.mapThemesChanged)

        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 1)
        self.assertEqual(theme_changed_spy[-1][0], 'theme1')
        self.assertEqual(len(themes_changed_spy), 1)

        # reinsert
        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 2)
        self.assertEqual(theme_changed_spy[-1][0], 'theme1')
        self.assertEqual(len(themes_changed_spy), 2)

        # update
        collection.update('theme1', record)
        self.assertEqual(len(theme_changed_spy), 3)
        self.assertEqual(theme_changed_spy[-1][0], 'theme1')
        self.assertEqual(len(themes_changed_spy), 3)

        # remove invalid
        collection.removeMapTheme(
            'i wish i was a slave to an age old trade... like riding around on rail cars and working long days'
        )
        self.assertEqual(len(theme_changed_spy), 3)
        self.assertEqual(len(themes_changed_spy), 3)
        # remove valid
        collection.removeMapTheme('theme1')
        self.assertEqual(len(theme_changed_spy), 3)  # not changed - removed!
        self.assertEqual(len(themes_changed_spy), 4)

        # reinsert
        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 4)
        self.assertEqual(len(themes_changed_spy), 5)

        # clear
        collection.clear()
        self.assertEqual(len(theme_changed_spy), 4)  # not changed - removed!
        self.assertEqual(len(themes_changed_spy), 6)

        # check that mapThemeChanged is emitted if layer is removed
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        project.addMapLayers([layer, layer2])

        # record for layer1
        record.addLayerRecord(QgsMapThemeCollection.MapThemeLayerRecord(layer))
        collection.insert('theme1', record)
        self.assertEqual(len(theme_changed_spy), 5)
        self.assertEqual(len(themes_changed_spy), 7)

        # now kill layer 2
        project.removeMapLayer(layer2)
        self.assertEqual(
            len(theme_changed_spy),
            5)  # signal should not be emitted - layer is not in record
        # now kill layer 1
        project.removeMapLayer(layer)
        app.processEvents()
        self.assertEqual(len(theme_changed_spy),
                         6)  # signal should be emitted - layer is in record
Example #39
0
    def testTransparency(self):
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1)
        myRasterLayer.setRenderer(renderer)
        myRasterLayer.setContrastEnhancement(
            QgsContrastEnhancement.StretchToMinimumMaximum,
            QgsRasterMinMaxOrigin.MinMax)

        myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement()
        # print ("myContrastEnhancement.minimumValue = %.17g" %
        #       myContrastEnhancement.minimumValue())
        # print ("myContrastEnhancement.maximumValue = %.17g" %
        #        myContrastEnhancement.maximumValue())

        # Unfortunately the minimum/maximum values calculated in C++ and Python
        # are slightly different (e.g. 3.3999999521443642e+38 x
        # 3.3999999521444001e+38)
        # It is not clear where the precision is lost.
        # We set the same values as C++.
        myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38)
        myContrastEnhancement.setMaximumValue(3.3999999521443642e+38)
        #myType = myRasterLayer.dataProvider().dataType(1);
        #myEnhancement = QgsContrastEnhancement(myType);

        myTransparentSingleValuePixelList = []
        rasterTransparency = QgsRasterTransparency()

        myTransparentPixel1 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel1.min = -2.5840000772112106e+38
        myTransparentPixel1.max = -1.0879999684602689e+38
        myTransparentPixel1.percentTransparent = 50
        myTransparentSingleValuePixelList.append(myTransparentPixel1)

        myTransparentPixel2 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel2.min = 1.359999960575336e+37
        myTransparentPixel2.max = 9.520000231087593e+37
        myTransparentPixel2.percentTransparent = 70
        myTransparentSingleValuePixelList.append(myTransparentPixel2)

        rasterTransparency.setTransparentSingleValuePixelList(
            myTransparentSingleValuePixelList)

        rasterRenderer = myRasterLayer.renderer()
        assert rasterRenderer

        rasterRenderer.setRasterTransparency(rasterTransparency)

        QgsProject.instance().addMapLayers([
            myRasterLayer,
        ])

        myMapSettings = QgsMapSettings()
        myMapSettings.setLayers([myRasterLayer])
        myMapSettings.setExtent(myRasterLayer.extent())

        myChecker = QgsRenderChecker()
        myChecker.setControlName("expected_raster_transparency")
        myChecker.setMapSettings(myMapSettings)

        myResultFlag = myChecker.runTest("raster_transparency_python")
        assert myResultFlag, "Raster transparency rendering test failed"
 def testLayout(self):
     # test that layouts have a collection
     p = QgsProject()
     l = QgsLayout(p)
     self.assertTrue(l.pageCollection())
     self.assertEqual(l.pageCollection().layout(), l)
Example #41
0
    def formatCoord(self, pt, delimiter):
        '''Format the coordinate string according to the settings from
        the settings dialog.'''
        if self.settings.captureProjIsWgs84():  # ProjectionTypeWgs84
            # Make sure the coordinate is transformed to EPSG:4326
            canvasCRS = self.canvas.mapSettings().destinationCrs()
            if canvasCRS == epsg4326:
                pt4326 = pt
            else:
                transform = QgsCoordinateTransform(canvasCRS, epsg4326,
                                                   QgsProject.instance())
                pt4326 = transform.transform(pt.x(), pt.y())
            lat = pt4326.y()
            lon = pt4326.x()
            if self.settings.wgs84NumberFormat == self.settings.Wgs84TypeDMS:  # DMS
                msg = formatDmsString(lat, lon, 0, self.settings.dmsPrecision,
                                      self.settings.coordOrder, delimiter,
                                      settings.captureAddDmsSpace,
                                      settings.capturePadZeroes)
            elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeDDMMSS:  # DDMMSS
                msg = formatDmsString(lat, lon, 1, self.settings.dmsPrecision,
                                      self.settings.coordOrder, delimiter,
                                      settings.capturePadZeroes)
            elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeDMM:  # DM.MM
                msg = formatDmsString(lat, lon, 2,
                                      settings.captureDmmPrecision,
                                      self.settings.coordOrder, delimiter,
                                      settings.captureAddDmsSpace,
                                      settings.capturePadZeroes)
            elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeWKT:  # WKT
                msg = 'POINT({:.{prec}f} {:.{prec}f})'.format(
                    pt4326.x(), pt4326.y(), prec=self.settings.decimalDigits)
            elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeGeoJSON:  # GeoJSON
                msg = '{{"type": "Point","coordinates": [{:.{prec}f},{:.{prec}f}]}}'.format(
                    pt4326.x(), pt4326.y(), prec=self.settings.decimalDigits)
            else:  # decimal degrees
                if self.settings.coordOrder == self.settings.OrderYX:
                    msg = '{:.{prec}f}{}{:.{prec}f}'.format(
                        pt4326.y(),
                        delimiter,
                        pt4326.x(),
                        prec=self.settings.decimalDigits)
                else:
                    msg = '{:.{prec}f}{}{:.{prec}f}'.format(
                        pt4326.x(),
                        delimiter,
                        pt4326.y(),
                        prec=self.settings.decimalDigits)
        elif self.settings.captureProjIsProjectCRS():
            # Projection in the project CRS
            if self.settings.otherNumberFormat == 0:  # Numerical
                if self.settings.coordOrder == self.settings.OrderYX:
                    msg = '{:.{prec}f}{}{:.{prec}f}'.format(
                        pt.y(),
                        delimiter,
                        pt.x(),
                        prec=self.settings.decimalDigits)
                else:
                    msg = '{:.{prec}f}{}{:.{prec}f}'.format(
                        pt.x(),
                        delimiter,
                        pt.y(),
                        prec=self.settings.decimalDigits)
            else:
                msg = 'POINT({:.{prec}f} {:.{prec}f})'.format(
                    pt.x(), pt.y(), prec=self.settings.decimalDigits)
        elif self.settings.captureProjIsCustomCRS():
            # Projection is a custom CRS
            canvasCRS = self.canvas.mapSettings().destinationCrs()
            customCRS = self.settings.captureCustomCRS()
            transform = QgsCoordinateTransform(canvasCRS, customCRS,
                                               QgsProject.instance())
            pt = transform.transform(pt.x(), pt.y())
            if self.settings.otherNumberFormat == 0:  # Numerical
                if self.settings.coordOrder == self.settings.OrderYX:
                    msg = '{:.{prec}f}{}{:.{prec}f}'.format(
                        pt.y(),
                        delimiter,
                        pt.x(),
                        prec=self.settings.decimalDigits)
                else:
                    msg = '{:.{prec}f}{}{:.{prec}f}'.format(
                        pt.x(),
                        delimiter,
                        pt.y(),
                        prec=self.settings.decimalDigits)
            else:
                msg = 'POINT({:.{prec}f} {:.{prec}f})'.format(
                    pt.x(), pt.y(), prec=self.settings.decimalDigits)
        elif self.settings.captureProjIsMGRS():
            # Make sure the coordinate is transformed to EPSG:4326
            canvasCRS = self.canvas.mapSettings().destinationCrs()
            if canvasCRS == epsg4326:
                pt4326 = pt
            else:
                transform = QgsCoordinateTransform(canvasCRS, epsg4326,
                                                   QgsProject.instance())
                pt4326 = transform.transform(pt.x(), pt.y())
            try:
                msg = mgrs.toMgrs(pt4326.y(), pt4326.x())
            except Exception:
                # traceback.print_exc()
                msg = None
        elif self.settings.captureProjIsPlusCodes():
            # Make sure the coordinate is transformed to EPSG:4326
            canvasCRS = self.canvas.mapSettings().destinationCrs()
            if canvasCRS == epsg4326:
                pt4326 = pt
            else:
                transform = QgsCoordinateTransform(canvasCRS, epsg4326,
                                                   QgsProject.instance())
                pt4326 = transform.transform(pt.x(), pt.y())
            try:
                msg = olc.encode(pt4326.y(), pt4326.x(),
                                 self.settings.plusCodesLength)
            except Exception:
                msg = None
        elif self.settings.captureProjIsUTM():
            # Make sure the coordinate is transformed to EPSG:4326
            canvasCRS = self.canvas.mapSettings().destinationCrs()
            if canvasCRS == epsg4326:
                pt4326 = pt
            else:
                transform = QgsCoordinateTransform(canvasCRS, epsg4326,
                                                   QgsProject.instance())
                pt4326 = transform.transform(pt.x(), pt.y())
            msg = latLon2UtmString(pt4326.y(), pt4326.x(),
                                   settings.captureUtmPrecision)
            if msg == '':
                msg = None
        elif self.settings.captureProjIsGeohash():
            # Make sure the coordinate is transformed to EPSG:4326
            canvasCRS = self.canvas.mapSettings().destinationCrs()
            if canvasCRS == epsg4326:
                pt4326 = pt
            else:
                transform = QgsCoordinateTransform(canvasCRS, epsg4326,
                                                   QgsProject.instance())
                pt4326 = transform.transform(pt.x(), pt.y())
            msg = geohash.encode(pt4326.y(), pt4326.x(),
                                 settings.captureGeohashPrecision)
            if msg == '':
                msg = None
        elif self.settings.captureProjIsMaidenhead():
            # Make sure the coordinate is transformed to EPSG:4326
            canvasCRS = self.canvas.mapSettings().destinationCrs()
            if canvasCRS == epsg4326:
                pt4326 = pt
            else:
                transform = QgsCoordinateTransform(canvasCRS, epsg4326,
                                                   QgsProject.instance())
                pt4326 = transform.transform(pt.x(), pt.y())
            try:
                msg = maidenhead.toMaiden(
                    pt4326.y(),
                    pt4326.x(),
                    precision=settings.captureMaidenheadPrecision)
            except Exception:
                msg = None

        msg = '{}{}{}'.format(self.settings.capturePrefix, msg,
                              self.settings.captureSuffix)
        return msg
Example #42
0
    def testMasterLayerOrder(self):
        """ test master layer order"""
        prj = QgsProject.instance()
        prj.clear()
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                "memory")
        prj.addMapLayers([layer, layer2, layer3])

        prj.layerTreeRoot().setHasCustomLayerOrder(True)
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
        self.assertEqual(prj.mapThemeCollection().masterLayerOrder(),
                         [layer2, layer])

        prj.layerTreeRoot().setCustomLayerOrder([layer, layer2, layer3])
        # make some themes...
        theme1 = QgsMapThemeCollection.MapThemeRecord()
        theme1.setLayerRecords([
            QgsMapThemeCollection.MapThemeLayerRecord(layer3),
            QgsMapThemeCollection.MapThemeLayerRecord(layer)
        ])

        theme2 = QgsMapThemeCollection.MapThemeRecord()
        theme2.setLayerRecords([
            QgsMapThemeCollection.MapThemeLayerRecord(layer3),
            QgsMapThemeCollection.MapThemeLayerRecord(layer2),
            QgsMapThemeCollection.MapThemeLayerRecord(layer)
        ])

        theme3 = QgsMapThemeCollection.MapThemeRecord()
        theme3.setLayerRecords([
            QgsMapThemeCollection.MapThemeLayerRecord(layer2),
            QgsMapThemeCollection.MapThemeLayerRecord(layer)
        ])

        prj.mapThemeCollection().insert('theme1', theme1)
        prj.mapThemeCollection().insert('theme2', theme2)
        prj.mapThemeCollection().insert('theme3', theme3)

        #order of layers in theme should respect master order
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme1'),
            [layer, layer3])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme2'),
            [layer, layer2, layer3])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme3'),
            [layer, layer2])

        # also check ids!
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'),
            [layer.id(), layer3.id()])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'),
            [layer.id(), layer2.id(), layer3.id()])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'),
            [layer.id(), layer2.id()])

        # reset master order
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer3, layer])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme1'),
            [layer3, layer])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme2'),
            [layer2, layer3, layer])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme3'),
            [layer2, layer])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'),
            [layer3.id(), layer.id()])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'),
            [layer2.id(), layer3.id(), layer.id()])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'),
            [layer2.id(), layer.id()])

        # check that layers include those hidden in the layer tree
        canvas = QgsMapCanvas()
        bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas)
        root = prj.layerTreeRoot()
        layer_node = root.findLayer(layer2.id())
        layer_node.setItemVisibilityChecked(False)
        app.processEvents()
        prj.layerTreeRoot().setHasCustomLayerOrder(False)
        self.assertEqual(prj.mapThemeCollection().masterLayerOrder(),
                         [layer, layer2, layer3])

        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme1'),
            [layer, layer3])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme2'),
            [layer, layer2, layer3])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayers('theme3'),
            [layer, layer2])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'),
            [layer.id(), layer3.id()])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'),
            [layer.id(), layer2.id(), layer3.id()])
        self.assertEqual(
            prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'),
            [layer.id(), layer2.id()])
Example #43
0
 def setUp(self):
   self.project = QgsProject.instance()
Example #44
0
    def testMapTheme(self):
        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)
        self.assertEqual(canvas.width(), 600)
        self.assertEqual(canvas.height(), 400)

        layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
                               "layer", "memory")
        # add a polygon to layer
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer.dataProvider().addFeatures([f]))

        # create a style
        sym1 = QgsFillSymbol.createSimple({'color': '#ffb200'})
        renderer = QgsSingleSymbolRenderer(sym1)
        layer.setRenderer(renderer)

        canvas.setLayers([layer])
        canvas.setExtent(QgsRectangle(10, 30, 20, 35))
        canvas.show()

        # need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
        while not canvas.isDrawing():
            app.processEvents()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add some styles
        layer.styleManager().addStyleFromLayer('style1')
        sym2 = QgsFillSymbol.createSimple({'color': '#00b2ff'})
        renderer2 = QgsSingleSymbolRenderer(sym2)
        layer.setRenderer(renderer2)
        layer.styleManager().addStyleFromLayer('style2')

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

        layer.styleManager().setCurrentStyle('style1')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # OK, so all good with setting/rendering map styles
        # try setting canvas to a particular theme

        # make some themes...
        theme1 = QgsMapThemeCollection.MapThemeRecord()
        record1 = QgsMapThemeCollection.MapThemeLayerRecord(layer)
        record1.currentStyle = 'style1'
        record1.usingCurrentStyle = True
        theme1.setLayerRecords([record1])

        theme2 = QgsMapThemeCollection.MapThemeRecord()
        record2 = QgsMapThemeCollection.MapThemeLayerRecord(layer)
        record2.currentStyle = 'style2'
        record2.usingCurrentStyle = True
        theme2.setLayerRecords([record2])

        QgsProject.instance().mapThemeCollection().insert('theme1', theme1)
        QgsProject.instance().mapThemeCollection().insert('theme2', theme2)

        canvas.setTheme('theme2')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

        canvas.setTheme('theme1')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add another layer
        layer2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
                                "layer2", "memory")
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer2.dataProvider().addFeatures([f]))

        # create a style
        sym1 = QgsFillSymbol.createSimple({'color': '#b2ff00'})
        renderer = QgsSingleSymbolRenderer(sym1)
        layer2.setRenderer(renderer)

        # rerender canvas - should NOT show new layer
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))
        # test again - this time refresh all layers
        canvas.refreshAllLayers()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add layer 2 to theme1
        record3 = QgsMapThemeCollection.MapThemeLayerRecord(layer2)
        theme1.setLayerRecords([record3])
        QgsProject.instance().mapThemeCollection().update('theme1', theme1)

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

        # change the appearance of an active style
        layer2.styleManager().addStyleFromLayer('original')
        layer2.styleManager().addStyleFromLayer('style4')
        record3.currentStyle = 'style4'
        record3.usingCurrentStyle = True
        theme1.setLayerRecords([record3])
        QgsProject.instance().mapThemeCollection().update('theme1', theme1)

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

        layer2.styleManager().setCurrentStyle('style4')
        sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'})
        layer2.renderer().setSymbol(sym3)
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # try setting layers while a theme is in place
        canvas.setLayers([layer])
        canvas.refresh()

        # should be no change... setLayers should be ignored if canvas is following a theme!
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # setLayerStyleOverrides while theme is in place
        canvas.setLayerStyleOverrides({layer2.id(): 'original'})
        # should be no change... setLayerStyleOverrides should be ignored if canvas is following a theme!
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # clear theme
        canvas.setTheme('')
        canvas.refresh()
        canvas.waitWhileRendering()
        # should be different - we should now render project layers
        self.assertFalse(self.canvasImageCheck('theme4', 'theme4', canvas))
    def testAlign(self):
        p = QgsProject()
        l = QgsLayout(p)

        # add some items
        item1 = QgsLayoutItemPicture(l)
        item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item1)
        item2 = QgsLayoutItemPicture(l)
        item2.attemptMove(QgsLayoutPoint(6, 10, QgsUnitTypes.LayoutMillimeters))
        item2.attemptResize(QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item2)
        item3 = QgsLayoutItemPicture(l)
        item3.attemptMove(QgsLayoutPoint(0.8, 1.2, QgsUnitTypes.LayoutCentimeters))
        item3.attemptResize(QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
        l.addItem(item3)

        QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignLeft)
        self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(4, 10, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignHCenter)
        self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(8, 10, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignRight)
        self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 10, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignTop)
        self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignVCenter)
        self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 10, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 11.5, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignBottom)
        self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 15, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
    def accept(self):
        alg_parameters = []

        feedback = self.createFeedback()

        load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
        project = QgsProject.instance() if load_layers else None

        for row in range(self.mainWidget().tblParameters.rowCount()):
            col = 0
            parameters = {}
            for param in self.algorithm().parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
                    continue
                wrapper = self.mainWidget().wrappers[row][col]
                parameters[param.name()] = wrapper.value()
                if not param.checkValueIsAcceptable(wrapper.value()):
                    self.messageBar().pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
                        param.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return
                col += 1
            count_visible_outputs = 0
            for out in self.algorithm().destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue

                count_visible_outputs += 1
                widget = self.mainWidget().tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if out.checkValueIsAcceptable(text):
                    if isinstance(out, (QgsProcessingParameterRasterDestination,
                                        QgsProcessingParameterFeatureSink)):
                        # load rasters and sinks on completion
                        parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, project)
                    else:
                        parameters[out.name()] = text
                    col += 1
                else:
                    self.messageBar().pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
                        out.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return

            alg_parameters.append(parameters)

        with OverrideCursor(Qt.WaitCursor):

            self.mainWidget().setEnabled(False)
            self.cancelButton().setEnabled(True)

            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.showLog()
                self.repaint()
            except:
                pass

            start_time = time.time()

            algorithm_results = []
            for count, parameters in enumerate(alg_parameters):
                if feedback.isCanceled():
                    break
                self.setProgressText(QCoreApplication.translate('BatchAlgorithmDialog', '\nProcessing algorithm {0}/{1}…').format(count + 1, len(alg_parameters)))
                self.setInfo(self.tr('<b>Algorithm {0} starting&hellip;</b>').format(self.algorithm().displayName()), escapeHtml=False)

                parameters = self.algorithm().preprocessParameters(parameters)

                feedback.pushInfo(self.tr('Input parameters:'))
                feedback.pushCommandInfo(pformat(parameters))
                feedback.pushInfo('')

                # important - we create a new context for each iteration
                # this avoids holding onto resources and layers from earlier iterations,
                # and allows batch processing of many more items then is possible
                # if we hold on to these layers
                context = dataobjects.createContext(feedback)

                alg_start_time = time.time()
                ret, results = execute(self.algorithm(), parameters, context, feedback)
                if ret:
                    self.setInfo(QCoreApplication.translate('BatchAlgorithmDialog', 'Algorithm {0} correctly executed…').format(self.algorithm().displayName()), escapeHtml=False)
                    feedback.setProgress(100)
                    feedback.pushInfo(
                        self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
                    feedback.pushInfo(self.tr('Results:'))
                    feedback.pushCommandInfo(pformat(results))
                    feedback.pushInfo('')
                    algorithm_results.append(results)
                else:
                    break

                handleAlgorithmResults(self.algorithm(), context, feedback, False)

        feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))

        self.finish(algorithm_results)
        self.cancelButton().setEnabled(False)
    def test_getcapabilities(self):
        project = self._project_path
        assert os.path.exists(project), "Project file not found: " + project

        # without cache
        query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities')
        header, body = self._execute_request(query_string)
        doc = QDomDocument("wms_getcapabilities_130.xml")
        doc.setContent(body)
        # with cache
        header, body = self._execute_request(query_string)

        # without cache
        query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.1.1&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities')
        header, body = self._execute_request(query_string)
        # with cache
        header, body = self._execute_request(query_string)

        # without cache
        query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.1.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities')
        header, body = self._execute_request(query_string)
        # with cache
        header, body = self._execute_request(query_string)

        # without cache
        query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities')
        header, body = self._execute_request(query_string)
        # with cache
        header, body = self._execute_request(query_string)

        # without cache
        query_string = '?MAP=%s&SERVICE=WCS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities')
        header, body = self._execute_request(query_string)
        # with cache
        header, body = self._execute_request(query_string)

        # without cache
        query_string = '?MAP=%s&SERVICE=WMTS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities')
        header, body = self._execute_request(query_string)
        # with cache
        header, body = self._execute_request(query_string)

        filelist = [f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml")]
        self.assertEqual(len(filelist), 6, 'Not enough file in cache')

        cacheManager = self._server_iface.cacheManager()

        self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True')

        filelist = [f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml")]
        self.assertEqual(len(filelist), 0, 'All files in cache are not deleted ')

        prj = QgsProject()
        prj.read(project)

        query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities')
        request = QgsBufferServerRequest(query_string, QgsServerRequest.GetMethod, {}, None)

        accessControls = self._server_iface.accessControls()

        cDoc = QDomDocument("wms_getcapabilities_130.xml")
        self.assertFalse(cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is not None')

        self.assertTrue(cacheManager.setCachedDocument(doc, prj, request, accessControls), 'setCachedDocument false')

        self.assertTrue(cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is None')
        self.assertEqual(doc.documentElement().tagName(), cDoc.documentElement().tagName(), 'cachedDocument not equal to provide document')

        self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True')
    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')
Example #49
0
    def testCombo(self):
        project = QgsProject()
        layout = QgsPrintLayout(project)

        combo = QgsLayoutItemComboBox(None)
        spy = QSignalSpy(combo.itemChanged)
        self.assertEqual(combo.count(), 0)
        self.assertIsNone(combo.currentLayout())
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(combo.currentIndex(), -1)
        self.assertEqual(len(spy), 0)

        combo.setCurrentLayout(layout)
        self.assertEqual(combo.currentIndex(), -1)
        self.assertEqual(len(spy), 0)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.count(), 0)
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 0)

        combo.setAllowEmptyItem(True)
        self.assertEqual(combo.currentIndex(), 0)
        self.assertEqual(combo.count(), 1)
        self.assertEqual(len(spy), 2)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 2)
        self.assertEqual(combo.currentIndex(), 0)
        self.assertEqual(combo.itemText(0), '')

        combo.setAllowEmptyItem(False)
        self.assertEqual(combo.currentIndex(), -1)
        self.assertEqual(combo.count(), 0)
        self.assertEqual(len(spy), 4)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertIsNone(combo.currentItem())
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 4)
        self.assertEqual(combo.currentIndex(), -1)

        label1 = QgsLayoutItemLabel(layout)
        label1.setId('llll')
        # don't add to layout yet!
        combo.setItem(label1)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 4)
        self.assertEqual(combo.currentIndex(), -1)
        combo.setAllowEmptyItem(True)
        combo.setItem(label1)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 6)
        self.assertEqual(combo.currentIndex(), 0)
        combo.setAllowEmptyItem(False)

        layout.addLayoutItem(label1)
        self.assertEqual(combo.currentIndex(), 0)
        self.assertEqual(combo.count(), 1)
        self.assertEqual(combo.itemText(0), 'llll')
        self.assertEqual(len(spy), 10)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(combo.item(0), label1)
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(1))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 11)
        self.assertEqual(combo.currentIndex(), -1)
        combo.setItem(label1)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(len(spy), 12)
        self.assertEqual(combo.currentIndex(), 0)

        combo.setAllowEmptyItem(True)
        self.assertEqual(combo.currentIndex(), 1)
        self.assertEqual(combo.count(), 2)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'llll')
        self.assertEqual(len(spy), 13)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.currentItem(), label1)
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label1)
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(2))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 14)
        self.assertEqual(combo.currentIndex(), 0)
        combo.setItem(label1)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(len(spy), 15)
        self.assertEqual(combo.currentIndex(), 1)

        label2 = QgsLayoutItemLabel(layout)
        label2.setId('mmmm')
        layout.addLayoutItem(label2)
        self.assertEqual(combo.currentIndex(), 1)
        self.assertEqual(combo.count(), 3)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'llll')
        self.assertEqual(combo.itemText(2), 'mmmm')
        self.assertEqual(len(spy), 15)
        self.assertEqual(combo.currentLayout(), layout)
        self.assertEqual(combo.currentItem(), label1)
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label1)
        self.assertEqual(combo.item(2), label2)
        self.assertIsNone(combo.item(-1))
        self.assertIsNone(combo.item(3))
        combo.setItem(None)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(len(spy), 16)
        self.assertEqual(combo.currentIndex(), 0)
        combo.setItem(label1)
        self.assertEqual(combo.currentItem(), label1)
        self.assertEqual(len(spy), 17)
        self.assertEqual(combo.currentIndex(), 1)

        label1.setId('nnnn')
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'mmmm')
        self.assertEqual(combo.itemText(2), 'nnnn')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.item(2), label1)
        self.assertEqual(combo.currentItem(), label1)

        combo.setAllowEmptyItem(False)
        self.assertEqual(combo.itemText(0), 'mmmm')
        self.assertEqual(combo.itemText(1), 'nnnn')
        self.assertEqual(combo.item(0), label2)
        self.assertEqual(combo.item(1), label1)
        self.assertEqual(combo.currentItem(), label1)

        combo.setItem(label2)
        label2.setId('oooo')
        self.assertEqual(combo.itemText(0), 'nnnn')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertEqual(combo.item(0), label1)
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.currentItem(), label2)

        combo.setAllowEmptyItem(True)
        layout.removeLayoutItem(label1)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.currentItem(), label2)

        map = QgsLayoutItemMap(layout)
        layout.addLayoutItem(map)
        map.setId('pppp')
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertEqual(combo.itemText(2), 'pppp')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertEqual(combo.item(2), map)
        self.assertEqual(combo.currentItem(), label2)

        combo.setItemType(QgsLayoutItemRegistry.LayoutMap)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'pppp')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), map)
        self.assertIsNone(combo.currentItem())

        combo.setItemType(QgsLayoutItemRegistry.LayoutLabel)
        self.assertEqual(combo.itemText(0), '')
        self.assertEqual(combo.itemText(1), 'oooo')
        self.assertIsNone(combo.item(0))
        self.assertEqual(combo.item(1), label2)
        self.assertIsNone(combo.currentItem())

        combo.setItemType(QgsLayoutItemRegistry.LayoutAttributeTable)
        self.assertEqual(combo.itemText(0), '')
        self.assertIsNone(combo.item(0))
        self.assertIsNone(combo.currentItem())

        combo.setAllowEmptyItem(False)
        self.assertEqual(combo.count(), 0)
        self.assertIsNone(combo.currentItem())
        self.assertEqual(combo.currentIndex(), -1)
    def testDistribute(self):
        p = QgsProject()
        l = QgsLayout(p)

        # add some items
        item1 = QgsLayoutItemPicture(l)
        item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item1)
        item2 = QgsLayoutItemPicture(l)
        item2.attemptMove(QgsLayoutPoint(7, 10, QgsUnitTypes.LayoutMillimeters))
        item2.attemptResize(QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item2)
        item3 = QgsLayoutItemPicture(l)
        item3.attemptMove(QgsLayoutPoint(0.8, 1.2, QgsUnitTypes.LayoutCentimeters))
        item3.attemptResize(QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
        l.addItem(item3)

        QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeLeft)
        self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3)
        self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3)
        self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeHCenter)
        self.assertAlmostEqual(item1.positionWithUnits().x(), 5.0, 3)
        self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3)
        self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3)
        self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeRight)
        self.assertAlmostEqual(item1.positionWithUnits().x(), 3.0, 3)
        self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3)
        self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3)
        self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeTop)
        self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3)
        self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item2.positionWithUnits().y(), 10.0, 3)
        self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3)
        self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeVCenter)
        self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3)
        self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item2.positionWithUnits().y(), 12.5, 3)
        self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3)
        self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))

        QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeBottom)
        self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3)
        self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item2.positionWithUnits().y(), 15.0, 3)
        self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters)
        self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters))
        self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3)
        self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
Example #51
0
 def activeLayer(self):
     """Get pointer to the active layer (layer selected in the legend)"""
     myLayers = QgsProject.instance().mapLayers()
     for myItem in myLayers:
         return myLayers[myItem]
Example #52
0
class TestQgsLayerTreeView(unittest.TestCase):
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        # setup a dummy project
        self.project = QgsProject()
        self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1",
                                    "memory")
        self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                     "memory")
        self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                     "memory")
        self.layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                     "memory")
        self.layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5",
                                     "memory")
        self.project.addMapLayers([self.layer, self.layer2, self.layer3])
        self.model = QgsLayerTreeModel(self.project.layerTreeRoot())

    def nodeOrder(self, group):
        nodeorder = []
        layerTree = QgsLayerTree()
        for node in group:
            if QgsLayerTree.isGroup(node):
                groupname = node.name()
                nodeorder.append(groupname)
                for child in self.nodeOrder(node.children()):
                    nodeorder.append(groupname + '-' + child)
            elif QgsLayerTree.isLayer(node):
                nodeorder.append(node.layer().name())
        return nodeorder

    def testSetModel(self):
        view = QgsLayerTreeView()

        # should not work
        string_list_model = QStringListModel()
        view.setModel(string_list_model)
        self.assertFalse(view.model())

        # should work
        view.setModel(self.model)
        self.assertEqual(view.model(), self.model)

    def testSetCurrentLayer(self):
        view = QgsLayerTreeView()
        view.setModel(self.model)
        current_layer_changed_spy = QSignalSpy(view.currentLayerChanged)
        self.assertFalse(view.currentLayer())
        view.setCurrentLayer(self.layer3)
        self.assertEqual(view.currentLayer(), self.layer3)
        self.assertEqual(len(current_layer_changed_spy), 1)
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentLayer(), self.layer)
        self.assertEqual(len(current_layer_changed_spy), 2)
        view.setCurrentLayer(None)
        self.assertFalse(view.currentLayer())
        self.assertEqual(len(current_layer_changed_spy), 3)

    def testDefaultActions(self):
        view = QgsLayerTreeView()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)

        # show in overview action
        view.setCurrentLayer(self.layer)
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         False)
        show_in_overview = actions.actionShowInOverview()
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         True)
        show_in_overview.trigger()
        self.assertEqual(view.currentNode().customProperty('overview', 0),
                         False)

    def testMoveOutOfGroupActionLayer(self):
        """Test move out of group action on layer"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        view.setCurrentLayer(self.layer5)
        moveOutOfGroup = actions.actionMoveOutOfGroup()
        moveOutOfGroup.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                self.layer5.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
            ])

    def testMoveToTopActionLayer(self):
        """Test move to top action on layer"""
        view = QgsLayerTreeView()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer, self.layer2, self.layer3])
        view.setCurrentLayer(self.layer3)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer3, self.layer, self.layer2])

    def testMoveToTopActionGroup(self):
        """Test move to top action on group"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        nodeLayerIndex = self.model.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
            ])

    def testMoveToTopActionEmbeddedGroup(self):
        """Test move to top action on embeddedgroup layer"""
        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer4.name(),
                groupname + '-' + self.layer5.name(),
            ])

        view.setCurrentLayer(self.layer5)
        movetotop = actions.actionMoveToTop()
        movetotop.trigger()
        self.assertEqual(
            self.nodeOrder(self.project.layerTreeRoot().children()), [
                self.layer.name(),
                self.layer2.name(),
                self.layer3.name(),
                groupname,
                groupname + '-' + self.layer5.name(),
                groupname + '-' + self.layer4.name(),
            ])
Example #53
0
    def testReadWriteXml(self):
        p = QgsProject()
        l = QgsPrintLayout(p)
        l.setName('my layout')
        l.setUnits(QgsUnitTypes.LayoutInches)
        collection = l.pageCollection()

        # add a page
        page = QgsLayoutItemPage(l)
        page.setPageSize('A6')
        collection.addPage(page)

        grid = l.gridSettings()
        grid.setResolution(QgsLayoutMeasurement(5, QgsUnitTypes.LayoutPoints))

        g1 = QgsLayoutGuide(
            Qt.Horizontal,
            QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters),
            l.pageCollection().page(0))
        l.guides().addGuide(g1)

        snapper = l.snapper()
        snapper.setSnapTolerance(7)

        # add some items
        item1 = QgsLayoutItemMap(l)
        item1.setId('xxyyxx')
        l.addItem(item1)
        item2 = QgsLayoutItemMap(l)
        item2.setId('zzyyzz')
        l.addItem(item2)

        l.setReferenceMap(item2)

        doc = QDomDocument("testdoc")
        elem = l.writeXml(doc, QgsReadWriteContext())

        l2 = QgsPrintLayout(p)
        self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext()))
        self.assertEqual(l2.name(), 'my layout')
        self.assertEqual(l2.units(), QgsUnitTypes.LayoutInches)

        collection2 = l2.pageCollection()
        self.assertEqual(collection2.pageCount(), 1)
        self.assertAlmostEqual(collection2.page(0).pageSize().width(), 105, 4)
        self.assertEqual(collection2.page(0).pageSize().height(), 148)
        self.assertEqual(l2.gridSettings().resolution().length(), 5.0)
        self.assertEqual(l2.gridSettings().resolution().units(),
                         QgsUnitTypes.LayoutPoints)
        self.assertEqual(l2.guides().guidesOnPage(0)[0].orientation(),
                         Qt.Horizontal)
        self.assertEqual(l2.guides().guidesOnPage(0)[0].position().length(),
                         5.0)
        self.assertEqual(l2.guides().guidesOnPage(0)[0].position().units(),
                         QgsUnitTypes.LayoutCentimeters)
        self.assertEqual(l2.snapper().snapTolerance(), 7)

        # check restored items
        new_item1 = l2.itemByUuid(item1.uuid())
        self.assertTrue(new_item1)
        self.assertEqual(new_item1.id(), 'xxyyxx')
        new_item2 = l2.itemByUuid(item2.uuid())
        self.assertTrue(new_item2)
        self.assertEqual(new_item2.id(), 'zzyyzz')
        self.assertEqual(l2.referenceMap().id(), 'zzyyzz')
    def addFeature(self):
        text = self.lineEdit.text().strip()
        if text == "":
            return
        layer = self.iface.activeLayer()
        if layer is None:
            return
        try:
            if (self.inputProjection == 0) or (text[0] == '{'):
                # If this is GeoJson it does not matter what inputProjection is
                if text[0] == '{':  # This may be a GeoJSON point
                    codec = QTextCodec.codecForName("UTF-8")
                    fields = QgsJsonUtils.stringToFields(text, codec)
                    fet = QgsJsonUtils.stringToFeatureList(text, fields, codec)
                    if (len(fet) == 0) or not fet[0].isValid():
                        raise ValueError('Invalid Coordinates')

                    geom = fet[0].geometry()
                    if geom.isEmpty() or (geom.wkbType() != QgsWkbTypes.Point):
                        raise ValueError('Invalid GeoJSON Geometry')
                    pt = geom.asPoint()
                    lat = pt.y()
                    lon = pt.x()
                elif re.search(r'POINT\(', text) is not None:
                    m = re.findall(r'POINT\(\s*([+-]?\d*\.?\d*)\s+([+-]?\d*\.?\d*)', text)
                    if len(m) != 1:
                        raise ValueError('Invalid Coordinates')
                    lon = float(m[0][0])
                    lat = float(m[0][1])
                else:
                    lat, lon = parseDMSString(text, self.inputXYOrder)
                srcCrs = epsg4326
            elif self.inputProjection == 1:
                # This is an MGRS coordinate
                text = re.sub(r'\s+', '', text)  # Remove all white space
                lat, lon = mgrs.toWgs(text)
                srcCrs = epsg4326
            elif self.inputProjection == 4:
                text = text.strip()
                coord = olc.decode(text)
                lat = coord.latitudeCenter
                lon = coord.longitudeCenter
                srcCrs = epsg4326
            elif self.inputProjection == 5:
                text = text.strip()
                pt = utm2Point(text, epsg4326)
                lat = pt.y()
                lon = pt.x()
                srcCrs = epsg4326
            else:  # Is either the project or custom CRS
                if re.search(r'POINT\(', text) is None:
                    coords = re.split(r'[\s,;:]+', text, 1)
                    if len(coords) < 2:
                        raise ValueError('Invalid Coordinates')
                    if self.inputXYOrder == 0:  # Y, X Order
                        lat = float(coords[0])
                        lon = float(coords[1])
                    else:
                        lon = float(coords[0])
                        lat = float(coords[1])
                else:
                    m = re.findall(r'POINT\(\s*([+-]?\d*\.?\d*)\s+([+-]?\d*\.?\d*)', text)
                    if len(m) != 1:
                        raise ValueError('Invalid Coordinates')
                    lon = float(m[0][0])
                    lat = float(m[0][1])
                if self.inputProjection == 2:  # Project CRS
                    srcCrs = self.canvas.mapSettings().destinationCrs()
                else:
                    srcCrs = QgsCoordinateReferenceSystem(self.inputCustomCRS)
        except Exception:
            # traceback.print_exc()
            self.iface.messageBar().pushMessage("", "Invalid Coordinate", level=Qgis.Warning, duration=2)
            return
        self.lineEdit.clear()
        caps = layer.dataProvider().capabilities()
        if caps & QgsVectorDataProvider.AddFeatures:
            destCRS = layer.crs()  # Get the CRS of the layer we are adding a point toWgs
            transform = QgsCoordinateTransform(srcCrs, destCRS, QgsProject.instance())
            # Transform the input coordinate projection to the layer CRS
            x, y = transform.transform(float(lon), float(lat))
            geom = QgsGeometry.fromPointXY(QgsPointXY(x, y))
            feat = QgsVectorLayerUtils.createFeature(layer, geom, {}, layer.createExpressionContext() )
            if layer.fields().count() == 0:
                layer.addFeature(feat)
                self.lltools.zoomTo(srcCrs, lat, lon)
            else:
                if self.iface.openFeatureForm(layer, feat):
                    layer.addFeature(feat)
                    self.lltools.zoomTo(srcCrs, lat, lon)
Example #55
0
    def testAddItemsFromXml(self):
        p = QgsProject()
        l = QgsLayout(p)

        # add some items
        item1 = QgsLayoutItemLabel(l)
        item1.setId('xxyyxx')
        item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        item1.attemptResize(
            QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item1)
        item2 = QgsLayoutItemLabel(l)
        item2.setId('zzyyzz')
        item2.attemptMove(
            QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters))
        item2.attemptResize(
            QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
        l.addItem(item2)

        doc = QDomDocument("testdoc")
        # store in xml
        elem = l.writeXml(doc, QgsReadWriteContext())

        l2 = QgsLayout(p)
        new_items = l2.addItemsFromXml(elem, doc, QgsReadWriteContext())
        self.assertEqual(len(new_items), 2)
        items = l2.items()
        self.assertTrue([i for i in items if i.id() == 'xxyyxx'])
        self.assertTrue([i for i in items if i.id() == 'zzyyzz'])
        self.assertTrue(new_items[0] in l2.items())
        self.assertTrue(new_items[1] in l2.items())
        new_item1 = [i for i in items if i.id() == 'xxyyxx'][0]
        new_item2 = [i for i in items if i.id() == 'zzyyzz'][0]
        self.assertEqual(new_item1.positionWithUnits(),
                         QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(new_item1.sizeWithUnits(),
                         QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(
            new_item2.positionWithUnits(),
            QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(
            new_item2.sizeWithUnits(),
            QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))

        # test with a group
        group = QgsLayoutItemGroup(l)
        group.addItem(item1)
        group.addItem(item2)
        l.addLayoutItem(group)
        elem = l.writeXml(doc, QgsReadWriteContext())

        l3 = QgsLayout(p)
        new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext())
        self.assertEqual(len(new_items), 3)
        items = l3.items()
        self.assertTrue([i for i in items if i.id() == 'xxyyxx'])
        self.assertTrue([i for i in items if i.id() == 'zzyyzz'])
        self.assertTrue(new_items[0] in l3.items())
        self.assertTrue(new_items[1] in l3.items())
        self.assertTrue(new_items[2] in l3.items())

        # f*** you sip, I'll just manually cast
        new_group = sip.cast(l3.itemByUuid(group.uuid()), QgsLayoutItemGroup)
        self.assertIsNotNone(new_group)
        other_items = [i for i in new_items if i.type() != new_group.type()]
        self.assertCountEqual(new_group.items(), other_items)

        # test restoring at set position
        l3 = QgsLayout(p)
        new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext(),
                                       QPointF(10, 30))
        self.assertEqual(len(new_items), 3)
        items = l3.items()
        new_item1 = [i for i in items if i.id() == 'xxyyxx'][0]
        new_item2 = [i for i in items if i.id() == 'zzyyzz'][0]
        self.assertEqual(
            new_item1.positionWithUnits(),
            QgsLayoutPoint(10, 30, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(new_item1.sizeWithUnits(),
                         QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(
            new_item2.positionWithUnits(),
            QgsLayoutPoint(2.0, 4.0, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(
            new_item2.sizeWithUnits(),
            QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))

        # paste in place
        l4 = QgsLayout(p)
        page = QgsLayoutItemPage(l)
        page.setPageSize('A3')
        l4.pageCollection().addPage(page)
        page = QgsLayoutItemPage(l)
        page.setPageSize('A6')
        l4.pageCollection().addPage(page)

        new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(),
                                       QPointF(10, 30), True)
        self.assertEqual(len(new_items), 3)
        new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0]
        new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0]
        self.assertEqual(new_item1.pagePositionWithUnits(),
                         QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(new_item1.sizeWithUnits(),
                         QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(new_item1.page(), 0)
        self.assertEqual(
            new_item2.pagePositionWithUnits(),
            QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(
            new_item2.sizeWithUnits(),
            QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(new_item2.page(), 0)

        # paste in place, page 2
        new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(),
                                       QPointF(10, 550), True)
        self.assertEqual(len(new_items), 3)
        new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0]
        new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0]
        self.assertEqual(new_item1.pagePositionWithUnits(),
                         QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(new_item1.page(), 1)
        self.assertEqual(new_item1.sizeWithUnits(),
                         QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        self.assertEqual(
            new_item2.pagePositionWithUnits(),
            QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters))
        self.assertEqual(new_item2.page(), 1)
        self.assertEqual(
            new_item2.sizeWithUnits(),
            QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
Example #56
0
    def testStacking(self):
        p = QgsProject()
        l = QgsLayout(p)

        # add some items
        item1 = QgsLayoutItemMap(l)
        l.addLayoutItem(item1)
        item2 = QgsLayoutItemMap(l)
        l.addLayoutItem(item2)
        item3 = QgsLayoutItemMap(l)
        l.addLayoutItem(item3)

        self.assertEqual(item1.zValue(), 1)
        self.assertEqual(item2.zValue(), 2)
        self.assertEqual(item3.zValue(), 3)

        # no effect interactions
        self.assertFalse(l.raiseItem(None))
        self.assertFalse(l.lowerItem(None))
        self.assertFalse(l.moveItemToTop(None))
        self.assertFalse(l.moveItemToBottom(None))

        self.assertEqual(item1.zValue(), 1)
        self.assertEqual(item2.zValue(), 2)
        self.assertEqual(item3.zValue(), 3)

        # raising
        self.assertFalse(l.raiseItem(item3))
        self.assertEqual(item1.zValue(), 1)
        self.assertEqual(item2.zValue(), 2)
        self.assertEqual(item3.zValue(), 3)

        self.assertTrue(l.raiseItem(item2))
        self.assertEqual(item1.zValue(), 1)
        self.assertEqual(item2.zValue(), 3)
        self.assertEqual(item3.zValue(), 2)

        self.assertFalse(l.raiseItem(item2))
        self.assertEqual(item1.zValue(), 1)
        self.assertEqual(item2.zValue(), 3)
        self.assertEqual(item3.zValue(), 2)

        self.assertTrue(l.raiseItem(item1))
        self.assertEqual(item1.zValue(), 2)
        self.assertEqual(item2.zValue(), 3)
        self.assertEqual(item3.zValue(), 1)

        # lower
        self.assertFalse(l.lowerItem(item3))
        self.assertEqual(item1.zValue(), 2)
        self.assertEqual(item2.zValue(), 3)
        self.assertEqual(item3.zValue(), 1)

        self.assertTrue(l.lowerItem(item2))
        self.assertEqual(item1.zValue(), 3)
        self.assertEqual(item2.zValue(), 2)
        self.assertEqual(item3.zValue(), 1)

        self.assertTrue(l.lowerItem(item2))
        self.assertEqual(item1.zValue(), 3)
        self.assertEqual(item2.zValue(), 1)
        self.assertEqual(item3.zValue(), 2)

        # raise to top
        self.assertFalse(l.moveItemToTop(item1))
        self.assertEqual(item1.zValue(), 3)
        self.assertEqual(item2.zValue(), 1)
        self.assertEqual(item3.zValue(), 2)

        self.assertTrue(l.moveItemToTop(item3))
        self.assertEqual(item1.zValue(), 2)
        self.assertEqual(item2.zValue(), 1)
        self.assertEqual(item3.zValue(), 3)

        self.assertTrue(l.moveItemToTop(item2))
        self.assertEqual(item1.zValue(), 1)
        self.assertEqual(item2.zValue(), 3)
        self.assertEqual(item3.zValue(), 2)

        # move to bottom
        self.assertFalse(l.moveItemToBottom(item1))
        self.assertEqual(item1.zValue(), 1)
        self.assertEqual(item2.zValue(), 3)
        self.assertEqual(item3.zValue(), 2)

        self.assertTrue(l.moveItemToBottom(item3))
        self.assertEqual(item1.zValue(), 2)
        self.assertEqual(item2.zValue(), 3)
        self.assertEqual(item3.zValue(), 1)

        self.assertTrue(l.moveItemToBottom(item2))
        self.assertEqual(item1.zValue(), 3)
        self.assertEqual(item2.zValue(), 1)
        self.assertEqual(item3.zValue(), 2)
    def testSnapPointsToItems(self):
        p = QgsProject()
        l = QgsLayout(p)
        page = QgsLayoutItemPage(l)
        page.setPageSize('A4')
        #l.pageCollection().addPage(page)
        s = QgsLayoutSnapper(l)
        guides = l.guides()

        s.setSnapToItems(True)
        s.setSnapTolerance(1)

        # no items
        point, snapped = s.snapPointsToItems([0.5], Qt.Horizontal, 1, [])
        self.assertFalse(snapped)

        line = QGraphicsLineItem()
        line.setVisible(True)
        point, snapped = s.snapPointsToItems([0.5], Qt.Horizontal, 1, [], line)
        self.assertFalse(line.isVisible())

        guides.addGuide(
            QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(1), page))

        # add an item
        item1 = QgsLayoutItemMap(l)
        item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        item1.attemptResize(
            QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item1)

        point, snapped = s.snapPointsToItems([3.5], Qt.Horizontal, 1, [], line)
        self.assertTrue(snapped)
        self.assertEqual(point, 0.5)
        self.assertTrue(line.isVisible())
        point, snapped = s.snapPointsToItems([4.5], Qt.Horizontal, 1, [])
        self.assertTrue(snapped)
        self.assertEqual(point, -0.5)
        point, snapped = s.snapPointsToItems([4.6, 4.5], Qt.Horizontal, 1, [])
        self.assertTrue(snapped)
        self.assertEqual(point, -0.5)
        point, snapped = s.snapPointsToItems([4.6, 4.5, 3.7], Qt.Horizontal, 1,
                                             [])
        self.assertTrue(snapped)
        self.assertAlmostEqual(point, 0.3, 5)

        # ignoring item
        point, snapped = s.snapPointsToItems([4.5], Qt.Horizontal, 1, [item1])
        self.assertFalse(snapped)

        # outside tolerance
        point, snapped = s.snapPointsToItems([5.5], Qt.Horizontal, 1, [], line)
        self.assertFalse(snapped)
        self.assertFalse(line.isVisible())

        # snap to center
        point, snapped = s.snapPointsToItems([12.5], Qt.Horizontal, 1, [])
        self.assertTrue(snapped)
        self.assertEqual(point, 0.5)

        # snap to right
        point, snapped = s.snapPointsToItems([22.5], Qt.Horizontal, 1, [])
        self.assertTrue(snapped)
        self.assertEqual(point, -0.5)

        #snap to top
        point, snapped = s.snapPointsToItems([7.5], Qt.Vertical, 1, [], line)
        self.assertTrue(snapped)
        self.assertEqual(point, 0.5)
        self.assertTrue(line.isVisible())
        point, snapped = s.snapPointsToItems([8.5], Qt.Vertical, 1, [])
        self.assertTrue(snapped)
        self.assertEqual(point, -0.5)

        # outside tolerance
        point, snapped = s.snapPointsToItems([5.5], Qt.Vertical, 1, [], line)
        self.assertFalse(snapped)
        self.assertFalse(line.isVisible())

        # snap to center
        point, snapped = s.snapPointsToItems([13.5], Qt.Vertical, 1, [])
        self.assertTrue(snapped)
        self.assertEqual(point, 0.5)

        # snap to bottom
        point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 1, [])
        self.assertTrue(snapped)
        self.assertEqual(point, -0.5)

        # snapping off
        s.setSnapToItems(False)
        line.setVisible(True)
        point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 1, [], line)
        self.assertFalse(snapped)
        self.assertFalse(line.isVisible())

        # with different pixel scale
        s.setSnapToItems(True)
        point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 3, [])
        self.assertFalse(snapped)
Example #58
0
    def testSaveLoadTemplate(self):
        tmpfile = os.path.join(self.basetestpath, 'testTemplate.qpt')

        p = QgsProject()
        l = QgsLayout(p)
        l.initializeDefaults()

        # add some items
        item1 = QgsLayoutItemLabel(l)
        item1.setId('xxyyxx')
        item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters))
        item1.attemptResize(
            QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item1)
        item2 = QgsLayoutItemLabel(l)
        item2.setId('zzyyzz')
        item2.attemptMove(
            QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters))
        item2.attemptResize(
            QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
        l.addItem(item2)

        # multiframe
        multiframe1 = QgsLayoutItemHtml(l)
        multiframe1.setHtml('mf1')
        l.addMultiFrame(multiframe1)
        frame1 = QgsLayoutFrame(l, multiframe1)
        frame1.setId('frame1')
        frame1.attemptMove(QgsLayoutPoint(4, 8,
                                          QgsUnitTypes.LayoutMillimeters))
        frame1.attemptResize(
            QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters))
        multiframe1.addFrame(frame1)

        multiframe2 = QgsLayoutItemHtml(l)
        multiframe2.setHtml('mf2')
        l.addMultiFrame(multiframe2)
        frame2 = QgsLayoutFrame(l, multiframe2)
        frame2.setId('frame2')
        frame2.attemptMove(
            QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters))
        frame2.attemptResize(
            QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
        multiframe2.addFrame(frame2)

        uuids = {
            item1.uuid(),
            item2.uuid(),
            frame1.uuid(),
            frame2.uuid(),
            multiframe1.uuid(),
            multiframe2.uuid()
        }
        original_uuids = {
            item1.uuid(),
            item2.uuid(),
            frame1.uuid(),
            frame2.uuid()
        }

        self.assertTrue(l.saveAsTemplate(tmpfile, QgsReadWriteContext()))

        l2 = QgsLayout(p)
        with open(tmpfile) as f:
            template_content = f.read()
        doc = QDomDocument()
        doc.setContent(template_content)

        # adding to existing items
        new_items, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False)
        self.assertTrue(ok)
        self.assertEqual(len(new_items), 4)
        items = l2.items()
        multiframes = l2.multiFrames()
        self.assertEqual(len(multiframes), 2)
        self.assertTrue([i for i in items if i.id() == 'xxyyxx'])
        self.assertTrue([i for i in items if i.id() == 'zzyyzz'])
        self.assertTrue([i for i in items if i.id() == 'frame1'])
        self.assertTrue([i for i in items if i.id() == 'frame2'])
        self.assertTrue([i for i in multiframes if i.html() == 'mf1'])
        self.assertTrue([i for i in multiframes if i.html() == 'mf2'])
        self.assertTrue(new_items[0] in l2.items())
        self.assertTrue(new_items[1] in l2.items())
        self.assertTrue(new_items[2] in l2.items())
        self.assertTrue(new_items[3] in l2.items())

        # double check that new items have a unique uid
        self.assertNotIn(new_items[0].uuid(), uuids)
        uuids.add(new_items[0].uuid())
        self.assertNotIn(new_items[1].uuid(), uuids)
        uuids.add(new_items[1].uuid())
        self.assertNotIn(new_items[2].uuid(), uuids)
        uuids.add(new_items[2].uuid())
        self.assertNotIn(new_items[3].uuid(), uuids)
        uuids.add(new_items[3].uuid())

        self.assertNotIn(
            multiframes[0].uuid(),
            [multiframe1.uuid(), multiframe2.uuid()])
        self.assertNotIn(
            multiframes[1].uuid(),
            [multiframe1.uuid(), multiframe2.uuid()])
        new_multiframe1 = [i for i in multiframes if i.html() == 'mf1'][0]
        self.assertEqual(new_multiframe1.layout(), l2)
        new_multiframe2 = [i for i in multiframes if i.html() == 'mf2'][0]
        self.assertEqual(new_multiframe2.layout(), l2)
        new_frame1 = sip.cast([i for i in items if i.id() == 'frame1'][0],
                              QgsLayoutFrame)
        new_frame2 = sip.cast([i for i in items if i.id() == 'frame2'][0],
                              QgsLayoutFrame)
        self.assertEqual(new_frame1.multiFrame(), new_multiframe1)
        self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid())
        self.assertEqual(new_frame2.multiFrame(), new_multiframe2)
        self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid())

        # adding to existing items
        new_items2, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False)
        self.assertTrue(ok)
        self.assertEqual(len(new_items2), 4)
        items = l2.items()
        self.assertEqual(len(items), 8)
        multiframes2 = l2.multiFrames()
        self.assertEqual(len(multiframes2), 4)
        multiframes2 = [
            m for m in l2.multiFrames() if
            not m.uuid() in [new_multiframe1.uuid(),
                             new_multiframe2.uuid()]
        ]
        self.assertEqual(len(multiframes2), 2)
        self.assertTrue([i for i in items if i.id() == 'xxyyxx'])
        self.assertTrue([i for i in items if i.id() == 'zzyyzz'])
        self.assertTrue([i for i in items if i.id() == 'frame1'])
        self.assertTrue([i for i in items if i.id() == 'frame2'])
        self.assertTrue([i for i in multiframes2 if i.html() == 'mf1'])
        self.assertTrue([i for i in multiframes2 if i.html() == 'mf2'])
        self.assertTrue(new_items[0] in l2.items())
        self.assertTrue(new_items[1] in l2.items())
        self.assertTrue(new_items[2] in l2.items())
        self.assertTrue(new_items[3] in l2.items())
        self.assertTrue(new_items2[0] in l2.items())
        self.assertTrue(new_items2[1] in l2.items())
        self.assertTrue(new_items2[2] in l2.items())
        self.assertTrue(new_items2[3] in l2.items())
        self.assertNotIn(new_items2[0].uuid(), uuids)
        uuids.add(new_items[0].uuid())
        self.assertNotIn(new_items2[1].uuid(), uuids)
        uuids.add(new_items[1].uuid())
        self.assertNotIn(new_items2[2].uuid(), uuids)
        uuids.add(new_items[2].uuid())
        self.assertNotIn(new_items2[3].uuid(), uuids)
        uuids.add(new_items[3].uuid())

        self.assertNotIn(multiframes2[0].uuid(), [
            multiframe1.uuid(),
            multiframe2.uuid(),
            new_multiframe1.uuid(),
            new_multiframe2.uuid()
        ])
        self.assertNotIn(multiframes2[1].uuid(), [
            multiframe1.uuid(),
            multiframe2.uuid(),
            new_multiframe1.uuid(),
            new_multiframe2.uuid()
        ])

        new_multiframe1b = [i for i in multiframes2 if i.html() == 'mf1'][0]
        self.assertEqual(new_multiframe1b.layout(), l2)
        new_multiframe2b = [i for i in multiframes2 if i.html() == 'mf2'][0]
        self.assertEqual(new_multiframe2b.layout(), l2)
        new_frame1b = sip.cast([
            i for i in items
            if i.id() == 'frame1' and i.uuid() != new_frame1.uuid()
        ][0], QgsLayoutFrame)
        new_frame2b = sip.cast([
            i for i in items
            if i.id() == 'frame2' and i.uuid() != new_frame2.uuid()
        ][0], QgsLayoutFrame)
        self.assertEqual(new_frame1b.multiFrame(), new_multiframe1b)
        self.assertEqual(new_multiframe1b.frames()[0].uuid(),
                         new_frame1b.uuid())
        self.assertEqual(new_frame2b.multiFrame(), new_multiframe2b)
        self.assertEqual(new_multiframe2b.frames()[0].uuid(),
                         new_frame2b.uuid())

        # clearing existing items
        new_items3, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), True)
        new_multiframes = l2.multiFrames()
        self.assertTrue(ok)
        self.assertEqual(len(new_items3), 5)  # includes page
        self.assertEqual(len(new_multiframes), 2)
        items = l2.items()
        self.assertTrue([
            i for i in items
            if isinstance(i, QgsLayoutItem) and i.id() == 'xxyyxx'
        ])
        self.assertTrue([
            i for i in items
            if isinstance(i, QgsLayoutItem) and i.id() == 'zzyyzz'
        ])
        self.assertTrue([
            i for i in items
            if isinstance(i, QgsLayoutItem) and i.id() == 'frame1'
        ])
        self.assertTrue([
            i for i in items
            if isinstance(i, QgsLayoutItem) and i.id() == 'frame2'
        ])
        self.assertTrue(new_items3[0] in l2.items())
        self.assertTrue(new_items3[1] in l2.items())
        self.assertTrue(new_items3[2] in l2.items())
        self.assertTrue(new_items3[3] in l2.items())
        new_multiframe1 = [i for i in new_multiframes if i.html() == 'mf1'][0]
        new_multiframe2 = [i for i in new_multiframes if i.html() == 'mf2'][0]

        new_frame1 = sip.cast([
            i for i in items
            if isinstance(i, QgsLayoutItem) and i.id() == 'frame1'
        ][0], QgsLayoutFrame)
        new_frame2 = sip.cast([
            i for i in items
            if isinstance(i, QgsLayoutItem) and i.id() == 'frame2'
        ][0], QgsLayoutFrame)
        self.assertEqual(new_frame1.multiFrame(), new_multiframe1)
        self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid())
        self.assertEqual(new_frame2.multiFrame(), new_multiframe2)
        self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid())
Example #59
0
    def __init__(self, map_theme, layer, extent, tile_size, mupp, output,
                 make_trans, map_settings):
        """
        :param map_theme:
        :param extent:
        :param layer:
        :param tile_size:
        :param mupp:
        :param output:
        :param map_settings: Map canvas map settings used for some fallback
        values and CRS
        """

        self.extent = extent
        self.mupp = mupp
        self.tile_size = tile_size

        driver = self.getDriverForFile(output)

        if not driver:
            raise QgsProcessingException(
                u'Could not load GDAL driver for file {}'.format(output))

        crs = map_settings.destinationCrs()

        self.x_tile_count = math.ceil(extent.width() / mupp / tile_size)
        self.y_tile_count = math.ceil(extent.height() / mupp / tile_size)

        xsize = self.x_tile_count * tile_size
        ysize = self.y_tile_count * tile_size

        if make_trans:
            no_bands = 4
        else:
            no_bands = 3

        self.dataset = driver.Create(output, xsize, ysize, no_bands)
        self.dataset.SetProjection(str(crs.toWkt()))
        self.dataset.SetGeoTransform(
            [extent.xMinimum(), mupp, 0, extent.yMaximum(), 0, -mupp])

        self.image = QImage(QSize(tile_size, tile_size), QImage.Format_ARGB32)

        self.settings = QgsMapSettings()
        self.settings.setOutputDpi(self.image.logicalDpiX())
        self.settings.setOutputImageFormat(QImage.Format_ARGB32)
        self.settings.setDestinationCrs(crs)
        self.settings.setOutputSize(self.image.size())
        self.settings.setFlag(QgsMapSettings.Antialiasing, True)
        self.settings.setFlag(QgsMapSettings.RenderMapTile, True)
        self.settings.setFlag(QgsMapSettings.UseAdvancedEffects, True)

        if make_trans:
            self.settings.setBackgroundColor(QColor(255, 255, 255, 0))
        else:
            self.settings.setBackgroundColor(QColor(255, 255, 255))

        if QgsProject.instance().mapThemeCollection().hasMapTheme(map_theme):
            self.settings.setLayers(
                QgsProject.instance().mapThemeCollection(

                ).mapThemeVisibleLayers(
                    map_theme))
            self.settings.setLayerStyleOverrides(
                QgsProject.instance().mapThemeCollection(

                ).mapThemeStyleOverrides(
                    map_theme))
        elif layer:
            self.settings.setLayers([layer])
        else:
            self.settings.setLayers(map_settings.layers())
    def testSnapRect(self):
        p = QgsProject()
        l = QgsLayout(p)
        page = QgsLayoutItemPage(l)
        page.setPageSize('A4')
        l.pageCollection().addPage(page)
        s = QgsLayoutSnapper(l)
        guides = l.guides()

        # first test snapping to grid
        l.gridSettings().setResolution(
            QgsLayoutMeasurement(5, QgsUnitTypes.LayoutMillimeters))
        s.setSnapToItems(False)
        s.setSnapToGrid(True)
        s.setSnapTolerance(1)

        rect, snapped = s.snapRect(QRectF(1, 1, 2, 1), 1)
        self.assertTrue(snapped)
        self.assertEqual(rect, QRectF(0, 0, 2, 1))
        rect, snapped = s.snapRect(QRectF(1, 1, 3.5, 3.5), 1)
        self.assertTrue(snapped)
        self.assertEqual(rect, QRectF(1.5, 1.5, 3.5, 3.5))

        s.setSnapToItems(False)
        s.setSnapToGrid(False)
        rect, snapped = s.snapRect(QRectF(1, 1, 3.5, 3.5), 1)
        self.assertFalse(snapped)
        self.assertEqual(rect, QRectF(1, 1, 3.5, 3.5))

        # test that guide takes precedence
        s.setSnapToGrid(True)
        s.setSnapToGuides(True)
        guides.addGuide(
            QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(0.5), page))
        rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1)
        self.assertTrue(snapped)
        self.assertEqual(rect, QRectF(0.0, 0.5, 2.0, 3.0))

        # add an item
        item1 = QgsLayoutItemMap(l)
        item1.attemptMove(
            QgsLayoutPoint(121, 1.1, QgsUnitTypes.LayoutMillimeters))
        l.addItem(item1)

        # test that guide takes precedence over item
        s.setSnapToGrid(True)
        s.setSnapToGuides(True)
        s.setSnapToItems(True)
        rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1)
        self.assertTrue(snapped)
        self.assertEqual(rect, QRectF(0.0, 0.5, 2.0, 3.0))
        # but items take precedence over grid
        s.setSnapToGuides(False)
        rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1)
        self.assertTrue(snapped)
        self.assertEqual(rect, QRectF(0.0, 1.1, 2.0, 3.0))

        # ... unless item is ignored!
        rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1, None, None, [item1])
        self.assertTrue(snapped)
        self.assertEqual(rect, QRectF(0.0, 0.0, 2.0, 3.0))