为什么打印在 Geodjango 中显示 SRID 3847?

Why does print show SRID 3847 in Geodjango?

我正在使用 Geodjango 和 PostGIS 开发应用程序。在我网站的管理区域,所有多边形都正确显示,(默认)SRID 为 4326,例如

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

为什么,当我 print 上网时 server/console SRID 显示在 3857 中?上面的管理区域多边形打印为:

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

此外,如果我将形状渲染到我的模板中,例如{{geometry.polygon}}{{geometry.buffer}} 都使用正确的 SRID 4326 呈现。

所以似乎在 views.py(或其他地方)中执行 print 时,多边形打印为 3857。

请注意,我使用 OSMWidget 来获取用户输入的多边形。但是,我明确定义了地图的 SRID:

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

编辑于 21 年 9 月 16 日 经过一些进一步的实验,我认为问题出现在表单提交和将数据提交到模型之间的space。

OSMWidget 有一个名为 map_srid 的参数,从表面上看,它允许您在表单中指定坐标 returned 的 SRID。因此,设置 map_srid=4326 应该 return 该格式的坐标。然而,事实并非如此。如果你打印:

form.cleaned_data['my_geometry_field']

不管你怎么设置都会打印3857map_srid

一旦您将表单数据提交给模型,它就会转换为您在字段中设置的任何 SRID(默认为 4326)。如果你这样做(伪代码)mymodel.objects.get() 然后 print(my_model_field) 你会看到你的坐标显示在 4326 中,正如你所期望的那样。

因此我怀疑 OSMWidget 存在错误。那或者我完全误解了这个表单小部件的工作原理。

好的,在这里回答我自己的问题。这让我咬牙切齿了很多,我不确定我是不是太笨了还是有某种错误。对于那些需要它的人,可以找到关于地理空间字段的官方 Django 文档 here.

我的理解是 Django 中的 'geospatial stuff'(此处广泛使用该术语)默认为 WGS84 (SRID 4326)。我的意思是,如果您不特意覆盖 argument/attribute,它将默认为 4326。无论出于何种原因,这似乎不适用于 GeoDjango 表单字段。

而在我上面的问题中,我将我的地理空间字段指定为:

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

我应该做的是明确设置 SRID 参数。因此它应该是:

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

我在 Django 文档中看不到任何关于为什么的提及,如果您不在表单的几何字段中指定 SRID,它会开始在 3857 中吐出坐标。但它确实是出于...原因。如果出现这种情况有正当理由——也许我遗漏了文档中的某些内容——那么我真的很想知道发生了什么。

尽管如此,我也遇到了这个问题,但无法通过如上所述将 SRID 参数明确指定为 4356 来纠正它。这是使用 Django 4.0.

经过一番尝试,我不得不使用 OSGEO 包手动转换它并添加一个小函数来处理它:

from osgeo import ogr, osr

def convert_3857_to_4326 (coords_3857):


# create Geometry Object
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(coords_3857.coords[0], coords_3857.coords[1])
# create coordinate transformation
inSpatialRef = osr.SpatialReference()
inSpatialRef.ImportFromEPSG(3857)
outSpatialRef = osr.SpatialReference()
outSpatialRef.ImportFromEPSG(4326)

coordTransform = osr.CoordinateTransformation(inSpatialRef, outSpatialRef)
# transform point
point.Transform(coordTransform)

# print point in EPSG 4326
print (point.GetX(), point.GetY())

return point