Skip to content

Commit

Permalink
Merge pull request #4416 from nyalldawson/feature_sink
Browse files Browse the repository at this point in the history
Add a QgsFeatureSink interface
  • Loading branch information
nyalldawson committed Apr 26, 2017
2 parents 13b4472 + 4293de6 commit 16cb244
Show file tree
Hide file tree
Showing 30 changed files with 414 additions and 108 deletions.
2 changes: 2 additions & 0 deletions doc/api_break.dox
Expand Up @@ -2113,6 +2113,8 @@ displayExpression instead. For the map tip use mapTipTemplate() instead.
- snapPoint() has been removed - use QgsPointLocator class instead.
- snapWithContext() has been removed - use QgsPointLocator class instead.
- insertSegmentVerticesForSnap() has been removed - use addTopologicalPoints() directly.
- addFeature() no longer accepts an alsoUpdateExtent boolean - this extra argument has been ignored for some time
- addFeatures() no longer accepts a makeSelected boolean, and will not automatically select newly added features. If desired, features must be manually selected by calling selectByIds() after addFeatures()


QgsVectorLayerEditBuffer {#qgis_api_break_3_0_QgsVectorLayerEditBuffer}
Expand Down
1 change: 0 additions & 1 deletion python/auto_sip.blacklist
Expand Up @@ -117,7 +117,6 @@ core/qgsvectorsimplifymethod.sip
core/qgscachedfeatureiterator.sip
core/qgscacheindex.sip
core/qgscacheindexfeatureid.sip
core/qgsfeaturestore.sip
core/qgsgeometrycache.sip
core/qgslayerdefinition.sip
core/qgsprojectfiletransform.sip
Expand Down
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -56,6 +56,7 @@
%Include qgsfeaturefilterprovider.sip
%Include qgsfeatureiterator.sip
%Include qgsfeaturerequest.sip
%Include qgsfeaturesink.sip
%Include qgsfeedback.sip
%Include qgsfield.sip
%Include qgsfieldconstraints.sip
Expand Down
58 changes: 58 additions & 0 deletions python/core/qgsfeaturesink.sip
@@ -0,0 +1,58 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturesink.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsFeatureSink
{
%Docstring
An interface for objects which accept features via addFeature(s) methods.

.. versionadded:: 3.0
%End

%TypeHeaderCode
#include "qgsfeaturesink.h"
%End
public:

virtual ~QgsFeatureSink();

virtual bool addFeature( QgsFeature &feature );
%Docstring
Adds a single ``feature`` to the sink.
\see addFeatures()
:return: true in case of success and false in case of failure
:rtype: bool
%End

virtual bool addFeatures( QgsFeatureList &features ) = 0;
%Docstring
Adds a list of ``features`` to the sink.
\see addFeature()
:return: true in case of success and false in case of failure
:rtype: bool
%End

virtual bool addFeatures( QgsFeatureIterator &iterator );
%Docstring
Adds all features from the specified ``iterator`` to the sink.
:return: true if all features were added successfully, or false if any feature could not be added
:rtype: bool
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturesink.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
97 changes: 75 additions & 22 deletions python/core/qgsfeaturestore.sip
@@ -1,39 +1,92 @@
class QgsFeatureStore
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturestore.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/


class QgsFeatureStore : QgsFeatureSink
{
%Docstring
A container for features with the same fields and crs.
%End

%TypeHeaderCode
#include <qgsfeaturestore.h>
#include "qgsfeaturestore.h"
%End
public:
//! Constructor
QgsFeatureStore();
%Docstring
Constructor
%End

//! Constructor
QgsFeatureStore( const QgsFields& fields, const QgsCoordinateReferenceSystem& crs );
QgsFeatureStore( const QgsFields &fields, const QgsCoordinateReferenceSystem &crs );
%Docstring
Constructor
%End

/** Get fields list */
QgsFields& fields();
QgsFields fields() const;
%Docstring
Returns the store's field list.
\see setFields()
:rtype: QgsFields
%End

/** Set fields. Resets feature's fields to pointer to new internal fields. */
void setFields( const QgsFields & fields );
void setFields( const QgsFields &fields );
%Docstring
Sets the store's ``fields``. Every contained feature's fields will be reset to match ``fields``.
\see fields()
%End

/** Get crs */
QgsCoordinateReferenceSystem crs() const;
%Docstring
Returns the store's coordinate reference system.
\see setCrs()
:rtype: QgsCoordinateReferenceSystem
%End

void setCrs( const QgsCoordinateReferenceSystem &crs );
%Docstring
Sets the store's ``crs``.
\see crs()
%End

/** Set crs */
void setCrs( const QgsCoordinateReferenceSystem& crs );
virtual bool addFeature( QgsFeature &feature );

/** Add feature. Feature's fields will be set to pointer to the store fields.
* @param feature
* @note added in 2.1
*/
void addFeature( const QgsFeature& feature );
virtual bool addFeatures( QgsFeatureList &features );

/** Get features list reference */
QgsFeatureList& features();

/** Set map of optional parameters */
void setParams( const QMap<QString, QVariant> &params );
QgsFeatureList features() const;
%Docstring
Returns the list of features contained in the store.
:rtype: QgsFeatureList
%End

void setParams( const QMap<QString, QVariant> &parameters );
%Docstring
Sets a map of optional ``parameters`` for the store.
\see params()
%End

/** Get map of optional parameters */
QMap<QString, QVariant> params() const;
%Docstring
Returns the map of optional parameters.
\see setParams()
:rtype: QMap<str, QVariant>
%End

};

typedef QList<QgsFeatureStore> QgsFeatureStoreList;



/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsfeaturestore.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
6 changes: 1 addition & 5 deletions python/core/qgsvectordataprovider.sip
@@ -1,5 +1,5 @@

class QgsVectorDataProvider : QgsDataProvider
class QgsVectorDataProvider : QgsDataProvider, QgsFeatureSink
{
%TypeHeaderCode
#include <qgsvectordataprovider.h>
Expand Down Expand Up @@ -197,10 +197,6 @@ class QgsVectorDataProvider : QgsDataProvider
*/
virtual void enumValues( int index, QStringList& enumList /Out/ ) const;

/**
* Adds a list of features
* @return true in case of success and false in case of failure
*/
virtual bool addFeatures( QList<QgsFeature> &flist /In,Out/ );

/**
Expand Down
7 changes: 5 additions & 2 deletions python/core/qgsvectorfilewriter.sip
Expand Up @@ -4,7 +4,7 @@
1. static call to QgsVectorFileWriter::writeAsVectorFormat(...) which saves the whole vector layer
2. create an instance of the class and issue calls to addFeature(...)
*/
class QgsVectorFileWriter
class QgsVectorFileWriter : QgsFeatureSink
{
%TypeHeaderCode
#include <qgsvectorfilewriter.h>
Expand Down Expand Up @@ -380,8 +380,11 @@ class QgsVectorFileWriter
/** Retrieves error message */
QString errorMessage();

bool addFeature( QgsFeature &feature );
bool addFeatures( QgsFeatureList &features );

/** Add feature to the currently opened data source */
bool addFeature( QgsFeature& feature, QgsFeatureRenderer* renderer = 0, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );
bool addFeature( QgsFeature& feature, QgsFeatureRenderer* renderer, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );

//! @note not available in python bindings
// QMap<int, int> attrIdxToOgrIdx();
Expand Down
19 changes: 5 additions & 14 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -19,7 +19,7 @@ typedef QList<QgsPointV2> QgsPointSequence;



class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator
class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator, QgsFeatureSink
{
%Docstring
Represents a vector layer which manages a vector based data sets.
Expand Down Expand Up @@ -901,14 +901,8 @@ Return the provider type for this layer
:rtype: QgsFeatureIterator
%End

bool addFeature( QgsFeature &feature, bool alsoUpdateExtent = true );
%Docstring
Adds a feature
\param feature feature to add
\param alsoUpdateExtent If True, will also go to the effort of e.g. updating the extents.
:return: True in case of success and False in case of error
:rtype: bool
%End
virtual bool addFeature( QgsFeature &feature );


bool updateFeature( QgsFeature &f );
%Docstring
Expand Down Expand Up @@ -1256,11 +1250,8 @@ Delete an attribute field (but does not commit it)
:rtype: bool
%End

bool addFeatures( QgsFeatureList features, bool makeSelected = true );
%Docstring
Insert a copy of the given features into the layer (but does not commit it)
:rtype: bool
%End
virtual bool addFeatures( QgsFeatureList &features );


bool deleteFeature( QgsFeatureId fid );
%Docstring
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgisapp.cpp
Expand Up @@ -7632,7 +7632,7 @@ void QgisApp::mergeSelectedFeatures()
vl->deleteFeature( *feature_it );
}

vl->addFeature( newFeature, false );
vl->addFeature( newFeature );

vl->endEditCommand();

Expand Down Expand Up @@ -7934,7 +7934,7 @@ void QgisApp::editPaste( QgsMapLayer *destinationLayer )
// now create new feature using pasted feature as a template. This automatically handles default
// values and field constraints
QgsFeature newFeature = QgsVectorLayerUtils::createFeature( pasteVectorLayer, geom, dstAttr, &context );
pasteVectorLayer->addFeature( newFeature, false );
pasteVectorLayer->addFeature( newFeature );
newIds << newFeature.id();

++featureIt;
Expand Down Expand Up @@ -8131,7 +8131,7 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
feature.setGeometry( g );
}
}
if ( ! layer->addFeatures( features, false ) || !layer->commitChanges() )
if ( ! layer->addFeatures( features ) || !layer->commitChanges() )
{
QgsDebugMsg( "Cannot add features or commit changes" );
delete layer;
Expand Down
3 changes: 2 additions & 1 deletion src/app/qgsidentifyresultsdialog.cpp
Expand Up @@ -1898,7 +1898,8 @@ void QgsIdentifyResultsDialog::copyFeature()
}

QgsFeatureStore featureStore( item->fields(), item->crs() );
featureStore.features().append( item->feature() );
QgsFeature f( item->feature() );
featureStore.addFeature( f );
emit copyToClipboard( featureStore );
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -136,6 +136,7 @@ SET(QGIS_CORE_SRCS
qgsfeature.cpp
qgsfeatureiterator.cpp
qgsfeaturerequest.cpp
qgsfeaturesink.cpp
qgsfeaturestore.cpp
qgsfield.cpp
qgsfieldconstraints.cpp
Expand Down Expand Up @@ -720,6 +721,7 @@ SET(QGIS_CORE_HDRS
qgsfeaturefilterprovider.h
qgsfeatureiterator.h
qgsfeaturerequest.h
qgsfeaturesink.h
qgsfeaturestore.h
qgsfieldformatter.h
qgsfield_p.h
Expand Down
41 changes: 41 additions & 0 deletions src/core/qgsfeaturesink.cpp
@@ -0,0 +1,41 @@
/***************************************************************************
qgsfeaturesink.cpp
------------------
begin : April 2017
copyright : (C) 2017 by Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsfeaturestore.h"

bool QgsFeatureSink::addFeature( QgsFeature &feature )
{
QgsFeatureList features;
features << feature;
bool result = addFeatures( features );

// need to update the passed feature reference to the updated copy from the features list
feature = features.at( 0 );
return result;
}

bool QgsFeatureSink::addFeatures( QgsFeatureIterator &iterator )
{
QgsFeature f;
bool result = true;
while ( iterator.nextFeature( f ) )
{
result = result && addFeature( f );
}
return result;
}

0 comments on commit 16cb244

Please sign in to comment.