@@ -79,6 +79,7 @@ static QString DEFAULT_LATLON_CRS = "CRS:84";
79
79
80
80
QMap<QString, QgsWmsStatistics::Stat> QgsWmsStatistics::sData ;
81
81
82
+
82
83
QgsWmsProvider::QgsWmsProvider ( QString const & uri, const QgsWmsCapabilities* capabilities )
83
84
: QgsRasterDataProvider( uri )
84
85
, mHttpGetLegendGraphicResponse( nullptr )
@@ -110,14 +111,26 @@ QgsWmsProvider::QgsWmsProvider( QString const& uri, const QgsWmsCapabilities* ca
110
111
if ( !addLayers () )
111
112
return ;
112
113
113
- // if there are already parsed capabilities, use them!
114
- if ( capabilities )
115
- mCaps = *capabilities;
116
-
117
- // Make sure we have capabilities - other functions here may need them
118
- if ( !retrieveServerCapabilities () )
114
+ if ( mSettings .mXyz )
119
115
{
120
- return ;
116
+ // we are working with XYZ tiles
117
+ // no need to get capabilities, the whole definition is in URI
118
+ // so we just generate a dummy WMTS definition
119
+ setupXyzCapabilities ( uri );
120
+ }
121
+ else
122
+ {
123
+ // we are working with WMS / WMTS server
124
+
125
+ // if there are already parsed capabilities, use them!
126
+ if ( capabilities )
127
+ mCaps = *capabilities;
128
+
129
+ // Make sure we have capabilities - other functions here may need them
130
+ if ( !retrieveServerCapabilities () )
131
+ {
132
+ return ;
133
+ }
121
134
}
122
135
123
136
// setImageCrs is using mTiled !!!
@@ -781,6 +794,28 @@ QImage *QgsWmsProvider::draw( QgsRectangle const & viewExtent, int pixelWidth, i
781
794
}
782
795
break ;
783
796
797
+ case XYZ:
798
+ {
799
+ QString url = mSettings .mBaseUrl ;
800
+ int z = tm ->identifier .toInt ();
801
+ int i = 0 ;
802
+ for ( int row = row0; row <= row1; row++ )
803
+ {
804
+ for ( int col = col0; col <= col1; col++ )
805
+ {
806
+ QString turl ( url );
807
+ turl.replace ( " {x}" , QString::number ( col ), Qt::CaseInsensitive );
808
+ turl.replace ( " {y}" , QString::number ( row ), Qt::CaseInsensitive );
809
+ turl.replace ( " {z}" , QString::number ( z ), Qt::CaseInsensitive );
810
+
811
+ if ( feedback && !feedback->preview_only )
812
+ QgsDebugMsg ( QString ( " tileRequest %1 %2/%3 (%4,%5): %6" ).arg ( mTileReqNo ).arg ( i++ ).arg ( n ).arg ( row ).arg ( col ).arg ( turl ) );
813
+ requests << QgsWmsTiledImageDownloadHandler::TileRequest ( turl, tm ->tileRect ( col, row ), i );
814
+ }
815
+ }
816
+ }
817
+ break ;
818
+
784
819
default :
785
820
QgsDebugMsg ( QString ( " unexpected tile mode %1" ).arg ( mTileLayer ->tileMode ) );
786
821
return image;
@@ -935,6 +970,60 @@ bool QgsWmsProvider::retrieveServerCapabilities( bool forceRefresh )
935
970
}
936
971
937
972
973
+ void QgsWmsProvider::setupXyzCapabilities ( const QString &uri )
974
+ {
975
+ QgsDataSourceUri parsedUri;
976
+ parsedUri.setEncodedUri ( uri );
977
+
978
+ QgsCoordinateTransform ct ( QgsCoordinateReferenceSystem ( " EPSG:4326" ), QgsCoordinateReferenceSystem ( mSettings .mCrsId ) );
979
+ // the whole world is projected to a square:
980
+ // X going from 180 W to 180 E
981
+ // Y going from ~85 N to ~85 S (=atan(sinh(pi)) ... to get a square)
982
+ QgsPoint topLeftLonLat ( -180 , 180.0 / M_PI * atan ( sinh ( M_PI ) ) );
983
+ QgsPoint bottomRightLonLat ( 180 , 180.0 / M_PI * atan ( sinh ( -M_PI ) ) );
984
+ QgsPoint topLeft = ct.transform ( topLeftLonLat );
985
+ QgsPoint bottomRight = ct.transform ( bottomRightLonLat );
986
+ double xspan = ( bottomRight.x () - topLeft.x () );
987
+
988
+ QgsWmsBoundingBoxProperty bbox;
989
+ bbox.crs = mSettings .mCrsId ;
990
+ bbox.box = QgsRectangle ( topLeft.x (), bottomRight.y (), bottomRight.x (), topLeft.y () );
991
+
992
+ QgsWmtsTileLayer tl;
993
+ tl.tileMode = XYZ;
994
+ tl.identifier = " xyz" ; // as set in parseUri
995
+ tl.boundingBoxes << bbox;
996
+ mCaps .mTileLayersSupported .append ( tl );
997
+
998
+ QgsWmtsTileMatrixSet tms;
999
+ tms.identifier = " tms0" ; // as set in parseUri
1000
+ tms.crs = mSettings .mCrsId ;
1001
+ mCaps .mTileMatrixSets [tms.identifier ] = tms;
1002
+
1003
+ int minZoom = 0 ;
1004
+ int maxZoom = 18 ;
1005
+ if ( parsedUri.hasParam ( " zmin" ) )
1006
+ minZoom = parsedUri.param ( " zmin" ).toInt ();
1007
+ if ( parsedUri.hasParam ( " zmax" ) )
1008
+ maxZoom = parsedUri.param ( " zmax" ).toInt ();
1009
+
1010
+ // zoom 0 is one tile for the whole world
1011
+ for ( int zoom = minZoom; zoom <= maxZoom; ++zoom )
1012
+ {
1013
+ QgsWmtsTileMatrix tm ;
1014
+ tm .identifier = QString::number ( zoom );
1015
+ tm .topLeft = topLeft;
1016
+ tm .tileWidth = 256 ;
1017
+ tm .tileHeight = 256 ;
1018
+ tm .matrixWidth = pow ( 2 , zoom );
1019
+ tm .matrixHeight = pow ( 2 , zoom );
1020
+ tm .tres = xspan / ( tm .tileWidth * tm .matrixWidth );
1021
+
1022
+ mCaps .mTileMatrixSets [tms.identifier ].tileMatrices [tm .tres ] = tm ;
1023
+ }
1024
+ }
1025
+
1026
+
938
1027
Qgis::DataType QgsWmsProvider::dataType ( int bandNo ) const
939
1028
{
940
1029
return sourceDataType ( bandNo );
@@ -1835,6 +1924,10 @@ QString QgsWmsProvider::metadata()
1835
1924
{
1836
1925
metadata += tr ( " WMS-C" );
1837
1926
}
1927
+ else if ( l.tileMode == XYZ )
1928
+ {
1929
+ metadata += tr ( " XYZ" );
1930
+ }
1838
1931
else
1839
1932
{
1840
1933
metadata += tr ( " Invalid tile mode" );
0 commit comments