Skip to content

Commit

Permalink
[GRASS][FEATURE] copy layers within location mapsets using browser dr…
Browse files Browse the repository at this point in the history
…ag and drop
  • Loading branch information
blazek committed May 20, 2015
1 parent 80a8c49 commit 27c2b5c
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 142 deletions.
113 changes: 90 additions & 23 deletions src/providers/grass/qgsgrass.cpp
Expand Up @@ -76,6 +76,52 @@ QgsGrassObject::QgsGrassObject( const QString& gisdbase, const QString& location
{
}

bool QgsGrassObject::setFromUri( const QString& uri )
{
QgsDebugMsg( "uri = " + uri );
QFileInfo fi( uri );

if ( fi.isFile() )
{
QString path = fi.canonicalFilePath();
QgsDebugMsg( "path = " + path );
// /gisdbase_path/location/mapset/cellhd/raster_map
QRegExp rx( "(.*)/([^/]*)/([^/]*)/cellhd/([^/]*)", Qt::CaseInsensitive );
if ( rx.indexIn( path ) > -1 )
{
mGisdbase = rx.cap( 1 );
mLocation = rx.cap( 2 );
mMapset = rx.cap( 3 );
mName = rx.cap( 4 );
mType = Raster;
return QgsGrass::isLocation( mGisdbase + "/" + mLocation );
}
}
else
{
// /gisdbase_path/location/mapset/vector_map/layer
// QFileInfo.canonicalPath() on non existing file does not work (returns empty string)
// QFileInfo.absolutePath() does not necessarily remove symbolic links or redundant "." or ".."
QDir dir = fi.dir(); // .../mapset/vector_map - does not exist
if ( dir.cdUp() ) // .../mapset/
{
QString path = dir.canonicalPath();
QRegExp rx( "(.*)/([^/]*)/([^/]*)" );
if ( rx.indexIn( path ) > -1 )
{
mGisdbase = rx.cap( 1 );
mLocation = rx.cap( 2 );
mMapset = rx.cap( 3 );
mName = fi.dir().dirName();
mType = Vector;
QgsDebugMsg( "parsed : " + toString() );
return QgsGrass::isLocation( mGisdbase + "/" + mLocation );
}
}
}
return false;
}

QString QgsGrassObject::elementShort() const
{
if ( mType == Raster )
Expand Down Expand Up @@ -122,9 +168,23 @@ QString QgsGrassObject::dirName( Type type )
return "";
}

bool QgsGrassObject::mapsetIdentical( const QgsGrassObject &other )
QString QgsGrassObject::toString() const
{
return elementName() + " : " + mapsetPath() + " : " + mName;
}

bool QgsGrassObject::locationIdentical( const QgsGrassObject &other ) const
{
return mGisdbase == other.mGisdbase && mLocation == other.mLocation && mMapset == other.mMapset;
QFileInfo fi( locationPath() );
QFileInfo otherFi( other.locationPath() );
return fi == otherFi;
}

bool QgsGrassObject::mapsetIdentical( const QgsGrassObject &other ) const
{
QFileInfo fi( mapsetPath() );
QFileInfo otherFi( other.mapsetPath() );
return fi == otherFi;
}

QRegExp QgsGrassObject::newNameRegExp( Type type )
Expand Down Expand Up @@ -1792,11 +1852,32 @@ void QgsGrass::renameObject( const QgsGrassObject & object, const QString& newNa

arguments << object.elementShort() + "=" + object.name() + "," + newName;

int timeout = 10000; // What timeout to use? It can take long time on network or database
int timeout = -1; // What timeout to use? It can take long time on network or database
// throws QgsGrass::Exception
QgsGrass::runModule( object.gisdbase(), object.location(), object.mapset(), cmd, arguments, timeout, false );
}

void QgsGrass::copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject )
{
QgsDebugMsg( "srcObject = " + srcObject.toString() );
QgsDebugMsg( "destObject = " + destObject.toString() );

if ( !srcObject.locationIdentical( destObject ) ) // should not happen
{
throw QgsGrass::Exception( QObject::tr( "Attempt to copy from different location." ) );
}

QString cmd = "g.copy";
QStringList arguments;

arguments << srcObject.elementShort() + "=" + srcObject.name() + "@" + srcObject.mapset() + "," + destObject.name();

int timeout = -1; // What timeout to use? It can take long time on network or database
// throws QgsGrass::Exception
// TODO: g.copy does not seem to return error code if fails (6.4.3RC1)
QgsGrass::runModule( destObject.gisdbase(), destObject.location(), destObject.mapset(), cmd, arguments, timeout, false );
}

bool QgsGrass::deleteObject( const QgsGrassObject & object )
{
QgsDebugMsg( "entered" );
Expand Down Expand Up @@ -2008,28 +2089,14 @@ Qt::CaseSensitivity GRASS_LIB_EXPORT QgsGrass::caseSensitivity()
#endif
}

bool GRASS_LIB_EXPORT QgsGrass::isMapset( QString path )
bool GRASS_LIB_EXPORT QgsGrass::isLocation( const QString& path )
{
#if 0
/* TODO: G_is_mapset() was added to GRASS 6.1 06-05-24,
enable its use after some period (others do update) */

if ( QgsGrass::versionMajor() > 6 || QgsGrass::versionMinor() > 0 )
{
if ( G_is_mapset( path.toUtf8().constData() ) )
return true;
}
else
{
#endif
QString windf = path + "/WIND";
if ( QFile::exists( windf ) )
return true;
#if 0
}
#endif
return G_is_location( path.toUtf8().constData() ) == 1;
}

return false;
bool GRASS_LIB_EXPORT QgsGrass::isMapset( const QString& path )
{
return G_is_mapset( path.toUtf8().constData() ) == 1;
}

QString GRASS_LIB_EXPORT QgsGrass::lockFilePath()
Expand Down
16 changes: 14 additions & 2 deletions src/providers/grass/qgsgrass.h
Expand Up @@ -81,6 +81,7 @@ class GRASS_LIB_EXPORT QgsGrassObject
void setGisdbase( const QString& gisdbase ) { mGisdbase = gisdbase; }
QString location() const { return mLocation; }
void setLocation( const QString& location ) { mLocation = location; }
QString locationPath() const { return mGisdbase + "/" + mLocation; }
QString mapset() const { return mMapset; }
void setMapset( const QString& mapset ) { mMapset = mapset; }
QString mapsetPath() const { return mGisdbase + "/" + mLocation + "/" + mMapset; }
Expand All @@ -89,6 +90,8 @@ class GRASS_LIB_EXPORT QgsGrassObject
QString fullName() const { return mName + "@" + mMapset; }
Type type() const { return mType; }
void setType( Type type ) { mType = type; }
// set from QGIS layer uri, returns true if set correctly, verifies also if location is a GRASS location
bool setFromUri( const QString& uri );
// element name used as modules param, e.g. g.remove element=name
QString elementShort() const;
// descriptive full name
Expand All @@ -97,8 +100,11 @@ class GRASS_LIB_EXPORT QgsGrassObject
// name of directory in GRASS mapset to look for the object (cellhd,vector,window)
QString dirName() const;
static QString dirName( Type type );
QString toString() const;
// returns true if gisdbase and location are the same
bool locationIdentical( const QgsGrassObject &other ) const;
// returns true if gisdbase, location and mapset are the same
bool mapsetIdentical( const QgsGrassObject &other );
bool mapsetIdentical( const QgsGrassObject &other ) const;
// get regexp patter for new names, e.g. vectors should not start with number
static QRegExp newNameRegExp( Type type );
private:
Expand Down Expand Up @@ -277,8 +283,11 @@ class QgsGrass

static GRASS_LIB_EXPORT void init( void );

//! test if the directory is location
static GRASS_LIB_EXPORT bool isLocation( const QString& path );;

// ! test if the directory is mapset
static GRASS_LIB_EXPORT bool isMapset( QString path );
static GRASS_LIB_EXPORT bool isMapset( const QString& path );

// ! Get the lock file
static GRASS_LIB_EXPORT QString lockFilePath();
Expand Down Expand Up @@ -357,6 +366,9 @@ class QgsGrass
// ! Rename GRASS object, throws QgsGrass::Exception
static GRASS_LIB_EXPORT void renameObject( const QgsGrassObject & object, const QString& newName );

// ! Copy GRASS object, throws QgsGrass::Exception
static GRASS_LIB_EXPORT void copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject );

// ! Delete map
static GRASS_LIB_EXPORT bool deleteObject( const QgsGrassObject & object );

Expand Down
124 changes: 72 additions & 52 deletions src/providers/grass/qgsgrassimport.cpp
Expand Up @@ -37,9 +37,19 @@ extern "C"
QgsGrassImport::QgsGrassImport( QgsGrassObject grassObject )
: QObject()
, mGrassObject( grassObject )
, mFutureWatcher( 0 )
{
}

QgsGrassImport::~QgsGrassImport()
{
if ( mFutureWatcher && !mFutureWatcher->isFinished() )
{
QgsDebugMsg( "mFutureWatcher not finished -> waitForFinished()" );
mFutureWatcher->waitForFinished();
}
}

void QgsGrassImport::setError( QString error )
{
QgsDebugMsg( "error: " + error );
Expand All @@ -51,6 +61,34 @@ QString QgsGrassImport::error()
return mError;
}

void QgsGrassImport::importInThread()
{
QgsDebugMsg( "entered" );
mFutureWatcher = new QFutureWatcher<bool>( this );
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
}

bool QgsGrassImport::run( QgsGrassImport *imp )
{
QgsDebugMsg( "entered" );
imp->import();
return true;
}

void QgsGrassImport::onFinished()
{
QgsDebugMsg( "entered" );
emit finished( this );
}

QStringList QgsGrassImport::names() const
{
QStringList list;
list << mGrassObject.name();
return list;
}

//------------------------------ QgsGrassRasterImport ------------------------------------
QgsGrassRasterImport::QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassObject& grassObject,
const QgsRectangle &extent, int xSize, int ySize )
Expand All @@ -59,7 +97,6 @@ QgsGrassRasterImport::QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassO
, mExtent( extent )
, mXSize( xSize )
, mYSize( ySize )
, mFutureWatcher( 0 )
{
}

Expand All @@ -73,21 +110,6 @@ QgsGrassRasterImport::~QgsGrassRasterImport()
delete mPipe;
}

void QgsGrassRasterImport::importInThread()
{
QgsDebugMsg( "entered" );
mFutureWatcher = new QFutureWatcher<bool>( this );
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
}

bool QgsGrassRasterImport::run( QgsGrassRasterImport *imp )
{
QgsDebugMsg( "entered" );
imp->import();
return true;
}

bool QgsGrassRasterImport::import()
{
QgsDebugMsg( "entered" );
Expand Down Expand Up @@ -152,7 +174,7 @@ bool QgsGrassRasterImport::import()
{
name += QString( "_%1" ).arg( band );
}
arguments.append( "output=" + name );
arguments.append( "output=" + name ); // get list of all output names
QTemporaryFile gisrcFile;
QProcess* process = 0;
try
Expand Down Expand Up @@ -236,13 +258,7 @@ bool QgsGrassRasterImport::import()
return true;
}

void QgsGrassRasterImport::onFinished()
{
QgsDebugMsg( "entered" );
emit finished( this );
}

QString QgsGrassRasterImport::uri() const
QString QgsGrassRasterImport::srcDescription() const
{
if ( !mPipe || !mPipe->provider() )
{
Expand Down Expand Up @@ -285,7 +301,6 @@ QStringList QgsGrassRasterImport::names() const
QgsGrassVectorImport::QgsGrassVectorImport( QgsVectorDataProvider* provider, const QgsGrassObject& grassObject )
: QgsGrassImport( grassObject )
, mProvider( provider )
, mFutureWatcher( 0 )
{
}

Expand All @@ -299,24 +314,8 @@ QgsGrassVectorImport::~QgsGrassVectorImport()
delete mProvider;
}

void QgsGrassVectorImport::importInThread()
{
QgsDebugMsg( "entered" );
mFutureWatcher = new QFutureWatcher<bool>( this );
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
}

bool QgsGrassVectorImport::run( QgsGrassVectorImport *imp )
{
QgsDebugMsg( "entered" );
imp->import();
return true;
}

bool QgsGrassVectorImport::import()
{

QgsDebugMsg( "entered" );

if ( !mProvider )
Expand Down Expand Up @@ -432,13 +431,7 @@ bool QgsGrassVectorImport::import()
return true;
}

void QgsGrassVectorImport::onFinished()
{
QgsDebugMsg( "entered" );
emit finished( this );
}

QString QgsGrassVectorImport::uri() const
QString QgsGrassVectorImport::srcDescription() const
{
if ( !mProvider )
{
Expand All @@ -447,9 +440,36 @@ QString QgsGrassVectorImport::uri() const
return mProvider->dataSourceUri();
}

QStringList QgsGrassVectorImport::names() const
//------------------------------ QgsGrassCopy ------------------------------------
QgsGrassCopy::QgsGrassCopy( const QgsGrassObject& srcObject, const QgsGrassObject& destObject )
: QgsGrassImport( destObject )
, mSrcObject( srcObject )
{
QStringList list;
list << mGrassObject.name();
return list;
}

QgsGrassCopy::~QgsGrassCopy()
{
}

bool QgsGrassCopy::import()
{
QgsDebugMsg( "entered" );

try
{
QgsGrass::copyObject( mSrcObject, mGrassObject );
}
catch ( QgsGrass::Exception &e )
{
setError( e.what() );
return false;
}

return true;
}


QString QgsGrassCopy::srcDescription() const
{
return mSrcObject.toString();
}

0 comments on commit 27c2b5c

Please sign in to comment.