如何使用GeoDjango / PostGIS满足“enforce_srid_coordinate”约束?

时间:2012-05-07 17:10:41

标签: django postgresql postgis geodjango

我使用GeoDjango并使用带有PointField的Django模型:

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

当我尝试使用纬度和经度插入新的ArchivrItem时,我收到此错误:

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

我可以通过尝试执行此操作来避免Django直接在postgresql中获得相同的错误:

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

我可能对SRID和点系统天真无知......我错过了什么?感谢。

更新:我应该添加约束条件。表格的限制是:

"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)

2 个答案:

答案 0 :(得分:1)

听起来你正试图通过这样做来添加一个新的ArchivrItem:

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

由于某些我不确定的原因,这并没有获得正确的默认SRID。但是,明确指定它应该有效,例如:

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

我会说srid是可选的,如果它与模型定义相匹配,但在指定它时没有任何害处,你可以看看是否只是简单地使用对象方式来修复它。 https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#creating-and-saving-geographic-models还有一些例子。

[除此之外,请注意POINT()是X然后是Y,即lon然后是lat,而不是lat / lon。如果SRID扩展为WKT并且“SRID = 4326; POINT(-0.094833 51.520667)”,则可以输入SRID

答案 1 :(得分:0)

在一位同事遇到同一问题后,我们似乎已将此问题跟踪到安装了GEOS版本的问题。使用具有此问题的版本,如果p是django.contrib.gis.geos.Point,p.wkb和p.ewkb返回相同的数据 - EWKB缺少SRID信息。由于Django使用EWKB构建SQL以导入到PostGIS中,因此无论构建如何构建它都会失败。

我之前的评论使用的是Debian的3.2.0,它根本没有显示这个问题。 3.2.3是这里显示此问题的版本。升级到3.3.6修复了问题(并且还测试了3.3.3,这很好)。我今天晚些时候会尝试其他版本,因为我有更多时间尝试进一步跟踪它。

您可以通过以下方式查看您的GEOS版本:

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