def test_wcslayersids(self): # retrieve entry from project result = QgsServerProjectUtils.wcsLayerIds(self.prj) expected = [] expected.append('landsat20170313142548073') self.assertEqual(expected, result)
def test_wmsrestrictedlayers(self): # retrieve entry from project result = QgsServerProjectUtils.wmsRestrictedLayers(self.prj) expected = [] expected.append('points') # layer expected.append('group1') # local group expected.append('groupEmbedded') # embedded group self.assertListEqual(sorted(expected), sorted(result))
def test_wfslayersids(self): # retrieve entry from project result = QgsServerProjectUtils.wfsLayerIds(self.prj) expected = [] expected.append('multipoint20170309173637804') # from embedded group expected.append('points20170309173738552') # local layer expected.append('polys20170309173913723') # from local group self.assertEqual(expected, result)
def test_wmsuselayerids(self): self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj), False) self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj2), True)
def test_size(self): self.assertEqual(QgsServerProjectUtils.wmsMaxWidth(self.prj), 400) self.assertEqual(QgsServerProjectUtils.wmsMaxHeight(self.prj), 500)
def test_url(self): self.assertEqual(QgsServerProjectUtils.wmsServiceUrl(self.prj), "my_wms_advertised_url") self.assertEqual(QgsServerProjectUtils.wcsServiceUrl(self.prj), "my_wcs_advertised_url") self.assertEqual(QgsServerProjectUtils.wfsServiceUrl(self.prj), "my_wfs_advertised_url")
def project_info(project_path): """Extracts project information and returns it as a dictionary""" info = {} p = QgsProject() canvas = QgsMapCanvas() def _readCanvasSettings(xmlDocument): canvas.readProject(xmlDocument) p.readProject.connect(_readCanvasSettings, Qt.DirectConnection) if p.read(project_path): # initial extent extent = canvas.extent() if p.crs().authid() != 4326: ct = QgsCoordinateTransform( p.crs(), QgsCoordinateReferenceSystem.fromEpsgId(4326), p.transformContext()) extent = ct.transform(extent) info['initial_extent'] = [ extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum(), ] #################################################### # Main section info['title'] = p.metadata().title() if not info['title']: info['title'] = QgsServerProjectUtils.owsServiceTitle(p) if not info['title']: info['title'] = p.title() if not info['title']: info['title'] = p.baseName() info['description'] = p.metadata().abstract() if not info['description']: info['description'] = QgsServerProjectUtils.owsServiceAbstract(p) # Extent, CRS and published WMS layers typenames wmsOutputCrsList = QgsServerProjectUtils.wmsOutputCrsList(p) info[ 'crs'] = 'EPSG:4326' if 'EPSG:4326' in wmsOutputCrsList else wmsOutputCrsList[ 0] extent, info['wms_layers'] = project_wms(p, info['crs']) info['extent'] = [ extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum() ] geographic_extent = extent if info['crs'] != 'EPSG:4326': extent_crs = QgsCoordinateReferenceSystem.fromEpsgId( int(info['crs'].split(':')[1])) ct = QgsCoordinateTransform( extent_crs, QgsCoordinateReferenceSystem.fromEpsgId(4326), p.transformContext()) geographic_extent = ct.transform(geographic_extent) info['geographic_extent'] = [ geographic_extent.xMinimum(), geographic_extent.yMinimum(), geographic_extent.xMaximum(), geographic_extent.yMaximum() ] #################################################### # Metadata section m = p.metadata() metadata = {} for prop in ( 'title', 'identifier', 'parentIdentifier', 'abstract', 'author', 'language', 'categories', 'history', 'type', ): metadata[prop] = getattr(m, prop)() # links array metadata['links'] = _read_links(m) # contacts array metadata['contacts'] = _read_contacts(m) metadata['creationDateTime'] = m.creationDateTime().toString( Qt.ISODate) info['metadata'] = metadata #################################################### # WMS Service Capabilities section capabilities = {} for c in ('owsServiceAbstract', 'owsServiceAccessConstraints', 'owsServiceCapabilities', 'owsServiceContactMail', 'owsServiceContactOrganization', 'owsServiceContactPerson', 'owsServiceContactPhone', 'owsServiceContactPosition', 'owsServiceFees', 'owsServiceKeywords', 'owsServiceOnlineResource', 'owsServiceTitle', 'wcsLayerIds', 'wcsServiceUrl', 'wfsLayerIds', 'wfsServiceUrl', 'wfstDeleteLayerIds', 'wfstInsertLayerIds', 'wfstUpdateLayerIds', 'wmsDefaultMapUnitsPerMm', 'wmsExtent', 'wmsFeatureInfoAddWktGeometry', 'wmsFeatureInfoDocumentElement', 'wmsFeatureInfoDocumentElementNs', 'wmsFeatureInfoLayerAliasMap', 'wmsFeatureInfoPrecision', 'wmsFeatureInfoSchema', 'wmsFeatureInfoSegmentizeWktGeometry', 'wmsImageQuality', 'wmsInfoFormatSia2045', 'wmsInspireActivate', 'wmsInspireLanguage', 'wmsInspireMetadataDate', 'wmsInspireMetadataUrl', 'wmsInspireMetadataUrlType', 'wmsInspireTemporalReference', 'wmsMaxAtlasFeatures', 'wmsMaxHeight', 'wmsMaxWidth', 'wmsOutputCrsList', 'wmsRestrictedComposers', 'wmsRestrictedLayers', 'wmsRootName', 'wmsServiceUrl', 'wmsTileBuffer', 'wmsUseLayerIds', 'wmtsServiceUrl'): capabilities[c] = getattr(QgsServerProjectUtils, c)(p) info['capabilities'] = capabilities #################################################### # WMS Layers section info['wms_root_name'] = capabilities['wmsRootName'] if capabilities[ 'wmsRootName'] else p.title() restricted_wms = capabilities['wmsRestrictedLayers'] wms_layers = {} use_ids = capabilities['wmsUseLayerIds'] # Map layer title to layer name (or id if use_ids) wms_layers_map = {} # Maps a typename to a layer id wms_layers_typename_id_map = {} wms_layers_searchable = [] wms_layers_queryable = [] for l in p.mapLayers().values(): if l.name() not in restricted_wms: wms_layers[l.id()] = layer_info(l) name = l.title() if l.title() else l.name() short_name = l.shortName() if l.shortName() else l.name() wms_layers_typename_id_map[short_name] = l.id() wms_layers_map[name] = l.id() if use_ids else short_name if bool(l.flags() & QgsMapLayer.Searchable): wms_layers_searchable.append(l.id()) if bool(l.flags() & QgsMapLayer.Identifiable): wms_layers_queryable.append(l.id()) info['wms_layers'] = wms_layers info['wms_layers_map'] = wms_layers_map info['wms_layers_searchable'] = wms_layers_searchable info['wms_layers_queryable'] = wms_layers_queryable info['wms_layers_typename_id_map'] = wms_layers_typename_id_map #################################################### # TOC tree (WMS published only) info['toc'] = get_toc(p, info) return info
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