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'))
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'))
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()
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'))
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)