How to count polygons in multipart features?

4 years later it seems as if QGIS has integrated this feature into the field calculator. The expression syntax is:


Field Calculator: num_geometries

I know that you're looking for an answer that uses QGIS but if you're willing to use the open-source GIS Whitebox Geospatial Analysis Tools instead, then here is a complete answer that will take any shapefile, and create a new attribute field in its table that contains the number of feature parts. You simply need to open the Scripter window in Whitebox, change the script language to Groovy, and paste the following code in:

import whitebox.geospatialfiles.ShapeFile
import whitebox.geospatialfiles.shapefile.*
import whitebox.geospatialfiles.shapefile.attributes.*

def inputFileName = "/MY_DIRECTORY/MY_FILE_NAME.shp"
def shape = new ShapeFile(inputFileName)
AttributeTable table = shape.getAttributeTable()

DBFField field = new DBFField()
for (int i = 0; i < shape.getNumberOfRecords(); i++) {
    ShapeFileRecord record = shape.getRecord(i)
    int numParts = record.getGeometry().getParts().length
    recData = table.getRecord(i)
    recData[recData.length - 1] = new Double(numParts)
    table.updateRecord(i, recData)

println("I'm done")

You'll need to update the value of the inputFileName variable near the top to point it to your file. You could also use Python to achieve the same thing, but I wrote this in Groovy. If you like, I can also have the script exclude hole parts if you are working with polygons.

Here's an example of a world country map that has been rendered to show the number of parts each country's polygon feature includes:

enter image description here

If QGIS is the only tool available The following python code in the Python Console might do the trick:

layer = iface.activeLayer()
for x in layer.getFeatures():
    geometry = x.geometry().asMultiPolygon()
    print len(geometry)

Of course this is not a complete solution, it will just print a bunch of numbers without indicating which feature they pertain to, but it's a start. You could have it also print the 'NAME' field or some other preferred key attribute. Or you could modify to write the len(geometry) integer to some other field in the layer.