32void QgsJoinByLocationSummaryAlgorithm::initAlgorithm( 
const QVariantMap & )
 
   36  auto predicateParam = std::make_unique<QgsProcessingParameterEnum>( QStringLiteral( 
"PREDICATE" ), QObject::tr( 
"Where the features" ), QgsJoinByLocationAlgorithm::translatedPredicates(), 
true, 0 );
 
   37  QVariantMap predicateMetadata;
 
   38  QVariantMap widgetMetadata;
 
   39  widgetMetadata.insert( QStringLiteral( 
"useCheckBoxes" ), 
true );
 
   40  widgetMetadata.insert( QStringLiteral( 
"columns" ), 2 );
 
   41  predicateMetadata.insert( QStringLiteral( 
"widget_wrapper" ), widgetMetadata );
 
   42  predicateParam->setMetadata( predicateMetadata );
 
   43  addParameter( predicateParam.release() );
 
   49  mAllSummaries << QObject::tr( 
"count" )
 
   50                << QObject::tr( 
"unique" )
 
   51                << QObject::tr( 
"min" )
 
   52                << QObject::tr( 
"max" )
 
   53                << QObject::tr( 
"range" )
 
   54                << QObject::tr( 
"sum" )
 
   55                << QObject::tr( 
"mean" )
 
   56                << QObject::tr( 
"median" )
 
   57                << QObject::tr( 
"stddev" )
 
   58                << QObject::tr( 
"minority" )
 
   59                << QObject::tr( 
"majority" )
 
   60                << QObject::tr( 
"q1" )
 
   61                << QObject::tr( 
"q3" )
 
   62                << QObject::tr( 
"iqr" )
 
   63                << QObject::tr( 
"empty" )
 
   64                << QObject::tr( 
"filled" )
 
   65                << QObject::tr( 
"min_length" )
 
   66                << QObject::tr( 
"max_length" )
 
   67                << QObject::tr( 
"mean_length" );
 
   69  auto summaryParam = std::make_unique<QgsProcessingParameterEnum>( QStringLiteral( 
"SUMMARIES" ), QObject::tr( 
"Summaries to calculate (leave empty to use all available)" ), mAllSummaries, 
true, QVariant(), 
true );
 
   70  addParameter( summaryParam.release() );
 
   72  addParameter( 
new QgsProcessingParameterBoolean( QStringLiteral( 
"DISCARD_NONMATCHING" ), QObject::tr( 
"Discard records which could not be joined" ), 
false ) );
 
   76QString QgsJoinByLocationSummaryAlgorithm::name()
 const 
   78  return QStringLiteral( 
"joinbylocationsummary" );
 
   81QString QgsJoinByLocationSummaryAlgorithm::displayName()
 const 
   83  return QObject::tr( 
"Join attributes by location (summary)" );
 
   86QStringList QgsJoinByLocationSummaryAlgorithm::tags()
 const 
   88  return QObject::tr( 
"summary,aggregate,join,intersects,intersecting,touching,within,contains,overlaps,relation,spatial," 
   89                      "stats,statistics,sum,maximum,minimum,mean,average,standard,deviation," 
   90                      "count,distinct,unique,variance,median,quartile,range,majority,minority,histogram,distinct" )
 
   94QString QgsJoinByLocationSummaryAlgorithm::group()
 const 
   96  return QObject::tr( 
"Vector general" );
 
   99QString QgsJoinByLocationSummaryAlgorithm::groupId()
 const 
  101  return QStringLiteral( 
"vectorgeneral" );
 
  104QString QgsJoinByLocationSummaryAlgorithm::shortHelpString()
 const 
  106  return QObject::tr( 
"This algorithm takes an input vector layer and creates a new vector layer that is an extended version of the input one, with additional attributes in its attribute table.\n\n" 
  107                      "The additional attributes and their values are taken from a second vector layer. A spatial criteria is applied to select the values from the second layer that are added to each feature from the first layer in the resulting one.\n\n" 
  108                      "The algorithm calculates a statistical summary for the values from matching features in the second layer( e.g. maximum value, mean value, etc )." );
 
  111QString QgsJoinByLocationSummaryAlgorithm::shortDescription()
 const 
  113  return QObject::tr( 
"Calculates summaries of attributes from one vector layer to another by location." );
 
  116QIcon QgsJoinByLocationSummaryAlgorithm::icon()
 const 
  121QString QgsJoinByLocationSummaryAlgorithm::svgIconPath()
 const 
  126QgsJoinByLocationSummaryAlgorithm *QgsJoinByLocationSummaryAlgorithm::createInstance()
 const 
  128  return new QgsJoinByLocationSummaryAlgorithm();
 
  133  std::unique_ptr<QgsProcessingFeatureSource> baseSource( parameterAsSource( parameters, QStringLiteral( 
"INPUT" ), context ) );
 
  137  std::unique_ptr<QgsProcessingFeatureSource> joinSource( parameterAsSource( parameters, QStringLiteral( 
"JOIN" ), context ) );
 
  142    feedback->
reportError( QObject::tr( 
"No spatial index exists for join layer, performance will be severely degraded" ) );
 
  144  QStringList joinedFieldNames = parameterAsStrings( parameters, QStringLiteral( 
"JOIN_FIELDS" ), context );
 
  146  bool discardNonMatching = parameterAsBoolean( parameters, QStringLiteral( 
"DISCARD_NONMATCHING" ), context );
 
  148  QList<int> summaries = parameterAsEnums( parameters, QStringLiteral( 
"SUMMARIES" ), context );
 
  149  if ( summaries.empty() )
 
  151    for ( 
int i = 0; i < mAllSummaries.size(); ++i )
 
  155  QgsFields sourceFields = baseSource->fields();
 
  157  QList<int> joinFieldIndices;
 
  158  if ( joinedFieldNames.empty() )
 
  161    for ( 
const QgsField &sourceField : joinSource->fields() )
 
  163      joinedFieldNames.
append( sourceField.name() );
 
  168  auto addFieldKeepType = [&fieldsToJoin]( 
const QgsField &original, 
const QString &statistic ) {
 
  171    fieldsToJoin.
append( field );
 
  175  auto addFieldWithType = [&fieldsToJoin]( 
const QgsField &original, 
const QString &statistic, QMetaType::Type type ) {
 
  179    if ( type == QMetaType::Type::Double )
 
  184    fieldsToJoin.
append( field );
 
  193  QList<FieldType> fieldTypes;
 
  195  struct FieldStatistic
 
  197      FieldStatistic( 
int enumIndex, 
const QString &name, QMetaType::Type type )
 
  198        : enumIndex( enumIndex )
 
  205      QMetaType::Type type;
 
  207  static const QVector<FieldStatistic> sNumericStats {
 
  208    FieldStatistic( 0, QStringLiteral( 
"count" ), QMetaType::Type::LongLong ),
 
  209    FieldStatistic( 1, QStringLiteral( 
"unique" ), QMetaType::Type::LongLong ),
 
  210    FieldStatistic( 2, QStringLiteral( 
"min" ), QMetaType::Type::Double ),
 
  211    FieldStatistic( 3, QStringLiteral( 
"max" ), QMetaType::Type::Double ),
 
  212    FieldStatistic( 4, QStringLiteral( 
"range" ), QMetaType::Type::Double ),
 
  213    FieldStatistic( 5, QStringLiteral( 
"sum" ), QMetaType::Type::Double ),
 
  214    FieldStatistic( 6, QStringLiteral( 
"mean" ), QMetaType::Type::Double ),
 
  215    FieldStatistic( 7, QStringLiteral( 
"median" ), QMetaType::Type::Double ),
 
  216    FieldStatistic( 8, QStringLiteral( 
"stddev" ), QMetaType::Type::Double ),
 
  217    FieldStatistic( 9, QStringLiteral( 
"minority" ), QMetaType::Type::Double ),
 
  218    FieldStatistic( 10, QStringLiteral( 
"majority" ), QMetaType::Type::Double ),
 
  219    FieldStatistic( 11, QStringLiteral( 
"q1" ), QMetaType::Type::Double ),
 
  220    FieldStatistic( 12, QStringLiteral( 
"q3" ), QMetaType::Type::Double ),
 
  221    FieldStatistic( 13, QStringLiteral( 
"iqr" ), QMetaType::Type::Double ),
 
  223  static const QVector<FieldStatistic> sDateTimeStats {
 
  224    FieldStatistic( 0, QStringLiteral( 
"count" ), QMetaType::Type::LongLong ),
 
  225    FieldStatistic( 1, QStringLiteral( 
"unique" ), QMetaType::Type::LongLong ),
 
  226    FieldStatistic( 14, QStringLiteral( 
"empty" ), QMetaType::Type::LongLong ),
 
  227    FieldStatistic( 15, QStringLiteral( 
"filled" ), QMetaType::Type::LongLong ),
 
  228    FieldStatistic( 2, QStringLiteral( 
"min" ), QMetaType::Type::UnknownType ),
 
  229    FieldStatistic( 3, QStringLiteral( 
"max" ), QMetaType::Type::UnknownType ),
 
  231  static const QVector<FieldStatistic> sStringStats {
 
  232    FieldStatistic( 0, QStringLiteral( 
"count" ), QMetaType::Type::LongLong ),
 
  233    FieldStatistic( 1, QStringLiteral( 
"unique" ), QMetaType::Type::LongLong ),
 
  234    FieldStatistic( 14, QStringLiteral( 
"empty" ), QMetaType::Type::LongLong ),
 
  235    FieldStatistic( 15, QStringLiteral( 
"filled" ), QMetaType::Type::LongLong ),
 
  236    FieldStatistic( 2, QStringLiteral( 
"min" ), QMetaType::Type::UnknownType ),
 
  237    FieldStatistic( 3, QStringLiteral( 
"max" ), QMetaType::Type::UnknownType ),
 
  238    FieldStatistic( 16, QStringLiteral( 
"min_length" ), QMetaType::Type::Int ),
 
  239    FieldStatistic( 17, QStringLiteral( 
"max_length" ), QMetaType::Type::Int ),
 
  240    FieldStatistic( 18, QStringLiteral( 
"mean_length" ), QMetaType::Type::Double ),
 
  243  for ( 
const QString &field : std::as_const( joinedFieldNames ) )
 
  245    const int fieldIndex = joinSource->fields().lookupField( field );
 
  246    if ( fieldIndex >= 0 )
 
  248      joinFieldIndices.append( fieldIndex );
 
  250      const QgsField joinField = joinSource->fields().at( fieldIndex );
 
  251      QVector<FieldStatistic> statisticList;
 
  254        fieldTypes.append( FieldType::Numeric );
 
  255        statisticList = sNumericStats;
 
  257      else if ( joinField.
type() == QMetaType::Type::QDate
 
  258                || joinField.
type() == QMetaType::Type::QTime
 
  259                || joinField.
type() == QMetaType::Type::QDateTime )
 
  261        fieldTypes.append( FieldType::DateTime );
 
  262        statisticList = sDateTimeStats;
 
  266        fieldTypes.append( FieldType::String );
 
  267        statisticList = sStringStats;
 
  270      for ( 
const FieldStatistic &statistic : std::as_const( statisticList ) )
 
  272        if ( summaries.contains( statistic.enumIndex ) )
 
  274          if ( statistic.type != QMetaType::Type::UnknownType )
 
  275            addFieldWithType( joinField, statistic.name, statistic.type );
 
  277            addFieldKeepType( joinField, statistic.name );
 
  286  std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, QStringLiteral( 
"OUTPUT" ), context, destId, outputFields, baseSource->wkbType(), baseSource->sourceCrs() ) );
 
  292  QList<int> predicates = parameterAsEnums( parameters, QStringLiteral( 
"PREDICATE" ), context );
 
  293  QgsJoinByLocationAlgorithm::sortPredicates( predicates );
 
  297  const double step = baseSource->featureCount() > 0 ? 100.0 / baseSource->featureCount() : 1;
 
  306      if ( !discardNonMatching )
 
  318    std::unique_ptr<QgsGeometryEngine> engine;
 
  319    QVector<QVector<QVariant>> values;
 
  336        engine->prepareGeometry();
 
  339      if ( QgsJoinByLocationAlgorithm::featureFilter( testJoinFeature, engine.get(), 
true, predicates ) )
 
  342        joinAttributes.reserve( joinFieldIndices.size() );
 
  343        for ( 
int joinIndex : std::as_const( joinFieldIndices ) )
 
  345          joinAttributes.append( testJoinFeature.
attribute( joinIndex ) );
 
  347        values.append( joinAttributes );
 
  357    if ( values.empty() )
 
  359      if ( discardNonMatching )
 
  377      outputAttributes.reserve( outputFields.
size() );
 
  378      for ( 
int fieldIndex = 0; fieldIndex < joinFieldIndices.size(); ++fieldIndex )
 
  380        const FieldType &fieldType = fieldTypes.at( fieldIndex );
 
  383          case FieldType::Numeric:
 
  386            for ( 
const QVector<QVariant> &value : std::as_const( values ) )
 
  391            for ( 
const FieldStatistic &statistic : sNumericStats )
 
  393              if ( summaries.contains( statistic.enumIndex ) )
 
  396                switch ( statistic.enumIndex )
 
  441                if ( val.isValid() && std::isnan( val.toDouble() ) )
 
  443                outputAttributes.append( val );
 
  449          case FieldType::DateTime:
 
  452            QVariantList inputValues;
 
  453            inputValues.reserve( values.size() );
 
  454            for ( 
const QVector<QVariant> &value : std::as_const( values ) )
 
  456              inputValues << value.at( fieldIndex );
 
  459            for ( 
const FieldStatistic &statistic : sDateTimeStats )
 
  461              if ( summaries.contains( statistic.enumIndex ) )
 
  464                switch ( statistic.enumIndex )
 
  485                outputAttributes.append( val );
 
  491          case FieldType::String:
 
  494            QVariantList inputValues;
 
  495            inputValues.reserve( values.size() );
 
  496            for ( 
const QVector<QVariant> &value : std::as_const( values ) )
 
  498              if ( value.at( fieldIndex ).isNull() )
 
  501                stat.
addString( value.at( fieldIndex ).toString() );
 
  504            for ( 
const FieldStatistic &statistic : sStringStats )
 
  506              if ( summaries.contains( statistic.enumIndex ) )
 
  509                switch ( statistic.enumIndex )
 
  539                outputAttributes.append( val );
 
  557  results.insert( QStringLiteral( 
"OUTPUT" ), destId );
 
@ VectorAnyGeometry
Any vector layer with geometry.
 
@ NotPresent
No spatial index exists for the source.
 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
 
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
 
Calculator for summary statistics and aggregates for a list of datetimes.
 
void calculate(const QVariantList &values)
Calculates summary statistics for a list of variants.
 
QDateTime min() const
Returns the minimum (earliest) non-null datetime value.
 
int count() const
Returns the calculated count of values.
 
int countMissing() const
Returns the number of missing (null) datetime values.
 
int countDistinct() const
Returns the number of distinct datetime values.
 
QDateTime max() const
Returns the maximum (latest) non-null datetime value.
 
Wrapper for iterator of features from vector data provider or vector layer.
 
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
 
Wraps a request for features to a vector layer (or directly its vector data provider).
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
 
QgsFeatureRequest & setDestinationCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets the destination crs for feature's geometries.
 
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
 
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
void resizeAttributes(int fieldCount)
Resizes the attributes attached to this feature to the given number of fields.
 
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
 
bool hasGeometry() const
Returns true if the feature has an associated geometry.
 
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
 
bool isCanceled() const
Tells whether the operation has been canceled already.
 
void setProgress(double progress)
Sets the current progress for the feedback object.
 
Encapsulate a field in an attribute table or data source.
 
void setPrecision(int precision)
Set the field precision.
 
void setName(const QString &name)
Set the field name.
 
void setType(QMetaType::Type type)
Set variant type.
 
void setLength(int len)
Set the field length.
 
Container of fields for a vector layer.
 
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
 
int size() const
Returns number of items.
 
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
 
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry, double precision=0.0, Qgis::GeosCreationFlags flags=Qgis::GeosCreationFlag::SkipEmptyInteriorRings)
Creates and returns a new geometry engine representing the specified geometry using precision on a gr...
 
Contains information about the context in which a processing algorithm is executed.
 
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
 
Custom exception class for processing related exceptions.
 
Base class for providing feedback from a processing algorithm.
 
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
 
A boolean parameter for processing algorithms.
 
A feature sink output for processing algorithms.
 
An input feature source (such as vector layers) parameter for processing algorithms.
 
A vector layer or feature source field parameter for processing algorithms.
 
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
 
Calculator for summary statistics for a list of doubles.
 
void addVariant(const QVariant &value)
Adds a single value to the statistics calculation.
 
double firstQuartile() const
Returns the first quartile of the values.
 
double sum() const
Returns calculated sum of values.
 
double mean() const
Returns calculated mean of values.
 
double majority() const
Returns majority of values.
 
double interQuartileRange() const
Returns the inter quartile range of the values.
 
double median() const
Returns calculated median of values.
 
double minority() const
Returns minority of values.
 
double min() const
Returns calculated minimum from values.
 
double stDev() const
Returns population standard deviation.
 
double thirdQuartile() const
Returns the third quartile of the values.
 
int count() const
Returns calculated count of values.
 
double range() const
Returns calculated range (difference between maximum and minimum values).
 
double max() const
Returns calculated maximum from values.
 
void finalize()
Must be called after adding all values with addValues() and before retrieving any calculated statisti...
 
int variety() const
Returns variety of values.
 
Calculator for summary statistics and aggregates for a list of strings.
 
QString max() const
Returns the maximum (non-null) string value.
 
QString min() const
Returns the minimum (non-null) string value.
 
int countMissing() const
Returns the number of missing (null) string values.
 
int count() const
Returns the calculated count of values.
 
int countDistinct() const
Returns the number of distinct string values.
 
void finalize()
Must be called after adding all strings with addString() and before retrieving any calculated string ...
 
void addString(const QString &string)
Adds a single string to the statistics calculation.
 
int minLength() const
Returns the minimum length of strings.
 
int maxLength() const
Returns the maximum length of strings.
 
double meanLength() const
Returns the mean length of strings.