mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-28 00:17:30 -05:00
Make operations on the feature selection more memory friendly
This commit is contained in:
parent
30ada2833a
commit
e613c8b35c
@ -120,7 +120,10 @@ void QgsMapToolMoveFeature::canvasPressEvent( QMouseEvent * e )
|
||||
mMovedFeatures = vlayer->selectedFeaturesIds();
|
||||
|
||||
mRubberBand = createRubberBand( vlayer->geometryType() );
|
||||
Q_FOREACH( const QgsFeature& feat, vlayer->selectedFeatures() )
|
||||
QgsFeature feat;
|
||||
QgsFeatureIterator it = vlayer->selectedFeaturesIterator( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() ) );
|
||||
|
||||
while ( it.nextFeature( feat ) )
|
||||
{
|
||||
mRubberBand->addGeometry( feat.geometry(), vlayer );
|
||||
}
|
||||
|
@ -163,9 +163,12 @@ void QgsMapToolRotateFeature::canvasPressEvent( QMouseEvent * e )
|
||||
mRotatedFeatures = vlayer->selectedFeaturesIds();
|
||||
|
||||
mRubberBand = createRubberBand( vlayer->geometryType() );
|
||||
for ( int i = 0; i < vlayer->selectedFeatureCount(); i++ )
|
||||
|
||||
QgsFeature feat;
|
||||
QgsFeatureIterator it = vlayer->selectedFeaturesIterator();
|
||||
while ( it.nextFeature( feat ) )
|
||||
{
|
||||
mRubberBand->addGeometry( vlayer->selectedFeatures()[i].geometry(), vlayer );
|
||||
mRubberBand->addGeometry( feat.geometry(), vlayer );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2301,13 +2301,7 @@ QgsFeatureList QgsVectorLayer::selectedFeatures()
|
||||
{
|
||||
QgsFeatureList features;
|
||||
|
||||
QgsFeatureRequest req;
|
||||
if ( geometryType() == QGis::NoGeometry )
|
||||
req.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
|
||||
req.setFilterFids( mSelectedFeatureIds );
|
||||
|
||||
QgsFeatureIterator it = getFeatures( req );
|
||||
QgsFeatureIterator it = selectedFeaturesIterator();
|
||||
|
||||
QgsFeature f;
|
||||
while ( it.nextFeature( f ) )
|
||||
@ -2318,6 +2312,16 @@ QgsFeatureList QgsVectorLayer::selectedFeatures()
|
||||
return features;
|
||||
}
|
||||
|
||||
QgsFeatureIterator QgsVectorLayer::selectedFeaturesIterator( QgsFeatureRequest request )
|
||||
{
|
||||
if ( geometryType() == QGis::NoGeometry )
|
||||
request.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
|
||||
request.setFilterFids( mSelectedFeatureIds );
|
||||
|
||||
return getFeatures( request );
|
||||
}
|
||||
|
||||
bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
|
||||
{
|
||||
if ( !mEditBuffer || !mDataProvider )
|
||||
|
@ -734,6 +734,18 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
|
||||
*/
|
||||
QgsFeatureList selectedFeatures();
|
||||
|
||||
/**
|
||||
* Get an iterator of the selected features
|
||||
*
|
||||
* @param request You may specify a request, e.g. to limit the set of requested attributes.
|
||||
* Any filter on the request will be discarded.
|
||||
*
|
||||
* @return Iterator over the selected features
|
||||
*
|
||||
* @see selectedFeaturesIds()
|
||||
*/
|
||||
QgsFeatureIterator selectedFeaturesIterator( QgsFeatureRequest request = QgsFeatureRequest() );
|
||||
|
||||
/**
|
||||
* Return reference to identifiers of selected features
|
||||
*
|
||||
|
@ -198,12 +198,12 @@ int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bo
|
||||
int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
|
||||
int numberOfSplittedFeatures = 0;
|
||||
|
||||
QgsFeatureList featureList;
|
||||
QgsFeatureIterator features;
|
||||
const QgsFeatureIds selectedIds = L->selectedFeaturesIds();
|
||||
|
||||
if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection
|
||||
{
|
||||
featureList = L->selectedFeatures();
|
||||
features = L->selectedFeaturesIterator();
|
||||
}
|
||||
else //else consider all the feature that intersect the bounding box of the split line
|
||||
{
|
||||
@ -243,28 +243,24 @@ int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bo
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
|
||||
|
||||
QgsFeature f;
|
||||
while ( fit.nextFeature( f ) )
|
||||
featureList << QgsFeature( f );
|
||||
features = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
|
||||
}
|
||||
|
||||
QgsFeatureList::iterator select_it = featureList.begin();
|
||||
for ( ; select_it != featureList.end(); ++select_it )
|
||||
QgsFeature feat;
|
||||
while ( features.nextFeature( feat ) )
|
||||
{
|
||||
if ( !select_it->geometry() )
|
||||
if ( !feat.geometry() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QList<QgsGeometry*> newGeometries;
|
||||
QList<QgsPoint> topologyTestPoints;
|
||||
QgsGeometry* newGeometry = 0;
|
||||
splitFunctionReturn = select_it->geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
|
||||
splitFunctionReturn = feat.geometry()->splitGeometry( splitLine, newGeometries, topologicalEditing, topologyTestPoints );
|
||||
if ( splitFunctionReturn == 0 )
|
||||
{
|
||||
//change this geometry
|
||||
L->editBuffer()->changeGeometry( select_it->id(), select_it->geometry() );
|
||||
L->editBuffer()->changeGeometry( feat.id(), feat.geometry() );
|
||||
|
||||
//insert new features
|
||||
for ( int i = 0; i < newGeometries.size(); ++i )
|
||||
@ -275,7 +271,7 @@ int QgsVectorLayerEditUtils::splitFeatures( const QList<QgsPoint>& splitLine, bo
|
||||
|
||||
//use default value where possible for primary key (e.g. autoincrement),
|
||||
//and use the value from the original (split) feature if not primary key
|
||||
QgsAttributes newAttributes = select_it->attributes();
|
||||
QgsAttributes newAttributes = feat.attributes();
|
||||
foreach ( int pkIdx, L->dataProvider()->pkAttributeIndexes() )
|
||||
{
|
||||
const QVariant defaultValue = L->dataProvider()->defaultValue( pkIdx );
|
||||
@ -335,12 +331,11 @@ int QgsVectorLayerEditUtils::splitParts( const QList<QgsPoint>& splitLine, bool
|
||||
int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
|
||||
int numberOfSplittedParts = 0;
|
||||
|
||||
QgsFeatureList featureList;
|
||||
const QgsFeatureIds selectedIds = L->selectedFeaturesIds();
|
||||
QgsFeatureIterator fit;
|
||||
|
||||
if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection
|
||||
if ( L->selectedFeatureCount() > 0 ) //consider only the selected features if there is a selection
|
||||
{
|
||||
featureList = L->selectedFeatures();
|
||||
fit = L->selectedFeaturesIterator();
|
||||
}
|
||||
else //else consider all the feature that intersect the bounding box of the split line
|
||||
{
|
||||
@ -380,15 +375,13 @@ int QgsVectorLayerEditUtils::splitParts( const QList<QgsPoint>& splitLine, bool
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
|
||||
|
||||
QgsFeature f;
|
||||
while ( fit.nextFeature( f ) )
|
||||
featureList << QgsFeature( f );
|
||||
fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
|
||||
}
|
||||
|
||||
int addPartRet = 0;
|
||||
foreach ( const QgsFeature& feat, featureList )
|
||||
|
||||
QgsFeature feat;
|
||||
while ( fit.nextFeature( feat ) )
|
||||
{
|
||||
QList<QgsGeometry*> newGeometries;
|
||||
QList<QgsPoint> topologyTestPoints;
|
||||
@ -448,7 +441,7 @@ int QgsVectorLayerEditUtils::splitParts( const QList<QgsPoint>& splitLine, bool
|
||||
qDeleteAll( newGeometries );
|
||||
}
|
||||
|
||||
if ( numberOfSplittedParts == 0 && selectedIds.size() > 0 && returnCode == 0 )
|
||||
if ( numberOfSplittedParts == 0 && L->selectedFeatureCount() > 0 && returnCode == 0 )
|
||||
{
|
||||
//There is a selection but no feature has been split.
|
||||
//Maybe user forgot that only the selected features are split
|
||||
|
@ -28,49 +28,19 @@ QgsReaderFeatures::QgsReaderFeatures( QgsVectorLayer *layer, bool useSelection )
|
||||
|
||||
} // QgsReaderFeatures::QgsReaderFeatures(QgsVectorLayer *layer, bool useSelection)
|
||||
|
||||
QgsReaderFeatures::~QgsReaderFeatures()
|
||||
{
|
||||
if ( mListSelectedFeature.count() > 0 )
|
||||
{
|
||||
mListSelectedFeature.clear();
|
||||
}
|
||||
|
||||
} // QgsReaderFeatures::~QgsReaderFeatures()
|
||||
|
||||
bool QgsReaderFeatures::nextFeature( QgsFeature & feature )
|
||||
{
|
||||
return ( this->*mFuncNextFeature )( feature );
|
||||
|
||||
return mFit.nextFeature( feature );
|
||||
} // bool QgsReaderFeatures::nextFeature(QgsFeature & feature)
|
||||
|
||||
void QgsReaderFeatures::initReader( bool useSelection )
|
||||
{
|
||||
if ( useSelection )
|
||||
{
|
||||
mListSelectedFeature = mLayer->selectedFeatures();
|
||||
mIterSelectedFeature = mListSelectedFeature.begin();
|
||||
mFuncNextFeature = &QgsReaderFeatures::nextFeatureSelected;
|
||||
mFit = mLayer->selectedFeaturesIterator( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
mFit = mLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() ) );
|
||||
mFuncNextFeature = &QgsReaderFeatures::nextFeatureTotal;
|
||||
}
|
||||
|
||||
} // void QgsReaderFeatures::initReader()
|
||||
|
||||
bool QgsReaderFeatures::nextFeatureTotal( QgsFeature & feature )
|
||||
{
|
||||
return mFit.nextFeature( feature );
|
||||
} // bool QgsReaderFeatures::nextFeatureTotal ( QgsFeature & feature )
|
||||
|
||||
bool QgsReaderFeatures::nextFeatureSelected( QgsFeature & feature )
|
||||
{
|
||||
if ( mIterSelectedFeature == mListSelectedFeature.end() )
|
||||
return false;
|
||||
|
||||
feature = *mIterSelectedFeature;
|
||||
++mIterSelectedFeature;
|
||||
|
||||
return true;
|
||||
} // bool QgsReaderFeatures::nextFeatureSelected( QgsFeature &feature )
|
||||
|
@ -35,11 +35,6 @@ class QgsReaderFeatures
|
||||
*/
|
||||
QgsReaderFeatures( QgsVectorLayer *layer, bool useSelection );
|
||||
|
||||
/**
|
||||
* \brief Destructor
|
||||
*/
|
||||
~QgsReaderFeatures();
|
||||
|
||||
/**
|
||||
* \brief Next feature
|
||||
* \param feature reference to next Feature.
|
||||
@ -54,24 +49,7 @@ class QgsReaderFeatures
|
||||
*/
|
||||
void initReader( bool useSelection );
|
||||
|
||||
/**
|
||||
* \brief Next feature, not using the features selected
|
||||
* \param feature reference to next Feature.
|
||||
* \returns True if has next feature.
|
||||
*/
|
||||
bool nextFeatureTotal( QgsFeature & feature );
|
||||
|
||||
/**
|
||||
* \brief Next feature, using the features selected
|
||||
* \param feature reference to next Feature.
|
||||
* \returns True if has next feature.
|
||||
*/
|
||||
bool nextFeatureSelected( QgsFeature & feature );
|
||||
|
||||
QgsVectorLayer * mLayer;
|
||||
QgsFeatureList mListSelectedFeature;
|
||||
QList<QgsFeature>::iterator mIterSelectedFeature;
|
||||
bool ( QgsReaderFeatures::* mFuncNextFeature )( QgsFeature & );
|
||||
QgsFeatureIterator mFit;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user