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
# 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.__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
# 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.__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.
.. versionadded:: 3.0
%End
virtual Qgis::DataProviderFlags flags() const;
%Docstring
Returns the generic data provider flags.
.. versionadded:: 3.26
%End
virtual QgsDataProviderTemporalCapabilities *temporalCapabilities();

View File

@ -486,10 +486,19 @@ The development version
enum class MapLayerProperty
{
UsersCannotToggleEditing,
IsBasemapLayer,
};
typedef QFlags<Qgis::MapLayerProperty> MapLayerProperties;
enum class DataProviderFlag
{
IsBasemapSource,
};
typedef QFlags<Qgis::DataProviderFlag> DataProviderFlags;
enum class AnnotationItemFlag
{
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::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 Qgis::MapLayerProperties properties() const;
QPixmap paletteAsPixmap( int bandNumber = 1 );
%Docstring

View File

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

View File

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

View File

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

View File

@ -778,11 +778,26 @@ class CORE_EXPORT Qgis
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.
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
Q_DECLARE_FLAGS( MapLayerProperties, 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.
*
@ -1468,6 +1483,8 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::VectorLayerTypeFlags )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::MarkerLinePlacements )
Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::TextRendererFlags )
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

View File

@ -480,6 +480,16 @@ QString QgsRasterLayer::htmlMetadata() const
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 )
{
//TODO: This function should take dimensions

View File

@ -344,6 +344,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
bool isSpatial() const override { return true; }
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

View File

@ -403,6 +403,22 @@ QString QgsVectorTileLayer::loadDefaultStyle( bool &resultFlag )
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 )
{
QgsDataSourceUri dsUri;

View File

@ -132,6 +132,7 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsMapLayer
StyleCategories categories = AllStyleCategories ) const override;
void setTransformContext( const QgsCoordinateTransformContext &transformContext ) 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

View File

@ -425,6 +425,17 @@ void QgsWmsProvider::setConnectionName( QString const &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 )
{
if ( layers.size() != mSettings.mActiveSubLayers.size() )

View File

@ -232,6 +232,8 @@ class QgsWmsProvider final: public QgsRasterDataProvider
*/
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;
//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 ) );
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 );
}
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()
{
// test that we auto-populate openstreetmap tile metadata