예제 #1
0
    def test_qgis_server_endpoint(self):
        """Test QGIS Server endpoint url."""

        # Internal url should go to http://qgis-server (docker container
        self.assertEqual(
            settings.QGIS_SERVER_URL, qgis_server_endpoint(internal=True))
        # Public url should go to proxy url
        parse_result = urlparse.urlparse(qgis_server_endpoint(internal=False))
        self.assertEqual(parse_result.path, reverse('qgis_server:request'))
예제 #2
0
    def test_qgis_server_endpoint(self):
        """Test QGIS Server endpoint url."""

        # Internal url should go to http://qgis-server (docker container
        self.assertEqual(settings.QGIS_SERVER_URL,
                         qgis_server_endpoint(internal=True))
        # Public url should go to proxy url
        parse_result = urlparse.urlparse(qgis_server_endpoint(internal=False))
        self.assertEqual(parse_result.path, reverse('qgis_server:request'))
예제 #3
0
파일: analysis.py 프로젝트: kartoza/geosafe
def layer_geojson(request):
    """Ajax request to get layer's content as geojson.
    """
    if request.method != 'GET':
        return HttpResponseBadRequest()
    layer_id = request.GET.get('layer_id')
    if not layer_id:
        return HttpResponseBadRequest()
    try:
        layer = Layer.objects.get(id=layer_id)
        qgis_layer = get_object_or_404(QGISServerLayer, layer=layer)
        params = {
            'SERVICE': 'WFS',
            'REQUEST': 'GetFeature',
            'MAP': qgis_layer.qgis_project_path,
            'TYPENAME': layer.name,
            'OUTPUTFORMAT': 'GeoJSON'
        }
        qgis_server_url = qgis_server_endpoint(True)
        response = requests.get(qgis_server_url, params=params)

        return HttpResponse(
            # json.dumps(response.content), content_type="application/json"
            response.content,
            content_type=response.headers.get('content-type'))

    except Exception as e:
        LOGGER.exception(e)
        return HttpResponseServerError()
예제 #4
0
def qgis_server_request(request):
    """View to forward OGC request to QGIS Server."""
    # Make a copy of the query string with capital letters for the key.
    query = request.GET or request.POST
    params = {
        param.upper(): value for param, value in query.iteritems()}

    # 900913 is deprecated
    if params.get('SRS') == 'EPSG:900913':
        params['SRS'] = 'EPSG:3857'
    if params.get('CRS') == 'EPSG:900913':
        params['CRS'] = 'EPSG:3857'

    map_param = params.get('MAP')

    # As we have one QGIS project per layer, we don't support GetCapabilities
    # for now without any layer. We know, it's not OGC compliant.
    if params.get('REQUEST') == 'GetCapabilities':
        if (not map_param and
                not (params.get('LAYERS') or params.get('TYPENAME'))):
            return HttpResponse('GetCapabilities is not supported yet.')

    # As we have one project per layer, we add the MAP path if the request is
    # specific for one layer.
    if not map_param and (params.get('LAYERS') or params.get('TYPENAME')):
        # LAYERS is for WMS, TYPENAME for WFS
        layer_name = params.get('LAYERS') or params.get('TYPENAME')

        if len(layer_name.split(',')) > 1:
            return HttpResponse(
                'We do not support many layers in the request')

        layer = get_object_or_404(Layer, name=layer_name)
        qgis_layer = get_object_or_404(QGISServerLayer, layer=layer)
        params['MAP'] = qgis_layer.qgis_project_path

    # We have some shortcuts here instead of asking QGIS-Server.
    if params.get('SERVICE') == 'WMS':
        if params.get('REQUEST') == 'GetLegendGraphic':
            layer_name = params.get('LAYER')
            if not layer_name:
                raise Http404('LAYER is not found for a GetLegendGraphic')
            layer = get_object_or_404(Layer, name=layer_name)
            return legend(request, layername=layer.name)

    # Validation for STYLEMANAGER service
    if params.get('SERVICE') == 'STYLEMANAGER':
        project_param = params.get('PROJECT')
        layer_name = params.get('LAYER')
        if not project_param and layer_name:
            layer = get_object_or_404(Layer, name=layer_name)
            qgis_layer = get_object_or_404(QGISServerLayer, layer=layer)
            params['PROJECT'] = qgis_layer.qgis_project_path

    # if not shortcut, we forward any request to internal QGIS Server
    qgis_server_url = qgis_server_endpoint(internal=True)
    response = requests.get(qgis_server_url, params)

    content = response.content

    # if it is GetCapabilities request, we need to replace all reference to
    # our proxy
    if params.get('REQUEST') == 'GetCapabilities':
        qgis_server_base_url = qgis_server_endpoint(internal=True)
        pattern = '{endpoint}'.format(endpoint=qgis_server_base_url)
        content = re.sub(
            pattern, qgis_server_endpoint(internal=False), content)

    return HttpResponse(
        content, content_type=response.headers.get('content-type'))
예제 #5
0
파일: analysis.py 프로젝트: kartoza/geosafe
def prepare_aggregation_filter(analysis_id):
    """Filter current aggregation layer.

    :param analysis_id: analysis id of the object
    :type analysis_id: int

    :return: uri path of filtered aggregation layer
    :rtype: basestring
    """
    analysis = Analysis.objects.get(id=analysis_id)
    if not analysis.aggregation_layer:
        return None
    aggregation_layer = analysis.aggregation_layer.qgis_layer

    endpoint = qgis_server_endpoint(internal=True)

    # construct WFS filter query_params
    query_string = {
        'MAP': aggregation_layer.qgis_project_path,
        'SERVICE': 'WFS',
        'REQUEST': 'GetFeature',
        'TYPENAME': aggregation_layer.layer.name,
        'OUTPUTFORMAT': 'GeoJSON'
    }
    filter_string = None
    if analysis.aggregation_filter:
        try:
            filter_dict = json.loads(analysis.aggregation_filter)

            property_name = filter_dict['property_name']
            property_values = filter_dict['values']

            like_statement = []
            for val in property_values:
                like_statement.append(
                    '<PropertyIsLike>'
                    '<PropertyName>{name}</PropertyName>'
                    '<Literal>{value}</Literal>'
                    '</PropertyIsLike>'.format(name=property_name, value=val)
                )
            filter_string = '<Filter>{filter}</Filter>'.format(
                filter=''.join(like_statement))

        except BaseException as e:
            LOGGER.error(e)
            # something happened, don't use filter
            filter_string = None

    if filter_string:
        query_string['FILTER'] = filter_string

    response = requests.get(endpoint, params=query_string)
    if response.ok:
        try:
            # try parse geojson
            geojson = response.json()
            # if successful, create temporary inasafe layer
            prefix_name = '{layer_name}_'.format(
                layer_name=aggregation_layer.qgis_layer_name)
            # the files needs to be at the same dir where aggregation layer is
            dirname = os.path.dirname(aggregation_layer.base_layer_path)
            temp_aggregation = tempfile.mkstemp(
                    prefix=prefix_name,
                    suffix='.geojson',
                    dir=dirname)[1]
            with open(temp_aggregation, mode='w+b') as f:
                # Re dump just to be safe
                f.write(json.dumps(geojson))
            filename, _ = os.path.splitext(os.path.basename(temp_aggregation))
            # copy metadata
            copy_inasafe_metadata(
                aggregation_layer.base_layer_path, dirname, filename)

            # Update filtered aggregation location
            Analysis.objects.filter(id=analysis_id).update(
                filtered_aggregation=temp_aggregation)

            # Return temporary path
            return get_layer_path(temp_aggregation)
        except BaseException as e:
            LOGGER.error(e)
            # Failed to filter aggregation layer somehow

    # when everything fails
    return get_layer_path(analysis.aggregation_layer)