Add API for specifying fallback CRS and layer WKB type to use

for QgsVectorLayer, when constructing a layer with a URI which
may be invalid

These may be used for layers where the geometry type/CRS is
known in advance, and where the layer path may not be
initially resolvable. (E.g. layers with a URI pointing to a
non-existant file). It is only ever used if the layer cannot
be resolved, otherwise the actual layer geometry type will be
detected and used for the layer.
This commit is contained in:
Nyall Dawson 2019-04-18 10:39:10 +10:00
parent bca78c05c4
commit 9da6a03b50
9 changed files with 62 additions and 12 deletions

View File

@ -406,7 +406,7 @@ class QgsAttributeEditorHtmlElement : QgsAttributeEditorElement
%Docstring
An attribute editor widget that will represent arbitrary HTML code.
.. versionadded:: 3.10
.. versionadded:: 3.8
%End
%TypeHeaderCode

View File

@ -119,7 +119,7 @@ Returns data provider coordinate transform context
.. seealso:: :py:func:`setTransformContext`
.. versionadded:: 3.10
.. versionadded:: 3.8
%End
void setTransformContext( const QgsCoordinateTransformContext &transformContext );
@ -128,7 +128,7 @@ Sets data coordinate transform context to ``transformContext``
.. seealso:: :py:func:`transformContext`
.. versionadded:: 3.10
.. versionadded:: 3.8
%End
public:

View File

@ -339,7 +339,7 @@ Constructor for LayerOptions.
%Docstring
Constructor for LayerOptions.
.. versionadded:: 3.10
.. versionadded:: 3.8
%End
bool loadDefaultStyle;
@ -348,8 +348,11 @@ Constructor for LayerOptions.
QgsCoordinateTransformContext transformContext;
};
QgsWkbTypes::Type fallbackWkbType;
QgsCoordinateReferenceSystem fallbackCrs;
};
explicit QgsVectorLayer( const QString &path = QString(), const QString &baseName = QString(),
const QString &providerLib = "ogr", const QgsVectorLayer::LayerOptions &options = QgsVectorLayer::LayerOptions() );

View File

@ -474,7 +474,7 @@ class CORE_EXPORT QgsAttributeEditorQmlElement : public QgsAttributeEditorElemen
* \ingroup core
* An attribute editor widget that will represent arbitrary HTML code.
*
* \since QGIS 3.10
* \since QGIS 3.8
*/
class CORE_EXPORT QgsAttributeEditorHtmlElement : public QgsAttributeEditorElement
{

View File

@ -120,7 +120,7 @@ class CORE_EXPORT QgsReadWriteContext
*
* \see setTransformContext()
*
* \since QGIS 3.10
* \since QGIS 3.8
*/
QgsCoordinateTransformContext transformContext() const;
@ -129,7 +129,7 @@ class CORE_EXPORT QgsReadWriteContext
*
* \see transformContext()
*
* \since QGIS 3.10
* \since QGIS 3.8
*/
void setTransformContext( const QgsCoordinateTransformContext &transformContext );

View File

@ -148,6 +148,10 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
, mAuxiliaryLayerKey( QString() )
, mReadExtentFromXml( options.readExtentFromXml )
{
if ( options.fallbackCrs.isValid() )
setCrs( options.fallbackCrs, false );
mWkbType = options.fallbackWkbType;
setProviderType( providerKey );
mGeometryOptions = qgis::make_unique<QgsGeometryOptions>();

View File

@ -409,7 +409,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
/**
* Constructor for LayerOptions.
* \since QGIS 3.10
* \since QGIS 3.8
*/
explicit LayerOptions( const QgsCoordinateTransformContext &transformContext,
bool loadDefaultStyle = true,
@ -431,12 +431,37 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
/**
* Coordinate transform context
* \since QGIS 3.10
* \since QGIS 3.8
*/
QgsCoordinateTransformContext transformContext = QgsCoordinateTransformContext();
};
/**
* Fallback geometry type.
*
* This may be set for layers where the geometry type is known in advance, and where
* the layer path may not be initially resolvable. (E.g. layers with a URI pointing
* to a non-existent file). It is only ever used if the layer cannot be resolved,
* otherwise the actual layer geometry type will be detected and used for the layer.
*
* \see fallbackCrs
* \since QGIS 3.8
*/
QgsWkbTypes::Type fallbackWkbType = QgsWkbTypes::Unknown;
/**
* Fallback layer coordinate reference system.
*
* This may be set for layers where the coordinate reference system is known in advance, and where
* the layer path may not be initially resolvable. (E.g. layers with a URI pointing
* to a non-existent file). It is only ever used if the layer cannot be resolved,
* otherwise the actual layer CRS will be detected and used for the layer.
*
* \see fallbackWkbType
* \since QGIS 3.8
*/
QgsCoordinateReferenceSystem fallbackCrs;
};
/**
* Constructor - creates a vector layer

View File

@ -73,7 +73,7 @@ class GUI_EXPORT QgsHtmlWidgetWrapper : public QgsWidgetWrapper
/**
* \ingroup gui
* To pass the QgsExpression functionality and it's context to the context of the QWebView
* \since QGIS 3.10
* \since QGIS 3.8
*/
class HtmlExpression : public QObject
{

View File

@ -434,6 +434,24 @@ class TestQgsVectorLayer(unittest.TestCase, FeatureSourceTestCase):
shutil.rmtree(temp_path, True)
def testFallbackCrsWkbType(self):
"""
Test fallback CRS and WKB types are used when layer path is invalid
"""
vl = QgsVectorLayer('this is an outrage!!!')
self.assertFalse(vl.isValid()) # i'd certainly hope so...
self.assertEqual(vl.wkbType(), QgsWkbTypes.Unknown)
self.assertFalse(vl.crs().isValid())
# with fallback
options = QgsVectorLayer.LayerOptions()
options.fallbackWkbType = QgsWkbTypes.CircularString
options.fallbackCrs = QgsCoordinateReferenceSystem('EPSG:3111')
vl = QgsVectorLayer("i'm the moon", options=options)
self.assertFalse(vl.isValid())
self.assertEqual(vl.wkbType(), QgsWkbTypes.CircularString)
self.assertEqual(vl.crs().authid(), 'EPSG:3111')
def test_layer_crs(self):
"""
Test that spatial layers have CRS, and non-spatial don't