Example #1
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.project.addMapLayers([self.layer, self.layer2, self.layer3])
        self.model = QgsLayerTreeModel(self.project.layerTreeRoot())

    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 test_project_server_validator(self):
        """Test project server validator."""
        project = QgsProject()
        layer = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1',
                               'memory')
        project.addMapLayers([layer])

        # Valid
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertFalse(results)

        layer_1 = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1',
                                 'memory')
        project.addMapLayers([layer_1])

        # Not valid, same layer name
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.DuplicatedNames,
                         results[0].error)

        # Not valid, short name is invalid
        layer_1.setShortName('layer_1_invalid_#')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.ShortNames,
                         results[0].error)

        # Not valid, same short name as the first layer name
        layer_1.setShortName('layer_1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.DuplicatedNames,
                         results[0].error)

        # Valid
        layer_1.setShortName('layer_1_bis')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertEqual(0, len(results))

        # Not valid, a group with same name as the first layer
        group = project.layerTreeRoot().addGroup('layer_1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.DuplicatedNames,
                         results[0].error)

        # Valid
        group.setCustomProperty('wmsShortName', 'my_group1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertEqual(0, len(results))
Example #3
0
    def test_layer_order_with_group_layer(self):
        """
        Test retrieving layer order with group layers present
        """
        p = QgsProject()
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        p.addMapLayer(layer, False)
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        p.addMapLayer(layer2, False)
        layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                "memory")
        p.addMapLayer(layer3, False)
        layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                "memory")
        p.addMapLayer(layer4, False)

        p.layerTreeRoot().addLayer(layer)
        group_node = p.layerTreeRoot().addGroup('my group')
        group_node.addLayer(layer2)
        group_node.addLayer(layer3)
        p.layerTreeRoot().addLayer(layer4)

        self.assertEqual(p.layerTreeRoot().layerOrder(),
                         [layer, layer2, layer3, layer4])

        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        p.addMapLayer(group_layer, False)
        self.assertEqual(p.layerTreeRoot().layerOrder(),
                         [layer, group_layer, layer4])
        self.assertEqual(group_layer.childLayers(), [layer3, layer2])
Example #4
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.project.addMapLayers([self.layer, self.layer2, self.layer3])
        self.model = QgsLayerTreeModel(self.project.layerTreeRoot())

    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)
Example #5
0
    def test_json_export(self):

        project = QgsProject()
        self.assertTrue(project.read(os.path.join(unitTestDataPath('qgis_server'), 'test_project.qgs')))
        model = QgsLegendModel(project.layerTreeRoot())
        ctx = QgsRenderContext()
        settings = QgsLegendSettings()
        renderer = QgsLegendRenderer(model, settings)
        nodes = renderer.exportLegendToJson(ctx)['nodes'].toVariant()
        self.assertEqual(len(nodes), 7)
        self.assertEqual(nodes[0]['type'], 'layer')
        self.assertEqual(nodes[0]['title'], 'testlayer')
Example #6
0
    def create(self, qgis_project: QgsProject, group=None):
        if not group:
            group = qgis_project.layerTreeRoot()

        existing_layer_source_uris = [
            found_layer.layer().dataProvider().dataSourceUri()
            for found_layer in qgis_project.layerTreeRoot().findLayers()
        ]

        static_index = 0
        for item in self.items:
            if isinstance(item, LegendGroup):
                subgroup = group.findGroup(item.name)
                if subgroup is None:
                    subgroup = group.addGroup(item.name)
                item.create(qgis_project, subgroup)
                subgroup.setExpanded(item.expanded)
                subgroup.setItemVisibilityChecked(item.checked)
                subgroup.setIsMutuallyExclusive(item.mutually_exclusive,
                                                item.mutually_exclusive_child)
            else:
                layer = item.layer
                if (layer.dataProvider().dataSourceUri()
                        not in existing_layer_source_uris):
                    if self.static_sorting:
                        index = static_index
                    elif layer.isSpatial():
                        index = get_suggested_index_for_layer(
                            layer, group, self.ignore_node_names)
                    else:
                        index = 0
                    layernode = QgsLayerTreeLayer(layer)
                    layernode.setExpanded(item.expanded)
                    layernode.setItemVisibilityChecked(item.checked)
                    layernode.setCustomProperty("showFeatureCount",
                                                item.featurecount)
                    group.insertChildNode(index, layernode)
            static_index += 1
Example #7
0
    def test_restore_group_node_group_layer(self):
        """
        Test that group node's QgsGroupLayers are restored with projects
        """
        p = QgsProject()
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        p.addMapLayer(layer, False)
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        p.addMapLayer(layer2, False)

        group_node = p.layerTreeRoot().addGroup('my group')
        group_node.addLayer(layer)
        group_node.addLayer(layer2)
        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        p.addMapLayer(group_layer, False)

        with TemporaryDirectory() as d:
            path = os.path.join(d, 'group_layers.qgs')

            p.setFileName(path)
            p.write()

            p2 = QgsProject()
            p2.read(path)

            restored_group_node = p2.layerTreeRoot().children()[0]
            self.assertEqual(restored_group_node.name(), 'my group')

            restored_group_layer = restored_group_node.groupLayer()
            self.assertIsNotNone(restored_group_layer)

            self.assertEqual(restored_group_layer.childLayers()[0].name(),
                             'layer2')
            self.assertEqual(restored_group_layer.childLayers()[1].name(),
                             'layer1')
Example #8
0
def _get_group(
    *,
    project: qgc.QgsProject,
    group_path: tuple[str, ...],
) -> qgc.QgsLayerTreeGroup:
    # Starting at the root of the layer tree, climb the tree until we reach the
    # parent of group_node.
    group = project.layerTreeRoot()
    for group_name in group_path:
        group = group.findGroup(group_name)
        if not group:
            raise exc.QgrQgsLayerTreeGroupError(
                f'Unable to find group {group_path}.', )

    return group
Example #9
0
    def create(self, qgis_project: QgsProject, group=None):
        if not group:
            group = qgis_project.layerTreeRoot()

        for item in self.items:
            if isinstance(item, LegendGroup):
                subgroup = group.findGroup(item.name)
                if subgroup is None:
                    subgroup = group.addGroup(item.name)
                    subgroup.setExpanded(item.expanded)
                item.create(qgis_project, subgroup)
            else:
                layer = item.layer
                index = get_suggested_index_for_layer(layer, group) if layer.isSpatial() else 0
                group.insertLayer(index, layer)
Example #10
0
    def testEmbeddedGroup(self):
        testdata_path = unitTestDataPath('embedded_groups') + '/'

        prj_path = os.path.join(testdata_path, "project2.qgs")
        prj = QgsProject()
        prj.read(prj_path)

        layer_tree_group = prj.layerTreeRoot()
        self.assertEqual(len(layer_tree_group.findLayerIds()), 2)
        for layer_id in layer_tree_group.findLayerIds():
            name = prj.mapLayer(layer_id).name()
            self.assertTrue(name in ['polys', 'lines'])
            if name == 'polys':
                self.assertTrue(layer_tree_group.findLayer(layer_id).itemVisibilityChecked())
            elif name == 'lines':
                self.assertFalse(layer_tree_group.findLayer(layer_id).itemVisibilityChecked())
Example #11
0
    def testEmbeddedGroup(self):
        testdata_path = unitTestDataPath('embedded_groups') + '/'

        prj_path = os.path.join(testdata_path, "project2.qgs")
        prj = QgsProject()
        prj.read(prj_path)

        layer_tree_group = prj.layerTreeRoot()
        layers_ids = layer_tree_group.findLayerIds()

        layers_names = []
        for layer_id in layers_ids:
            name = prj.mapLayer(layer_id).name()
            layers_names.append(name)

        expected = ['polys', 'lines']
        self.assertEqual(sorted(layers_names), sorted(expected))
Example #12
0
    def testEmbeddedGroup(self):
        testdata_path = unitTestDataPath('embedded_groups') + '/'

        prj_path = os.path.join(testdata_path, "project2.qgs")
        prj = QgsProject()
        prj.read(prj_path)

        layer_tree_group = prj.layerTreeRoot()
        layers_ids = layer_tree_group.findLayerIds()

        layers_names = []
        for layer_id in layers_ids:
            name = prj.mapLayer(layer_id).name()
            layers_names.append(name)

        expected = ['polys', 'lines']
        self.assertEqual(sorted(layers_names), sorted(expected))
Example #13
0
    def create(self, qgis_project: QgsProject, group=None):
        if not group:
            group = qgis_project.layerTreeRoot()

        for item in self.items:
            if isinstance(item, LegendGroup):
                subgroup = get_group_non_recursive(group, item.name)
                if subgroup is None:
                    # If the subgroup does not exist or it's not child of root
                    subgroup = group.addGroup(item.name)
                    subgroup.setExpanded(item.expanded)
                item.create(qgis_project, subgroup)
            else:
                layer = item.layer
                index = get_suggested_index_for_layer(
                    layer, group,
                    self.ignore_node_names) if layer.isSpatial() else 0
                group.insertLayer(index, layer)
Example #14
0
    def testEmbeddedGroup(self):
        testdata_path = unitTestDataPath('embedded_groups') + '/'

        prj_path = os.path.join(testdata_path, "project2.qgs")
        prj = QgsProject()
        prj.read(prj_path)

        layer_tree_group = prj.layerTreeRoot()
        self.assertEqual(len(layer_tree_group.findLayerIds()), 2)
        for layer_id in layer_tree_group.findLayerIds():
            name = prj.mapLayer(layer_id).name()
            self.assertTrue(name in ['polys', 'lines'])
            if name == 'polys':
                self.assertTrue(
                    layer_tree_group.findLayer(
                        layer_id).itemVisibilityChecked())
            elif name == 'lines':
                self.assertFalse(
                    layer_tree_group.findLayer(
                        layer_id).itemVisibilityChecked())
Example #15
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(),
            ])
    export_type = sys.argv[sys.argv.index("-T") + 1]
if "-D" in sys.argv:
    target_dir = sys.argv[sys.argv.index("-D") + 1]
if "-O" in sys.argv:
    output_log = sys.argv[sys.argv.index("-O") + 1]

# Instantiate QGIS
QgsApplication.setPrefixPath(qgisPrefixPath, True)
qgs = QgsApplication([], True)
QgsApplication.initQgis()

# Open the project
p = QgsProject()
p.read(project_path)
canvas = QgsMapCanvas()
bridge = QgsLayerTreeMapCanvasBridge(p.layerTreeRoot(), canvas)
bridge.setCanvasLayers()

# Get the layers in the project
layerList = p.mapLayersByName(parcelle_layer)
if not layerList:
    layers = p.mapLayers()
    for lname, layer in layers.items():
        print(lname + ' ' + layer.name() + ' ' + parcelle_layer)
    layerList = [
        layer for lname, layer in layers.items()
        if layer.name() == parcelle_layer
    ]
layer = layerList[0]

# Get Feature
Example #17
0
    def testCustomLayerOrder(self):
        """ test project layer order"""
        prj = QgsProject()
        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])

        layer_order_changed_spy = QSignalSpy(prj.layerTreeRoot().customLayerOrderChanged)
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
        self.assertEqual(len(layer_order_changed_spy), 1)
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
        self.assertEqual(len(layer_order_changed_spy), 1) # no signal, order not changed

        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer])
        prj.layerTreeRoot().setCustomLayerOrder([layer])
        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer])
        self.assertEqual(len(layer_order_changed_spy), 2)

        # remove a layer
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer, layer3])
        self.assertEqual(len(layer_order_changed_spy), 3)
        prj.removeMapLayer(layer)
        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer3])
        self.assertEqual(len(layer_order_changed_spy), 4)

        # save and restore
        file_name = os.path.join(QDir.tempPath(), 'proj.qgs')
        prj.setFileName(file_name)
        prj.write()
        prj2 = QgsProject()
        prj2.setFileName(file_name)
        prj2.read()
        self.assertEqual([l.id() for l in prj2.layerTreeRoot().customLayerOrder()], [layer2.id(), layer3.id()])

        # clear project
        prj.clear()
        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [])
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 #19
0
    def print_atlas(project_path, composer_name, predefined_scales, feature_filter, page_name_expression=None):
        if not feature_filter:
            QgsMessageLog.logMessage("atlasprint: NO feature_filter provided !", 'atlasprint', Qgis.Critical)
            return None

        # Get composer from project
        # in QGIS 2, we can't get composers without iface
        # so we reading project xml and extract composer
        # TODO Since QGIS 3.0, we should be able to use project layoutManager()
        # noinspection PyPep8Naming
        from xml.etree import ElementTree as ET
        composer_xml = None
        with open(project_path, 'r') as f:
            tree = ET.parse(f)
            for elem in tree.findall('.//Composer[@title="%s"]' % composer_name):
                composer_xml = ET.tostring(
                    elem,
                    encoding='utf8',
                    method='xml'
                )
            if not composer_xml:
                for elem in tree.findall('.//Layout[@name="%s"]' % composer_name):
                    composer_xml = ET.tostring(
                        elem,
                        encoding='utf8',
                        method='xml'
                    )

        if not composer_xml:
            QgsMessageLog.logMessage("atlasprint: Composer XML not parsed !", 'atlasprint', Qgis.Critical)
            return None

        document = QDomDocument()
        document.setContent(composer_xml)

        # Get canvas, map setting & instantiate composition
        canvas = QgsMapCanvas()
        project = QgsProject()
        project.read(project_path)
        bridge = QgsLayerTreeMapCanvasBridge(
            project.layerTreeRoot(),
            canvas
        )
        bridge.setCanvasLayers()

        layout = QgsPrintLayout(project)

        # Load content from XML
        layout.loadFromTemplate(
            document,
            QgsReadWriteContext(),
        )

        atlas = layout.atlas()
        atlas.setEnabled(True)

        atlas_map = layout.referenceMap()
        atlas_map.setAtlasDriven(True)
        atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Predefined)

        layout.reportContext().setPredefinedScales(predefined_scales)

        if page_name_expression:
            atlas.setPageNameExpression(page_name_expression)

        # Filter feature here to avoid QGIS looping through every feature when doing : composition.setAtlasMode(QgsComposition.ExportAtlas)
        coverage_layer = atlas.coverageLayer()

        # Filter by FID as QGIS cannot compile expressions with $id or other $ vars
        # which leads to bad performance for big dataset
        use_fid = None
        if '$id' in feature_filter:
            import re
            ids = list(map(int, re.findall(r'\d+', feature_filter)))
            if len(ids) > 0:
                use_fid = ids[0]
        if use_fid:
            qReq = QgsFeatureRequest().setFilterFid(use_fid)
        else:
            qReq = QgsFeatureRequest().setFilterExpression(feature_filter)

        # Change feature_filter in order to improve performance
        pks = coverage_layer.dataProvider().pkAttributeIndexes()
        if use_fid and len(pks) == 1:
            pk = coverage_layer.dataProvider().fields()[pks[0]].name()
            feature_filter = '"%s" IN (%s)' % (pk, use_fid)
            QgsMessageLog.logMessage("atlasprint: feature_filter changed into: %s" % feature_filter, 'atlasprint', Qgis.Info)
            qReq = QgsFeatureRequest().setFilterExpression(feature_filter)
        atlas.setFilterFeatures(True)
        atlas.setFilterExpression(feature_filter)
        uid = uuid4()
        i = 0  # We use a single page for now.

        atlas.beginRender()
        atlas.seekTo(i)

        # setup settings
        settings = QgsLayoutExporter.PdfExportSettings()
        export_path = os.path.join(
                tempfile.gettempdir(),
                '%s_%s.pdf' % (atlas.nameForPage(i), uid)
        )
        exporter = QgsLayoutExporter(layout)
        result = exporter.exportToPdf(export_path, settings)

        atlas.endRender()
        if result != QgsLayoutExporter.Success:
            QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical)
            return None

        if not os.path.isfile(export_path):
            QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical)
            return None

        QgsMessageLog.logMessage("atlasprint: path generated %s" % export_path, 'atlasprint', Qgis.Success)
        return export_path
Example #20
0
    def test_nested_groups(self):
        """
        Test logic relating to nested groups with group layers
        """
        p = QgsProject()
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        p.addMapLayer(layer, False)
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        p.addMapLayer(layer2, False)
        layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                "memory")
        p.addMapLayer(layer3, False)
        layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                "memory")
        p.addMapLayer(layer4, False)

        group_node = p.layerTreeRoot().addGroup('my group')
        group_node.addLayer(layer)
        group_node.addLayer(layer2)

        child_group = group_node.addGroup('child')
        layer3_node = child_group.addLayer(layer3)

        grandchild_group = child_group.addGroup('grandchild')
        layer4_node = grandchild_group.addLayer(layer4)

        self.assertEqual(p.layerTreeRoot().layerOrder(),
                         [layer, layer2, layer3, layer4])
        self.assertEqual(p.layerTreeRoot().checkedLayers(),
                         [layer, layer2, layer3, layer4])

        spy = QSignalSpy(p.layerTreeRoot().layerOrderChanged)

        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        p.addMapLayer(group_layer, False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [layer4, layer3, layer2, layer])
        spy_count = len(spy)
        self.assertEqual(spy_count, 1)

        grandchild_group_layer = grandchild_group.convertToGroupLayer(options)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(), [layer3, layer2, layer])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [grandchild_group_layer, layer3, layer2, layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        child_group_layer = child_group.convertToGroupLayer(options)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer4_node.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(), [layer3])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer3_node.setItemVisibilityChecked(False)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        layer3_node.setItemVisibilityChecked(True)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(),
                         [grandchild_group_layer, layer3])
        self.assertEqual(grandchild_group_layer.childLayers(), [layer4])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        grandchild_group.setGroupLayer(None)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [child_group_layer, layer2, layer])
        self.assertEqual(child_group_layer.childLayers(), [layer4, layer3])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        child_group.setGroupLayer(None)
        self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer])
        self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer])
        self.assertEqual(group_layer.childLayers(),
                         [layer4, layer3, layer2, layer])
        self.assertGreater(len(spy), spy_count)
        spy_count = len(spy)

        group_node.setGroupLayer(None)
        self.assertEqual(p.layerTreeRoot().layerOrder(),
                         [layer, layer2, layer3, layer4])
        self.assertEqual(p.layerTreeRoot().checkedLayers(),
                         [layer, layer2, layer3, layer4])
        self.assertGreater(len(spy), spy_count)
Example #21
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())
        if USE_MODEL_TESTER:
            self.tester = QAbstractItemModelTester(self.model)

    def nodeOrder(self, group):

        nodeorder = []
        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)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        self.assertEqual(view.layerTreeModel(), self.model)

    def testSetCurrentLayer(self):

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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 = view.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)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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(),
            ])

    def testMoveToTopActionLayerAndGroup(self):
        """Test move to top action for a group and it's layer simultaneously"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().addGroup("embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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(),
            ])

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

    def testMoveToBottomActionLayer(self):
        """Test move to bottom action on layer"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer, self.layer2, self.layer3])
        view.setCurrentLayer(self.layer)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.trigger()
        self.assertEqual(self.project.layerTreeRoot().layerOrder(),
                         [self.layer2, self.layer3, self.layer])

    def testMoveToBottomActionGroup(self):
        """Test move to bottom action on group"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().insertGroup(0, "embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        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(),
            ])

        nodeLayerIndex = view.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.trigger()
        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(),
            ])

    def testMoveToBottomActionEmbeddedGroup(self):
        """Test move to bottom 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)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.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.layer4)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.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(),
            ])

    def testMoveToBottomActionLayerAndGroup(self):
        """Test move to top action for a group and it's layer simultaneously"""

        view = QgsLayerTreeView()
        group = self.project.layerTreeRoot().insertGroup(0, "embeddedgroup")
        group.addLayer(self.layer4)
        group.addLayer(self.layer5)
        groupname = group.name()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        actions = QgsLayerTreeViewDefaultActions(view)
        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(),
            ])

        selectionMode = view.selectionMode()
        view.setSelectionMode(QgsLayerTreeView.MultiSelection)
        nodeLayerIndex = view.node2index(group)
        view.setCurrentIndex(nodeLayerIndex)
        view.setCurrentLayer(self.layer4)
        view.setSelectionMode(selectionMode)
        movetobottom = actions.actionMoveToBottom()
        movetobottom.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(),
            ])

    def testSetLayerVisible(self):

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        self.project.layerTreeRoot().findLayer(
            self.layer).setItemVisibilityChecked(True)
        self.project.layerTreeRoot().findLayer(
            self.layer2).setItemVisibilityChecked(True)
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer).itemVisibilityChecked())
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer2).itemVisibilityChecked())

        view.setLayerVisible(None, True)
        view.setLayerVisible(self.layer, True)
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer).itemVisibilityChecked())
        view.setLayerVisible(self.layer2, False)
        self.assertFalse(self.project.layerTreeRoot().findLayer(
            self.layer2).itemVisibilityChecked())
        view.setLayerVisible(self.layer2, True)
        self.assertTrue(self.project.layerTreeRoot().findLayer(
            self.layer2).itemVisibilityChecked())

    def testProxyModel(self):
        """Test proxy model filtering and private layers"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
        tree_model = view.layerTreeModel()
        proxy_model = view.proxyModel()

        self.assertEqual(tree_model.rowCount(), 3)
        self.assertEqual(proxy_model.rowCount(), 3)

        items = []
        for r in range(tree_model.rowCount()):
            items.append(tree_model.data(tree_model.index(r, 0)))

        self.assertEqual(items, ['layer1', 'layer2', 'layer3'])

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2', 'layer3'])

        self.layer3.setFlags(self.layer.Private)
        self.assertEqual(tree_model.rowCount(), 3)
        self.assertEqual(proxy_model.rowCount(), 2)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2'])

        view.setShowPrivateLayers(True)

        self.assertEqual(proxy_model.rowCount(), 3)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2', 'layer3'])

        view.setShowPrivateLayers(False)

        self.assertEqual(proxy_model.rowCount(), 2)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer1', 'layer2'])

        # Test filters
        proxy_model.setFilterText('layer2')

        self.assertEqual(proxy_model.rowCount(), 1)

        proxy_items = []
        for r in range(proxy_model.rowCount()):
            proxy_items.append(proxy_model.data(proxy_model.index(r, 0)))

        self.assertEqual(proxy_items, ['layer2'])

    def testProxyModelCurrentIndex(self):
        """Test a crash spotted out while developing the proxy model"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
            tree_tester = QAbstractItemModelTester(view.layerTreeModel())

        view.setCurrentLayer(self.layer3)
        self.layer3.setFlags(self.layer.Private)

    def testNode2IndexMethods(self):
        """Test node2index and node2sourceIndex"""

        view = QgsLayerTreeView()
        view.setModel(self.model)
        if USE_MODEL_TESTER:
            proxy_tester = QAbstractItemModelTester(view.model())
            tree_tester = QAbstractItemModelTester(view.layerTreeModel())

        tree_model = view.layerTreeModel()
        proxy_model = view.proxyModel()

        proxy_index = proxy_model.index(1, 0)
        node2 = view.index2node(proxy_index)
        self.assertEqual(node2.name(), 'layer2')

        proxy_layer2_index = view.node2index(node2)
        self.assertEqual(proxy_layer2_index, view.node2index(node2))

        source_index = tree_model.index(1, 0)
        tree_layer2_index = view.node2sourceIndex(node2)
        self.assertEqual(tree_layer2_index, view.node2sourceIndex(node2))
Example #22
0
if "-D" in sys.argv:
    target_dir = sys.argv[sys.argv.index("-D") + 1]
if "-O" in sys.argv:
    output_log = sys.argv[sys.argv.index("-O") + 1]

# Instantiate QGIS
QgsApplication.setPrefixPath(qgisPrefixPath, True)
qgs = QgsApplication([], True)
QgsApplication.initQgis()

# Open the project
p = QgsProject()
p.read(project_path)
canvas = QgsMapCanvas()
bridge = QgsLayerTreeMapCanvasBridge(
    p.layerTreeRoot(),
    canvas
)
bridge.setCanvasLayers()

# Get the layers in the project
layerList = p.mapLayersByName(parcelle_layer)
if not layerList:
    layers = p.mapLayers()
    for lname, layer in layers.items():
        print(lname + ' ' + layer.name() + ' ' + parcelle_layer)
    layerList = [layer for lname, layer in layers.items() if layer.name() == parcelle_layer]
layer = layerList[0]

# Get Feature
req = QgsFeatureRequest()
Example #23
0
    def setUpTestData(cls):

        super().setUpTestData()

        cls.temp_dir = QTemporaryDir()
        cls.temp_project_path = os.path.join(cls.temp_dir.path(),
                                             'pg_openrouteservice.qgs')

        # Create test layer
        conn_str = "dbname='{NAME}' host={HOST} port={PORT} user='******' password='******' sslmode=disable".format(
            **settings.DATABASES['default'])

        cls.conn_uri = conn_str

        md = QgsProviderRegistry.instance().providerMetadata('postgres')

        conn = md.createConnection(conn_str, {})

        conn.executeSql(
            "DROP SCHEMA IF EXISTS \"openrouteservice test\" CASCADE")
        conn.executeSql("CREATE SCHEMA \"openrouteservice test\"")
        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_poly_not_compatible ( pk SERIAL NOT NULL, name TEXT, geom GEOMETRY(POLYGON, 4326), PRIMARY KEY ( pk ) )"
        )

        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_point_not_compatible ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POINT, 4326), PRIMARY KEY ( pk ) )"
        )

        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_compatible ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POLYGON, 4326), PRIMARY KEY ( pk ) )"
        )

        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_compatible_3857 ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POLYGON, 3857), PRIMARY KEY ( pk ) )"
        )

        # Input layers for async tests
        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_point_3857 ( pk SERIAL NOT NULL, geom GEOMETRY(POINT, 3857), PRIMARY KEY ( pk ) )"
        )
        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_multipoint_4326 ( pk SERIAL NOT NULL, geom GEOMETRY(MULTIPOINT, 4326), PRIMARY KEY ( pk ) )"
        )

        # Add sample points for async tests
        conn.executeSql(
            """INSERT INTO "openrouteservice test".openrouteservice_multipoint_4326 (geom) VALUES
            ( 'SRID=4326;MULTIPOINT ((-77.55542807059459 37.56350130888833), (-77.5513628235481 37.547924590224554), (-77.53848954123421 37.58068563329007), (-77.59608054105951 37.59518182260462))'::geometry),
	        ('SRID=4326;MULTIPOINT ((-77.4077240945721 37.538254644499624), (-77.41991983571157 37.54470141434406), (-77.4260177062813 37.55920460826607), (-77.39349572990939 37.562427156963516), (-77.40840163574651 37.58337032579007))'::geometry)"""
        )

        conn.executeSql(
            """INSERT INTO "openrouteservice test".openrouteservice_point_3857 (geom) VALUES
            ('SRID=3857;POINT (-8636824.820306677 4510025.909782101)'::geometry),
            ('SRID=3857;POINT (-8633657.031688528 4512364.0394764505)'::geometry),
            ('SRID=3857;POINT (-8637126.514460787 4512741.157169087)'::geometry),
            ('SRID=3857;POINT (-8634109.572919691 4503916.603161385)'::geometry)"""
        )

        cls.layer_specs = {}

        project = QgsProject()

        for table_name, table_spec in {
                'openrouteservice_poly_not_compatible': ('Polygon', 4326),
                'openrouteservice_point_not_compatible': ('Point', 4326),
                'openrouteservice_compatible': ('Polygon', 4326),
                'openrouteservice_compatible_3857': ('Polygon', 3857),
                'openrouteservice_point_3857': ('Point', 3857),
                'openrouteservice_multipoint_4326': ('MultiPoint', 4326),
        }.items():
            layer_uri = conn_str + " sslmode=disable key='pk' estimatedmetadata=false srid={srid} type={geometry_type} checkPrimaryKeyUnicity='0' table=\"openrouteservice test\".\"{table_name}\" (geom)".format(
                table_name=table_name,
                geometry_type=table_spec[0],
                srid=table_spec[1])
            layer = QgsVectorLayer(layer_uri, table_name, 'postgres')
            assert layer.isValid()
            cls.layer_specs[table_name] = layer_uri
            project.addMapLayers([layer])

        assert project.write(cls.temp_project_path)

        Project.objects.filter(title='Test openrouteservice project').delete()

        toc = buildLayerTreeNodeObject(project.layerTreeRoot())

        cls.qdjango_project = Project(qgis_file=File(
            open(cls.temp_project_path, 'r')),
                                      title='Test openrouteservice project',
                                      group=cls.project_group,
                                      layers_tree=toc)
        cls.qdjango_project.save()

        for layer_id, layer in project.mapLayers().items():
            _, created = Layer.objects.get_or_create(
                name=layer.name(),
                title=layer.name(),
                origname=layer.name(),
                qgs_layer_id=layer_id,
                srid=layer.crs().postgisSrid(),
                project=cls.qdjango_project,
                layer_type='postgres',
                datasource=cls.layer_specs[layer.name()])
            assert created

        OpenrouteserviceProject.objects.get_or_create(
            project=cls.qdjango_project,
            services={OpenrouteserviceService.ISOCHRONE.value})
    def create(self, path: str, qgis_project: QgsProject):
        qgis_project.setAutoTransaction(self.auto_transaction)
        qgis_project.setEvaluateDefaultValues(self.evaluate_default_values)
        qgis_layers = list()
        for layer in self.layers:
            qgis_layer = layer.create()
            self.layer_added.emit(qgis_layer.id())
            if not self.crs and qgis_layer.isSpatial():
                self.crs = qgis_layer.crs()

            qgis_layers.append(qgis_layer)

        qgis_project.addMapLayers(qgis_layers, not self.legend)

        if self.crs:
            if isinstance(self.crs, QgsCoordinateReferenceSystem):
                qgis_project.setCrs(self.crs)
            else:
                crs = QgsCoordinateReferenceSystem.fromEpsgId(self.crs)
                if not crs.isValid():
                    crs = QgsCoordinateReferenceSystem(self.crs)  # Fallback
                qgis_project.setCrs(crs)

        qgis_relations = list(
            qgis_project.relationManager().relations().values())
        dict_layers = {layer.layer.id(): layer for layer in self.layers}
        for relation in self.relations:
            rel = relation.create(qgis_project, qgis_relations)
            assert rel.isValid()
            qgis_relations.append(rel)

            referenced_layer = dict_layers.get(rel.referencedLayerId(), None)
            referencing_layer = dict_layers.get(rel.referencingLayerId(), None)

            if referenced_layer and referenced_layer.is_domain:
                editor_widget_setup = QgsEditorWidgetSetup(
                    "RelationReference",
                    {
                        "Relation":
                        rel.id(),
                        "ShowForm":
                        False,
                        "OrderByValue":
                        True,
                        "ShowOpenFormButton":
                        False,
                        "AllowNULL":
                        True,
                        "FilterExpression":
                        "\"{}\" = '{}'".format(ENUM_THIS_CLASS_COLUMN,
                                               relation.child_domain_name)
                        if relation.child_domain_name else "",
                        "FilterFields":
                        list(),
                    },
                )
            elif referenced_layer and referenced_layer.is_basket_table:
                editor_widget_setup = QgsEditorWidgetSetup(
                    "RelationReference",
                    {
                        "Relation":
                        rel.id(),
                        "ShowForm":
                        False,
                        "OrderByValue":
                        True,
                        "ShowOpenFormButton":
                        False,
                        "AllowNULL":
                        True,
                        "AllowAddFeatures":
                        False,
                        "FilterExpression":
                        "\"topic\" = '{}' and attribute(get_feature('{}', 't_id', \"dataset\"), 'datasetname') != '{}'"
                        .format(
                            referencing_layer.model_topic_name,
                            "T_ILI2DB_DATASET" if referenced_layer.provider
                            == "ogr" else "t_ili2db_dataset",
                            CATALOGUE_DATASETNAME,
                        ) if referencing_layer.model_topic_name else "",
                        "FilterFields":
                        list(),
                    },
                )
            else:
                editor_widget_setup = QgsEditorWidgetSetup(
                    "RelationReference",
                    {
                        "Relation": rel.id(),
                        "ShowForm": False,
                        "OrderByValue": True,
                        "ShowOpenFormButton": False,
                        "AllowAddFeatures": True,
                        "AllowNULL": True,
                    },
                )

            referencing_layer = rel.referencingLayer()
            referencing_layer.setEditorWidgetSetup(rel.referencingFields()[0],
                                                   editor_widget_setup)

        qgis_project.relationManager().setRelations(qgis_relations)

        # Set Bag of Enum widget
        for layer_name, bag_of_enum in self.bags_of_enum.items():
            for attribute, bag_of_enum_info in bag_of_enum.items():
                layer_obj = bag_of_enum_info[0]
                cardinality = bag_of_enum_info[1]
                domain_table = bag_of_enum_info[2]
                key_field = bag_of_enum_info[3]
                value_field = bag_of_enum_info[4]

                minimal_selection = cardinality.startswith("1")

                current_layer = layer_obj.create()

                field_widget = "ValueRelation"
                field_widget_config = {
                    "AllowMulti": True,
                    "UseCompleter": False,
                    "Value": value_field,
                    "OrderByValue": False,
                    "AllowNull": True,
                    "Layer": domain_table.create().id(),
                    "FilterExpression": "",
                    "Key": key_field,
                    "NofColumns": 1,
                }
                field_idx = current_layer.fields().indexOf(attribute)
                setup = QgsEditorWidgetSetup(field_widget, field_widget_config)
                current_layer.setEditorWidgetSetup(field_idx, setup)
                if minimal_selection:
                    constraint_expression = 'array_length("{}")>0'.format(
                        attribute)
                    current_layer.setConstraintExpression(
                        field_idx,
                        constraint_expression,
                        self.tr("The minimal selection is 1"),
                    )

        for layer in self.layers:
            layer.create_form(self)

        if self.legend:
            self.legend.create(qgis_project)

        custom_layer_order = list()
        for custom_layer_name in self.custom_layer_order_structure:
            custom_layer = qgis_project.mapLayersByName(custom_layer_name)
            if custom_layer:
                custom_layer_order.append(custom_layer[0])
        if custom_layer_order:
            root = qgis_project.layerTreeRoot()
            order = root.customLayerOrder() if root.hasCustomLayerOrder(
            ) else []
            order.extend(custom_layer_order)
            root.setCustomLayerOrder(custom_layer_order)
            root.setHasCustomLayerOrder(True)

        if path:
            qgis_project.write(path)
Example #25
0
def print_layout(
    project: QgsProject,
    layout_name: str,
    output_format: OutputFormat,
    feature_filter: str = None,
    scales: list = None,
    scale: int = None,
    **kwargs,
):
    """Generate a PDF for an atlas or a report.

    :param project: The QGIS project.
    :type project: QgsProject

    :param layout_name: Name of the layout of the atlas or report.
    :type layout_name: basestring

    :param feature_filter: QGIS Expression to use to select the feature.
    It can return many features, a multiple pages PDF will be returned.
    This is required to print atlas, not report
    :type feature_filter: basestring

    :param scale: A scale to force in the atlas context. Default to None.
    :type scale: int

    :param scales: A list of predefined list of scales to force in the atlas context.
    Default to None.
    :type scales: list

    :param output_format: The output format, default to PDF if not provided.

    :return: Path to the PDF.
    :rtype: basestring
    """
    canvas = QgsMapCanvas()
    bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas)
    bridge.setCanvasLayers()
    manager = project.layoutManager()
    master_layout = manager.layoutByName(layout_name)

    if output_format == OutputFormat.Svg:
        settings = QgsLayoutExporter.SvgExportSettings()
    elif output_format in (OutputFormat.Png, OutputFormat.Jpeg):
        settings = QgsLayoutExporter.ImageExportSettings()
    else:
        # PDF by default
        settings = QgsLayoutExporter.PdfExportSettings()

    atlas = None
    atlas_layout = None
    report_layout = None

    logger = Logger()

    if not master_layout:
        raise AtlasPrintException("Layout `{}` not found".format(layout_name))

    if master_layout.layoutType() == QgsMasterLayoutInterface.PrintLayout:
        for _print_layout in manager.printLayouts():
            if _print_layout.name() == layout_name:
                atlas_layout = _print_layout
                break

        atlas = atlas_layout.atlas()
        if not atlas.enabled():
            raise AtlasPrintException("The layout is not enabled for an atlas")

        layer = atlas.coverageLayer()

        if feature_filter is None:
            raise AtlasPrintException(
                "EXP_FILTER is mandatory to print an atlas layout")

        feature_filter = optimize_expression(layer, feature_filter)

        expression = QgsExpression(feature_filter)
        if expression.hasParserError():
            raise AtlasPrintException(
                "Expression is invalid, parser error: {}".format(
                    expression.parserErrorString()))

        context = QgsExpressionContext()
        context.appendScope(QgsExpressionContextUtils.globalScope())
        context.appendScope(QgsExpressionContextUtils.projectScope(project))
        context.appendScope(
            QgsExpressionContextUtils.layoutScope(atlas_layout))
        context.appendScope(QgsExpressionContextUtils.atlasScope(atlas))
        context.appendScope(QgsExpressionContextUtils.layerScope(layer))
        expression.prepare(context)
        if expression.hasEvalError():
            raise AtlasPrintException(
                "Expression is invalid, eval error: {}".format(
                    expression.evalErrorString()))

        atlas.setFilterFeatures(True)
        atlas.setFilterExpression(feature_filter)
        atlas.updateFeatures()

        if scale:
            atlas_layout.referenceMap().setAtlasScalingMode(
                QgsLayoutItemMap.Fixed)
            atlas_layout.referenceMap().setScale(scale)

        if scales:
            atlas_layout.referenceMap().setAtlasScalingMode(
                QgsLayoutItemMap.Predefined)
            settings.predefinedMapScales = scales

        if (not scales and atlas_layout.referenceMap().atlasScalingMode()
                == QgsLayoutItemMap.Predefined):
            use_project = project.useProjectScales()
            map_scales = project.mapScales()
            if not use_project or len(map_scales) == 0:
                logger.info(
                    "Map scales not found in project, fetching predefined map scales in global config"
                )
                map_scales = global_scales()
            settings.predefinedMapScales = map_scales

    elif master_layout.layoutType() == QgsMasterLayoutInterface.Report:
        report_layout = master_layout

    else:
        raise AtlasPrintException("The layout is not supported by the plugin")

    for key, value in kwargs.items():
        found = False
        if atlas_layout:
            item = atlas_layout.itemById(key.lower())
            if isinstance(item, QgsLayoutItemLabel):
                item.setText(value)
                found = True
        logger.info(
            'Additional parameters "{key}" {found} in layout, value "{value}"'.
            format(key=key,
                   found="found" if found else "not found",
                   value=value))

    file_name = "{}_{}.{}".format(clean_string(layout_name), uuid4(),
                                  output_format.name.lower())
    export_path = Path(tempfile.gettempdir()).joinpath(file_name)

    Logger().info("Exporting the request in {} using {}".format(
        export_path, output_format.value))

    if output_format in (OutputFormat.Png, OutputFormat.Jpeg):
        exporter = QgsLayoutExporter(atlas_layout or report_layout)
        result = exporter.exportToImage(str(export_path), settings)
        error = result_message(result)
    elif output_format in (OutputFormat.Svg, ):
        exporter = QgsLayoutExporter(atlas_layout or report_layout)
        result = exporter.exportToSvg(str(export_path), settings)
        error = result_message(result)
    else:
        # Default to PDF
        result, error = QgsLayoutExporter.exportToPdf(atlas or report_layout,
                                                      str(export_path),
                                                      settings)
        # Let's override error message
        _ = error
        error = result_message(result)

    if result != QgsLayoutExporter.Success:
        raise Exception("Export not generated in QGIS exporter {} : {}".format(
            export_path, error))

    if not export_path.is_file():
        logger.warning(
            "No error from QGIS Exporter, but the file does not exist.\n"
            "Message from QGIS exporter : {}\n"
            "File path : {}\n".format(error, export_path))
        raise Exception(
            "Export OK from QGIS, but file not found on the file system : {}".
            format(export_path))

    return export_path
    def test_project_server_validator(self):
        """Test project server validator."""
        project = QgsProject()
        layer = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1',
                               'memory')
        project.addMapLayers([layer])

        # Valid
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertFalse(results)

        layer_1 = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1',
                                 'memory')
        project.addMapLayers([layer_1])

        # Not valid, same layer name
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.DuplicatedNames,
                         results[0].error)

        # Not valid, short name is invalid
        layer_1.setShortName('layer_1_invalid_#')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.LayerShortName,
                         results[0].error)

        # Not valid, same short name as the first layer name
        layer_1.setShortName('layer_1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.DuplicatedNames,
                         results[0].error)

        # Valid
        layer_1.setShortName('layer_1_bis')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertEqual(0, len(results))

        # Not valid, a group with same name as the first layer
        group = project.layerTreeRoot().addGroup('layer_1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.DuplicatedNames,
                         results[0].error)

        # Valid
        group.setCustomProperty('wmsShortName', 'my_group1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertEqual(0, len(results))

        # Not valid, the project title is invalid
        project.setTitle('@ layer 1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.ProjectShortName,
                         results[0].error)

        # Valid project title
        project.setTitle('project_title')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertEqual(0, len(results))

        # Valid despite the bad project title, use project short name
        project.setTitle('@ layer 1')
        project.writeEntry('WMSRootName', '/', 'project_short_name')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertTrue(valid)
        self.assertEqual(0, len(results))

        # Not valid project short name
        project.setTitle('project_title')
        project.writeEntry('WMSRootName', '/', 'project with space')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertFalse(valid)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.ProjectShortName,
                         results[0].error)

        # Not valid, duplicated project short name
        project.writeEntry('WMSRootName', '/', 'layer_1')
        valid, results = QgsProjectServerValidator.validate(project)
        self.assertEqual(1, len(results))
        self.assertEqual(QgsProjectServerValidator.ProjectRootNameConflict,
                         results[0].error)
Example #27
0
    target_dir = sys.argv[sys.argv.index("-D") + 1]
if("-O" in sys.argv):
    output_log = sys.argv[sys.argv.index("-O") + 1]


# Instantiate QGIS
QgsApplication.setPrefixPath(qgisPrefixPath, True)
qgs = QgsApplication([], True)
QgsApplication.initQgis()

# Open the project
p = QgsProject()
p.read(project_path)
canvas = QgsMapCanvas()
bridge = QgsLayerTreeMapCanvasBridge(
    p.layerTreeRoot(),
    canvas
)
bridge.setCanvasLayers()

# Get the layers in the project
layerList = p.mapLayersByName(parcelle_layer)
if not layerList:
    layers = p.mapLayers()
    for lname,layer in layers.items():
        print(lname+' '+layer.name()+' '+parcelle_layer)
    layerList = [ layer for lname,layer in layers.items() if layer.name() == parcelle_layer ]
layer = layerList[0]

# Get Feature
req = QgsFeatureRequest()
Example #28
0
    def testCustomLayerOrder(self):
        """ test project layer order"""
        prj = QgsProject()
        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])

        layer_order_changed_spy = QSignalSpy(prj.layerTreeRoot().customLayerOrderChanged)
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
        self.assertEqual(len(layer_order_changed_spy), 1)
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer])
        self.assertEqual(len(layer_order_changed_spy), 1) # no signal, order not changed

        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer])
        prj.layerTreeRoot().setCustomLayerOrder([layer])
        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer])
        self.assertEqual(len(layer_order_changed_spy), 2)

        # remove a layer
        prj.layerTreeRoot().setCustomLayerOrder([layer2, layer, layer3])
        self.assertEqual(len(layer_order_changed_spy), 3)
        prj.removeMapLayer(layer)
        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer3])
        self.assertEqual(len(layer_order_changed_spy), 4)

        # save and restore
        file_name = os.path.join(QDir.tempPath(), 'proj.qgs')
        prj.setFileName(file_name)
        prj.write()
        prj2 = QgsProject()
        prj2.setFileName(file_name)
        prj2.read()
        self.assertEqual([l.id() for l in prj2.layerTreeRoot().customLayerOrder()], [layer2.id(), layer3.id()])

        # clear project
        prj.clear()
        self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [])
Example #29
0
            self.layBotonera.addWidget(boto)
        self.fBotonera.show()
        spacer = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding,
                                       QtWidgets.QSizePolicy.Minimum)
        self.layBotonera.addSpacerItem(spacer)


# Demo d'ús quan es crida el fitxer de la classe per separat
if __name__ == "__main__":

    with qgisapp() as app:
        # Canvas, projecte i bridge
        canvas = QgsMapCanvas()
        # canvas.show()
        project = QgsProject().instance()
        root = project.layerTreeRoot()
        bridge = QgsLayerTreeMapCanvasBridge(root, canvas)

        # llegim un projecte de demo
        project.read(projecteInicial)

        # Instanciem la classe QvUbicacions
        ubicacions = QvUbicacions(canvas)
        """
        Amb aquesta linia:
        ubicacions.show()
        es veuria el widget suelto, separat del canvas.

        Les següents línies mostren com integrar el widget 'ubicacions' com a dockWidget.
        """