I'm trying to store a polygon using OSMGeoAdmin map widget and I've declared my admin class like this:
class ProjectAdmin(OSMGeoAdmin):
default_lon = 4600000
default_lat = 180000
default_zoom = 4
And this is my geometry models base class:
class AbstractGeometryModel(models.Model):
class Meta:
abstract = True
geometry = models.MultiPolygonField()
@property
def boundary(self):
boundary = self.geometry.boundary[0]
return [[x[1], x[0]] for x in boundary]
@property
def bbox(self):
box = self.geometry.extent
return [[box[1], box[0]], [box[3], box[2]]]
@property
def centroid(self):
return [self.geometry.centroid[1], self.geometry.centroid[0]]
As mentioned in Django docs, the default SRID should be 4326, and as I checked personally, when you get the extent of a geometry it's in [lat, lon, lat, lon]
format, and I needed them to be lon, lat
so I wrote those property methods.
The problem is, whenever I deploy my service in a new production env or bring it up from scratch in a local development environment, I see that the lat, lon
s are stored in reverse format.
to check this problem, I decided to compare the production database with my local development db, and here are the results:
>>> from django.contrib.gis.geos import GEOSGeometry
>>> production_data = GEOSGeometry('0106...(Geometry copied from production db)...1532')
>>> production_data.extent
(17.2922570380823, 44.879874515170165, 18.00644604063442, 46.02245264001086)
>>> production_data.srid
4326
>>> development_data = GEOSGeometry('0106...(Geometry copied from development db)...1532')
>>> development_data.extent
(44.75627832378126, 17.887728306166515, 46.09661035484472, 18.10414680358874)
>>> development_data.srid
4326
As you can see, the SRIDs are the same but data is stored as lat, lon
in production db, and also as lon, lat
in local db!
I tried to debug to find out what's going on, but I didn't succeed. I'll appreciate it if someone can help me with this problem. Thanks.
UPDATE I also run below code both in server and local python console:
local:
Python 3.8.3rc1 (default, May 10 2020, 12:11:09)
[GCC 7.4.0] on linux
Django 2.2.4
>>> from django.contrib.gis.geos import GEOSGeometry
>>> a = GEOSGeometry('SRID=3857;MULTIPOLYGON(((..lots of geo numbers...)))')
>>> a.transofrm(4326)
>>> a.extent
(34.109070627613065, 46.87535791416505, 36.24604033684087, 53.423209475753794)
server:
root@fdfd7ccf489b:/code# python manage.py shell
Python 3.7.6 (default, Feb 26 2020, 15:34:58)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.13.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from django.contrib.gis.geos import GEOSGeometry
In [2]: a = GEOSGeometry('SRID=3857;MULTIPOLYGON(((..lots of geo numbers...)))')
In [3]: a.extent
Out[3]: (5218140.9737573, 4043456.9660937, 5947044.4753833, 4334529.1697632)
In [4]: a.transform(4326)
In [5]: a.extent
Out[5]: (46.875357914165036, 34.10907062761305, 53.42320947575378, 36.246040336840856)
so it seems that problem is something related to the GeoDjango version or config...
It seems that the root source of the problem is different versions of GDAL installed on production (GDAL 2.4.0) and local (GDAL 3.0.1) environment.