sipify QgsVectorLayerFeatureIterator

This commit is contained in:
Denis Rouzaud 2017-05-23 09:34:27 +02:00
parent 8d2f42af2d
commit a14ad32b67
9 changed files with 237 additions and 141 deletions

View File

@ -13,4 +13,4 @@
# #
###########################################################################
pip install autopep8
pip install autopep8

View File

@ -41,15 +41,13 @@ matrix:
- os: linux
language: python # This lets us use newer python versions from virtualenv
language: python
env:
- TRAVIS_CONFIG=code_layout
dist: trusty
sudo: false
cache:
apt: true
#compiler: clang
#python: "3.3"
addons:
apt:
sources:
@ -59,10 +57,11 @@ matrix:
- xvfb
- flip
# used for spell checks
- perl # lookahead regex in spell check script
- perl # sipify, lookahead regex in spell check script
- silversearcher-ag
- expect-dev # unbuffer
- coreutils
- libyaml-tiny-perl
# OSX based build with QT4 and Python 2
- os: osx
osx_image: xcode8.3 # MacOS 10.12: Sierra

View File

@ -2,7 +2,6 @@ core/conversions.sip
core/qgsexception.sip
core/qgis.sip
core/qgsrange.sip
core/qgsvectorlayerfeatureiterator.sip
core/composer/qgsaddremoveitemcommand.sip
core/composer/qgsgroupungroupitemscommand.sip
core/composer/qgsaddremovemultiframecommand.sip

View File

@ -8,6 +8,8 @@
class QgsAbstractFeatureIterator
{
%Docstring
@ -123,6 +125,33 @@ Setup the simplification of geometries to fetch using the specified simplify met
};
template<T>
class QgsAbstractFeatureIteratorFromSource : QgsAbstractFeatureIterator
{
%Docstring
Helper template that cares of two things: 1. automatic deletion of source if owned by iterator, 2. notification of open/closed iterator.
.. note::
not available in Python bindings (although present in SIP file)
%End
%TypeHeaderCode
#include "qgsfeatureiterator.h"
%End
public:
QgsAbstractFeatureIteratorFromSource( T *source, bool ownSource, const QgsFeatureRequest &request );
~QgsAbstractFeatureIteratorFromSource();
protected:
void iteratorClosed();
%Docstring
to be called by from subclass in close()
%End
};
class QgsFeatureIterator
{
%Docstring
@ -196,6 +225,9 @@ find out whether the iterator is still valid or closed already
%End
protected:
};

View File

@ -1,93 +1,147 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsvectorlayerfeatureiterator.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
// abstract feature iterator implementations are not part of public API
%ModuleHeaderCode
#include "qgsfeatureiterator.h"
%End
class QgsVectorLayerFeatureSource : QgsAbstractFeatureSource
{
%Docstring
Partial snapshot of vector layer's state (only the members necessary for access to features)
%End
%TypeHeaderCode
#include <qgsvectorlayerfeatureiterator.h>
#include "qgsvectorlayerfeatureiterator.h"
%End
public:
/** Constructor for QgsVectorLayerFeatureSource.
* \param layer source layer
*/
explicit QgsVectorLayerFeatureSource( const QgsVectorLayer *layer );
%Docstring
Constructor for QgsVectorLayerFeatureSource.
\param layer source layer
%End
~QgsVectorLayerFeatureSource();
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() );
QgsFields fields();
};
class QgsVectorLayerFeatureIterator : QgsAbstractFeatureIterator
{
%TypeHeaderCode
#include <qgsvectorlayerfeatureiterator.h>
QgsFields fields() const;
%Docstring
Returns the fields that will be available for features that are retrieved from
this source.
.. versionadded:: 3.0
:rtype: QgsFields
%End
public:
~QgsVectorLayerFeatureIterator();
//! reset the iterator to the starting position
virtual bool rewind();
//! end of iterating: free the resources / lock
virtual bool close();
protected:
//! fetch next feature, return true on success
};
typedef QgsAbstractFeatureIteratorFromSource<QgsVectorLayerFeatureSource> QgsAbstractFeatureIteratorFromSourceQgsVectorLayerFeatureSourceBase;
class QgsVectorLayerFeatureIterator : QgsAbstractFeatureIteratorFromSourceQgsVectorLayerFeatureSourceBase
{
%TypeHeaderCode
#include "qgsvectorlayerfeatureiterator.h"
#include "qgsfeatureiterator.h"
typedef QgsAbstractFeatureIteratorFromSource<QgsVectorLayerFeatureSource> QgsAbstractFeatureIteratorFromSourceQgsVectorLayerFeatureSourceBase;
%End
public:
QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource *source, bool ownSource, const QgsFeatureRequest &request );
~QgsVectorLayerFeatureIterator();
virtual bool rewind();
%Docstring
reset the iterator to the starting position
:rtype: bool
%End
virtual bool close();
%Docstring
end of iterating: free the resources / lock
:rtype: bool
%End
struct FetchJoinInfo
{
const QgsVectorLayerJoinInfo *joinInfo;//!< Canonical source of information about the join
QgsAttributeList attributes; //!< Attributes to fetch
int indexOffset; //!< At what position the joined fields start
QgsVectorLayer *joinLayer; //!< Resolved pointer to the joined layer
int targetField; //!< Index of field (of this layer) that drives the join
int joinField; //!< Index of field (of the joined layer) must have equal value
void addJoinedAttributesCached( QgsFeature &f, const QVariant &joinValue ) const;
void addJoinedAttributesDirect( QgsFeature &f, const QVariant &joinValue ) const;
};
protected:
virtual bool fetchFeature( QgsFeature &feature );
%Docstring
fetch next feature, return true on success
:rtype: bool
%End
//! Overrides default method as we only need to filter features in the edit buffer
//! while for others filtering is left to the provider implementation.
virtual bool nextFeatureFilterExpression( QgsFeature &f );
%Docstring
while for others filtering is left to the provider implementation.
:rtype: bool
%End
//! Setup the simplification of geometries to fetch using the specified simplify method
virtual bool prepareSimplification( const QgsSimplifyMethod &simplifyMethod );
%Docstring
Setup the simplification of geometries to fetch using the specified simplify method
:rtype: bool
%End
//! @note not available in Python bindings
//void rewindEditBuffer();
//! @note not available in Python bindings
//void prepareJoins();
//! @note not available in Python bindings
//void prepareExpressions();
//! @note not available in Python bindings
//bool fetchNextAddedFeature( QgsFeature &f );
//! @note not available in Python bindings
//bool fetchNextChangedGeomFeature( QgsFeature &f );
//! @note not available in Python bindings
//bool fetchNextChangedAttributeFeature( QgsFeature &f );
//! @note not available in Python bindings
//void useAddedFeature( const QgsFeature &src, QgsFeature &f );
//! @note not available in Python bindings
//void useChangedAttributeFeature( QgsFeatureId fid, const QgsGeometry &geom, QgsFeature &f );
//! @note not available in Python bindings
//bool nextFeatureFid( QgsFeature &f );
//! @note not available in Python bindings
//void addJoinedAttributes( QgsFeature &f );
/**
* Adds attributes that don't source from the provider but are added inside QGIS
* Includes
* - Joined fields
* - Expression fields
*
* @param f The feature will be modified
* @note not available in Python bindings
*/
//void addVirtualAttributes( QgsFeature &f );
/** Update feature with uncommitted attribute updates.
* @note not available in Python bindings
*/
//void updateChangedAttributes( QgsFeature &f );
/** Update feature with uncommitted geometry updates.
* @note not available in Python bindings
*/
//void updateFeatureGeometry( QgsFeature &f );
private:
QgsVectorLayerFeatureIterator( const QgsVectorLayerFeatureIterator &rhs );
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsvectorlayerfeatureiterator.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -2,7 +2,9 @@
use strict;
use warnings;
use File::Basename;
use File::Spec;
use Getopt::Long;
use YAML::Tiny;
no if $] >= 5.018000, warnings => 'experimental::smartmatch';
use constant PRIVATE => 0;
@ -17,41 +19,16 @@ my $debug = 0;
die("usage: $0 [-debug] headerfile\n") unless GetOptions ("debug" => \$debug) && @ARGV == 1;
my $headerfile = $ARGV[0];
sub processDoxygenLine
{
my $line = $_[0];
# remove \a formatting
$line =~ s/\\a (.+?)\b/``$1``/g;
# replace :: with . (changes c++ style namespace/class directives to Python style)
$line =~ s/::/./g;
# replace nullptr with None (nullptr means nothing to Python devs)
$line =~ s/\bnullptr\b/None/g;
# replace \returns with :return:
$line =~ s/\\return(s)?/:return:/g;
if ( $line =~ m/[\\@](ingroup|class)/ ) {
return ""
}
if ( $line =~ m/\\since .*?([\d\.]+)/i ) {
return ".. versionadded:: $1\n";
}
if ( $line =~ m/\\see (.*)/ ) {
return ".. seealso:: $1\n";
}
if ( $line =~ m/[\\@]note (.*)/ ) {
return ".. note::\n\n $1\n";
}
if ( $line =~ m/[\\@]brief (.*)/ ) {
return " $1\n";
}
return "$line\n";
}
# read file
open(my $handle, "<", $headerfile) || die "Couldn't open '".$headerfile."' for reading because: ".$!;
chomp(my @lines = <$handle>);
close $handle;
# config
my $cfg_file = File::Spec->catfile( dirname(__FILE__), 'sipify.yaml' );
my $yaml = YAML::Tiny->read( $cfg_file );
my $SIP_CONFIG = $yaml->[0];
# contexts
my $SIP_RUN = 0;
my $HEADER_CODE = 0;
@ -97,6 +74,36 @@ sub dbg_info
}
}
sub processDoxygenLine
{
my $line = $_[0];
# remove \a formatting
$line =~ s/\\a (.+?)\b/``$1``/g;
# replace :: with . (changes c++ style namespace/class directives to Python style)
$line =~ s/::/./g;
# replace nullptr with None (nullptr means nothing to Python devs)
$line =~ s/\bnullptr\b/None/g;
# replace \returns with :return:
$line =~ s/\\return(s)?/:return:/g;
if ( $line =~ m/[\\@](ingroup|class)/ ) {
return ""
}
if ( $line =~ m/\\since .*?([\d\.]+)/i ) {
return ".. versionadded:: $1\n";
}
if ( $line =~ m/\\see (.*)/ ) {
return ".. seealso:: $1\n";
}
if ( $line =~ m/[\\@]note (.*)/ ) {
return ".. note::\n\n $1\n";
}
if ( $line =~ m/[\\@]brief (.*)/ ) {
return " $1\n";
}
return "$line\n";
}
sub detect_and_remove_following_body_or_initializerlist {
# https://regex101.com/r/ZaP3tC/6
do {no warnings 'uninitialized';
@ -441,8 +448,12 @@ while ($line_idx < $line_count){
while (@template_inheritance_template) {
my $tpl = pop @template_inheritance_template;
my $cls = pop @template_inheritance_class;
my $tpl_header = lc $tpl . ".h";
if (exists $SIP_CONFIG->{class_headerfile}->{$tpl}){
$tpl_header = $SIP_CONFIG->{class_headerfile}->{$tpl};
}
$line = "\ntypedef $tpl<$cls> ${tpl}${cls}Base;\n\n$line";
$line .= "\n#include \"" . lc $tpl . ".h\"";
$line .= "\n#include \"" . $tpl_header . "\"";
$line .= "\ntypedef $tpl<$cls> ${tpl}${cls}Base;";
}
if ( PRIVATE ~~ @ACCESS && $#ACCESS != 0){

4
scripts/sipify.yaml Normal file
View File

@ -0,0 +1,4 @@
class_headerfile:
QgsAbstractFeatureIteratorFromSource: qgsfeatureiterator.h

View File

@ -19,7 +19,7 @@
#include "qgsfeaturerequest.h"
#include "qgsindexedfeature.h"
#ifndef SIP_RUN
/** \ingroup core
* Interface that can be optionally attached to an iterator so its
@ -27,15 +27,13 @@
* \since QGIS 2.16
* \note not available in Python bindings
*/
class CORE_EXPORT QgsInterruptionChecker
class CORE_EXPORT QgsInterruptionChecker SIP_SKIP
{
public:
//! return true if the iterator must stop as soon as possible
virtual bool mustStop() const = 0;
};
#endif
/** \ingroup core
* Internal feature iterator to be implemented within data providers
*/
@ -65,8 +63,6 @@ class CORE_EXPORT QgsAbstractFeatureIterator
//! end of iterating: free the resources / lock
virtual bool close() = 0;
#ifndef SIP_RUN
/** Attach an object that can be queried regularly by the iterator to check
* if it must stopped. This is mostly useful for iterators where a single
* nextFeature()/fetchFeature() iteration might be very long. A typical use case is the
@ -75,8 +71,7 @@ class CORE_EXPORT QgsAbstractFeatureIterator
* \since QGIS 2.16
* \note not available in Python bindings
*/
virtual void setInterruptionChecker( QgsInterruptionChecker *interruptionChecker );
#endif
virtual void setInterruptionChecker( QgsInterruptionChecker *interruptionChecker ) SIP_SKIP;
/** Returns the status of expression compilation for filter expression requests.
* \since QGIS 2.16
@ -179,14 +174,13 @@ class CORE_EXPORT QgsAbstractFeatureIterator
void setupOrderBy( const QList<QgsFeatureRequest::OrderByClause> &orderBys );
};
#ifndef SIP_RUN
/** \ingroup core
* Helper template that cares of two things: 1. automatic deletion of source if owned by iterator, 2. notification of open/closed iterator.
* \note not available in Python bindings
* \note not available in Python bindings (although present in SIP file)
*/
template<typename T>
class QgsAbstractFeatureIteratorFromSource : public QgsAbstractFeatureIterator
class CORE_EXPORT QgsAbstractFeatureIteratorFromSource : public QgsAbstractFeatureIterator
{
public:
QgsAbstractFeatureIteratorFromSource( T *source, bool ownSource, const QgsFeatureRequest &request )
@ -211,7 +205,6 @@ class QgsAbstractFeatureIteratorFromSource : public QgsAbstractFeatureIterator
bool mOwnSource;
};
#endif
/**
* \ingroup core
@ -260,8 +253,6 @@ class CORE_EXPORT QgsFeatureIterator
//! find out whether the iterator is still valid or closed already
bool isClosed() const;
#ifndef SIP_RUN
/** Attach an object that can be queried regularly by the iterator to check
* if it must stopped. This is mostly useful for iterators where a single
* nextFeature()/fetchFeature() iteration might be very long. A typical use case is the
@ -269,24 +260,19 @@ class CORE_EXPORT QgsFeatureIterator
* \since QGIS 2.16
* \note not available in Python bindings
*/
void setInterruptionChecker( QgsInterruptionChecker *interruptionChecker );
#endif
void setInterruptionChecker( QgsInterruptionChecker *interruptionChecker ) SIP_SKIP;
/** Returns the status of expression compilation for filter expression requests.
* \since QGIS 2.16
*/
QgsAbstractFeatureIterator::CompileStatus compileStatus() const { return mIter->compileStatus(); }
#ifndef SIP_RUN
friend bool operator== ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 );
friend bool operator!= ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 );
friend bool operator== ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 ) SIP_SKIP;
friend bool operator!= ( const QgsFeatureIterator &fi1, const QgsFeatureIterator &fi2 ) SIP_SKIP;
protected:
QgsAbstractFeatureIterator *mIter = nullptr;
#endif
};

View File

@ -24,7 +24,7 @@
#include <QSet>
#include <memory>
typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap;
typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap SIP_SKIP;
class QgsExpressionFieldBuffer;
class QgsVectorLayer;
@ -35,6 +35,12 @@ class QgsExpressionContext;
class QgsVectorLayerFeatureIterator;
#ifdef SIP_RUN
% ModuleHeaderCode
#include "qgsfeatureiterator.h"
% End
#endif
/** \ingroup core
* Partial snapshot of vector layer's state (only the members necessary for access to features)
*/
@ -51,7 +57,7 @@ class CORE_EXPORT QgsVectorLayerFeatureSource : public QgsAbstractFeatureSource
virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest &request = QgsFeatureRequest() ) override;
friend class QgsVectorLayerFeatureIterator;
friend class QgsVectorLayerFeatureIterator SIP_SKIP;
/**
* Returns the fields that will be available for features that are retrieved from
@ -101,7 +107,24 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
//! end of iterating: free the resources / lock
virtual bool close() override;
virtual void setInterruptionChecker( QgsInterruptionChecker *interruptionChecker ) override;
virtual void setInterruptionChecker( QgsInterruptionChecker *interruptionChecker ) override SIP_SKIP;
/** Join information prepared for fast attribute id mapping in QgsVectorLayerJoinBuffer::updateFeatureAttributes().
* Created in the select() method of QgsVectorLayerJoinBuffer for the joins that contain fetched attributes
*/
struct FetchJoinInfo
{
const QgsVectorLayerJoinInfo *joinInfo;//!< Canonical source of information about the join
QgsAttributeList attributes; //!< Attributes to fetch
int indexOffset; //!< At what position the joined fields start
QgsVectorLayer *joinLayer; //!< Resolved pointer to the joined layer
int targetField; //!< Index of field (of this layer) that drives the join
int joinField; //!< Index of field (of the joined layer) must have equal value
void addJoinedAttributesCached( QgsFeature &f, const QVariant &joinValue ) const;
void addJoinedAttributesDirect( QgsFeature &f, const QVariant &joinValue ) const;
};
protected:
//! fetch next feature, return true on success
@ -173,22 +196,6 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
*/
void updateFeatureGeometry( QgsFeature &f ) SIP_SKIP;
/** Join information prepared for fast attribute id mapping in QgsVectorLayerJoinBuffer::updateFeatureAttributes().
* Created in the select() method of QgsVectorLayerJoinBuffer for the joins that contain fetched attributes
*/
struct FetchJoinInfo
{
const QgsVectorLayerJoinInfo *joinInfo;//!< Canonical source of information about the join
QgsAttributeList attributes; //!< Attributes to fetch
int indexOffset; //!< At what position the joined fields start
QgsVectorLayer *joinLayer; //!< Resolved pointer to the joined layer
int targetField; //!< Index of field (of this layer) that drives the join
int joinField; //!< Index of field (of the joined layer) must have equal value
void addJoinedAttributesCached( QgsFeature &f, const QVariant &joinValue ) const;
void addJoinedAttributesDirect( QgsFeature &f, const QVariant &joinValue ) const;
};
QgsFeatureRequest mProviderRequest;
QgsFeatureIterator mProviderIterator;
QgsFeatureRequest mChangedFeaturesRequest;
@ -203,13 +210,17 @@ class CORE_EXPORT QgsVectorLayerFeatureIterator : public QgsAbstractFeatureItera
/** Information about joins used in the current select() statement.
Allows faster mapping of attribute ids compared to mVectorJoins */
QMap<const QgsVectorLayerJoinInfo *, FetchJoinInfo> mFetchJoinInfo;
QMap<const QgsVectorLayerJoinInfo *, QgsVectorLayerFeatureIterator::FetchJoinInfo> mFetchJoinInfo;
QMap<int, QgsExpression *> mExpressionFieldInfo;
bool mHasVirtualAttributes;
private:
#ifdef SIP_RUN
QgsVectorLayerFeatureIterator( const QgsVectorLayerFeatureIterator &rhs );
#endif
std::unique_ptr<QgsExpressionContext> mExpressionContext;
QgsInterruptionChecker *mInterruptionChecker = nullptr;