Search code examples
djangogisgeodjango

Why does print show SRID 3847 in Geodjango?


I'm developing an app using Geodjango and PostGIS. In the admin area of my site, all polygons are displayed correctly with the (default) SRID of 4326 e.g.

SRID=4326;POLYGON ((0.6564331054687499 52.13854550670472, 0.6289672851562499 52.08456959594681, 0.7553100585937497 52.08456959594681, 0.6564331054687499 52.13854550670472))

Why, when I print to the web server/console does the SRID show in 3857? The above admin area polygon is printed as:

SRID=3857;POLYGON ((73073.79904062848 6825215.129639958, 70016.31790922143 6815431.190019455, 84080.73111369385 6815431.190019455, 73073.79904062848 6825215.129639958))

In addition, if I render the shapes into my template with e.g. {{geometry.polygon}} and {{geometry.buffer}} both are rendered with the correct SRID of 4326.

So it seems that when doing a print in views.py (or elsewhere) the polygon is printed in 3857.

Note that I'm using OSMWidget to get user-inputted polygons. However, I'm explictly defining the map's SRID with:

class jobForm(forms.ModelForm):
    location = PolygonField(
        widget=OSMWidget(
            attrs={'map_width': 800,
                   'map_height': 500,
                   'map_srid': 4326,
                   'template_name': 'gis/openlayers-osm.html',
                   'default_zoom':8,
                   'default_lat': 52,
                   'default_lon': 0.5}))

EDIT on 16/09/21 After some further experimentation, I think the issue is occurring in the space between form submission and committing the data to a model.

OSMWidget has an argument called map_srid which, ostensibly, is there to allow you to specify the SRID of the coordinates returned in your form. Thus, setting map_srid=4326 should return the coordinates in that format. However, it doesn't. If you print:

form.cleaned_data['my_geometry_field']

it will print in 3857, regardless of how you set map_srid.

Once you have committed the form's data to a model, it's converted to whatever SRID you've set on your field (by default 4326). If you do (pseudocode) mymodel.objects.get() and then print(my_model_field) you'll see your coordinates displayed in 4326 as you'd expect.

I'm therefore suspecting that there's a bug with OSMWidget. That or I'm completely misunderstanding how this form widget works.


Solution

  • Okay so, answering my own question here. This has taken a lot of teeth-gnashing and I'm not sure if I'm just being dense or there's a bug of sorts. For those who need it, the official Django documentation for geospatial fields can be found here.

    My understanding is that 'geospatial stuff' (using the term broadly here) in Django defaults to WGS84 (SRID 4326). Which I take to mean that, providing you don't go out of your way to override an argument/attribute, it'll default to 4326. For whatever reason, this doesn't seem to apply to GeoDjango form fields.

    Whereas above in my question I specfied my geospatial field as:

    class jobForm(forms.ModelForm):
        location = PolygonField(
            widget=OSMWidget(
                attrs={'map_width': 800,
                       'map_height': 500,
                       'map_srid': 4326,
                       'template_name': 'gis/openlayers-osm.html',
                       'default_zoom':8,
                       'default_lat': 52,
                       'default_lon': 0.5}))
    

    What I should have done is explictly set the SRID argument. Thus it should be:

    class jobForm(forms.ModelForm):
        location = PolygonField(
            srid=4326,
            widget=OSMWidget(
                attrs={'map_width': 800,
                       'map_height': 500,
                       'map_srid': 4326,
                       'template_name': 'gis/openlayers-osm.html',
                       'default_zoom':8,
                       'default_lat': 52,
                       'default_lon': 0.5}))
    

    I can't see any mention in the Django documentation as to why, if you don't specify an SRID in a form's geometry field it starts spitting out coordinates in 3857. But it does for...reasons. If there is a legitimate reason why this is the case--perhaps I've missed something in the docs--then I would genuinely like to know what's going on.