简体   繁体   中英

How do I satisfy “enforce_srid_coordinate” constraint with GeoDjango/PostGIS?

I'm using GeoDjango and have a Django model with a PointField:

class ArchivrItem(models.Model):
    ...
    coordinate = models.PointField(srid=4326)

When I try to insert a new ArchivrItem, using latitude and longitude, I get this error:

ERROR:  new row for relation "archivr_archivritem" violates check constraint "enforce_srid_coordinate"

I can avoid Django and get the same error in postgresql directly by trying to do this:

INSERT INTO archivr_archivritem (coordinate) VALUES ('POINT(51.520667 -0.094833)');

I'm probably being naive and ignorant around SRID and point systems... what am I missing? Thanks.

UPDATE: I should add what the constraint is. The constraints on the table are:

"enforce_dims_coordinate" CHECK (st_ndims(coordinate) = 2)
"enforce_geotype_coordinate" CHECK (geometrytype(coordinate) = 'POINT'::text OR coordinate IS NULL)
"enforce_srid_coordinate" CHECK (st_srid(coordinate) = 4326)

It sounds like you're trying to add a new ArchivrItem by doing this:

item = ArchivrItem(coordinate='POINT(51.520667 -0.094833)')
item.save()

And this is not getting the right default SRID for some reason I'm not sure about. However, specifying it explicitly should work, eg:

from django.contrib.gis.geos import Point
item = ArchivrItem(coordinate=Point(-0.094833, 51.520667, srid=4326))
item.save()

I'd say the srid is optional if it's going to match the model definition, but no harm in specifying it, and you can see if simply using the object way fixes it anyway. https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#creating-and-saving-geographic-models has some more examples.

[Aside, note that POINT() is X then Y, ie lon then lat, not lat/lon. You can put a SRID in if it's extended WKT with "SRID=4326;POINT(-0.094833 51.520667)"]

After a colleague coming across the same issue, we appear to have tracked this down to an issue with the version of GEOS installed. Using a version with this problem, if p is a django.contrib.gis.geos.Point, p.wkb and p.ewkb return the same data - the EWKB lacks the SRID information. As Django uses EWKB to construct the SQL for import into PostGIS, this is why it fails, no matter the construction of the creation.

My previous comments were using Debian's 3.2.0 which does not show this issue at all. 3.2.3 is the version that is showing this issue here. Upgrading to 3.3.6 fixed the issue (and also tested 3.3.3 which is fine). I'll try other versions later today when I have more time to try and track it down further.

You can see your version of GEOS with:

from django.contrib.gis.geos.libgeos import geos_version
geos_version()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM