Skip to content
Permalink
Browse files

[GRASS] update all providers on map reload; dynamic cidx count in ite…

…rator
  • Loading branch information
blazek committed Oct 1, 2015
1 parent 2819668 commit dcdfe8beed3a0621cc254c26b52bdecd4bc84e64
@@ -313,9 +313,9 @@ bool QgsGrassFeatureIterator::fetchFeature( QgsFeature& feature )
cat = 0;
type = 0;
lid = 0;
QgsDebugMsgLevel( QString( "mNextLid = %1 mNextCidx = %2 numLines() = %3 mCidxFieldNumCats = %4" )
QgsDebugMsgLevel( QString( "mNextLid = %1 mNextCidx = %2 numLines() = %3 mCidxFieldIndex = %4 cidxFieldNumCats() = %5" )
.arg( mNextLid ).arg( mNextCidx ).arg( mSource->mLayer->map()->numLines() )
.arg( mSource->mCidxFieldNumCats ), 3 );
.arg( mSource->mCidxFieldIndex ).arg( mSource->mLayer->cidxFieldNumCats() ), 3 );
if ( mSource->mEditing )
{
// TODO should be numLines before editing started (?), but another layer
@@ -414,7 +414,7 @@ bool QgsGrassFeatureIterator::fetchFeature( QgsFeature& feature )
}
else // standard layer
{
if ( mNextCidx >= mSource->mCidxFieldNumCats )
if ( mNextCidx >= mSource->mLayer->cidxFieldNumCats() )
{
break;
}
@@ -692,7 +692,6 @@ QgsGrassFeatureSource::QgsGrassFeatureSource( const QgsGrassProvider* p )
, mGrassType( p->mGrassType )
, mQgisType( p->mQgisType )
, mCidxFieldIndex( p->mCidxFieldIndex )
, mCidxFieldNumCats( p->mCidxFieldNumCats )
, mFields( p->fields() )
, mEncoding( p->mEncoding )
, mEditing( p->mEditBuffer )
@@ -57,7 +57,6 @@ class GRASS_LIB_EXPORT QgsGrassFeatureSource : public QgsAbstractFeatureSource
QGis::WkbType mQgisType; // WKBPoint, WKBLineString, ...

int mCidxFieldIndex; // !UPDATE! Index for layerField in category index or -1 if no such field
int mCidxFieldNumCats; // !UPDATE! Number of records in field index

QgsFields mFields;
QTextCodec* mEncoding;
@@ -82,7 +82,6 @@ QgsGrassProvider::QgsGrassProvider( QString uri )
, mLayer( 0 )
, mMapVersion( 0 )
, mCidxFieldIndex( -1 )
, mCidxFieldNumCats( 0 )
, mNumberFeatures( 0 )
, mEditBuffer( 0 )
, mEditLayer( 0 )
@@ -209,40 +208,17 @@ QgsGrassProvider::QgsGrassProvider( QString uri )
break;
}

// the map may be invalid (e.g. wrong uri or open failed)
QgsGrassVectorMap *vectorMap = QgsGrassVectorMapStore::instance()->openMap( mGrassObject );
if ( !vectorMap ) // should not happen
{
QgsDebugMsg( "Cannot open map" );
return;
}
if ( !vectorMap->isValid() ) // may happen
{
QgsDebugMsg( "vectorMap is not valid" );
return;
}

mLayer = vectorMap->openLayer( mLayerField );

if ( !mLayer ) // should not happen
if ( !openLayer() )
{
QgsDebugMsg( "Cannot open layer" );
return;
}
if ( !mLayer->map() || !mLayer->map()->map() ) // should not happen
{
QgsDebugMsg( "map is null" );
return;
}

loadMapInfo();
setTopoFields();

mLayer->map()->version();

connect( mLayer->map(), SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );


// TODO: types according to database
mNativeTypes
<< QgsVectorDataProvider::NativeType( tr( "Whole number (integer)" ), "integer", QVariant::Int, 1, 10 )
@@ -266,6 +242,38 @@ int QgsGrassProvider::capabilities() const
return 0;
}

bool QgsGrassProvider::openLayer()
{
QgsDebugMsg( "entered" );
// the map may be invalid (e.g. wrong uri or open failed)
QgsGrassVectorMap *vectorMap = QgsGrassVectorMapStore::instance()->openMap( mGrassObject );
if ( !vectorMap ) // should not happen
{
QgsDebugMsg( "Cannot open map" );
return false;
}
if ( !vectorMap->isValid() ) // may happen
{
QgsDebugMsg( "vectorMap is not valid" );
return false;
}

mLayer = vectorMap->openLayer( mLayerField );

if ( !mLayer ) // should not happen
{
QgsDebugMsg( "Cannot open layer" );
return false;
}
if ( !mLayer->map() || !mLayer->map()->map() ) // should not happen
{
QgsDebugMsg( "map is null" );
return false;
}
mMapVersion = mLayer->map()->version();
return true;
}

void QgsGrassProvider::loadMapInfo()
{
// Getting the total number of features in the layer
@@ -291,38 +299,38 @@ void QgsGrassProvider::loadMapInfo()
if ( mCidxFieldIndex >= 0 )
{
mNumberFeatures = Vect_cidx_get_type_count( map(), mLayerField, mGrassType );
mCidxFieldNumCats = Vect_cidx_get_num_cats_by_index( map(), mCidxFieldIndex );
}
}
else
{
// TODO nofield layers
mNumberFeatures = 0;
mCidxFieldNumCats = 0;
}
}
QgsDebugMsg( QString( "mNumberFeatures = %1 mCidxFieldIndex = %2 mCidxFieldNumCats = %3" ).arg( mNumberFeatures ).arg( mCidxFieldIndex ).arg( mCidxFieldNumCats ) );

QgsDebugMsg( QString( "mNumberFeatures = %1 mCidxFieldIndex = %2" ).arg( mNumberFeatures ).arg( mCidxFieldIndex ) );
}

void QgsGrassProvider::update( void )
void QgsGrassProvider::update()
{
QgsDebugMsg( "entered" );
// TODO
#if 0

mValid = false;

if ( !map()s[mLayers[mLayerId].mapId].valid )
if ( mLayer )
{
mLayer->close();
mLayer = 0;
}

if ( !openLayer() )
{
QgsDebugMsg( "Cannot open layer" );
return;
}

// Getting the total number of features in the layer
// It may happen that the field disappeares from the map (deleted features, new map without that field)
loadMapInfo();

map()Version = map()s[mLayers[mLayerId].mapId].version;

mValid = true;
#endif
}

QgsGrassProvider::~QgsGrassProvider()
@@ -486,6 +494,7 @@ int QgsGrassProvider::grassLayerType( QString name )
void QgsGrassProvider::onDataChanged()
{
QgsDebugMsg( "entered" );
update();
emit dataChanged();
}

@@ -403,6 +403,7 @@ class GRASS_LIB_EXPORT QgsGrassProvider : public QgsVectorDataProvider
private:
struct Map_info * map();
void setMapset();
bool openLayer();

QgsGrassObject mGrassObject;
// field part of layer or -1 if no field specified
@@ -420,8 +421,6 @@ class GRASS_LIB_EXPORT QgsGrassProvider : public QgsVectorDataProvider

// Index for layerField in category index or -1 if no such field
int mCidxFieldIndex;
// Number of records in field index
int mCidxFieldNumCats;

bool mValid;
long mNumberFeatures;
@@ -289,6 +289,8 @@ bool QgsGrassVectorMap::startEdit()
}

mValid = true;
printDebug();

QgsGrass::unlock();
unlockOpenClose();
emit dataChanged();
@@ -527,6 +529,32 @@ QString QgsGrassVectorMap::toString()
return mGrassObject.mapsetPath() + "/" + mGrassObject.name();
}

void QgsGrassVectorMap::printDebug()
{
QgsDebugMsg( "entered" );
if ( !mValid || !mMap )
{
QgsDebugMsg( "map not valid" );
return;
}
G_TRY
{
int ncidx = Vect_cidx_get_num_fields( mMap );
QgsDebugMsg( QString( "ncidx = %1" ).arg( ncidx ) );

for ( int i = 0; i < ncidx; i++ )
{
int layer = Vect_cidx_get_field_number( mMap, i );
int ncats = Vect_cidx_get_num_cats_by_index( mMap, i );
QgsDebugMsg( QString( "i = %1 layer = %2 ncats = %3" ).arg( i ).arg( layer ).arg( ncats ) );
}
}
G_CATCH( QgsGrass::Exception &e )
{
QgsDebugMsg( "Cannot read info from map: " + QString( e.what() ) );
}
}

void QgsGrassVectorMap::lockOpenClose()
{
QgsDebugMsg( "lockOpenClose" );
@@ -626,6 +654,10 @@ QgsAbstractGeometryV2 * QgsGrassVectorMap::areaGeometry( int id )
QgsPolygonV2 * polygon = new QgsPolygonV2();

struct line_pnts *points = Vect_new_line_struct();
QgsDebugMsgLevel( QString( "points= %1" ).arg(( long )points ), 3 );
// Vect_get_area_points and Vect_get_isle_pointsis using static variable -> lock
// TODO: Faster to lock the whole feature iterator? Maybe only for areas?
QgsGrass::lock();
Vect_get_area_points( mMap, id, points );

QList<QgsPointV2> pointList;
@@ -653,6 +685,7 @@ QgsAbstractGeometryV2 * QgsGrassVectorMap::areaGeometry( int id )
ring->setPoints( pointList );
polygon->addInteriorRing( ring );
}
QgsGrass::unlock();
Vect_destroy_line_struct( points );
return polygon;
}
@@ -138,6 +138,8 @@ class GRASS_LIB_EXPORT QgsGrassVectorMap : public QObject

static QString topoSymbolFieldName() { return "topo_symbol" ; }

void printDebug();

signals:
/** Ask all iterators to cancel iteration when possible. Connected to iterators with
* Qt::DirectConnection (non blocking) */
@@ -40,6 +40,7 @@ QgsGrassVectorMapLayer::QgsGrassVectorMapLayer( QgsGrassVectorMap *map, int fiel
: mField( field )
, mValid( false )
, mMap( map )
, mCidxFieldIndex( -1 )
, mFieldInfo( 0 )
, mDriver( 0 )
, mHasTable( false )
@@ -51,6 +52,7 @@ QgsGrassVectorMapLayer::QgsGrassVectorMapLayer( QgsGrassVectorMap *map, int fiel
void QgsGrassVectorMapLayer::clear()
{
QgsDebugMsg( "entered" );
mCidxFieldIndex = -1;
mTableFields.clear();
mFields.clear();
mAttributeFields.clear();
@@ -62,6 +64,15 @@ void QgsGrassVectorMapLayer::clear()
mFieldInfo = 0;
}

int QgsGrassVectorMapLayer::cidxFieldNumCats()
{
if ( !mMap->map() || mCidxFieldIndex < 0 )
{
return 0;
}
return Vect_cidx_get_num_cats_by_index( mMap->map(), mCidxFieldIndex );
}

void QgsGrassVectorMapLayer::load()
{
QgsDebugMsg( "entered" );
@@ -78,6 +89,9 @@ void QgsGrassVectorMapLayer::load()
return;
}

mCidxFieldIndex = Vect_cidx_get_field_index( mMap->map(), mField );
QgsDebugMsg( QString( "mCidxFieldIndex = %1 cidxFieldNumCats() = %2" ).arg( cidxFieldNumCats() ) );

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

if ( !mFieldInfo )
@@ -275,19 +289,18 @@ void QgsGrassVectorMapLayer::load()
mTableFields.append( QgsField( "cat", QVariant::Int, "integer" ) );
QPair<double, double> minMax( 0, 0 );

int cidx = Vect_cidx_get_field_index( mMap->map(), mField );
if ( cidx >= 0 )
if ( mCidxFieldIndex >= 0 )
{
int ncats, cat, type, id;

ncats = Vect_cidx_get_num_cats_by_index( mMap->map(), cidx );
ncats = Vect_cidx_get_num_cats_by_index( mMap->map(), mCidxFieldIndex );

if ( ncats > 0 )
{
Vect_cidx_get_cat_by_index( mMap->map(), cidx, 0, &cat, &type, &id );
Vect_cidx_get_cat_by_index( mMap->map(), mCidxFieldIndex, 0, &cat, &type, &id );
minMax.first = cat;

Vect_cidx_get_cat_by_index( mMap->map(), cidx, ncats - 1, &cat, &type, &id );
Vect_cidx_get_cat_by_index( mMap->map(), mCidxFieldIndex, ncats - 1, &cat, &type, &id );
minMax.second = cat;
}
}
@@ -51,6 +51,9 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
bool isValid() const { return mValid; }
QgsGrassVectorMap *map() { return mMap; }

/** Current number of cats in cat index, changing during editing */
int cidxFieldNumCats();

/** Original fields before editing started + topo field if edited.
* Does not reflect add/delete column.
* Original fields must be returned by provider fields() */
@@ -68,6 +71,7 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
int keyColumn() { return mKeyColumn; }
QString keyColumnName() { return mFieldInfo ? mFieldInfo->key : QString(); }
QList< QPair<double, double> > minMax() { return mMinMax; }

int userCount() { return mUsers; }
void addUser();
void removeUser();
@@ -144,6 +148,7 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
int mField;
bool mValid;
QgsGrassVectorMap *mMap;
int mCidxFieldIndex;
struct field_info *mFieldInfo;
dbDriver *mDriver;

0 comments on commit dcdfe8b

Please sign in to comment.
You can’t perform that action at this time.