1

I have a roads shapefile. In its name field, I'll create a new shapefile per attribute. I already got each unique attribute under name. The for-loop that iterates over the unique attributes and selects the features isn't working.

from qgis.core import QgsProject
 
def split_shp():
 # Parameters
 layer_name = 'bicolRoads_primary_secondary'
 field_name = 'name'
 
 layer = QgsProject.instance().mapLayersByName(layer_name)[0] # road shp
 shp_index = layer.fields().indexOf(field_name) # road shp index
 unique_values = layer.uniqueValues(shp_index) # unique attributes under 'name' field
 for i in unique_values: # for-loop that iterates over the unique attributes
 dog = layer.selectByExpression('field_name=i') # selects features matching i/current attribute
 print(dog)
 #shp_writer = QgsVectorFileWriter.writeAsVectorFormat(layer, new_shp, 'utf-8', \
 #driverName='ESRI Shapefile', onlySelected=True)
 
split_shp()

The result is this

enter image description here

asked Jul 18, 2020 at 3:09
5
  • 4
    You can do it in two lines: res = processing.run("native:splitvectorlayer", {'INPUT':'/path/to/data.shp','FIELD':'unique_field','FILE_TYPE':1,'OUTPUT':'/my/folder/'}), print(res['OUTPUT_LAYERS']) Commented Jul 18, 2020 at 3:27
  • @GermánCarrillo, I think this is for QGIS 2. Mine (3.10) says QgsProcessingException: Error: Algorithm native:splitvectorlayer not found. The current documentation doesn't also show what's the keyword nor the log when running the Split Vector Layer tool. Commented Jul 18, 2020 at 13:21
  • @GermánCarrillo, solved it. Instead of "native:splitvectorlayer", I used "qgis:splitvectorlayer" but it saves per shapefile into a geopackage which is why I opted to make my own script instead of using the tool. Thanks anyways! Commented Jul 18, 2020 at 13:31
  • Here's the link to the documentation docs.qgis.org/testing/en/docs/user_manual/processing_algs/qgis/… Commented Jul 18, 2020 at 13:37
  • 2
    Right, the code I put in my comment is for QGIS 3.14, where the algorithm is already in C++ and accepts the output format (1: Shapefile). Good luck! Commented Jul 18, 2020 at 13:57

1 Answer 1

1

Seems like the return value from layer.SelectByExpression is None even if features are selected.

Try building the query like this:

def split_shp():
 # Parameters
 layer_name = 'ak_riks'
 field_name = 'LAN_KOD'
 
 layer = QgsProject.instance().mapLayersByName(layer_name)[0] # road shp
 shp_index = layer.fields().indexOf(field_name) # road shp index
 unique_values = layer.uniqueValues(shp_index) # unique attributes under 'name' field
 for i in unique_values: # for-loop that iterates over the unique attributes
 s = layer.selectByExpression(""""{0}" = '{1}'""".format(field_name, i))
 print(s, layer.selectedFeatureCount())
 ...

enter image description here

But as commented Split vector layer would be easier. But if you want to do it your way Extract by expression might be easier than selecting then exporting.

answered Jul 18, 2020 at 9:21
1
  • 1
    Thank you for this! .format(field_name, i) is the line I kept searching for. This is really helpful. Thanks again, @BERA. Commented Jul 18, 2020 at 13:33

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.