Exemple #1
0
    def requestReady(self):
        request = self.serverInterface().requestHandler()
        params = request.parameterMap()

        self.layers_render = []

        # Get rastertime layers
        project = QGS_SERVER.project.qgis_project
        if params.get('LAYERS') and params.get('SERVICE').upper() == 'WMS' and \
                params.get('REQUEST').upper() in ('GETMAP', 'GETLEGENDGRAPHIC') and params.get('RBAND'):
            layers = params.get('LAYERS').split(',')
            use_qgs_layer_id = QgsServerProjectUtils.wmsUseLayerIds(project)

            rlayer, rband = params.get('RBAND').split(',')

            for layer in layers:
                if use_qgs_layer_id:
                    qlayer = project.mapLayer(layer)
                else:
                    qlayer = project.mapLayerByName(layer)

                if qlayer.dataProvider().name() == Layer.TYPES.gdal and rlayer == qlayer.id():

                    self.layers_render.append({
                       'qlayer': qlayer,
                       'renderer': qlayer.renderer().clone()
                    })

                    rts = RTS(qlayer)
                    rts.setDateIndex(int(rband))
Exemple #2
0
def get_toc(project, info):
    """Get the WMS TOC information for the project"""

    use_ids = QgsServerProjectUtils.wmsUseLayerIds(project)
    wmsRestrictedLayers = QgsServerProjectUtils.wmsRestrictedLayers(project)

    def _harvest(node, parent_id=None):
        node_name = node.name() if parent_id is not None else 'root'
        rec = {
            'title': node_name,  # Override with title for layers
            'name': node_name,
            'expanded': node.isExpanded(),
            'visible': node.isVisible(),
        }
        try:
            rec['id'] = node.layerId()
            rec['queryable'] = node.layerId() in info['wms_layers_queryable']
            rec['searchable'] = node.layerId() in info['wms_layers_searchable']
            rec['wfs_enabled'] = node.layerId(
            ) in info['capabilities']['wfsLayerIds']
            short_name = node.layer().shortName() if node.layer().shortName(
            ) else node.layer().name()
            rec['typename'] = node.layer().id() if use_ids else short_name
            # Override title
            if node.layer().title():
                rec['title'] = node.layer().title()
            if node.layer().type() not in (QgsMapLayerType.VectorLayer,
                                           QgsMapLayerType.RasterLayer):
                raise Exception
            rec['layer_type'] = 'vector' if node.layer().type(
            ) == QgsMapLayerType.VectorLayer else 'raster'
            rec['has_scale_based_visibility'] = node.layer(
            ).hasScaleBasedVisibility()
            if rec['has_scale_based_visibility']:
                rec['min_scale'] = node.layer().minimumScale()
                rec['max_scale'] = node.layer().maximumScale()
            rec['is_layer'] = True
        except AttributeError:
            rec['is_layer'] = False

        rec['tree_id'] = (parent_id + '.' +
                          rec['title']) if parent_id is not None else 'root'
        rec['tree_id_hash'] = hashlib.md5(
            rec['tree_id'].encode('utf8')).hexdigest()

        children = []
        for cn in [
                n for n in node.children()
                if n.name() not in wmsRestrictedLayers
        ]:
            try:
                children.append(_harvest(cn, rec['tree_id']))
            except:
                pass

        rec['children'] = children
        return rec

    return _harvest(project.layerTreeRoot())
 def _get_custom_properties_by_layer(self, request, response, project):
     if QgsServerProjectUtils.wmsUseLayerIds(project):
         dict_key = 'id'
     else:
         dict_key = 'name'
     try:
         layer_keys_str = request.parameters()['LAYERS']
     except KeyError:
         layer_keys_str = None
     try:
         filter_str = request.parameters()['FILTER']
     except KeyError:
         filter_str = None
     if layer_keys_str:
         layer_keys = layer_keys_str.split(',')
     else:
         layer_keys = None
     if filter_str:
         filter_prop_items = [filter_prop.split(':')
                              for filter_prop in filter_str.split(',')]
         filter_props = {
             filter_prop_name: filter_prop_value
             for filter_prop_name, filter_prop_value in filter_prop_items}
     else:
         filter_props = None
     custom_props = {}
     for layer_id, layer in project.mapLayers().items():
         # If a shortname is set, we must use it instead of
         # the plain layer name
         layer_name = layer.shortName() or layer.name()
         if dict_key == 'name':
             custom_props_key = layer_name
         else:
             custom_props_key = layer_id
         if layer_keys:
             if dict_key == 'name' and layer_name not in layer_keys:
                 continue
             if dict_key == 'id' and layer_id not in layer_keys:
                 continue
         custom_props[custom_props_key] = {}
         if dict_key == 'name':
             custom_props[layer_name]['layer_id'] = layer_id
         else:
             custom_props[layer_id]['layer_name'] = layer_name
         for prop in layer.customPropertyKeys():
             prop_value = layer.customProperty(prop)
             custom_props[custom_props_key][prop] = prop_value
     custom_props_filtered = custom_props.copy()
     if filter_props:
         for filter_prop in filter_props:
             for layer in custom_props:
                 filter_prop_value = filter_props[filter_prop]
                 if custom_props[layer][filter_prop] != filter_prop_value:
                     del custom_props_filtered[layer]
     response.setStatusCode(200)
     response.write(
         json.dumps(custom_props_filtered, indent=4, sort_keys=True))
Exemple #4
0
def project_wms(project, crs):
    """Calculate the extent from WMS advertized (if defined) or from
        WMS published layers.

    :param project: [description]
    :type project: [type]
    :returns: a tuple with WMS extent and list of published WMS typenames
    :rtype: tuple
    """

    wms_typenames = []
    extent = ''

    restricted_wms = QgsServerProjectUtils.wmsRestrictedLayers(project)
    use_ids = QgsServerProjectUtils.wmsUseLayerIds(project)

    for l in project.mapLayers().values():
        if l.name() not in restricted_wms:
            lid = l.id() if use_ids else l.name()
            wms_typenames.append(lid)

    extent = QgsServerProjectUtils.wmsExtent(project)
    if extent.isNull():
        target_crs = QgsCoordinateReferenceSystem.fromEpsgId(
            int(crs.split(':')[1]))
        for l in project.mapLayers().values():
            if l.name() not in restricted_wms:
                l_extent = l.extent()
                if l.crs() != target_crs:
                    ct = QgsCoordinateTransform(l.crs(), target_crs,
                                                project.transformContext())
                    l_extent = ct.transform(l_extent)
                if extent.isNull():
                    extent = l_extent
                else:
                    extent.combineExtentWith(l_extent)
    else:
        if crs != project.crs().authid():
            target_crs = QgsCoordinateReferenceSystem.fromEpsgId(
                int(crs.split(':')[1]))
            ct = QgsCoordinateTransform(project.crs(), target_crs,
                                        project.transformContext())
            extent = ct.transform(extent)

    return extent, wms_typenames
 def _get_fields_by_layer(self, request, response, project):
     if QgsServerProjectUtils.wmsUseLayerIds(project):
         dict_key = 'id'
     else:
         dict_key = 'name'
     try:
         layer_keys_str = request.parameters()['LAYERS']
     except KeyError:
         layer_keys_str = None
     if layer_keys_str:
         layer_keys = layer_keys_str.split(',')
     else:
         layer_keys = None
     fields_by_layer = {}
     for layer_id, layer in project.mapLayers().items():
         if isinstance(layer, QgsRasterLayer):
             continue
         # If a shortname is set, we must use it instead of
         # the plain layer name
         layer_name = layer.shortName() or layer.name()
         if dict_key == 'name':
             layer_key = layer_name
         else:
             layer_key = layer_id
         if layer_keys:
             if dict_key == 'name' and layer_name not in layer_keys:
                 continue
             if dict_key == 'id' and layer_id not in layer_keys:
                 continue
         fields_by_layer[layer_key] = {}
         if dict_key == 'name':
             fields_by_layer[layer_name]['layer_id'] = layer_id
         else:
             fields_by_layer[layer_id]['layer_name'] = layer_name
         fields_by_layer[layer_key] = [
             field.name() for field in layer.fields()]
     response.setStatusCode(200)
     response.write(
         json.dumps(fields_by_layer, indent=4, sort_keys=True))
 def test_wmsuselayerids(self):
     self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj), False)
     self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj2), True)
 def test_wmsuselayerids(self):
     self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj), False)
     self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj2), True)
Exemple #8
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