mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Store vector layer wkb type in xml
We can use this when restoring the layer, if the uri turns out to be invalid at that stage (e.g. a file has moved). By storing and falling back to the last known wkb type, we avoid unnecessarily discarding the existing layer renderer, and can still show the expected layer type in the layer tree.
This commit is contained in:
parent
786929b4ea
commit
0f1660990f
@ -1,2 +1,3 @@
|
||||
# The following has been generated automatically from src/core/geometry/qgswkbtypes.h
|
||||
QgsWkbTypes.Type.baseClass = QgsWkbTypes
|
||||
QgsWkbTypes.GeometryType.baseClass = QgsWkbTypes
|
||||
|
@ -128,6 +128,7 @@ class CORE_EXPORT QgsWkbTypes
|
||||
MultiLineString25D,
|
||||
MultiPolygon25D
|
||||
};
|
||||
Q_ENUM( Type )
|
||||
|
||||
/**
|
||||
* The geometry types are used to group QgsWkbTypes::Type in a
|
||||
|
@ -1839,8 +1839,9 @@ bool QgsProject::writeProjectFile( const QString &filename )
|
||||
if ( emIt == mEmbeddedLayers.constEnd() )
|
||||
{
|
||||
QDomElement maplayerElem;
|
||||
// If layer is not valid, let's try to restore saved properties from invalidLayerProperties
|
||||
if ( ml->isValid() )
|
||||
// If layer is not valid, prefer to restore saved properties from invalidLayerProperties. But if that's
|
||||
// not available, just write what we DO have
|
||||
if ( ml->isValid() || ml->originalXmlProperties().isEmpty() )
|
||||
{
|
||||
// general layer metadata
|
||||
maplayerElem = doc->createElement( QStringLiteral( "maplayer" ) );
|
||||
|
@ -1418,6 +1418,11 @@ bool QgsVectorLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &c
|
||||
if ( !setDataProvider( mProviderKey, options ) )
|
||||
{
|
||||
QgsDebugMsg( QStringLiteral( "Could not set data provider for layer %1" ).arg( publicSource() ) );
|
||||
const QDomElement elem = layer_node.toElement();
|
||||
|
||||
// for invalid layer sources, we fallback to stored wkbType if available
|
||||
if ( elem.hasAttribute( QStringLiteral( "wkbType" ) ) )
|
||||
mWkbType = qgsEnumKeyToValue( elem.attribute( QStringLiteral( "wkbType" ) ), mWkbType );
|
||||
}
|
||||
|
||||
QDomElement pkeyElem = pkeyNode.toElement();
|
||||
@ -1705,6 +1710,7 @@ bool QgsVectorLayer::writeXml( QDomNode &layer_node,
|
||||
|
||||
// set the geometry type
|
||||
mapLayerNode.setAttribute( QStringLiteral( "geometry" ), QgsWkbTypes::geometryDisplayString( geometryType() ) );
|
||||
mapLayerNode.setAttribute( QStringLiteral( "wkbType" ), qgsEnumValueToKey( wkbType() ) );
|
||||
|
||||
// add provider node
|
||||
if ( mDataProvider )
|
||||
|
@ -15,9 +15,11 @@ __revision__ = '$Format:%H$'
|
||||
import qgis # NOQA
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
from qgis.PyQt.QtCore import QVariant, Qt
|
||||
from qgis.PyQt.QtGui import QPainter
|
||||
from qgis.PyQt.QtGui import QPainter, QColor
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
|
||||
from qgis.core import (QgsWkbTypes,
|
||||
@ -393,6 +395,45 @@ class TestQgsVectorLayer(unittest.TestCase, FeatureSourceTestCase):
|
||||
# should STILL have kept renderer!
|
||||
self.assertEqual(layer.renderer(), r)
|
||||
|
||||
def testStoreWkbTypeInvalidLayers(self):
|
||||
"""
|
||||
Test that layer wkb types are restored for projects with invalid layer paths
|
||||
"""
|
||||
layer = createLayerWithOnePoint()
|
||||
layer.setName('my test layer')
|
||||
r = QgsSingleSymbolRenderer(QgsSymbol.defaultSymbol(QgsWkbTypes.PointGeometry))
|
||||
r.symbol().setColor(QColor('#123456'))
|
||||
layer.setRenderer(r)
|
||||
self.assertEqual(layer.renderer().symbol().color().name(), '#123456')
|
||||
|
||||
p = QgsProject()
|
||||
p.addMapLayer(layer)
|
||||
|
||||
# reset layer to a bad path
|
||||
options = QgsDataProvider.ProviderOptions()
|
||||
layer.setDataSource('nothing', 'new name', 'ogr', options)
|
||||
# should have kept the same renderer and wkb type!
|
||||
self.assertEqual(layer.wkbType(), QgsWkbTypes.Point)
|
||||
self.assertEqual(layer.renderer().symbol().color().name(), '#123456')
|
||||
|
||||
# save project to a temporary file
|
||||
temp_path = tempfile.mkdtemp()
|
||||
temp_project_path = os.path.join(temp_path, 'temp.qgs')
|
||||
self.assertTrue(p.write(temp_project_path))
|
||||
|
||||
# restore project
|
||||
p2 = QgsProject()
|
||||
self.assertTrue(p2.read(temp_project_path))
|
||||
|
||||
l2 = p2.mapLayersByName('new name')[0]
|
||||
self.assertFalse(l2.isValid())
|
||||
|
||||
# should have kept the same renderer and wkb type!
|
||||
self.assertEqual(l2.wkbType(), QgsWkbTypes.Point)
|
||||
self.assertEqual(l2.renderer().symbol().color().name(), '#123456')
|
||||
|
||||
shutil.rmtree(temp_path, True)
|
||||
|
||||
def test_layer_crs(self):
|
||||
"""
|
||||
Test that spatial layers have CRS, and non-spatial don't
|
||||
|
Loading…
x
Reference in New Issue
Block a user