Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    def test_zip_new_project(self):
        tmpDir = QTemporaryDir()
        tmpFile = "{}/project.qgz".format(tmpDir.path())

        # zip with existing file
        open(tmpFile, 'a').close()

        project = QgsProject()
        self.assertTrue(project.write(tmpFile))

        # zip with non existing file
        os.remove(tmpFile)

        project = QgsProject()
        self.assertTrue(project.write(tmpFile))
        self.assertTrue(os.path.isfile(tmpFile))
Ejemplo n.º 4
0
    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())
Ejemplo n.º 5
0
    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 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"
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
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(), [])
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    def testQgdCreation(self):
        # New project
        p = QgsProject()
        self.assertTrue(p.auxiliaryStorage().isValid())

        # Save the project
        path = tmpPath()
        qgs = path + '.qgs'
        self.assertTrue(p.write(qgs))
        self.assertTrue(os.path.exists(qgs))

        # Auxiliary storage is empty so .qgd file should not be saved
        qgd = path + '.qgd'
        self.assertFalse(os.path.exists(qgd))

        # Add a vector layer and an auxiliary layer in the project
        vl = createLayer()
        self.assertTrue(vl.isValid())
        p.addMapLayers([vl])

        pkf = vl.fields().field(vl.fields().indexOf('pk'))
        al = p.auxiliaryStorage().createAuxiliaryLayer(pkf, vl)
        self.assertTrue(al.isValid())
        vl.setAuxiliaryLayer(al)

        # Add an auxiliary field to have a non empty auxiliary storage
        pdef = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut')
        self.assertTrue(al.addAuxiliaryField(pdef))

        # Save the project
        newpath = tmpPath()
        qgs = newpath + '.qgs'
        self.assertTrue(p.write(qgs))
        self.assertTrue(os.path.exists(qgs))

        # Auxiliary storage is NOT empty so .qgd file should be saved now
        qgd = newpath + '.qgd'
        self.assertTrue(os.path.exists(qgd))
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
    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}
Ejemplo n.º 13
0
    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 {}
Ejemplo n.º 14
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')
Ejemplo n.º 15
0
    def processAlgorithm(self, parameters, context, feedback):
        project = QgsProject()
        project.setFileName(
            os.path.join(parameters[self.FOLDER], "summary-walk-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)

        def addCrossingsLayerSeveritySize(layerpath, colour, transparent,
                                          layername):
            vlayer = QgsVectorLayer(layerpath, layername, "ogr")
            if not vlayer.isValid():
                feedback.pushInfo("Layer failed to load: " + layerpath)
            else:
                context.temporaryLayerStore().addMapLayer(vlayer)

                categories = []
                for formality in ["I", "F"]:
                    for severity, size in [(3, 8), (2, 6), (1, 4)]:
                        symbol_code = "%s%d" % (formality, severity)
                        if formality == "F":
                            symbol = QgsMarkerSymbol.createSimple({
                                'color':
                                colour,
                                'size':
                                str(size),
                                'outline_color':
                                '#888888'
                            })
                        else:
                            assert (formality == "I")
                            symbol = QgsMarkerSymbol.createSimple({
                                'color':
                                colour,
                                'size':
                                str(size),
                                'outline_color':
                                '#000000',
                                'name':
                                'star'
                            })

                        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("symbol")
                vlayer.setRenderer(renderer)
                vlayer.setOpacity(1 - transparent)

                project.addMapLayer(vlayer)
                feedback.pushInfo("Loaded " + layerpath)

        addFlowLayerLineWidth(parameters[self.DESTFLOWSSHP],
                              parameters[self.DESTFLOWSFIELD],
                              "red",
                              0,
                              "School walking flows (pupils)",
                              widthscale=0.5)
        addFlowLayerLineWidth(parameters[self.ALLFLOWSSHP],
                              parameters[self.ALLFLOWSFIELD], "blue", 0.65,
                              "All walking flows (relative)")
        addCrossingsLayerSeveritySize(parameters[self.DESTCROSSINGSSHP], "red",
                                      0, "School crossings")
        addCrossingsLayerSeveritySize(parameters[self.ALLCROSSINGSSHP], "blue",
                                      0.65, "All crossings")

        project.write()
        return {}
Ejemplo n.º 16
0
def test_wmts_document_cache_time(client):
    """  Test getcapabilites response time
    """
    plugin = client.getplugin('wmtsCacheServer')
    assert plugin is not None

    # Create a filter
    cachefilter = plugin.create_filter()

    # Copy project
    shutil.copy(
        client.getprojectpath("france_parts.qgs"),
        client.getprojectpath("france_parts_copy.qgs")
    )

    # Delete document
    project = QgsProject()
    project.setFileName(client.getprojectpath("france_parts_copy.qgs").strpath)

    # Get project document root path
    docroot = cachefilter._cache.get_documents_root(project.fileName())

    cachefilter.deleteCachedDocuments(project)

    assert not os.path.exists(docroot.as_posix())

    parameters = {
        'MAP': project.fileName(),
        'REQUEST': 'GetCapabilities',
        'SERVICE': 'WMTS'
    }

    # Get the cached path from the request parameters
    docpath = cachefilter._cache.get_document_cache(
        project.fileName(), parameters, '.xml'
    ).as_posix()

    assert not os.path.exists(docpath)

    # Make a request
    qs = "?" + "&".join("%s=%s" % item for item in parameters.items())
    rv = client.get(qs, project.fileName())
    assert rv.status_code == 200

    # Test that document cache has been created
    assert os.path.exists(docpath)

    # Get time of document cache creation
    docmtime = os.stat(docpath).st_mtime
    projmtime = project.lastModified().toMSecsSinceEpoch() / 1000.0

    assert projmtime < docmtime

    project.write()
    projmtime = project.lastModified().toMSecsSinceEpoch() / 1000.0

    assert projmtime > docmtime

    # Make a second request
    rv = client.get(qs, project.fileName())
    assert rv.status_code == 200

    ndocmtime = os.stat(docpath).st_mtime
    projmtime = project.lastModified().toMSecsSinceEpoch() / 1000.0

    assert projmtime < ndocmtime
    assert docmtime < ndocmtime

    # Clean files after testing
    Path(client.getprojectpath("france_parts_copy.qgs")).unlink()
Ejemplo n.º 17
0
    def test_read_write_project2(self):
        """
        Test reading and writing to project, signals based
        """
        p = QgsProject()
        original = PlotSettings('test',
                                properties={
                                    'marker_width': 2,
                                    'marker_size': 5
                                },
                                layout={
                                    'title': 'my plot',
                                    'legend_orientation': 'v',
                                    'font_xlabel_color': '#00FFFF'
                                })
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_FILTER,
            QgsProperty.fromExpression('"ap">50'))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_MARKER_SIZE,
            QgsProperty.fromExpression('5+6'))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_COLOR, QgsProperty.fromExpression("'red'"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_STROKE_WIDTH,
            QgsProperty.fromExpression('12/2'))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_TITLE,
            QgsProperty.fromExpression("concat('my', '_title')"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_LEGEND_TITLE,
            QgsProperty.fromExpression("concat('my', '_legend')"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_X_TITLE,
            QgsProperty.fromExpression("concat('my', '_x_axis')"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_Y_TITLE,
            QgsProperty.fromExpression("concat('my', '_y_axis')"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_Z_TITLE,
            QgsProperty.fromExpression("concat('my', '_z_axis')"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_X_MIN, QgsProperty.fromExpression("-1*10"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_X_MAX, QgsProperty.fromExpression("+1*10"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_Y_MIN, QgsProperty.fromExpression("-1*10"))
        original.data_defined_properties.setProperty(
            PlotSettings.PROPERTY_Y_MAX, QgsProperty.fromExpression("+1*10"))

        self.test_read_write_project2_written = False

        def write(doc):
            self.test_read_write_project2_written = True
            original.write_to_project(doc)

        p.writeProject.connect(write)

        path = os.path.join(tempfile.gettempdir(),
                            'test_dataplotly_project.qgs')
        self.assertTrue(p.write(path))
        for _ in range(100):
            QCoreApplication.processEvents()
        self.assertTrue(self.test_read_write_project2_written)

        p2 = QgsProject()
        res = PlotSettings('gg')
        self.test_read_write_project2_read = False

        def read(doc):
            res.read_from_project(doc)
            self.test_read_write_project2_read = True

        p2.readProject.connect(read)
        self.assertTrue(p2.read(path))
        for _ in range(100):
            QCoreApplication.processEvents()
        self.assertTrue(self.test_read_write_project2_read)

        self.assertEqual(res.plot_type, original.plot_type)
        self.assertEqual(res.properties, original.properties)
        self.assertEqual(res.layout, original.layout)
        self.assertEqual(
            res.data_defined_properties.property(PlotSettings.PROPERTY_FILTER),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_FILTER))
        self.assertEqual(
            res.data_defined_properties.property(
                PlotSettings.PROPERTY_MARKER_SIZE),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_MARKER_SIZE))
        self.assertEqual(
            res.data_defined_properties.property(PlotSettings.PROPERTY_COLOR),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_COLOR))
        self.assertEqual(
            res.data_defined_properties.property(
                PlotSettings.PROPERTY_STROKE_WIDTH),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_STROKE_WIDTH))
        self.assertEqual(
            res.data_defined_properties.property(PlotSettings.PROPERTY_TITLE),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_TITLE))
        self.assertEqual(
            res.data_defined_properties.property(
                PlotSettings.PROPERTY_LEGEND_TITLE),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_LEGEND_TITLE))
        self.assertEqual(
            res.data_defined_properties.property(
                PlotSettings.PROPERTY_X_TITLE),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_X_TITLE))
        self.assertEqual(
            res.data_defined_properties.property(
                PlotSettings.PROPERTY_Y_TITLE),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_Y_TITLE))
        self.assertEqual(
            res.data_defined_properties.property(
                PlotSettings.PROPERTY_Z_TITLE),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_Z_TITLE))
        self.assertEqual(
            res.data_defined_properties.property(PlotSettings.PROPERTY_X_MIN),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_X_MIN))
        self.assertEqual(
            res.data_defined_properties.property(PlotSettings.PROPERTY_X_MAX),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_X_MAX))
        self.assertEqual(
            res.data_defined_properties.property(PlotSettings.PROPERTY_Y_MIN),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_Y_MIN))
        self.assertEqual(
            res.data_defined_properties.property(PlotSettings.PROPERTY_Y_MAX),
            original.data_defined_properties.property(
                PlotSettings.PROPERTY_Y_MAX))
Ejemplo n.º 18
0
 def test_zip_invalid_path(self):
     project = QgsProject()
     self.assertFalse(project.write())
     self.assertFalse(project.write(""))
     self.assertFalse(project.write("/fake/test.zip"))
Ejemplo n.º 19
0
def create_basic_qgis_project(project_path=None, project_name=None):
    """
    Create a basic QGIS project with OSM background and a simple vector layer.
    :return: Project file path on successful creation of a new project, None otherwise
    """
    if project_path is None:
        project_path = get_new_qgis_project_filepath(project_name=project_name)
    if project_path is None:
        return False
    new_project = QgsProject()
    crs = QgsCoordinateReferenceSystem()
    crs.createFromString("EPSG:3857")
    new_project.setCrs(crs)
    new_project.setFileName(project_path)
    osm_url = "crs=EPSG:3857&type=xyz&zmin=0&zmax=19&url=http://tile.openstreetmap.org/{z}/{x}/{y}.png"
    osm_layer = QgsRasterLayer(osm_url, "OpenStreetMap", "wms")
    new_project.addMapLayer(osm_layer)

    mem_uri = "Point?crs=epsg:3857"
    mem_layer = QgsVectorLayer(mem_uri, "Survey points", "memory")
    res = mem_layer.dataProvider().addAttributes([
        QgsField("date", QVariant.DateTime),
        QgsField("notes", QVariant.String),
        QgsField("photo", QVariant.String),
    ])
    mem_layer.updateFields()
    vector_fname, err = save_vector_layer_as_gpkg(
        mem_layer, os.path.dirname(project_path))
    if err:
        QMessageBox.warning(None, "Error Creating New Project",
                            f"Couldn't save vector layer to:\n{vector_fname}")
    vector_layer = QgsVectorLayer(vector_fname, "Survey", "ogr")
    symbol = QgsMarkerSymbol.createSimple({
        'name': 'circle',
        'color': '#d73027',
        'size': '3',
        "outline_color": '#e8e8e8',
        'outline_style': 'solid',
        'outline_width': '0.4'
    })
    vector_layer.renderer().setSymbol(symbol)
    fid_ws = QgsEditorWidgetSetup("Hidden", {})
    vector_layer.setEditorWidgetSetup(0, fid_ws)
    datetime_config = {
        'allow_null': True,
        'calendar_popup': True,
        'display_format': 'yyyy-MM-dd HH:mm:ss',
        'field_format': 'yyyy-MM-dd HH:mm:ss',
        'field_iso_format': False
    }
    datetime_ws = QgsEditorWidgetSetup("DateTime", datetime_config)
    vector_layer.setEditorWidgetSetup(1, datetime_ws)
    photo_config = {
        'DocumentViewer': 1,
        'DocumentViewerHeight': 0,
        'DocumentViewerWidth': 0,
        'FileWidget': True,
        'FileWidgetButton': True,
        'FileWidgetFilter': '',
        'RelativeStorage': 1,
        'StorageMode': 0,
        'PropertyCollection': {
            'name': NULL,
            'properties': {},
            'type': 'collection'
        },
    }
    photo_ws = QgsEditorWidgetSetup("ExternalResource", photo_config)
    vector_layer.setEditorWidgetSetup(3, photo_ws)
    new_project.addMapLayer(vector_layer)

    write_success = new_project.write()
    if not write_success:
        QMessageBox.warning(None, "Error Creating New Project",
                            f"Couldn't create new project:\n{project_path}")
        return None
    return project_path
Ejemplo n.º 20
0
    def setUpTestData(cls):

        super().setUpTestData()

        cls.temp_dir = QTemporaryDir()
        cls.temp_project_path = os.path.join(cls.temp_dir.path(),
                                             'pg_openrouteservice.qgs')

        # Create test layer
        conn_str = "dbname='{NAME}' host={HOST} port={PORT} user='******' password='******' sslmode=disable".format(
            **settings.DATABASES['default'])

        cls.conn_uri = conn_str

        md = QgsProviderRegistry.instance().providerMetadata('postgres')

        conn = md.createConnection(conn_str, {})

        conn.executeSql(
            "DROP SCHEMA IF EXISTS \"openrouteservice test\" CASCADE")
        conn.executeSql("CREATE SCHEMA \"openrouteservice test\"")
        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_poly_not_compatible ( pk SERIAL NOT NULL, name TEXT, geom GEOMETRY(POLYGON, 4326), PRIMARY KEY ( pk ) )"
        )

        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_point_not_compatible ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POINT, 4326), PRIMARY KEY ( pk ) )"
        )

        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_compatible ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POLYGON, 4326), PRIMARY KEY ( pk ) )"
        )

        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_compatible_3857 ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POLYGON, 3857), PRIMARY KEY ( pk ) )"
        )

        # Input layers for async tests
        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_point_3857 ( pk SERIAL NOT NULL, geom GEOMETRY(POINT, 3857), PRIMARY KEY ( pk ) )"
        )
        conn.executeSql(
            "CREATE TABLE \"openrouteservice test\".openrouteservice_multipoint_4326 ( pk SERIAL NOT NULL, geom GEOMETRY(MULTIPOINT, 4326), PRIMARY KEY ( pk ) )"
        )

        # Add sample points for async tests
        conn.executeSql(
            """INSERT INTO "openrouteservice test".openrouteservice_multipoint_4326 (geom) VALUES
            ( 'SRID=4326;MULTIPOINT ((-77.55542807059459 37.56350130888833), (-77.5513628235481 37.547924590224554), (-77.53848954123421 37.58068563329007), (-77.59608054105951 37.59518182260462))'::geometry),
	        ('SRID=4326;MULTIPOINT ((-77.4077240945721 37.538254644499624), (-77.41991983571157 37.54470141434406), (-77.4260177062813 37.55920460826607), (-77.39349572990939 37.562427156963516), (-77.40840163574651 37.58337032579007))'::geometry)"""
        )

        conn.executeSql(
            """INSERT INTO "openrouteservice test".openrouteservice_point_3857 (geom) VALUES
            ('SRID=3857;POINT (-8636824.820306677 4510025.909782101)'::geometry),
            ('SRID=3857;POINT (-8633657.031688528 4512364.0394764505)'::geometry),
            ('SRID=3857;POINT (-8637126.514460787 4512741.157169087)'::geometry),
            ('SRID=3857;POINT (-8634109.572919691 4503916.603161385)'::geometry)"""
        )

        cls.layer_specs = {}

        project = QgsProject()

        for table_name, table_spec in {
                'openrouteservice_poly_not_compatible': ('Polygon', 4326),
                'openrouteservice_point_not_compatible': ('Point', 4326),
                'openrouteservice_compatible': ('Polygon', 4326),
                'openrouteservice_compatible_3857': ('Polygon', 3857),
                'openrouteservice_point_3857': ('Point', 3857),
                'openrouteservice_multipoint_4326': ('MultiPoint', 4326),
        }.items():
            layer_uri = conn_str + " sslmode=disable key='pk' estimatedmetadata=false srid={srid} type={geometry_type} checkPrimaryKeyUnicity='0' table=\"openrouteservice test\".\"{table_name}\" (geom)".format(
                table_name=table_name,
                geometry_type=table_spec[0],
                srid=table_spec[1])
            layer = QgsVectorLayer(layer_uri, table_name, 'postgres')
            assert layer.isValid()
            cls.layer_specs[table_name] = layer_uri
            project.addMapLayers([layer])

        assert project.write(cls.temp_project_path)

        Project.objects.filter(title='Test openrouteservice project').delete()

        toc = buildLayerTreeNodeObject(project.layerTreeRoot())

        cls.qdjango_project = Project(qgis_file=File(
            open(cls.temp_project_path, 'r')),
                                      title='Test openrouteservice project',
                                      group=cls.project_group,
                                      layers_tree=toc)
        cls.qdjango_project.save()

        for layer_id, layer in project.mapLayers().items():
            _, created = Layer.objects.get_or_create(
                name=layer.name(),
                title=layer.name(),
                origname=layer.name(),
                qgs_layer_id=layer_id,
                srid=layer.crs().postgisSrid(),
                project=cls.qdjango_project,
                layer_type='postgres',
                datasource=cls.layer_specs[layer.name()])
            assert created

        OpenrouteserviceProject.objects.get_or_create(
            project=cls.qdjango_project,
            services={OpenrouteserviceService.ISOCHRONE.value})
Ejemplo n.º 21
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"
Ejemplo n.º 22
0
    def create(self, path: str, qgis_project: QgsProject):
        qgis_project.setAutoTransaction(self.auto_transaction)
        qgis_project.setEvaluateDefaultValues(self.evaluate_default_values)
        qgis_layers = list()
        for layer in self.layers:
            qgis_layer = layer.create()
            self.layer_added.emit(qgis_layer.id())
            if not self.crs and qgis_layer.isSpatial():
                self.crs = qgis_layer.crs()

            qgis_layers.append(qgis_layer)

        qgis_project.addMapLayers(qgis_layers, not self.legend)

        if self.crs:
            if isinstance(self.crs, QgsCoordinateReferenceSystem):
                qgis_project.setCrs(self.crs)
            else:
                qgis_project.setCrs(
                    QgsCoordinateReferenceSystem.fromEpsgId(self.crs))

        qgis_relations = list(
            qgis_project.relationManager().relations().values())
        dict_domains = {
            layer.layer.id(): layer.is_domain
            for layer in self.layers
        }
        for relation in self.relations:
            rel = relation.create(qgis_project, qgis_relations)
            assert rel.isValid()
            qgis_relations.append(rel)

            if rel.referencedLayerId() in dict_domains and dict_domains[
                    rel.referencedLayerId()]:
                editor_widget_setup = QgsEditorWidgetSetup(
                    'RelationReference', {
                        'Relation': rel.id(),
                        'ShowForm': False,
                        'OrderByValue': True,
                        'ShowOpenFormButton': False
                    })
            else:
                editor_widget_setup = QgsEditorWidgetSetup(
                    'RelationReference', {
                        'Relation': rel.id(),
                        'ShowForm': False,
                        'OrderByValue': True,
                        'ShowOpenFormButton': False,
                        'AllowAddFeatures': True
                    })

            referencing_layer = rel.referencingLayer()
            referencing_layer.setEditorWidgetSetup(rel.referencingFields()[0],
                                                   editor_widget_setup)

        qgis_project.relationManager().setRelations(qgis_relations)

        # Set Bag of Enum widget
        for layer_name, bag_of_enum in self.bags_of_enum.items():
            for attribute, bag_of_enum_info in bag_of_enum.items():
                layer_obj = bag_of_enum_info[0]
                cardinality = bag_of_enum_info[1]
                domain_table = bag_of_enum_info[2]
                key_field = bag_of_enum_info[3]
                value_field = bag_of_enum_info[4]

                allow_null = cardinality.startswith('0')
                allow_multi = cardinality.endswith('*')

                current_layer = layer_obj.create()

                field_widget = 'ValueRelation'
                field_widget_config = {
                    'AllowMulti': allow_multi,
                    'UseCompleter': False,
                    'Value': value_field,
                    'OrderByValue': False,
                    'AllowNull': allow_null,
                    'Layer': domain_table.create().id(),
                    'FilterExpression': '',
                    'Key': key_field,
                    'NofColumns': 1
                }

                field_idx = current_layer.fields().indexOf(attribute)
                setup = QgsEditorWidgetSetup(field_widget, field_widget_config)
                current_layer.setEditorWidgetSetup(field_idx, setup)

        for layer in self.layers:
            layer.create_form(self)

        if self.legend:
            self.legend.create(qgis_project)

        if path:
            qgis_project.write(path)
Ejemplo n.º 23
0
    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
Ejemplo n.º 24
0
 def test_zip_invalid_path(self):
     project = QgsProject()
     self.assertFalse(project.write())
     self.assertFalse(project.write(""))
     self.assertFalse(project.write("/fake/test.zip"))
Ejemplo n.º 25
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')