def testCasting(self): """ Test that sip correctly casts stuff """ p = QgsProject() p.read(os.path.join(TEST_DATA_DIR, 'layouts', 'layout_casting.qgs')) layout = p.layoutManager().layouts()[0] # check a method which often fails casting map = layout.itemById('map') self.assertIsInstance(map, QgsLayoutItemMap) label = layout.itemById('label') self.assertIsInstance(label, QgsLayoutItemLabel) # another method -- sometimes this fails casting for different(?) reasons # make sure we start from a new project so sip hasn't remembered item instances p2 = QgsProject() p2.read(os.path.join(TEST_DATA_DIR, 'layouts', 'layout_casting.qgs')) layout = p2.layoutManager().layouts()[0] items = layout.items() map2 = [i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'map'][0] self.assertIsInstance(map2, QgsLayoutItemMap) label2 = [i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'label'][0] self.assertIsInstance(label2, QgsLayoutItemLabel)
class TestQgsServerProjectUtils(unittest.TestCase): def setUp(self): self.testdata_path = unitTestDataPath('qgis_server_project') + '/' self.prj = QgsProject() self.prjPath = os.path.join(self.testdata_path, "project.qgs") self.prj.read(self.prjPath) self.prj2 = QgsProject() self.prj2Path = os.path.join(self.testdata_path, "project2.qgs") self.prj2.read(self.prj2Path) def tearDown(self): pass 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 test_wmsuselayerids(self): self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj), False) self.assertEqual(QgsServerProjectUtils.wmsUseLayerIds(self.prj2), True) 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_wcslayersids(self): # retrieve entry from project result = QgsServerProjectUtils.wcsLayerIds(self.prj) expected = [] expected.append('landsat20170313142548073') self.assertEqual(expected, result)
def test_wmts_config(self): projectPath = self.projectGroupsPath assert os.path.exists(projectPath), "Project file not found: " + projectPath project = QgsProject() project.read(projectPath) self.wmts_request_compare_project(project, 'GetCapabilities', reference_base_name='wmts_getcapabilities_config') self.assertTrue(project.removeEntry('WMTSGrids', 'Config')) self.assertTrue(project.removeEntry('WMTSGrids', 'CRS')) self.wmts_request_compare_project(project, 'GetCapabilities', reference_base_name='wmts_getcapabilities_config') self.assertTrue(project.writeEntry('WMTSGrids', 'Config', ('EPSG:3857,20037508.342789248,-20037508.342789248,559082264.0287179,20',))) self.assertTrue(project.writeEntry('WMTSGrids', 'CRS', ('EPSG:3857',))) self.wmts_request_compare_project(project, 'GetCapabilities', reference_base_name='wmts_getcapabilities_config_3857')
def test_zip_unzip(self): tmpDir = QTemporaryDir() tmpFile = "{}/project.qgz".format(tmpDir.path()) project = QgsProject() l0 = QgsVectorLayer(os.path.join(TEST_DATA_DIR, "points.shp"), "points", "ogr") l1 = QgsVectorLayer(os.path.join(TEST_DATA_DIR, "lines.shp"), "lines", "ogr") project.addMapLayers([l0, l1]) self.assertTrue(project.write(tmpFile)) project2 = QgsProject() self.assertFalse(project2.isZipped()) self.assertTrue(project2.fileName() == "") self.assertTrue(project2.read(tmpFile)) self.assertTrue(project2.isZipped()) self.assertTrue(project2.fileName() == tmpFile) layers = project2.mapLayers() self.assertEqual(len(layers.keys()), 2) self.assertTrue(layers[l0.id()].isValid(), True) self.assertTrue(layers[l1.id()].isValid(), True) project2.clear() self.assertFalse(project2.isZipped())
def testSaveRestoreFromProject(self): p = QgsProject() provider = ProjectProvider(p) # add some algorithms alg = QgsProcessingModelAlgorithm('test name', 'test group') provider.add_model(alg) alg2 = QgsProcessingModelAlgorithm('test name2', 'test group2') provider.add_model(alg2) self.assertEqual(len(provider.algorithms()), 2) tmp_file = QTemporaryFile() tmp_file.open() # fileName is no available until open temp_path = tmp_file.fileName() tmp_file.close() self.assertTrue(p.write(temp_path)) # restore project p2 = QgsProject() provider2 = ProjectProvider(p2) self.assertTrue(p2.read(temp_path)) self.assertEqual(len(provider2.model_definitions), 2) self.assertEqual(len(provider2.algorithms()), 2) self.assertEqual(provider2.algorithms()[0].name(), 'test name') self.assertEqual(provider2.algorithms()[0].group(), 'test group') self.assertEqual(provider2.algorithms()[1].name(), 'test name2') self.assertEqual(provider2.algorithms()[1].group(), 'test group2') # clear project should remove algorithms p2.clear() self.assertFalse(provider2.algorithms())
def testEmbeddedGroup(self): testdata_path = unitTestDataPath('embedded_groups') + '/' prj_path = os.path.join(testdata_path, "project2.qgs") prj = QgsProject() prj.read(prj_path) layer_tree_group = prj.layerTreeRoot() self.assertEqual(len(layer_tree_group.findLayerIds()), 2) for layer_id in layer_tree_group.findLayerIds(): name = prj.mapLayer(layer_id).name() self.assertTrue(name in ['polys', 'lines']) if name == 'polys': self.assertTrue(layer_tree_group.findLayer(layer_id).itemVisibilityChecked()) elif name == 'lines': self.assertFalse(layer_tree_group.findLayer(layer_id).itemVisibilityChecked())
def testSaveLoadProject(self): schema_uri = encode_uri(self.ds_uri, 'qgis_test') project_uri = encode_uri(self.ds_uri, 'qgis_test', 'abc') self.dropProjectsTable() # make sure we have a clean start prj = QgsProject() uri = self.vl.source() vl1 = QgsVectorLayer(uri, 'test', 'postgres') self.assertEqual(vl1.isValid(), True) prj.addMapLayer(vl1) prj_storage = QgsApplication.projectStorageRegistry().projectStorageFromType("postgresql") self.assertTrue(prj_storage) lst0 = prj_storage.listProjects(schema_uri) self.assertEqual(lst0, []) # try to save project in the database prj.setFileName(project_uri) res = prj.write() self.assertTrue(res) lst1 = prj_storage.listProjects(schema_uri) self.assertEqual(lst1, ["abc"]) # now try to load the project back prj2 = QgsProject() prj2.setFileName(project_uri) res = prj2.read() self.assertTrue(res) self.assertEqual(len(prj2.mapLayers()), 1) self.assertEqual(prj2.baseName(), "abc") self.assertEqual(prj2.absoluteFilePath(), "") # path not supported for project storages self.assertTrue(abs(prj2.lastModified().secsTo(QDateTime.currentDateTime())) < 10) # try to see project's metadata res, metadata = prj_storage.readProjectStorageMetadata(project_uri) self.assertTrue(res) self.assertEqual(metadata.name, "abc") time_project = metadata.lastModified time_now = QDateTime.currentDateTime() time_diff = time_now.secsTo(time_project) self.assertTrue(abs(time_diff) < 10) # try to remove the project res = prj_storage.removeProject(project_uri) self.assertTrue(res) lst2 = prj_storage.listProjects(schema_uri) self.assertEqual(lst2, []) self.dropProjectsTable() # make sure we have a clean finish... "leave no trace"
def testEmbeddedGroup(self): testdata_path = unitTestDataPath('embedded_groups') + '/' prj_path = os.path.join(testdata_path, "project2.qgs") prj = QgsProject() prj.read(prj_path) layer_tree_group = prj.layerTreeRoot() layers_ids = layer_tree_group.findLayerIds() layers_names = [] for layer_id in layers_ids: name = prj.mapLayer(layer_id).name() layers_names.append(name) expected = ['polys', 'lines'] self.assertEqual(sorted(layers_names), sorted(expected))
def _load_project(self, path): """ Read a qgis project from path """ if not os.path.exists(path): raise FileNotFoundError(path) project = QgsProject() if not project.read(path): raise LizmapConfigError("Error reading qgis project") return project
def test_configpath(self): """ Test plugin can read confif path """ try: from qgis.server import QgsServerFilter from qgis.core import QgsProject except ImportError: print("QGIS Server plugins are not compiled. Skipping test") return d = unitTestDataPath('qgis_server_accesscontrol') + '/' self.projectPath = os.path.join(d, "project.qgs") self.server = QgsServer() # global to be modified inside plugin filters globals()['configFilePath2'] = None class Filter0(QgsServerFilter): """Body setter, clear body, keep headers""" def requestReady(self): global configFilePath2 configFilePath2 = self.serverInterface().configFilePath() serverIface = self.server.serverInterface() serverIface.registerFilter(Filter0(serverIface), 100) # Test using MAP self._execute_request('?service=simple&MAP=%s' % self.projectPath) # Check config file path self.assertEqual(configFilePath2, self.projectPath) # Reset result globals()['configFilePath2'] = None # Test with prqject as argument project = QgsProject() project.read(self.projectPath) self._execute_request_project('?service=simple', project=project) # Check config file path self.assertEqual(configFilePath2, project.fileName())
def testCustomLayerOrder(self): """ test project layer order""" prj = QgsProject() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") prj.addMapLayers([layer, layer2, layer3]) layer_order_changed_spy = QSignalSpy(prj.layerTreeRoot().customLayerOrderChanged) prj.layerTreeRoot().setCustomLayerOrder([layer2, layer]) self.assertEqual(len(layer_order_changed_spy), 1) prj.layerTreeRoot().setCustomLayerOrder([layer2, layer]) self.assertEqual(len(layer_order_changed_spy), 1) # no signal, order not changed self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer]) prj.layerTreeRoot().setCustomLayerOrder([layer]) self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer]) self.assertEqual(len(layer_order_changed_spy), 2) # remove a layer prj.layerTreeRoot().setCustomLayerOrder([layer2, layer, layer3]) self.assertEqual(len(layer_order_changed_spy), 3) prj.removeMapLayer(layer) self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer3]) self.assertEqual(len(layer_order_changed_spy), 4) # save and restore file_name = os.path.join(QDir.tempPath(), 'proj.qgs') prj.setFileName(file_name) prj.write() prj2 = QgsProject() prj2.setFileName(file_name) prj2.read() self.assertEqual([l.id() for l in prj2.layerTreeRoot().customLayerOrder()], [layer2.id(), layer3.id()]) # clear project prj.clear() self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [])
def testPalPropertiesReadWrite(self): tmpDir = QTemporaryDir() tmpFile = "{}/project.qgs".format(tmpDir.path()) s0 = QgsLabelingEngineSettings() s0.setNumCandidatePositions(3, 33, 333) p0 = QgsProject() p0.setFileName(tmpFile) p0.setLabelingEngineSettings(s0) p0.write() p1 = QgsProject() p1.read(tmpFile) s1 = p1.labelingEngineSettings() candidates = s1.numCandidatePositions() self.assertEqual(candidates[0], 3) self.assertEqual(candidates[1], 33) self.assertEqual(candidates[2], 333)
class TestQgsServerProjectUtils(unittest.TestCase): def setUp(self): self.testdata_path = unitTestDataPath('qgis_server_project') + '/' self.prj = QgsProject() prjPath = os.path.join(self.testdata_path, "project.qgs") self.prj.setFileName(prjPath) self.prj.read() def tearDown(self): pass 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 wms_request_compare_project(self, request, extra=None, reference_file=None): projectPath = self.testdata_path + "test_project.qgs" assert os.path.exists(projectPath), "Project file not found: " + projectPath project = QgsProject() project.read(projectPath) query_string = 'https://www.qgis.org/?SERVICE=WMS&VERSION=1.3&REQUEST=%s' % (request) if extra is not None: query_string += extra header, body = self._execute_request_project(query_string, project) response = header + body reference_path = self.testdata_path + (request.lower() if not reference_file else reference_file) + '.txt' self.store_reference(reference_path, response) f = open(reference_path, 'rb') expected = f.read() f.close() response = re.sub(RE_STRIP_UNCHECKABLE, b'*****', response) expected = re.sub(RE_STRIP_UNCHECKABLE, b'*****', expected) self.assertXMLEqual(response, expected, msg="request %s failed.\nQuery: %s\nExpected file: %s\nResponse:\n%s" % (query_string, request, reference_path, response.decode('utf-8')))
def get(self, query: str, project: str=None) -> _Response: """ Return server response from query """ request = QgsBufferServerRequest(query, QgsServerRequest.GetMethod, {}, None) response = QgsBufferServerResponse() if project is not None and not os.path.isabs(project): projectpath = self.datapath.join(project) qgsproject = QgsProject() if not qgsproject.read(projectpath.strpath): raise ValueError("Error reading project '%s':" % projectpath.strpath) else: qgsproject = None self.server.handleRequest(request, response, project=qgsproject) return _Response(response)
def testWriteEntry(self): tmpDir = QTemporaryDir() tmpFile = "{}/project.qgs".format(tmpDir.path()) # zip with existing file project = QgsProject() query = 'select * from "sample DH" where "sample DH"."Elev" > 130 and "sample DH"."Elev" < 140' self.assertTrue(project.writeEntry('myscope', 'myentry', query)) self.assertTrue(project.write(tmpFile)) self.assertTrue(project.read(tmpFile)) q, ok = project.readEntry('myscope', 'myentry') self.assertTrue(ok) self.assertEqual(q, query)
def testRelativePaths(self): """ Test whether paths to layer sources are stored as relative to the project path """ tmpDir = QTemporaryDir() tmpFile = "{}/project.qgs".format(tmpDir.path()) copyfile(os.path.join(TEST_DATA_DIR, "points.shp"), os.path.join(tmpDir.path(), "points.shp")) copyfile(os.path.join(TEST_DATA_DIR, "points.dbf"), os.path.join(tmpDir.path(), "points.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "points.shx"), os.path.join(tmpDir.path(), "points.shx")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shp"), os.path.join(tmpDir.path(), "lines.shp")) copyfile(os.path.join(TEST_DATA_DIR, "lines.dbf"), os.path.join(tmpDir.path(), "lines.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shx"), os.path.join(tmpDir.path(), "lines.shx")) copyfile(os.path.join(TEST_DATA_DIR, "landsat_4326.tif"), os.path.join(tmpDir.path(), "landsat_4326.tif")) project = QgsProject() l0 = QgsVectorLayer(os.path.join(tmpDir.path(), "points.shp"), "points", "ogr") l1 = QgsVectorLayer(os.path.join(tmpDir.path(), "lines.shp"), "lines", "ogr") l2 = QgsRasterLayer(os.path.join(tmpDir.path(), "landsat_4326.tif"), "landsat", "gdal") self.assertTrue(l0.isValid()) self.assertTrue(l1.isValid()) self.assertTrue(l2.isValid()) self.assertTrue(project.addMapLayers([l0, l1, l2])) self.assertTrue(project.write(tmpFile)) del project with open(tmpFile, 'r') as f: content = ''.join(f.readlines()) self.assertTrue('source="./lines.shp"' in content) self.assertTrue('source="./points.shp"' in content) self.assertTrue('source="./landsat_4326.tif"' in content) # Re-read the project and store absolute project = QgsProject() self.assertTrue(project.read(tmpFile)) store = project.layerStore() self.assertEquals(set([l.name() for l in store.mapLayers().values()]), set(['lines', 'landsat', 'points'])) project.writeEntryBool('Paths', '/Absolute', True) tmpFile2 = "{}/project2.qgs".format(tmpDir.path()) self.assertTrue(project.write(tmpFile2)) with open(tmpFile2, 'r') as f: content = ''.join(f.readlines()) self.assertTrue('source="{}/lines.shp"'.format(tmpDir.path()) in content) self.assertTrue('source="{}/points.shp"'.format(tmpDir.path()) in content) self.assertTrue('source="{}/landsat_4326.tif"'.format(tmpDir.path()) in content) del project
def testSymbolicLinkInProjectPath(self): """ Test whether paths to layer sources relative to the project are stored correctly when project'name contains a symbolic link. In other words, test if project's and layers' names are correctly resolved. """ tmpDir = QTemporaryDir() tmpFile = "{}/project.qgs".format(tmpDir.path()) copyfile(os.path.join(TEST_DATA_DIR, "points.shp"), os.path.join(tmpDir.path(), "points.shp")) copyfile(os.path.join(TEST_DATA_DIR, "points.dbf"), os.path.join(tmpDir.path(), "points.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "points.shx"), os.path.join(tmpDir.path(), "points.shx")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shp"), os.path.join(tmpDir.path(), "lines.shp")) copyfile(os.path.join(TEST_DATA_DIR, "lines.dbf"), os.path.join(tmpDir.path(), "lines.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shx"), os.path.join(tmpDir.path(), "lines.shx")) copyfile(os.path.join(TEST_DATA_DIR, "landsat_4326.tif"), os.path.join(tmpDir.path(), "landsat_4326.tif")) project = QgsProject() l0 = QgsVectorLayer(os.path.join(tmpDir.path(), "points.shp"), "points", "ogr") l1 = QgsVectorLayer(os.path.join(tmpDir.path(), "lines.shp"), "lines", "ogr") l2 = QgsRasterLayer(os.path.join(tmpDir.path(), "landsat_4326.tif"), "landsat", "gdal") self.assertTrue(l0.isValid()) self.assertTrue(l1.isValid()) self.assertTrue(l2.isValid()) self.assertTrue(project.addMapLayers([l0, l1, l2])) self.assertTrue(project.write(tmpFile)) del project # Create symbolic link to previous project tmpDir2 = QTemporaryDir() symlinkDir = os.path.join(tmpDir2.path(), "dir") os.symlink(tmpDir.path(), symlinkDir) tmpFile = "{}/project.qgs".format(symlinkDir) # Open project from symmlink and force re-save. project = QgsProject() self.assertTrue(project.read(tmpFile)) self.assertTrue(project.write(tmpFile)) del project with open(tmpFile, 'r') as f: content = ''.join(f.readlines()) self.assertTrue('source="./lines.shp"' in content) self.assertTrue('source="./points.shp"' in content) self.assertTrue('source="./landsat_4326.tif"' in content)
def test_wfs3_collection_items_limit(self): """Test WFS3 API item limits""" project = QgsProject() project.read(unitTestDataPath('qgis_server') + '/test_project.qgs') request = QgsBufferServerRequest('http://server.qgis.org/wfs3/collections/testlayer%20èé/items?limit=1') self.compareApi(request, project, 'test_wfs3_collections_items_testlayer_èé_limit_1.json')
def test_wfs3_field_filters_star(self): """Test field filters""" project = QgsProject() project.read(unitTestDataPath('qgis_server') + '/test_project.qgs') request = QgsBufferServerRequest('http://server.qgis.org/wfs3/collections/testlayer3/items?name=tw*') self.compareApi(request, project, 'test_wfs3_collections_items_testlayer3_name_eq_tw_star.json')
def test_wms_getprint_legend(self): """Test project has 2 layer: red and green and five templates: red: follow map theme red green: follow map theme green blank: no map theme full: follow map theme full with both layer falsegreen : follow map theme falsegreen (visible layer : green but with blue style) """ tmp_dir = QTemporaryDir() shutil.copyfile( os.path.join(unitTestDataPath('qgis_server'), 'test_project_legend.qgs'), os.path.join(tmp_dir.path(), 'test_project_legend.qgs')) shutil.copyfile( os.path.join(unitTestDataPath('qgis_server'), 'test_project_legend.gpkg'), os.path.join(tmp_dir.path(), 'test_project_legend.gpkg')) project = QgsProject() self.assertTrue( project.read( os.path.join(tmp_dir.path(), 'test_project_legend.qgs'))) params = { "SERVICE": "WMS", "VERSION": "1.3", "REQUEST": "GetPrint", "TEMPLATE": "blank", "FORMAT": "png", "LAYERS": "", "map0:EXTENT": "778000,5600000,836000,5650000", "map0:SCALE": "281285", "map0:LAYERS": "red", "CRS": "EPSG:3857", "DPI": '72' } ###################################################### # Template legend tests # Legend symbol are displayed at coordinates : # First item : 600 x , 40 y # Second item : 600 x , 60 y # blank template, no theme, no LAYERS, specified map0:LAYERS is red response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the red layer is displayed, there is no second item self._assertRed(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # blank template, no LAYERS, specified map0:LAYERS is green params["map0:LAYERS"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the green layer is displayed, there is no second item self._assertGreen(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # blank template params["map0:LAYERS"] = "" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the red layer is displayed, there is no second item self._assertRed(image.pixelColor(600, 40)) self._assertGreen(image.pixelColor(600, 60)) # red template, red theme, specified map0:LAYERS is red params["TEMPLATE"] = "red" params["map0:LAYERS"] = "red" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the red layer is displayed, there is no second item self._assertRed(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # red template, red theme, specified map0:LAYERS is green params["map0:LAYERS"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the green layer is displayed, there is no second item self._assertGreen(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # red template, red theme, no map0:LAYERS params["map0:LAYERS"] = "" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the red layer is displayed, there is no second item self._assertRed(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # green template, green theme, specified map0:LAYERS is red params["TEMPLATE"] = "green" params["map0:LAYERS"] = "red" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the red layer is displayed, there is no second item self._assertRed(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # green template, green theme, specified map0:LAYERS is green params["map0:LAYERS"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the green layer is displayed, there is no second item self._assertGreen(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # green template, green theme, no map0:LAYERS params["map0:LAYERS"] = "" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the green layer is displayed, there is no second item self._assertGreen(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # full template, full theme, specified map0:LAYERS is red params["TEMPLATE"] = "full" params["map0:LAYERS"] = "red" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the red layer is displayed, there is no second item self._assertRed(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # full template, full theme, specified map0:LAYERS is green params["map0:LAYERS"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the green layer is displayed, there is no second item self._assertGreen(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # full template, full theme, no map0:LAYERS params["map0:LAYERS"] = "" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Both red and green layers are displayed self._assertRed(image.pixelColor(600, 40)) self._assertGreen(image.pixelColor(600, 60)) # falsegreen template, falsegreen theme (green layer is blue), specified map0:LAYERS is red params["TEMPLATE"] = "falsegreen" params["map0:LAYERS"] = "red" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the red layer is displayed, there is no second item self._assertRed(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # full template, full theme, specified map0:LAYERS is green params["map0:LAYERS"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the green layer (in blue) is displayed, there is no second item self._assertBlue(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60)) # full template, full theme, no map0:LAYERS params["map0:LAYERS"] = "" response = QgsBufferServerResponse() request = QgsBufferServerRequest( '?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") # Only the green layer (in blue) is displayed, there is no second item self._assertBlue(image.pixelColor(600, 40)) self._assertWhite(image.pixelColor(600, 60))
def testOgcApiHandler(self): """Test OGC API Handler""" project = QgsProject() project.read(unitTestDataPath('qgis_server') + '/test_project.qgs') request = QgsBufferServerRequest( 'http://server.qgis.org/wfs3/collections/testlayer%20èé/items?limit=-1' ) response = QgsBufferServerResponse() ctx = QgsServerApiContext('/services/api1', request, response, project, self.server.serverInterface()) h = Handler1() self.assertTrue( h.staticPath(ctx).endswith('/resources/server/api/ogc/static')) self.assertEqual(h.path(), QtCore.QRegularExpression("/handlerone")) self.assertEqual(h.description(), 'The first handler ever') self.assertEqual(h.operationId(), 'handlerOne') self.assertEqual(h.summary(), 'First of its name') self.assertEqual(h.linkTitle(), 'Handler One Link Title') self.assertEqual(h.linkType(), QgsServerOgcApi.data) with self.assertRaises(QgsServerApiBadRequestException) as ex: h.handleRequest(ctx) self.assertEqual(str(ex.exception), 'Missing required argument: \'value1\'') r = ctx.response() self.assertEqual(r.data(), '') with self.assertRaises(QgsServerApiBadRequestException) as ex: h.values(ctx) self.assertEqual(str(ex.exception), 'Missing required argument: \'value1\'') # Add handler to API and test for /api2 ctx = QgsServerApiContext('/services/api2', request, response, project, self.server.serverInterface()) api = QgsServerOgcApi(self.server.serverInterface(), '/api2', 'apitwo', 'a second api', '1.2') api.registerHandler(h) # Add a second handler (will be tested later) h2 = Handler2() api.registerHandler(h2) ctx.request().setUrl(QtCore.QUrl('http://www.qgis.org/services/api1')) with self.assertRaises(QgsServerApiBadRequestException) as ex: api.executeRequest(ctx) self.assertEqual( str(ex.exception), 'Requested URI does not match any registered API handler') ctx.request().setUrl(QtCore.QUrl('http://www.qgis.org/services/api2')) with self.assertRaises(QgsServerApiBadRequestException) as ex: api.executeRequest(ctx) self.assertEqual( str(ex.exception), 'Requested URI does not match any registered API handler') ctx.request().setUrl( QtCore.QUrl('http://www.qgis.org/services/api2/handlerone')) with self.assertRaises(QgsServerApiBadRequestException) as ex: api.executeRequest(ctx) self.assertEqual(str(ex.exception), 'Missing required argument: \'value1\'') ctx.request().setUrl( QtCore.QUrl( 'http://www.qgis.org/services/api2/handlerone?value1=not+a+double' )) with self.assertRaises(QgsServerApiBadRequestException) as ex: api.executeRequest(ctx) self.assertEqual( str(ex.exception), 'Argument \'value1\' could not be converted to Double') ctx.request().setUrl( QtCore.QUrl( 'http://www.qgis.org/services/api2/handlerone?value1=1.2345')) params = h.values(ctx) self.assertEqual(params, {'value1': 1.2345}) api.executeRequest(ctx) self.assertEqual( json.loads(bytes(ctx.response().data()))['value1'], 1.2345) # Test path fragments extraction ctx.request().setUrl( QtCore.QUrl( 'http://www.qgis.org/services/api2/handlertwo/00/555?value1=1.2345' )) params = h2.values(ctx) self.assertEqual(params, { 'code1': '00', 'value1': 1.2345, 'value2': None }) # Test string encoding ctx.request().setUrl( QtCore.QUrl( 'http://www.qgis.org/services/api2/handlertwo/00/555?value1=1.2345&value2=a%2Fstring%20some' )) params = h2.values(ctx) self.assertEqual(params, { 'code1': '00', 'value1': 1.2345, 'value2': 'a/string some' }) # Test links self.assertEqual( h2.href(ctx), 'http://www.qgis.org/services/api2/handlertwo/00/555?value1=1.2345&value2=a%2Fstring%20some' ) self.assertEqual( h2.href(ctx, '/extra'), 'http://www.qgis.org/services/api2/handlertwo/00/555/extra?value1=1.2345&value2=a%2Fstring%20some' ) self.assertEqual( h2.href(ctx, '/extra', 'json'), 'http://www.qgis.org/services/api2/handlertwo/00/555/extra.json?value1=1.2345&value2=a%2Fstring%20some' ) # Test template path self.assertTrue( h2.templatePath(ctx).endswith( '/resources/server/api/ogc/templates/services/api2/handlerTwo.html' ))
def test_unzip_invalid_path(self): project = QgsProject() self.assertFalse(project.read()) self.assertFalse(project.read("")) self.assertFalse(project.read("/fake/test.zip"))
parcelle_id = sys.argv[sys.argv.index("-I") + 1] if "-T" in sys.argv: export_type = sys.argv[sys.argv.index("-T") + 1] if "-D" in sys.argv: target_dir = sys.argv[sys.argv.index("-D") + 1] if "-O" in sys.argv: output_log = sys.argv[sys.argv.index("-O") + 1] # Instantiate QGIS QgsApplication.setPrefixPath(qgisPrefixPath, True) qgs = QgsApplication([], True) QgsApplication.initQgis() # Open the project p = QgsProject() p.read(project_path) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(p.layerTreeRoot(), canvas) bridge.setCanvasLayers() # Get the layers in the project layerList = p.mapLayersByName(parcelle_layer) if not layerList: layers = p.mapLayers() for lname, layer in layers.items(): print(lname + ' ' + layer.name() + ' ' + parcelle_layer) layerList = [ layer for lname, layer in layers.items() if layer.name() == parcelle_layer ] layer = layerList[0]
def testProjectStorage(self): # New project without fileName p0 = QgsProject() self.assertTrue(p0.auxiliaryStorage().isValid()) # Create new layers with key otherwise auxiliary layers are not # automacially created when added in project vl0 = createLayer() vl0Shp = writeShape(vl0, 'vl0.shp') vl1 = createLayer() vl1Shp = writeShape(vl1, 'vl1.shp') vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr') self.assertTrue(vl0.isValid()) vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr') self.assertTrue(vl1.isValid()) # Add layers to project and check underlying auxiliary layers p0.addMapLayers([vl0, vl1]) self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk')) self.assertTrue(vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char')) al0 = vl0.auxiliaryLayer() al1 = vl1.auxiliaryLayer() self.assertEqual(al0.joinInfo().targetFieldName(), 'pk') self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char') # Add a field in auxiliary layers pdef0 = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut') self.assertTrue(al0.addAuxiliaryField(pdef0)) pdef1 = QgsPropertyDefinition('propname1', QgsPropertyDefinition.DataTypeString, '', '', 'ut') self.assertTrue(al1.addAuxiliaryField(pdef1)) # Check auxiliary fields names af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False) self.assertEqual(af0Name, 'ut_propname') af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False) self.assertEqual(af1Name, 'ut_propname1') # Set value for auxiliary fields req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl0.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True) index0 = vl0.fields().indexOf(af0Name) vl0.changeAttributeValue(f.id(), index0, 333) req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True) index1 = vl1.fields().indexOf(af1Name) vl1.changeAttributeValue(f.id(), index0, 'myvalue') req = QgsFeatureRequest().setFilterExpression("name = 'Orange'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) vl1.changeAttributeValue(f.id(), index0, 'myvalue1') # Save the project in a zip file f = tmpPath() + '.qgz' p0.write(f) # Open the zip file with embedded auxiliary storage p1 = QgsProject() p1.read(f) # Check that auxiliary fields are well loaded in layers self.assertEqual(len(p1.mapLayers().values()), 2) for vl in p1.mapLayers().values(): al = vl.auxiliaryLayer() self.assertEqual(len(al.auxiliaryFields()), 1) af = al.auxiliaryFields()[0] afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af) self.assertEqual(afPropDef.origin(), 'ut') if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk': self.assertEqual(afPropDef.name(), 'propname') self.assertEqual(al.featureCount(), 1) req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index0], 333.0) else: # num_char self.assertEqual(al.featureCount(), 2) self.assertEqual(afPropDef.name(), 'propname1') req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue') req = QgsFeatureRequest().setFilterExpression("name = 'Orange'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue1')
def testStyles(self): """Test that styles for rasters and vectors are kept when setDataSource is called""" options = QgsDataProvider.ProviderOptions() temp_dir = QTemporaryDir() p = QgsProject.instance() for f in ( 'bad_layer_raster_test.tfw', 'bad_layer_raster_test.tiff', 'bad_layer_raster_test.tiff.aux.xml', 'bad_layers_test.gpkg', 'good_layers_test.qgs'): copyfile(os.path.join(TEST_DATA_DIR, 'projects', f), os.path.join(temp_dir.path(), f)) project_path = os.path.join(temp_dir.path(), 'good_layers_test.qgs') p = QgsProject().instance() self.assertTrue(p.read(project_path)) self.assertEqual(p.count(), 3) ms = self.getBaseMapSettings() point_a = list(p.mapLayersByName('point_a'))[0] point_b = list(p.mapLayersByName('point_b'))[0] raster = list(p.mapLayersByName('bad_layer_raster_test'))[0] self.assertTrue(point_a.isValid()) self.assertTrue(point_b.isValid()) self.assertTrue(raster.isValid()) ms.setExtent(QgsRectangle(2.81861, 41.98138, 2.81952, 41.9816)) ms.setLayers([point_a, point_b, raster]) image = renderMapToImage(ms) print(os.path.join(temp_dir.path(), 'expected.png')) self.assertTrue(image.save(os.path.join(temp_dir.path(), 'expected.png'), 'PNG')) point_a_source = point_a.publicSource() point_b_source = point_b.publicSource() raster_source = raster.publicSource() point_a.setDataSource(point_a_source, point_a.name(), 'ogr', options) point_b.setDataSource(point_b_source, point_b.name(), 'ogr', options) raster.setDataSource(raster_source, raster.name(), 'gdal', options) self.assertTrue(image.save(os.path.join(temp_dir.path(), 'actual.png'), 'PNG')) self.assertTrue(filecmp.cmp(os.path.join(temp_dir.path(), 'actual.png'), os.path.join(temp_dir.path(), 'expected.png')), False) # Now build a bad project bad_project_path = os.path.join(temp_dir.path(), 'bad_layers_test.qgs') with open(project_path, 'r') as infile: with open(bad_project_path, 'w+') as outfile: outfile.write(infile.read().replace('./bad_layers_test.', './bad_layers_test-BAD_SOURCE.').replace('bad_layer_raster_test.tiff', 'bad_layer_raster_test-BAD_SOURCE.tiff')) self.assertTrue(p.read(bad_project_path)) self.assertEqual(p.count(), 3) point_a = list(p.mapLayersByName('point_a'))[0] point_b = list(p.mapLayersByName('point_b'))[0] raster = list(p.mapLayersByName('bad_layer_raster_test'))[0] self.assertFalse(point_a.isValid()) self.assertFalse(point_b.isValid()) self.assertFalse(raster.isValid()) point_a.setDataSource(point_a_source, point_a.name(), 'ogr', options) point_b.setDataSource(point_b_source, point_b.name(), 'ogr', options) raster.setDataSource(raster_source, raster.name(), 'gdal', options) self.assertTrue(image.save(os.path.join(temp_dir.path(), 'actual_fixed.png'), 'PNG')) self.assertTrue(filecmp.cmp(os.path.join(temp_dir.path(), 'actual_fixed.png'), os.path.join(temp_dir.path(), 'expected.png')), False)
def testStyles(self): """Test that styles for rasters and vectors are kept when setDataSource is called""" temp_dir = QTemporaryDir() p = QgsProject.instance() for f in ('bad_layer_raster_test.tfw', 'bad_layer_raster_test.tiff', 'bad_layer_raster_test.tiff.aux.xml', 'bad_layers_test.gpkg', 'good_layers_test.qgs'): copyfile(os.path.join(TEST_DATA_DIR, 'projects', f), os.path.join(temp_dir.path(), f)) project_path = os.path.join(temp_dir.path(), 'good_layers_test.qgs') p = QgsProject().instance() p.removeAllMapLayers() self.assertTrue(p.read(project_path)) self.assertEqual(p.count(), 4) ms = self.getBaseMapSettings() point_a_copy = list(p.mapLayersByName('point_a copy'))[0] point_a = list(p.mapLayersByName('point_a'))[0] point_b = list(p.mapLayersByName('point_b'))[0] raster = list(p.mapLayersByName('bad_layer_raster_test'))[0] self.assertTrue(point_a_copy.isValid()) self.assertTrue(point_a.isValid()) self.assertTrue(point_b.isValid()) self.assertTrue(raster.isValid()) ms.setExtent(QgsRectangle(2.81861, 41.98138, 2.81952, 41.9816)) ms.setLayers([point_a_copy, point_a, point_b, raster]) image = renderMapToImage(ms) self.assertTrue( image.save(os.path.join(temp_dir.path(), 'expected.png'), 'PNG')) point_a_source = point_a.publicSource() point_b_source = point_b.publicSource() raster_source = raster.publicSource() self._change_data_source(point_a, point_a_source, 'ogr') # Attention: we are not passing the subset string here: self._change_data_source(point_a_copy, point_a_source, 'ogr') self._change_data_source(point_b, point_b_source, 'ogr') self._change_data_source(raster, raster_source, 'gdal') self.assertTrue( image.save(os.path.join(temp_dir.path(), 'actual.png'), 'PNG')) self.assertTrue( filecmp.cmp(os.path.join(temp_dir.path(), 'actual.png'), os.path.join(temp_dir.path(), 'expected.png')), False) # Now build a bad project p.removeAllMapLayers() bad_project_path = os.path.join(temp_dir.path(), 'bad_layers_test.qgs') with open(project_path, 'r') as infile: with open(bad_project_path, 'w+') as outfile: outfile.write(infile.read().replace( './bad_layers_test.', './bad_layers_test-BAD_SOURCE.').replace( 'bad_layer_raster_test.tiff', 'bad_layer_raster_test-BAD_SOURCE.tiff')) p.removeAllMapLayers() self.assertTrue(p.read(bad_project_path)) self.assertEqual(p.count(), 4) point_a_copy = list(p.mapLayersByName('point_a copy'))[0] point_a = list(p.mapLayersByName('point_a'))[0] point_b = list(p.mapLayersByName('point_b'))[0] raster = list(p.mapLayersByName('bad_layer_raster_test'))[0] self.assertFalse(point_a.isValid()) self.assertFalse(point_a_copy.isValid()) self.assertFalse(point_b.isValid()) self.assertFalse(raster.isValid()) ms.setLayers([point_a_copy, point_a, point_b, raster]) image = renderMapToImage(ms) self.assertTrue( image.save(os.path.join(temp_dir.path(), 'bad.png'), 'PNG')) self.assertFalse( filecmp.cmp(os.path.join(temp_dir.path(), 'bad.png'), os.path.join(temp_dir.path(), 'expected.png')), False) self._change_data_source(point_a, point_a_source, 'ogr') # We are not passing the subset string!! self._change_data_source(point_a_copy, point_a_source, 'ogr') self._change_data_source(point_b, point_b_source, 'ogr') self._change_data_source(raster, raster_source, 'gdal') self.assertTrue(point_a.isValid()) self.assertTrue(point_a_copy.isValid()) self.assertTrue(point_b.isValid()) self.assertTrue(raster.isValid()) ms.setLayers([point_a_copy, point_a, point_b, raster]) image = renderMapToImage(ms) self.assertTrue( image.save(os.path.join(temp_dir.path(), 'actual_fixed.png'), 'PNG')) self.assertTrue( filecmp.cmp(os.path.join(temp_dir.path(), 'actual_fixed.png'), os.path.join(temp_dir.path(), 'expected.png')), False)
if("-T" in sys.argv): export_type = sys.argv[sys.argv.index("-T") + 1] if("-D" in sys.argv): target_dir = sys.argv[sys.argv.index("-D") + 1] if("-O" in sys.argv): output_log = sys.argv[sys.argv.index("-O") + 1] # Instantiate QGIS QgsApplication.setPrefixPath(qgisPrefixPath, True) qgs = QgsApplication([], True) QgsApplication.initQgis() # Open the project p = QgsProject() p.read(project_path) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge( p.layerTreeRoot(), canvas ) bridge.setCanvasLayers() # Get the layers in the project layerList = p.mapLayersByName(parcelle_layer) if not layerList: layers = p.mapLayers() for lname,layer in layers.items(): print(lname+' '+layer.name()+' '+parcelle_layer) layerList = [ layer for lname,layer in layers.items() if layer.name() == parcelle_layer ] layer = layerList[0]
def testSaveLoadProject(self): schema_uri = encode_uri(self.ds_uri, 'qgis_test') project_uri = encode_uri(self.ds_uri, 'qgis_test', 'abc') self.dropProjectsTable() # make sure we have a clean start prj = QgsProject() uri = self.vl.source() vl1 = QgsVectorLayer(uri, 'test', 'postgres') self.assertEqual(vl1.isValid(), True) prj.addMapLayer(vl1) prj_storage = QgsApplication.projectStorageRegistry( ).projectStorageFromType("postgresql") self.assertTrue(prj_storage) lst0 = prj_storage.listProjects(schema_uri) self.assertEqual(lst0, []) # try to save project in the database prj.setFileName(project_uri) res = prj.write() self.assertTrue(res) lst1 = prj_storage.listProjects(schema_uri) self.assertEqual(lst1, ["abc"]) # now try to load the project back prj2 = QgsProject() prj2.setFileName(project_uri) res = prj2.read() self.assertTrue(res) self.assertEqual(len(prj2.mapLayers()), 1) self.assertEqual(prj2.baseName(), "abc") self.assertEqual(prj2.absoluteFilePath(), "") # path not supported for project storages self.assertTrue( abs(prj2.lastModified().secsTo(QDateTime.currentDateTime())) < 10) # try to see project's metadata res, metadata = prj_storage.readProjectStorageMetadata(project_uri) self.assertTrue(res) self.assertEqual(metadata.name, "abc") time_project = metadata.lastModified time_now = QDateTime.currentDateTime() time_diff = time_now.secsTo(time_project) self.assertTrue(abs(time_diff) < 10) # try to remove the project res = prj_storage.removeProject(project_uri) self.assertTrue(res) lst2 = prj_storage.listProjects(schema_uri) self.assertEqual(lst2, []) self.dropProjectsTable( ) # make sure we have a clean finish... "leave no trace"
def test_wfs3_collections_html(self): """Test WFS3 API collections in html format""" request = QgsBufferServerRequest('http://server.qgis.org/wfs3/collections.html') project = QgsProject() project.read(unitTestDataPath('qgis_server') + '/test_project.qgs') self.compareApi(request, project, 'test_wfs3_collections_project.html')
def test_wms_getprint_maptheme(self): """Test project has 2 layer: red and green and three templates: red: follow map theme red green: follow map theme green blank: no map theme """ tmp_dir = QTemporaryDir() shutil.copyfile(os.path.join(unitTestDataPath('qgis_server'), 'test_project_mapthemes.qgs'), os.path.join(tmp_dir.path(), 'test_project_mapthemes.qgs')) shutil.copyfile(os.path.join(unitTestDataPath('qgis_server'), 'test_project_mapthemes.gpkg'), os.path.join(tmp_dir.path(), 'test_project_mapthemes.gpkg')) project = QgsProject() self.assertTrue(project.read(os.path.join(tmp_dir.path(), 'test_project_mapthemes.qgs'))) params = { "SERVICE": "WMS", "VERSION": "1.3", "REQUEST": "GetPrint", "TEMPLATE": "blank", "FORMAT": "png", "LAYERS": "", "map0:EXTENT": "44.92867722467413216,7.097696894150993252,45.0714498943264914,7.378188333645007368", "map0:LAYERS": "red", "CRS": "EPSG:4326", "DPI": '72' } polygon = 'POLYGON((7.09769689415099325 44.92867722467413216, 7.37818833364500737 44.92867722467413216, 7.37818833364500737 45.0714498943264914, 7.09769689415099325 45.0714498943264914, 7.09769689415099325 44.92867722467413216))' ###################################################### # Template map theme tests, no HIGHLIGHT # blank template, specified layer is red response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 255) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 0) # blank template, specified layer is green params["map0:LAYERS"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 255) self.assertEqual(color.blue(), 0) # red template, no specified layers params["map0:LAYERS"] = "" params["TEMPLATE"] = "red" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 255) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 0) # green template, no specified layers params["map0:LAYERS"] = "" params["TEMPLATE"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 255) self.assertEqual(color.blue(), 0) # green template, specified layer is red # This is a conflict situation: the green template map is set to follow green theme # but we tell the server to render the red layer, red is what we get. params["map0:LAYERS"] = "red" params["TEMPLATE"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 255) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 0) ###################################################### # Start HIGHLIGHT tests params["TEMPLATE"] = "blank" params["map0:LAYERS"] = "red" params["map0:HIGHLIGHT_GEOM"] = polygon params["map0:HIGHLIGHT_SYMBOL"] = r'<StyledLayerDescriptor><UserStyle><FeatureTypeStyle><Rule><PolygonSymbolizer><Fill><CssParameter name="fill">%230000FF</CssParameter></Fill></PolygonSymbolizer></Rule></FeatureTypeStyle></UserStyle></StyledLayerDescriptor>' response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 255) # Test highlight without layers params["TEMPLATE"] = "blank" params["map0:LAYERS"] = "" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 255) # Test highlight on follow theme (issue GH #34178) params["TEMPLATE"] = "red" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 255) # Test highlight on follow theme (issue GH #34178) params["TEMPLATE"] = "green" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 255) # Test highlight on follow theme, but add LAYERS (issue GH #34178) params["TEMPLATE"] = "green" params["LAYERS"] = "red" response = QgsBufferServerResponse() request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()])) self.server.handleRequest(request, response, project) image = QImage.fromData(response.body(), "PNG") color = image.pixelColor(100, 100) self.assertEqual(color.red(), 0) self.assertEqual(color.green(), 0) self.assertEqual(color.blue(), 255)
# else: # print("The file does not exist") # Demo d'ús quan es crida el fitxer de la classe per separat if __name__ == "__main__": with qgisapp() as app: # Canvas, projecte i bridge canvas = QgsMapCanvas() project = QgsProject().instance() root = project.layerTreeRoot() bridge = QgsLayerTreeMapCanvasBridge(root, canvas) # llegim un projecte de demo project.read(projecteInicial) # windowTest = QMainWindow() windowTest = MyWindow() # Posem el canvas com a element central windowTest.setCentralWidget(canvas) # Instanciamos la classe QvcrearMapetaConBotones crearMapetaConBotones = QvCrearMapetaConBotones(canvas) crearMapetaConBotones.show() """ Amb aquesta linia: crearMapeta.show() es veuria el widget suelto, separat del canvas. Les següents línies mostren com integrar el widget 'crearMapeta' com a dockWidget. """
def testProjectStorage(self): # New project without fileName p0 = QgsProject() self.assertTrue(p0.auxiliaryStorage().isValid()) # Create new layers with key otherwise auxiliary layers are not # automacially created when added in project vl0 = createLayer() vl0Shp = writeShape(vl0, 'vl0.shp') vl1 = createLayer() vl1Shp = writeShape(vl1, 'vl1.shp') vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr') self.assertTrue(vl0.isValid()) vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr') self.assertTrue(vl1.isValid()) # Add layers to project and check underlying auxiliary layers p0.addMapLayers([vl0, vl1]) self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk')) self.assertTrue( vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char')) al0 = vl0.auxiliaryLayer() al1 = vl1.auxiliaryLayer() self.assertEqual(al0.joinInfo().targetFieldName(), 'pk') self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char') # Add a field in auxiliary layers pdef0 = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut') self.assertTrue(al0.addAuxiliaryField(pdef0)) pdef1 = QgsPropertyDefinition('propname1', QgsPropertyDefinition.DataTypeString, '', '', 'ut') self.assertTrue(al1.addAuxiliaryField(pdef1)) # Check auxiliary fields names af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False) self.assertEqual(af0Name, 'ut_propname') af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False) self.assertEqual(af1Name, 'ut_propname1') # Set value for auxiliary fields req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl0.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True) index0 = vl0.fields().indexOf(af0Name) vl0.changeAttributeValue(f.id(), index0, 333) req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True) index1 = vl1.fields().indexOf(af1Name) vl1.changeAttributeValue(f.id(), index0, 'myvalue') req = QgsFeatureRequest().setFilterExpression("name = 'Orange'") f = QgsFeature() vl1.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) vl1.changeAttributeValue(f.id(), index0, 'myvalue1') # Save the project in a zip file f = tmpPath() + '.qgz' p0.write(f) # Open the zip file with embedded auxiliary storage p1 = QgsProject() p1.read(f) # Check that auxiliary fields are well loaded in layers self.assertEqual(len(p1.mapLayers().values()), 2) for vl in p1.mapLayers().values(): al = vl.auxiliaryLayer() self.assertEqual(len(al.auxiliaryFields()), 1) af = al.auxiliaryFields()[0] afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af) self.assertEqual(afPropDef.origin(), 'ut') if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk': self.assertEqual(afPropDef.name(), 'propname') self.assertEqual(al.featureCount(), 1) req = QgsFeatureRequest().setFilterExpression("name = 'Honey'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index0], 333.0) else: # num_char self.assertEqual(al.featureCount(), 2) self.assertEqual(afPropDef.name(), 'propname1') req = QgsFeatureRequest().setFilterExpression("name = 'Apple'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue') req = QgsFeatureRequest().setFilterExpression( "name = 'Orange'") f = QgsFeature() vl.getFeatures(req).nextFeature(f) self.assertTrue(f.isValid()) self.assertEqual(f.attributes()[index1], 'myvalue1')
def testRelativePaths(self): """ Test whether paths to layer sources are stored as relative to the project path """ tmpDir = QTemporaryDir() tmpFile = "{}/project.qgs".format(tmpDir.path()) copyfile(os.path.join(TEST_DATA_DIR, "points.shp"), os.path.join(tmpDir.path(), "points.shp")) copyfile(os.path.join(TEST_DATA_DIR, "points.dbf"), os.path.join(tmpDir.path(), "points.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "points.shx"), os.path.join(tmpDir.path(), "points.shx")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shp"), os.path.join(tmpDir.path(), "lines.shp")) copyfile(os.path.join(TEST_DATA_DIR, "lines.dbf"), os.path.join(tmpDir.path(), "lines.dbf")) copyfile(os.path.join(TEST_DATA_DIR, "lines.shx"), os.path.join(tmpDir.path(), "lines.shx")) copyfile(os.path.join(TEST_DATA_DIR, "landsat_4326.tif"), os.path.join(tmpDir.path(), "landsat_4326.tif")) project = QgsProject() l0 = QgsVectorLayer(os.path.join(tmpDir.path(), "points.shp"), "points", "ogr") l1 = QgsVectorLayer(os.path.join(tmpDir.path(), "lines.shp"), "lines", "ogr") l2 = QgsRasterLayer(os.path.join(tmpDir.path(), "landsat_4326.tif"), "landsat", "gdal") self.assertTrue(l0.isValid()) self.assertTrue(l1.isValid()) self.assertTrue(l2.isValid()) self.assertTrue(project.addMapLayers([l0, l1, l2])) self.assertTrue(project.write(tmpFile)) del project with open(tmpFile, 'r') as f: content = ''.join(f.readlines()) self.assertTrue('source="./lines.shp"' in content) self.assertTrue('source="./points.shp"' in content) self.assertTrue('source="./landsat_4326.tif"' in content) # Re-read the project and store absolute project = QgsProject() self.assertTrue(project.read(tmpFile)) store = project.layerStore() self.assertEquals(set([l.name() for l in store.mapLayers().values()]), set(['lines', 'landsat', 'points'])) project.writeEntryBool('Paths', '/Absolute', True) tmpFile2 = "{}/project2.qgs".format(tmpDir.path()) self.assertTrue(project.write(tmpFile2)) with open(tmpFile2, 'r') as f: content = ''.join(f.readlines()) self.assertTrue( 'source="{}/lines.shp"'.format(tmpDir.path()) in content) self.assertTrue( 'source="{}/points.shp"'.format(tmpDir.path()) in content) self.assertTrue('source="{}/landsat_4326.tif"'.format( tmpDir.path()) in content) del project
def test_getcapabilities(self): project = self._project_path assert os.path.exists(project), "Project file not found: " + project # without cache query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) doc = QDomDocument("wms_getcapabilities_130.xml") doc.setContent(body) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.1.1&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.1.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WCS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WMTS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) filelist = [f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml")] self.assertEqual(len(filelist), 6, 'Not enough file in cache') cacheManager = self._server_iface.cacheManager() self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True') filelist = [f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml")] self.assertEqual(len(filelist), 0, 'All files in cache are not deleted ') prj = QgsProject() prj.read(project) query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') request = QgsBufferServerRequest(query_string, QgsServerRequest.GetMethod, {}, None) accessControls = self._server_iface.accessControls() cDoc = QDomDocument("wms_getcapabilities_130.xml") self.assertFalse(cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is not None') self.assertTrue(cacheManager.setCachedDocument(doc, prj, request, accessControls), 'setCachedDocument false') self.assertTrue(cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is None') self.assertEqual(doc.documentElement().tagName(), cDoc.documentElement().tagName(), 'cachedDocument not equal to provide document') self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True')
def test_getcapabilities(self): project = self._project_path assert os.path.exists(project), "Project file not found: " + project # without cache query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % ( urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) doc = QDomDocument("wms_getcapabilities_130.xml") doc.setContent(body) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.1.1&REQUEST=%s' % ( urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.1.0&REQUEST=%s' % ( urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.0.0&REQUEST=%s' % ( urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WCS&VERSION=1.0.0&REQUEST=%s' % ( urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WMTS&VERSION=1.0.0&REQUEST=%s' % ( urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) filelist = [ f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml") ] self.assertEqual(len(filelist), 6, 'Not enough file in cache') cacheManager = self._server_iface.cacheManager() self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True') filelist = [ f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml") ] self.assertEqual(len(filelist), 0, 'All files in cache are not deleted ') prj = QgsProject() prj.read(project) query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % ( urllib.parse.quote(project), 'GetCapabilities') request = QgsBufferServerRequest(query_string, QgsServerRequest.GetMethod, {}, None) accessControls = self._server_iface.accessControls() cDoc = QDomDocument("wms_getcapabilities_130.xml") self.assertFalse( cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is not None') self.assertTrue( cacheManager.setCachedDocument(doc, prj, request, accessControls), 'setCachedDocument false') self.assertTrue( cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is None') self.assertEqual(doc.documentElement().tagName(), cDoc.documentElement().tagName(), 'cachedDocument not equal to provide document') self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True')
def test_layer_info(self): p = QgsProject() p.read(list(projects().values())[1]) info = layer_info( p.mapLayer('points_842425df_7f45_4091_a6c9_086e1dc1edd1')) self.assertEqual(info['name'], 'points') self.assertEqual(info['id'], 'points_842425df_7f45_4091_a6c9_086e1dc1edd1') self.assertEqual( info['metadata']['categories'], ['Geoscientific Information', 'Imagery Base Maps Earth Cover']) self.assertEqual( info['metadata']['contacts'][0], { 'name': 'Layer Metadata Contact Name', 'role': 'distributor', 'email': 'Layer Metadata Contact Email', 'fax': 'Layer Metadata Contact Fax', 'voice': 'Layer Metadata Contact Voice', 'organization': 'Layer Metadata Contact Organization', 'position': 'Layer Metadata Contact Position', 'addresses': [{ 'address': 'street 1', 'city': 'Milan', 'country': 'Italy', 'postalCode': '10021', 'type': 'postal', 'administrativeArea': 'Lombardy' }] }) self.assertEqual( info['fields'], { 'fid': { 'type': 'Integer64', 'label': 'fid', 'precision': 0, 'length': 0, 'not_null': True, 'unique': True, 'has_expression': False, 'default': 'Autogenerate', 'expression': '', 'editable': False }, 'name': { 'type': 'String', 'label': 'name', 'precision': 0, 'length': 0, 'not_null': False, 'unique': False, 'has_expression': False, 'default': '', 'expression': '', 'editable': True } })
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