mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	Add expression based filter for QgsVectorLayerExporter
This commit is contained in:
		
							parent
							
								
									32373e1999
								
							
						
					
					
						commit
						f22baa38f1
					
				@ -70,6 +70,10 @@ Encapsulates options for use with QgsVectorLayerExporter.
 | 
			
		||||
%Docstring
 | 
			
		||||
Sets whether the export should only include selected features.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.setFilterExpression`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
@ -81,6 +85,10 @@ Sets whether the export should only include selected features.
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns whether the export will only include selected features.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.filterExpression`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
@ -140,6 +148,58 @@ Only features with a bounding box intersecting this extent will be exported.
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setExtent`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        void setFilterExpression( const QString &expression );
 | 
			
		||||
%Docstring
 | 
			
		||||
Set the filter ``expression`` for the features to export.
 | 
			
		||||
 | 
			
		||||
Only features matching this expression will be exported.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.setSelectedOnly`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setExpressionContext`
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`filterExpression`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        QString filterExpression() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the filter expression for features to export.
 | 
			
		||||
 | 
			
		||||
Only features matching this expression will be exported.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.selectedOnly`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`expressionContext`
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setFilterExpression`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        void setExpressionContext( const QgsExpressionContext &context );
 | 
			
		||||
%Docstring
 | 
			
		||||
Sets the expression ``context`` to use when a :py:func:`~ExportOptions.filterExpression` is set.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`expressionContext`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        const QgsExpressionContext &expressionContext() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the expression context used when a :py:func:`~ExportOptions.filterExpression` is set.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setExpressionContext`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -70,6 +70,10 @@ Encapsulates options for use with QgsVectorLayerExporter.
 | 
			
		||||
%Docstring
 | 
			
		||||
Sets whether the export should only include selected features.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.setFilterExpression`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
@ -81,6 +85,10 @@ Sets whether the export should only include selected features.
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns whether the export will only include selected features.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.filterExpression`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
@ -140,6 +148,58 @@ Only features with a bounding box intersecting this extent will be exported.
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setExtent`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        void setFilterExpression( const QString &expression );
 | 
			
		||||
%Docstring
 | 
			
		||||
Set the filter ``expression`` for the features to export.
 | 
			
		||||
 | 
			
		||||
Only features matching this expression will be exported.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.setSelectedOnly`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setExpressionContext`
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`filterExpression`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        QString filterExpression() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the filter expression for features to export.
 | 
			
		||||
 | 
			
		||||
Only features matching this expression will be exported.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This setting is incompatible with :py:func:`~ExportOptions.selectedOnly`
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This option only applies when the :py:func:`QgsVectorLayerExporter.exportLayer()` method is used.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`expressionContext`
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setFilterExpression`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        void setExpressionContext( const QgsExpressionContext &context );
 | 
			
		||||
%Docstring
 | 
			
		||||
Sets the expression ``context`` to use when a :py:func:`~ExportOptions.filterExpression` is set.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`expressionContext`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
        const QgsExpressionContext &expressionContext() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the expression context used when a :py:func:`~ExportOptions.filterExpression` is set.
 | 
			
		||||
 | 
			
		||||
.. seealso:: :py:func:`setExpressionContext`
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -81,6 +81,26 @@ QgsReferencedRectangle QgsVectorLayerExporter::ExportOptions::extent() const
 | 
			
		||||
  return mExtent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorLayerExporter::ExportOptions::setFilterExpression( const QString &expression )
 | 
			
		||||
{
 | 
			
		||||
  mFilterExpression = expression;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString QgsVectorLayerExporter::ExportOptions::filterExpression() const
 | 
			
		||||
{
 | 
			
		||||
  return mFilterExpression;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorLayerExporter::ExportOptions::setExpressionContext( const QgsExpressionContext &context )
 | 
			
		||||
{
 | 
			
		||||
  mExpressionContext = context;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const QgsExpressionContext &QgsVectorLayerExporter::ExportOptions::expressionContext() const
 | 
			
		||||
{
 | 
			
		||||
  return mExpressionContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// QgsVectorLayerExporter
 | 
			
		||||
@ -423,7 +443,12 @@ Qgis::VectorExportResult QgsVectorLayerExporter::exportLayer( QgsVectorLayer *la
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ( exportOptions.selectedOnly() )
 | 
			
		||||
  if ( !exportOptions.filterExpression().isEmpty() )
 | 
			
		||||
  {
 | 
			
		||||
    req.setFilterExpression( exportOptions.filterExpression() );
 | 
			
		||||
    req.setExpressionContext( exportOptions.expressionContext() );
 | 
			
		||||
  }
 | 
			
		||||
  else if ( exportOptions.selectedOnly() )
 | 
			
		||||
  {
 | 
			
		||||
    req.setFilterFids( layer->selectedFeatureIds() );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -86,6 +86,8 @@ class CORE_EXPORT QgsVectorLayerExporter : public QgsFeatureSink
 | 
			
		||||
        /**
 | 
			
		||||
         * Sets whether the export should only include selected features.
 | 
			
		||||
         *
 | 
			
		||||
         * \warning This setting is incompatible with setFilterExpression()
 | 
			
		||||
         *
 | 
			
		||||
         * \note This option only applies when the QgsVectorLayerExporter::exportLayer() method is used.
 | 
			
		||||
         *
 | 
			
		||||
         * \seee selectedOnly()
 | 
			
		||||
@ -95,6 +97,8 @@ class CORE_EXPORT QgsVectorLayerExporter : public QgsFeatureSink
 | 
			
		||||
        /**
 | 
			
		||||
         * Returns whether the export will only include selected features.
 | 
			
		||||
         *
 | 
			
		||||
         * \warning This setting is incompatible with filterExpression()
 | 
			
		||||
         *
 | 
			
		||||
         * \note This option only applies when the QgsVectorLayerExporter::exportLayer() method is used.
 | 
			
		||||
         *
 | 
			
		||||
         * \seee setSelectedOnly()
 | 
			
		||||
@ -151,6 +155,48 @@ class CORE_EXPORT QgsVectorLayerExporter : public QgsFeatureSink
 | 
			
		||||
         */
 | 
			
		||||
        QgsReferencedRectangle extent() const;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Set the filter \a expression for the features to export.
 | 
			
		||||
         *
 | 
			
		||||
         * Only features matching this expression will be exported.
 | 
			
		||||
         *
 | 
			
		||||
         * \warning This setting is incompatible with setSelectedOnly()
 | 
			
		||||
         *
 | 
			
		||||
         * \note This option only applies when the QgsVectorLayerExporter::exportLayer() method is used.
 | 
			
		||||
         *
 | 
			
		||||
         * \see setExpressionContext()
 | 
			
		||||
         * \see filterExpression()
 | 
			
		||||
         */
 | 
			
		||||
        void setFilterExpression( const QString &expression );
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Returns the filter expression for features to export.
 | 
			
		||||
         *
 | 
			
		||||
         * Only features matching this expression will be exported.
 | 
			
		||||
         *
 | 
			
		||||
         * \warning This setting is incompatible with selectedOnly()
 | 
			
		||||
         *
 | 
			
		||||
         * \note This option only applies when the QgsVectorLayerExporter::exportLayer() method is used.
 | 
			
		||||
         *
 | 
			
		||||
         * \see expressionContext()
 | 
			
		||||
         * \see setFilterExpression()
 | 
			
		||||
         */
 | 
			
		||||
        QString filterExpression() const;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Sets the expression \a context to use when a filterExpression() is set.
 | 
			
		||||
         *
 | 
			
		||||
         * \see expressionContext()
 | 
			
		||||
         */
 | 
			
		||||
        void setExpressionContext( const QgsExpressionContext &context );
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Returns the expression context used when a filterExpression() is set.
 | 
			
		||||
         *
 | 
			
		||||
         * \see setExpressionContext()
 | 
			
		||||
         */
 | 
			
		||||
        const QgsExpressionContext &expressionContext() const;
 | 
			
		||||
 | 
			
		||||
      private:
 | 
			
		||||
 | 
			
		||||
        bool mSelectedOnly = false;
 | 
			
		||||
@ -161,6 +207,9 @@ class CORE_EXPORT QgsVectorLayerExporter : public QgsFeatureSink
 | 
			
		||||
 | 
			
		||||
        QgsReferencedRectangle mExtent;
 | 
			
		||||
 | 
			
		||||
        QString mFilterExpression;
 | 
			
		||||
        QgsExpressionContext mExpressionContext;
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -196,6 +196,59 @@ class TestQgsVectorLayerExporter(QgisTestCase):
 | 
			
		||||
                [f["fldtxt"] for f in layer.getFeatures()], ["test2", "test3"]
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    def test_expression_filter(self):
 | 
			
		||||
        with tempfile.TemporaryDirectory() as temp_dir:
 | 
			
		||||
            dest_file_name = Path(temp_dir) / "test_expression.gpkg"
 | 
			
		||||
 | 
			
		||||
            # create a layer to export
 | 
			
		||||
            layer = QgsVectorLayer(
 | 
			
		||||
                "Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory"
 | 
			
		||||
            )
 | 
			
		||||
            self.assertTrue(layer.isValid())
 | 
			
		||||
            pr = layer.dataProvider()
 | 
			
		||||
            f = QgsFeature()
 | 
			
		||||
            f.setAttributes(["test", 123])
 | 
			
		||||
            f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
 | 
			
		||||
            f2 = QgsFeature()
 | 
			
		||||
            f2.setAttributes(["abc", 457])
 | 
			
		||||
            f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(3, 4)))
 | 
			
		||||
            f3 = QgsFeature()
 | 
			
		||||
            f3.setAttributes(["def", 4573])
 | 
			
		||||
            f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(5, 6)))
 | 
			
		||||
            f4 = QgsFeature()
 | 
			
		||||
            f4.setAttributes(["a feature", 4574])
 | 
			
		||||
            f4.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(7, 8)))
 | 
			
		||||
            self.assertTrue(pr.addFeature(f))
 | 
			
		||||
            self.assertTrue(pr.addFeature(f2))
 | 
			
		||||
            self.assertTrue(pr.addFeature(f3))
 | 
			
		||||
            self.assertTrue(pr.addFeature(f4))
 | 
			
		||||
            layer.setCrs(QgsCoordinateReferenceSystem("EPSG:4326"))
 | 
			
		||||
 | 
			
		||||
            export_options = QgsVectorLayerExporter.ExportOptions()
 | 
			
		||||
            export_options.setFilterExpression("left(\"fldtxt\", 1) = 'a'")
 | 
			
		||||
 | 
			
		||||
            res, error = QgsVectorLayerExporter.exportLayer(
 | 
			
		||||
                layer,
 | 
			
		||||
                dest_file_name.as_posix(),
 | 
			
		||||
                "ogr",
 | 
			
		||||
                export_options,
 | 
			
		||||
                providerOptions={"layerName": "expression", "update": True},
 | 
			
		||||
            )
 | 
			
		||||
            self.assertEqual(res, Qgis.VectorExportResult.Success)
 | 
			
		||||
 | 
			
		||||
            # true to read result
 | 
			
		||||
            layer = QgsVectorLayer(
 | 
			
		||||
                dest_file_name.as_posix() + "|layername=expression",
 | 
			
		||||
                "test",
 | 
			
		||||
                "ogr",
 | 
			
		||||
            )
 | 
			
		||||
            self.assertTrue(layer.isValid())
 | 
			
		||||
            self.assertEqual(layer.featureCount(), 2)
 | 
			
		||||
 | 
			
		||||
            self.assertCountEqual(
 | 
			
		||||
                [f["fldtxt"] for f in layer.getFeatures()], ["abc", "a feature"]
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    @unittest.skipIf(
 | 
			
		||||
        int(gdal.VersionInfo("VERSION_NUM")) < GDAL_COMPUTE_VERSION(3, 8, 0),
 | 
			
		||||
        "GDAL 3.8 required",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user