Skip to content

Commit e223bcc

Browse files
committedOct 7, 2015
[GRASS] initial editing test
1 parent 3dcabfb commit e223bcc

File tree

10 files changed

+414
-37
lines changed

10 files changed

+414
-37
lines changed
 

‎src/providers/grass/qgsgrass.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,35 @@ bool QgsGrass::deleteObjectDialog( const QgsGrassObject & object )
21242124
QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes;
21252125
}
21262126

2127+
void QgsGrass::createVectorMap( const QgsGrassObject & object, QString &error )
2128+
{
2129+
QgsDebugMsg( "entered" );
2130+
2131+
QgsGrass::setMapset( object );
2132+
2133+
struct Map_info *Map = 0;
2134+
QgsGrass::lock();
2135+
G_TRY
2136+
{
2137+
Map = vectNewMapStruct();
2138+
Vect_open_new( Map, object.name().toUtf8().data(), 0 );
2139+
2140+
#if ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6
2141+
Vect_build( Map );
2142+
#else
2143+
Vect_build( Map, stderr );
2144+
#endif
2145+
Vect_set_release_support( Map );
2146+
Vect_close( Map );
2147+
}
2148+
G_CATCH( QgsGrass::Exception &e )
2149+
{
2150+
error = tr( "Cannot create new vector: %1" ).arg( e.what() );
2151+
}
2152+
QgsGrass::vectDestroyMapStruct( Map );
2153+
QgsGrass::unlock();
2154+
}
2155+
21272156
void QgsGrass::createTable( dbDriver *driver, const QString tableName, const QgsFields &fields )
21282157
{
21292158
if ( !driver ) // should not happen

‎src/providers/grass/qgsgrass.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,11 @@ class GRASS_LIB_EXPORT QgsGrass : public QObject
459459
*/
460460
static bool deleteObjectDialog( const QgsGrassObject & object );
461461

462+
/** Create new vector map
463+
* @param object GRASS object specifying location/mapset/map
464+
* @param error */
465+
static void createVectorMap( const QgsGrassObject & object, QString &error );
466+
462467
/** Create new table. Throws QgsGrass::Exception */
463468
static void createTable( dbDriver *driver, const QString tableName, const QgsFields &fields );
464469

‎src/providers/grass/qgsgrassprovider.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,14 @@ const QgsFields & QgsGrassProvider::fields() const
418418
else
419419
{
420420
// Original fields must be returned during editing because edit buffer updates fields by indices
421-
return mLayer->fields();
421+
if ( mEditBuffer )
422+
{
423+
return mLayer->fields();
424+
}
425+
else
426+
{
427+
return mLayer->tableFields();
428+
}
422429
}
423430
}
424431

@@ -1454,6 +1461,8 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
14541461

14551462
setAddedFeaturesSymbol();
14561463
}
1464+
QgsDebugMsg( QString( "mCidxFieldIndex = %1 cidxFieldNumCats() = %2" )
1465+
.arg( mCidxFieldIndex ).arg( mLayer->cidxFieldNumCats() ) );
14571466
}
14581467

14591468
void QgsGrassProvider::onFeatureDeleted( QgsFeatureId fid )

‎src/providers/grass/qgsgrassprovidermodule.cpp

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -211,31 +211,18 @@ QString QgsGrassItemActions::newVectorMap()
211211
QString name = dialog.name();
212212
QgsDebugMsg( "name = " + name );
213213

214-
QgsGrass::setMapset( mGrassObject );
214+
QgsGrassObject mapObject = mGrassObject;
215+
mapObject.setName( name );
216+
mapObject.setType( QgsGrassObject::Vector );
215217

216-
struct Map_info *Map = 0;
217-
QgsGrass::lock();
218-
G_TRY
219-
{
220-
Map = QgsGrass::vectNewMapStruct();
221-
Vect_open_new( Map, dialog.name().toUtf8().data(), 0 );
222-
223-
#if ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6
224-
Vect_build( Map );
225-
#else
226-
Vect_build( Map, stderr );
227-
#endif
228-
Vect_set_release_support( Map );
229-
Vect_close( Map );
230-
QgsGrass::vectDestroyMapStruct( Map );
231-
}
232-
G_CATCH( QgsGrass::Exception &e )
218+
QString error;
219+
220+
QgsGrass::createVectorMap( mapObject, error );
221+
if ( !error.isEmpty() )
233222
{
234-
QgsGrass::warning( tr( "Cannot create new vector: %1" ).arg( e.what() ) );
223+
QgsGrass::warning( error );
235224
name = "";
236-
QgsGrass::vectDestroyMapStruct( Map );
237225
}
238-
QgsGrass::unlock();
239226
return name;
240227
}
241228

‎src/providers/grass/qgsgrassvectormap.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,8 @@ void QgsGrassVectorMap::closeAllIterators()
702702
}
703703

704704
//------------------------------------ QgsGrassVectorMapStore ------------------------------------
705+
QgsGrassVectorMapStore * QgsGrassVectorMapStore::mStore = 0;
706+
705707
QgsGrassVectorMapStore::QgsGrassVectorMapStore()
706708
{
707709
}
@@ -714,6 +716,10 @@ QgsGrassVectorMapStore::~QgsGrassVectorMapStore()
714716
QgsGrassVectorMapStore *QgsGrassVectorMapStore::instance()
715717
{
716718
static QgsGrassVectorMapStore instance;
719+
if ( mStore )
720+
{
721+
return mStore;
722+
}
717723
return &instance;
718724
}
719725

‎src/providers/grass/qgsgrassvectormap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ class QgsGrassVectorMapStore
211211

212212
static QgsGrassVectorMapStore *instance();
213213

214+
// Default instance may be overriden explicitely to avoid (temporarily) to share maps by providers
215+
// This is only used for editing test to have an independent map
216+
static void setStore( QgsGrassVectorMapStore * store ) { mStore = store; }
217+
214218
/** Open map.
215219
* @param grassObject
216220
* @return map, the map may be invalide */
@@ -222,6 +226,8 @@ class QgsGrassVectorMapStore
222226

223227
// Lock open/close map
224228
QMutex mMutex;
229+
230+
static QgsGrassVectorMapStore * mStore;
225231
};
226232

227233
#endif // QGSGRASSVECTORMAP_H

‎src/providers/grass/qgsgrassvectormaplayer.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ QgsGrassVectorMapLayer::QgsGrassVectorMapLayer( QgsGrassVectorMap *map, int fiel
4040
: mField( field )
4141
, mValid( false )
4242
, mMap( map )
43-
, mCidxFieldIndex( -1 )
4443
, mFieldInfo( 0 )
4544
, mDriver( 0 )
4645
, mHasTable( false )
@@ -52,7 +51,6 @@ QgsGrassVectorMapLayer::QgsGrassVectorMapLayer( QgsGrassVectorMap *map, int fiel
5251
void QgsGrassVectorMapLayer::clear()
5352
{
5453
QgsDebugMsg( "entered" );
55-
mCidxFieldIndex = -1;
5654
mTableFields.clear();
5755
mFields.clear();
5856
mAttributeFields.clear();
@@ -64,13 +62,22 @@ void QgsGrassVectorMapLayer::clear()
6462
mFieldInfo = 0;
6563
}
6664

65+
int QgsGrassVectorMapLayer::cidxFieldIndex()
66+
{
67+
if ( !mMap->map() )
68+
{
69+
return -1;
70+
}
71+
return Vect_cidx_get_field_index( mMap->map(), mField );
72+
}
73+
6774
int QgsGrassVectorMapLayer::cidxFieldNumCats()
6875
{
69-
if ( !mMap->map() || mCidxFieldIndex < 0 )
76+
if ( !mMap->map() || cidxFieldIndex() < 0 )
7077
{
7178
return 0;
7279
}
73-
return Vect_cidx_get_num_cats_by_index( mMap->map(), mCidxFieldIndex );
80+
return Vect_cidx_get_num_cats_by_index( mMap->map(), cidxFieldIndex() );
7481
}
7582

7683
void QgsGrassVectorMapLayer::load()
@@ -89,8 +96,7 @@ void QgsGrassVectorMapLayer::load()
8996
return;
9097
}
9198

92-
mCidxFieldIndex = Vect_cidx_get_field_index( mMap->map(), mField );
93-
QgsDebugMsg( QString( "mCidxFieldIndex = %1 cidxFieldNumCats() = %2" ).arg( cidxFieldNumCats() ) );
99+
QgsDebugMsg( QString( "cidxFieldIndex() = %1 cidxFieldNumCats() = %2" ).arg( cidxFieldIndex() ).arg( cidxFieldNumCats() ) );
94100

95101
mFieldInfo = Vect_get_field( mMap->map(), mField ); // should work also with field = 0
96102

@@ -289,18 +295,18 @@ void QgsGrassVectorMapLayer::load()
289295
mTableFields.append( QgsField( "cat", QVariant::Int, "integer" ) );
290296
QPair<double, double> minMax( 0, 0 );
291297

292-
if ( mCidxFieldIndex >= 0 )
298+
if ( cidxFieldIndex() >= 0 )
293299
{
294300
int ncats, cat, type, id;
295301

296-
ncats = Vect_cidx_get_num_cats_by_index( mMap->map(), mCidxFieldIndex );
302+
ncats = Vect_cidx_get_num_cats_by_index( mMap->map(), cidxFieldIndex() );
297303

298304
if ( ncats > 0 )
299305
{
300-
Vect_cidx_get_cat_by_index( mMap->map(), mCidxFieldIndex, 0, &cat, &type, &id );
306+
Vect_cidx_get_cat_by_index( mMap->map(), cidxFieldIndex(), 0, &cat, &type, &id );
301307
minMax.first = cat;
302308

303-
Vect_cidx_get_cat_by_index( mMap->map(), mCidxFieldIndex, ncats - 1, &cat, &type, &id );
309+
Vect_cidx_get_cat_by_index( mMap->map(), cidxFieldIndex(), ncats - 1, &cat, &type, &id );
304310
minMax.second = cat;
305311
}
306312
}

‎src/providers/grass/qgsgrassvectormaplayer.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
5151
bool isValid() const { return mValid; }
5252
QgsGrassVectorMap *map() { return mMap; }
5353

54+
/** Category index index */
55+
int cidxFieldIndex();
56+
5457
/** Current number of cats in cat index, changing during editing */
5558
int cidxFieldNumCats();
5659

@@ -59,6 +62,10 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
5962
* Original fields must be returned by provider fields() */
6063
QgsFields & fields() { return mFields; }
6164

65+
/** Current fields, as modified during editing, it contains cat field, without topo field.
66+
* This fields are used by layers which are not editied to reflect current state of editing. */
67+
QgsFields & tableFields() { return mTableFields; }
68+
6269
static QStringList fieldNames( QgsFields & fields );
6370

6471
QMap<int, QList<QVariant> > & attributes() { return mAttributes; }
@@ -159,7 +166,6 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
159166
int mField;
160167
bool mValid;
161168
QgsGrassVectorMap *mMap;
162-
int mCidxFieldIndex;
163169
struct field_info *mFieldInfo;
164170
dbDriver *mDriver;
165171

‎tests/src/providers/grass/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
ADD_DEFINITIONS("-DGRASS_EXPORT=${DLLIMPORT} -DGRASS_LIB_EXPORT=${DLLIMPORT}")
22

3-
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/providers/grass)
3+
INCLUDE_DIRECTORIES(
4+
${CMAKE_SOURCE_DIR}/src/providers/grass
5+
${GDAL_INCLUDE_DIR}
6+
${PROJ_INCLUDE_DIR}
7+
${GEOS_INCLUDE_DIR}
8+
${POSTGRES_INCLUDE_DIR}
9+
)
410

511

612
MACRO (ADD_QGIS_GRASS_TEST grass_build_version testname testsrc)

‎tests/src/providers/grass/testqgsgrassprovider.cpp

Lines changed: 320 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,19 @@
2424

2525
#include <qgsapplication.h>
2626
#include <qgscoordinatereferencesystem.h>
27-
#include <qgsgrass.h>
28-
#include <qgsgrassimport.h>
27+
#include <qgsgeometry.h>
28+
#include <qgslinestringv2.h>
29+
#include <qgspointv2.h>
30+
#include <qgspolygonv2.h>
2931
#include <qgsproviderregistry.h>
3032
#include <qgsrasterbandstats.h>
3133
#include <qgsrasterlayer.h>
3234
#include <qgsvectordataprovider.h>
35+
#include <qgsvectorlayer.h>
36+
37+
#include <qgsgrass.h>
38+
#include <qgsgrassimport.h>
39+
#include <qgsgrassprovider.h>
3340

3441
extern "C"
3542
{
@@ -62,6 +69,7 @@ class TestQgsGrassProvider: public QObject
6269
void info();
6370
void rasterImport();
6471
void vectorImport();
72+
void edit();
6573
private:
6674
void reportRow( const QString& message );
6775
void reportHeader( const QString& message );
@@ -78,6 +86,10 @@ class TestQgsGrassProvider: public QObject
7886
bool removeRecursively( const QString &filePath, QString *error = 0 );
7987
bool copyLocation( QString& tmpGisdbase );
8088
bool createTmpLocation( QString& tmpGisdbase, QString& tmpLocation, QString& tmpMapset );
89+
bool equal( QgsFeature feature, QgsFeature expectedFeatures );
90+
bool compare( QList<QgsFeature> features, QList<QgsFeature> expectedFeatures, bool& ok );
91+
bool compare( QString uri, QgsGrassObject mapObject, QgsVectorLayer *expectedLayer, bool& ok );
92+
QList<QgsFeature> getFeatures( QgsVectorLayer *layer );
8193
QString mGisdbase;
8294
QString mLocation;
8395
QString mReport;
@@ -105,7 +117,7 @@ void TestQgsGrassProvider::initTestCase()
105117
// in version different form which we are testing here and it would also load GRASS libs in different version
106118
// and result in segfault when __do_global_dtors_aux() is called.
107119
// => we must set QGIS_PROVIDER_FILE before QgsApplication::initQgis() to avoid loading GRASS provider in different version
108-
QgsGrass::putEnv( "QGIS_PROVIDER_FILE", "gdal|ogr" );
120+
QgsGrass::putEnv( "QGIS_PROVIDER_FILE", QString( "gdal|ogr|memoryprovider|grassprovider%1" ).arg( GRASS_BUILD_VERSION ) );
109121
QgsApplication::initQgis();
110122
QString mySettings = QgsApplication::showSettings();
111123
mySettings = mySettings.replace( "\n", "<br />\n" );
@@ -599,6 +611,7 @@ bool TestQgsGrassProvider::createTmpLocation( QString& tmpGisdbase, QString& tmp
599611
tmpFile->open();
600612
tmpGisdbase = tmpFile->fileName();
601613
delete tmpFile;
614+
//tmpGisdbase = QDir::tempPath() + "/qgis-grass-test/test"; // debug
602615
reportRow( "tmpGisdbase: " + tmpGisdbase );
603616
tmpLocation = "test";
604617
tmpMapset = "PERMANENT";
@@ -754,5 +767,309 @@ void TestQgsGrassProvider::vectorImport()
754767
GVERIFY( ok );
755768
}
756769

770+
class TestQgsGrassCommand
771+
{
772+
public:
773+
enum Command
774+
{
775+
AddFeature
776+
};
777+
778+
TestQgsGrassCommand( Command c, QgsFeature f, int t ) : command( c ), feature( f ), type( t ) {}
779+
780+
QString toString();
781+
Command command;
782+
QgsFeature feature;
783+
int type; // GRASS type
784+
};
785+
786+
QString TestQgsGrassCommand::toString()
787+
{
788+
QString string;
789+
if ( command == AddFeature )
790+
{
791+
string += "AddFeature ";
792+
string += feature.geometry()->exportToWkt( 1 );
793+
}
794+
return string;
795+
}
796+
797+
void TestQgsGrassProvider::edit()
798+
{
799+
reportHeader( "TestQgsGrassProvider::edit" );
800+
bool ok = true;
801+
802+
QString tmpGisdbase;
803+
QString tmpLocation;
804+
QString tmpMapset;
805+
806+
if ( !createTmpLocation( tmpGisdbase, tmpLocation, tmpMapset ) )
807+
{
808+
reportRow( "cannot create temporary location" );
809+
GVERIFY( false );
810+
return;
811+
}
812+
813+
QList<QList<TestQgsGrassCommand>> commandGroups;
814+
815+
QList<TestQgsGrassCommand> commands;
816+
QgsFeature feature;
817+
feature.setGeometry( new QgsGeometry( new QgsPointV2( QgsWKBTypes::Point, 10, 10, 0 ) ) );
818+
commands << TestQgsGrassCommand( TestQgsGrassCommand::AddFeature, feature, GV_POINT );
819+
commandGroups << commands;
820+
821+
for ( int i = 0; i < commandGroups.size(); i++ )
822+
{
823+
commands = commandGroups[i];
824+
825+
// Create GRASS vector
826+
QString name = QString( "edit_%1" ).arg( i );
827+
QgsGrassObject mapObject = QgsGrassObject( tmpGisdbase, tmpLocation, tmpMapset, name, QgsGrassObject::Vector );
828+
reportRow( "create new map: " + mapObject.toString() );
829+
QString error;
830+
QgsGrass::createVectorMap( mapObject, error );
831+
if ( !error.isEmpty() )
832+
{
833+
reportRow( error );
834+
ok = false;
835+
break;
836+
}
837+
838+
QString uri = mapObject.mapsetPath() + "/" + name + "/1_point";
839+
reportRow( "uri: " + uri );
840+
QgsVectorLayer *layer = new QgsVectorLayer( uri, name, "grass" );
841+
if ( !layer->isValid() )
842+
{
843+
reportRow( "layer is not valid" );
844+
ok = false;
845+
break;
846+
}
847+
QgsGrassProvider *provider = qobject_cast<QgsGrassProvider *>( layer->dataProvider() );
848+
if ( !provider )
849+
{
850+
reportRow( "cannot get provider" );
851+
ok = false;
852+
break;
853+
}
854+
855+
// Create memory vector for verification, it has no fields until added
856+
QgsVectorLayer *expectedLayer = new QgsVectorLayer( "Point", "test", "memory" );
857+
if ( !expectedLayer->isValid() )
858+
{
859+
reportRow( "verification layer is not valid" );
860+
ok = false;
861+
break;
862+
}
863+
864+
layer->startEditing();
865+
provider->startEditing( layer );
866+
867+
expectedLayer->startEditing();
868+
869+
for ( int j = 0; j < commands.size(); j++ )
870+
{
871+
TestQgsGrassCommand command = commands[j];
872+
if ( command.command == TestQgsGrassCommand::AddFeature )
873+
{
874+
reportRow( "command: " + command.toString() );
875+
provider->setNewFeatureType( command.type );
876+
877+
QgsFeature feature = command.feature;
878+
feature.initAttributes( layer->fields().size() ); // attributes must match layer fields
879+
layer->addFeature( feature );
880+
881+
QgsFeature expectedFeature = command.feature;
882+
expectedFeature.initAttributes( expectedLayer->fields().size() );
883+
//expectedFeature.setGeometry( new QgsGeometry( new QgsPointV2( QgsWKBTypes::Point, 10, 20, 0 ) ) ); // debug
884+
expectedLayer->addFeature( expectedFeature );
885+
}
886+
if ( !compare( uri, mapObject, expectedLayer, ok ) )
887+
{
888+
reportRow( "command failed" );
889+
break;
890+
}
891+
else
892+
{
893+
reportRow( "command ok" );
894+
}
895+
}
896+
897+
layer->commitChanges();
898+
delete layer;
899+
delete expectedLayer;
900+
}
901+
902+
removeRecursively( tmpGisdbase );
903+
GVERIFY( ok );
904+
}
905+
906+
QList<QgsFeature> TestQgsGrassProvider::getFeatures( QgsVectorLayer *layer )
907+
{
908+
QgsFeatureIterator iterator = layer->getFeatures( QgsFeatureRequest() );
909+
QgsFeature feature;
910+
QList<QgsFeature> features;
911+
while ( iterator.nextFeature( feature ) )
912+
{
913+
features << feature;
914+
}
915+
iterator.close();
916+
return features;
917+
}
918+
919+
bool TestQgsGrassProvider::equal( QgsFeature feature, QgsFeature expectedFeature )
920+
{
921+
if ( !feature.geometry()->equals( expectedFeature.geometry() ) )
922+
{
923+
return false;
924+
}
925+
// GRASS feature has always additional cat field
926+
QSet<int> indexes;
927+
for ( int i = 0; i < feature.fields()->size(); i++ )
928+
{
929+
QString name = feature.fields()->at( i ).name();
930+
if ( name == "cat" ) // skip cat
931+
{
932+
continue;
933+
}
934+
indexes << i;
935+
}
936+
for ( int i = 0; i < expectedFeature.fields()->size(); i++ )
937+
{
938+
QString name = expectedFeature.fields()->at( i ).name();
939+
int index = feature.fields()->indexFromName( name );
940+
if ( index < 0 )
941+
{
942+
// not found
943+
return false;
944+
}
945+
indexes.remove( index );
946+
if ( feature.attribute( index ) != expectedFeature.attribute( i ) )
947+
{
948+
return false;
949+
}
950+
}
951+
if ( indexes.size() > 0 )
952+
{
953+
// unexpected attribute in feature
954+
QStringList names;
955+
Q_FOREACH ( int i, indexes )
956+
{
957+
names << feature.fields()->at( i ).name();
958+
}
959+
reportRow( QString( "feature has %1 unexpected attributes: %2" ).arg( indexes.size() ).arg( names.join( "," ) ) );
960+
return false;
961+
}
962+
return true;
963+
}
964+
965+
bool TestQgsGrassProvider::compare( QList<QgsFeature> features, QList<QgsFeature> expectedFeatures, bool& ok )
966+
{
967+
bool localOk = true;
968+
if ( features.size() != expectedFeatures.size() )
969+
{
970+
reportRow( QString( "different number of features (%1) and expected features (%2)" ).arg( features.size() ).arg( expectedFeatures.size() ) );
971+
ok = false;
972+
return false;
973+
}
974+
// Check if each expected feature exists in features
975+
Q_FOREACH ( const QgsFeature& expectedFeature, expectedFeatures )
976+
{
977+
bool found = false;
978+
Q_FOREACH ( const QgsFeature& feature, features )
979+
{
980+
if ( equal( feature, expectedFeature ) )
981+
{
982+
found = true;
983+
break;
984+
}
985+
}
986+
if ( !found )
987+
{
988+
reportRow( QString( "expected feature fid = %1 not found in features" ).arg( expectedFeature.id() ) );
989+
ok = false;
990+
localOk = false;
991+
}
992+
}
993+
return localOk;
994+
}
995+
996+
bool TestQgsGrassProvider::compare( QString uri, QgsGrassObject mapObject, QgsVectorLayer *expectedLayer, bool& ok )
997+
{
998+
QList<QgsFeature> expectedFeatures = getFeatures( expectedLayer );
999+
1000+
// read the map using another layer/provider
1001+
QgsVectorLayer *layer = new QgsVectorLayer( uri, "test", "grass" );
1002+
if ( !layer->isValid() )
1003+
{
1004+
reportRow( "shared layer is not valid" );
1005+
ok = false;
1006+
return false;
1007+
}
1008+
QList<QgsFeature> features = getFeatures( layer );
1009+
delete layer;
1010+
layer = 0;
1011+
1012+
bool sharedOk = compare( features, expectedFeatures, ok );
1013+
if ( sharedOk )
1014+
{
1015+
reportRow( "comparison with shared layer ok" );
1016+
}
1017+
else
1018+
{
1019+
reportRow( "comparison with shared layer failed" );
1020+
}
1021+
1022+
// Open an independent layer which does not share data with edited one
1023+
// build topology
1024+
G_TRY
1025+
{
1026+
struct Map_info *map = QgsGrass::vectNewMapStruct();
1027+
QgsGrass::setMapset( mapObject );
1028+
Vect_open_old( map, mapObject.name().toUtf8().data(), mapObject.mapset().toUtf8().data() );
1029+
1030+
#if ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6
1031+
Vect_build( map );
1032+
#else
1033+
Vect_build( map, stderr );
1034+
#endif
1035+
Vect_set_release_support( map );
1036+
Vect_close( map );
1037+
QgsGrass::vectDestroyMapStruct( map );
1038+
}
1039+
G_CATCH( QgsGrass::Exception &e )
1040+
{
1041+
reportRow( "Cannot build topology: " + QString( e.what() ) );
1042+
ok = false;
1043+
return false;
1044+
}
1045+
1046+
QgsGrassVectorMapStore * mapStore = new QgsGrassVectorMapStore();
1047+
QgsGrassVectorMapStore::setStore( mapStore );
1048+
1049+
layer = new QgsVectorLayer( uri, "test", "grass" );
1050+
if ( !layer->isValid() )
1051+
{
1052+
reportRow( "independent layer is not valid" );
1053+
ok = false;
1054+
return false;
1055+
}
1056+
features = getFeatures( layer );
1057+
delete layer;
1058+
QgsGrassVectorMapStore::setStore( 0 );
1059+
delete mapStore;
1060+
1061+
bool independentOk = compare( features, expectedFeatures, ok );
1062+
if ( independentOk )
1063+
{
1064+
reportRow( "comparison with independent layer ok" );
1065+
}
1066+
else
1067+
{
1068+
reportRow( "comparison with independent layer failed" );
1069+
}
1070+
1071+
return sharedOk && independentOk;
1072+
}
1073+
7571074
QTEST_MAIN( TestQgsGrassProvider )
7581075
#include "testqgsgrassprovider.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.