Skip to content

Commit

Permalink
Fix raster style restore when setDataSource
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Nov 5, 2018
1 parent fbea9f5 commit 1743318
Show file tree
Hide file tree
Showing 9 changed files with 974 additions and 3 deletions.
39 changes: 39 additions & 0 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -786,6 +786,33 @@ void QgsRasterLayer::setDataProvider( QString const &provider, const QgsDataProv

void QgsRasterLayer::setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag )
{

bool wasValid( isValid() );

QDomImplementation domImplementation;
QDomDocumentType documentType;
QDomDocument doc;
QString errorMsg;
QDomElement rootNode;

// Store the original style
if ( wasValid && ! loadDefaultStyleFlag )
{
documentType = domImplementation.createDocumentType(
QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );
doc = QDomDocument( documentType );
rootNode = doc.createElement( QStringLiteral( "qgis" ) );
rootNode.setAttribute( QStringLiteral( "version" ), Qgis::QGIS_VERSION );
doc.appendChild( rootNode );
QgsReadWriteContext writeContext;
if ( ! writeSymbology( rootNode, doc, errorMsg, writeContext ) )
{
QgsDebugMsg( QStringLiteral( "Could not store symbology for layer %1: %2" )
.arg( name() )
.arg( errorMsg ) );
}
}

if ( mDataProvider )
closeDataProvider();

Expand All @@ -809,6 +836,18 @@ void QgsRasterLayer::setDataSource( const QString &dataSource, const QString &ba
{
loadDefaultStyle( defaultLoadedFlag );
}
else if ( wasValid && errorMsg.isEmpty() ) // Restore the style
{
QgsReadWriteContext readContext;
if ( ! readSymbology( rootNode, errorMsg, readContext ) )
{
QgsDebugMsg( QStringLiteral( "Could not restore symbology for layer %1: %2" )
.arg( name() )
.arg( errorMsg ) );

}
}

if ( !defaultLoadedFlag )
{
setDefaultContrastEnhancement();
Expand Down
61 changes: 59 additions & 2 deletions tests/src/python/test_qgsprojectbadlayers.py
Expand Up @@ -15,22 +15,29 @@
__revision__ = '$Format:%H$'

import os
import filecmp

import qgis # NOQA

from qgis.core import (QgsProject,
QgsVectorLayer,
QgsCoordinateTransform,
QgsMapSettings,
QgsRasterLayer,
QgsMapLayer,
QgsRectangle,
QgsDataProvider,
QgsCoordinateReferenceSystem,
)
from qgis.gui import (QgsLayerTreeMapCanvasBridge,
QgsMapCanvas)

from qgis.PyQt.QtGui import QFont, QColor
from qgis.PyQt.QtTest import QSignalSpy
from qgis.PyQt.QtCore import QT_VERSION_STR, QTemporaryDir
from qgis.PyQt.QtCore import QT_VERSION_STR, QTemporaryDir, QSize

from qgis.testing import start_app, unittest
from utilities import (unitTestDataPath)
from utilities import (unitTestDataPath, renderMapToImage)
from shutil import copyfile

app = start_app()
Expand All @@ -43,6 +50,24 @@ def setUp(self):
p = QgsProject.instance()
p.removeAllMapLayers()

@classmethod
def getBaseMapSettings(cls):
"""
:rtype: QgsMapSettings
"""
ms = QgsMapSettings()
crs = QgsCoordinateReferenceSystem()
""":type: QgsCoordinateReferenceSystem"""
crs.createFromSrid(4326)
ms.setBackgroundColor(QColor(152, 219, 249))
ms.setOutputSize(QSize(420, 280))
ms.setOutputDpi(72)
ms.setFlag(QgsMapSettings.Antialiasing, True)
ms.setFlag(QgsMapSettings.UseAdvancedEffects, False)
ms.setFlag(QgsMapSettings.ForceVectorOutput, False) # no caching?
ms.setDestinationCrs(crs)
return ms

def test_project_roundtrip(self):
"""Tests that a project with bad layers can be saved without loosing them"""

Expand Down Expand Up @@ -202,6 +227,38 @@ def _check_relations():
self.assertTrue(point_b.isValid())
_check_relations()

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()
copyfile(os.path.join(TEST_DATA_DIR, 'projects', 'good_layers_test.qgs'), os.path.join(temp_dir.path(), 'good_layers_test.qgs'))
copyfile(os.path.join(TEST_DATA_DIR, 'projects', 'bad_layers_test.gpkg'), os.path.join(temp_dir.path(), 'bad_layers_test.gpkg'))

p = QgsProject().instance()
self.assertTrue(p.read(os.path.join(TEST_DATA_DIR, 'projects', 'good_layers_test.qgs')))

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.setDataSource(point_a.publicSource(), point_a.name(), 'ogr', options)
point_b.setDataSource(point_b.publicSource(), point_b.name(), 'ogr', options)
raster.setDataSource(raster.publicSource(), 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)


if __name__ == '__main__':
unittest.main()
3 changes: 2 additions & 1 deletion tests/src/python/test_qgsrasterlayer.py
Expand Up @@ -722,6 +722,7 @@ def testSetDataSource(self):
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())
Expand All @@ -738,7 +739,7 @@ def testSetDataSource(self):
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')))
self.assertTrue(filecmp.cmp(os.path.join(temp_dir.path(), 'actual.png'), os.path.join(temp_dir.path(), 'expected.png')), False)


if __name__ == '__main__':
Expand Down
6 changes: 6 additions & 0 deletions tests/testdata/projects/bad_layer_raster_test.tfw
@@ -0,0 +1,6 @@
0.00000055284657534
0
0
-0.00000055284657534
2.8182844964232876
41.98181469976164948
Binary file not shown.
36 changes: 36 additions & 0 deletions tests/testdata/projects/bad_layer_raster_test.tiff.aux.xml
@@ -0,0 +1,36 @@
<PAMDataset>
<PAMRasterBand band="1">
<Histograms>
<HistItem>
<HistMin>-0.498046875</HistMin>
<HistMax>255.498046875</HistMax>
<BucketCount>256</BucketCount>
<IncludeOutOfRange>0</IncludeOutOfRange>
<Approximate>0</Approximate>
<HistCounts>13|18|50|12|7|13|16|15|14|20|6|13|13|8|9|58|31|15|21|16|15|25|51|20|19|22|16|47|30|20|29|32|22|38|24|32|32|39|35|47|70|68|52|35|121|46|42|60|53|37|39|44|49|83|52|63|54|67|77|73|61|72|56|76|63|73|72|76|99|69|93|90|80|85|92|110|100|106|112|109|100|99|92|113|137|151|136|129|182|156|152|146|126|147|162|163|195|157|145|202|219|164|180|175|213|187|206|193|195|214|211|208|192|211|191|925|454|420|397|455|428|333|414|313|402|378|392|418|364|400|427|420|453|444|477|403|447|513|438|537|510|527|530|544|570|546|619|530|595|651|597|660|738|714|668|876|828|20253|2012|1713|1589|1342|1401|1213|1242|1274|1335|1360|1307|1406|1363|1342|3316|1661|1674|1552|1719|1705|1667|1638|1449|1642|1468|1484|1550|1517|1605|1545|1617|1599|1683|2325|2934|3369|3918|4835|5909|7068|7857|148605|9058|10029|10103|9572|9936|10530|10904|11245|10726|10940|10999|11303|11583|12851|13863|15968|20827|1929455|12350|9950|9683|9843|10560|14977|666396|5951|5178|4871|4578|4364|4380|4142|4039|3754|3589|4403|3554|3073|2813|2513|2423|2209|2196|2167|2204|2215|2434|115706|1815|1722|1771|1920|2175|2521|3127|120133</HistCounts>
</HistItem>
</Histograms>
<Metadata>
<MDI key="STATISTICS_MAXIMUM">255</MDI>
<MDI key="STATISTICS_MEAN">217.8975575084</MDI>
<MDI key="STATISTICS_MINIMUM">0</MDI>
<MDI key="STATISTICS_STDDEV">16.402309158646</MDI>
</Metadata>
</PAMRasterBand>
<PAMRasterBand band="2">
<Metadata>
<MDI key="STATISTICS_MAXIMUM">255</MDI>
<MDI key="STATISTICS_MEAN">211.56457158206</MDI>
<MDI key="STATISTICS_MINIMUM">0</MDI>
<MDI key="STATISTICS_STDDEV">19.453039894122</MDI>
</Metadata>
</PAMRasterBand>
<PAMRasterBand band="3">
<Metadata>
<MDI key="STATISTICS_MAXIMUM">255</MDI>
<MDI key="STATISTICS_MEAN">203.74267168054</MDI>
<MDI key="STATISTICS_MINIMUM">8</MDI>
<MDI key="STATISTICS_STDDEV">21.479123268522</MDI>
</Metadata>
</PAMRasterBand>
</PAMDataset>
Binary file added tests/testdata/projects/bad_layers_test.gpkg
Binary file not shown.

0 comments on commit 1743318

Please sign in to comment.