1

我正在使用 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)
4

2 回答 2

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=4326;POINT(-0.094833 51.520667)”扩展 WKT,您可以放入 SRID]

于 2012-05-08T15:21:41.183 回答
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()
于 2013-02-15T17:57:22.520 回答