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_zip_filename(self): tmpDir = QTemporaryDir() tmpFile = "{}/project.qgz".format(tmpDir.path()) project = QgsProject() self.assertFalse(project.write()) project.setFileName(tmpFile) self.assertTrue(project.write()) self.assertTrue(os.path.isfile(tmpFile))
def testProjectTitleWithPeriod(self): tmpDir = QTemporaryDir() tmpFile = "{}/2.18.21.qgs".format(tmpDir.path()) tmpFile2 = "{}/qgis-3.2.0.qgs".format(tmpDir.path()) p0 = QgsProject() p0.setFileName(tmpFile) p1 = QgsProject() p1.setFileName(tmpFile2) self.assertEqual(p0.baseName(), '2.18.21') self.assertEqual(p1.baseName(), 'qgis-3.2.0')
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 testHomePath(self): p = QgsProject() path_changed_spy = QSignalSpy(p.homePathChanged) self.assertFalse(p.homePath()) self.assertFalse(p.presetHomePath()) # simulate save file tmp_dir = QTemporaryDir() tmp_file = "{}/project.qgs".format(tmp_dir.path()) with open(tmp_file, 'w') as f: pass p.setFileName(tmp_file) # home path should be file path self.assertEqual(p.homePath(), tmp_dir.path()) self.assertFalse(p.presetHomePath()) self.assertEqual(len(path_changed_spy), 1) # manually override home path p.setPresetHomePath('/tmp/my_path') self.assertEqual(p.homePath(), '/tmp/my_path') self.assertEqual(p.presetHomePath(), '/tmp/my_path') self.assertEqual(len(path_changed_spy), 2) # check project scope scope = QgsExpressionContextUtils.projectScope(p) self.assertEqual(scope.variable('project_home'), '/tmp/my_path') # no extra signal if path is unchanged p.setPresetHomePath('/tmp/my_path') self.assertEqual(p.homePath(), '/tmp/my_path') self.assertEqual(p.presetHomePath(), '/tmp/my_path') self.assertEqual(len(path_changed_spy), 2) # setting file name should not affect home path is manually set tmp_file_2 = "{}/project/project2.qgs".format(tmp_dir.path()) os.mkdir(tmp_dir.path() + '/project') with open(tmp_file_2, 'w') as f: pass p.setFileName(tmp_file_2) self.assertEqual(p.homePath(), '/tmp/my_path') self.assertEqual(p.presetHomePath(), '/tmp/my_path') self.assertEqual(len(path_changed_spy), 2) scope = QgsExpressionContextUtils.projectScope(p) self.assertEqual(scope.variable('project_home'), '/tmp/my_path') # clear manual path p.setPresetHomePath('') self.assertEqual(p.homePath(), tmp_dir.path() + '/project') self.assertFalse(p.presetHomePath()) self.assertEqual(len(path_changed_spy), 3) scope = QgsExpressionContextUtils.projectScope(p) self.assertEqual(scope.variable('project_home'), tmp_dir.path() + '/project') # relative path p.setPresetHomePath('../home') self.assertEqual(p.homePath(), tmp_dir.path() + '/home') self.assertEqual(p.presetHomePath(), '../home') self.assertEqual(len(path_changed_spy), 4) scope = QgsExpressionContextUtils.projectScope(p) self.assertEqual(scope.variable('project_home'), tmp_dir.path() + '/home') # relative path, no filename p.setFileName('') self.assertEqual(p.homePath(), '../home') self.assertEqual(p.presetHomePath(), '../home') scope = QgsExpressionContextUtils.projectScope(p) self.assertEqual(scope.variable('project_home'), '../home')
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 processAlgorithm(self, parameters, context, feedback): project = QgsProject() project.setFileName( os.path.join(parameters[self.FOLDER], "summary-cycle-qgis.qgs")) project.setCrs(QgsCoordinateReferenceSystem('EPSG:27700')) def getMaxValue(layer, fieldname): maxfound = float("-inf") for f in layer.getFeatures(): attr = f.attribute(fieldname) assert attr >= 0 if attr > maxfound: maxfound = attr return maxfound def addFlowLayerLineWidth(layerpath, fieldname, colour, transparent, layername, widthscale=1): vlayer = QgsVectorLayer(layerpath, layername, "ogr") if not vlayer.isValid(): feedback.pushInfo("Layer failed to load: " + layerpath) else: context.temporaryLayerStore().addMapLayer(vlayer) maxvalue = getMaxValue(vlayer, fieldname) symbol = QgsLineSymbol.createSimple({ 'color': colour, 'size': '1' }) objTransf = QgsSizeScaleTransformer( QgsSizeScaleTransformer.Flannery, 0, #minvalue maxvalue, #maxvalue 0.1, #minsize 5 * widthscale, #maxsize 0, #nullsize 1) #exponent objProp = QgsProperty() objProp.setField(fieldname) objProp.setTransformer(objTransf) symbol.setDataDefinedWidth(objProp) renderer = QgsSingleSymbolRenderer(symbol) vlayer.setRenderer(renderer) vlayer.setOpacity(1 - transparent) project.addMapLayer(vlayer) feedback.pushInfo("Loaded " + layerpath) addFlowLayerLineWidth(parameters[self.PCTSHAPE], parameters[self.PCTFIELD], "red", 0, "School cycling Go Dutch scenario (pupils)", widthscale=0.5) addFlowLayerLineWidth(parameters[self.ALLCYCLESHAPE], parameters[self.ALLFLOWSFIELD], "blue", 0.65, "All current cycling flows (relative)") project.write() return {}
def processAlgorithm(self, parameters, context, feedback): project = QgsProject() project.setFileName( os.path.join(parameters[self.FOLDER], "all-outputs-qgis.qgs")) project.setCrs(QgsCoordinateReferenceSystem('EPSG:27700')) def getMaxValue(layer, fieldname): maxfound = float("-inf") for f in layer.getFeatures(): attr = f.attribute(fieldname) assert attr >= 0 if attr > maxfound: maxfound = attr return maxfound with open( os.path.join(parameters[self.FOLDER], "all-town-metadata.json")) as f: metadata = json.load(f) classmethods = { 'quantile': QgsClassificationQuantile, 'jenks': QgsClassificationJenks, 'equal': QgsClassificationEqualInterval } html = "" output = [] views_sorted_by_mode = sorted(metadata["views"], key=lambda v: v["mode"]) for view in views_sorted_by_mode: keysymbol = u'🔑' viewname = view["label"] keysign = "" if viewname.find(keysymbol) != -1: viewname = viewname.replace(keysymbol, '', 1) keysign = "*** " viewname = keysign + view["mode"] + " " + viewname html += f""" <h2>{viewname}</h2> {view["description"]} <ul> """ for layer in view["layers"]: layername = viewname + " - " + layer["scalar_field_units"] layerpath = os.path.join(parameters[self.FOLDER], layer["file"]) vlayer = QgsVectorLayer(layerpath, layername, "ogr") if not vlayer.isValid(): feedback.pushInfo("Layer failed to load: " + layerpath) else: context.temporaryLayerStore().addMapLayer(vlayer) html += f"""<li><b>file:</b> {layer["file"]}""" if "symbol_field" in layer: html += f"""<ul> <li><b>symbol field:</b> {layer["symbol_field"]} </ul> """ categories = [] scalar_fieldname = layer["scalar_field"] maxvalue = getMaxValue(vlayer, scalar_fieldname) feedback.pushInfo("Max value for %s is %f" % (scalar_fieldname, maxvalue)) for formality in ["I", "F"]: for severity, colour in [(3, 'red'), (2, 'yellow'), (1, 'green')]: colour = { ("I", "red"): "#FF0000", ("I", "yellow"): "#FFFF00", ("I", "green"): "#00FF00", ("F", "red"): "#FF9999", ("F", "yellow"): "#FFFF66", ("F", "green"): "#99FF99", }[(formality, colour)] symbol_code = "%s%d" % (formality, severity) if formality == "F": symbol = QgsMarkerSymbol.createSimple({ 'color': colour, 'size': '3', 'outline_color': '#888888' }) else: assert (formality == "I") symbol = QgsMarkerSymbol.createSimple({ 'color': colour, 'size': '3', 'outline_color': '#000000', 'name': 'star' }) objTransf = QgsSizeScaleTransformer( QgsSizeScaleTransformer.Flannery, 0, #minvalue maxvalue, #maxvalue 3, #minsize 10, #maxsize 0, #nullsize 1) #exponent objProp = QgsProperty() objProp.setField(scalar_fieldname) objProp.setTransformer(objTransf) symbol.setDataDefinedSize(objProp) label = { "F": "Formal", "I": "Informal" }[formality] + " " + { 3: "Major", 2: "Secondary", 1: "Tertiary" }[severity] cat = QgsRendererCategory( symbol_code, symbol, label, True) categories.append(cat) renderer = QgsCategorizedSymbolRenderer( "Crossings", categories) renderer.setClassAttribute(layer["symbol_field"]) vlayer.setRenderer(renderer) else: html += f"""<ul> <li><b>field:</b> {layer["scalar_field"]} <li><b>units:</b> {layer["scalar_field_units"]} <li><b>recommended classification:</b> {layer["classes"]} </ul> """ default_style = QgsStyle().defaultStyle() color_ramp = default_style.colorRamp('bt') renderer = QgsGraduatedSymbolRenderer() renderer.setClassAttribute(layer["scalar_field"]) classmethod = classmethods[layer["classes"]]() renderer.setClassificationMethod(classmethod) renderer.updateClasses(vlayer, 5) renderer.updateColorRamp(color_ramp) vlayer.setRenderer(renderer) project.addMapLayer(vlayer) feedback.pushInfo("Loaded " + layerpath) html += "</ul>" project.write() town = views_sorted_by_mode[0]["town"] with open(os.path.join(parameters[self.FOLDER], "metadata.html"), "w") as htmlfile: htmlfile.write( f"<html><head><title>{town} metadata</title></head><body><h1>{town}</h1>{html}</body></html>" ) return {self.OUTPUT: output}