---
title: "地理数据库函数"
version: 5.0
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/5.0/ref/contrib/gis/functions/
canonical: https://djangodocs.dev/zh-hans/5.0/ref/contrib/gis/functions/
---
# 地理数据库函数

本页所描述的函数允许用户访问地理数据库函数，以便在 Django 中使用注释、聚合或过滤器。

例如：

```pycon
>>> from django.contrib.gis.db.models.functions import Length
>>> Track.objects.annotate(length=Length("line")).filter(length__gt=100)
```

并非所有的后端都支持所有的函数，所以请参考每个函数的文档，看看你的数据库后端是否支持你要使用的函数。如果你在一个不支持地理函数的后台调用该函数，你会得到一个 `NotImplementedError` 异常。

函数的摘要：

| 测量 | 关系映射 | 操作 | 编辑器 | 输入格式： | 输出格式 | 杂项 |
| --- | --- | --- | --- | --- | --- | --- |
| [`Area`](#django.contrib.gis.db.models.functions.Area) | [`Azimuth`](#django.contrib.gis.db.models.functions.Azimuth) | [`Difference`](#django.contrib.gis.db.models.functions.Difference) | [`ForcePolygonCW`](#django.contrib.gis.db.models.functions.ForcePolygonCW) |  | [`AsGeoJSON`](#django.contrib.gis.db.models.functions.AsGeoJSON) | [`IsEmpty`](#django.contrib.gis.db.models.functions.IsEmpty) |
| [`Distance`](#django.contrib.gis.db.models.functions.Distance) | [`BoundingCircle`](#django.contrib.gis.db.models.functions.BoundingCircle) | [`Intersection`](#django.contrib.gis.db.models.functions.Intersection) | [`MakeValid`](#django.contrib.gis.db.models.functions.MakeValid) |  | [`AsGML`](#django.contrib.gis.db.models.functions.AsGML) | [`IsValid`](#django.contrib.gis.db.models.functions.IsValid) |
| [`GeometryDistance`](#django.contrib.gis.db.models.functions.GeometryDistance) | [`Centroid`](#django.contrib.gis.db.models.functions.Centroid) | [`SymDifference`](#django.contrib.gis.db.models.functions.SymDifference) | [`Reverse`](#django.contrib.gis.db.models.functions.Reverse) |  | [`AsKML`](#django.contrib.gis.db.models.functions.AsKML) | [`MemSize`](#django.contrib.gis.db.models.functions.MemSize) |
| [`Length`](#django.contrib.gis.db.models.functions.Length) | [`ClosestPoint`](#django.contrib.gis.db.models.functions.ClosestPoint) | [`Union`](#django.contrib.gis.db.models.functions.Union) | [`Scale`](#django.contrib.gis.db.models.functions.Scale) |  | [`AsSVG`](#django.contrib.gis.db.models.functions.AsSVG) | [`NumGeometries`](#django.contrib.gis.db.models.functions.NumGeometries) |
| [`Perimeter`](#django.contrib.gis.db.models.functions.Perimeter) | [`Envelope`](#django.contrib.gis.db.models.functions.Envelope)<br>[`LineLocatePoint`](#django.contrib.gis.db.models.functions.LineLocatePoint)<br>[`PointOnSurface`](#django.contrib.gis.db.models.functions.PointOnSurface) |  | [`SnapToGrid`](#django.contrib.gis.db.models.functions.SnapToGrid)<br>[`Transform`](#django.contrib.gis.db.models.functions.Transform)<br>[`Translate`](#django.contrib.gis.db.models.functions.Translate) | [`FromWKB`](#django.contrib.gis.db.models.functions.FromWKB)<br>[`FromWKT`](#django.contrib.gis.db.models.functions.FromWKT) | [`AsWKB`](#django.contrib.gis.db.models.functions.AsWKB)<br>[`AsWKT`](#django.contrib.gis.db.models.functions.AsWKT)<br>[`GeoHash`](#django.contrib.gis.db.models.functions.GeoHash) | [`NumPoints`](#django.contrib.gis.db.models.functions.NumPoints) |

## `Area`

#### `class Area(expression, **extra)`

*可用性*：MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-polygon-property-functions.html#function_st-area), Oracle, [PostGIS](https://postgis.net/docs/ST_Area.html), SpatiaLite

接受单个地理字段或表达式，并将字段的面积作为一个 [`Area`](/zh-hans/5.0/ref/contrib/gis/measure/#django.contrib.gis.measure.Area) 测量返回。

在没有 LWGEOM/RTTOPO 支持的情况下，MySQL 和 SpatiaLite 不支持对地理 SRS（空间参考系统）进行面积计算。

## `AsGeoJSON`

#### `class AsGeoJSON(expression, bbox=False, crs=False, precision=8, **extra)`

*可用性*：MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/spatial-geojson-functions.html#function_st-asgeojson), Oracle, [PostGIS](https://postgis.net/docs/ST_AsGeoJSON.html), SpatiaLite

接受单个地理字段或表达式，并返回几何形状的 [GeoJSON](https://geojson.org/) 表示。请注意，结果不是完整的 GeoJSON 结构，而只是 GeoJSON 结构中 `geometry` 键的内容。另请参阅 [GeoJSON 序列化器](/zh-hans/5.0/ref/contrib/gis/serializers/)。

例如：

```pycon
>>> City.objects.annotate(json=AsGeoJSON("point")).get(name="Chicago").json
{"type":"Point","coordinates":[-87.65018,41.85039]}
```

| 关键字参数 | 描述 |
| --- | --- |
| `bbox` | 如果希望包含返回的 GeoJSON 中的边界框，请将其设置为 `True`。在 Oracle 中会被忽略。 |
| `crs` | 如果希望在返回的 GeoJSON 中包含坐标参考系统，请将其设置为 `True`。在 MySQL 和 Oracle 中会被忽略。 |
| `precision` | 可以用来指定 GeoJSON 表示中坐标的有效数字位数，其默认值为 8。在 Oracle 中会被忽略。 |

## `AsGML`

#### `class AsGML(expression, version=2, precision=8, **extra)`

*可用性*：Oracle, [PostGIS](https://postgis.net/docs/ST_AsGML.html), SpatiaLite

接受单个地理字段或表达式，并返回几何形状的 [Geographic Markup Language (GML)](https://en.wikipedia.org/wiki/Geography_Markup_Language) 表示。

例如：

```pycon
>>> qs = Zipcode.objects.annotate(gml=AsGML("poly"))
>>> print(qs[0].gml)
<gml:Polygon srsName="EPSG:4326"><gml:OuterBoundaryIs>-147.78711,70.245363 ...
-147.78711,70.245363</gml:OuterBoundaryIs></gml:Polygon>
```

| 关键字参数 | 描述 |
| --- | --- |
| `precision` | 指定在 GML 表示中坐标的有效数字位数，默认值为 8。在 Oracle 中会被忽略。 |
| `version` | 指定要使用的 GML 版本：2（默认）或 3。 |

## `AsKML`

#### `class AsKML(expression, precision=8, **extra)`

*可用性*：[PostGIS](https://postgis.net/docs/ST_AsKML.html), SpatiaLite

接受单个地理字段或表达式，并返回几何形状的 [Keyhole Markup Language (KML)](https://developers.google.com/kml/documentation/) 表示。

例如：

```pycon
>>> qs = Zipcode.objects.annotate(kml=AsKML("poly"))
>>> print(qs[0].kml)
<Polygon><outerBoundaryIs><LinearRing><coordinates>-103.04135,36.217596,0 ...
-103.04135,36.217596,0</coordinates></LinearRing></outerBoundaryIs></Polygon>
```

| 关键字参数 | 描述 |
| --- | --- |
| `precision` | 可以使用此关键字来指定 KML 表示中坐标的有效数字位数，其默认值为 8。 |

## `AsSVG`

#### `class AsSVG(expression, relative=False, precision=8, **extra)`

*可用性*：[PostGIS](https://postgis.net/docs/ST_AsSVG.html), SpatiaLite

接受单个地理字段或表达式，并返回几何形状的 [Scalable Vector Graphics (SVG)](https://www.w3.org/Graphics/SVG/) 表示。

| 关键字参数 | 描述 |
| --- | --- |
| `relative` | 如果设置为 `True`，路径数据将以相对移动的方式实现。默认为 `False`，表示使用绝对移动。 |
| `precision` | 可以使用此关键字来指定 SVG 表示中坐标的有效数字位数，其默认值为 8。 |

## `AsWKB`

#### `class AsWKB(expression, **extra)`

*可用性*：MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-format-conversion-functions.html#function_st-asbinary), Oracle, [PostGIS](https://postgis.net/docs/ST_AsBinary.html), SpatiaLite

接受单个地理字段或表达式，并返回几何形状的 [Well-known binary (WKB)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary) 表示。

例如：

```pycon
>>> bytes(City.objects.annotate(wkb=AsWKB("point")).get(name="Chelyabinsk").wkb)
b'\x01\x01\x00\x00\x00]3\xf9f\x9b\x91K@\x00X\x1d9\xd2\xb9N@'
```

## `AsWKT`

#### `class AsWKT(expression, **extra)`

*可用性*：MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-format-conversion-functions.html#function_st-astext), Oracle, [PostGIS](https://postgis.net/docs/ST_AsText.html), SpatiaLite

接受单个地理字段或表达式，并返回几何形状的 [Well-known text (WKT)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) 表示。

例如：

```pycon
>>> City.objects.annotate(wkt=AsWKT("point")).get(name="Chelyabinsk").wkt
'POINT (55.137555 61.451728)'
```

## `Azimuth`

#### `class Azimuth(point_a, point_b, **extra)`

*可用性*：[PostGIS](https://postgis.net/docs/ST_Azimuth.html), SpatiaLite (LWGEOM/RTTOPO)

返回由给定点几何形状定义的线段的方位角（以弧度表示），如果两个点重合，则返回 `None`。方位角是以北方为参考的角度，顺时针方向为正：north = `0`; east = `π/2`; south = `π`; west = `3π/2`。

## `BoundingCircle`

#### `class BoundingCircle(expression, num_seg=48, **extra)`

*可用性*：[PostGIS](https://postgis.net/docs/ST_MinimumBoundingCircle.html), [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/spatl/SDO_GEOM-reference.html#GUID-82A61626-BB64-4793-B53D-A0DBEC91831A)

接受单个地理字段或表达式，并返回可以完全包含几何形状的最小圆形多边形。

`num_seg` 参数仅在 PostGIS 中使用。

## `Centroid`

#### `class Centroid(expression, **extra)`

*可用性*：MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-polygon-property-functions.html#function_st-centroid), [PostGIS](https://postgis.net/docs/ST_Centroid.html), Oracle, SpatiaLite

接受单个地理字段或表达式，并返回几何形状的 `centroid` 值。

## `ClosestPoint`

> **New in Django 5.0**

#### `class ClosestPoint(expr1, expr2, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_ClosestPoint.html), SpatiaLite

接受两个地理字段或表达式，并返回在几何体 A 上最接近几何体 B 的二维点。

## `Difference`

#### `class Difference(expr1, expr2, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/spatial-operator-functions.html#function_st-difference), [PostGIS](https://postgis.net/docs/ST_Difference.html), Oracle, SpatiaLite

接受两个地理字段或表达式，并返回几何差异，即几何 A 中与几何 B 不相交的部分。

## `Distance`

#### `class Distance(expr1, expr2, spheroid=None, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/spatial-relation-functions-object-shapes.html#function_st-distance), [PostGIS](https://postgis.net/docs/ST_Distance.html), Oracle, SpatiaLite

接受两个地理字段或表达式，并返回它们之间的距离，作为一个 [`Distance`](/zh-hans/5.0/ref/contrib/gis/measure/#django.contrib.gis.measure.Distance) 对象。在 MySQL 上，当坐标是大地测量时，会返回原始的浮点值。

在支持大地测量坐标距离计算的后端上，根据几何形状的 SRID 值，会自动选择合适的后端函数（例如，在 PostGIS 上使用 [ST\_DistanceSphere](https://postgis.net/docs/ST_DistanceSphere.html)）。

当使用大地测量（角度）坐标计算距离时，例如默认的 WGS84 (4326) SRID，您可以设置 `spheroid` 关键字参数来决定计算是基于简单球体（精度较低，资源消耗较少）还是基于椭球体（精度较高，资源消耗较多）。

在以下示例中，计算了从霍巴特市到 `AustraliaCity` 查询集中的每个其他 [`PointField`](/zh-hans/5.0/ref/contrib/gis/model-api/#django.contrib.gis.db.models.PointField) 的距离：

```pycon
>>> from django.contrib.gis.db.models.functions import Distance
>>> pnt = AustraliaCity.objects.get(name="Hobart").point
>>> for city in AustraliaCity.objects.annotate(distance=Distance("point", pnt)):
...     print(city.name, city.distance)
...
Wollongong 990071.220408 m
Shellharbour 972804.613941 m
Thirroul 1002334.36351 m
...
```

> **Note**
>
> 因为 `distance` 属性是一个 [`Distance`](/zh-hans/5.0/ref/contrib/gis/measure/#django.contrib.gis.measure.Distance) 对象，您可以轻松地以您选择的单位表示该值。例如，`city.distance.mi` 表示英里中的距离值，`city.distance.km` 表示千米中的距离值。有关用法详细信息和支持的单位列表，请参阅 [测量对象](/zh-hans/5.0/ref/contrib/gis/measure/)。

## `Envelope`

#### `class Envelope(expression, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-general-property-functions.html#function_st-envelope), [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/spatl/spatial-operators-reference.html#GUID-ACED800F-3435-44AA-9606-D40934A23ED0), [PostGIS](https://postgis.net/docs/ST_Envelope.html), SpatiaLite

接受单个地理字段或表达式，并返回表示几何形状的边界框的几何形状。

## `ForcePolygonCW`

#### `class ForcePolygonCW(expression, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_ForcePolygonCW.html), SpatiaLite

接受单个地理字段或表达式，并返回多边形/多多边形的修改版本，其中所有外部环都按顺时针方向排列，所有内部环都按逆时针方向排列。非多边形几何形状保持不变。

## `FromWKB`

> **New in Django 4.2**

#### `class FromWKB(expression, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-wkb-functions.html#function_st-geomfromwkb), Oracle, [PostGIS](https://postgis.net/docs/ST_GeomFromWKB.html), SpatiaLite

从 [Well-known binary (WKB)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary) 表示创建几何形状。

## `FromWKT`

> **New in Django 4.2**

#### `class FromWKT(expression, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-wkt-functions.html#function_st-geomfromtext), Oracle, [PostGIS](https://postgis.net/docs/ST_GeomFromText.html), SpatiaLite

从 [Well-known text (WKT)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) 表示创建几何形状。

## `GeoHash`

#### `class GeoHash(expression, precision=None, **extra)`

*可用性*: [MySQL](https://dev.mysql.com/doc/refman/en/spatial-geohash-functions.html#function_st-geohash), [PostGIS](https://postgis.net/docs/ST_GeoHash.html), SpatiaLite (LWGEOM/RTTOPO)

接受单个地理字段或表达式，并返回几何形状的 [GeoHash](https://en.wikipedia.org/wiki/Geohash) 表示。

`precision` 关键字参数控制结果中的字符数。

## `GeometryDistance`

#### `class GeometryDistance(expr1, expr2, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/geometry_distance_knn.html)

接受两个地理字段或表达式，并返回它们之间的距离。当在 [`order_by()`](/zh-hans/5.0/ref/models/querysets/#django.db.models.query.QuerySet.order_by) 子句中使用时，它提供了辅助索引的最近邻结果集。

## `Intersection`

#### `class Intersection(expr1, expr2, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/spatial-operator-functions.html#function_st-intersection), [PostGIS](https://postgis.net/docs/ST_Intersection.html), Oracle, SpatiaLite

接受两个地理字段或表达式，并返回它们之间的几何交集。

## `IsEmpty`

> **New in Django 4.2**

#### `class IsEmpty(expr)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_IsEmpty.html)

接受地理字段或表达式，并测试其值是否为空几何形状。如果其值为空，则返回 `True`，否则返回 `False`。

## `IsValid`

#### `class IsValid(expr)`

*可用性*: [MySQL](https://dev.mysql.com/doc/refman/en/spatial-convenience-functions.html#function_st-isvalid), [PostGIS](https://postgis.net/docs/ST_IsValid.html), Oracle, SpatiaLite

接受地理字段或表达式，并测试其值是否格式正确。如果其值是有效的几何形状，则返回 `True`，否则返回 `False`。

## `Length`

#### `class Length(expression, spheroid=True, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-linestring-property-functions.html#function_st-length), Oracle, [PostGIS](https://postgis.net/docs/ST_Length.html), SpatiaLite

接受单个地理线串或多线串字段或表达式，并将其长度返回为 [`Distance`](/zh-hans/5.0/ref/contrib/gis/measure/#django.contrib.gis.measure.Distance) 测量。

在 PostGIS 和 SpatiaLite 上，当坐标是大地测量（角度）时，您可以使用 `spheroid` 关键字参数来指定计算是基于简单球体（精度较低，资源消耗较少）还是基于椭球体（精度较高，资源消耗较多）。

MySQL 不支持在地理 SRS 上进行长度计算。

## `LineLocatePoint`

#### `class LineLocatePoint(linestring, point, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_LineLocatePoint.html), SpatiaLite

返回一个介于 0 和 1 之间的浮点数，表示最接近给定的 `point` 在 `linestring` 上的位置，作为 2D 线长度的一部分。

## `MakeValid`

#### `class MakeValid(expr)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_MakeValid.html), SpatiaLite (LWGEOM/RTTOPO)

接受地理字段或表达式，并尝试将值转换为有效的几何形状，同时不丢失任何输入顶点。已经有效的几何形状将保持不变。简单多边形可能会变成多重多边形，结果的维度可能比输入低。

## `MemSize`

#### `class MemSize(expression, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_MemSize.html)

接受单个地理字段或表达式，并返回几何字段占用的内存大小（字节数）。

## `NumGeometries`

#### `class NumGeometries(expression, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-geometrycollection-property-functions.html#function_st-numgeometries), [PostGIS](https://postgis.net/docs/ST_NumGeometries.html), Oracle, SpatiaLite

接受单个地理字段或表达式，并返回如果几何字段是集合（例如 `GEOMETRYCOLLECTION` 或 `MULTI*` 字段）则包含的几何形状数量。对于单个几何形状，返回 1。

在 MySQL 上，对于单个几何形状，返回 `None`。

## `NumPoints`

#### `class NumPoints(expression, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/gis-linestring-property-functions.html#function_st-numpoints), [PostGIS](https://postgis.net/docs/ST_NPoints.html), Oracle, SpatiaLite

接受单个地理字段或表达式，并返回几何形状中点的数量。

在 MySQL 上，对于任何非 `LINESTRING` 几何形状，返回 `None`。

## `Perimeter`

#### `class Perimeter(expression, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_Perimeter.html), Oracle, SpatiaLite

接受单个地理字段或表达式，并将几何字段的周长返回为 [`Distance`](/zh-hans/5.0/ref/contrib/gis/measure/#django.contrib.gis.measure.Distance) 对象。

## `PointOnSurface`

#### `class PointOnSurface(expression, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_PointOnSurface.html), MariaDB, Oracle, SpatiaLite

接受单个地理字段或表达式，并返回一个保证位于字段表面上的 `Point` 几何形状；否则返回 `None`。

## `Reverse`

#### `class Reverse(expression, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_Reverse.html), Oracle, SpatiaLite

接受单个地理字段或表达式，并返回具有颠倒坐标的几何形状。

## `Scale`

#### `class Scale(expression, x, y, z=0.0, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_Scale.html), SpatiaLite

接受单个地理字段或表达式，并返回通过将坐标与 `x`、`y` 和可选的 `z` 参数相乘来缩放坐标的几何形状。

## `SnapToGrid`

#### `class SnapToGrid(expression, *args, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_SnapToGrid.html), SpatiaLite

接受单个地理字段或表达式，并返回所有点都根据给定的网格进行捕捉的几何形状。如何将几何形状捕捉到网格取决于提供了多少个数字参数（可以是浮点数、整数或长整数）。

| 参数数量： | 描述 |
| --- | --- |
| 1 | 一个单独的大小，用于捕捉 X 和 Y 网格。 |
| 2 | 捕捉网格的 X 和 Y 大小。 |
| 4 | X、Y 大小以及相应的 X、Y 起始点。 |

## `SymDifference`

#### `class SymDifference(expr1, expr2, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/spatial-operator-functions.html#function_st-symdifference), [PostGIS](https://postgis.net/docs/ST_SymDifference.html), Oracle, SpatiaLite

接受两个地理字段或表达式，并返回给定参数之间的几何对称差异（联合而不包括交集）。

## `Transform`

#### `class Transform(expression, srid, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_Transform.html), Oracle, SpatiaLite

接受一个地理字段或表达式以及一个 SRID 整数代码，并将几何形状转换为由 `srid` 参数指定的空间参考系统。

> **Note**
>
> 整数 SRID 对应的空间参考系统可能取决于使用的空间数据库。换句话说，用于 Oracle 的 SRID 号码不一定与用于 PostGIS 的相同。

## `Translate`

#### `class Translate(expression, x, y, z=0.0, **extra)`

*可用性*: [PostGIS](https://postgis.net/docs/ST_Translate.html), SpatiaLite

接受单个地理字段或表达式，并返回其坐标根据 `x`、`y` 和可选的 `z` 数值参数进行偏移的几何形状。

## `Union`

#### `class Union(expr1, expr2, **extra)`

*可用性*: MariaDB, [MySQL](https://dev.mysql.com/doc/refman/en/spatial-operator-functions.html#function_st-union), [PostGIS](https://postgis.net/docs/ST_Union.html), Oracle, SpatiaLite

接受两个地理字段或表达式，并返回两个几何形状的联合。
