mufasa
mufasa

Reputation: 1344

GeoDjango: transform SRID in DRF Serializer

I am currently writing an API using an OSM DB, a regular DB, DRF3 and django-rest-framework-gis.

The OSM DB is using SRID 900913, but I would like the API to only output coordinates according to SRID 4326. This is achievable by using the transform(srid=4326) on my geoquerysets, but unfortunately that is not an option in my case (explained why further down).

Of what I understand, I should be able to specify another SRID in the field definition of the model like so:

class Polygon(models.Model):
    osm_id = models.AutoField(primary_key=True)
    name = models.CharField(null=True)
    way = models.PolygonField(null=True, srid=4326)
    admin_level = models.CharField(default='2', null=True)

    objects = models.GeoManager()

    class Meta:
        db_table = 'osm_poly_lu'

But the API keeps returning polygons with coordinates in the 900913 format.

Do I understand it correctly; should I be able to set the srid on my polygon field to 4326 for Django to automatically convert it from my DBs 900913? If so, I guess I must be missing something; any ideas of what may be wrong? I feel like a true newbie in this area - any help is very appreciated.

The reason why I can not use transform() on my querysets:

What I am doing is querying my member table, and the member model is a regular model. It does however have a relation to the OSM Polygon table (field is called osm_id_origin) and this is a geoDjango model. So when I serialize the member with a DRF3 Serializer, I have a nested Serializer in the member serializer that serializes the osm_id_origin field in the member model as a geoJSON. The nested serializer I am using for creating the geoJSON is a subclass of the django-rest-framework-gis serializer GeoFeatureModelSerializer. Since I query the member model, which is a regular queryset, I can not run the transform(srid=4326) on it.

Upvotes: 1

Views: 1101

Answers (1)

Julien Fastré
Julien Fastré

Reputation: 1048

This is a late answer, but I encounter the same issue and I created a dedicated serializer field to handle transformation. As you will see, this code stores the geometry in srid 31370, and transform the geometry to srid 3857 (which is quite the same as 900913) when serialized:

from rest_framework_gis.fields import GeometryField

class ProjectedGeometrySerializerField(GeometryField):
    """
    Transform a geometry from SRID 3857 (representation data)
    to 31370 (internal value)
    """

    def to_representation(self, value):

        if isinstance(value, dict) or value is None:
            return value

        cloned = value.clone()
        cloned.transform(3857)

        return super().to_representation(cloned)

    def to_internal_value(self, value):
        geom = super().to_internal_value(value)
        geom.srid = 3857
        geom.transform(31370)
        return geom

Upvotes: 1

Related Questions