Skip to content

Commit c382655

Browse files
committed
Merge branch 'master' of https://github.com/qgis/QGIS
2 parents d14c4aa + 27c2b5c commit c382655

6 files changed

+289
-142
lines changed

src/providers/grass/qgsgrass.cpp

+90-23
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,52 @@ QgsGrassObject::QgsGrassObject( const QString& gisdbase, const QString& location
7676
{
7777
}
7878

79+
bool QgsGrassObject::setFromUri( const QString& uri )
80+
{
81+
QgsDebugMsg( "uri = " + uri );
82+
QFileInfo fi( uri );
83+
84+
if ( fi.isFile() )
85+
{
86+
QString path = fi.canonicalFilePath();
87+
QgsDebugMsg( "path = " + path );
88+
// /gisdbase_path/location/mapset/cellhd/raster_map
89+
QRegExp rx( "(.*)/([^/]*)/([^/]*)/cellhd/([^/]*)", Qt::CaseInsensitive );
90+
if ( rx.indexIn( path ) > -1 )
91+
{
92+
mGisdbase = rx.cap( 1 );
93+
mLocation = rx.cap( 2 );
94+
mMapset = rx.cap( 3 );
95+
mName = rx.cap( 4 );
96+
mType = Raster;
97+
return QgsGrass::isLocation( mGisdbase + "/" + mLocation );
98+
}
99+
}
100+
else
101+
{
102+
// /gisdbase_path/location/mapset/vector_map/layer
103+
// QFileInfo.canonicalPath() on non existing file does not work (returns empty string)
104+
// QFileInfo.absolutePath() does not necessarily remove symbolic links or redundant "." or ".."
105+
QDir dir = fi.dir(); // .../mapset/vector_map - does not exist
106+
if ( dir.cdUp() ) // .../mapset/
107+
{
108+
QString path = dir.canonicalPath();
109+
QRegExp rx( "(.*)/([^/]*)/([^/]*)" );
110+
if ( rx.indexIn( path ) > -1 )
111+
{
112+
mGisdbase = rx.cap( 1 );
113+
mLocation = rx.cap( 2 );
114+
mMapset = rx.cap( 3 );
115+
mName = fi.dir().dirName();
116+
mType = Vector;
117+
QgsDebugMsg( "parsed : " + toString() );
118+
return QgsGrass::isLocation( mGisdbase + "/" + mLocation );
119+
}
120+
}
121+
}
122+
return false;
123+
}
124+
79125
QString QgsGrassObject::elementShort() const
80126
{
81127
if ( mType == Raster )
@@ -122,9 +168,23 @@ QString QgsGrassObject::dirName( Type type )
122168
return "";
123169
}
124170

125-
bool QgsGrassObject::mapsetIdentical( const QgsGrassObject &other )
171+
QString QgsGrassObject::toString() const
172+
{
173+
return elementName() + " : " + mapsetPath() + " : " + mName;
174+
}
175+
176+
bool QgsGrassObject::locationIdentical( const QgsGrassObject &other ) const
126177
{
127-
return mGisdbase == other.mGisdbase && mLocation == other.mLocation && mMapset == other.mMapset;
178+
QFileInfo fi( locationPath() );
179+
QFileInfo otherFi( other.locationPath() );
180+
return fi == otherFi;
181+
}
182+
183+
bool QgsGrassObject::mapsetIdentical( const QgsGrassObject &other ) const
184+
{
185+
QFileInfo fi( mapsetPath() );
186+
QFileInfo otherFi( other.mapsetPath() );
187+
return fi == otherFi;
128188
}
129189

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

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

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

1860+
void QgsGrass::copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject )
1861+
{
1862+
QgsDebugMsg( "srcObject = " + srcObject.toString() );
1863+
QgsDebugMsg( "destObject = " + destObject.toString() );
1864+
1865+
if ( !srcObject.locationIdentical( destObject ) ) // should not happen
1866+
{
1867+
throw QgsGrass::Exception( QObject::tr( "Attempt to copy from different location." ) );
1868+
}
1869+
1870+
QString cmd = "g.copy";
1871+
QStringList arguments;
1872+
1873+
arguments << srcObject.elementShort() + "=" + srcObject.name() + "@" + srcObject.mapset() + "," + destObject.name();
1874+
1875+
int timeout = -1; // What timeout to use? It can take long time on network or database
1876+
// throws QgsGrass::Exception
1877+
// TODO: g.copy does not seem to return error code if fails (6.4.3RC1)
1878+
QgsGrass::runModule( destObject.gisdbase(), destObject.location(), destObject.mapset(), cmd, arguments, timeout, false );
1879+
}
1880+
18001881
bool QgsGrass::deleteObject( const QgsGrassObject & object )
18011882
{
18021883
QgsDebugMsg( "entered" );
@@ -2008,28 +2089,14 @@ Qt::CaseSensitivity GRASS_LIB_EXPORT QgsGrass::caseSensitivity()
20082089
#endif
20092090
}
20102091

2011-
bool GRASS_LIB_EXPORT QgsGrass::isMapset( QString path )
2092+
bool GRASS_LIB_EXPORT QgsGrass::isLocation( const QString& path )
20122093
{
2013-
#if 0
2014-
/* TODO: G_is_mapset() was added to GRASS 6.1 06-05-24,
2015-
enable its use after some period (others do update) */
2016-
2017-
if ( QgsGrass::versionMajor() > 6 || QgsGrass::versionMinor() > 0 )
2018-
{
2019-
if ( G_is_mapset( path.toUtf8().constData() ) )
2020-
return true;
2021-
}
2022-
else
2023-
{
2024-
#endif
2025-
QString windf = path + "/WIND";
2026-
if ( QFile::exists( windf ) )
2027-
return true;
2028-
#if 0
2029-
}
2030-
#endif
2094+
return G_is_location( path.toUtf8().constData() ) == 1;
2095+
}
20312096

2032-
return false;
2097+
bool GRASS_LIB_EXPORT QgsGrass::isMapset( const QString& path )
2098+
{
2099+
return G_is_mapset( path.toUtf8().constData() ) == 1;
20332100
}
20342101

20352102
QString GRASS_LIB_EXPORT QgsGrass::lockFilePath()

src/providers/grass/qgsgrass.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class GRASS_LIB_EXPORT QgsGrassObject
8181
void setGisdbase( const QString& gisdbase ) { mGisdbase = gisdbase; }
8282
QString location() const { return mLocation; }
8383
void setLocation( const QString& location ) { mLocation = location; }
84+
QString locationPath() const { return mGisdbase + "/" + mLocation; }
8485
QString mapset() const { return mMapset; }
8586
void setMapset( const QString& mapset ) { mMapset = mapset; }
8687
QString mapsetPath() const { return mGisdbase + "/" + mLocation + "/" + mMapset; }
@@ -89,6 +90,8 @@ class GRASS_LIB_EXPORT QgsGrassObject
8990
QString fullName() const { return mName + "@" + mMapset; }
9091
Type type() const { return mType; }
9192
void setType( Type type ) { mType = type; }
93+
// set from QGIS layer uri, returns true if set correctly, verifies also if location is a GRASS location
94+
bool setFromUri( const QString& uri );
9295
// element name used as modules param, e.g. g.remove element=name
9396
QString elementShort() const;
9497
// descriptive full name
@@ -97,8 +100,11 @@ class GRASS_LIB_EXPORT QgsGrassObject
97100
// name of directory in GRASS mapset to look for the object (cellhd,vector,window)
98101
QString dirName() const;
99102
static QString dirName( Type type );
103+
QString toString() const;
104+
// returns true if gisdbase and location are the same
105+
bool locationIdentical( const QgsGrassObject &other ) const;
100106
// returns true if gisdbase, location and mapset are the same
101-
bool mapsetIdentical( const QgsGrassObject &other );
107+
bool mapsetIdentical( const QgsGrassObject &other ) const;
102108
// get regexp patter for new names, e.g. vectors should not start with number
103109
static QRegExp newNameRegExp( Type type );
104110
private:
@@ -277,8 +283,11 @@ class QgsGrass
277283

278284
static GRASS_LIB_EXPORT void init( void );
279285

286+
//! test if the directory is location
287+
static GRASS_LIB_EXPORT bool isLocation( const QString& path );;
288+
280289
// ! test if the directory is mapset
281-
static GRASS_LIB_EXPORT bool isMapset( QString path );
290+
static GRASS_LIB_EXPORT bool isMapset( const QString& path );
282291

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

369+
// ! Copy GRASS object, throws QgsGrass::Exception
370+
static GRASS_LIB_EXPORT void copyObject( const QgsGrassObject & srcObject, const QgsGrassObject & destObject );
371+
360372
// ! Delete map
361373
static GRASS_LIB_EXPORT bool deleteObject( const QgsGrassObject & object );
362374

src/providers/grass/qgsgrassimport.cpp

+72-52
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,19 @@ extern "C"
3737
QgsGrassImport::QgsGrassImport( QgsGrassObject grassObject )
3838
: QObject()
3939
, mGrassObject( grassObject )
40+
, mFutureWatcher( 0 )
4041
{
4142
}
4243

44+
QgsGrassImport::~QgsGrassImport()
45+
{
46+
if ( mFutureWatcher && !mFutureWatcher->isFinished() )
47+
{
48+
QgsDebugMsg( "mFutureWatcher not finished -> waitForFinished()" );
49+
mFutureWatcher->waitForFinished();
50+
}
51+
}
52+
4353
void QgsGrassImport::setError( QString error )
4454
{
4555
QgsDebugMsg( "error: " + error );
@@ -51,6 +61,34 @@ QString QgsGrassImport::error()
5161
return mError;
5262
}
5363

64+
void QgsGrassImport::importInThread()
65+
{
66+
QgsDebugMsg( "entered" );
67+
mFutureWatcher = new QFutureWatcher<bool>( this );
68+
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
69+
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
70+
}
71+
72+
bool QgsGrassImport::run( QgsGrassImport *imp )
73+
{
74+
QgsDebugMsg( "entered" );
75+
imp->import();
76+
return true;
77+
}
78+
79+
void QgsGrassImport::onFinished()
80+
{
81+
QgsDebugMsg( "entered" );
82+
emit finished( this );
83+
}
84+
85+
QStringList QgsGrassImport::names() const
86+
{
87+
QStringList list;
88+
list << mGrassObject.name();
89+
return list;
90+
}
91+
5492
//------------------------------ QgsGrassRasterImport ------------------------------------
5593
QgsGrassRasterImport::QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassObject& grassObject,
5694
const QgsRectangle &extent, int xSize, int ySize )
@@ -59,7 +97,6 @@ QgsGrassRasterImport::QgsGrassRasterImport( QgsRasterPipe* pipe, const QgsGrassO
5997
, mExtent( extent )
6098
, mXSize( xSize )
6199
, mYSize( ySize )
62-
, mFutureWatcher( 0 )
63100
{
64101
}
65102

@@ -73,21 +110,6 @@ QgsGrassRasterImport::~QgsGrassRasterImport()
73110
delete mPipe;
74111
}
75112

76-
void QgsGrassRasterImport::importInThread()
77-
{
78-
QgsDebugMsg( "entered" );
79-
mFutureWatcher = new QFutureWatcher<bool>( this );
80-
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
81-
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
82-
}
83-
84-
bool QgsGrassRasterImport::run( QgsGrassRasterImport *imp )
85-
{
86-
QgsDebugMsg( "entered" );
87-
imp->import();
88-
return true;
89-
}
90-
91113
bool QgsGrassRasterImport::import()
92114
{
93115
QgsDebugMsg( "entered" );
@@ -152,7 +174,7 @@ bool QgsGrassRasterImport::import()
152174
{
153175
name += QString( "_%1" ).arg( band );
154176
}
155-
arguments.append( "output=" + name );
177+
arguments.append( "output=" + name ); // get list of all output names
156178
QTemporaryFile gisrcFile;
157179
QProcess* process = 0;
158180
try
@@ -236,13 +258,7 @@ bool QgsGrassRasterImport::import()
236258
return true;
237259
}
238260

239-
void QgsGrassRasterImport::onFinished()
240-
{
241-
QgsDebugMsg( "entered" );
242-
emit finished( this );
243-
}
244-
245-
QString QgsGrassRasterImport::uri() const
261+
QString QgsGrassRasterImport::srcDescription() const
246262
{
247263
if ( !mPipe || !mPipe->provider() )
248264
{
@@ -285,7 +301,6 @@ QStringList QgsGrassRasterImport::names() const
285301
QgsGrassVectorImport::QgsGrassVectorImport( QgsVectorDataProvider* provider, const QgsGrassObject& grassObject )
286302
: QgsGrassImport( grassObject )
287303
, mProvider( provider )
288-
, mFutureWatcher( 0 )
289304
{
290305
}
291306

@@ -299,24 +314,8 @@ QgsGrassVectorImport::~QgsGrassVectorImport()
299314
delete mProvider;
300315
}
301316

302-
void QgsGrassVectorImport::importInThread()
303-
{
304-
QgsDebugMsg( "entered" );
305-
mFutureWatcher = new QFutureWatcher<bool>( this );
306-
connect( mFutureWatcher, SIGNAL( finished() ), SLOT( onFinished() ) );
307-
mFutureWatcher->setFuture( QtConcurrent::run( run, this ) );
308-
}
309-
310-
bool QgsGrassVectorImport::run( QgsGrassVectorImport *imp )
311-
{
312-
QgsDebugMsg( "entered" );
313-
imp->import();
314-
return true;
315-
}
316-
317317
bool QgsGrassVectorImport::import()
318318
{
319-
320319
QgsDebugMsg( "entered" );
321320

322321
if ( !mProvider )
@@ -432,13 +431,7 @@ bool QgsGrassVectorImport::import()
432431
return true;
433432
}
434433

435-
void QgsGrassVectorImport::onFinished()
436-
{
437-
QgsDebugMsg( "entered" );
438-
emit finished( this );
439-
}
440-
441-
QString QgsGrassVectorImport::uri() const
434+
QString QgsGrassVectorImport::srcDescription() const
442435
{
443436
if ( !mProvider )
444437
{
@@ -447,9 +440,36 @@ QString QgsGrassVectorImport::uri() const
447440
return mProvider->dataSourceUri();
448441
}
449442

450-
QStringList QgsGrassVectorImport::names() const
443+
//------------------------------ QgsGrassCopy ------------------------------------
444+
QgsGrassCopy::QgsGrassCopy( const QgsGrassObject& srcObject, const QgsGrassObject& destObject )
445+
: QgsGrassImport( destObject )
446+
, mSrcObject( srcObject )
451447
{
452-
QStringList list;
453-
list << mGrassObject.name();
454-
return list;
448+
}
449+
450+
QgsGrassCopy::~QgsGrassCopy()
451+
{
452+
}
453+
454+
bool QgsGrassCopy::import()
455+
{
456+
QgsDebugMsg( "entered" );
457+
458+
try
459+
{
460+
QgsGrass::copyObject( mSrcObject, mGrassObject );
461+
}
462+
catch ( QgsGrass::Exception &e )
463+
{
464+
setError( e.what() );
465+
return false;
466+
}
467+
468+
return true;
469+
}
470+
471+
472+
QString QgsGrassCopy::srcDescription() const
473+
{
474+
return mSrcObject.toString();
455475
}

0 commit comments

Comments
 (0)