Esempio n. 1
0
    def testSetDataSource(self):
        """Test change data source"""

        temp_dir = QTemporaryDir()
        options = QgsDataProvider.ProviderOptions()
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        layer = QgsRasterLayer(myPath, myBaseName)
        renderer = QgsSingleBandGrayRenderer(layer.dataProvider(), 2)

        image = layer.previewAsImage(QSize(400, 400))
        self.assertFalse(image.isNull())
        self.assertTrue(image.save(os.path.join(temp_dir.path(), 'expected.png'), "PNG"))

        layer.setDataSource(myPath.replace('4326.tif', '4326-BAD_SOURCE.tif'), 'bad_layer', 'gdal', options)
        self.assertFalse(layer.isValid())
        image = layer.previewAsImage(QSize(400, 400))
        self.assertTrue(image.isNull())

        layer.setDataSource(myPath.replace('4326-BAD_SOURCE.tif', '4326.tif'), 'bad_layer', 'gdal', options)
        self.assertTrue(layer.isValid())
        image = layer.previewAsImage(QSize(400, 400))
        self.assertFalse(image.isNull())
        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)
Esempio n. 2
0
    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')
Esempio n. 3
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())
Esempio n. 4
0
    def test_unzip_file_not_exist(self):
        outDir = QTemporaryDir()

        zip = os.path.join(self.zipDir, 'fake.zip')
        rc, files = QgsZipUtils.unzip(zip, outDir.path())

        self.assertFalse(rc)
Esempio n. 5
0
 def testSaveNamedStyle(self):
     layer = QgsVectorLayer("Point?field=fldtxt:string", "layer", "memory")
     dir = QTemporaryDir()
     dir_path = dir.path()
     style_path = os.path.join(dir_path, 'my.qml')
     _, result = layer.saveNamedStyle(style_path)
     self.assertTrue(result)
     self.assertTrue(os.path.exists(style_path))
Esempio n. 6
0
    def test_unzip_ok(self):
        outDir = QTemporaryDir()

        zip = os.path.join(self.zipDir, 'testzip.zip')
        rc, files = QgsZipUtils.unzip(zip, outDir.path())

        self.assertTrue(rc)
        self.assertEqual(len(files), 11)
Esempio 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)
Esempio n. 8
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))
Esempio n. 9
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)
Esempio n. 10
0
    def test_zip_unzip_ok(self):
        zip = tmpPath()

        f0 = os.path.join(unitTestDataPath(), 'multipoint.shp')
        f1 = os.path.join(unitTestDataPath(), 'lines.shp')
        f2 = os.path.join(unitTestDataPath(), 'joins.qgs')

        rc = QgsZipUtils.zip(zip, [f0, f1, f2])
        self.assertTrue(rc)

        outDir = QTemporaryDir()
        rc, files = QgsZipUtils.unzip(zip, outDir.path())

        self.assertTrue(rc)
        self.assertEqual(len(files), 3)
Esempio n. 11
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))
Esempio n. 12
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)
Esempio n. 13
0
 def test_unzip_file_empty(self):
     outDir = QTemporaryDir()
     rc, files = QgsZipUtils.unzip("", outDir.path())
     self.assertFalse(rc)
Esempio n. 14
0
    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')
Esempio n. 15
0
    def test_project_roundtrip(self):
        """Tests that a project with bad layers can be saved and restored"""

        p = QgsProject.instance()
        temp_dir = QTemporaryDir()
        for ext in ('shp', 'dbf', 'shx', 'prj'):
            copyfile(os.path.join(TEST_DATA_DIR, 'lines.%s' % ext), os.path.join(temp_dir.path(), 'lines.%s' % ext))
        copyfile(os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'))
        copyfile(os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'))
        l = QgsVectorLayer(os.path.join(temp_dir.path(), 'lines.shp'), 'lines', 'ogr')
        self.assertTrue(l.isValid())

        rl = QgsRasterLayer(os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'), 'raster', 'gdal')
        self.assertTrue(rl.isValid())
        rl_copy = QgsRasterLayer(os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'), 'raster_copy', 'gdal')
        self.assertTrue(rl_copy.isValid())
        self.assertTrue(p.addMapLayers([l, rl, rl_copy]))

        # Save project
        project_path = os.path.join(temp_dir.path(), 'project.qgs')
        self.assertTrue(p.write(project_path))

        # Re-load the project, checking for the XML properties
        p.removeAllMapLayers()
        self.assertTrue(p.read(project_path))
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.originalXmlProperties() != '')
        self.assertTrue(raster.originalXmlProperties() != '')
        self.assertTrue(raster_copy.originalXmlProperties() != '')
        # Test setter
        raster.setOriginalXmlProperties('pippo')
        self.assertEqual(raster.originalXmlProperties(), 'pippo')

        # Now create and invalid project:
        bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs')
        with open(project_path, 'r') as infile:
            with open(bad_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace('./lines.shp', './lines-BAD_SOURCE.shp').replace('band1_byte_ct_epsg4326_copy.tif', 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif'))

        # Load the bad project
        p.removeAllMapLayers()
        self.assertTrue(p.read(bad_project_path))
        # Check layer is invalid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertIsNotNone(vector.dataProvider())
        self.assertIsNotNone(raster.dataProvider())
        self.assertIsNotNone(raster_copy.dataProvider())
        self.assertFalse(vector.isValid())
        self.assertFalse(raster_copy.isValid())
        # Try a getFeatures
        self.assertEqual([f for f in vector.getFeatures()], [])
        self.assertTrue(raster.isValid())
        self.assertEqual(vector.providerType(), 'ogr')

        # Save the project
        bad_project_path2 = os.path.join(temp_dir.path(), 'project_bad2.qgs')
        p.write(bad_project_path2)
        # Re-save the project, with fixed paths
        good_project_path = os.path.join(temp_dir.path(), 'project_good.qgs')
        with open(bad_project_path2, 'r') as infile:
            with open(good_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace('./lines-BAD_SOURCE.shp', './lines.shp').replace('band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif', 'band1_byte_ct_epsg4326_copy.tif'))

        # Load the good project
        p.removeAllMapLayers()
        self.assertTrue(p.read(good_project_path))
        # Check layer is valid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.isValid())
        self.assertTrue(raster.isValid())
        self.assertTrue(raster_copy.isValid())
Esempio n. 16
0
    def test_project_relations(self):
        """Tests that a project with bad layers and relations can be saved with relations"""

        temp_dir = QTemporaryDir()
        p = QgsProject.instance()
        for ext in ('qgs', 'gpkg'):
            copyfile(os.path.join(TEST_DATA_DIR, 'projects', 'relation_reference_test.%s' % ext), os.path.join(temp_dir.path(), 'relation_reference_test.%s' % ext))

        # Load the good project
        project_path = os.path.join(temp_dir.path(), 'relation_reference_test.qgs')
        p.removeAllMapLayers()
        self.assertTrue(p.read(project_path))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        point_a_source = point_a.publicSource()
        point_b_source = point_b.publicSource()
        self.assertTrue(point_a.isValid())
        self.assertTrue(point_b.isValid())

        # Check relations
        def _check_relations():
            relation = list(p.relationManager().relations().values())[0]
            self.assertTrue(relation.isValid())
            self.assertEqual(relation.referencedLayer().id(), point_b.id())
            self.assertEqual(relation.referencingLayer().id(), point_a.id())

        _check_relations()

        # Now build a bad project
        bad_project_path = os.path.join(temp_dir.path(), 'relation_reference_test_bad.qgs')
        with open(project_path, 'r') as infile:
            with open(bad_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace('./relation_reference_test.gpkg', './relation_reference_test-BAD_SOURCE.gpkg'))

        # Load the bad project
        p.removeAllMapLayers()
        self.assertTrue(p.read(bad_project_path))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        self.assertFalse(point_a.isValid())
        self.assertFalse(point_b.isValid())

        # This fails because relations are not valid anymore
        with self.assertRaises(AssertionError):
            _check_relations()

        # Changing data source, relations should be restored:
        point_a.setDataSource(point_a_source, 'point_a', 'ogr')
        point_b.setDataSource(point_b_source, 'point_b', 'ogr')
        self.assertTrue(point_a.isValid())
        self.assertTrue(point_b.isValid())

        # Check if relations were restored
        _check_relations()

        # Reload the bad project
        p.removeAllMapLayers()
        self.assertTrue(p.read(bad_project_path))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        self.assertFalse(point_a.isValid())
        self.assertFalse(point_b.isValid())

        # This fails because relations are not valid anymore
        with self.assertRaises(AssertionError):
            _check_relations()

        # Save the bad project
        bad_project_path2 = os.path.join(temp_dir.path(), 'relation_reference_test_bad2.qgs')
        p.write(bad_project_path2)

        # Now fix the bad project
        bad_project_path_fixed = os.path.join(temp_dir.path(), 'relation_reference_test_bad_fixed.qgs')
        with open(bad_project_path2, 'r') as infile:
            with open(bad_project_path_fixed, 'w+') as outfile:
                outfile.write(infile.read().replace('./relation_reference_test-BAD_SOURCE.gpkg', './relation_reference_test.gpkg'))

        # Load the fixed project
        p.removeAllMapLayers()
        self.assertTrue(p.read(bad_project_path_fixed))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        point_a_source = point_a.publicSource()
        point_b_source = point_b.publicSource()
        self.assertTrue(point_a.isValid())
        self.assertTrue(point_b.isValid())
        _check_relations()
Esempio n. 17
0
    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)
Esempio n. 18
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
Esempio n. 19
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)
    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)
Esempio n. 21
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
    def test_project_relations(self):
        """Tests that a project with bad layers and relations can be saved with relations"""

        temp_dir = QTemporaryDir()
        p = QgsProject.instance()
        for ext in ('qgs', 'gpkg'):
            copyfile(os.path.join(TEST_DATA_DIR, 'projects', 'relation_reference_test.%s' % ext), os.path.join(temp_dir.path(), 'relation_reference_test.%s' % ext))

        # Load the good project
        project_path = os.path.join(temp_dir.path(), 'relation_reference_test.qgs')
        self.assertTrue(p.read(project_path))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        point_a_source = point_a.publicSource()
        point_b_source = point_b.publicSource()
        self.assertTrue(point_a.isValid())
        self.assertTrue(point_b.isValid())

        # Check relations
        def _check_relations():
            relation = list(p.relationManager().relations().values())[0]
            self.assertTrue(relation.isValid())
            self.assertEqual(relation.referencedLayer().id(), point_b.id())
            self.assertEqual(relation.referencingLayer().id(), point_a.id())

        _check_relations()

        # Now build a bad project
        bad_project_path = os.path.join(temp_dir.path(), 'relation_reference_test_bad.qgs')
        with open(project_path, 'r') as infile:
            with open(bad_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace('./relation_reference_test.gpkg', './relation_reference_test-BAD_SOURCE.gpkg'))

        # Load the bad project
        self.assertTrue(p.read(bad_project_path))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        self.assertFalse(point_a.isValid())
        self.assertFalse(point_b.isValid())

        # This fails because relations are not valid anymore
        with self.assertRaises(AssertionError):
            _check_relations()

        # Changing data source, relations should be restored:
        point_a.setDataSource(point_a_source, 'point_a', 'ogr')
        point_b.setDataSource(point_b_source, 'point_b', 'ogr')
        self.assertTrue(point_a.isValid())
        self.assertTrue(point_b.isValid())

        # Check if relations were restored
        _check_relations()

        # Reload the bad project
        self.assertTrue(p.read(bad_project_path))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        self.assertFalse(point_a.isValid())
        self.assertFalse(point_b.isValid())

        # This fails because relations are not valid anymore
        with self.assertRaises(AssertionError):
            _check_relations()

        # Save the bad project
        bad_project_path2 = os.path.join(temp_dir.path(), 'relation_reference_test_bad2.qgs')
        p.write(bad_project_path2)

        # Now fix the bad project
        bad_project_path_fixed = os.path.join(temp_dir.path(), 'relation_reference_test_bad_fixed.qgs')
        with open(bad_project_path2, 'r') as infile:
            with open(bad_project_path_fixed, 'w+') as outfile:
                outfile.write(infile.read().replace('./relation_reference_test-BAD_SOURCE.gpkg', './relation_reference_test.gpkg'))

        # Load the fixed project
        self.assertTrue(p.read(bad_project_path_fixed))
        point_a = list(p.mapLayersByName('point_a'))[0]
        point_b = list(p.mapLayersByName('point_b'))[0]
        point_a_source = point_a.publicSource()
        point_b_source = point_b.publicSource()
        self.assertTrue(point_a.isValid())
        self.assertTrue(point_b.isValid())
        _check_relations()
Esempio n. 23
0
    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 test_project_roundtrip(self):
        """Tests that a project with bad layers can be saved and restored"""

        p = QgsProject.instance()
        temp_dir = QTemporaryDir()
        for ext in ('shp', 'dbf', 'shx', 'prj'):
            copyfile(os.path.join(TEST_DATA_DIR, 'lines.%s' % ext), os.path.join(temp_dir.path(), 'lines.%s' % ext))
        copyfile(os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'))
        copyfile(os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'))
        l = QgsVectorLayer(os.path.join(temp_dir.path(), 'lines.shp'), 'lines', 'ogr')
        self.assertTrue(l.isValid())

        rl = QgsRasterLayer(os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'), 'raster', 'gdal')
        self.assertTrue(rl.isValid())
        rl_copy = QgsRasterLayer(os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'), 'raster_copy', 'gdal')
        self.assertTrue(rl_copy.isValid())
        self.assertTrue(p.addMapLayers([l, rl, rl_copy]))

        # Save project
        project_path = os.path.join(temp_dir.path(), 'project.qgs')
        self.assertTrue(p.write(project_path))

        # Re-load the project, checking for the XML properties
        self.assertTrue(p.read(project_path))
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.originalXmlProperties() != '')
        self.assertTrue(raster.originalXmlProperties() != '')
        self.assertTrue(raster_copy.originalXmlProperties() != '')
        # Test setter
        raster.setOriginalXmlProperties('pippo')
        self.assertEqual(raster.originalXmlProperties(), 'pippo')

        # Now create and invalid project:
        bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs')
        with open(project_path, 'r') as infile:
            with open(bad_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace('./lines.shp', './lines-BAD_SOURCE.shp').replace('band1_byte_ct_epsg4326_copy.tif', 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif'))

        # Load the bad project
        self.assertTrue(p.read(bad_project_path))
        # Check layer is invalid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertIsNotNone(vector.dataProvider())
        self.assertIsNotNone(raster.dataProvider())
        self.assertIsNotNone(raster_copy.dataProvider())
        self.assertFalse(vector.isValid())
        self.assertFalse(raster_copy.isValid())
        # Try a getFeatures
        self.assertEqual([f for f in vector.getFeatures()], [])
        self.assertTrue(raster.isValid())
        self.assertEqual(vector.providerType(), 'ogr')

        # Save the project
        bad_project_path2 = os.path.join(temp_dir.path(), 'project_bad2.qgs')
        p.write(bad_project_path2)
        # Re-save the project, with fixed paths
        good_project_path = os.path.join(temp_dir.path(), 'project_good.qgs')
        with open(bad_project_path2, 'r') as infile:
            with open(good_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace('./lines-BAD_SOURCE.shp', './lines.shp').replace('band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif', 'band1_byte_ct_epsg4326_copy.tif'))

        # Load the good project
        self.assertTrue(p.read(good_project_path))
        # Check layer is valid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.isValid())
        self.assertTrue(raster.isValid())
        self.assertTrue(raster_copy.isValid())
Esempio n. 25
0
 def test_unzip_file_empty(self):
     outDir = QTemporaryDir()
     rc, files = QgsZipUtils.unzip("", outDir.path())
     self.assertFalse(rc)