コード例 #1
0
ファイル: test_ows.py プロジェクト: lucamanga/g3w-admin
    def test_get_qgs_project(self):
        """test get_qgs_project"""

        qgs_project = get_qgs_project(self.qdjango_project.qgis_file.path)
        self.assertTrue(isinstance(qgs_project, QgsProject))
        qgs_project = self.qdjango_project.qgis_project
        self.assertTrue(isinstance(qgs_project, QgsProject))
コード例 #2
0
    def qgis_project(self):
        """Returns the QgsProject instance corresponding to this Project, or None in case of errors

        :return: the QgsProject instance
        :rtype: QgsProject or None
        """

        from qdjango.apps import get_qgs_project
        return get_qgs_project(self.qgis_file.path)
コード例 #3
0
ファイル: test_app.py プロジェクト: nstoykov/g3w-admin
    def test_get_qgs_project_virtual_layer(self):
        """test get_qgs_project with virtual layers geopackage_join.qgs (issue with invalid layers and QgsProject.setInstance)"""

        qgs_project = get_qgs_project('{}{}{}'.format(CURRENT_PATH,
                                                      TEST_BASE_PATH,
                                                      'geopackage_join.qgs'))
        self.assertTrue(isinstance(qgs_project, QgsProject))
        for layer in list(qgs_project.mapLayers().values()):
            self.assertTrue(layer.isValid(),
                            'Layer %s is not valid!' % layer.id())
コード例 #4
0
ファイル: test_api.py プロジェクト: leolami/g3w-admin
    def testCoreVectorApiConfig(self):
        """Test core-vector-api config"""

        # Add a constraint expression to "name" field
        project = get_qgs_project(
            Layer.objects.get(qgs_layer_id='spatialite_points20190604101052075'
                              ).project.qgis_file.path)
        layer = project.mapLayers()['spatialite_points20190604101052075']
        layer.setFieldConstraint(1, QgsFieldConstraints.ConstraintExpression,
                                 QgsFieldConstraints.ConstraintStrengthHard)
        layer.setConstraintExpression(1, '"name" != \'my name is no name\'')
        response = self._testApiCall(
            'core-vector-api',
            ['config', 'qdjango', '1', 'spatialite_points20190604101052075'])
        resp = json.loads(response.content)
        self.assertIsNone(resp["vector"]["count"])
        self.assertEqual(resp["vector"]["format"], "GeoJSON")
        self.assertEqual(resp["vector"]["fields"], [{
            'name': 'pkuid',
            'type': 'bigint',
            'label': 'pkuid',
            'editable': False,
            'validate': {
                'required': True,
                'unique': True
            },
            'pk': True,
            'default': 'Autogenerate',
            'input': {
                'type': 'text',
                'options': {}
            }
        }, {
            'name': 'name',
            'type': 'varchar',
            'label': 'name',
            'editable': True,
            'validate': {
                'expression': '"name" != \'my name is no name\''
            },
            'pk': False,
            'default': '',
            'input': {
                'type': 'text',
                'options': {}
            }
        }])
        self.assertEqual(resp["vector"]["geometrytype"], "Point")
        self.assertIsNone(resp["vector"]["data"])
        self.assertTrue(resp["result"])
        self.assertIsNone(resp["featurelocks"])
コード例 #5
0
ファイル: models.py プロジェクト: nstoykov/g3w-admin
def get_capabilities4layer(qgs_maplayer=None, **kwargs):
    """
    Return bitwise layer capabilities (by QGIS consts) values
    :param qgs_maplayer: QgsMapLayer instance
    :param **kwargs: optional params
    :return: int
    """

    # get qgs_maplayer if not set
    if not qgs_maplayer:
        qgs_maplayer = get_qgs_project(kwargs['layer'].project.qgis_file.path).mapLayers()[kwargs['layer'].qgs_layer_id]

    capabilities = 0
    if bool(qgs_maplayer.flags() & QgsMapLayer.Identifiable):
        capabilities |= settings.QUERYABLE
    if bool(qgs_maplayer.flags() & QgsMapLayer.Searchable):
        capabilities |= settings.FILTRABLE

    return capabilities
コード例 #6
0
def get_qgis_layer(layer_info):
    """Returns a QGIS vector layer from a layer information record.
    The layer is normally not a clone but it is the live
    instance of the QgsProject it belongs to. If the project does not exist
    a new layer will be created.

    :param layer_info: layer record from g3w suite table
    :type layer_info: Layer
    :return: a (possibly invalid) QGIS vector layer
    :rtype: QgsVectorLayer
    """

    try:
        project = get_qgs_project(layer_info.project.qgis_file.path)
        return project.mapLayers()[layer_info.qgs_layer_id]
    except:
        provider_name = layer_info.layer_type
        datasource = layer_info.datasource
        name = layer_info.name
        return QgsVectorLayer(datasource, name, provider_name)
コード例 #7
0
ファイル: serializers.py プロジェクト: lucamanga/g3w-admin
    def to_representation(self, instance):
        ret = super(ProjectSerializer, self).to_representation(instance)

        # add a QGSMapLayer instance
        qgs_project = get_qgs_project(instance.qgis_file.path)

        # set init and map extent
        ret['initextent'], ret['extent'] = self.get_map_extent(instance)

        ret['print'] = json.loads(clean_for_json(
            instance.layouts)) if instance.layouts else []

        # add layers data, widgets
        # init proprties
        ret['layers'] = []
        ret['search'] = []
        ret['widget'] = []
        ret['relations'] = []
        ret['no_legend'] = []
        layers = {l.qgs_layer_id: l for l in instance.layer_set.all()}

        # check fo title
        if hasattr(settings, 'G3W_CLIENT_SEARCH_TITLE'):
            ret['search_title'] = _(settings.G3W_CLIENT_SEARCH_TITLE)

        # for client map like multilayer
        meta_layer = QdjangoMetaLayer()
        to_remove_from_layerstree = []

        def readLeaf(layer, container):
            if 'nodes' in layer:
                for node in layer['nodes']:
                    readLeaf(node, layer['nodes'])
            else:
                layer_serialized = LayerSerializer(layers[layer['id']],
                                                   qgs_project=qgs_project)
                layer_serialized_data = layer_serialized.data

                # alter layer serialized data from plugin
                # send layerseralized original and came back only key->value changed
                for signal_receiver, data in after_serialized_project_layer.send(
                        layer_serialized, layer=layers[layer['id']]):
                    update_serializer_data(layer_serialized_data, data)
                layer_serialized_data[
                    'multilayer'] = meta_layer.getCurrentByLayer(
                        layer_serialized_data)

                # check for vectorjoins and add to project relations
                if layer_serialized_data['vectorjoins']:
                    ret['relations'] += self.get_map_layers_relations_from_vectorjoins(
                        layer['id'], layer_serialized_data['vectorjoins'],
                        layers)
                del (layer_serialized_data['vectorjoins'])

                ret['layers'].append(layer_serialized_data)

                # get widgects for layer
                widgets = layers[layer['id']].widget_set.all()
                for widget in widgets:
                    widget_serializzer_data = WidgetSerializer(
                        widget, layer=layers[layer['id']]).data
                    if widget_serializzer_data['type'] == 'search':
                        widget_serializzer_data['options']['layerid'] = layer[
                            'id']
                        widget_serializzer_data['options'][
                            'querylayerid'] = layer['id']
                        ret['search'].append(widget_serializzer_data)
                    else:
                        load_qdjango_widget_layer.send(self,
                                                       layer=layer,
                                                       ret=ret,
                                                       widget=widget)

                # add exclude to legend
                if layers[layer['id']].exclude_from_legend:
                    ret['no_legend'].append(layers[layer['id']].qgs_layer_id)

        for l in ret['layerstree']:
            readLeaf(l, ret['layerstree'])

        # remove layers from layerstree
        for to_remove in to_remove_from_layerstree:
            to_remove[0].remove(to_remove[1])

        # add baselayer default
        ret['initbaselayer'] = instance.baselayer.id if instance.baselayer else None

        # add relations if exists
        if instance.relations:
            ret['relations'] += self.get_map_layers_relations(instance)

        # add project metadata
        ret['metadata'] = self.get_metadata(instance, qgs_project)

        # set client options/actions
        ret.update(self._set_options(instance))

        # set ow method
        ret['ows_method'] = self._set_ows_method(instance)

        # add html_page_title
        ret['html_page_title'] = u'{} | {}'.format(
            getattr(settings, 'G3WSUITE_CUSTOM_TITLE', 'g3w - client'),
            instance.title_ur if instance.title_ur else instance.title)

        # set name by language if is set
        if instance.title_ur:
            ret['name'] = instance.title_ur

        # Set to macrogroup images if options use_logo is checked
        try:
            macrogroup = instance.group.macrogroups.get(use_logo_client=True)
            ret['thumbnail'] = macrogroup.logo_img.url
        except:
            pass

        ret['search_endpoint'] = settings.G3W_CLIENT_SEARCH_ENDPOINT

        return ret
コード例 #8
0
ファイル: views.py プロジェクト: nstoykov/g3w-admin
    def layerstree(self, request, **kwargs):

        try:

            # Retrieve project qdjando instance and qgsproject instance
            project = get_object_or_404(Project, pk=kwargs['project_id'])
            qgs_project = get_qgs_project(project.qgis_file.path)

            # Validation theme name
            theme_collections = qgs_project.mapThemeCollection()
            map_themes = theme_collections.mapThemes()
            theme_name = kwargs['theme_name']

            if len(map_themes) == 0:
                raise Exception(
                    f"Themes are not available for project {project.title}")

            if theme_name not in map_themes:
                raise Exception(f"Theme name '{theme_name}' is not available!")

            map_theme = theme_collections.mapThemeState(theme_name)

            # Get node group expanded anche checked
            node_group_expanded = map_theme.expandedGroupNodes()
            node_group_checked = map_theme.checkedGroupNodes()

            # Layers checked are layers into mapTheme layerRecords
            node_layerids_checked = []
            for r in map_theme.layerRecords():
                id = r.layer().id()
                if id not in node_layerids_checked:
                    node_layerids_checked.append(id)

            def build_group_name_by_parents(node):

                parent = node.parent()
                if parent and parent.nodeType() == 0 and parent.name() != '':
                    return build_group_name_by_parents(
                        parent) + '/' + node.name()
                else:
                    return node.name()

            def build_tree(layertreenode):
                toRetLayers = []
                for node in layertreenode.children():

                    toRetLayer = {'name': node.name()}

                    try:
                        # try for layer node
                        toRetLayer.update({
                            'id':
                            node.layerId(),
                            'visible':
                            True if node.layerId() in node_layerids_checked
                            else False
                        })

                    except:

                        # Try to build by parent
                        deep_tree_name = build_group_name_by_parents(node)

                        toRetLayer.update({
                            'mutually-exclusive':
                            node.isMutuallyExclusive(),
                            'nodes':
                            build_tree(node),
                            'checked':
                            True
                            if deep_tree_name in node_group_checked else False,
                            'expanded':
                            True
                            if deep_tree_name in node_group_expanded else False
                        })

                    toRetLayers.append(toRetLayer)
                return toRetLayers

            layers_tree = build_tree(qgs_project.layerTreeRoot())

            self.results.results.update({'data': layers_tree})

        except Http404 as e:
            self.results.error = f"Project with id {kwargs['project_id']} not found!"
            self.results.result = False

        except Exception as e:
            self.results.error = str(e)
            self.results.result = False

        return Response(self.results.results)
コード例 #9
0
ファイル: views.py プロジェクト: lucamanga/g3w-admin
    def response_commit_mode(self, request):
        """
        Perform commit operation with data
        :param request: API request object
        :return: Vector params
        """

        # get post data from request object
        # data = request.data
        # post_layer_data = data[self.layer_name]
        post_layer_data = request.data

        new_relations = dict()

        # Store references to all layers that have been made editable,
        # used to commit/rollback at the end of the loop and on errors
        editing_layers = []

        # Get the layer
        qgis_layer = self.metadata_layer.qgis_layer

        # Get the project
        qgis_project = get_qgs_project(
            Layer.objects.get(
                pk=self.metadata_layer.layer_id).project.qgis_file.path)

        # Check if we have transaction groups activated
        # Performs all operations in the editing buffer if we have transactions
        has_transactions = qgis_project.transactionGroup(
            qgis_layer.providerType(),
            QgsDataSourceUri(qgis_layer.source()).connectionInfo()) is not None

        try:

            if has_transactions:

                # Start layer editing on main layer
                if not self.metadata_layer.qgis_layer.startEditing():
                    raise Exception(
                        _('Layer %s is not editable!') %
                        self.metadata_layer.qgis_layer.name())

                editing_layers.append(self.metadata_layer.qgis_layer)

            ref_insert_ids, ref_lock_ids = self.save_vector_data(
                self.metadata_layer, post_layer_data, has_transactions)

            # get every relationsedits
            post_relations_data = dict()
            if self.relations_data_key in post_layer_data and bool(
                    post_layer_data[self.relations_data_key]):
                post_relations_data = post_layer_data[self.relations_data_key]

            # save relations if post data exists
            for referencing_layer in self.metadata_relations.keys():

                if referencing_layer in post_relations_data:

                    post_relation_data = post_relations_data[referencing_layer]

                    if has_transactions:
                        # Editing on related layers has already started because
                        # it's part of a transaction group
                        editing_layers.append(
                            self.metadata_relations[referencing_layer].
                            qgis_layer)

                    # instance lock for relation
                    self.metadata_relations[referencing_layer].lock = LayerLock(
                        appName=self.app_name,
                        layer=self.metadata_relations[referencing_layer].layer,
                        user=request.user,
                        sessionid=self.sessionid)

                    insert_ids, lock_ids = self.save_vector_data(
                        self.metadata_relations[referencing_layer],
                        post_relation_data,
                        has_transactions,
                        referenced_layer_insert_ids=ref_insert_ids)
                    new_relations[referencing_layer] = {
                        'new': insert_ids,
                        'new_lockids': lock_ids
                    }

            if has_transactions:
                # Commit changes on all editable layers
                # The check is required because when committing the
                # "parent" layer in a transaction group all other layers are
                # committed as well.
                for ql in editing_layers:
                    if ql.isEditable() and not ql.commitChanges():
                        raise Exception(
                            _('Backend error saving layer %s: %s') %
                            (ql.name(), ql.commitErrors()))

        except ValidationError as ve:

            if has_transactions:
                for ql in editing_layers:
                    ql.rollBack()

            self.results.update({'result': False, 'errors': ve.detail})

        except Exception as e:

            if has_transactions:
                for ql in editing_layers:
                    ql.rollBack()

            self.results.update({'result': False, 'errors': str(e)})

        try:
            self.results.update({
                'response': {
                    'new': ref_insert_ids,
                    'new_lockids': ref_lock_ids,
                    'new_relations': new_relations
                }
            })
        except:
            pass
コード例 #10
0
ファイル: serializers.py プロジェクト: leolami/g3w-admin
    def to_representation(self, instance):
        logging.warning('Serializer')
        ret = super(ProjectSerializer, self).to_representation(instance)
        logging.warning('Before reading project')

        # add a QGSMapLayer instance
        qgs_project = get_qgs_project(instance.qgis_file.path)

        logging.warning('Got project: %s' % qgs_project.fileName())

        # set init and map extent
        ret['initextent'], ret['extent'] = self.get_map_extent(instance)

        ret['print'] = json.loads(clean_for_json(
            instance.layouts)) if instance.layouts else []

        # Get layer which request.user can view:
        if self.request:
            view_layer_ids = [l.qgs_layer_id for l in get_objects_for_user(self.request.user, 'qdjango.view_layer', Layer) \
            | get_objects_for_user(get_anonymous_user(), 'qdjango.view_layer', Layer)]

        # add layers data, widgets
        # init properties
        if qgs_project.layerTreeRoot().hasCustomLayerOrder():
            ret['layers'] = {}
        else:
            ret['layers'] = []
        ret['search'] = []
        ret['widget'] = []
        ret['relations'] = []

        layers = {l.qgs_layer_id: l for l in instance.layer_set.all()}

        # check fo title
        if hasattr(settings, 'G3W_CLIENT_SEARCH_TITLE'):
            ret['search_title'] = _(settings.G3W_CLIENT_SEARCH_TITLE)

        # for client map like multilayer
        meta_layer = QdjangoMetaLayer()
        to_remove_from_layerstree = []

        def readLeaf(layer, container):

            if 'nodes' in layer:
                for node in layer['nodes']:
                    readLeaf(node, layer['nodes'])
            else:

                # Check for empty vector layer
                if settings.G3W_CLIENT_NOT_SHOW_EMPTY_VECTORLAYER and self.layer_is_empty(
                        layers[layer['id']]):
                    return

                # Check if layer is visible for user
                if self.request and not layer['id'] in view_layer_ids:
                    return

                try:
                    layer_serialized = LayerSerializer(layers[layer['id']],
                                                       qgs_project=qgs_project)
                except KeyError:
                    logger.error('Layer %s is missing from QGIS project!' %
                                 layer['id'])
                    return

                layer_serialized_data = layer_serialized.data

                # alter layer serialized data from plugin
                # send layerseralized original and came back only key->value changed
                for signal_receiver, data in after_serialized_project_layer.send(
                        layer_serialized,
                        layer=layers[layer['id']],
                        request=self.request):
                    update_serializer_data(layer_serialized_data, data)
                layer_serialized_data[
                    'multilayer'] = meta_layer.getCurrentByLayer(
                        layer_serialized_data)

                # check for vectorjoins and add to project relations
                if layer_serialized_data['vectorjoins']:
                    ret['relations'] += self.get_map_layers_relations_from_vectorjoins(
                        layer['id'], layer_serialized_data['vectorjoins'],
                        layers)
                del (layer_serialized_data['vectorjoins'])

                if qgs_project.layerTreeRoot().hasCustomLayerOrder():
                    ret['layers'].update(
                        {layer_serialized_data['id']: layer_serialized_data})
                else:
                    ret['layers'].append(layer_serialized_data)

                # get widgects for layer
                widgets = layers[layer['id']].widget_set.all()
                for widget in widgets:
                    widget_serializzer_data = WidgetSerializer(
                        widget, layer=layers[layer['id']]).data
                    if widget_serializzer_data['type'] == 'search':
                        widget_serializzer_data['options']['layerid'] = layer[
                            'id']
                        widget_serializzer_data['options'][
                            'querylayerid'] = layer['id']
                        ret['search'].append(widget_serializzer_data)
                    else:
                        load_qdjango_widget_layer.send(self,
                                                       layer=layer,
                                                       ret=ret,
                                                       widget=widget)

        for l in ret['layerstree']:
            readLeaf(l, ret['layerstree'])

        # remove layers from layerstree
        for to_remove in to_remove_from_layerstree:
            to_remove[0].remove(to_remove[1])

        # for custom order layer
        # ======================
        if qgs_project.layerTreeRoot().hasCustomLayerOrder():
            custom_layer_order_ids = []
            new_order = []
            meta_layer = QdjangoMetaLayer()
            for qgs_layer in qgs_project.layerTreeRoot().customLayerOrder():
                if qgs_layer.id() in ret['layers']:
                    custom_layer_order_ids.append(qgs_layer.id())
                    lsd = ret['layers'][qgs_layer.id()]
                    lsd['multilayer'] = meta_layer.getCurrentByLayer(lsd)
                    new_order.append(lsd)

            # get layers not in customLayerOrder to add an the end of return layers list
            to_add_to_end = set(
                ret['layers'].keys()) - set(custom_layer_order_ids)
            for qgs_layer_id in list(to_add_to_end):
                lsd = ret['layers'][qgs_layer_id]
                lsd['multilayer'] = meta_layer.getCurrentByLayer(lsd)
                new_order.append(lsd)

            ret['layers'] = new_order

        # add baselayer default
        ret['initbaselayer'] = instance.baselayer.id if instance.baselayer else None

        # add relations if exists
        if instance.relations:
            ret['relations'] += self.get_map_layers_relations(instance)

        # add project metadata
        ret['metadata'] = self.get_metadata(instance, qgs_project)

        # set client options/actions
        ret.update(self._set_options(instance))

        # set ow method
        ret['ows_method'] = self._set_ows_method(instance)

        # add html_page_title
        ret['html_page_title'] = u'{} | {}'.format(
            getattr(settings, 'G3WSUITE_CUSTOM_TITLE', 'g3w - client'),
            instance.title_ur if instance.title_ur else instance.title)

        # set name by language if is set
        if instance.title_ur:
            ret['name'] = instance.title_ur

        # Set to macrogroup images if options use_logo is checked
        try:
            if instance.group.use_logo_client:
                ret['thumbnail'] = instance.group.header_logo_img.url
            else:
                macrogroup = instance.group.macrogroups.get(
                    use_logo_client=True)
                ret['thumbnail'] = macrogroup.logo_img.url
        except:
            pass

        ret['search_endpoint'] = settings.G3W_CLIENT_SEARCH_ENDPOINT

        # reset tokenfilter by session
        self.reset_filtertoken()

        return ret
コード例 #11
0
ファイル: test_api.py プロジェクト: leolami/g3w-admin
    def testPagination(self):
        """Test pagination"""

        world = Layer.objects.get(name='world')
        qgis_project = get_qgs_project(world.project.qgis_file.path)
        qgis_layer = qgis_project.mapLayer(world.qgs_layer_id)

        response = self._testApiCall(
            'core-vector-api', ['data', 'qdjango', '1', world.qgs_layer_id], {
                'in_bbox': '10.60,44.34,10.70,44.36',
            })
        resp = json.loads(response.content)
        self.assertEqual(resp['vector']['count'], 1)

        # There is one feature returned by the query
        self.assertEqual(len(resp['vector']['data']['features']), 1)

        # Now we get 36 countries:
        resp = json.loads(
            self._testApiCall('core-vector-api',
                              ['data', 'qdjango', '1', world.qgs_layer_id], {
                                  'in_bbox': '-5,-4,12,80',
                              }).content)
        self.assertEqual(len(resp['vector']['data']['features']), 36)
        self.assertEqual(resp['vector']['count'], 36)

        # Start paging
        # We have 4 full pages plus one of four
        for page in range(1, 4):
            resp = json.loads(
                self._testApiCall(
                    'core-vector-api',
                    ['data', 'qdjango', '1', world.qgs_layer_id], {
                        'in_bbox': '-5,-4,12,80',
                        'page': page,
                        'page_size': 8,
                        'ordering': 'ogc_fid',
                    }).content)
            self.assertEqual(len(resp['vector']['data']['features']), 8)
            self.assertEqual(resp['vector']['count'], 36)

        resp = json.loads(
            self._testApiCall(
                'core-vector-api',
                ['data', 'qdjango', '1', world.qgs_layer_id], {
                    'in_bbox': '-5,-4,12,80',
                    'page': 5,
                    'page_size': 8,
                    'ordering': 'ogc_fid',
                }).content)
        self.assertEqual(len(resp['vector']['data']['features']), 4)
        self.assertEqual(resp['vector']['count'], 36)

        # Or one single page of 36 elements and 0 next pages
        resp = json.loads(
            self._testApiCall(
                'core-vector-api',
                ['data', 'qdjango', '1', world.qgs_layer_id], {
                    'in_bbox': '-5,-4,12,80',
                    'page': 1,
                    'page_size': 36,
                    'ordering': 'ogc_fid',
                }).content)
        self.assertEqual(len(resp['vector']['data']['features']), 36)
        self.assertEqual(resp['vector']['count'], 36)

        resp = json.loads(
            self._testApiCall(
                'core-vector-api',
                ['data', 'qdjango', '1', world.qgs_layer_id], {
                    'in_bbox': '-5,-4,12,80',
                    'page': 2,
                    'page_size': 36,
                    'ordering': 'ogc_fid',
                }).content)
        self.assertEqual(len(resp['vector']['data']['features']), 0)
        self.assertEqual(resp['vector']['count'], 36)
コード例 #12
0
    def baseDoRequest(self, q):

        request = self.request

        # Uppercase REQUEST
        if 'REQUEST' in [k.upper() for k in q.keys()]:
            if request.method == 'GET':
                ows_request = q['REQUEST'].upper()
            else:
                if request.content_type == 'application/x-www-form-urlencoded':
                    ows_request = request.POST['REQUEST'].upper()
                else:
                    ows_request = request.POST['REQUEST'][0].upper()
            q['REQUEST'] = ows_request

        # FIXME: proxy or redirect in case of WMS/WFS/XYZ cascading?
        qgs_project = get_qgs_project(self.project.qgis_file.path)

        if qgs_project is None:
            raise Http404('The requested QGIS project could not be loaded!')

        data = None
        if request.method == 'GET':
            method = QgsBufferServerRequest.GetMethod
        elif request.method == 'POST':
            method = QgsBufferServerRequest.PostMethod
            data = request.body
        elif request.method == 'PUT':
            method = QgsBufferServerRequest.PutMethod
            data = request.body
        elif request.method == 'PATCH':
            method = QgsBufferServerRequest.PatchMethod
            data = request.body
        elif request.method == 'HEAD':
            method = QgsBufferServerRequest.HeadMethod
        elif request.method == 'DELETE':
            method = QgsBufferServerRequest.DeleteMethod
        else:
            logger.warning("Request method not supported: %s, assuming GET" %
                           request.method)
            method = QgsBufferServerRequest.GetMethod

        headers = {}
        for header_key in request.headers.keys():
            headers[header_key] = request.headers.get(header_key)
        uri = request.build_absolute_uri(request.path) + '?' + q.urlencode()
        logger.debug('Calling QGIS Server: %s' % uri)
        qgs_request = QgsBufferServerRequest(uri, method, headers, data)

        # Attach user and project to the server object to make them accessible by the
        # server access control plugins (constraints etc.)
        QGS_SERVER.user = request.user
        QGS_SERVER.project = self.project

        qgs_response = QgsBufferServerResponse()
        try:
            QGS_SERVER.handleRequest(qgs_request, qgs_response, qgs_project)
        except Exception as ex:
            return HttpResponseServerError(
                reason="Error handling server request: %s" % ex)

        response = HttpResponse(bytes(qgs_response.body()))
        response.status_code = qgs_response.statusCode()

        for key, value in qgs_response.headers().items():
            response[key] = value

        return response
コード例 #13
0
    def baseDoRequest(self, q):

        request = self.request

        # Uppercase REQUEST
        if 'REQUEST' in [k.upper() for k in q.keys()]:
            if request.method == 'GET':
                ows_request = q['REQUEST'].upper()
            else:
                if request.content_type == 'application/x-www-form-urlencoded':
                    ows_request = request.POST['REQUEST'].upper()
                else:
                    ows_request = request.POST['REQUEST'][0].upper()
            q['REQUEST'] = ows_request

        # FIXME: proxy or redirect in case of WMS/WFS/XYZ cascading?
        qgs_project = get_qgs_project(self.project.qgis_file.path)

        if qgs_project is None:
            raise Http404('The requested QGIS project could not be loaded!')

        data = None
        if request.method == 'GET':
            method = QgsBufferServerRequest.GetMethod
        elif request.method == 'POST':
            method = QgsBufferServerRequest.PostMethod
            data = request.body
        elif request.method == 'PUT':
            method = QgsBufferServerRequest.PutMethod
            data = request.body
        elif request.method == 'PATCH':
            method = QgsBufferServerRequest.PatchMethod
            data = request.body
        elif request.method == 'HEAD':
            method = QgsBufferServerRequest.HeadMethod
        elif request.method == 'DELETE':
            method = QgsBufferServerRequest.DeleteMethod
        else:
            logger.warning(
                "Request method not supported: %s, assuming GET" % request.method)
            method = QgsBufferServerRequest.GetMethod

        headers = {}
        for header_key in request.headers.keys():
            headers[header_key] = request.headers.get(header_key)
        uri = request.build_absolute_uri(request.path) + '?' + q.urlencode()
        logger.debug('Calling QGIS Server: %s' % uri)
        qgs_request = QgsBufferServerRequest(uri, method, headers, data)

        # Attach user and project to the server object to make them accessible by the
        # server access control plugins (constraints etc.)
        QGS_SERVER.djrequest = request
        QGS_SERVER.user = request.user
        QGS_SERVER.project = self.project


        # For GetPrint QGIS functions that rely on layers visibility, we need to check
        # the layers from LAYERS
        use_ids = QgsServerProjectUtils.wmsUseLayerIds(qgs_project)
        tree_root = qgs_project.layerTreeRoot()

        # Loop through the layers and make them visible
        for layer_name in qgs_request.queryParameter('LAYERS').split(','):
            layer_name = urllib.parse.unquote(layer_name)
            layer = None
            if use_ids:
                layer = qgs_project.mapLayer(layer_name)
            else:
                try:
                    layer = qgs_project.mapLayersByName(layer_name)[0]
                except:  # short name?
                    for l in qgs_project.mapLayers().values():
                        if l.shortName() == layer_name:
                            layer = l
                            break

            if layer is None:
                logger.warning(
                    'Could not find layer "{}" when configuring OWS call'.format(layer_name))
            else:
                layer_node = tree_root.findLayer(layer)
                if layer_node is not None:
                    layer_node.setItemVisibilityCheckedParentRecursive(True)
                else:
                    logger.warning(
                        'Could not find layer tree node "{}" when configuring OWS call'.format(layer_name))


        qgs_response = QgsBufferServerResponse()
        try:
            QGS_SERVER.handleRequest(qgs_request, qgs_response, qgs_project)
        except Exception as ex:
            return HttpResponseServerError(reason="Error handling server request: %s" % ex)

        response = HttpResponse(bytes(qgs_response.body()))
        response.status_code = qgs_response.statusCode()

        for key, value in qgs_response.headers().items():
            response[key] = value

        return response