def get_capabilities(self, params: Dict[str, str], response: QgsServerResponse, project: QgsProject) -> None:
        """ Get cadastral capabilities based on config stored as project custom variables
        """
        # get project custom variables
        variables = project.customVariables()

        if 'cadastre_parcelle_layer_id' not in variables or \
                'cadastre_parcelle_unique_field' not in variables:
            raise CadastreError(400, "Project has no cadastral capabilities")

        parcelle_layer_id = variables['cadastre_parcelle_layer_id']
        parcelle_layer_unique_field = variables['cadastre_parcelle_unique_field']

        player = project.mapLayer(parcelle_layer_id)
        if not player:
            raise CadastreError(404, "Parcel layer not available")

        capabilities = {
            'parcelle': {
                'id': player.id(),
                'name': player.name(),
                'title': player.title(),
                'shortName': player.shortName(),
                'unique_field': parcelle_layer_unique_field
            }
        }

        if 'cadastre_section_layer_id' in variables:
            section_layer_id = variables['cadastre_section_layer_id']
            slayer = project.mapLayer(section_layer_id)
            if slayer:
                capabilities['section'] = {
                    'id': slayer.id(),
                    'name': slayer.name(),
                    'title': slayer.title(),
                    'shortName': slayer.shortName()
                }
                if 'cadastre_section_unique_field' in variables:
                    capabilities['section']['unique_field'] = variables['cadastre_section_unique_field']

        if 'cadastre_commune_layer_id' in variables:
            commune_layer_id = variables['cadastre_commune_layer_id']
            slayer = project.mapLayer(commune_layer_id)
            if slayer:
                capabilities['commune'] = {
                    'id': slayer.id(),
                    'name': slayer.name(),
                    'title': slayer.title(),
                    'shortName': slayer.shortName()
                }
                if 'cadastre_commune_unique_field' in variables:
                    capabilities['commune']['unique_field'] = variables['cadastre_commune_unique_field']

        write_json_response({
            'status': 'success',
            'message': 'Capabilities',
            'data': capabilities
        }, response)
Example #2
0
    def test_style_delete(self):
        """Test delete style"""

        self.assertTrue(self.qdjango_layer.delete_style('style2'))
        self.assertFalse(self.qdjango_layer.delete_style('style1'))

        # Verify
        p = QgsProject()
        p.read(self.qdjango_project.qgis_project.fileName())
        l = p.mapLayer(self.qdjango_layer.qgis_layer.id())
        self.assertTrue(l.isValid())
        sm = l.styleManager()
        self.assertEqual(sm.styles(), ['style1'])
        del(sm)
        del(p)
Example #3
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 #4
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 #5
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 #6
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 #7
0
    def actions(nameAction, params):
        def _getRasterLayer(feature):
            pathfile = feature.attribute('pathfile')
            info = QFileInfo(pathfile)
            if not info.exists():
                return {
                    'isOk': False,
                    'message': "Raster file '{}' not found".format(pathfile)
                }

            sources = dict([(layer.source(), layer)
                            for layer in project.mapLayers().values()])
            if pathfile in sources.keys():
                layer = sources[pathfile]
                needAdd = False
            else:
                name = QFileInfo(pathfile).completeBaseName()
                layer = QgsRasterLayer(pathfile, name)
                needAdd = True
            return {'isOk': True, 'layer': layer, 'needAdd': needAdd}

        def _addRaster(layer):
            project.addMapLayer(layer)
            ltl = project.layerTreeRoot().findLayer(layer)
            ltl.setItemVisibilityChecked(True)
            ltl.setExpanded(False)

        # Actions functions
        def flash():
            m = MapCanvasFeature()
            m.flash(layer, feature)
            return {'isOk': True}

        def zoom():
            m = MapCanvasFeature()
            m.zoom(layer, feature)
            return {'isOk': True}

        def show_hideImage():
            r = _getRasterLayer(feature)
            if not r['isOk']:
                return r
            if r['needAdd']:
                _addRaster(r['layer'])
            else:
                ltl = project.layerTreeRoot().findLayer(r['layer'])
                ltl.setItemVisibilityChecked(not ltl.isVisible())
            return {'isOk': True}

        def setCurrent():
            r = _getRasterLayer(feature)
            if not r['isOk']:
                return r
            if r['needAdd']:
                _addRaster(r['layer'])
            else:
                QgsUtils.iface.setActiveLayer(r['layer'])
            return {'isOk': True}

        def setZeroTransparency():
            def existsCatalog(raster):
                vfilter = '"pathfile" = \'{}\''.format(raster.source())
                viter = layer.getFeatures(vfilter)
                feat = QgsFeature()
                vreturn = viter.nextFeature(feat)
                del feat
                return vreturn

            maplayers = map(lambda ltl: ltl.layer(),
                            StyleOutputFootPrint.root.findLayers())
            rasters = filter(
                lambda layer: layer.type() == QgsMapLayer.RasterLayer,
                maplayers)
            for raster in rasters:
                if existsCatalog(raster):
                    RasterTransparency.setTransparency(raster)

            return {'isOk': True}

        actionsFunc = {
            'flash': flash,
            'zoom': zoom,
            'show_hideImage': show_hideImage,
            'setCurrent': setCurrent,
            'setZeroTransparency': setZeroTransparency
        }
        if not nameAction in actionsFunc.keys():
            return {
                'isOk': False,
                'message': "Missing action '{}'".format(nameAction)
            }
        project = QgsProject().instance()
        layer = project.mapLayer(params['layer_id'])
        if 'feature_id' in params:
            feature = layer.getFeature(params['feature_id'])
        return actionsFunc[nameAction]()
Example #8
0
    def onItemChanged(self, layerType, item):
        """
        Get data when table item content has changed
        And store it for future use
        """

        # Get table
        if layerType == 'vector':
            table = self.dlg.vectorLayers
        elif layerType == 'raster':
            table = self.dlg.rasterLayers
        else:
            return

        # Get row and column
        row = item.row()
        col = item.column()

        # Unselect row and item
        table.clearSelection()

        # Get layer
        layerId = table.item(row, 0).data(Qt.EditRole)
        lr = QgsProject().instance()
        layer = lr.mapLayer(layerId)
        if not layer:
            return

        # Get changed property
        prop = self.layersAttributes[layerType][col]['key']
        data = table.item(row, col).data(Qt.EditRole)

        # test if new datasource prop is valid otherwise restore previous data
        if prop == 'source|uri' and not self.newDatasourceIsValid(layer, data):
            table.itemChanged.disconnect()
            item.setData(Qt.EditRole, self.getLayerProperty(layer, 'source|uri'))
            slot = partial(self.onItemChanged, layerType)
            table.itemChanged.connect(slot)
            return

        # Check encoding and revert if problem
        if prop == 'encoding' and data not in layer.dataProvider().availableEncodings():
            table.itemChanged.disconnect()
            item.setData(Qt.EditRole, self.getLayerProperty(layer, 'encoding'))
            slot = partial(self.onItemChanged, layerType)
            table.itemChanged.connect(slot)
            return

        #  Check shortname and modify to remove unwanted chars
        if prop == 'shortname':
            table.itemChanged.disconnect()
            newshortname = re.sub('[^A-Za-z0-9\.-]', '_', data)
            item.setData(Qt.EditRole, newshortname)
            slot = partial(self.onItemChanged, layerType)
            table.itemChanged.connect(slot)

        # Store data in global property
        self.layerBoardChangedData[layerType][layerId][prop] = data

        # Change cell background
        table.item(row, col).setBackground(Qt.yellow)
Example #9
0
    def populateLayerTable(self, layerType):
        """
        Fill the table for a given layer type
        """
        # Get parameters for the widget
        lt = self.layersTable[layerType]
        table = lt['tableWidget']

        # Reset layerBoardChangedData
        self.layerBoardChangedData[layerType] = {}

        # disconnect itemChanged signal
        try:
            table.itemChanged.disconnect()
        except Exception:
            pass

        attributes = self.layersTable['generic']['attributes'] + lt['attributes']
        self.layersAttributes[layerType] = attributes

        self.layerBoardData[layerType] = []
        headerData = [a['key'] for a in attributes]
        self.layerBoardData[layerType].append(headerData)

        # empty previous content
        for row in range(table.rowCount()):
            table.removeRow(row)
        table.setRowCount(0)
        table.setColumnCount(0)

        # create columns and header row
        columns = [a['key'] for a in attributes]
        columnsLabels = [a['label'] for a in attributes]
        colCount = len(columns)
        table.setColumnCount(colCount)
        table.setHorizontalHeaderLabels(tuple(columnsLabels))

        # load content from project layers
        lr = QgsProject().instance()
        for lid in lr.mapLayers():
            layer = lr.mapLayer(lid)

            if layerType == 'vector' and layer.type() != QgsMapLayer.VectorLayer:
                continue
            if layerType == 'raster' and layer.type() != QgsMapLayer.RasterLayer:
                continue

            # Add layer in the layerBoardChangedData
            self.layerBoardChangedData[layerType][lid] = {}
            lineData = []

            # Set row and column count
            twRowCount = table.rowCount()
            # add a new line
            table.setRowCount(twRowCount + 1)
            table.setColumnCount(colCount)
            i = 0

            # get information
            for attr in attributes:
                newItem = QTableWidgetItem()
                newItem.setToolTip(layer.name())

                if layerType == 'vector' and not layer.isSpatial() and attr.get('spatial_only'):
                    newItem.setFlags(Qt.NoItemFlags)
                # Is editable or not
                elif attr.get('editable'):
                    newItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled)
                else:
                    newItem.setFlags(Qt.ItemIsSelectable)

                # Item value
                if layerType == 'vector' and not layer.isSpatial() and attr.get('spatial_only'):
                    value = None
                else:
                    value = self.getLayerProperty(layer, attr['key'])
                newItem.setData(Qt.EditRole, value)

                # Add cell data to lineData
                # encode it in the file system encoding, only if needed
                # TODO DISABLED due to migration to Python 3, related to CSV export
                # if hasattr(value, 'encode'):
                #     value = value.encode(sys.getfilesystemencoding())
                lineData.append(value)

                if attr['key'] == 'name':
                    icon = QgsMapLayerModel.iconForLayer(layer)
                    newItem.setIcon(icon)

                # Add item
                table.setItem(twRowCount, i, newItem)
                i += 1

            # Add data to layerBoardData
            self.layerBoardData[layerType].append(lineData)

        # Launch slot on item changed slot
        slot = partial(self.onItemChanged, layerType)
        table.itemChanged.connect(slot)
Example #10
0
    def test_model_methods(self):
        """Test model style manager CRUD methods"""

        self.assertEqual(self.qdjango_layer.styles, [
            {
                'name': 'style1',
                'current': False
            },
            {
                'name': 'style2',
                'current': True
            },
        ])

        self.assertFalse(self.qdjango_project.is_dirty)
        self.assertFalse(
            self.qdjango_layer.set_current_style('style1234567890'))
        self.assertTrue(self.qdjango_layer.set_current_style('style1'))
        self.assertTrue(self.qdjango_project.is_dirty)
        self.assertEqual(self.qdjango_layer.styles, [
            {
                'name': 'style1',
                'current': True
            },
            {
                'name': 'style2',
                'current': False
            },
        ])

        # Verify the project was written
        p = QgsProject()
        p.read(self.qdjango_project.qgis_project.fileName())
        l = p.mapLayer(self.qdjango_layer.qgis_layer.id())
        self.assertTrue(l.isValid())
        sm = l.styleManager()
        self.assertEqual(sm.currentStyle(), 'style1')
        del(sm)
        del(p)

        # Test rename
        self.assertFalse(self.qdjango_layer.rename_style(
            'style1234567890', 'new_name'))
        self.assertFalse(self.qdjango_layer.rename_style('style2', 'style1'))
        self.assertTrue(self.qdjango_layer.rename_style('style2', 'new_name'))
        self.assertTrue(self.qdjango_layer.rename_style('style1', 'new_name1'))
        self.assertTrue(self.qdjango_layer.rename_style('new_name1', 'style1'))

        # Verify the project was written
        p = QgsProject()
        p.read(self.qdjango_project.qgis_project.fileName())
        l = p.mapLayer(self.qdjango_layer.qgis_layer.id())
        self.assertTrue(l.isValid())
        sm = l.styleManager()
        self.assertEqual(sm.styles(), ['new_name', 'style1'])
        del(sm)
        del(p)

        # Test remove/delete
        self.assertFalse(self.qdjango_layer.delete_style('style1234567890'))
        self.assertTrue(self.qdjango_layer.delete_style('style1'))
        self.assertFalse(self.qdjango_layer.delete_style('new_name'))
        assert self.qdjango_layer.rename_style('new_name', 'style1')

        # Verify the project was written
        p = QgsProject()
        p.read(self.qdjango_project.qgis_project.fileName())
        l = p.mapLayer(self.qdjango_layer.qgis_layer.id())
        self.assertTrue(l.isValid())
        sm = l.styleManager()
        self.assertEqual(sm.styles(), ['style1'])
        del(sm)
        del(p)

        # Test add new style
        with open(os.path.join(
                CURRENT_PATH + TEST_BASE_PATH, 'multiple_styles_manager_test.qml'), 'r') as f:
            qml = f.read()

        self.assertFalse(self.qdjango_layer.add_style('style1', qml))
        self.assertTrue(self.qdjango_layer.add_style(
            'My new fancy èé style', qml))

        # Verify the project was written
        p = QgsProject()
        p.read(self.qdjango_project.qgis_project.fileName())
        l = p.mapLayer(self.qdjango_layer.qgis_layer.id())
        self.assertTrue(l.isValid())
        sm = l.styleManager()
        self.assertEqual(sm.styles(), ['My new fancy èé style', 'style1'])
        del(sm)
        del(p)

        # Test invalid QML
        self.assertFalse(self.qdjango_layer.add_style(
            'My invalid style', '<xxxx>this is not a valid style</xxxx>'))

        # Restore the project and check the dirt flag
        project_file = File(open(self.project_path, 'r'))
        project = QgisProject(project_file)
        project.instance = self.qdjango_project
        project.title = 'Test qdjango postgres multiple styles manager project'
        project.group = self.project_group
        project.save()
        self.assertFalse(self.qdjango_project.is_dirty)
Example #11
0
 def test_layer_info(self):
     p = QgsProject()
     p.read(list(projects().values())[1])
     info = layer_info(
         p.mapLayer('points_842425df_7f45_4091_a6c9_086e1dc1edd1'))
     self.assertEqual(info['name'], 'points')
     self.assertEqual(info['id'],
                      'points_842425df_7f45_4091_a6c9_086e1dc1edd1')
     self.assertEqual(
         info['metadata']['categories'],
         ['Geoscientific Information', 'Imagery Base Maps Earth Cover'])
     self.assertEqual(
         info['metadata']['contacts'][0], {
             'name':
             'Layer Metadata Contact Name',
             'role':
             'distributor',
             'email':
             'Layer Metadata Contact Email',
             'fax':
             'Layer Metadata Contact Fax',
             'voice':
             'Layer Metadata Contact Voice',
             'organization':
             'Layer Metadata Contact Organization',
             'position':
             'Layer Metadata Contact Position',
             'addresses': [{
                 'address': 'street 1',
                 'city': 'Milan',
                 'country': 'Italy',
                 'postalCode': '10021',
                 'type': 'postal',
                 'administrativeArea': 'Lombardy'
             }]
         })
     self.assertEqual(
         info['fields'], {
             'fid': {
                 'type': 'Integer64',
                 'label': 'fid',
                 'precision': 0,
                 'length': 0,
                 'not_null': True,
                 'unique': True,
                 'has_expression': False,
                 'default': 'Autogenerate',
                 'expression': '',
                 'editable': False
             },
             'name': {
                 'type': 'String',
                 'label': 'name',
                 'precision': 0,
                 'length': 0,
                 'not_null': False,
                 'unique': False,
                 'has_expression': False,
                 'default': '',
                 'expression': '',
                 'editable': True
             }
         })