8

I'm trying to count the number of polygons in a multipart feature. My aim is to have a 'count' attribute to quantify fragmentation of multipart land parcels.

I've looked at the field calculator and for suitable plugins, but can't see anything that would help. There are lots of ways to count points, lines and vertices, but not polygons.

1
  • I should say that I'm trying to count polygons within each multipart feature, not just the total in the layer.
    – Sorbus
    Commented Aug 2, 2014 at 20:31

6 Answers 6

15

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

num_geometries($geometry)

Field Calculator: num_geometries

4

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()
field.setName("NUM_PARTS")
field.setDataType(DBFField.DBFDataType.NUMERIC)
field.setFieldLength(5)
field.setDecimalCount(0)
table.addField(field)
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

6
  • I'm downloading and will give it a try - thank you
    – Sorbus
    Commented Aug 2, 2014 at 21:41
  • No problem, let me know if you have any problems or if you want me to update the script to optionally exclude holes in polygons. Also, you said that your shapefile has thousands of polygons with multiple parts. This script will be able to process that in a couple seconds. Performance is quite good. Commented Aug 2, 2014 at 21:43
  • I'm getting an error: javax.script.ScriptException: whitebox.geospatialfiles.shapefile.attributes.DBFException: Invalid value for field 3 None of the table headings have invalid characters. Any ideas?
    – Sorbus
    Commented Aug 2, 2014 at 22:05
  • @Sorbus, Hmmm, that's very odd because it works like a charm on my computer. The error is occurring when it hits the line, table.updateRecord(i, recData). The problem seems to be with the third attribute. How many attributes do you have in the table, other than the one that is being added by the script? Are you able to email me the file so I can hunt for the error? ([email protected]) Commented Aug 2, 2014 at 22:31
  • Many thanks John. If the script counts from zero it was throwing the error on a 'date' column. I deleted unnecessary columns from the table and the script ran perfectly! I'll send you the files so you can test it yourself. Your software looks extremely useful. I'll definitely check out the tutorials. I'm sorry I can't up vote your answer yet...
    – Sorbus
    Commented Aug 2, 2014 at 22:45
4

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.

2

Another non-QGIS solution is to use OpenJUMP. It has a special tool in Tools - Stastistics - Feature Stastistics. The tool creates a new layer with these attributes:

  • nPts (number of vertices)
  • nHoles (number of holes)
  • nComponents (number of components)
  • area
  • length
  • type (type ot geometry)

If you aim is to count the number of polygons in multipolygons this tool should do the job fine. However, if you want to count how many polygons there are in GeometryCollections which contain also other sort of geometries you must explode the collections first.

0
1

You can try to dissociate multi polygons into unique polygon and then open the attribute table and watch the number of lines (which represents the number of polygons).

To separate multipolygon : Vector->Geometry Tools->Multipart to single parts

3
  • If I did that, is there a way to populate the table with a count? The dataset has thousands of multipart features, so manual counting is not an option.
    – Sorbus
    Commented Aug 2, 2014 at 20:28
  • Of course, you can use field calculator (Right clic on the layer > attribute field > field calculator) to count everything you need.
    – Leasye
    Commented Aug 2, 2014 at 21:18
  • What specific function would you suggest?
    – Sorbus
    Commented Aug 2, 2014 at 21:46
1

This information is now in the information pop up. If you right click the layer and select properties, the window that pops up shows the feature count.

enter image description here

1
  • I think this shows the number of Multi Polygon features, not the number of parts of multi-part geometries. Commented Nov 22, 2022 at 15:55

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.