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

class GeometryField

几何字段的基本类。

PointField

PointField

存储一个 Point

LineStringField

LineStringField

存储一个 LineString

PolygonField

PolygonField

存储一个 Polygon

MultiPointField

MultiPointField

存储一个 MultiPoint

MultiLineStringField

MultiLineStringField

存储一个 MultiLineString

MultiPolygonField

MultiPolygonField

存储 MultiPolygon

GeometryCollectionField

GeometryCollectionField

存储 GeometryCollection

RasterField

RasterField

存储 GDALRaster

RasterField 目前仅针对 PostGIS 后端实现。

空间字段选项

除了可用于 Django 模型字段的常规 字段选项 外,空间字段还有以下附加选项。所有选项均为可选。

srid

BaseSpatialField.srid

将几何字段的 SRID [2](空间参考系统标识)设置为给定值。默认为 4326(也称为 WGS84,单位为经度和纬度的度数)。

选择 SRID

为模型选择合适的 SRID 是开发人员应仔细考虑的重要决策。SRID 是一个整数说明符,它对应于用于解释空间数据库中数据的投影系统。 [3] 投影系统为指定位置的坐标提供上下文。尽管 大地测量学 的详细信息超出了本说明文件的范围,但一般问题是地球是球形的,而地球的表示(例如,纸质地图、网络地图)不是。

大多数人都熟悉使用纬度和经度来参考地球表面的位置。但是,纬度和经度是角度,不是距离。换句话说,虽然平面上两点之间的最短路径是一条直线,但曲面上(例如地球)两点之间的最短路径是 大圆[4] 因此,需要进行额外的计算才能获得平面单位(例如,公里和英里)的距离。稍后,使用地理坐标系可能会给开发人员带来复杂性。例如,SpatiaLite 无法使用地理坐标系在几何体之间执行距离计算,例如构建一个查询以查找存储为 WGS84 的县界内 5 英里范围内的所有点。 [5]

地球表面的部分可以投影到二维或笛卡尔平面上。投影坐标系对于特定区域的应用程序特别方便,例如,如果您知道您的数据库将仅覆盖北堪萨斯州中的几何图形,那么您可以考虑使用特定于该区域的投影系统。此外,投影坐标系以笛卡尔单位(如米或英尺)定义,简化了距离计算。

注意

如果您希望在 PostGIS 中使用非点几何图形执行任意距离查询,并且您希望获得良好的性能,请启用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 类型

geography 类型为用地理坐标(例如,WGS84 经度/纬度)表示的空间要素提供本机支持。 [6] 与 geometry 类型使用的平面不同,geography 类型使用球面表示其数据。在地理列上执行的距离和测量操作会自动采用大圆弧计算并返回线性单位。换句话说,当对两个地理调用 ST_Distance 时,将返回以米为单位的值(如果在 WGS84 中对 geometry 列调用,则返回以度为单位的值)。

由于地理计算涉及更多数学,因此仅 PostGIS 空间查找的子集可用于 geography 类型。实际上,这意味着除了 距离查找 之外,仅以下附加 空间查找 可用于 geography 列

如果您需要使用不支持地理类型作为输入的空间查找或聚合,则可以使用 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 文档包含一个有用的部分,用于确定 何时使用地理数据类型而不是几何数据类型

脚注

[1]OpenGIS Consortium, Inc.,适用于 SQL 的简单要素规范
[2]请参见 id. 第 2.3.8 章,第 39 页(几何值和空间参考系统)。
[3]通常,SRID 整数对应于 EPSG (欧洲石油勘测组) 标识符。但是,它也可能与空间数据库的空间参考系统表中定义的自定义投影相关联。
[4]Terry A. Slocum、Robert B. McMaster、Fritz C. Kessler 和 Hugh H. Howard,专题制图和地理可视化(Prentice Hall,第 2 版),第 7.1.3 章。
[5]此限制不适用于 PostGIS。
[6]有关更多详细信息,请参阅 PostGIS 地理类型 文档。
返回顶部