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

class GeometryField[source]

几何字段的基类。

PointField

class PointField[source]

存储一个 Point

LineStringField

class LineStringField[source]

存储一个 LineString

PolygonField

class PolygonField[source]

存储一个 Polygon

MultiPointField

class MultiPointField[source]

存储一个 MultiPoint

MultiLineStringField

class MultiLineStringField[source]

存储一个 MultiLineString

MultiPolygonField

class MultiPolygonField[source]

存储一个 MultiPolygon

GeometryCollectionField

class GeometryCollectionField[source]

存储一个 GeometryCollection

RasterField

class RasterField[source]

存储一个 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 文档中关于确定 何时使用地理数据类型而不是几何数据类型 的有用部分。

脚注

Back to Top