Why is GeoDjango not returning my GeoJSON in SRID 4326?

I have a model with point data stored in srid 2953. When I serialize this data, I assumed that GeoDjando would convert this to valid GeoJSON by converting the coordinates to SRID 4326. Maybe I need to specificly tell it to convert this? From what I have read I understand that CRS has been depreciated from GeoJSON, and that it is only valid in SRID 4326?

class Hpnrecord(models.Model):
    ...
    geom = models.PointField(srid=2953, null=True)

Later in a serializer I have:

class HpnrecordSerializer(serializers.GeoFeatureModelSerializer):
    class Meta:
        fields = "__all__"
        geo_field = "geom"
        model = Hpnrecord

When I view the returned data I am getting this:

{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [ 2594598.985, 7425392.375 ] }, "properties": { } },

as you can see, the coordinates are being displayed as Easting and Northing (the same as what is stored in the model), and not being converted to SRID 4326. My endpoint is expecting to receive this in srid 4326.

How do I specify that I expect the serializaiton to be in SRID 4326?


Solution 1:

As you might have noticed, SRID transformations are not done automatically. I have 2 suggestions for you:

Suggestion 1: Store the data in the desired SRID

Before you store the data, you convert it first to your desired srid of 4326. Your model would change:

class Hpnrecord(models.Model):
    ...
    geom = models.PointField(srid=4326, null=True)

Storing the data would look like this:

from django.contrib.gis.geos import Point

...

point = Point(x, y, srid=2953)
point.transform(4326)
model_instance.geom = point
model_instance.save()

Suggestion 2: Use the serializer's to_representation()

You keep your models as they are and you convert the SRID on the fly using the serializer's to_representation() method, see the docs. Note that converting it on the fly will result in a speed penalty, but you can leave the models as they are.

class HpnrecordSerializer(serializers.GeoFeatureModelSerializer):
    class Meta:
        fields = "__all__"
        geo_field = "geom"
        model = Hpnrecord
    
    def to_representation(self, instance):
        """Convert `geom` to srid 4326."""
        ret = super().to_representation(instance)
        ret['geom'] = ret['geom'].transform(4326)
        return ret