Skip to content

Commit

Permalink
Add API for specifying fallback CRS and layer WKB type to use
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nyalldawson committed Apr 18, 2019
1 parent bca78c0 commit 9da6a03
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 12 deletions.
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions python/core/auto_generated/qgsreadwritecontext.sip.in
Expand Up @@ -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 );
Expand All @@ -128,7 +128,7 @@ Sets data coordinate transform context to ``transformContext``

.. seealso:: :py:func:`transformContext`

.. versionadded:: 3.10
.. versionadded:: 3.8
%End

public:
Expand Down
7 changes: 5 additions & 2 deletions python/core/auto_generated/qgsvectorlayer.sip.in
Expand Up @@ -339,7 +339,7 @@ Constructor for LayerOptions.
%Docstring
Constructor for LayerOptions.

.. versionadded:: 3.10
.. versionadded:: 3.8
%End

bool loadDefaultStyle;
Expand All @@ -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() );
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsattributeeditorelement.h
Expand Up @@ -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
{
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsreadwritecontext.h
Expand Up @@ -120,7 +120,7 @@ class CORE_EXPORT QgsReadWriteContext
*
* \see setTransformContext()
*
* \since QGIS 3.10
* \since QGIS 3.8
*/
QgsCoordinateTransformContext transformContext() const;

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

Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -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>();
Expand Down
31 changes: 28 additions & 3 deletions src/core/qgsvectorlayer.h
Expand Up @@ -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,
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/gui/editorwidgets/qgshtmlwidgetwrapper.h
Expand Up @@ -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
{
Expand Down
18 changes: 18 additions & 0 deletions tests/src/python/test_qgsvectorlayer.py
Expand Up @@ -434,6 +434,24 @@ def testStoreWkbTypeInvalidLayers(self):

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
Expand Down

0 comments on commit 9da6a03

Please sign in to comment.