mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-17 00:09:36 -04:00
Ensure that non-EPSG:3857 vector tiles layers can be rendered in the
correct place This fixes the rendering of vector tiles layers which are constructed in any non web mercator CRS. (Unfortunately the required information is not recorded in mbtiles packages, so it's necessary to set the correct parameters via API calls when trying to load non-3857 mbtiles.)
This commit is contained in:
parent
1879f51781
commit
b39761f8f0
@ -117,7 +117,9 @@ Returns a tile matrix for the usual web mercator
|
||||
const QgsPointXY &z0TopLeftPoint, double z0Dimension,
|
||||
int z0MatrixWidth = 1, int z0MatrixHeight = 1 );
|
||||
%Docstring
|
||||
Returns a tile matrix for a specific CRS, top left point, zoom level 0 dimension in CRS units
|
||||
Returns a tile matrix for a specific CRS, top left point, zoom level 0 dimension in CRS units.
|
||||
|
||||
The ``z0Dimension`` argument must specify the dimension (width or height, in map units) of the root tiles in zoom level 0.
|
||||
%End
|
||||
|
||||
static QgsTileMatrix fromTileMatrix( const int &zoomLevel, const QgsTileMatrix &tileMatrix );
|
||||
|
@ -130,6 +130,13 @@ Constructs a new vector tile layer
|
||||
|
||||
|
||||
|
||||
QgsVectorTileStructure &tileStructure();
|
||||
%Docstring
|
||||
Returns the vector tile structure.
|
||||
|
||||
.. versionadded:: 3.22.6
|
||||
%End
|
||||
|
||||
QString sourceType() const;
|
||||
%Docstring
|
||||
Returns type of the data source
|
||||
|
@ -0,0 +1,197 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/vectortile/qgsvectortilestructure.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsVectorTileStructure
|
||||
{
|
||||
%Docstring(signature="appended")
|
||||
Encapsulates properties of a vector tile structure, including tile origins and scaling information.
|
||||
|
||||
.. versionadded:: 3.22.6
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsvectortilestructure.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
static QgsVectorTileStructure fromWebMercator();
|
||||
%Docstring
|
||||
Returns a vector tile structure corresponding to the standard web mercator/GoogleCRS84Quad setup.
|
||||
%End
|
||||
|
||||
double z0xMin() const;
|
||||
%Docstring
|
||||
Returns the minimum x coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`setZ0xMin`
|
||||
%End
|
||||
|
||||
void setZ0xMin( double x );
|
||||
%Docstring
|
||||
Sets the minimum ``x`` coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`z0xMin`
|
||||
%End
|
||||
|
||||
double z0xMax() const;
|
||||
%Docstring
|
||||
Returns the maximum x coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`setZ0xMax`
|
||||
%End
|
||||
|
||||
void setZ0xMax( double x );
|
||||
%Docstring
|
||||
Sets the maximum ``x`` coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`z0xMin`
|
||||
%End
|
||||
|
||||
double z0yMin() const;
|
||||
%Docstring
|
||||
Returns the minimum y coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`setZ0xMin`
|
||||
%End
|
||||
|
||||
void setZ0yMin( double y );
|
||||
%Docstring
|
||||
Sets the minimum ``y`` coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`z0yMin`
|
||||
%End
|
||||
|
||||
double z0yMax() const;
|
||||
%Docstring
|
||||
Returns the maximum y coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`setZ0yMax`
|
||||
%End
|
||||
|
||||
void setZ0yMax( double y );
|
||||
%Docstring
|
||||
Sets the maximum ``y`` coordinate for zoom level 0.
|
||||
|
||||
This property is used when scaling raw vector tile coordinates.
|
||||
|
||||
.. seealso:: :py:func:`z0yMin`
|
||||
%End
|
||||
|
||||
double z0Dimension() const;
|
||||
%Docstring
|
||||
Returns the dimension (width or height, in map units) of the root tiles in zoom level 0.
|
||||
|
||||
.. seealso:: :py:func:`setZ0Dimension`
|
||||
%End
|
||||
|
||||
void setZ0Dimension( double dimension );
|
||||
%Docstring
|
||||
Sets the ``dimension`` (width or height, in map units) of the root tiles in zoom level 0.
|
||||
|
||||
.. seealso:: :py:func:`z0Dimension`
|
||||
%End
|
||||
|
||||
double z0Scale() const;
|
||||
%Docstring
|
||||
Returns the scale denominator corresponding to root tiles in zoom level 0.
|
||||
|
||||
.. seealso:: :py:func:`setZ0Dimension`
|
||||
%End
|
||||
|
||||
void setZ0Scale( double scale );
|
||||
%Docstring
|
||||
Sets the ``scale`` denominator of the root tiles in zoom level 0.
|
||||
|
||||
.. seealso:: :py:func:`z0Scale`
|
||||
%End
|
||||
|
||||
QgsCoordinateReferenceSystem crs() const;
|
||||
%Docstring
|
||||
Returns the coordinate reference system associated with the tiles.
|
||||
|
||||
.. seealso:: :py:func:`setCrs`
|
||||
%End
|
||||
|
||||
void setCrs( const QgsCoordinateReferenceSystem &crs );
|
||||
%Docstring
|
||||
Sets the coordinate reference system associated with the tiles.
|
||||
|
||||
.. seealso:: :py:func:`crs`
|
||||
%End
|
||||
|
||||
int minimumZoom() const;
|
||||
%Docstring
|
||||
Returns the minimum zoom level for tiles (where negative = unconstrained).
|
||||
|
||||
.. seealso:: :py:func:`setMinimumZoom`
|
||||
%End
|
||||
|
||||
void setMinimumZoom( int zoom );
|
||||
%Docstring
|
||||
Sets the minimum ``zoom`` level for tiles (where negative = unconstrained).
|
||||
|
||||
.. seealso:: :py:func:`minimumZoom`
|
||||
%End
|
||||
|
||||
int maximumZoom() const;
|
||||
%Docstring
|
||||
Returns the maximum zoom level for tiles (where negative = unconstrained).
|
||||
|
||||
.. seealso:: :py:func:`setMaximumZoom`
|
||||
%End
|
||||
|
||||
void setMaximumZoom( int zoom );
|
||||
%Docstring
|
||||
Sets the maximum ``zoom`` level for tiles (where negative = unconstrained).
|
||||
|
||||
.. seealso:: :py:func:`maximumZoom`
|
||||
%End
|
||||
|
||||
QgsTileMatrix tileMatrix( int zoom ) const;
|
||||
%Docstring
|
||||
Returns the tile matrix corresponding to the specified ``zoom``.
|
||||
%End
|
||||
|
||||
double scaleToZoom( double scale ) const;
|
||||
%Docstring
|
||||
Finds zoom level given a map ``scale`` denominator.
|
||||
%End
|
||||
|
||||
int scaleToZoomLevel( double scale ) const;
|
||||
%Docstring
|
||||
Finds the best fitting (integer) zoom level given a map ``scale`` denominator.
|
||||
|
||||
Values are constrained to the zoom levels between :py:func:`~QgsVectorTileStructure.minimumZoom` and :py:func:`~QgsVectorTileStructure.maximumZoom`.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/vectortile/qgsvectortilestructure.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -692,6 +692,7 @@
|
||||
%Include auto_generated/vectortile/qgsvectortilelabeling.sip
|
||||
%Include auto_generated/vectortile/qgsvectortilelayer.sip
|
||||
%Include auto_generated/vectortile/qgsvectortilerenderer.sip
|
||||
%Include auto_generated/vectortile/qgsvectortilestructure.sip
|
||||
%Include auto_generated/vectortile/qgsvectortilewriter.sip
|
||||
%Include auto_generated/gps/qgsqtlocationconnection.sip
|
||||
%Include auto_generated/gps/qgsgpsconnectionregistry.sip
|
||||
|
@ -845,6 +845,7 @@ set(QGIS_CORE_SRCS
|
||||
vectortile/qgsvectortilemvtencoder.cpp
|
||||
vectortile/qgsvectortilemvtutils.cpp
|
||||
vectortile/qgsvectortileprovidermetadata.cpp
|
||||
vectortile/qgsvectortilestructure.cpp
|
||||
vectortile/qgsvectortileutils.cpp
|
||||
vectortile/qgsvectortilewriter.cpp
|
||||
|
||||
@ -1788,6 +1789,7 @@ set(QGIS_CORE_HDRS
|
||||
vectortile/qgsvectortilemvtutils.h
|
||||
vectortile/qgsvectortileprovidermetadata.h
|
||||
vectortile/qgsvectortilerenderer.h
|
||||
vectortile/qgsvectortilestructure.h
|
||||
vectortile/qgsvectortileutils.h
|
||||
vectortile/qgsvectortilewriter.h
|
||||
)
|
||||
|
@ -107,7 +107,11 @@ class CORE_EXPORT QgsTileMatrix
|
||||
//! Returns a tile matrix for the usual web mercator
|
||||
static QgsTileMatrix fromWebMercator( int zoomLevel );
|
||||
|
||||
//! Returns a tile matrix for a specific CRS, top left point, zoom level 0 dimension in CRS units
|
||||
/**
|
||||
* Returns a tile matrix for a specific CRS, top left point, zoom level 0 dimension in CRS units.
|
||||
*
|
||||
* The \a z0Dimension argument must specify the dimension (width or height, in map units) of the root tiles in zoom level 0.
|
||||
*/
|
||||
static QgsTileMatrix fromCustomDef( int zoomLevel, const QgsCoordinateReferenceSystem &crs,
|
||||
const QgsPointXY &z0TopLeftPoint, double z0Dimension,
|
||||
int z0MatrixWidth = 1, int z0MatrixHeight = 1 );
|
||||
|
@ -40,6 +40,8 @@ QgsVectorTileLayer::QgsVectorTileLayer( const QString &uri, const QString &baseN
|
||||
: QgsMapLayer( QgsMapLayerType::VectorTileLayer, baseName )
|
||||
, mTransformContext( options.transformContext )
|
||||
{
|
||||
mTileStructure = QgsVectorTileStructure::fromWebMercator();
|
||||
|
||||
mDataSource = uri;
|
||||
|
||||
setValid( loadDataSource() );
|
||||
@ -80,13 +82,13 @@ bool QgsVectorTileLayer::loadDataSource()
|
||||
}
|
||||
|
||||
// online tiles
|
||||
mSourceMinZoom = 0;
|
||||
mSourceMaxZoom = 14;
|
||||
mTileStructure.setMinimumZoom( 0 );
|
||||
mTileStructure.setMaximumZoom( 14 );
|
||||
|
||||
if ( dsUri.hasParam( QStringLiteral( "zmin" ) ) )
|
||||
mSourceMinZoom = dsUri.param( QStringLiteral( "zmin" ) ).toInt();
|
||||
mTileStructure.setMinimumZoom( dsUri.param( QStringLiteral( "zmin" ) ).toInt() );
|
||||
if ( dsUri.hasParam( QStringLiteral( "zmax" ) ) )
|
||||
mSourceMaxZoom = dsUri.param( QStringLiteral( "zmax" ) ).toInt();
|
||||
mTileStructure.setMaximumZoom( dsUri.param( QStringLiteral( "zmax" ) ).toInt() );
|
||||
|
||||
setExtent( QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 ) );
|
||||
}
|
||||
@ -111,10 +113,10 @@ bool QgsVectorTileLayer::loadDataSource()
|
||||
const int minZoom = reader.metadataValue( QStringLiteral( "minzoom" ) ).toInt( &minZoomOk );
|
||||
const int maxZoom = reader.metadataValue( QStringLiteral( "maxzoom" ) ).toInt( &maxZoomOk );
|
||||
if ( minZoomOk )
|
||||
mSourceMinZoom = minZoom;
|
||||
mTileStructure.setMinimumZoom( minZoom );
|
||||
if ( maxZoomOk )
|
||||
mSourceMaxZoom = maxZoom;
|
||||
QgsDebugMsgLevel( QStringLiteral( "zoom range: %1 - %2" ).arg( mSourceMinZoom ).arg( mSourceMaxZoom ), 2 );
|
||||
mTileStructure.setMaximumZoom( maxZoom );
|
||||
QgsDebugMsgLevel( QStringLiteral( "zoom range: %1 - %2" ).arg( mTileStructure.minimumZoom() ).arg( mTileStructure.maximumZoom() ), 2 );
|
||||
|
||||
QgsRectangle r = reader.extent();
|
||||
QgsCoordinateTransform ct( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ),
|
||||
@ -190,14 +192,14 @@ bool QgsVectorTileLayer::setupArcgisVectorTileServiceConnection( const QString &
|
||||
|
||||
// if hardcoded zoom limits aren't specified, take them from the server
|
||||
if ( !dataSourceUri.hasParam( QStringLiteral( "zmin" ) ) )
|
||||
mSourceMinZoom = 0;
|
||||
mTileStructure.setMinimumZoom( 0 );
|
||||
else
|
||||
mSourceMinZoom = dataSourceUri.param( QStringLiteral( "zmin" ) ).toInt();
|
||||
mTileStructure.setMinimumZoom( dataSourceUri.param( QStringLiteral( "zmin" ) ).toInt() );
|
||||
|
||||
if ( !dataSourceUri.hasParam( QStringLiteral( "zmax" ) ) )
|
||||
mSourceMaxZoom = mArcgisLayerConfiguration.value( QStringLiteral( "maxzoom" ) ).toInt();
|
||||
mTileStructure.setMaximumZoom( mArcgisLayerConfiguration.value( QStringLiteral( "maxzoom" ) ).toInt() );
|
||||
else
|
||||
mSourceMaxZoom = dataSourceUri.param( QStringLiteral( "zmax" ) ).toInt();
|
||||
mTileStructure.setMaximumZoom( dataSourceUri.param( QStringLiteral( "zmax" ) ).toInt() );
|
||||
|
||||
setExtent( QgsRectangle( -20037508.3427892, -20037508.3427892, 20037508.3427892, 20037508.3427892 ) );
|
||||
|
||||
@ -234,6 +236,26 @@ bool QgsVectorTileLayer::readXml( const QDomNode &layerNode, QgsReadWriteContext
|
||||
{
|
||||
setValid( loadDataSource() );
|
||||
|
||||
const QDomElement structureElement = layerNode.firstChildElement( QStringLiteral( "tileStructure" ) );
|
||||
if ( !structureElement.isNull() )
|
||||
{
|
||||
QgsVectorTileStructure structure;
|
||||
structure.setZ0xMin( structureElement.attribute( QStringLiteral( "z0xMin" ) ).toDouble() );
|
||||
structure.setZ0xMax( structureElement.attribute( QStringLiteral( "z0xMax" ) ).toDouble() );
|
||||
structure.setZ0yMin( structureElement.attribute( QStringLiteral( "z0yMin" ) ).toDouble() );
|
||||
structure.setZ0yMax( structureElement.attribute( QStringLiteral( "z0yMax" ) ).toDouble() );
|
||||
structure.setZ0Dimension( structureElement.attribute( QStringLiteral( "z0Dimension" ) ).toDouble() );
|
||||
structure.setZ0Scale( structureElement.attribute( QStringLiteral( "z0Scale" ) ).toDouble() );
|
||||
structure.setMinimumZoom( structureElement.attribute( QStringLiteral( "minZoom" ) ).toInt() );
|
||||
structure.setMaximumZoom( structureElement.attribute( QStringLiteral( "maxZoom" ) ).toInt() );
|
||||
|
||||
QgsCoordinateReferenceSystem crs;
|
||||
crs.readXml( structureElement );
|
||||
structure.setCrs( crs );
|
||||
|
||||
mTileStructure = structure;
|
||||
}
|
||||
|
||||
QString errorMsg;
|
||||
if ( !readSymbology( layerNode, errorMsg, context ) )
|
||||
return false;
|
||||
@ -247,6 +269,20 @@ bool QgsVectorTileLayer::writeXml( QDomNode &layerNode, QDomDocument &doc, const
|
||||
QDomElement mapLayerNode = layerNode.toElement();
|
||||
mapLayerNode.setAttribute( QStringLiteral( "type" ), QgsMapLayerFactory::typeToString( QgsMapLayerType::VectorTileLayer ) );
|
||||
|
||||
QDomElement structureElement = doc.createElement( QStringLiteral( "tileStructure" ) );
|
||||
structureElement.setAttribute( QStringLiteral( "z0xMin" ), qgsDoubleToString( mTileStructure.z0xMin() ) );
|
||||
structureElement.setAttribute( QStringLiteral( "z0xMax" ), qgsDoubleToString( mTileStructure.z0xMax() ) );
|
||||
structureElement.setAttribute( QStringLiteral( "z0yMin" ), qgsDoubleToString( mTileStructure.z0yMin() ) );
|
||||
structureElement.setAttribute( QStringLiteral( "z0yMax" ), qgsDoubleToString( mTileStructure.z0yMax() ) );
|
||||
structureElement.setAttribute( QStringLiteral( "z0Dimension" ), qgsDoubleToString( mTileStructure.z0Dimension() ) );
|
||||
structureElement.setAttribute( QStringLiteral( "z0Scale" ), qgsDoubleToString( mTileStructure.z0Scale() ) );
|
||||
structureElement.setAttribute( QStringLiteral( "minZoom" ), mTileStructure.minimumZoom() );
|
||||
structureElement.setAttribute( QStringLiteral( "maxZoom" ), mTileStructure.maximumZoom() );
|
||||
mTileStructure.crs().writeXml( structureElement, doc );
|
||||
mapLayerNode.appendChild( structureElement );
|
||||
|
||||
mapLayerNode.setAttribute( QStringLiteral( "type" ), QgsMapLayerFactory::typeToString( QgsMapLayerType::VectorTileLayer ) );
|
||||
|
||||
// add provider node
|
||||
if ( mDataProvider )
|
||||
{
|
||||
@ -702,7 +738,7 @@ QString QgsVectorTileLayer::htmlMetadata() const
|
||||
|
||||
QByteArray QgsVectorTileLayer::getRawTile( QgsTileXYZ tileID )
|
||||
{
|
||||
const QgsTileMatrix tileMatrix = QgsTileMatrix::fromWebMercator( tileID.zoomLevel() );
|
||||
const QgsTileMatrix tileMatrix = mTileStructure.tileMatrix( tileID.zoomLevel() );
|
||||
const QgsTileRange tileRange( tileID.column(), tileID.column(), tileID.row(), tileID.row() );
|
||||
|
||||
QgsDataSourceUri dsUri;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "qgis_sip.h"
|
||||
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgsvectortilestructure.h"
|
||||
|
||||
class QgsVectorTileLabeling;
|
||||
class QgsVectorTileRenderer;
|
||||
@ -155,15 +156,22 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsMapLayer
|
||||
|
||||
// new methods
|
||||
|
||||
/**
|
||||
* Returns the vector tile structure.
|
||||
*
|
||||
* \since QGIS 3.22.6
|
||||
*/
|
||||
QgsVectorTileStructure &tileStructure() { return mTileStructure; }
|
||||
|
||||
//! Returns type of the data source
|
||||
QString sourceType() const { return mSourceType; }
|
||||
//! Returns URL/path of the data source (syntax different to each data source type)
|
||||
QString sourcePath() const { return mSourcePath; }
|
||||
|
||||
//! Returns minimum zoom level at which source has any valid tiles (negative = unconstrained)
|
||||
int sourceMinZoom() const { return mSourceMinZoom; }
|
||||
int sourceMinZoom() const { return mTileStructure.minimumZoom(); }
|
||||
//! Returns maximum zoom level at which source has any valid tiles (negative = unconstrained)
|
||||
int sourceMaxZoom() const { return mSourceMaxZoom; }
|
||||
int sourceMaxZoom() const { return mTileStructure.maximumZoom(); }
|
||||
|
||||
/**
|
||||
* Fetches raw tile data for the give tile coordinates. If failed to fetch tile data,
|
||||
@ -203,10 +211,8 @@ class CORE_EXPORT QgsVectorTileLayer : public QgsMapLayer
|
||||
QString mSourceType;
|
||||
//! URL/Path of the data source
|
||||
QString mSourcePath;
|
||||
//! Minimum zoom level at which source has any valid tiles (negative = unconstrained)
|
||||
int mSourceMinZoom = -1;
|
||||
//! Maximum zoom level at which source has any valid tiles (negative = unconstrained)
|
||||
int mSourceMaxZoom = -1;
|
||||
|
||||
QgsVectorTileStructure mTileStructure;
|
||||
|
||||
//! Renderer assigned to the layer to draw map
|
||||
std::unique_ptr<QgsVectorTileRenderer> mRenderer;
|
||||
|
@ -35,12 +35,11 @@ QgsVectorTileLayerRenderer::QgsVectorTileLayerRenderer( QgsVectorTileLayer *laye
|
||||
: QgsMapLayerRenderer( layer->id(), &context )
|
||||
, mSourceType( layer->sourceType() )
|
||||
, mSourcePath( layer->sourcePath() )
|
||||
, mSourceMinZoom( layer->sourceMinZoom() )
|
||||
, mSourceMaxZoom( layer->sourceMaxZoom() )
|
||||
, mRenderer( layer->renderer()->clone() )
|
||||
, mDrawTileBoundaries( layer->isTileBorderRenderingEnabled() )
|
||||
, mFeedback( new QgsFeedback )
|
||||
, mLayerOpacity( layer->opacity() )
|
||||
, mTileStructure( layer->tileStructure() )
|
||||
{
|
||||
|
||||
QgsDataSourceUri dsUri;
|
||||
@ -86,10 +85,10 @@ bool QgsVectorTileLayerRenderer::render()
|
||||
QgsDebugMsgLevel( QStringLiteral( "Vector tiles rendering extent: " ) + ctx.extent().toString( -1 ), 2 );
|
||||
QgsDebugMsgLevel( QStringLiteral( "Vector tiles map scale 1 : %1" ).arg( ctx.rendererScale() ), 2 );
|
||||
|
||||
mTileZoom = QgsVectorTileUtils::scaleToZoomLevel( ctx.rendererScale(), mSourceMinZoom, mSourceMaxZoom );
|
||||
mTileZoom = mTileStructure.scaleToZoomLevel( ctx.rendererScale() );
|
||||
QgsDebugMsgLevel( QStringLiteral( "Vector tiles zoom level: %1" ).arg( mTileZoom ), 2 );
|
||||
|
||||
mTileMatrix = QgsTileMatrix::fromWebMercator( mTileZoom );
|
||||
mTileMatrix = QgsTileMatrix::fromCustomDef( mTileZoom, mTileStructure.crs(), QgsPointXY( mTileStructure.z0xMin(), mTileStructure.z0yMax() ), mTileStructure.z0Dimension() );
|
||||
|
||||
mTileRange = mTileMatrix.tileRangeFromExtent( ctx.extent() );
|
||||
QgsDebugMsgLevel( QStringLiteral( "Vector tiles range X: %1 - %2 Y: %3 - %4" )
|
||||
@ -150,7 +149,7 @@ bool QgsVectorTileLayerRenderer::render()
|
||||
// add @zoom_level variable which can be used in styling
|
||||
QgsExpressionContextScope *scope = new QgsExpressionContextScope( QObject::tr( "Tiles" ) ); // will be deleted by popper
|
||||
scope->setVariable( QStringLiteral( "zoom_level" ), mTileZoom, true );
|
||||
scope->setVariable( QStringLiteral( "vector_tile_zoom" ), QgsVectorTileUtils::scaleToZoom( ctx.rendererScale() ), true );
|
||||
scope->setVariable( QStringLiteral( "vector_tile_zoom" ), mTileStructure.scaleToZoom( ctx.rendererScale() ), true );
|
||||
const QgsExpressionContextScopePopper popper( ctx.expressionContext(), scope );
|
||||
|
||||
mRenderer->startRender( *renderContext(), mTileZoom, mTileRange );
|
||||
@ -188,7 +187,7 @@ bool QgsVectorTileLayerRenderer::render()
|
||||
|
||||
if ( !isAsync )
|
||||
{
|
||||
for ( const QgsVectorTileRawData &rawTile : rawTiles )
|
||||
for ( const QgsVectorTileRawData &rawTile : std::as_const( rawTiles ) )
|
||||
{
|
||||
if ( ctx.renderingStopped() )
|
||||
break;
|
||||
@ -229,7 +228,7 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData &
|
||||
tLoad.start();
|
||||
|
||||
// currently only MVT encoding supported
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( mTileStructure );
|
||||
if ( !decoder.decode( rawTile.id, rawTile.data ) )
|
||||
{
|
||||
QgsDebugMsgLevel( QStringLiteral( "Failed to parse raw tile data! " ) + rawTile.id.toString(), 2 );
|
||||
@ -262,17 +261,19 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData &
|
||||
if ( ctx.renderingStopped() )
|
||||
return;
|
||||
|
||||
// set up clipping so that rendering does not go behind tile's extent
|
||||
const QgsScopedQPainterState savePainterState( ctx.painter() );
|
||||
// we have to intersect with any existing painter clip regions, or we risk overwriting valid clip
|
||||
// regions setup outside of the vector tile renderer (e.g. layout map clip region)
|
||||
ctx.painter()->setClipRegion( QRegion( tile.tilePolygon() ), Qt::IntersectClip );
|
||||
{
|
||||
// set up clipping so that rendering does not go behind tile's extent
|
||||
const QgsScopedQPainterState savePainterState( ctx.painter() );
|
||||
// we have to intersect with any existing painter clip regions, or we risk overwriting valid clip
|
||||
// regions setup outside of the vector tile renderer (e.g. layout map clip region)
|
||||
ctx.painter()->setClipRegion( QRegion( tile.tilePolygon() ), Qt::IntersectClip );
|
||||
|
||||
QElapsedTimer tDraw;
|
||||
tDraw.start();
|
||||
QElapsedTimer tDraw;
|
||||
tDraw.start();
|
||||
|
||||
mRenderer->renderTile( tile, ctx );
|
||||
mTotalDrawTime += tDraw.elapsed();
|
||||
mRenderer->renderTile( tile, ctx );
|
||||
mTotalDrawTime += tDraw.elapsed();
|
||||
}
|
||||
|
||||
if ( mLabelProvider )
|
||||
mLabelProvider->registerTileFeatures( tile, ctx );
|
||||
@ -284,7 +285,14 @@ void QgsVectorTileLayerRenderer::decodeAndDrawTile( const QgsVectorTileRawData &
|
||||
|
||||
QPen pen( Qt::red );
|
||||
pen.setWidth( 3 );
|
||||
QBrush brush( QColor( 255, 0, 0, 40 ), Qt::BrushStyle::Dense3Pattern );
|
||||
|
||||
ctx.painter()->setPen( pen );
|
||||
ctx.painter()->setBrush( brush );
|
||||
ctx.painter()->drawPolygon( tile.tilePolygon() );
|
||||
#if 0
|
||||
ctx.painter()->setBrush( QBrush( QColor( 255, 0, 0 ) ) );
|
||||
ctx.painter()->drawText( tile.tilePolygon().boundingRect().center(), tile.id().toString() );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ class QgsVectorTileLabelProvider;
|
||||
#include "qgsvectortilerenderer.h"
|
||||
#include "qgsmapclippingregion.h"
|
||||
#include "qgshttpheaders.h"
|
||||
#include "qgsvectortilestructure.h"
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
@ -62,10 +63,6 @@ class QgsVectorTileLayerRenderer : public QgsMapLayerRenderer
|
||||
QString mAuthCfg;
|
||||
QgsHttpHeaders mHeaders;
|
||||
|
||||
//! Minimum zoom level at which source has any valid tiles (negative = unconstrained)
|
||||
int mSourceMinZoom = -1;
|
||||
//! Maximum zoom level at which source has any valid tiles (negative = unconstrained)
|
||||
int mSourceMaxZoom = -1;
|
||||
//! Tile renderer object to do rendering of individual tiles
|
||||
std::unique_ptr<QgsVectorTileRenderer> mRenderer;
|
||||
|
||||
@ -101,6 +98,9 @@ class QgsVectorTileLayerRenderer : public QgsMapLayerRenderer
|
||||
|
||||
QList< QgsMapClippingRegion > mClippingRegions;
|
||||
double mLayerOpacity = 1.0;
|
||||
|
||||
QgsVectorTileStructure mTileStructure;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -31,7 +31,9 @@
|
||||
#include <QPointer>
|
||||
|
||||
|
||||
QgsVectorTileMVTDecoder::QgsVectorTileMVTDecoder() = default;
|
||||
QgsVectorTileMVTDecoder::QgsVectorTileMVTDecoder( const QgsVectorTileStructure &structure )
|
||||
: mStructure( structure )
|
||||
{}
|
||||
|
||||
QgsVectorTileMVTDecoder::~QgsVectorTileMVTDecoder() = default;
|
||||
|
||||
@ -55,7 +57,9 @@ bool QgsVectorTileMVTDecoder::decode( QgsTileXYZ tileID, const QByteArray &rawTi
|
||||
QStringList QgsVectorTileMVTDecoder::layers() const
|
||||
{
|
||||
QStringList layerNames;
|
||||
for ( int layerNum = 0; layerNum < tile.layers_size(); layerNum++ )
|
||||
const int layerSize = tile.layers_size();
|
||||
layerNames.reserve( layerSize );
|
||||
for ( int layerNum = 0; layerNum < layerSize; layerNum++ )
|
||||
{
|
||||
const ::vector_tile::Tile_Layer &layer = tile.layers( layerNum );
|
||||
const QString layerName = layer.name().c_str();
|
||||
@ -71,7 +75,9 @@ QStringList QgsVectorTileMVTDecoder::layerFieldNames( const QString &layerName )
|
||||
|
||||
const ::vector_tile::Tile_Layer &layer = tile.layers( mLayerNameToIndex[layerName] );
|
||||
QStringList fieldNames;
|
||||
for ( int i = 0; i < layer.keys_size(); ++i )
|
||||
const int size = layer.keys_size();
|
||||
fieldNames.reserve( size );
|
||||
for ( int i = 0; i < size; ++i )
|
||||
{
|
||||
const QString fieldName = layer.keys( i ).c_str();
|
||||
fieldNames << fieldName;
|
||||
@ -84,12 +90,10 @@ QgsVectorTileFeatures QgsVectorTileMVTDecoder::layerFeatures( const QMap<QString
|
||||
QgsVectorTileFeatures features;
|
||||
|
||||
const int numTiles = static_cast<int>( pow( 2, mTileID.zoomLevel() ) ); // assuming we won't ever go over 30 zoom levels
|
||||
double z0xMin = -20037508.3427892, z0yMin = -20037508.3427892;
|
||||
double z0xMax = 20037508.3427892, z0yMax = 20037508.3427892;
|
||||
const double tileDX = ( z0xMax - z0xMin ) / numTiles;
|
||||
const double tileDY = ( z0yMax - z0yMin ) / numTiles;
|
||||
const double tileXMin = z0xMin + mTileID.column() * tileDX;
|
||||
const double tileYMax = z0yMax - mTileID.row() * tileDY;
|
||||
const double tileDX = ( mStructure.z0xMax() - mStructure.z0xMin() ) / numTiles;
|
||||
const double tileDY = ( mStructure.z0yMax() - mStructure.z0yMin() ) / numTiles;
|
||||
const double tileXMin = mStructure.z0xMin() + mTileID.column() * tileDX;
|
||||
const double tileYMax = mStructure.z0yMax() - mTileID.row() * tileDY;
|
||||
|
||||
for ( int layerNum = 0; layerNum < tile.layers_size(); layerNum++ )
|
||||
{
|
||||
|
@ -26,6 +26,8 @@ class QgsFeature;
|
||||
#include "vector_tile.pb.h"
|
||||
|
||||
#include "qgsvectortilerenderer.h"
|
||||
#include "qgsvectortilestructure.h"
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
@ -36,7 +38,11 @@ class QgsFeature;
|
||||
class CORE_EXPORT QgsVectorTileMVTDecoder
|
||||
{
|
||||
public:
|
||||
QgsVectorTileMVTDecoder();
|
||||
|
||||
/**
|
||||
* Constructor for QgsVectorTileMVTDecoder, using the specified tile \a structure.
|
||||
*/
|
||||
QgsVectorTileMVTDecoder( const QgsVectorTileStructure &structure );
|
||||
~QgsVectorTileMVTDecoder();
|
||||
|
||||
//! Tries to decode raw tile data, returns true on success
|
||||
@ -59,6 +65,7 @@ class CORE_EXPORT QgsVectorTileMVTDecoder
|
||||
private:
|
||||
vector_tile::Tile tile;
|
||||
QgsTileXYZ mTileID;
|
||||
QgsVectorTileStructure mStructure;
|
||||
QMap<QString, int> mLayerNameToIndex;
|
||||
};
|
||||
|
||||
|
46
src/core/vectortile/qgsvectortilestructure.cpp
Normal file
46
src/core/vectortile/qgsvectortilestructure.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/***************************************************************************
|
||||
qgsvectortilestructure.cpp
|
||||
--------------------------------------
|
||||
Date : March 2022
|
||||
Copyright : (C) 2022 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsvectortilestructure.h"
|
||||
#include "qgstiles.h"
|
||||
#include "qgsvectortileutils.h"
|
||||
|
||||
QgsVectorTileStructure QgsVectorTileStructure::fromWebMercator()
|
||||
{
|
||||
QgsVectorTileStructure res;
|
||||
res.setCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3857" ) ) );
|
||||
res.setZ0xMin( -20037508.3427892 );
|
||||
res.setZ0xMax( 20037508.3427892 );
|
||||
res.setZ0yMin( -20037508.3427892 );
|
||||
res.setZ0yMax( 20037508.3427892 );
|
||||
res.setZ0Dimension( 2 * 20037508.3427892 );
|
||||
res.setZ0Scale( 559082264.0287178 );
|
||||
return res;
|
||||
}
|
||||
|
||||
QgsTileMatrix QgsVectorTileStructure::tileMatrix( int zoom ) const
|
||||
{
|
||||
return QgsTileMatrix::fromCustomDef( zoom, mCrs, QgsPointXY( mZ0xMin, mZ0yMax ), mZ0Dimension );
|
||||
}
|
||||
|
||||
double QgsVectorTileStructure::scaleToZoom( double scale ) const
|
||||
{
|
||||
return QgsVectorTileUtils::scaleToZoom( scale, mZ0Scale );
|
||||
}
|
||||
|
||||
int QgsVectorTileStructure::scaleToZoomLevel( double scale ) const
|
||||
{
|
||||
return QgsVectorTileUtils::scaleToZoomLevel( scale, mMinZoom, mMaxZoom, mZ0Scale );
|
||||
}
|
215
src/core/vectortile/qgsvectortilestructure.h
Normal file
215
src/core/vectortile/qgsvectortilestructure.h
Normal file
@ -0,0 +1,215 @@
|
||||
/***************************************************************************
|
||||
qgsvectortilestructure.h
|
||||
--------------------------------------
|
||||
Date : March 2022
|
||||
Copyright : (C) 2022 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSVECTORTILESTRUCTURE_H
|
||||
#define QGSVECTORTILESTRUCTURE_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
|
||||
class QgsTileMatrix;
|
||||
|
||||
/**
|
||||
* Encapsulates properties of a vector tile structure, including tile origins and scaling information.
|
||||
* \ingroup core
|
||||
* \since QGIS 3.22.6
|
||||
*/
|
||||
class CORE_EXPORT QgsVectorTileStructure
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Returns a vector tile structure corresponding to the standard web mercator/GoogleCRS84Quad setup.
|
||||
*/
|
||||
static QgsVectorTileStructure fromWebMercator();
|
||||
|
||||
/**
|
||||
* Returns the minimum x coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see setZ0xMin()
|
||||
*/
|
||||
double z0xMin() const { return mZ0xMin; }
|
||||
|
||||
/**
|
||||
* Sets the minimum \a x coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see z0xMin()
|
||||
*/
|
||||
void setZ0xMin( double x ) { mZ0xMin = x; }
|
||||
|
||||
/**
|
||||
* Returns the maximum x coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see setZ0xMax()
|
||||
*/
|
||||
double z0xMax() const { return mZ0xMax; }
|
||||
|
||||
/**
|
||||
* Sets the maximum \a x coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see z0xMin()
|
||||
*/
|
||||
void setZ0xMax( double x ) { mZ0xMax = x; }
|
||||
|
||||
/**
|
||||
* Returns the minimum y coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see setZ0xMin()
|
||||
*/
|
||||
double z0yMin() const { return mZ0yMin; }
|
||||
|
||||
/**
|
||||
* Sets the minimum \a y coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see z0yMin()
|
||||
*/
|
||||
void setZ0yMin( double y ) { mZ0yMin = y; }
|
||||
|
||||
/**
|
||||
* Returns the maximum y coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see setZ0yMax()
|
||||
*/
|
||||
double z0yMax() const { return mZ0yMax; }
|
||||
|
||||
/**
|
||||
* Sets the maximum \a y coordinate for zoom level 0.
|
||||
*
|
||||
* This property is used when scaling raw vector tile coordinates.
|
||||
*
|
||||
* \see z0yMin()
|
||||
*/
|
||||
void setZ0yMax( double y ) { mZ0yMax = y; }
|
||||
|
||||
/**
|
||||
* Returns the dimension (width or height, in map units) of the root tiles in zoom level 0.
|
||||
*
|
||||
* \see setZ0Dimension()
|
||||
*/
|
||||
double z0Dimension() const { return mZ0Dimension; }
|
||||
|
||||
/**
|
||||
* Sets the \a dimension (width or height, in map units) of the root tiles in zoom level 0.
|
||||
*
|
||||
* \see z0Dimension()
|
||||
*/
|
||||
void setZ0Dimension( double dimension ) { mZ0Dimension = dimension;}
|
||||
|
||||
/**
|
||||
* Returns the scale denominator corresponding to root tiles in zoom level 0.
|
||||
*
|
||||
* \see setZ0Dimension()
|
||||
*/
|
||||
double z0Scale() const { return mZ0Scale; }
|
||||
|
||||
/**
|
||||
* Sets the \a scale denominator of the root tiles in zoom level 0.
|
||||
*
|
||||
* \see z0Scale()
|
||||
*/
|
||||
void setZ0Scale( double scale ) { mZ0Scale = scale;}
|
||||
|
||||
/**
|
||||
* Returns the coordinate reference system associated with the tiles.
|
||||
*
|
||||
* \see setCrs()
|
||||
*/
|
||||
QgsCoordinateReferenceSystem crs() const { return mCrs; }
|
||||
|
||||
/**
|
||||
* Sets the coordinate reference system associated with the tiles.
|
||||
*
|
||||
* \see crs()
|
||||
*/
|
||||
void setCrs( const QgsCoordinateReferenceSystem &crs ) { mCrs = crs; }
|
||||
|
||||
/**
|
||||
* Returns the minimum zoom level for tiles (where negative = unconstrained).
|
||||
*
|
||||
* \see setMinimumZoom()
|
||||
*/
|
||||
int minimumZoom() const { return mMinZoom; }
|
||||
|
||||
/**
|
||||
* Sets the minimum \a zoom level for tiles (where negative = unconstrained).
|
||||
*
|
||||
* \see minimumZoom()
|
||||
*/
|
||||
void setMinimumZoom( int zoom ) { mMinZoom = zoom; }
|
||||
|
||||
/**
|
||||
* Returns the maximum zoom level for tiles (where negative = unconstrained).
|
||||
*
|
||||
* \see setMaximumZoom()
|
||||
*/
|
||||
int maximumZoom() const { return mMaxZoom; }
|
||||
|
||||
/**
|
||||
* Sets the maximum \a zoom level for tiles (where negative = unconstrained).
|
||||
*
|
||||
* \see maximumZoom()
|
||||
*/
|
||||
void setMaximumZoom( int zoom ) { mMaxZoom = zoom; }
|
||||
|
||||
/**
|
||||
* Returns the tile matrix corresponding to the specified \a zoom.
|
||||
*/
|
||||
QgsTileMatrix tileMatrix( int zoom ) const;
|
||||
|
||||
/**
|
||||
* Finds zoom level given a map \a scale denominator.
|
||||
*/
|
||||
double scaleToZoom( double scale ) const;
|
||||
|
||||
/**
|
||||
* Finds the best fitting (integer) zoom level given a map \a scale denominator.
|
||||
*
|
||||
* Values are constrained to the zoom levels between minimumZoom() and maximumZoom().
|
||||
*/
|
||||
int scaleToZoomLevel( double scale ) const;
|
||||
|
||||
private:
|
||||
|
||||
double mZ0xMin = 0;
|
||||
double mZ0xMax = 0;
|
||||
double mZ0yMin = 0;
|
||||
double mZ0yMax = 0;
|
||||
|
||||
double mZ0Dimension = 0;
|
||||
double mZ0Scale = 0;
|
||||
|
||||
int mMinZoom = -1;
|
||||
int mMaxZoom = -1;
|
||||
|
||||
QgsCoordinateReferenceSystem mCrs;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSVECTORTILESTRUCTURE_H
|
@ -48,7 +48,7 @@ QPolygon QgsVectorTileUtils::tilePolygon( QgsTileXYZ id, const QgsCoordinateTran
|
||||
return path;
|
||||
}
|
||||
|
||||
QgsFields QgsVectorTileUtils::makeQgisFields( QSet<QString> flds )
|
||||
QgsFields QgsVectorTileUtils::makeQgisFields( const QSet<QString> &flds )
|
||||
{
|
||||
QgsFields fields;
|
||||
QStringList fieldsSorted = qgis::setToList( flds );
|
||||
@ -60,17 +60,17 @@ QgsFields QgsVectorTileUtils::makeQgisFields( QSet<QString> flds )
|
||||
return fields;
|
||||
}
|
||||
|
||||
double QgsVectorTileUtils::scaleToZoom( double mapScale )
|
||||
double QgsVectorTileUtils::scaleToZoom( double mapScale, double z0Scale )
|
||||
{
|
||||
double s0 = 559082264.0287178; // scale denominator at zoom level 0 of GoogleCRS84Quad
|
||||
double s0 = z0Scale;
|
||||
double tileZoom2 = log( s0 / mapScale ) / log( 2 );
|
||||
tileZoom2 -= 1; // TODO: it seems that map scale is double (is that because of high-dpi screen?)
|
||||
return tileZoom2;
|
||||
}
|
||||
|
||||
int QgsVectorTileUtils::scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom )
|
||||
int QgsVectorTileUtils::scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale )
|
||||
{
|
||||
int tileZoom = static_cast<int>( round( scaleToZoom( mapScale ) ) );
|
||||
int tileZoom = static_cast<int>( round( scaleToZoom( mapScale, z0Scale ) ) );
|
||||
|
||||
if ( tileZoom < sourceMinZoom )
|
||||
tileZoom = sourceMinZoom;
|
||||
@ -82,7 +82,7 @@ int QgsVectorTileUtils::scaleToZoomLevel( double mapScale, int sourceMinZoom, in
|
||||
|
||||
QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer *mvt, QgsTileXYZ tileID, const QString &layerName )
|
||||
{
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( mvt->tileStructure() );
|
||||
decoder.decode( tileID, mvt->getRawTile( tileID ) );
|
||||
QSet<QString> fieldNames = qgis::listToSet( decoder.layerFieldNames( layerName ) );
|
||||
fieldNames << QStringLiteral( "_geom_type" );
|
||||
@ -112,7 +112,7 @@ QgsVectorLayer *QgsVectorTileUtils::makeVectorLayerForTile( QgsVectorTileLayer *
|
||||
vl->dataProvider()->addAttributes( fields.toList() );
|
||||
vl->updateFields();
|
||||
bool res = vl->dataProvider()->addFeatures( featuresList );
|
||||
Q_UNUSED( res );
|
||||
Q_UNUSED( res )
|
||||
Q_ASSERT( res );
|
||||
Q_ASSERT( featuresList.count() == vl->featureCount() );
|
||||
vl->updateExtents();
|
||||
@ -149,7 +149,7 @@ bool QgsVectorTileUtils::checkXYZUrlTemplate( const QString &url )
|
||||
struct LessThanTileRequest
|
||||
{
|
||||
QPointF center; //!< Center in tile matrix (!) coordinates
|
||||
bool operator()( const QgsTileXYZ &req1, const QgsTileXYZ &req2 )
|
||||
bool operator()( QgsTileXYZ req1, QgsTileXYZ req2 )
|
||||
{
|
||||
QPointF p1( req1.column() + 0.5, req1.row() + 0.5 );
|
||||
QPointF p2( req2.column() + 0.5, req2.row() + 0.5 );
|
||||
@ -160,7 +160,7 @@ struct LessThanTileRequest
|
||||
}
|
||||
};
|
||||
|
||||
QVector<QgsTileXYZ> QgsVectorTileUtils::tilesInRange( const QgsTileRange &range, int zoomLevel )
|
||||
QVector<QgsTileXYZ> QgsVectorTileUtils::tilesInRange( QgsTileRange range, int zoomLevel )
|
||||
{
|
||||
QVector<QgsTileXYZ> tiles;
|
||||
for ( int tileRow = range.startRow(); tileRow <= range.endRow(); ++tileRow )
|
||||
@ -173,7 +173,7 @@ QVector<QgsTileXYZ> QgsVectorTileUtils::tilesInRange( const QgsTileRange &range,
|
||||
return tiles;
|
||||
}
|
||||
|
||||
void QgsVectorTileUtils::sortTilesByDistanceFromCenter( QVector<QgsTileXYZ> &tiles, const QPointF ¢er )
|
||||
void QgsVectorTileUtils::sortTilesByDistanceFromCenter( QVector<QgsTileXYZ> &tiles, QPointF center )
|
||||
{
|
||||
LessThanTileRequest cmp;
|
||||
cmp.center = center;
|
||||
|
@ -47,9 +47,9 @@ class CORE_EXPORT QgsVectorTileUtils
|
||||
public:
|
||||
|
||||
//! Returns a list of tiles in the given tile range
|
||||
static QVector<QgsTileXYZ> tilesInRange( const QgsTileRange &range, int zoomLevel );
|
||||
static QVector<QgsTileXYZ> tilesInRange( QgsTileRange range, int zoomLevel );
|
||||
//! Orders tile requests according to the distance from view center (given in tile matrix coords)
|
||||
static void sortTilesByDistanceFromCenter( QVector<QgsTileXYZ> &tiles, const QPointF ¢er );
|
||||
static void sortTilesByDistanceFromCenter( QVector<QgsTileXYZ> &tiles, QPointF center );
|
||||
|
||||
/**
|
||||
* Returns polygon (made by four corners of the tile) in screen coordinates
|
||||
@ -59,17 +59,25 @@ class CORE_EXPORT QgsVectorTileUtils
|
||||
static QPolygon tilePolygon( QgsTileXYZ id, const QgsCoordinateTransform &ct, const QgsTileMatrix &tm, const QgsMapToPixel &mtp );
|
||||
|
||||
//! Returns QgsFields instance based on the set of field names
|
||||
static QgsFields makeQgisFields( QSet<QString> flds );
|
||||
static QgsFields makeQgisFields( const QSet<QString> &flds );
|
||||
|
||||
/**
|
||||
* Finds zoom level (assuming GoogleCRS84Quad tile matrix set) given map scale denominator.
|
||||
* Finds zoom level given map scale denominator.
|
||||
*
|
||||
* The \a z0Scale argument gives the scale denominator at zoom level 0, where the default
|
||||
* value corresponds to GoogleCRS84Quad tile matrix set
|
||||
*
|
||||
* \since QGIS 3.16
|
||||
*/
|
||||
static double scaleToZoom( double mapScale );
|
||||
static double scaleToZoom( double mapScale, double z0Scale = 559082264.0287178 );
|
||||
|
||||
//! Finds best fitting zoom level (assuming GoogleCRS84Quad tile matrix set) given map scale denominator and allowed zoom level range
|
||||
static int scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom );
|
||||
/**
|
||||
* Finds the best fitting zoom level given a map scale denominator and allowed zoom level range.
|
||||
*
|
||||
* The \a z0Scale argument gives the scale denominator at zoom level 0, where the default
|
||||
* value corresponds to GoogleCRS84Quad tile matrix set.
|
||||
*/
|
||||
static int scaleToZoomLevel( double mapScale, int sourceMinZoom, int sourceMaxZoom, double z0Scale = 559082264.0287178 );
|
||||
//! Returns a temporary vector layer for given sub-layer of tile in vector tile layer
|
||||
static QgsVectorLayer *makeVectorLayerForTile( QgsVectorTileLayer *mvt, QgsTileXYZ tileID, const QString &layerName );
|
||||
//! Returns formatted tile URL string replacing {x}, {y}, {z} placeholders (or {-y} instead of {y} for TMS convention)
|
||||
|
@ -447,9 +447,9 @@ bool QgsMapToolIdentify::identifyVectorTileLayer( QList<QgsMapToolIdentify::Iden
|
||||
}
|
||||
}
|
||||
|
||||
int tileZoom = QgsVectorTileUtils::scaleToZoomLevel( mCanvas->scale(), layer->sourceMinZoom(), layer->sourceMaxZoom() );
|
||||
const QgsTileMatrix tileMatrix = QgsTileMatrix::fromWebMercator( tileZoom );
|
||||
QgsTileRange tileRange = tileMatrix.tileRangeFromExtent( r );
|
||||
const int tileZoom = layer->tileStructure().scaleToZoomLevel( mCanvas->scale() );
|
||||
const QgsTileMatrix tileMatrix = layer->tileStructure().tileMatrix( tileZoom );
|
||||
const QgsTileRange tileRange = tileMatrix.tileRangeFromExtent( r );
|
||||
|
||||
for ( int row = tileRange.startRow(); row <= tileRange.endRow(); ++row )
|
||||
{
|
||||
@ -460,7 +460,7 @@ bool QgsMapToolIdentify::identifyVectorTileLayer( QList<QgsMapToolIdentify::Iden
|
||||
if ( data.isEmpty() )
|
||||
continue; // failed to get data
|
||||
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( layer->tileStructure() );
|
||||
if ( !decoder.decode( tileID, data ) )
|
||||
continue; // failed to decode
|
||||
|
||||
|
@ -116,7 +116,7 @@ void TestQgsVectorTileWriter::test_basic()
|
||||
QgsVectorTileLayer *vtLayer = new QgsVectorTileLayer( ds.encodedUri(), "output" );
|
||||
|
||||
const QByteArray tile0 = vtLayer->getRawTile( QgsTileXYZ( 0, 0, 0 ) );
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( QgsVectorTileStructure::fromWebMercator() );
|
||||
const bool resDecode0 = decoder.decode( QgsTileXYZ( 0, 0, 0 ), tile0 );
|
||||
QVERIFY( resDecode0 );
|
||||
const QStringList layerNames = decoder.layers();
|
||||
@ -185,7 +185,7 @@ void TestQgsVectorTileWriter::test_mbtiles()
|
||||
QgsVectorTileLayer *vtLayer = new QgsVectorTileLayer( ds.encodedUri(), "output" );
|
||||
|
||||
const QByteArray tile0 = vtLayer->getRawTile( QgsTileXYZ( 0, 0, 0 ) );
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( QgsVectorTileStructure::fromWebMercator() );
|
||||
const bool resDecode0 = decoder.decode( QgsTileXYZ( 0, 0, 0 ), tile0 );
|
||||
QVERIFY( resDecode0 );
|
||||
const QStringList layerNames = decoder.layers();
|
||||
@ -301,7 +301,7 @@ void TestQgsVectorTileWriter::test_filtering()
|
||||
QgsVectorTileLayer *vtLayer = new QgsVectorTileLayer( ds.encodedUri(), "output" );
|
||||
|
||||
const QByteArray tile0 = vtLayer->getRawTile( QgsTileXYZ( 0, 0, 0 ) );
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( QgsVectorTileStructure::fromWebMercator() );
|
||||
const bool resDecode0 = decoder.decode( QgsTileXYZ( 0, 0, 0 ), tile0 );
|
||||
QVERIFY( resDecode0 );
|
||||
const QStringList layerNames = decoder.layers();
|
||||
@ -364,7 +364,7 @@ void TestQgsVectorTileWriter::test_z0TileMatrix3857()
|
||||
QgsVectorTileLayer *vtLayer = new QgsVectorTileLayer( ds.encodedUri(), "output" );
|
||||
|
||||
const QByteArray tile0 = vtLayer->getRawTile( QgsTileXYZ( 0, 0, 0 ) );
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( QgsVectorTileStructure::fromWebMercator() );
|
||||
const bool resDecode0 = decoder.decode( QgsTileXYZ( 0, 0, 0 ), tile0 );
|
||||
QVERIFY( resDecode0 );
|
||||
const QStringList layerNames = decoder.layers();
|
||||
@ -450,7 +450,7 @@ void TestQgsVectorTileWriter::test_z0TileMatrix2154()
|
||||
QgsVectorTileLayer *vtLayer = new QgsVectorTileLayer( ds.encodedUri(), "output" );
|
||||
|
||||
const QByteArray tile0 = vtLayer->getRawTile( QgsTileXYZ( 0, 0, 0 ) );
|
||||
QgsVectorTileMVTDecoder decoder;
|
||||
QgsVectorTileMVTDecoder decoder( QgsVectorTileStructure::fromWebMercator() );
|
||||
const bool resDecode0 = decoder.decode( QgsTileXYZ( 0, 0, 0 ), tile0 );
|
||||
QVERIFY( resDecode0 );
|
||||
const QStringList layerNames = decoder.layers();
|
||||
|
Loading…
x
Reference in New Issue
Block a user