GeoDjango 模型 API¶
本文档探讨了 GeoDjango 模型 API 的细节。在本节中,我们将使用以下地理模型作为示例:邮政编码 和 数字高程模型
from django.contrib.gis.db import models
class Zipcode(models.Model):
code = models.CharField(max_length=5)
poly = models.PolygonField()
class Elevation(models.Model):
name = models.CharField(max_length=100)
rast = models.RasterField()
空间字段类型¶
空间字段包含一系列几何字段类型和一个栅格字段类型。每个几何字段类型都对应于 OpenGIS 简单要素规范 [1]。栅格数据没有此类标准。
GeometryField
¶
几何字段的基类。
PointField
¶
存储一个 Point
。
LineStringField
¶
存储一个 LineString
。
PolygonField
¶
存储一个 Polygon
。
MultiPointField
¶
存储一个 MultiPoint
。
MultiLineStringField
¶
存储一个 MultiLineString
。
MultiPolygonField
¶
存储一个 MultiPolygon
。
GeometryCollectionField
¶
存储一个 GeometryCollection
。
RasterField
¶
存储一个 GDALRaster
。
RasterField
目前仅在 PostGIS 后端实现。
空间字段选项¶
除了 Django 模型字段可用的常规 字段选项 之外,空间字段还有以下附加选项。所有选项都是可选的。
srid
¶
- BaseSpatialField.srid¶
将几何字段的 SRID [2](空间参考系统标识)设置为给定值。默认为 4326(也称为 WGS84,单位为经度和纬度的度数)。
选择 SRID¶
为您的模型选择合适的 SRID 是开发人员应仔细考虑的重要决定。SRID 是一个整数说明符,对应于将用于解释空间数据库中数据的投影系统。[3] 投影系统为指定位置的坐标提供上下文。虽然 大地测量学 的细节超出了本文档的范围,但一般问题是地球是球形的,而地球的表示(例如,纸质地图、网络地图)则不是。
大多数人都熟悉使用经纬度来参考地球表面的位置。但是,经纬度是角度,而不是距离。换句话说,虽然平面上两点之间的最短路径是直线,但曲面上(例如地球)两点之间的最短路径是 大圆 的弧。[4] 因此,需要额外的计算才能获得平面单位(例如,公里和英里)的距离。使用地理坐标系可能会在以后给开发人员带来复杂性。例如,SpatiaLite 没有使用地理坐标系在几何图形之间执行距离计算的功能,例如构造查询以查找存储为 WGS84 的县边界 5 英里内的所有点。[5]
地球表面的部分可以投影到二维或笛卡尔平面上。投影坐标系对于特定区域的应用程序特别方便,例如,如果您知道您的数据库只覆盖 堪萨斯州北部 的几何图形,那么您可以考虑使用特定于该区域的投影系统。此外,投影坐标系以笛卡尔单位(例如米或英尺)定义,简化了距离计算。
注意
如果您希望在 PostGIS 中使用 WGS84 中的非点几何体执行任意距离查询并希望获得不错的性能,请启用 GeometryField.geography
关键字,以便使用 地理数据库类型。
附加资源
spatialreference.org:一个由 Django 驱动的空间参考系统数据库。
州平面坐标系统:一个涵盖美国使用的各种投影系统的网站。遇到的许多美国空间数据都将采用这些坐标系统之一,而不是地理坐标系统(如 WGS84)。
spatial_index
¶
- BaseSpatialField.spatial_index¶
默认为 True
。为给定的几何字段创建空间索引。
注意
这与 db_index
字段选项不同,因为空间索引的创建方式与常规数据库索引不同。具体来说,空间索引通常使用 R 树的变体创建,而常规数据库索引通常使用 B 树。
几何字段选项¶
几何字段还提供其他选项。以下所有选项都是可选的。
dim
¶
- GeometryField.dim¶
此选项可用于自定义几何字段的坐标维度。默认情况下,它设置为 2,用于表示二维几何体。对于支持它的空间后端,可以将其设置为 3 以支持三维。
注意
目前,3D 支持仅限于 PostGIS 和 SpatiaLite 后端。
geography
¶
- GeometryField.geography¶
如果设置为 True
,此选项将创建一个 geography 类型的数据库列,而不是 geometry 类型。请参阅下面的 geography 类型 部分了解更多详细信息。
注意
Geography 支持限于 PostGIS,并将强制 SRID 为 4326。
地理类型¶
geography 类型为以地理坐标(例如,WGS84 经度/纬度)表示的空间要素提供本机支持。[6] 与 geometry 类型使用的平面不同,geography 类型使用其数据的球面表示。对 geography 列执行的距离和测量操作会自动采用大圆弧计算并返回线性单位。换句话说,当对两个地理位置调用 ST_Distance
时,会返回米值(如果在 WGS84 中的 geometry 列上调用,则返回度值)。
由于地理计算涉及更多数学运算,因此 geography 类型仅支持 PostGIS 空间查找的一个子集。实际上,这意味着除了 距离查找 之外,geography 列还仅支持以下附加 空间查找:
如果您需要使用不支持 geography 类型作为输入的空间查找或聚合,则可以使用 Cast
数据库函数将查询中的 geography 列转换为 geometry 类型。
from django.contrib.gis.db.models import PointField
from django.db.models.functions import Cast
Zipcode.objects.annotate(geom=Cast("geography_field", PointField())).filter(
geom__within=poly
)
有关更多信息,PostGIS 文档包含一个关于确定 何时在 geometry 数据类型上使用 geography 数据类型 的有用部分。
脚注