Convert Polygon Feature Centroid to Points using Python

Simply use Fiona or GeoPandas (Python 2.7.x and 3.x)

Some polygons

enter image description here

import geopandas as gpd
# GeoDataFrame creation
poly = gpd.read_file("geoch_poly.shp")
poly.head()

enter image description here

Transformation to points (centroids)

# copy poly to new GeoDataFrame
points = poly.copy()
# change the geometry
points.geometry = points['geometry'].centroid
# same crs
points.crs =poly.crs
points.head()

enter image description here

# save the shapefile
points.to_file('geoch_centroid.shp')

Result

enter image description here


You can run an ogr2ogr command (e.g. from a OSGeo4w Shell). E.g. on a shapefile of countries:

cd path/to/shapefiles
ogr2ogr -sql "SELECT ST_Centroid(geometry), * FROM countries" -dialect sqlite countries_centroid.shp countries.shp

The new shapefile countries_centroid.shp should be similar to the input, but just contain one point per [Multi]Polygon.

@PEL also shows a good example with ST_PointOnSurface, which is simple to substitute in this command.


Something similar can be done in Python, if needed, but it may take a few lines of code more:

import os
from osgeo import ogr

ogr.UseExceptions()
os.chdir('path/to/shapefiles')

ds = ogr.Open('countries.shp')
ly = ds.ExecuteSQL('SELECT ST_Centroid(geometry), * FROM countries', dialect='sqlite')
drv = ogr.GetDriverByName('Esri shapefile')
ds2 = drv.CreateDataSource('countries_centroid.shp')
ds2.CopyLayer(ly, '')
ly = ds = ds2 = None  # save, close

Another, perhaps more 'low level', way would be to directly use fiona and shapely for I/O and geometry processing.

import fiona
from shapely.geometry import shape, mapping

with fiona.open('input_shapefile.shp') as src:
    meta = src.meta
    meta['schema']['geometry'] = 'Point'
    with fiona.open('output_shapefile.shp', 'w', **meta) as dst:
        for f in src:
            centroid = shape(f['geometry']).centroid
            f['geometry'] = mapping(centroid)
            dst.write(f)