25 constexpr
double z0xMin = -20037508.3427892;
26 constexpr
double z0yMax = 20037508.3427892;
32 const QgsPointXY &z0TopLeftPoint,
double z0Dimension,
int z0MatrixWidth,
int z0MatrixHeight )
35 double z0xMin = z0TopLeftPoint.
x();
36 double z0yMax = z0TopLeftPoint.
y();
37 double z0xMax = z0xMin + z0MatrixWidth * z0Dimension;
38 double z0yMin = z0yMax - z0MatrixHeight * z0Dimension;
41 constexpr
double TILE_SIZE = 256.0;
42 constexpr
double PIXELS_TO_M = 2.8 / 10000.0;
45 const double scaleDenom0 = ( z0Dimension / TILE_SIZE ) * ( unitToMeters / PIXELS_TO_M );
47 int numTiles =
static_cast<int>( pow( 2,
zoomLevel ) );
52 tm.mMatrixWidth = z0MatrixWidth * numTiles;
53 tm.mMatrixHeight = z0MatrixHeight * numTiles;
54 tm.mTileXSpan = ( z0xMax - z0xMin ) / tm.mMatrixWidth;
55 tm.mTileYSpan = ( z0yMax - z0yMin ) / tm.mMatrixHeight;
56 tm.mExtent =
QgsRectangle( z0xMin, z0yMin, z0xMax, z0yMax );
57 tm.mScaleDenom = scaleDenom0 / pow( 2,
zoomLevel );
64 int numTiles =
static_cast<int>( pow( 2,
zoomLevel ) );
66 int aNumTiles =
static_cast<int>( pow( 2, aZoomLevel ) );
70 tm.mCrs = tileMatrix.
crs();
72 tm.mMatrixWidth = aMatrixWidth * numTiles / aNumTiles;
73 tm.mMatrixHeight = aMatrixHeight * numTiles / aNumTiles;
74 tm.mTileXSpan = aExtent.
width() / tm.mMatrixWidth;
75 tm.mTileYSpan = aExtent.
height() / tm.mMatrixHeight;
77 tm.mScaleDenom = tileMatrix.
scale() * pow( 2, aZoomLevel ) / pow( 2,
zoomLevel );
83 double xMin = mExtent.
xMinimum() + mTileXSpan *
id.column();
84 double xMax = xMin + mTileXSpan;
85 double yMax = mExtent.
yMaximum() - mTileYSpan *
id.row();
86 double yMin = yMax - mTileYSpan;
92 double x = mExtent.
xMinimum() + mTileXSpan *
id.column() + mTileXSpan / 2;
93 double y = mExtent.
yMaximum() - mTileYSpan *
id.row() - mTileYSpan / 2;
103 if ( x0 >= x1 || y0 >= y1 )
106 double tileX1 = ( x0 - mExtent.
xMinimum() ) / mTileXSpan;
107 double tileX2 = ( x1 - mExtent.
xMinimum() ) / mTileXSpan;
108 double tileY1 = ( mExtent.
yMaximum() - y1 ) / mTileYSpan;
109 double tileY2 = ( mExtent.
yMaximum() - y0 ) / mTileYSpan;
111 QgsDebugMsgLevel( QStringLiteral(
"Tile range of edges [%1,%2] - [%3,%4]" ).arg( tileX1 ).arg( tileY1 ).arg( tileX2 ).arg( tileY2 ), 2 );
114 int startColumn = std::clamp(
static_cast<int>( floor( tileX1 ) ), 0, mMatrixWidth - 1 );
115 int endColumn = std::clamp(
static_cast<int>( floor( tileX2 ) ), 0, mMatrixWidth - 1 );
116 int startRow = std::clamp(
static_cast<int>( floor( tileY1 ) ), 0, mMatrixHeight - 1 );
117 int endRow = std::clamp(
static_cast<int>( floor( tileY2 ) ), 0, mMatrixHeight - 1 );
118 return QgsTileRange( startColumn, endColumn, startRow, endRow );
123 double dx = mapPoint.
x() - mExtent.
xMinimum();
124 double dy = mExtent.
yMaximum() - mapPoint.
y();
125 return QPointF( dx / mTileXSpan, dy / mTileYSpan );
134 return mTileMatrices.isEmpty();
150 return mTileMatrices.value( zoom );
155 mTileMatrices.insert( matrix.
zoomLevel(), matrix );
161 for (
auto it = mTileMatrices.constBegin(); it != mTileMatrices.constEnd(); ++it )
163 if ( res == -1 || it->zoomLevel() < res )
164 res = it->zoomLevel();
172 for (
auto it = mTileMatrices.constBegin(); it != mTileMatrices.constEnd(); ++it )
174 if ( res == -1 || it->zoomLevel() > res )
175 res = it->zoomLevel();
182 for (
auto it = mTileMatrices.begin(); it != mTileMatrices.end(); )
186 it = mTileMatrices.erase( it );
197 if ( mTileMatrices.empty() )
207 double scaleUnder = 0;
208 double scaleOver = 0;
210 switch ( mScaleToTileZoomMethod )
223 for (
auto it = mTileMatrices.constBegin(); it != mTileMatrices.constEnd(); ++it )
225 if ( it->scale() > scale && ( zoomUnder == -1 || zoomUnder < it->zoomLevel() ) )
227 zoomUnder = it->zoomLevel();
228 scaleUnder = it->scale();
230 if ( it->scale() < scale && ( zoomOver == -1 || zoomOver > it->zoomLevel() ) )
232 zoomOver = it->zoomLevel();
233 scaleOver = it->scale();
242 return ( scaleUnder - scale ) / ( scaleUnder - scaleOver ) * ( zoomOver - zoomUnder ) + zoomUnder;
248 switch ( mScaleToTileZoomMethod )
251 tileZoom =
static_cast<int>( round(
scaleToZoom( scale ) ) );
254 tileZoom =
static_cast<int>( floor(
scaleToZoom( scale ) ) );
267 context.
painter()->device()->logicalDpiX() );
272 switch ( mScaleToTileZoomMethod )
275 return actualMapScale;
282 constexpr
double METERS_PER_DEGREE = M_PI / 180.0 * 6378137;
283 constexpr
double INCHES_PER_METER = 39.370078;
284 const double mapWidthInches = mapExtent.
width() * METERS_PER_DEGREE * INCHES_PER_METER;
286 double scale = mapWidthInches * mapDpi /
static_cast< double >( mapSize.width() );
297 return actualMapScale;
305 mTileMatrices.clear();
309 const QDomNodeList children = element.childNodes();
310 for (
int i = 0; i < children.size(); i++ )
312 const QDomElement matrixElement = children.at( i ).toElement();
315 matrix.mZoomLevel = matrixElement.attribute( QStringLiteral(
"zoomLevel" ) ).toInt();
316 matrix.mMatrixWidth = matrixElement.attribute( QStringLiteral(
"matrixWidth" ) ).toInt();
317 matrix.mMatrixHeight = matrixElement.attribute( QStringLiteral(
"matrixHeight" ) ).toInt();
319 matrixElement.attribute( QStringLiteral(
"xMin" ) ).toDouble(),
320 matrixElement.attribute( QStringLiteral(
"yMin" ) ).toDouble(),
321 matrixElement.attribute( QStringLiteral(
"xMax" ) ).toDouble(),
322 matrixElement.attribute( QStringLiteral(
"yMax" ) ).toDouble()
325 matrix.mScaleDenom = matrixElement.attribute( QStringLiteral(
"scale" ) ).toDouble();
326 matrix.mTileXSpan = matrixElement.attribute( QStringLiteral(
"tileXSpan" ) ).toDouble();
327 matrix.mTileYSpan = matrixElement.attribute( QStringLiteral(
"tileYSpan" ) ).toDouble();
328 matrix.mCrs.
readXml( matrixElement );
336 QDomElement setElement = document.createElement( QStringLiteral(
"matrixSet" ) );
337 setElement.setAttribute( QStringLiteral(
"scaleToZoomMethod" ),
qgsEnumValueToKey( mScaleToTileZoomMethod ) );
339 for (
auto it = mTileMatrices.constBegin(); it != mTileMatrices.constEnd(); ++it )
341 QDomElement matrixElement = document.createElement( QStringLiteral(
"matrix" ) );
342 matrixElement.setAttribute( QStringLiteral(
"zoomLevel" ), it->zoomLevel() );
343 matrixElement.setAttribute( QStringLiteral(
"matrixWidth" ), it->matrixWidth() );
344 matrixElement.setAttribute( QStringLiteral(
"matrixHeight" ), it->matrixHeight() );
346 matrixElement.setAttribute( QStringLiteral(
"xMin" ),
qgsDoubleToString( it->mExtent.xMinimum() ) );
347 matrixElement.setAttribute( QStringLiteral(
"xMax" ),
qgsDoubleToString( it->mExtent.xMaximum() ) );
348 matrixElement.setAttribute( QStringLiteral(
"yMin" ),
qgsDoubleToString( it->mExtent.yMinimum() ) );
349 matrixElement.setAttribute( QStringLiteral(
"yMax" ),
qgsDoubleToString( it->mExtent.yMaximum() ) );
351 matrixElement.setAttribute( QStringLiteral(
"scale" ),
qgsDoubleToString( it->scale() ) );
352 matrixElement.setAttribute( QStringLiteral(
"tileXSpan" ),
qgsDoubleToString( it->mTileXSpan ) );
353 matrixElement.setAttribute( QStringLiteral(
"tileYSpan" ),
qgsDoubleToString( it->mTileYSpan ) );
355 it->crs().writeXml( matrixElement, document );
356 setElement.appendChild( matrixElement );