1

I have figured out how to save only the features of a vector layer that intersect a rectangle (I'm doing something similar to the example below):

TransformContext = QgsProject.instance().transformContext()
SaveOptions = QgsVectorFileWriter.SaveVectorOptions()
SaveOptions.driverName = "GPKG"
listOfLayers : list[QgsMapLayer] = layerIdsToLayers.values()

for layer in listOfLayers:
  currentExtentsToSave = QgsRectangle(0, 0, 1, 1)
  SaveOptions.filterExtent = currentExtentsToSave
  SaveOptions.onlySelectedFeatures = False

  SaveOptions.actionOnExistingFile = QgsVectorFileWriter.ActionOnExistingFile.CreateOrOverwriteLayer
  fileName = "Example.gpkg"
  QgsVectorFileWriter.writeAsVectorFormatV3(layer, fileName, TransformContext, SaveOptions)

With some testing, I confirmed that the calculation to determine overlap checks if any parts of the geometry of each feature overlap with the extents provided in the SaveOptions.

How can I modify the SaveOptions so that the calculation performed to determine an overlap only uses the center of each feature's geometry?

1
  • 2
    Unfortunatelly, I have not yet found a way to check geometry topology between a point and a QgsRectangle in the filterExtent. However, one could try the QgsFeatureRequest with .setFilterExpression() together with the materialize to create a temp layer. Additionally, it is better to switch to writeAsVectorFormatV3 as v1 and v2 are deprecated since QGIS 3.40 and QGIS 3.20, correspondingly. Commented Apr 15 at 7:01

1 Answer 1

1

A solution I found with the help of @Taras is to use the "Extract by expression" processing function:

To use it, I first added some variables to the layer that I wanted to extract features from:

upperLat = 32.494
lowerLat = 32.3
upperLong = -117
lowerLong = -120

layer = QgsProject.instance().mapLayersByShortName("MyLayer")[0]
QgsExpressionContextUtils.setLayerVariable(layer, "upperLat", upperLat)
QgsExpressionContextUtils.setLayerVariable(layer, "lowerLat", lowerLat)
QgsExpressionContextUtils.setLayerVariable(layer, "upperLong", upperLong)
QgsExpressionContextUtils.setLayerVariable(layer, "lowerLong", lowerLong)

I then used those variables in the expression:

expression = "with_variable('xCoor', x(centroid(@geometry)),@xCoor >= @lowerLong and @xCoor <= @upperLong) andwith_variable('yCoor', y(centroid(@geometry)),@yCoor >= @lowerLat and @yCoor <= @upperLat)"

I then used the expression in the processing plugin:

processing.run("native:extractbyexpression", {'INPUT':'/home/user/Downloads/layer.000|layername=MyLayer|geometrytype=Polygon|uniqueGeometryType=yes','EXPRESSION':"with_variable('xCoor', x(centroid(@geometry)),\n@xCoor >= @lowerLong and @xCoor <= @upperLong) and\nwith_variable('yCoor', y(centroid(@geometry)),\n@yCoor >= @lowerLat and @yCoor <= @upperLat)",'OUTPUT':'TEMPORARY_OUTPUT'})
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.