GeoDjango 模型 API¶
本文探讨了 GeoDjango 模型 API 的详细内容。在本节中,我们将使用以下地理模型作为示例,包括一个 ZIP code 和一个 Digital Elevation Model。
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 Simple Features 规范 [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]
地球表面的部分区域可以投影到二维或笛卡尔平面上。投影坐标系统对于区域特定的应用特别方便,例如,如果您知道您的数据库只涵盖了 北堪萨斯 的几何体,那么您可以考虑使用针对该地区的投影系统。此外,投影坐标系统是用笛卡尔单位(例如米或英尺)定义的,使距离计算更加方便。
Note
如果您希望在 PostGIS 中使用 WGS84 中的非点几何体执行任意距离查询,并且希望获得良好的性能,请启用 GeometryField.geography
关键字,以便使用 地理数据库类型。
其他资源:
spatialreference.org:一个由 Django 驱动的空间参考系统数据库。
The State Plane Coordinate System:一个涵盖美国使用的各种投影系统的网站。在美国遇到的大部分空间数据将采用这些坐标系统之一,而不是像 WGS84 这样的地理坐标系统。
spatial_index
¶
- BaseSpatialField.spatial_index¶
默认为 True
。为给定的几何字段创建一个空间索引。
Note
这与 db_index
字段选项不同,因为空间索引是以与常规数据库索引不同的方式创建的。具体而言,空间索引通常是使用 R-Tree 的变种创建的,而常规数据库索引通常使用 B-Tree。
几何字段选项¶
几何字段还有其他可用的选项。以下所有选项都是可选的。
dim
¶
- GeometryField.dim¶
此选项可用于自定义几何字段的坐标维度。默认情况下,它设置为 2,用于表示二维几何体。对于支持的空间后端,它可以设置为 3,以支持三维。
Note
目前,对三维的支持仅限于 PostGIS 和 SpatiaLite 后端。
geography
¶
- GeometryField.geography¶
如果设置为 True
,此选项将创建一个数据库列,其类型为 geography,而不是 geometry。有关更多详细信息,请参阅下面的 地理类型 部分。
Note
地理支持仅限于 PostGIS,并且会强制将 SRID 设置为 4326。
地理类型¶
地理类型提供对使用地理坐标表示的空间要素的本地支持(例如,WGS84 经度/纬度)。[6] 与几何类型使用的平面不同,地理类型使用其数据的球面表示。对地理列执行的距离和测量操作会自动采用大圆弧计算,并返回线性单位。换句话说,当对两个地理要素调用 ST_Distance
时,将返回以米为单位的值(与在 WGS84 中对几何列调用时返回的度数不同)。
由于地理计算涉及更多的数学运算,因此地理类型仅支持 PostGIS 空间查询的子集。实际上,这意味着除了 距离查询 之外,地理列仅支持以下其他 空间查询:
如果您需要使用不支持地理类型作为输入的空间查询或聚合函数,您可以在查询中使用 Cast
数据库函数将地理列转换为几何类型:
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 文档中关于确定 何时使用地理数据类型而不是几何数据类型 的有用部分。
脚注