[FEATURE] WMTS

This commit is contained in:
Juergen E. Fischer 2012-04-26 13:51:33 +02:00
parent db1c3d9f4e
commit 018a047c5b
19 changed files with 1898 additions and 1002 deletions

View File

@ -34,10 +34,10 @@ fi
# save original changes
if [ -d .svn ]; then
REV=r$(svn info | sed -ne "s/Revision: //p")
svn diff >$REV.diff
svn diff >rev-$REV.diff
elif [ -d .git ]; then
REV=$(git log -n1 --pretty=%H)
git diff >$REV.diff
git diff >sha-$REV.diff
fi
ASTYLEDIFF=astyle.$REV.diff

View File

@ -95,7 +95,6 @@ SET(QGIS_APP_SRCS
qgssinglesymboldialog.cpp
qgssnappingdialog.cpp
qgsundowidget.cpp
qgstilescalewidget.cpp
qgstipgui.cpp
qgstipfactory.cpp
qgsuniquevaluedialog.cpp
@ -232,7 +231,6 @@ SET (QGIS_APP_MOC_HDRS
qgssnappingdialog.h
qgssponsors.h
qgstextannotationdialog.h
qgstilescalewidget.h
qgstipgui.h
qgstipfactory.h
qgsundowidget.h

View File

@ -164,7 +164,6 @@
#include "qgssnappingdialog.h"
#include "qgssponsors.h"
#include "qgstextannotationitem.h"
#include "qgstilescalewidget.h"
#include "qgstipgui.h"
#include "qgsundowidget.h"
#include "qgsvectordataprovider.h"
@ -403,7 +402,6 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
, mSplash( splash )
, mShowProjectionTab( false )
, mPythonUtils( NULL )
, mpTileScaleWidget( NULL )
#ifdef Q_OS_WIN
, mSkipNextContextMenuEvent( 0 )
#endif
@ -651,6 +649,8 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
// request notification of FileOpen events (double clicking a file icon in Mac OS X Finder)
QgsApplication::setFileOpenEventReceiver( this );
QgsProviderRegistry::instance()->registerGuis( this );
// update windows
qApp->processEvents();
@ -788,12 +788,6 @@ void QgisApp::readSettings()
// Add the recently accessed project file paths to the File menu
mRecentProjectPaths = settings.value( "/UI/recentProjectsList" ).toStringList();
// Restore state of tile scale widget
if ( settings.value( "/UI/tileScaleEnabled", false ).toBool() )
{
showTileScale();
}
}
@ -899,7 +893,6 @@ void QgisApp::createActions()
connect( mActionRemoveLayer, SIGNAL( triggered() ), this, SLOT( removeLayer() ) );
connect( mActionSetLayerCRS, SIGNAL( triggered() ), this, SLOT( setLayerCRS() ) );
connect( mActionSetProjectCRSFromLayer, SIGNAL( triggered() ), this, SLOT( setProjectCRSFromLayer() ) );
connect( mActionTileScale, SIGNAL( triggered() ), this, SLOT( showTileScale() ) );
connect( mActionLayerProperties, SIGNAL( triggered() ), this, SLOT( layerProperties() ) );
connect( mActionLayerSubsetString, SIGNAL( triggered() ), this, SLOT( layerSubsetString() ) );
connect( mActionAddToOverview, SIGNAL( triggered() ), this, SLOT( isInOverview() ) );
@ -2072,17 +2065,6 @@ void QgisApp::saveWindowState()
// store window geometry
settings.setValue( "/UI/geometry", saveGeometry() );
// Persist state of tile scale slider
if ( mpTileScaleWidget )
{
settings.setValue( "/UI/tileScaleEnabled", true );
delete mpTileScaleWidget;
}
else
{
settings.setValue( "/UI/tileScaleEnabled", false );
}
QgsPluginRegistry::instance()->unloadAll();
}
@ -4854,32 +4836,6 @@ void QgisApp::setProjectCRSFromLayer()
mMapCanvas->refresh();
}
void QgisApp::showTileScale()
{
if ( !mpTileScaleWidget )
{
mpTileScaleWidget = new QgsTileScaleWidget( mMapCanvas );
//create the dock widget
mpTileScaleDock = new QDockWidget( tr( "Tile scale" ), this );
mpTileScaleDock->setObjectName( "TileScale" );
mpTileScaleDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
addDockWidget( Qt::RightDockWidgetArea, mpTileScaleDock );
// add to the Panel submenu
mPanelMenu->addAction( mpTileScaleDock->toggleViewAction() );
// now add our widget to the dock - ownership of the widget is passed to the dock
mpTileScaleDock->setWidget( mpTileScaleWidget );
mpTileScaleDock->show();
connect( mMapLegend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
mpTileScaleWidget, SLOT( layerChanged( QgsMapLayer* ) ) );
}
else
{
mpTileScaleDock->setVisible( mpTileScaleDock->isHidden() );
}
}
void QgisApp::zoomToLayerExtent()
{
mMapLegend->legendLayerZoom();

View File

@ -58,7 +58,6 @@ class QgsRasterLayer;
class QgsRectangle;
class QgsUndoWidget;
class QgsVectorLayer;
class QgsTileScaleWidget;
class QDomDocument;
class QNetworkReply;
@ -289,7 +288,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QAction *actionRemoveLayer() { return mActionRemoveLayer; }
QAction *actionSetLayerCRS() { return mActionSetLayerCRS; }
QAction *actionSetProjectCRSFromLayer() { return mActionSetProjectCRSFromLayer; }
QAction *actionTileScale() { return mActionTileScale; }
QAction *actionLayerProperties() { return mActionLayerProperties; }
QAction *actionLayerSubsetString() { return mActionLayerSubsetString; }
QAction *actionAddToOverview() { return mActionAddToOverview; }
@ -544,8 +542,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void setLayerCRS();
//! Assign layer CRS to project
void setProjectCRSFromLayer();
//! Show tile scale slider
void showTileScale();
//! zoom to extent of layer
void zoomToLayerExtent();
//! zoom to actual size of raster layer
@ -1005,7 +1001,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QDockWidget *mLegendDock;
QDockWidget *mLayerOrderDock;
QDockWidget *mOverviewDock;
QDockWidget *mpTileScaleDock;
QDockWidget *mpGpsDock;
QDockWidget *mLogDock;
@ -1173,9 +1168,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QgsSnappingDialog* mSnappingDialog;
//! Persistent tile scale slider
QgsTileScaleWidget * mpTileScaleWidget;
QgsDecorationCopyright* mDecorationCopyright;
QgsDecorationNorthArrow* mDecorationNorthArrow;
QgsDecorationScaleBar* mDecorationScaleBar;

View File

@ -133,16 +133,25 @@ bool QgsCoordinateReferenceSystem::createFromString( const QString theDefinition
bool QgsCoordinateReferenceSystem::createFromOgcWmsCrs( QString theCrs )
{
QRegExp re( "(user|custom|qgis):(\\d+)", Qt::CaseInsensitive );
if ( re.exactMatch( theCrs ) && createFromSrsId( re.cap( 2 ).toInt() ) )
QRegExp re( "urn:ogc:def:crs:([^:]+).+([^:]+)", Qt::CaseInsensitive );
if ( re.exactMatch( theCrs ) )
{
return true;
theCrs = re.cap( 1 ) + ":" + re.cap( 2 );
}
else
{
re.setPattern( "(user|custom|qgis):(\\d+)" );
if ( re.exactMatch( theCrs ) && createFromSrsId( re.cap( 2 ).toInt() ) )
{
return true;
}
}
if ( loadFromDb( QgsApplication::srsDbFilePath(), "lower(auth_name||':'||auth_id)", theCrs.toLower() ) )
return true;
if ( theCrs.compare( "CRS:84", Qt::CaseInsensitive ) == 0 )
if ( theCrs.compare( "CRS:84", Qt::CaseInsensitive ) == 0 ||
theCrs.compare( "OGC:CRS84", Qt::CaseInsensitive ) == 0 )
{
createFromSrsId( GEOCRS_ID );
return true;

View File

@ -436,12 +436,8 @@ typedef QWidget * selectFactoryFunction_t( QWidget * parent, Qt::WFlags fl );
QWidget* QgsProviderRegistry::selectWidget( const QString & providerKey,
QWidget * parent, Qt::WFlags fl )
{
QLibrary *myLib = providerLibrary( providerKey );
if ( !myLib )
return 0;
selectFactoryFunction_t * selectFactory =
( selectFactoryFunction_t * ) cast_to_fptr( myLib->resolve( "selectWidget" ) );
( selectFactoryFunction_t * ) cast_to_fptr( function( providerKey, "selectWidget" ) );
if ( !selectFactory )
return 0;
@ -449,7 +445,6 @@ QWidget* QgsProviderRegistry::selectWidget( const QString & providerKey,
return selectFactory( parent, fl );
}
void * QgsProviderRegistry::function( QString const & providerKey,
QString const & functionName )
{
@ -489,6 +484,21 @@ QLibrary *QgsProviderRegistry::providerLibrary( QString const & providerKey ) co
return 0;
}
void QgsProviderRegistry::registerGuis( QWidget *parent )
{
typedef void registerGui_function( QWidget * parent );
foreach( const QString &provider, providerList() )
{
registerGui_function *registerGui = ( registerGui_function * ) cast_to_fptr( function( provider, "registerGui" ) );
if ( !registerGui )
continue;
registerGui( parent );
}
}
QString QgsProviderRegistry::fileVectorFilters() const
{
return mVectorFileFilters;

View File

@ -140,6 +140,8 @@ class CORE_EXPORT QgsProviderRegistry
/** type for data provider metadata associative container */
typedef std::map<QString, QgsProviderMetadata*> Providers;
void registerGuis( QWidget *widget );
private:
/** ctor private since instance() creates it */

View File

@ -83,7 +83,7 @@ QgsMapCanvas::QgsMapCanvas( QWidget * parent, const char *name )
, mPainting( false )
, mAntiAliasing( false )
{
Q_UNUSED( name );
setObjectName( name );
//disable the update that leads to the resize crash
if ( viewport() )
{

View File

@ -4,12 +4,16 @@ SET (WMS_SRCS
qgswmssourceselect.cpp
qgswmsconnection.cpp
qgswmsdataitems.cpp
qgstilescalewidget.cpp
qgswmtsdimensions.cpp
)
SET (WMS_MOC_HDRS
qgswmsprovider.h
qgswmssourceselect.h
qgswmsconnection.h
qgswmsdataitems.h
qgstilescalewidget.h
qgswmtsdimensions.h
)
QT4_WRAP_CPP (WMS_MOC_SRCS ${WMS_MOC_HDRS})

View File

@ -18,8 +18,15 @@
#include "qgstilescalewidget.h"
#include "qgsmapcanvas.h"
#include "qgsrasterlayer.h"
#include "qgswmsprovider.h"
#include "qgsmessagelog.h"
#include "qgslogger.h"
#include <QDockWidget>
#include <QMainWindow>
#include <QMenu>
#include <QGraphicsView>
QgsTileScaleWidget::QgsTileScaleWidget( QgsMapCanvas * mapCanvas, QWidget * parent, Qt::WindowFlags f )
: QWidget( parent, f )
, mMapCanvas( mapCanvas )
@ -31,54 +38,46 @@ QgsTileScaleWidget::QgsTileScaleWidget( QgsMapCanvas * mapCanvas, QWidget * pare
layerChanged( mMapCanvas->currentLayer() );
}
QgsTileScaleWidget::~QgsTileScaleWidget()
{
QSettings settings;
settings.setValue( "/UI/tileScaleEnabled", isVisible() );
}
void QgsTileScaleWidget::layerChanged( QgsMapLayer *layer )
{
QgsRasterLayer *rl = qobject_cast<QgsRasterLayer *>( layer );
mResolutions.clear();
mSlider->setDisabled( true );
if ( !rl || rl->providerType() != "wms" )
if ( !rl )
return;
QString uri = rl->source();
int tiledpos = uri.indexOf( "tiled=" );
int urlpos = uri.indexOf( "url=" );
QgsWmsProvider *wms = qobject_cast<QgsWmsProvider *>( rl->dataProvider() );
if ( !wms )
return;
if ( tiledpos >= 0 && urlpos >= 0 && urlpos > tiledpos )
QgsWmtsTileMatrixSet *tileMatrixSet = wms->tileMatrixSet();
if ( !tileMatrixSet )
return;
mSlider->setDisabled( true );
mResolutions = tileMatrixSet->tileMatrices.keys();
qSort( mResolutions );
for ( int i = 0; i < mResolutions.size(); i++ )
{
uri = uri.mid( tiledpos + 6 );
int pos = uri.indexOf( "," );
if ( pos >= 0 )
uri = uri.left( pos );
QStringList params = uri.split( ";" );
if ( params.size() < 3 )
return;
params.takeFirst();
params.takeFirst();
mResolutions.clear();
foreach( QString r, params )
{
mResolutions << r.toDouble();
}
qSort( mResolutions );
for ( int i = 0; i < mResolutions.size(); i++ )
QgsDebugMsg( QString( "found resolution %1: %2" ).arg( i ).arg( mResolutions[i] ) );
mSlider->setRange( 0, mResolutions.size() - 1 );
mSlider->setTickInterval( 1 );
mSlider->setInvertedAppearance( true );
mSlider->setPageStep( 1 );
mSlider->setTracking( false );
scaleChanged( mMapCanvas->scale() );
mSlider->setEnabled( true );
show();
QgsDebugMsg( QString( "found resolution %1: %2" ).arg( i ).arg( mResolutions[i] ) );
}
mSlider->setRange( 0, mResolutions.size() - 1 );
mSlider->setTickInterval( 1 );
mSlider->setInvertedAppearance( true );
mSlider->setPageStep( 1 );
mSlider->setTracking( false );
scaleChanged( mMapCanvas->scale() );
mSlider->setEnabled( true );
show();
}
void QgsTileScaleWidget::scaleChanged( double scale )
@ -103,7 +102,9 @@ void QgsTileScaleWidget::scaleChanged( double scale )
}
QgsDebugMsg( QString( "selected resolution %1: %2" ).arg( i ).arg( mResolutions[i] ) );
mSlider->blockSignals( true );
mSlider->setValue( i );
mSlider->blockSignals( false );
}
void QgsTileScaleWidget::on_mSlider_valueChanged( int value )
@ -112,3 +113,58 @@ void QgsTileScaleWidget::on_mSlider_valueChanged( int value )
QgsDebugMsg( QString( "slider released at %1: %2" ).arg( mSlider->value() ).arg( mResolutions[mSlider->value()] ) );
mMapCanvas->zoomByFactor( mResolutions[mSlider->value()] / mMapCanvas->mapUnitsPerPixel() );
}
void QgsTileScaleWidget::showTileScale( QMainWindow *mainWindow )
{
QDockWidget *dock = mainWindow->findChild<QDockWidget *>( "theTileScaleDock" );
if ( dock )
{
dock->setVisible( dock->isHidden() );
return;
}
QgsMapCanvas *canvas = mainWindow->findChild<QgsMapCanvas *>( "theMapCanvas" );
QgsDebugMsg( QString( "canvas:%1 [%2]" ).arg(( ulong ) canvas, 0, 16 ).arg( canvas ? canvas->objectName() : "" ) );
if ( !canvas )
{
QgsDebugMsg( "map canvas theMapCanvas not found" );
return;
}
QgsTileScaleWidget *tws = new QgsTileScaleWidget( canvas );
tws->setObjectName( "theTileScaleWidget" );
QObject *legend = mainWindow->findChild<QObject*>( "theMapLegend" );
if ( legend )
{
connect( legend, SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
tws, SLOT( layerChanged( QgsMapLayer* ) ) );
}
else
{
QgsDebugMsg( "legend not found" );
}
//create the dock widget
dock = new QDockWidget( tr( "Tile scale" ), mainWindow );
dock->setObjectName( "theTileScaleDock" );
dock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
mainWindow->addDockWidget( Qt::RightDockWidgetArea, dock );
// add to the Panel submenu
QMenu *panelMenu = mainWindow->findChild<QMenu *>( "mPanelMenu" );
if ( panelMenu )
{
// add to the Panel submenu
panelMenu->addAction( dock->toggleViewAction() );
}
else
{
QgsDebugMsg( "panel menu not found" );
}
panelMenu->addAction( dock->toggleViewAction() );
dock->setWidget( tws );
dock->show();
}

View File

@ -22,13 +22,14 @@
class QgsMapCanvas;
class QgsMapLayer;
class QwtSlider;
class QMainWindow;
class QgsTileScaleWidget : public QWidget, private Ui::QgsTileScaleWidget
{
Q_OBJECT
public:
QgsTileScaleWidget( QgsMapCanvas *mapCanvas, QWidget * parent = 0, Qt::WindowFlags f = 0 );
static void showTileScale( QMainWindow *mainWindow );
public slots:
void layerChanged( QgsMapLayer *layer );
@ -36,6 +37,9 @@ class QgsTileScaleWidget : public QWidget, private Ui::QgsTileScaleWidget
void on_mSlider_valueChanged( int );
private:
QgsTileScaleWidget( QgsMapCanvas *mapCanvas, QWidget *parent = 0, Qt::WindowFlags f = 0 );
~QgsTileScaleWidget();
QgsMapCanvas *mMapCanvas;
QList<double> mResolutions;
};

View File

@ -1,11 +1,8 @@
/***************************************************************************
qgswmsconnection.cpp - selector for WMS servers, etc.
-------------------
begin : 3 April 2005
copyright :
original : (C) 2005 by Brendan Morley email : morb at ozemail dot com dot au
wms search : (C) 2009 Mathias Walker <mwa at sourcepole.ch>, Sourcepole AG
wms-c support : (C) 2010 Juergen E. Fischer < jef at norbit dot de >, norBIT GmbH
begin : May 2011
original : (C) 2011 by Martin Dobias
***************************************************************************/
@ -20,28 +17,13 @@
#include "../providers/wms/qgswmsprovider.h"
#include "qgis.h" // GEO_EPSG_CRS_ID
//#include "qgisapp.h" //for getThemeIcon
//#include "qgscontexthelp.h"
//#include "qgscoordinatereferencesystem.h"
//#include "qgsgenericprojectionselector.h"
//#include "qgslogger.h"
//#include "qgsmanageconnectionsdialog.h"
//#include "qgsmessageviewer.h"
#include "qgsnewhttpconnection.h"
//#include "qgsnumericsortlistviewitem.h"
#include "qgsproject.h"
#include "qgsproviderregistry.h"
#include "qgswmsconnection.h"
#include "qgsnetworkaccessmanager.h"
//#include <QButtonGroup>
//#include <QFileDialog>
//#include <QRadioButton>
//#include <QDomDocument>
//#include <QHeaderView>
//#include <QImageReader>
#include <QInputDialog>
//#include <QMap>
#include <QMessageBox>
#include <QPicture>
#include <QSettings>
@ -110,12 +92,12 @@ QgsWMSConnection::~QgsWMSConnection()
}
QString QgsWMSConnection::connectionInfo( )
QString QgsWMSConnection::connectionInfo()
{
return mConnectionInfo;
}
QgsWmsProvider * QgsWMSConnection::provider( )
QgsWmsProvider *QgsWMSConnection::provider()
{
// TODO: Create and bind to data provider

View File

@ -7,6 +7,8 @@
#include "qgsnewhttpconnection.h"
#include "qgstilescalewidget.h"
// ---------------------------------------------------------------------------
QgsWMSConnectionItem::QgsWMSConnectionItem( QgsDataItem* parent, QString name, QString path )
: QgsDataCollectionItem( parent, name, path )
@ -23,7 +25,7 @@ QVector<QgsDataItem*> QgsWMSConnectionItem::createChildren()
QgsDebugMsg( "Entered" );
QVector<QgsDataItem*> children;
QgsWMSConnection connection( mName );
QgsWmsProvider *wmsProvider = connection.provider( );
QgsWmsProvider *wmsProvider = connection.provider();
if ( !wmsProvider )
return children;
@ -248,6 +250,11 @@ void QgsWMSRootItem::newConnection()
// ---------------------------------------------------------------------------
QGISEXTERN void registerGui( QMainWindow *mainWindow )
{
QgsTileScaleWidget::showTileScale( mainWindow );
}
QGISEXTERN QgsWMSSourceSelect * selectWidget( QWidget * parent, Qt::WFlags fl )
{
return new QgsWMSSourceSelect( parent, fl );

File diff suppressed because it is too large Load Diff

View File

@ -93,13 +93,14 @@ struct QgsWmsRequestProperty
// we already know what's in this part.
QgsWmsOperationType getMap;
QgsWmsOperationType getFeatureInfo;
QgsWmsOperationType getTile;
};
/** Exception Property structure */
// TODO: Fill to WMS specifications
struct QgsWmsExceptionProperty
{
QStringList format; // text formats supported.
QStringList format; // text formats supported.
};
/** Primary Contact Person Property structure */
@ -304,26 +305,114 @@ struct QgsWmsLayerProperty
int fixedHeight;
};
struct QgsWmsTileSetProfile
struct QgsWmtsTheme
{
QString crs;
QgsWmsBoundingBoxProperty boundingBox;
QStringList resolutions;
QString identifier;
QString title, abstract;
QStringList keywords;
QgsWmtsTheme *subTheme;
QStringList layerRefs;
QgsWmtsTheme() : subTheme( 0 ) {}
~QgsWmtsTheme() { delete subTheme; }
};
struct QgsWmtsTileMatrix
{
QString identifier;
QString title, abstract;
QStringList keywords;
double scaleDenom;
QgsPoint topLeft;
int tileWidth;
int tileHeight;
int matrixWidth;
int matrixHeight;
};
struct QgsWmtsTileMatrixSet
{
QString identifier;
QString title, abstract;
QStringList keywords;
QVector<QgsWmsBoundingBoxProperty> boundingBox;
QString crs;
QString wkScaleSet;
QMap<double, QgsWmtsTileMatrix> tileMatrices;
};
enum QgsTileMode { WMTS, WMSC };
struct QgsWmtsTileMatrixLimits
{
QString tileMatrix;
int minTileRow, maxTileRow;
int minTileCol, maxTileCol;
};
struct QgsWmtsTileMatrixSetLink
{
QString tileMatrixSet;
QHash<QString, QgsWmtsTileMatrixLimits> limits;
};
struct QgsWmtsLegendURL
{
QString format;
QStringList styles;
QStringList layers;
double minScale, maxScale;
QString href;
int width, height;
};
struct QgsWmtsStyle
{
QString identifier;
QString title, abstract;
QStringList keywords;
bool isDefault;
QList<QgsWmtsLegendURL> legendURLs;
};
struct QgsWmtsDimension
{
QString identifier;
QString title, abstract;
QStringList keywords;
QString UOM;
QString unitSymbol;
QString defaultValue;
bool current;
QStringList values;
};
struct QgsWmtsTileLayer
{
enum QgsTileMode tileMode;
QString identifier;
QString title, abstract;
QStringList keywords;
QgsWmsBoundingBoxProperty boundingBox;
QString format;
QString infoFormat;
QString defaultStyle;
QHash<QString, QgsWmtsDimension> dimensions;
QHash<QString, QgsWmtsStyle> styles;
QHash<QString, QgsWmtsTileMatrixSetLink> setLinks;
QHash<QString, QString> getTileURLs;
QHash<QString, QString> getFeatureInfoURLs;
};
/** Capability Property structure */
// TODO: Fill to WMS specifications
struct QgsWmsCapabilityProperty
{
QgsWmsRequestProperty request;
QgsWmsExceptionProperty exception;
QgsWmsLayerProperty layer;
QVector<QgsWmsTileSetProfile> tileSetProfiles;
QgsWmsRequestProperty request;
QgsWmsExceptionProperty exception;
QgsWmsLayerProperty layer;
QList<QgsWmtsTileLayer> tileLayers;
QHash<QString, QgsWmtsTileMatrixSet> tileMatrixSets;
};
/** Capabilities Property structure */
@ -383,14 +472,19 @@ class QgsWmsProvider : public QgsRasterDataProvider
virtual bool supportedLayers( QVector<QgsWmsLayerProperty> &layers );
/**
* \brief Returns a list of the supported tile sets of the WMS server
* \brief Returns a list of the supported tile layers of the WMS server
*
* \param[out] tileset The list of tile sets will be placed here.
*
* \retval false if the tile sets could not be retrieved or parsed -
* see lastError() for more info
*/
virtual bool supportedTileSets( QVector<QgsWmsTileSetProfile> &tilesets );
virtual bool supportedTileLayers( QList<QgsWmtsTileLayer> &tileLayers );
/**
* \brief Returns a list of the available tile matrix sets
*/
virtual bool supportedTileMatrixSets( QHash<QString, QgsWmtsTileMatrixSet> &tileMatrixSets );
/**
* \brief Returns a map for the hierarchy of layers
@ -480,10 +574,12 @@ class QgsWmsProvider : public QgsRasterDataProvider
*/
bool isValid();
#if 0
/**Returns true if layer has tile set profiles
* @added in 1.5
*/
virtual bool hasTiles() const;
#endif
/**Returns the base url
* @added in 1.5
@ -500,10 +596,15 @@ class QgsWmsProvider : public QgsRasterDataProvider
*/
virtual QString getFeatureInfoUrl() const;
//! get WMS Server version string
/**Return the GetTile url
* @added in 1.9
*/
virtual QString getTileUrl() const;
//! get WMS version string
QString wmsVersion();
//! get raster image encodings supported by the WMS Server, expressed as MIME types
//! get raster image encodings supported by the WMS, expressed as MIME types
QStringList supportedImageEncodings();
/**
@ -550,13 +651,13 @@ class QgsWmsProvider : public QgsRasterDataProvider
/**
* \brief Identify details from a WMS Server from the last screen update
* \brief Identify details from a WMS from the last screen update
*
* \param point[in] The pixel coordinate (as it was displayed locally on screen)
*
* \return A html document containing the return from the WMS server
*
* \note WMS Servers prefer to receive coordinates in image space, therefore
* \note WMS prefer to receive coordinates in image space, therefore
* this function expects coordinates in that format.
*
* \note The arbitraryness of the returned document is enforced by WMS standards
@ -565,13 +666,13 @@ class QgsWmsProvider : public QgsRasterDataProvider
QString identifyAsHtml( const QgsPoint& point );
/**
* \brief Identify details from a WMS Server from the last screen update
* \brief Identify details from a WMS from the last screen update
*
* \param point[in] The pixel coordinate (as it was displayed locally on screen)
*
* \return A text document containing the return from the WMS server
*
* \note WMS Servers prefer to receive coordinates in image space, therefore
* \note WMS prefer to receive coordinates in image space, therefore
* this function expects coordinates in that format.
*
* \note The arbitraryness of the returned document is enforced by WMS standards
@ -640,6 +741,16 @@ class QgsWmsProvider : public QgsRasterDataProvider
static QVector<QgsWmsSupportedFormat> supportedFormats();
/**
returns the current tile layer (if any)
*/
QgsWmtsTileLayer *tileLayer() { return mTileLayer; }
/**
returns the current tile matrix set (if any)
*/
QgsWmtsTileMatrixSet *tileMatrixSet() { return mTileMatrixSet; }
signals:
/** \brief emit a signal to notify of a progress event */
@ -729,7 +840,13 @@ class QgsWmsProvider : public QgsRasterDataProvider
QgsWmsLayerProperty *parentProperty = 0 );
//! extract tile information from VendorSpecificCapabilities
void parseTileSetProfile( QDomElement const &e, QVector<QgsWmsTileSetProfile> &tileSetProfiles );
void parseTileSetProfile( QDomElement const &e );
//! extract tile information from WMTS Contents
void parseWMTSContents( QDomElement const &e );
void parseKeywords( const QDomNode &e, QStringList &keywords );
void parseTheme( const QDomElement &e, QgsWmtsTheme &t );
/**
* \brief parse the full WMS ServiceExceptionReport XML document
@ -741,6 +858,8 @@ class QgsWmsProvider : public QgsRasterDataProvider
//! parse the WMS ServiceException XML element
void parseServiceException( QDomElement const &e );
void parseOperationMetadata( QDomElement const &e );
/**
* \brief Calculates the combined extent of the layers selected by layersDrawn
@ -779,10 +898,10 @@ class QgsWmsProvider : public QgsRasterDataProvider
void setAuthorization( QNetworkRequest &request ) const;
//! Data source URI of the WMS for this layer
QString httpuri;
QString mHttpUri;
//! Name of the stored connection
QString connectionName;
QString mConnectionName;
//! URL part of URI (httpuri)
QString mBaseUrl;
@ -790,57 +909,67 @@ class QgsWmsProvider : public QgsRasterDataProvider
/**
* Flag indicating if the layer data source is a valid WMS layer
*/
bool valid;
bool mValid;
/**
* Spatial reference id of the layer
*/
QString srid;
QString mSrid;
/**
* Rectangle that contains the extent (bounding box) of the layer
*/
QgsRectangle layerExtent;
QgsRectangle mLayerExtent;
/**
* Capabilities of the WMS Server (raw)
* Capabilities of the WMS (raw)
*/
QByteArray httpcapabilitiesresponse;
QByteArray mHttpCapabilitiesResponse;
/**
* Capabilities of the WMS Server
* Capabilities of the WMS
*/
QDomDocument capabilitiesDom;
QDomDocument mCapabilitiesDom;
/**
* Last Service Exception Report from the WMS Server
* Last Service Exception Report from the WMS
*/
QDomDocument serviceExceptionReportDom;
QDomDocument mServiceExceptionReportDom;
/**
* Parsed capabilities of the WMS Server
* Parsed capabilities of the WMS
*/
QgsWmsCapabilitiesProperty mCapabilities;
/**
* layers hosted by the WMS Server
* layers hosted by the WMS
*/
QVector<QgsWmsLayerProperty> layersSupported;
QVector<QgsWmsLayerProperty> mLayersSupported;
/**
* tilesets hosted by the WMS Server
* tilesets hosted by the WMTS
*/
QVector<QgsWmsTileSetProfile> tilesetsSupported;
QList<QgsWmtsTileLayer> mTileLayersSupported;
/**
* tile matrix sets hosted by the WMS
*/
QHash<QString, QgsWmtsTileMatrixSet> mTileMatrixSets;
/**
* themes hosted by the WMTS
*/
QList<QgsWmtsTheme> mTileThemes;
/**
* extents per layer (in WMS CRS:84 datum)
*/
QMap<QString, QgsRectangle> extentForLayer;
QMap<QString, QgsRectangle> mExtentForLayer;
/**
* available CRSs per layer
*/
QMap<QString, QStringList > crsForLayer;
QMap<QString, QStringList > mCrsForLayer;
/**
* WMS "queryable" per layer
@ -852,40 +981,40 @@ class QgsWmsProvider : public QgsRasterDataProvider
* Active sublayers managed by this provider in a draw function, in order from bottom to top
* (some may not be visible in a draw function, cf. activeSubLayerVisibility)
*/
QStringList activeSubLayers;
QStringList activeSubStyles;
QStringList mActiveSubLayers;
QStringList mActiveSubStyles;
/**
* Visibility status of the given active sublayer
*/
QMap<QString, bool> activeSubLayerVisibility;
QMap<QString, bool> mActiveSubLayerVisibility;
/**
* MIME type of the image encoding used from the WMS server
*/
QString imageMimeType;
QString mImageMimeType;
/**
* WMS CRS type of the image CRS used from the WMS server
*/
QString imageCrs;
QString mImageCrs;
/**
* The previously retrieved image from the WMS server.
* This can be reused if draw() is called consecutively
* with the same parameters.
*/
QImage *cachedImage;
QImage *mCachedImage;
/**
* The reply to the on going request to fill the cache
*/
QNetworkReply *cacheReply;
QNetworkReply *mCacheReply;
/**
* Running tile requests
*/
QList<QNetworkReply*> tileReplies;
QList<QNetworkReply*> mTileReplies;
/**
* The reply to the capabilities request
@ -905,9 +1034,15 @@ class QgsWmsProvider : public QgsRasterDataProvider
/**
* The previous parameters to draw().
*/
QgsRectangle cachedViewExtent;
int cachedViewWidth;
int cachedViewHeight;
QgsRectangle mCachedViewExtent;
int mCachedViewWidth;
int mCachedViewHeight;
/**
* Maximum width and height of getmap requests
*/
int mMaxWidth;
int mMaxHeight;
/**
* The error caption associated with the last WMS error.
@ -928,10 +1063,11 @@ class QgsWmsProvider : public QgsRasterDataProvider
QgsCoordinateTransform *mCoordinateTransform;
//! See if calculateExtents() needs to be called before extent() returns useful data
bool extentDirty;
bool mExtentDirty;
//! Base URL for WMS GetFeatureInfo requests
QString mGetFeatureInfoUrlBase;
QString mServiceMetadataURL;
//! number of layers and parents
int mLayerCount;
@ -953,11 +1089,12 @@ class QgsWmsProvider : public QgsRasterDataProvider
//! Password for basic http authentication
QString mPassword;
//! layer is tiled, tile size and available resolutions
bool mTiled;
int mTileWidth;
int mTileHeight;
QVector<double> mResolutions;
//! layer is tiled, tile layer and active matrix set
bool mTiled;
QgsWmtsTileLayer *mTileLayer;
QString mTileMatrixSetId;
QHash<QString, QString> mTileDimensionValues;
QgsWmtsTileMatrixSet *mTileMatrixSet;
//! FEATURE_COUNT for GetFeatureInfo
int mFeatureCount;

View File

@ -5,7 +5,7 @@
copyright :
original : (C) 2005 by Brendan Morley email : morb at ozemail dot com dot au
wms search : (C) 2009 Mathias Walker <mwa at sourcepole.ch>, Sourcepole AG
wms-c support : (C) 2010 Juergen E. Fischer < jef at norbit dot de >, norBIT GmbH
wmts/wms-c support : (C) 2010-2012 Juergen E. Fischer < jef at norbit dot de >, norBIT GmbH
***************************************************************************/
@ -18,7 +18,7 @@
* *
***************************************************************************/
#include "../providers/wms/qgswmsprovider.h"
#include "qgswmsprovider.h"
#include "qgis.h" // GEO_EPSG_CRS_ID
#include "qgscontexthelp.h"
#include "qgscoordinatereferencesystem.h"
@ -33,6 +33,7 @@
#include "qgswmsconnection.h"
#include "qgswmsprovider.h"
#include "qgswmssourceselect.h"
#include "qgswmtsdimensions.h"
#include "qgsnetworkaccessmanager.h"
#include <QButtonGroup>
@ -333,57 +334,64 @@ bool QgsWMSSourceSelect::populateLayerList( QgsWmsProvider *wmsProvider )
lstLayers->sortByColumn( 0, Qt::AscendingOrder );
QVector<QgsWmsTileSetProfile> tilesets;
wmsProvider->supportedTileSets( tilesets );
wmsProvider->supportedTileLayers( mTileLayers );
tabServers->setTabEnabled( tabServers->indexOf( tabTilesets ), tilesets.size() > 0 );
tabServers->setTabEnabled( tabServers->indexOf( tabTilesets ), mTileLayers.size() > 0 );
if ( tabServers->isTabEnabled( tabServers->indexOf( tabTilesets ) ) )
tabServers->setCurrentWidget( tabTilesets );
if ( tilesets.size() > 0 )
if ( mTileLayers.size() > 0 )
{
QHash<QString, QgsWmtsTileMatrixSet> tileMatrixSets;
wmsProvider->supportedTileMatrixSets( tileMatrixSets );
int rows = 0;
foreach( const QgsWmtsTileLayer &l, mTileLayers )
{
rows += l.styles.size() * l.setLinks.size();
}
lstTilesets->clearContents();
lstTilesets->setRowCount( tilesets.size() );
lstTilesets->setRowCount( rows );
lstTilesets->setSortingEnabled( true );
for ( int i = 0; i < tilesets.size(); i++ )
int row = 0;
foreach( const QgsWmtsTileLayer &l, mTileLayers )
{
QTableWidgetItem *item = new QTableWidgetItem( tilesets[i].layers.join( ", " ) );
item->setData( Qt::UserRole + 0, tilesets[i].layers.join( "," ) );
item->setData( Qt::UserRole + 1, tilesets[i].styles.join( "," ) );
item->setData( Qt::UserRole + 2, tilesets[i].format );
item->setData( Qt::UserRole + 3, tilesets[i].crs );
item->setData( Qt::UserRole + 4, tilesets[i].tileWidth );
item->setData( Qt::UserRole + 5, tilesets[i].tileHeight );
item->setData( Qt::UserRole + 6, tilesets[i].resolutions );
lstTilesets->setItem( i, 0, item );
lstTilesets->setItem( i, 1, new QTableWidgetItem( tilesets[i].styles.join( ", " ) ) );
lstTilesets->setItem( i, 2, new QTableWidgetItem( QString( "%1x%2" ).arg( tilesets[i].tileWidth ).arg( tilesets[i].tileHeight ) ) );
lstTilesets->setItem( i, 3, new QTableWidgetItem( tilesets[i].format ) );
lstTilesets->setItem( i, 4, new QTableWidgetItem( tilesets[i].crs ) );
for ( int j = 0; j < 5; j++ )
foreach( const QgsWmtsStyle &style, l.styles )
{
QTableWidgetItem *item = lstTilesets->item( i, j );
item->setFlags( item->flags() & ~Qt::ItemIsEditable );
}
if ( !mMimeMap.contains( tilesets[i].format ) )
{
for ( int j = 0; j < 5; j++ )
foreach( const QgsWmtsTileMatrixSetLink &setLink, l.setLinks )
{
QTableWidgetItem *item = lstTilesets->item( i, j );
item->setFlags( item->flags() & ~Qt::ItemIsEnabled );
item->setToolTip( tr( "encoding %1 not supported." ).arg( tilesets[i].format ) );
QTableWidgetItem *item = new QTableWidgetItem( l.identifier );
item->setData( Qt::UserRole + 0, l.identifier );
item->setData( Qt::UserRole + 1, l.format );
item->setData( Qt::UserRole + 2, style.identifier );
item->setData( Qt::UserRole + 3, setLink.tileMatrixSet );
item->setData( Qt::UserRole + 4, tileMatrixSets[ setLink.tileMatrixSet ].crs );
lstTilesets->setItem( row, 0, item );
lstTilesets->setItem( row, 1, new QTableWidgetItem( l.format ) );
lstTilesets->setItem( row, 2, new QTableWidgetItem( style.identifier ) );
QTableWidgetItem *styleItem = new QTableWidgetItem( l.title );
if ( !l.abstract.isEmpty() )
styleItem->setToolTip( "<p>" + l.abstract + "</p>" );
lstTilesets->setItem( row, 3, styleItem );
lstTilesets->setItem( row, 4, new QTableWidgetItem( setLink.tileMatrixSet ) );
lstTilesets->setItem( row, 5, new QTableWidgetItem( tileMatrixSets[ setLink.tileMatrixSet ].crs ) );
if ( !mMimeMap.contains( l.format ) )
{
for ( int i = 0; i < lstTilesets->columnCount(); i++ )
{
QTableWidgetItem *item = lstTilesets->item( row, i );
item->setFlags( item->flags() & ~Qt::ItemIsEnabled );
item->setToolTip( tr( "encoding %1 not supported." ).arg( l.format ) );
}
}
row++;
}
}
QString crsName = descriptionForAuthId( tilesets[i].crs );
if ( crsName.isEmpty() )
crsName = tr( "CRS %1 not supported." ).arg( tilesets[i].crs );
lstTilesets->item( i, 4 )->setToolTip( crsName );
}
lstTilesets->resizeColumnsToContents();
@ -405,7 +413,7 @@ void QgsWMSSourceSelect::on_btnConnect_clicked()
mConnName = cmbConnections->currentText();
QgsWMSConnection connection( cmbConnections->currentText() );
QgsWmsProvider *wmsProvider = connection.provider( );
QgsWmsProvider *wmsProvider = connection.provider();
mConnectionInfo = connection.connectionInfo();
if ( wmsProvider )
@ -444,52 +452,90 @@ void QgsWMSSourceSelect::addClicked()
QString crs;
QString connInfo = connectionInfo();
QString connArgs;
QStringList connArgs;
if ( mTileWidth->text().toInt() > 0 && mTileHeight->text().toInt() > 0 )
{
connArgs << QString( "maxSize=%1;%2" ).arg( mTileWidth->text().toInt() ).arg( mTileHeight->text().toInt() );
}
if ( lstTilesets->selectedItems().isEmpty() )
{
collectSelectedLayers( layers, styles );
crs = mCRS;
format = mFormats[ mImageFormatGroup->checkedId()].format;
if ( mTileWidth->text().toInt() > 0 && mTileHeight->text().toInt() > 0 )
{
connArgs = QString( "tiled=%1;%2" ).arg( mTileWidth->text().toInt() ).arg( mTileHeight->text().toInt() );
}
}
else
{
QTableWidgetItem *item = lstTilesets->selectedItems().first();
layers = item->data( Qt::UserRole + 0 ).toStringList();
styles = item->data( Qt::UserRole + 1 ).toStringList();
format = item->data( Qt::UserRole + 2 ).toString();
crs = item->data( Qt::UserRole + 3 ).toString();
connArgs = QString( "tiled=%1;%2;%3" )
.arg( item->data( Qt::UserRole + 4 ).toInt() )
.arg( item->data( Qt::UserRole + 5 ).toInt() )
.arg( item->data( Qt::UserRole + 6 ).toStringList().join( ";" ) );
layers = QStringList( item->data( Qt::UserRole + 0 ).toString() );
format = item->data( Qt::UserRole + 1 ).toString();
styles = QStringList( item->data( Qt::UserRole + 2 ).toString() );
crs = item->data( Qt::UserRole + 4 ).toString();
connArgs << QString( "tileMatrixSet=%1" ).arg( item->data( Qt::UserRole + 3 ).toStringList().join( ";" ) );
const QgsWmtsTileLayer *layer = 0;
foreach( const QgsWmtsTileLayer &l, mTileLayers )
{
if ( l.identifier == layers.join( "," ) )
{
layer = &l;
break;
}
}
Q_ASSERT( layer );
if ( !layer->dimensions.isEmpty() )
{
QgsWmtsDimensions *dlg = new QgsWmtsDimensions( *layer, this );
if ( dlg->exec() != QDialog::Accepted )
{
delete dlg;
return;
}
QHash<QString, QString> dims;
dlg->selectedDimensions( dims );
QString dimString = "tileDimensions=";
QString delim;
for ( QHash<QString, QString>::const_iterator it = dims.constBegin();
it != dims.constEnd();
++it )
{
dimString += delim + it.key() + "=" + it.value();
delim = ";";
}
delete dlg;
connArgs << dimString;
}
}
if ( mFeatureCount->text().toInt() > 0 )
{
if ( !connArgs.isEmpty() )
connArgs += ",";
connArgs += QString( "featureCount=%1" ).arg( mFeatureCount->text().toInt() );
connArgs << QString( "featureCount=%1" ).arg( mFeatureCount->text().toInt() );
}
if ( !connArgs.isEmpty() )
{
if ( connInfo.startsWith( "username=" ) || connInfo.startsWith( "ignoreUrl=" ) )
if ( !connInfo.startsWith( "username=" ) && !connInfo.startsWith( "ignoreUrl=" ) )
{
connInfo.prepend( connArgs + "," );
}
else
{
connInfo.prepend( connArgs + ",url=" );
connInfo.prepend( "url=" );
}
connArgs << connInfo;
connInfo = connArgs.join( "," );
}
QgsDebugMsg( "crs = " + crs );
QgsDebugMsg( QString( "connInfo=%1 crs=%2 " ).arg( connInfo ).arg( crs ) );
emit addRasterLayer( connInfo,
leLayerName->text().isEmpty() ? layers.join( "/" ) : leLayerName->text(),

View File

@ -1,5 +1,5 @@
/***************************************************************************
qgserversourceselect.h - selector for WMS servers, etc.
qgswmssourceselect.h - selector for WMS servers, etc.
-------------------
begin : 3 April 2005
original : (C) 2005 by Brendan Morley email : morb at ozemail dot com dot au
@ -195,6 +195,9 @@ class QgsWMSSourceSelect : public QDialog, private Ui::QgsWMSSourceSelectBase
QList<QTreeWidgetItem*> mCurrentSelection;
QTableWidgetItem* mCurrentTileset;
QList<QgsWmtsTileLayer> mTileLayers;
signals:
void addRasterLayer( QString const & rasterLayerPath,
QString const & baseName,

View File

@ -128,7 +128,6 @@
<addaction name="mActionNewBookmark"/>
<addaction name="mActionShowBookmarks"/>
<addaction name="mActionDraw"/>
<addaction name="mActionTileScale"/>
</widget>
<widget class="QMenu" name="mLayerMenu">
<property name="title">
@ -1251,11 +1250,6 @@
<string>Set Project CRS from Layer</string>
</property>
</action>
<action name="mActionTileScale">
<property name="text">
<string>Tile scale slider</string>
</property>
</action>
<action name="mActionLayerProperties">
<property name="text">
<string>Properties...</string>

View File

@ -355,17 +355,7 @@
</attribute>
<column>
<property name="text">
<string>Layers</string>
</property>
</column>
<column>
<property name="text">
<string>Styles</string>
</property>
</column>
<column>
<property name="text">
<string>Size</string>
<string>Layer</string>
</property>
</column>
<column>
@ -373,6 +363,21 @@
<string>Format</string>
</property>
</column>
<column>
<property name="text">
<string>Style</string>
</property>
</column>
<column>
<property name="text">
<string>Title</string>
</property>
</column>
<column>
<property name="text">
<string>Tileset</string>
</property>
</column>
<column>
<property name="text">
<string>CRS</string>