diff --git a/python/core/qgsrasterlayer.sip b/python/core/qgsrasterlayer.sip index f15465022ac..c38d624493c 100644 --- a/python/core/qgsrasterlayer.sip +++ b/python/core/qgsrasterlayer.sip @@ -35,15 +35,10 @@ public: bool loadDefaultStyleFlag = true ); /** \brief [ data provider interface ] Constructor in provider mode */ - QgsRasterLayer( int dummy, - const QString & baseName = QString(), - const QString & path = QString(), - const QString & providerLib = QString(), - const QStringList & layers = QStringList(), - const QStringList & styles = QStringList(), - const QString & format = QString(), - const QString & crs = QString()); - + QgsRasterLayer( const QString & uri, + const QString & baseName, + const QString & providerKey, + bool loadDefaultStyleFlag = true ); /** \brief The destructor */ ~QgsRasterLayer(); @@ -195,11 +190,7 @@ public: QString redBandName(); /** [ data provider interface ] Set the data provider */ - void setDataProvider( const QString & provider, - const QStringList & layers, - const QStringList & styles, - const QString & format, - const QString & crs ); + void setDataProvider( const QString & provider ); /** \brief Mutator for drawing style */ void setDrawingStyle( const DrawingStyle & theDrawingStyle ); diff --git a/python/gui/qgisinterface.sip b/python/gui/qgisinterface.sip index 0e74993dac4..64179fd53ee 100644 --- a/python/gui/qgisinterface.sip +++ b/python/gui/qgisinterface.sip @@ -46,7 +46,7 @@ class QgisInterface : QObject //! Add a raster layer given a raster layer file name virtual QgsRasterLayer* addRasterLayer(QString rasterLayerPath, QString baseName = QString())=0; //! Add a WMS layer - virtual QgsRasterLayer* addRasterLayer(const QString& url, const QString& layerName, const QString& providerKey, const QStringList& layers, const QStringList& styles, const QString& format, const QString& crs) = 0; + virtual QgsRasterLayer* addRasterLayer(const QString& uri, const QString& baseName, const QString& providerKey) = 0; //! Add a project virtual bool addProject(QString theProject)=0; diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 3178172a3a3..658cd641046 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -753,7 +753,7 @@ void QgisApp::dropEvent( QDropEvent *event ) } else if ( u.layerType == "raster" ) { - addRasterLayer( u.uri, u.name, u.providerKey, QStringList(), QStringList(), QString(), QString() ); + addRasterLayer( u.uri, u.name, u.providerKey ); } } } @@ -2632,10 +2632,8 @@ void QgisApp::addWmsLayer() QMessageBox::warning( this, tr( "WMS" ), tr( "Cannot get WMS select dialog from provider." ) ); return; } - connect( wmss , SIGNAL( addRasterLayer( QString const &, QString const &, QString const &, QStringList const &, QStringList const &, QString const &, - QString const & ) ), - this , SLOT( addRasterLayer( QString const &, QString const &, QString const &, QStringList const &, QStringList const &, QString const &, - QString const & ) ) ); + connect( wmss , SIGNAL( addRasterLayer( QString const &, QString const &, QString const & ) ), + this , SLOT( addRasterLayer( QString const &, QString const &, QString const & ) ) ); wmss->exec(); delete wmss; } @@ -6813,22 +6811,17 @@ QgsRasterLayer* QgisApp::addRasterLayer( QString const & rasterFile, QString con /** Add a raster layer directly without prompting user for location The caller must provide information compatible with the provider plugin - using the rasterLayerPath and baseName. The provider can use these + using the uri and baseName. The provider can use these parameters in any way necessary to initialize the layer. The baseName parameter is used in the Map Legend so it should be formed in a meaningful way. \note Copied from the equivalent addVectorLayer function in this file - TODO Make it work for rasters specifically. */ QgsRasterLayer* QgisApp::addRasterLayer( - QString const &rasterLayerPath, + QString const &uri, QString const &baseName, - QString const &providerKey, - QStringList const & layers, - QStringList const & styles, - QString const &format, - QString const &crs ) + QString const &providerKey ) { QgsDebugMsg( "about to get library for " + providerKey ); @@ -6839,42 +6832,20 @@ QgsRasterLayer* QgisApp::addRasterLayer( mMapCanvas->freeze(); -// Let render() do its own cursor management -// QApplication::setOverrideCursor(Qt::WaitCursor); - // create the layer QgsRasterLayer *layer; - /* Eliminate the need to instantiate the layer based on provider type. - The caller is responsible for cobbling together the needed information to - open the layer - */ - QgsDebugMsg( "Creating new raster layer using " + rasterLayerPath - + " with baseName of " + baseName - + " and layer list of " + layers.join( ", " ) - + " and style list of " + styles.join( ", " ) - + " and format of " + format - + " and providerKey of " + providerKey - + " and CRS of " + crs ); + QgsDebugMsg( "Creating new raster layer using " + uri + + " with baseName of " + baseName ); - // TODO: Remove the 0 when the raster layer becomes a full provider gateway. - layer = new QgsRasterLayer( 0, rasterLayerPath, baseName, providerKey, layers, styles, format, crs ); + layer = new QgsRasterLayer( uri, baseName, providerKey ); QgsDebugMsg( "Constructed new layer." ); - if ( layer && shouldAskUserForGDALSublayers( layer ) ) - { - askUserForGDALSublayers( layer ); - - // The first layer loaded is not useful in that case. The user can select it in - // the list if he wants to load it. - delete layer; - } - else if ( layer && layer->isValid() ) + if ( layer && layer->isValid() ) { addRasterLayer( layer ); statusBar()->showMessage( mMapCanvas->extent().toString( 2 ) ); - } else { @@ -6889,10 +6860,6 @@ QgsRasterLayer* QgisApp::addRasterLayer( mMapCanvas->refresh(); return layer; - -// Let render() do its own cursor management -// QApplication::restoreOverrideCursor(); - } // QgisApp::addRasterLayer diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 2d98da3092f..c475655c0ac 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -468,16 +468,9 @@ class QgisApp : public QMainWindow, private Ui::MainWindow virtual bool event( QEvent * event ); /** Open a raster layer using the Raster Data Provider. - * Note this is included to support WMS layers only at this stage, - * GDAL layer support via a Provider is not yet implemented. + * \note added in 1.9 */ - QgsRasterLayer* addRasterLayer( QString const & rasterLayerPath, - QString const & baseName, - QString const & providerKey, - QStringList const & layers, - QStringList const & styles, - QString const & format, - QString const & crs ); + QgsRasterLayer* addRasterLayer( QString const & uri, QString const & baseName, QString const & providerKey ); void addWfsLayer( QString uri, QString typeName ); diff --git a/src/app/qgisappinterface.cpp b/src/app/qgisappinterface.cpp index 3d0b770b32d..6e13486d6f2 100644 --- a/src/app/qgisappinterface.cpp +++ b/src/app/qgisappinterface.cpp @@ -107,10 +107,9 @@ QgsRasterLayer* QgisAppInterface::addRasterLayer( QString rasterLayerPath, QStri return qgis->addRasterLayer( rasterLayerPath, baseName ); } -QgsRasterLayer* QgisAppInterface::addRasterLayer( const QString& url, const QString& baseName, const QString& providerKey, - const QStringList& layers, const QStringList& styles, const QString& format, const QString& crs ) +QgsRasterLayer* QgisAppInterface::addRasterLayer( const QString& url, const QString& baseName, const QString& providerKey ) { - return qgis->addRasterLayer( url, baseName, providerKey, layers, styles, format, crs ); + return qgis->addRasterLayer( url, baseName, providerKey ); } bool QgisAppInterface::addProject( QString theProjectName ) diff --git a/src/app/qgisappinterface.h b/src/app/qgisappinterface.h index 0fe8dddcb10..41c4bf28e4c 100644 --- a/src/app/qgisappinterface.h +++ b/src/app/qgisappinterface.h @@ -64,8 +64,7 @@ class QgisAppInterface : public QgisInterface //! Add a raster layer given its file name QgsRasterLayer* addRasterLayer( QString rasterLayerPath, QString baseName ); //! Add a WMS layer - QgsRasterLayer* addRasterLayer( const QString& url, const QString& baseName, const QString& providerKey, - const QStringList& layers, const QStringList& styles, const QString& format, const QString& crs ); + QgsRasterLayer* addRasterLayer( const QString& url, const QString& baseName, const QString& providerKey ); //! Add a project bool addProject( QString theProjectName ); diff --git a/src/app/qgsbrowserdockwidget.cpp b/src/app/qgsbrowserdockwidget.cpp index e86884cc24e..f70e783f5fa 100644 --- a/src/app/qgsbrowserdockwidget.cpp +++ b/src/app/qgsbrowserdockwidget.cpp @@ -307,33 +307,7 @@ void QgsBrowserDockWidget::addLayer( QgsLayerItem *layerItem ) } if ( type == QgsMapLayer::RasterLayer ) { - // This should go to WMS provider - QStringList URIParts = uri.split( "|" ); - QString rasterLayerPath = URIParts.at( 0 ); - QStringList layers; - QStringList styles; - QString format; - QString crs; - for ( int i = 1 ; i < URIParts.size(); i++ ) - { - QString part = URIParts.at( i ); - int pos = part.indexOf( "=" ); - QString field = part.left( pos ); - QString value = part.mid( pos + 1 ); - - if ( field == "layers" ) - layers = value.split( "," ); - if ( field == "styles" ) - styles = value.split( "," ); - if ( field == "format" ) - format = value; - if ( field == "crs" ) - crs = value; - } - QgsDebugMsg( "rasterLayerPath = " + rasterLayerPath ); - QgsDebugMsg( "layers = " + layers.join( " " ) ); - - QgisApp::instance()->addRasterLayer( rasterLayerPath, layerItem->layerName(), providerKey, layers, styles, format, crs ); + QgisApp::instance()->addRasterLayer( uri, layerItem->name(), providerKey ); } } @@ -413,7 +387,7 @@ void QgsBrowserDockWidget::showProperties( ) { QgsDebugMsg( "creating raster layer" ); // should copy code from addLayer() to split uri ? - QgsRasterLayer* layer = new QgsRasterLayer( 0, layerItem->uri(), layerItem->uri(), layerItem->providerKey() ); + QgsRasterLayer* layer = new QgsRasterLayer( layerItem->uri(), layerItem->uri(), layerItem->providerKey() ); if ( layer != NULL ) { layerCrs = layer->crs(); diff --git a/src/browser/qgsbrowser.cpp b/src/browser/qgsbrowser.cpp index 97eb960b58f..5739fb0c9df 100644 --- a/src/browser/qgsbrowser.cpp +++ b/src/browser/qgsbrowser.cpp @@ -207,33 +207,7 @@ bool QgsBrowser::layerClicked( QgsLayerItem *item ) } if ( type == QgsMapLayer::RasterLayer ) { - // This should go to WMS provider - QStringList URIParts = uri.split( "|" ); - QString rasterLayerPath = URIParts.at( 0 ); - QStringList layers; - QStringList styles; - QString format; - QString crs; - for ( int i = 1 ; i < URIParts.size(); i++ ) - { - QString part = URIParts.at( i ); - int pos = part.indexOf( "=" ); - QString field = part.left( pos ); - QString value = part.mid( pos + 1 ); - - if ( field == "layers" ) - layers = value.split( "," ); - if ( field == "styles" ) - styles = value.split( "," ); - if ( field == "format" ) - format = value; - if ( field == "crs" ) - crs = value; - } - QgsDebugMsg( "rasterLayerPath = " + rasterLayerPath ); - QgsDebugMsg( "layers = " + layers.join( " " ) ); - - mLayer = new QgsRasterLayer( 0, rasterLayerPath, "", providerKey, layers, styles, format, crs ); + mLayer = new QgsRasterLayer( uri, "", providerKey ); } } diff --git a/src/core/qgsbrowsermodel.cpp b/src/core/qgsbrowsermodel.cpp index 83fe136fb5d..618ade5b06a 100644 --- a/src/core/qgsbrowsermodel.cpp +++ b/src/core/qgsbrowsermodel.cpp @@ -127,11 +127,7 @@ Qt::ItemFlags QgsBrowserModel::flags( const QModelIndex & index ) const QgsDataItem* ptr = ( QgsDataItem* ) index.internalPointer(); if ( ptr->type() == QgsDataItem::Layer ) { - QgsLayerItem *layer = ( QgsLayerItem* ) ptr; - if ( layer->providerKey() != "wms" ) - { - flags |= Qt::ItemIsDragEnabled; - } + flags |= Qt::ItemIsDragEnabled; } if ( ptr->acceptDrop() ) flags |= Qt::ItemIsDropEnabled; @@ -368,7 +364,6 @@ QMimeData * QgsBrowserModel::mimeData( const QModelIndexList &indexes ) const QgsDataItem* ptr = ( QgsDataItem* ) index.internalPointer(); if ( ptr->type() != QgsDataItem::Layer ) continue; QgsLayerItem *layer = ( QgsLayerItem* ) ptr; - if ( layer->providerKey() == "wms" ) continue; lst.append( QgsMimeDataUtils::Uri( layer ) ); } } diff --git a/src/core/qgsdatasourceuri.cpp b/src/core/qgsdatasourceuri.cpp index 3ad594ed348..bc629031719 100644 --- a/src/core/qgsdatasourceuri.cpp +++ b/src/core/qgsdatasourceuri.cpp @@ -21,6 +21,7 @@ #include #include +#include QgsDataSourceURI::QgsDataSourceURI() : mSSLmode( SSLprefer ) @@ -587,6 +588,36 @@ QString QgsDataSourceURI::uri() const return theUri; } +QByteArray QgsDataSourceURI::encodedUri() const +{ + QUrl url; + foreach( QString key, mParams.uniqueKeys() ) + { + foreach( QString value, mParams.values( key ) ) + { + url.addQueryItem( key, value ); + } + } + return url.encodedQuery(); +} + +void QgsDataSourceURI::setEncodedUri( const QByteArray & uri ) +{ + mParams.clear(); + QUrl url; + url.setEncodedQuery( uri ); + QPair item; + foreach( item, url.queryItems() ) + { + mParams.insertMulti( item.first, item.second ); + } +} + +void QgsDataSourceURI::setEncodedUri( const QString & uri ) +{ + setEncodedUri( uri.toAscii() ); +} + QString QgsDataSourceURI::quotedTablename() const { if ( !mSchema.isEmpty() ) @@ -663,3 +694,32 @@ void QgsDataSourceURI::setSrid( QString srid ) { mSrid = srid; } + +void QgsDataSourceURI::setParam( const QString &key, const QString &value ) +{ + // may be multiple + mParams.insertMulti( key, value ); +} + +void QgsDataSourceURI::setParam( const QString &key, const QStringList &value ) +{ + foreach( QString val, value ) + { + mParams.insertMulti( key, val ); + } +} + +QString QgsDataSourceURI::param( const QString &key ) const +{ + return mParams.value( key ); +} + +QStringList QgsDataSourceURI::params( const QString &key ) const +{ + return mParams.values( key ); +} + +bool QgsDataSourceURI::hasParam( const QString &key ) const +{ + return mParams.contains( key ); +} diff --git a/src/core/qgsdatasourceuri.h b/src/core/qgsdatasourceuri.h index 8402039a592..ee2fb18a4dd 100644 --- a/src/core/qgsdatasourceuri.h +++ b/src/core/qgsdatasourceuri.h @@ -21,10 +21,16 @@ #include "qgis.h" +#include + /** \ingroup core * Class for storing the component parts of a PostgreSQL/RDBMS datasource URI. * This structure stores the database connection information, including host, database, * user name, password, schema, password, and sql where clause + * + * Extended to support generic params so that it may be used by any provider. + * The 2 modes (the old - RDMS specific and the new generic) may not yet be mixed. + * (Radim Blazek 4/2012) */ class CORE_EXPORT QgsDataSourceURI { @@ -38,15 +44,49 @@ class CORE_EXPORT QgsDataSourceURI //! constructor which parses input URI QgsDataSourceURI( QString uri ); + //! constructor which parses input encoded URI (generic mode) + // \note added in 1.9 + QgsDataSourceURI( const QByteArray & uri ); + //! return connection part of URI QString connectionInfo() const; //! return complete uri QString uri() const; + //! return complete encoded uri (generic mode) + // \note added in 1.9 + QByteArray encodedUri() const; + + //! set complete encoded uri (generic mode) + // \note added in 1.9 + void setEncodedUri( const QByteArray & uri ); + + //! set complete encoded uri (generic mode) + // \note added in 1.9 + void setEncodedUri( const QString & uri ); + //! quoted table name QString quotedTablename() const; + //! Set generic param (generic mode) + // \note if key exists, another is inserted + // \note added in 1.9 + void setParam( const QString &key, const QString &value ); + void setParam( const QString &key, const QStringList &value ); + + //! Get generic param (generic mode) + // \note added in 1.9 + QString param( const QString &key ) const; + + //! Get multiple generic param (generic mode) + // \note added in 1.9 + QStringList params( const QString &key ) const; + + //! Test if param exists (generic mode) + // \note added in 1.9 + bool hasParam( const QString &key ) const; + //! Set all connection related members at once //! \note This optional sslmode parameter has been added in version 1.1 void setConnection( const QString& aHost, @@ -163,6 +203,8 @@ class CORE_EXPORT QgsDataSourceURI QGis::WkbType mWkbType; //! SRID or a null string if not specified QString mSrid; + //! Generic params store + QMap mParams; }; #endif //QGSDATASOURCEURI_H diff --git a/src/core/qgsmaplayer.cpp b/src/core/qgsmaplayer.cpp index fe006094d18..ea1f5254f2d 100644 --- a/src/core/qgsmaplayer.cpp +++ b/src/core/qgsmaplayer.cpp @@ -165,6 +165,7 @@ bool QgsMapLayer::readXML( const QDomNode& layer_node ) mne = mnl.toElement(); mDataSource = mne.text(); + // TODO: this should go to providers if ( provider == "spatialite" ) { QgsDataSourceURI uri( mDataSource ); @@ -192,6 +193,82 @@ bool QgsMapLayer::readXML( const QDomNode& layer_node ) urlDest.setQueryItems( urlSource.queryItems() ); mDataSource = QString::fromAscii( urlDest.toEncoded() ); } + else if ( provider == "wms" ) + { + // >>> BACKWARD COMPATIBILITY < 1.9 + // For project file backward compatibility we must support old format: + // 1. mode: + // example: http://example.org/wms? + // 2. mode: tiled=;;;...,ignoreUrl=GetMap;GetFeatureInfo,featureCount=,username=,password=,url= + // example: tiled=256;256;0.703;0.351,url=http://example.org/tilecache? + // example: featureCount=10,http://example.org/wms? + // example: ignoreUrl=GetMap;GetFeatureInfo,username=cimrman,password=jara,url=http://example.org/wms? + // This is modified version of old QgsWmsProvider::parseUri + // The new format has always params crs,format,layers,styles and that params + // should not appear in old format url -> use them to identify version + if ( !mDataSource.contains( "crs=" ) && !mDataSource.contains( "format=" ) ) + { + QgsDebugMsg( "Old WMS URI format detected -> converting to new format" ); + QgsDataSourceURI uri; + if ( !mDataSource.startsWith( "http:" ) ) + { + QStringList parts = mDataSource.split( "," ); + QStringListIterator iter( parts ); + while ( iter.hasNext() ) + { + QString item = iter.next(); + if ( item.startsWith( "username=" ) ) + { + uri.setParam( "username", item.mid( 9 ) ); + } + else if ( item.startsWith( "password=" ) ) + { + uri.setParam( "password", item.mid( 9 ) ); + } + else if ( item.startsWith( "tiled=" ) ) + { + // in < 1.9 tiled= may apper in to variants: + // tiled=width;height - non tiled mode, specifies max width and max height + // tiled=width;height;resolutions-1;resolution2;... - tile mode + + QStringList params = item.mid( 6 ).split( ";" ); + + if ( params.size() == 2 ) // non tiled mode + { + uri.setParam( "maxWidth", params.takeFirst() ); + uri.setParam( "maxHeight", params.takeFirst() ); + } + else if ( params.size() > 2 ) // tiled mode + { + // resolutions are no more needed and size limit is not used for tiles + // we have to tell to the provider however that it is tiled + uri.setParam( "tileMatrixSet", "" ); + } + } + else if ( item.startsWith( "featureCount=" ) ) + { + uri.setParam( "featureCount", item.mid( 13 ) ); + } + else if ( item.startsWith( "url=" ) ) + { + uri.setParam( "url", item.mid( 4 ) ); + } + else if ( item.startsWith( "ignoreUrl=" ) ) + { + uri.setParam( "ignoreUrl", item.mid( 10 ).split( ";" ) ); + } + } + } + else + { + uri.setParam( "url", mDataSource ); + } + mDataSource = uri.encodedUri(); + // At this point, the URI is obviously incomplete, we add additional params + // in QgsRasterLayer::readXml + } + // <<< BACKWARD COMPATIBILITY < 1.9 + } else { mDataSource = QgsProject::instance()->readPath( mDataSource ); @@ -318,6 +395,7 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document ) QString src = source(); QgsVectorLayer *vlayer = qobject_cast( this ); + // TODO: what about postgres, mysql and others, they should not go through writePath() if ( vlayer && vlayer->providerType() == "spatialite" ) { QgsDataSourceURI uri( src ); diff --git a/src/core/raster/qgsrasterlayer.cpp b/src/core/raster/qgsrasterlayer.cpp index 356d37812a8..38766a9f100 100644 --- a/src/core/raster/qgsrasterlayer.cpp +++ b/src/core/raster/qgsrasterlayer.cpp @@ -16,6 +16,7 @@ email : tim at linfiniti.com ***************************************************************************/ #include "qgsapplication.h" +#include "qgsdatasourceuri.h" #include "qgslogger.h" #include "qgsmessagelog.h" #include "qgsmaplayerregistry.h" @@ -89,6 +90,12 @@ typedef bool isvalidrasterfilename_t( QString const & theFileNameQString, QStrin // doubles can take for the current system. (Yes, 20 was arbitrary.) #define TINY_VALUE std::numeric_limits::epsilon() * 20 +QgsRasterLayer::QgsRasterLayer() + : QgsMapLayer( RasterLayer ) +{ + init(); + mValid = false; +} QgsRasterLayer::QgsRasterLayer( QString const & path, @@ -109,18 +116,12 @@ QgsRasterLayer::QgsRasterLayer( // TODO, call constructor with provider key for now init(); - setDataProvider( "gdal", QStringList(), QStringList(), QString(), QString(), loadDefaultStyleFlag ); + setDataProvider( "gdal" ); if ( mValid && loadDefaultStyleFlag ) { bool defaultLoadedFlag = false; loadDefaultStyle( defaultLoadedFlag ); - // I'm no sure if this should be used somehow, in pre raster-providers there was - // only mLastViewPort init after this block, nothing to do with style - //if ( defaultLoadedFlag ) - //{ - //return; - //} } return; @@ -131,15 +132,14 @@ QgsRasterLayer::QgsRasterLayer( * @todo Rename into a general constructor when the old raster interface is retired * parameter dummy is just there to distinguish this function signature from the old non-provider one. */ -QgsRasterLayer::QgsRasterLayer( int dummy, - QString const & rasterLayerPath, - QString const & baseName, - QString const & providerKey, - QStringList const & layers, - QStringList const & styles, - QString const & format, - QString const & crs ) - : QgsMapLayer( RasterLayer, baseName, rasterLayerPath ) +QgsRasterLayer::QgsRasterLayer( const QString & uri, + const QString & baseName, + const QString & providerKey, + bool loadDefaultStyleFlag ) + : QgsMapLayer( RasterLayer, baseName, uri ) + // Constant that signals property not used. + , QSTRING_NOT_SET( "Not Set" ) + , TRSTRING_NOT_SET( tr( "Not Set" ) ) , mStandardDeviations( 0 ) , mDataProvider( 0 ) , mEditable( false ) @@ -148,27 +148,15 @@ QgsRasterLayer::QgsRasterLayer( int dummy, , mInvertColor( false ) , mModified( false ) , mProviderKey( providerKey ) - , mLayers( layers ) - , mStyles( styles ) - , mFormat( format ) - , mCrs( crs ) , mRenderer( 0 ) { - Q_UNUSED( dummy ); - - QgsDebugMsg( "(8 arguments) starting. with layer list of " + - layers.join( ", " ) + " and style list of " + styles.join( ", " ) + " and format of " + - format + " and CRS of " + crs ); - - + QgsDebugMsg( "Entered" ); init(); - // if we're given a provider type, try to create and bind one to this layer - bool loadDefaultStyleFlag = false ; // ??? - setDataProvider( providerKey, layers, styles, format, crs, loadDefaultStyleFlag ); + setDataProvider( providerKey ); // load default style if provider is gdal and if no style was given // this should be an argument like in the other constructor - if ( mValid && providerKey == "gdal" && layers.isEmpty() && styles.isEmpty() ) + if ( mValid && providerKey == "gdal" && loadDefaultStyleFlag ) { bool defaultLoadedFlag = false; loadDefaultStyle( defaultLoadedFlag ); @@ -188,8 +176,6 @@ QgsRasterLayer::QgsRasterLayer( int dummy, // TODO: Connect signals from the dataprovider to the qgisapp - QgsDebugMsg( "(8 arguments) exiting." ); - emit statusChanged( tr( "QgsRasterLayer created" ) ); } // QgsRasterLayer ctor @@ -2293,26 +2279,11 @@ QgsRasterDataProvider* QgsRasterLayer::loadProvider( QString theProviderKey, QSt return myDataProvider; } -void QgsRasterLayer::setDataProvider( QString const & provider, - QStringList const & layers, - QStringList const & styles, - QString const & format, - QString const & crs ) -{ - setDataProvider( provider, layers, styles, format, crs, false ); -} - /** Copied from QgsVectorLayer::setDataProvider * TODO: Make it work in the raster environment */ -void QgsRasterLayer::setDataProvider( QString const & provider, - QStringList const & layers, - QStringList const & styles, - QString const & format, - QString const & theCrs, - bool loadDefaultStyleFlag ) +void QgsRasterLayer::setDataProvider( QString const & provider ) { - Q_UNUSED( loadDefaultStyleFlag ); // XXX should I check for and possibly delete any pre-existing providers? // XXX How often will that scenario occur? @@ -2320,7 +2291,6 @@ void QgsRasterLayer::setDataProvider( QString const & provider, mValid = false; // assume the layer is invalid until we determine otherwise // set the layer name (uppercase first character) - if ( ! mLayerName.isEmpty() ) // XXX shouldn't this happen in parent? { setLayerName( mLayerName ); @@ -2335,29 +2305,12 @@ void QgsRasterLayer::setDataProvider( QString const & provider, return; } - if ( !mDataProvider->isValid() ) - { - if ( provider != "gdal" || !layers.isEmpty() || !styles.isEmpty() || !format.isNull() || !theCrs.isNull() ) - { - QgsMessageLog::logMessage( tr( "Data provider is invalid (layers: %1, styles: %2, formats: %3)" ) - .arg( layers.join( ", " ) ) - .arg( styles.join( ", " ) ) - .arg( format ), - tr( "Raster" ) ); - } - return; - } - if ( provider == "gdal" ) { // make sure that the /vsigzip or /vsizip is added to uri, if applicable mDataSource = mDataProvider->dataSourceUri(); } - mDataProvider->addLayers( layers, styles ); - mDataProvider->setImageEncoding( format ); - mDataProvider->setImageCrs( theCrs ); - setNoDataValue( mDataProvider->noDataValue() ); // get the extent @@ -2390,16 +2343,7 @@ void QgsRasterLayer::setDataProvider( QString const & provider, setDrawingStyle( MultiBandColor ); //sensible default // Setup source CRS - if ( mProviderKey == "wms" ) - { - QgsCoordinateReferenceSystem crs; - crs.createFromOgcWmsCrs( theCrs ); - setCrs( crs ); - } - else - { - setCrs( QgsCoordinateReferenceSystem( mDataProvider->crs() ) ); - } + setCrs( QgsCoordinateReferenceSystem( mDataProvider->crs() ) ); QString mySourceWkt = crs().toWkt(); @@ -3168,33 +3112,42 @@ bool QgsRasterLayer::readXml( const QDomNode& layer_node ) QDomNode rpNode = layer_node.namedItem( "rasterproperties" ); - // Collect sublayer names and styles - mLayers.clear(); - mStyles.clear(); - if ( mProviderKey == "wms" ) { - QDomElement layerElement = rpNode.firstChildElement( "wmsSublayer" ); - while ( !layerElement.isNull() ) + // >>> BACKWARD COMPATIBILITY < 1.9 + // The old WMS URI format does not contain all the informations, we add them here. + if ( !mDataSource.contains( "crs=" ) && !mDataSource.contains( "format=" ) ) { - // TODO: sublayer visibility - post-0.8 release timeframe + QgsDebugMsg( "Old WMS URI format detected -> adding params" ); + QgsDataSourceURI uri; + uri.setEncodedUri( mDataSource ); + QDomElement layerElement = rpNode.firstChildElement( "wmsSublayer" ); + while ( !layerElement.isNull() ) + { + // TODO: sublayer visibility - post-0.8 release timeframe - // collect name for the sublayer - mLayers += layerElement.namedItem( "name" ).toElement().text(); + // collect name for the sublayer + uri.setParam( "layers", layerElement.namedItem( "name" ).toElement().text() ); - // collect style for the sublayer - mStyles += layerElement.namedItem( "style" ).toElement().text(); + // collect style for the sublayer + uri.setParam( "styles", layerElement.namedItem( "style" ).toElement().text() ); - layerElement = layerElement.nextSiblingElement( "wmsSublayer" ); + layerElement = layerElement.nextSiblingElement( "wmsSublayer" ); + } + + // Collect format + QDomNode formatNode = rpNode.namedItem( "wmsFormat" ); + uri.setParam( "format", rpNode.namedItem( "wmsFormat" ).toElement().text() ); + + // WMS CRS URL param should not be mixed with that assigned to the layer. + // In the old WMS URI version there was no CRS and layer crs().authid() was used. + uri.setParam( "crs", crs().authid() ); + mDataSource = uri.encodedUri(); } - - // Collect format - mFormat = rpNode.namedItem( "wmsFormat" ).toElement().text(); + // <<< BACKWARD COMPATIBILITY < 1.9 } - mCrs = crs().authid(); - // Collect CRS - setDataProvider( mProviderKey, mLayers, mStyles, mFormat, mCrs ); + setDataProvider( mProviderKey ); QString theError; bool res = readSymbology( layer_node, theError ); @@ -3222,7 +3175,7 @@ bool QgsRasterLayer::readXml( const QDomNode& layer_node ) QgsDebugMsg( "data changed, reload provider" ); closeDataProvider(); init(); - setDataProvider( mProviderKey, mLayers, mStyles, mFormat, mCrs ); + setDataProvider( mProviderKey ); } } @@ -3244,49 +3197,6 @@ bool QgsRasterLayer::writeSymbology( QDomNode & layer_node, QDomDocument & docum mRenderer->writeXML( document, layerElem ); } - //is it still needed? -#if 0 - if ( mProviderKey == "wms" ) - { - // - for ( QStringList::const_iterator layerName = sl.begin(); - layerName != sl.end(); - ++layerName ) - { - - QgsDebugMsg( QString( " %1" ).arg( layerName->toLocal8Bit().data() ) ); - - QDomElement sublayerElement = document.createElement( "wmsSublayer" ); - - // TODO: sublayer visibility - post-0.8 release timeframe - - // - QDomElement sublayerNameElement = document.createElement( "name" ); - QDomText sublayerNameText = document.createTextNode( *layerName ); - sublayerNameElement.appendChild( sublayerNameText ); - sublayerElement.appendChild( sublayerNameElement ); - - //