Skip to content

Commit 384e85c

Browse files
committed
Add option on layer to read extent from xml in case of data source without metadata
1 parent 21c5f3d commit 384e85c

8 files changed

+134
-5
lines changed

python/core/qgsvectordataprovider.sip

+9
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,15 @@ Returns a list of available encodings
524524
:rtype: str
525525
%End
526526

527+
virtual bool hasMetadata() const;
528+
%Docstring
529+
Returns true if the data source has metadata, false otherwise.
530+
531+
:return: true if data source has metadata, false otherwise.
532+
533+
.. versionadded:: 3.0
534+
:rtype: bool
535+
%End
527536
signals:
528537

529538
void raiseError( const QString &msg ) const;

python/core/qgsvectorlayer.sip

+22-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,8 @@ class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator, QgsFeatureSin
315315
};
316316

317317
QgsVectorLayer( const QString &path = QString(), const QString &baseName = QString(),
318-
const QString &providerLib = "ogr", bool loadDefaultStyleFlag = true );
318+
const QString &providerLib = "ogr", bool loadDefaultStyleFlag = true,
319+
bool readExtent = false );
319320
%Docstring
320321
Constructor - creates a vector layer
321322

@@ -328,6 +329,7 @@ class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator, QgsFeatureSin
328329
\param baseName The name used to represent the layer in the legend
329330
\param providerLib The name of the data provider, e.g., "memory", "postgres"
330331
\param loadDefaultStyleFlag whether to load the default style
332+
\param readExtent Read extent from XML if true or let provider determine it if false
331333
%End
332334

333335

@@ -1727,6 +1729,25 @@ Returns the current blending mode for features
17271729
.. versionadded:: 3.0
17281730
%End
17291731

1732+
void setReadExtent( bool readExtent );
1733+
%Docstring
1734+
Flag allowing to indicate if the extent has be read from the XML
1735+
document when data source has no metadata or if the data provider has
1736+
to determine it.
1737+
1738+
.. versionadded:: 3.0
1739+
%End
1740+
1741+
bool readExtent() const;
1742+
%Docstring
1743+
Returns true if the extent is read from the XML document when data
1744+
source has no metadata, false if it's the data provider which determines
1745+
it.
1746+
1747+
.. versionadded:: 3.0
1748+
:rtype: bool
1749+
%End
1750+
17301751
public slots:
17311752

17321753
void select( QgsFeatureId featureId );

src/core/qgsproject.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,16 @@ bool QgsProject::addLayer( const QDomElement &layerElem, QList<QDomNode> &broken
717717
if ( type == QLatin1String( "vector" ) )
718718
{
719719
mapLayer = new QgsVectorLayer;
720+
721+
// apply specific settings to vector layer
722+
QgsSettings s;
723+
if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mapLayer ) )
724+
{
725+
if ( s.value( QStringLiteral( "/qgis/trustProject" ), false ).toBool() )
726+
{
727+
vl->setReadExtent( true );
728+
}
729+
}
720730
}
721731
else if ( type == QLatin1String( "raster" ) )
722732
{

src/core/qgsvectordataprovider.h

+8
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,14 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
516516
*/
517517
virtual QString translateMetadataValue( const QString &mdKey, const QVariant &value ) const { Q_UNUSED( mdKey ); return value.toString(); }
518518

519+
/** Returns true if the data source has metadata, false otherwise.
520+
*
521+
* \returns true if data source has metadata, false otherwise.
522+
*
523+
* \since QGIS 3.0
524+
*/
525+
virtual bool hasMetadata() const { return true; };
526+
519527
signals:
520528

521529
/**

src/core/qgsvectorlayer.cpp

+37-3
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ typedef bool deleteStyleById_t(
133133
QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
134134
const QString &baseName,
135135
const QString &providerKey,
136-
bool loadDefaultStyleFlag )
136+
bool loadDefaultStyleFlag,
137+
bool readExtent )
137138
: QgsMapLayer( VectorLayer, baseName, vectorLayerPath )
138139
, mDataProvider( nullptr )
139140
, mProviderKey( providerKey )
@@ -153,6 +154,7 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
153154
, mLazyExtent( true )
154155
, mSymbolFeatureCounted( false )
155156
, mEditCommandActive( false )
157+
, mReadExtent( readExtent )
156158

157159
{
158160
mActions = new QgsActionManager( this );
@@ -222,6 +224,7 @@ QgsVectorLayer *QgsVectorLayer::clone() const
222224
layer->setAttributeTableConfig( attributeTableConfig() );
223225
layer->setFeatureBlendMode( featureBlendMode() );
224226
layer->setOpacity( opacity() );
227+
layer->setReadExtent( readExtent() );
225228

226229
Q_FOREACH ( const QgsAction &action, actions()->actions() )
227230
{
@@ -800,8 +803,19 @@ QgsRectangle QgsVectorLayer::extent() const
800803

801804
if ( !mValidExtent && mLazyExtent && mDataProvider )
802805
{
803-
// get the extent
804-
QgsRectangle mbr = mDataProvider->extent();
806+
QgsRectangle mbr;
807+
808+
// get the extent from xml
809+
if ( mReadExtent && !mXmlExtent.isNull() && !mDataProvider->hasMetadata() )
810+
{
811+
mbr = mXmlExtent;
812+
}
813+
814+
// get the extent data provider if not yet defined
815+
if ( mbr.isNull() )
816+
{
817+
mbr = mDataProvider->extent();
818+
}
805819

806820
// show the extent
807821
QgsDebugMsg( "Extent of layer: " + mbr.toString() );
@@ -1428,6 +1442,16 @@ bool QgsVectorLayer::readXml( const QDomNode &layer_node, const QgsReadWriteCont
14281442

14291443
setLegend( QgsMapLayerLegend::defaultVectorLegend( this ) );
14301444

1445+
// read extent
1446+
if ( mReadExtent )
1447+
{
1448+
QDomNode extentNode = layer_node.namedItem( QStringLiteral( "extent" ) );
1449+
if ( !extentNode.isNull() )
1450+
{
1451+
mXmlExtent = QgsXmlUtils::readRectangle( extentNode.toElement() );
1452+
}
1453+
}
1454+
14311455
return mValid; // should be true if read successfully
14321456

14331457
} // void QgsVectorLayer::readXml
@@ -4418,3 +4442,13 @@ QgsAbstractVectorLayerLabeling *QgsVectorLayer::readLabelingFromCustomProperties
44184442

44194443
return labeling;
44204444
}
4445+
4446+
void QgsVectorLayer::setReadExtent( bool readExtent )
4447+
{
4448+
mReadExtent = readExtent;
4449+
}
4450+
4451+
bool QgsVectorLayer::readExtent() const
4452+
{
4453+
return mReadExtent;
4454+
}

src/core/qgsvectorlayer.h

+24-1
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,12 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
389389
* \param baseName The name used to represent the layer in the legend
390390
* \param providerLib The name of the data provider, e.g., "memory", "postgres"
391391
* \param loadDefaultStyleFlag whether to load the default style
392+
* \param readExtent Read extent from XML if true or let provider determine it if false
392393
*
393394
*/
394395
QgsVectorLayer( const QString &path = QString(), const QString &baseName = QString(),
395-
const QString &providerLib = "ogr", bool loadDefaultStyleFlag = true );
396+
const QString &providerLib = "ogr", bool loadDefaultStyleFlag = true,
397+
bool readExtent = false );
396398

397399

398400
virtual ~QgsVectorLayer();
@@ -1604,6 +1606,24 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
16041606
*/
16051607
void setEditFormConfig( const QgsEditFormConfig &editFormConfig );
16061608

1609+
/**
1610+
* Flag allowing to indicate if the extent has be read from the XML
1611+
* document when data source has no metadata or if the data provider has
1612+
* to determine it.
1613+
*
1614+
* \since QGIS 3.0
1615+
*/
1616+
void setReadExtent( bool readExtent );
1617+
1618+
/**
1619+
* Returns true if the extent is read from the XML document when data
1620+
* source has no metadata, false if it's the data provider which determines
1621+
* it.
1622+
*
1623+
* \since QGIS 3.0
1624+
*/
1625+
bool readExtent() const;
1626+
16071627
public slots:
16081628

16091629
/**
@@ -2041,6 +2061,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
20412061
//! True while an undo command is active
20422062
bool mEditCommandActive;
20432063

2064+
bool mReadExtent;
2065+
QgsRectangle mXmlExtent;
2066+
20442067
QgsFeatureIds mDeletedFids;
20452068

20462069
QgsAttributeTableConfig mAttributeTableConfig;

src/providers/postgres/qgspostgresprovider.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -4291,6 +4291,19 @@ QgsPostgresProvider::Relkind QgsPostgresProvider::relkind() const
42914291
return kind;
42924292
}
42934293

4294+
bool QgsPostgresProvider::hasMetadata() const
4295+
{
4296+
bool hasMetadata = true;
4297+
QgsPostgresProvider::Relkind kind = relkind();
4298+
4299+
if ( kind == Relkind::View || kind == Relkind::MaterializedView )
4300+
{
4301+
hasMetadata = false;
4302+
}
4303+
4304+
return hasMetadata;
4305+
}
4306+
42944307
/**
42954308
* Class factory to return a pointer to a newly created
42964309
* QgsPostgresProvider object

src/providers/postgres/qgspostgresprovider.h

+11
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,17 @@ class QgsPostgresProvider : public QgsVectorDataProvider
197197
virtual QList<QgsRelation> discoverRelations( const QgsVectorLayer *self, const QList<QgsVectorLayer *> &layers ) const override;
198198
virtual QgsAttrPalIndexNameHash palAttributeIndexNames() const override;
199199

200+
/** Returns true if the data source has metadata, false otherwise. For
201+
* example, if the kind of relation for the layer is a view or a
202+
* materialized view, then no metadata are associated with the data
203+
* source.
204+
*
205+
* \returns true if data source has metadata, false otherwise.
206+
*
207+
* \since QGIS 3.0
208+
*/
209+
virtual bool hasMetadata() const override;
210+
200211
signals:
201212

202213
/**

0 commit comments

Comments
 (0)