Add Qgis::MapLayerProperty flag for layers which should be considered

as "basemap" layers

This flag identifies if the layer is considered a 'basemap' layer, where
certain properties of the layer should be ignored when calculating
project-level properties. For instance, the extent of basemap layers
should be ignored when calculating the overall extent of a project,
as these layers are typically global and extend outside of a project's
area of interest.
This commit is contained in:
Nyall Dawson 2022-02-22 10:39:05 +10:00
parent 2785efe636
commit caee2cabbd
16 changed files with 111 additions and 1 deletions

View File

@ -674,10 +674,16 @@ Qgis.FileOperationFlag.__doc__ = 'File operation flags.\n\n.. versionadded:: 3.2
Qgis.FileOperationFlag.baseClass = Qgis Qgis.FileOperationFlag.baseClass = Qgis
# monkey patching scoped based enum # monkey patching scoped based enum
Qgis.MapLayerProperty.UsersCannotToggleEditing.__doc__ = "Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply that the layer is non-editable (see isEditable(), supportsEditing() ), rather that the editable status of the layer cannot be changed by users manually. Since QGIS 3.22." Qgis.MapLayerProperty.UsersCannotToggleEditing.__doc__ = "Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply that the layer is non-editable (see isEditable(), supportsEditing() ), rather that the editable status of the layer cannot be changed by users manually. Since QGIS 3.22."
Qgis.MapLayerProperty.__doc__ = 'Generic map layer properties.\n\n.. versionadded:: 3.22\n\n' + '* ``UsersCannotToggleEditing``: ' + Qgis.MapLayerProperty.UsersCannotToggleEditing.__doc__ Qgis.MapLayerProperty.IsBasemapLayer.__doc__ = "Layer is considered a 'basemap' layer, and certain properties of the layer should be ignored when calculating project-level properties. For instance, the extent of basemap layers is ignored when calculating the extent of a project, as these layers are typically global and extend outside of a project's area of interest. Since QGIS 3.26."
Qgis.MapLayerProperty.__doc__ = 'Generic map layer properties.\n\n.. versionadded:: 3.22\n\n' + '* ``UsersCannotToggleEditing``: ' + Qgis.MapLayerProperty.UsersCannotToggleEditing.__doc__ + '\n' + '* ``IsBasemapLayer``: ' + Qgis.MapLayerProperty.IsBasemapLayer.__doc__
# -- # --
Qgis.MapLayerProperty.baseClass = Qgis Qgis.MapLayerProperty.baseClass = Qgis
# monkey patching scoped based enum # monkey patching scoped based enum
Qgis.DataProviderFlag.IsBasemapSource.__doc__ = "Associated source should be considered a 'basemap' layer. See Qgis::MapLayerProperty::IsBasemapLayer."
Qgis.DataProviderFlag.__doc__ = 'Generic data provider flags.\n\n.. versionadded:: 3.26\n\n' + '* ``IsBasemapSource``: ' + Qgis.DataProviderFlag.IsBasemapSource.__doc__
# --
Qgis.DataProviderFlag.baseClass = Qgis
# monkey patching scoped based enum
Qgis.AnnotationItemFlag.ScaleDependentBoundingBox.__doc__ = "Item's bounding box will vary depending on map scale" Qgis.AnnotationItemFlag.ScaleDependentBoundingBox.__doc__ = "Item's bounding box will vary depending on map scale"
Qgis.AnnotationItemFlag.__doc__ = 'Flags for annotation items.\n\n.. versionadded:: 3.22\n\n' + '* ``ScaleDependentBoundingBox``: ' + Qgis.AnnotationItemFlag.ScaleDependentBoundingBox.__doc__ Qgis.AnnotationItemFlag.__doc__ = 'Flags for annotation items.\n\n.. versionadded:: 3.22\n\n' + '* ``ScaleDependentBoundingBox``: ' + Qgis.AnnotationItemFlag.ScaleDependentBoundingBox.__doc__
# -- # --

View File

@ -145,6 +145,13 @@ Set the data source specification.
Gets the data source specification. Gets the data source specification.
.. versionadded:: 3.0 .. versionadded:: 3.0
%End
virtual Qgis::DataProviderFlags flags() const;
%Docstring
Returns the generic data provider flags.
.. versionadded:: 3.26
%End %End
virtual QgsDataProviderTemporalCapabilities *temporalCapabilities(); virtual QgsDataProviderTemporalCapabilities *temporalCapabilities();

View File

@ -486,10 +486,19 @@ The development version
enum class MapLayerProperty enum class MapLayerProperty
{ {
UsersCannotToggleEditing, UsersCannotToggleEditing,
IsBasemapLayer,
}; };
typedef QFlags<Qgis::MapLayerProperty> MapLayerProperties; typedef QFlags<Qgis::MapLayerProperty> MapLayerProperties;
enum class DataProviderFlag
{
IsBasemapSource,
};
typedef QFlags<Qgis::DataProviderFlag> DataProviderFlags;
enum class AnnotationItemFlag enum class AnnotationItemFlag
{ {
ScaleDependentBoundingBox, ScaleDependentBoundingBox,
@ -913,6 +922,10 @@ QFlags<Qgis::TextRendererFlag> operator|(Qgis::TextRendererFlag f1, QFlags<Qgis:
QFlags<Qgis::HistoryProviderBackend> operator|(Qgis::HistoryProviderBackend f1, QFlags<Qgis::HistoryProviderBackend> f2); QFlags<Qgis::HistoryProviderBackend> operator|(Qgis::HistoryProviderBackend f1, QFlags<Qgis::HistoryProviderBackend> f2);
QFlags<Qgis::MapLayerProperty> operator|(Qgis::MapLayerProperty f1, QFlags<Qgis::MapLayerProperty> f2);
QFlags<Qgis::DataProviderFlag> operator|(Qgis::DataProviderFlag f1, QFlags<Qgis::DataProviderFlag> f2);

View File

@ -291,6 +291,8 @@ Returns a list with classification items (Text and color).
virtual QString htmlMetadata() const; virtual QString htmlMetadata() const;
virtual Qgis::MapLayerProperties properties() const;
QPixmap paletteAsPixmap( int bandNumber = 1 ); QPixmap paletteAsPixmap( int bandNumber = 1 );
%Docstring %Docstring

View File

@ -115,6 +115,8 @@ Constructs a new vector tile layer
virtual QString loadDefaultStyle( bool &resultFlag /Out/ ); virtual QString loadDefaultStyle( bool &resultFlag /Out/ );
virtual Qgis::MapLayerProperties properties() const;
virtual QString loadDefaultMetadata( bool &resultFlag /Out/ ); virtual QString loadDefaultMetadata( bool &resultFlag /Out/ );

View File

@ -27,6 +27,11 @@ QgsDataProvider::QgsDataProvider( const QString &uri, const QgsDataProvider::Pro
mReadFlags = flags; mReadFlags = flags;
} }
Qgis::DataProviderFlags QgsDataProvider::flags() const
{
return Qgis::DataProviderFlags();
}
QgsDataProviderTemporalCapabilities *QgsDataProvider::temporalCapabilities() QgsDataProviderTemporalCapabilities *QgsDataProvider::temporalCapabilities()
{ {
return nullptr; return nullptr;

View File

@ -206,6 +206,13 @@ class CORE_EXPORT QgsDataProvider : public QObject
return QgsDataSourceUri( mDataSourceURI ); return QgsDataSourceUri( mDataSourceURI );
} }
/**
* Returns the generic data provider flags.
*
* \since QGIS 3.26
*/
virtual Qgis::DataProviderFlags flags() const;
/** /**
* Returns the provider's temporal capabilities. * Returns the provider's temporal capabilities.
* *

View File

@ -778,11 +778,26 @@ class CORE_EXPORT Qgis
enum class MapLayerProperty : int enum class MapLayerProperty : int
{ {
UsersCannotToggleEditing = 1 << 0, //!< Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply that the layer is non-editable (see isEditable(), supportsEditing() ), rather that the editable status of the layer cannot be changed by users manually. Since QGIS 3.22. UsersCannotToggleEditing = 1 << 0, //!< Indicates that users are not allowed to toggle editing for this layer. Note that this does not imply that the layer is non-editable (see isEditable(), supportsEditing() ), rather that the editable status of the layer cannot be changed by users manually. Since QGIS 3.22.
IsBasemapLayer = 1 << 1, //!< Layer is considered a 'basemap' layer, and certain properties of the layer should be ignored when calculating project-level properties. For instance, the extent of basemap layers is ignored when calculating the extent of a project, as these layers are typically global and extend outside of a project's area of interest. Since QGIS 3.26.
}; };
//! Map layer properties //! Map layer properties
Q_DECLARE_FLAGS( MapLayerProperties, MapLayerProperty ) Q_DECLARE_FLAGS( MapLayerProperties, MapLayerProperty )
Q_ENUM( MapLayerProperty ) Q_ENUM( MapLayerProperty )
/**
* Generic data provider flags.
*
* \since QGIS 3.26
*/
enum class DataProviderFlag : int
{
IsBasemapSource = 1 << 1, //!< Associated source should be considered a 'basemap' layer. See Qgis::MapLayerProperty::IsBasemapLayer.
};
//! Data provider flags
Q_DECLARE_FLAGS( DataProviderFlags, DataProviderFlag )
Q_ENUM( DataProviderFlag )
/** /**
* Flags for annotation items. * Flags for annotation items.
* *
@ -1468,6 +1483,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::VectorLayerTypeFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::MarkerLinePlacements ) Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::MarkerLinePlacements )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::TextRendererFlags ) Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::TextRendererFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::HistoryProviderBackends ) Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::HistoryProviderBackends )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::MapLayerProperties )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::DataProviderFlags )
// hack to workaround warnings when casting void pointers // hack to workaround warnings when casting void pointers

View File

@ -480,6 +480,16 @@ QString QgsRasterLayer::htmlMetadata() const
return myMetadata; return myMetadata;
} }
Qgis::MapLayerProperties QgsRasterLayer::properties() const
{
Qgis::MapLayerProperties res;
if ( mDataProvider && ( mDataProvider->flags() & Qgis::DataProviderFlag::IsBasemapSource ) )
{
res |= Qgis::MapLayerProperty::IsBasemapLayer;
}
return res;
}
QPixmap QgsRasterLayer::paletteAsPixmap( int bandNumber ) QPixmap QgsRasterLayer::paletteAsPixmap( int bandNumber )
{ {
//TODO: This function should take dimensions //TODO: This function should take dimensions

View File

@ -344,6 +344,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
bool isSpatial() const override { return true; } bool isSpatial() const override { return true; }
QString htmlMetadata() const override; QString htmlMetadata() const override;
Qgis::MapLayerProperties properties() const override;
/** /**
* Returns a 100x100 pixmap of the color palette. If the layer has no palette a white pixmap will be returned * Returns a 100x100 pixmap of the color palette. If the layer has no palette a white pixmap will be returned

View File

@ -403,6 +403,22 @@ QString QgsVectorTileLayer::loadDefaultStyle( bool &resultFlag )
return error; return error;
} }
Qgis::MapLayerProperties QgsVectorTileLayer::properties() const
{
Qgis::MapLayerProperties res;
if ( mSourceType == QLatin1String( "xyz" ) )
{
// always consider xyz vector tiles as basemap layers
res |= Qgis::MapLayerProperty::IsBasemapLayer;
}
else
{
// TODO when should we consider mbtiles layers as basemap layers? potentially if their extent is "large"?
}
return res;
}
bool QgsVectorTileLayer::loadDefaultStyle( QString &error, QStringList &warnings ) bool QgsVectorTileLayer::loadDefaultStyle( QString &error, QStringList &warnings )
{ {
QgsDataSourceUri dsUri; QgsDataSourceUri dsUri;

View File

@ -132,6 +132,7 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsMapLayer
StyleCategories categories = AllStyleCategories ) const override; StyleCategories categories = AllStyleCategories ) const override;
void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override; void setTransformContext( const QgsCoordinateTransformContext &transformContext ) override;
QString loadDefaultStyle( bool &resultFlag SIP_OUT ) override; QString loadDefaultStyle( bool &resultFlag SIP_OUT ) override;
Qgis::MapLayerProperties properties() const override;
/** /**
* Loads the default style for the layer, and returns TRUE if the style was * Loads the default style for the layer, and returns TRUE if the style was

View File

@ -425,6 +425,17 @@ void QgsWmsProvider::setConnectionName( QString const &connName )
mConnectionName = connName; mConnectionName = connName;
} }
Qgis::DataProviderFlags QgsWmsProvider::flags() const
{
Qgis::DataProviderFlags res;
if ( mSettings.mXyz )
{
// always consider XYZ tiles as basemap sources
res |= Qgis::DataProviderFlag::IsBasemapSource;
}
return res;
}
void QgsWmsProvider::setLayerOrder( QStringList const &layers ) void QgsWmsProvider::setLayerOrder( QStringList const &layers )
{ {
if ( layers.size() != mSettings.mActiveSubLayers.size() ) if ( layers.size() != mSettings.mActiveSubLayers.size() )

View File

@ -232,6 +232,8 @@ class QgsWmsProvider final: public QgsRasterDataProvider
*/ */
void setConnectionName( QString const &connName ); void setConnectionName( QString const &connName );
Qgis::DataProviderFlags flags() const override;
bool readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override; bool readBlock( int bandNo, QgsRectangle const &viewExtent, int width, int height, void *data, QgsRasterBlockFeedback *feedback = nullptr ) override;
//void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, QgsCoordinateReferenceSystem srcCRS, QgsCoordinateReferenceSystem destCRS, void *data ); //void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, QgsCoordinateReferenceSystem srcCRS, QgsCoordinateReferenceSystem destCRS, void *data );

View File

@ -133,6 +133,9 @@ void TestQgsVectorTileLayer::test_basic()
const QByteArray invalidTileRawData = mLayer->getRawTile( QgsTileXYZ( 0, 0, 99 ) ); const QByteArray invalidTileRawData = mLayer->getRawTile( QgsTileXYZ( 0, 0, 99 ) );
QCOMPARE( invalidTileRawData.length(), 0 ); QCOMPARE( invalidTileRawData.length(), 0 );
// an xyz vector tile layer should be considered as a basemap layer
QCOMPARE( mLayer->properties(), Qgis::MapLayerProperties( Qgis::MapLayerProperty::IsBasemapLayer ) );
} }

View File

@ -235,6 +235,13 @@ class TestQgsWmsProvider: public QObject
QCOMPARE( encodedUri, uriString ); QCOMPARE( encodedUri, uriString );
} }
void testXyzIsBasemap()
{
// test that xyz tile layers are considered basemap layers
QgsRasterLayer layer( QStringLiteral( "type=xyz&url=file://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=19&zmin=0" ), QString(), QStringLiteral( "wms" ) );
QCOMPARE( layer.properties(), Qgis::MapLayerProperties( Qgis::MapLayerProperty::IsBasemapLayer ) );
}
void testOsmMetadata() void testOsmMetadata()
{ {
// test that we auto-populate openstreetmap tile metadata // test that we auto-populate openstreetmap tile metadata