Allows extraction of matching parts from a collection, returning
the corresponding collection subclass.
mixed_collection = QgsGeometryCollection()
mixed_collection.addGeometry(... mix of geometry types ...)
multi_line_string = mixed_collection.extractPartsByType(Qgis.WkbType.LineString)
In this case multi_line_string will be a QgsMultiLineString object,
containing just the line string parts from mixed_collection
And transparently map requests for grass7 provider to grass provider
It's misleading putting an old version number in the provider name,
when this provider supports grass versions 8 +
Use the safer method of explicitly including the provider type
when storing layer sources to string in more places, which eg
fixes running the copied qgis_process string when a non gdal
layer source is used for a raster layer. Also fixes the same
situation when restoring an algorithm from the history log.
Fixes#54264
Instead of writing errors to QgsMessageLog and discarding, instead
make the QgsTessellator class store errors and make the callers
responsible for pushing to QgsMessageLog when appropriate.
Gives us more flexibility to show user facing tesselation errors,
eg in the processing log.
The old sip based approach to handling property -> getter/setter
conversion is broken on sip6, so move the patching into Python.
Also fix incorrect checks in tests, and add additional test
for compatiblity code.
And make sipify handle this nicely. This means that all our non-flag
style enums correctly map across to IntFlag python enums on Qt 6,
fixing issues with negative enum values for these and providing
a better match for the original c++ enum.
sip6 converts all enums to python Enums, but ONLY creates
Enums with IntFlags types when the c++ type is an enum class : int.
Accordingly we need to patch back in all the operations which treat
enum values as ints, like |, &, bool, etc.
The long term solution here is to move all our c++ enums to enum
class, but that's not always straightforward and can break API
for plugins if it involves the signature of virtual methods.
Here we have to break with our previous approach of treating
null variants (NULL in Python) different to invalid qvariants (None in
Python)
There's simply NO way to construct null variants in PyQt6 -- they
are ALWAYS mapped across to Py_None.
This isn't as big a deal as it sounds, we already made the decision
in c++ code to move to invalid variants in favour of null variants.
Note that we STILL need the custom sip code here and can't rely
on base PyQt6 null variant conversion, as that relies on
QVariant::isNull when we must use QgsVariantUtils::isNull so
that the underlying type is correctly checked for null values
on Qt 6 builds.