Django - Get centroid of polygon in geoJSON format
django, django-rest-framework, django-rest-framework-gis, postgis, python
Solution
You can use a combination of the following methods:
- `AsGeoJSON`, which
Accepts a single geographic field or expression and returns a GeoJSON representation of the geometry.
- `Centroid()` which
Accepts a single geographic field or expression and returns the centroid value of the geometry.
- `.annotate()` which
Annotates each object in the QuerySet with the provided list of query expressions. [...] Each argument to `annotate()` is an annotation that will be added to each object in the QuerySet that is returned.
Example:
The following query:
Polygon.objects.annotate(geometry=AsGeoJSON(Centroid('coordinates')))
will add a field named `'geometry'` to the `Polygon` queryset which will contain the centroid calculated from the `coordinates` field of every `Polygon` object of your given model.
Problem
I'm building a REST API to manage geo-related data. My front-end developer wants to retrieve the centroid of polygons, depending on zoom level, in `geoJSON` format. My polygon model is as follows: ``` ... from django.contrib.gis.db import models as geomodels class Polygon(geomodels.Model): fk_owner = models.ForeignKey(User, on_delete=models.DO_NOTHING, blank=True) external_id = models.CharField(max_length=25, unique=True) func_type = models.CharField(max_length=15) coordinates = geomodels.PolygonField(srid=3857) properties = JSONField(default={}) ``` The API currently returns things like this: ``` "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [[[..]]] } }] ``` And I use `rest_framework_gis.serializers.GeoFeatureModelSerializer` to serialize my data. I see the following ways to get the centroid: - Add a column centroid to my model: I don't want to do this - Create a database view of my model: Django does not manage database views and I don't want to write a custom migration Use the same model and add an `extra(...)` to my orm statement: I tried but things get hard in or before serialization, because in the model the type is `Polygon`, and the centroid is a `Point`. The error is the following: ``` TypeError: Cannot set Polygon SpatialProxy (POLYGON) with value of type: <class 'django.contrib.gis.geos.point.Point'> ``` The expected output should be: ``` "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [..] } }] ``` What is your opinion ?