Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #1310 from manisandro/adjust_crs_drop_from_browser
Try to use the project CRS when adding a layer from the browser
  • Loading branch information
mhugent committed Dec 23, 2014
2 parents 32079ed + 2efda5d commit 1bce9cc
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 54 deletions.
9 changes: 9 additions & 0 deletions python/core/qgsdataitem.sip
Expand Up @@ -141,6 +141,15 @@ class QgsLayerItem : QgsDataItem
// Returns provider key
QString providerKey();

/** Returns the supported CRS
* @note Added in 2.8
*/
QStringList supportedCRS();

/** Returns the supported formats
* @note Added in 2.8
*/
QStringList supportedFormats();
public:
static const QIcon &iconPoint();
static const QIcon &iconLine();
Expand Down
37 changes: 35 additions & 2 deletions src/app/qgisapp.cpp
Expand Up @@ -151,6 +151,7 @@
#include "qgsmaplayerregistry.h"
#include "qgsmapoverviewcanvas.h"
#include "qgsmaprenderer.h"
#include "qgsmapsettings.h"
#include "qgsmaptip.h"
#include "qgsmergeattributesdialog.h"
#include "qgsmessageviewer.h"
Expand Down Expand Up @@ -955,13 +956,15 @@ void QgisApp::dropEvent( QDropEvent *event )
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( event->mimeData() );
foreach ( const QgsMimeDataUtils::Uri& u, lst )
{
QString uri = crsAndFormatAdjustedLayerUri( u.uri, u.supportedCrs, u.supportedFormats );

if ( u.layerType == "vector" )
{
addVectorLayer( u.uri, u.name, u.providerKey );
addVectorLayer( uri, u.name, u.providerKey );
}
else if ( u.layerType == "raster" )
{
addRasterLayer( u.uri, u.name, u.providerKey );
addRasterLayer( uri, u.name, u.providerKey );
}
}
}
Expand Down Expand Up @@ -2731,6 +2734,36 @@ void QgisApp::addLayerDefinition()
openLayerDefinition( path );
}

QString QgisApp::crsAndFormatAdjustedLayerUri( const QString &uri , const QStringList &supportedCrs, const QStringList &supportedFormats ) const
{
QString newuri = uri;

// Adjust layer CRS to project CRS
QgsCoordinateReferenceSystem testCrs;
foreach ( QString c, supportedCrs )
{
testCrs.createFromOgcWmsCrs( c );
if ( testCrs == mMapCanvas->mapRenderer()->destinationCrs() )
{
newuri.replace( QRegExp( "crs=[^&]+" ), "crs=" + c );
QgsDebugMsg( QString( "Changing layer crs to %1, new uri: %2" ).arg( c, uri ) );
break;
}
}

// Use the last used image format
QString lastImageEncoding = QSettings().value( "/qgis/lastWmsImageEncoding", "image/png" ).toString();
foreach ( QString fmt, supportedFormats )
{
if ( fmt == lastImageEncoding )
{
newuri.replace( QRegExp( "format=[^&]+" ), "format=" + fmt );
QgsDebugMsg( QString( "Changing layer format to %1, new uri: %2" ).arg( fmt, uri ) );
break;
}
}
return newuri;
}

/**
This method prompts the user for a list of vector file names with a dialog.
Expand Down
5 changes: 5 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -150,6 +150,11 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
*/
QgsRasterLayer *addRasterLayer( const QString &rasterFile, const QString &baseName, bool guiWarning = true );

/** Returns and adjusted uri for the layer based on current and available CRS as well as the last selected image format
* @note added in 2.4
*/
QString crsAndFormatAdjustedLayerUri(const QString& uri, const QStringList& supportedCrs, const QStringList& supportedFormats) const;

/** Add a 'pre-made' map layer to the project */
void addMapLayer( QgsMapLayer *theMapLayer );

Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsbrowserdockwidget.cpp
Expand Up @@ -480,7 +480,7 @@ void QgsBrowserDockWidget::addLayer( QgsLayerItem *layerItem )
if ( layerItem == NULL )
return;

QString uri = layerItem->uri();
QString uri = QgisApp::instance()->crsAndFormatAdjustedLayerUri( layerItem->uri(), layerItem->supportedCRS(), layerItem->supportedFormats() );
if ( uri.isEmpty() )
return;

Expand Down
13 changes: 13 additions & 0 deletions src/core/qgsdataitem.h
Expand Up @@ -277,11 +277,23 @@ class CORE_EXPORT QgsLayerItem : public QgsDataItem
// Returns provider key
QString providerKey() { return mProviderKey; }

/** Returns the supported CRS
* @note Added in 2.8
*/
QStringList supportedCRS() { return mSupportedCRS; }

/** Returns the supported formats
* @note Added in 2.8
*/
QStringList supportedFormats() { return mSupportFormats; }

protected:

QString mProviderKey;
QString mUri;
LayerType mLayerType;
QStringList mSupportedCRS;
QStringList mSupportFormats;

public:
static const QIcon &iconPoint();
Expand Down Expand Up @@ -442,3 +454,4 @@ class CORE_EXPORT QgsZipItem : public QgsDataCollectionItem

#endif // QGSDATAITEM_H


109 changes: 58 additions & 51 deletions src/core/qgsmimedatautils.cpp
Expand Up @@ -22,7 +22,11 @@
static const char* QGIS_URILIST_MIMETYPE = "application/x-vnd.qgis.qgis.uri";

QgsMimeDataUtils::Uri::Uri( QgsLayerItem* layerItem )
: providerKey( layerItem->providerKey() ), name( layerItem->layerName() ), uri( layerItem->uri() )
: providerKey( layerItem->providerKey() )
, name( layerItem->layerName() )
, uri( layerItem->uri() )
, supportedCrs( layerItem->supportedCRS() )
, supportedFormats( layerItem->supportedFormats() )
{
switch ( layerItem->mapLayerType() )
{
Expand All @@ -36,66 +40,26 @@ QgsMimeDataUtils::Uri::Uri( QgsLayerItem* layerItem )
layerType = "plugin";
break;
}

}

QgsMimeDataUtils::Uri::Uri( QString& encData )
{
QStringList parts;
QChar split = ':';
QChar escape = '\\';
QString part;
bool inEscape = false;
if ( encData.isEmpty() )
return;
for ( int i = 0; i < encData.length(); ++i )
{
if ( encData.at( i ) == escape && !inEscape )
{
inEscape = true;
}
else if ( encData.at( i ) == split && !inEscape )
{
parts << part;
part = "";
}
else
{
part += encData.at( i );
inEscape = false;
}
}
if ( !part.isEmpty() )
QStringList decoded = decode( encData );
if ( decoded.size() == 6 )
{
parts << part;
}

if ( parts.size() <= 5 ) // PostGISTRaster layers yields five parts
{
layerType = parts.value( 0 );
providerKey = parts.value( 1 );
name = parts.value( 2 );
// fetchs PostGISRaster layers
if ( parts.value( 3 ) == "PG" )
{
uri = parts.value( 3 ) + ":" + parts.value( 4 );
}
else
{
uri = parts.value( 3 );
}
QgsDebugMsg( "type: " + layerType + " key: " + providerKey + " name: " + name + " uri: " + uri );
layerType = decoded[0];
providerKey = decoded[1];
name = decoded[2];
uri = decoded[3];
supportedCrs = decode( decoded[4] );
supportedFormats = decode( decoded[5] );
QgsDebugMsg( "type: " + layerType + " key: " + providerKey + " name: " + name + " uri: " + uri + " supportedCRS: " + decoded[4] + " supportedFormats: " + decoded[5] );
}
}

QString QgsMimeDataUtils::Uri::data() const
{
QString escapedName = name;
QString escapeUri = uri;
escapedName.replace( ":", "\\:" );
escapeUri.replace( "\\", "\\\\" );
escapeUri.replace( ":", "\\:" );
return layerType + ":" + providerKey + ":" + escapedName + ":" + escapeUri;
return encode( QStringList() << layerType << providerKey << name << uri << encode( supportedCrs ) << encode( supportedFormats ) );
}

// -----
Expand Down Expand Up @@ -135,3 +99,46 @@ QgsMimeDataUtils::UriList QgsMimeDataUtils::decodeUriList( const QMimeData* data
}
return list;
}

QString QgsMimeDataUtils::encode( const QStringList& items )
{
QString encoded;
foreach ( const QString& item, items )
{
QString str = item;
str.replace( ":", "\\:" );
encoded += str + ":";
}
return encoded.left( encoded.length() - 1 );
}

QStringList QgsMimeDataUtils::decode( const QString& encoded )
{
QStringList items;
QString item;
bool inEscape = false;
foreach ( const QChar& c, encoded )
{
if ( c == '\\' && inEscape )
{
item += c;
}
else if ( c == '\\' )
{
inEscape = true;
}
else if ( c == ':' && !inEscape )
{
items.append( item );
item = "";
}
else
{
item += c;
inEscape = false;
}
}
items.append( item );
return items;
}

8 changes: 8 additions & 0 deletions src/core/qgsmimedatautils.h
Expand Up @@ -16,6 +16,7 @@
#define QGSMIMEDATAUTILS_H

#include <QMimeData>
#include <QStringList>

class QgsLayerItem;

Expand All @@ -34,6 +35,8 @@ class CORE_EXPORT QgsMimeDataUtils
QString providerKey;
QString name;
QString uri;
QStringList supportedCrs;
QStringList supportedFormats;
};
typedef QList<Uri> UriList;

Expand All @@ -43,6 +46,11 @@ class CORE_EXPORT QgsMimeDataUtils

static UriList decodeUriList( const QMimeData* data );

private:
static QString encode( const QStringList& items );
static QStringList decode( const QString& encoded );

};

#endif // QGSMIMEDATAUTILS_H

2 changes: 2 additions & 0 deletions src/providers/wcs/qgswcsdataitems.cpp
Expand Up @@ -125,6 +125,7 @@ QgsWCSLayerItem::QgsWCSLayerItem( QgsDataItem* parent, QString name, QString pat
mDataSourceUri( dataSourceUri ),
mCoverageSummary( coverageSummary )
{
mSupportedCRS = mCoverageSummary.supportedCrs;
QgsDebugMsg( "uri = " + mDataSourceUri.encodedUri() );
mUri = createUri();
// Populate everything, it costs nothing, all info about layers is collected
Expand Down Expand Up @@ -312,3 +313,4 @@ QGISEXTERN QgsWCSSourceSelect * selectWidget( QWidget * parent, Qt::WindowFlags
{
return new QgsWCSSourceSelect( parent, fl );
}

3 changes: 3 additions & 0 deletions src/providers/wms/qgswmsdataitems.cpp
Expand Up @@ -244,6 +244,8 @@ QgsWMSLayerItem::QgsWMSLayerItem( QgsDataItem* parent, QString name, QString pat
, mDataSourceUri( dataSourceUri )
, mLayerProperty( layerProperty )
{
mSupportedCRS = mLayerProperty.crs;
mSupportFormats = mCapabilitiesProperty.capability.request.getMap.format;
QgsDebugMsg( "uri = " + mDataSourceUri.encodedUri() );

mUri = createUri();
Expand Down Expand Up @@ -454,3 +456,4 @@ QGISEXTERN QgsDataItem * dataItem( QString thePath, QgsDataItem* parentItem )

return 0;
}

0 comments on commit 1bce9cc

Please sign in to comment.