---
title: "GEOS API"
version: 4.2
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/4.2/ref/contrib/gis/geos/
canonical: https://djangodocs.dev/zh-hans/4.2/ref/contrib/gis/geos/
---
# GEOS API

## 背景

### 什么是 GEOS?

[GEOS](https://libgeos.org/) 代表 **Geometry Engine - Open Source**，是一个 C++ 库，从 [Java Topology Suite](https://sourceforge.net/projects/jts-topo-suite/) 移植而来。GEOS 实现了 OpenGIS [Simple Features for SQL](https://www.ogc.org/standards/sfs) 空间谓词函数和空间操作符。GEOS，现在是一个 OSGeo 项目，最初由加拿大维多利亚的 [Refractions Research](http://www.refractions.net/) 开发和维护。

### 特性

GeoDjango 实现了一个高级的 Python 封装，用于 GEOS 库，其特点包括：

- 一个使用 `ctypes` 纯粹在 Python 中实现的，对 GEOS 几何例程提供的 BSD 许可接口。
- 与 GeoDjango 松散耦合。例如，可以在 Django 项目/应用程序之外使用 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象。换句话说，无需设置 [`DJANGO_SETTINGS_MODULE`](/zh-hans/4.2/topics/settings/#envvar-DJANGO_SETTINGS_MODULE) 或使用数据库等。
- 可变性：[`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象可以被修改。
- 跨平台并经过测试；兼容 Windows、Linux、Solaris 和 macOS 平台。

## 教程

这个部分包含了使用 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象的简要介绍和教程。

### 创建几何对象

[`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象可以以几种方式创建。首先，可以简单地在某些空间输入上实例化对象，以下是从 WKT、HEX、WKB 和 GeoJSON 创建相同几何的示例：

```pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> pnt = GEOSGeometry("POINT(5 23)")  # WKT
>>> pnt = GEOSGeometry("010100000000000000000014400000000000003740")  # HEX
>>> pnt = GEOSGeometry(
...     memoryview(
...         b"\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x007@"
...     )
... )  # WKB
>>> pnt = GEOSGeometry(
...     '{ "type": "Point", "coordinates": [ 5.000000, 23.000000 ] }'
... )  # GeoJSON
```

另一个选项是使用特定几何类型的构造函数来创建您希望创建的几何对象。例如，可以通过将 X 和 Y 坐标传递到其构造函数中来创建一个 [`Point`](#django.contrib.gis.geos.Point) 对象：

```pycon
>>> from django.contrib.gis.geos import Point
>>> pnt = Point(5, 23)
```

所有这些构造函数都接受关键字参数 `srid`。例如：

```pycon
>>> from django.contrib.gis.geos import GEOSGeometry, LineString, Point
>>> print(GEOSGeometry("POINT (0 0)", srid=4326))
SRID=4326;POINT (0 0)
>>> print(LineString((0, 0), (1, 1), srid=4326))
SRID=4326;LINESTRING (0 0, 1 1)
>>> print(Point(0, 0, srid=32140))
SRID=32140;POINT (0 0)
```

最后，还有一个 [`fromfile()`](#django.contrib.gis.geos.fromfile) 工厂方法，它可以从文件返回一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象：

```pycon
>>> from django.contrib.gis.geos import fromfile
>>> pnt = fromfile("/path/to/pnt.wkt")
>>> pnt = fromfile(open("/path/to/pnt.wkt"))
```

> **我的日志中充满了与 GEOS 相关的错误。**
>
> 你在 Web 服务器的日志文件中发现了许多 `TypeError` 或 `AttributeError` 异常。这通常意味着你在一些 Python 模块的顶层创建了 GEOS 对象。然后，由于垃圾收集器中的竞态条件，你的模块在 GEOS 对象之前被垃圾回收。为了防止这种情况发生，请在你的函数/方法的局部范围内创建 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象。

### 几何对象是符合 Python 风格的

[`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象是 'Pythonic' 的，换句话说，可以使用标准的 Python 惯例访问、修改和迭代其组件。例如，你可以迭代 [`Point`](#django.contrib.gis.geos.Point) 中的坐标：

```pycon
>>> pnt = Point(5, 23)
>>> [coord for coord in pnt]
[5.0, 23.0]
```

对于任何几何对象，可以使用 [`GEOSGeometry.coords`](#django.contrib.gis.geos.GEOSGeometry.coords) 属性将几何坐标作为 Python 元组获取：

```pycon
>>> pnt.coords
(5.0, 23.0)
```

可以使用标准的 Python 索引技术来获取/设置几何组件。但是，返回的内容取决于对象的几何类型。例如，在 [`LineString`](#django.contrib.gis.geos.LineString) 上进行索引返回一个坐标元组：

```pycon
>>> from django.contrib.gis.geos import LineString
>>> line = LineString((0, 0), (0, 50), (50, 50), (50, 0), (0, 0))
>>> line[0]
(0.0, 0.0)
>>> line[-2]
(50.0, 0.0)
```

而在 [`Polygon`](#django.contrib.gis.geos.Polygon) 上进行索引将返回与索引对应的环（一个 [`LinearRing`](#django.contrib.gis.geos.LinearRing) 对象）：

```pycon
>>> from django.contrib.gis.geos import Polygon
>>> poly = Polygon(((0.0, 0.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (0.0, 0.0)))
>>> poly[0]
<LinearRing object at 0x1044395b0>
>>> poly[0][-2]  # second-to-last coordinate of external ring
(50.0, 0.0)
```

此外，几何的坐标/组件可以像 Python 列表一样添加或修改：

```pycon
>>> line[0] = (1.0, 1.0)
>>> line.pop()
(0.0, 0.0)
>>> line.append((1.0, 1.0))
>>> line.coords
((1.0, 1.0), (0.0, 50.0), (50.0, 50.0), (50.0, 0.0), (1.0, 1.0))
```

几何对象支持类似集合的运算符：

```pycon
>>> from django.contrib.gis.geos import LineString
>>> ls1 = LineString((0, 0), (2, 2))
>>> ls2 = LineString((1, 1), (3, 3))
>>> print(ls1 | ls2)  # equivalent to `ls1.union(ls2)`
MULTILINESTRING ((0 0, 1 1), (1 1, 2 2), (2 2, 3 3))
>>> print(ls1 & ls2)  # equivalent to `ls1.intersection(ls2)`
LINESTRING (1 1, 2 2)
>>> print(ls1 - ls2)  # equivalent to `ls1.difference(ls2)`
LINESTRING(0 0, 1 1)
>>> print(ls1 ^ ls2)  # equivalent to `ls1.sym_difference(ls2)`
MULTILINESTRING ((0 0, 1 1), (2 2, 3 3))
```

> **等号运算符不检查空间相等性**
>
> [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 的等号运算符使用的是 [`equals_exact()`](#django.contrib.gis.geos.GEOSGeometry.equals_exact)，而不是 [`equals()`](#django.contrib.gis.geos.GEOSGeometry.equals)，也就是说，它要求比较的几何对象在相同的位置具有相同的坐标和相同的 SRID：
>
> ```pycon
> >>> from django.contrib.gis.geos import LineString
> >>> ls1 = LineString((0, 0), (1, 1))
> >>> ls2 = LineString((1, 1), (0, 0))
> >>> ls3 = LineString((1, 1), (0, 0), srid=4326)
> >>> ls1.equals(ls2)
> True
> >>> ls1 == ls2
> False
> >>> ls3 == ls2  # different SRIDs
> False
> ```

## 几何对象

### `GEOSGeometry`

#### `class GEOSGeometry(geo_input, srid=None)`

**参数:** - `geo_input` -- 几何输入值（字符串或 [`memoryview`](https://docs.python.org/3/library/stdtypes.html#memoryview)）
- `srid` ([`int`](https://docs.python.org/3/library/functions.html#int)) -- 空间参考标识符（SRID）

这是所有 GEOS 几何对象的基类。它根据给定的 `geo_input` 参数进行初始化，然后假定适当的几何子类（例如，`GEOSGeometry('POINT(1 1)')` 将创建一个 [`Point`](#django.contrib.gis.geos.Point) 对象）。

如果提供了 `srid` 参数，并且 `geo_input` 没有 SRID，则将其设置为创建的几何对象的 SRID。如果通过 `geo_input` 和 `srid` 参数提供了不同的 SRID，则会引发 `ValueError`：

```pycon
>>> from django.contrib.gis.geos import GEOSGeometry
>>> GEOSGeometry("POINT EMPTY", srid=4326).ewkt
'SRID=4326;POINT EMPTY'
>>> GEOSGeometry("SRID=4326;POINT EMPTY", srid=4326).ewkt
'SRID=4326;POINT EMPTY'
>>> GEOSGeometry("SRID=1;POINT EMPTY", srid=4326)
Traceback (most recent call last):
...
ValueError: Input geometry already has SRID: 1.
```

以下输入格式以及它们对应的 Python 类型被接受：

| 格式 | 输入类型 |
| --- | --- |
| WKT / EWKT | `str` |
| HEX / HEXEWKB | `str` |
| WKB / EWKB | `memoryview` |
| [**GeoJSON**](https://datatracker.ietf.org/doc/html/rfc7946.html) | `str` |

对于 GeoJSON 格式，SRID 是根据 `crs` 成员设置的。如果没有提供 `crs`，SRID 默认为 4326。

#### `classmethod GEOSGeometry.from_gml(gml_string)`

从给定的 GML 字符串构造一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)。

#### 属性

#### `GEOSGeometry.coords`

返回几何的坐标作为一个元组。

#### `GEOSGeometry.dims`

返回几何的维度：

- 对于 [`Point`](#django.contrib.gis.geos.Point) 和 [`MultiPoint`](#django.contrib.gis.geos.MultiPoint)，返回值为 `0`
- 对于 [`LineString`](#django.contrib.gis.geos.LineString) 和 [`MultiLineString`](#django.contrib.gis.geos.MultiLineString)，返回值为 `1`
- 对于 [`Polygon`](#django.contrib.gis.geos.Polygon) 和 [`MultiPolygon`](#django.contrib.gis.geos.MultiPolygon)，返回值为 `2`
- 对于空的 [`GeometryCollection`](#django.contrib.gis.geos.GeometryCollection)，返回值为 `-1`
- 对于非空的 [`GeometryCollection`](#django.contrib.gis.geos.GeometryCollection)，返回其元素的最大维度。

#### `GEOSGeometry.empty`

返回几何中的点集是否为空。

#### `GEOSGeometry.geom_type`

返回与几何类型相对应的字符串。例如：

```pycon
>>> pnt = GEOSGeometry("POINT(5 23)")
>>> pnt.geom_type
'Point'
```

#### `GEOSGeometry.geom_typeid`

返回 GEOS 几何类型的识别号码。以下表格显示了每种几何类型的值：

| 几何 | ID |
| --- | --- |
| [`Point`](#django.contrib.gis.geos.Point) | 0 |
| [`LineString`](#django.contrib.gis.geos.LineString) | 1 |
| [`LinearRing`](#django.contrib.gis.geos.LinearRing) | 2 |
| [`Polygon`](#django.contrib.gis.geos.Polygon) | 3 |
| [`MultiPoint`](#django.contrib.gis.geos.MultiPoint) | 4 |
| [`MultiLineString`](#django.contrib.gis.geos.MultiLineString) | 5 |
| [`MultiPolygon`](#django.contrib.gis.geos.MultiPolygon) | 6 |
| [`GeometryCollection`](#django.contrib.gis.geos.GeometryCollection) | 7 |

#### `GEOSGeometry.num_coords`

返回几何中坐标的数量。

#### `GEOSGeometry.num_geom`

返回此几何中的几何数量。换句话说，在几何集合之外的任何几何对象上都会返回 1。

#### `GEOSGeometry.hasz`

返回一个布尔值，指示几何是否是三维的。

#### `GEOSGeometry.ring`

返回一个布尔值，指示几何是否是 `LinearRing`。

#### `GEOSGeometry.simple`

返回一个布尔值，指示几何是否是 'simple'。只有当几何不与自身相交（除了边界点）时，几何才被认为是 simple。例如，如果 [`LineString`](#django.contrib.gis.geos.LineString) 对象与自身相交，则它不是 simple。因此，[`LinearRing`](#django.contrib.gis.geos.LinearRing) 和 [`Polygon`](#django.contrib.gis.geos.Polygon) 对象总是 simple，因为根据定义它们不能与自身相交。

#### `GEOSGeometry.valid`

返回一个布尔值，指示几何是否有效。

#### `GEOSGeometry.valid_reason`

返回一个描述几何无效的原因的字符串。

#### `GEOSGeometry.srid`

用于检索或设置与几何相关联的 SRID 的属性。例如：

```pycon
>>> pnt = Point(5, 23)
>>> print(pnt.srid)
None
>>> pnt.srid = 4326
>>> pnt.srid
4326
```

#### 输出属性

此部分中的属性将 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象导出为不同的格式。输出可以是字符串、缓冲区，甚至是另一个对象的形式。

#### `GEOSGeometry.ewkt`

返回几何的 "扩展" Well-Known Text（WKT）。此表示形式特定于 PostGIS，并且是 OGC WKT 标准的超集。[^1] 基本上，SRID 被添加到 WKT 表示中，例如 `SRID=4326;POINT(5 23)`。

> **Note**
>
> 此属性的输出不包括 PostGIS 在其 EWKT 表示中支持的 3dm、3dz 和 4d 信息。

#### `GEOSGeometry.hex`

以十六进制形式返回此几何的 WKB。请注意，SRID 值不包括在此表示中，因为它不是 OGC 规范的一部分（请使用 [`GEOSGeometry.hexewkb`](#django.contrib.gis.geos.GEOSGeometry.hexewkb) 属性）。

#### `GEOSGeometry.hexewkb`

以十六进制形式返回此几何的 EWKB。这是 WKB 规范的扩展，包括与此几何对象相关的 SRID 值。

#### `GEOSGeometry.json`

返回几何的 GeoJSON 表示。请注意，结果不是完整的 GeoJSON 结构，而只是 GeoJSON 结构中 `geometry` 键的内容。还请参阅 [GeoJSON 序列化器](/zh-hans/4.2/ref/contrib/gis/serializers/)。

#### `GEOSGeometry.geojson`

是 [`GEOSGeometry.json`](#django.contrib.gis.geos.GEOSGeometry.json) 的别名。

#### `GEOSGeometry.kml`

返回几何的 [KML](https://developers.google.com/kml/documentation/) （Keyhole Markup Language）表示。这应该仅用于具有 SRID 4326（WGS84）的几何对象，但此限制不受强制执行。

#### `GEOSGeometry.ogr`

返回与 GEOS 几何对应的 [`OGRGeometry`](/zh-hans/4.2/ref/contrib/gis/gdal/#django.contrib.gis.gdal.OGRGeometry) 对象。

#### `GEOSGeometry.wkb`

以 Python 缓冲区的形式返回此几何的 WKB（Well-Known Binary）表示。不包括 SRID 值，请使用 [`GEOSGeometry.ewkb`](#django.contrib.gis.geos.GEOSGeometry.ewkb) 属性代替。

#### `GEOSGeometry.ewkb`

以 Python 缓冲区的形式返回此几何的 EWKB 表示。这是 WKB 规范的扩展，包括与此几何对象相关的任何 SRID 值。

#### `GEOSGeometry.wkt`

返回几何的 Well-Known Text（OGC 标准）。

#### 空间谓词方法

以下所有的空间谓词方法都以另一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 实例（`other`）作为参数，并返回一个布尔值。

#### `GEOSGeometry.contains(other)`

如果 [`other.within(this)`](#django.contrib.gis.geos.GEOSGeometry.within) 返回 `True`，则返回 `True`。

#### `GEOSGeometry.covers(other)`

如果此几何覆盖指定的几何，则返回 `True`。

`covers` 谓词具有以下等价定义：

- 其他几何的每个点都是此几何的点。
- 两个几何对象的 [DE-9IM](https://en.wikipedia.org/wiki/DE-9IM) 交集矩阵为 `T*****FF*`, `*T****FF*`, `***T**FF*`, 或 `****T*FF*`。

如果其中一个几何为空，则返回 `False`。

此谓词类似于 [`GEOSGeometry.contains()`](#django.contrib.gis.geos.GEOSGeometry.contains)，但更加包容性（即对更多情况返回 `True`）。特别地，与 [`contains()`](#django.contrib.gis.geos.GEOSGeometry.contains) 不同，它不区分边界和几何内部的点。在大多数情况下，应该首选使用 `covers()` 而不是 [`contains()`](#django.contrib.gis.geos.GEOSGeometry.contains)。作为额外的好处，`covers()` 更容易进行优化，因此应该优于 [`contains()`](#django.contrib.gis.geos.GEOSGeometry.contains)。

#### `GEOSGeometry.crosses(other)`

如果两个几何对象的 DE-9IM 交集矩阵为 `T*T******` （对于点和曲线、点和区域或线和区域）或 `0********` （对于两个曲线），则返回 `True`。

#### `GEOSGeometry.disjoint(other)`

如果两个几何对象的 DE-9IM 交集矩阵为 `FF*FF****`，则返回 `True`。

#### `GEOSGeometry.equals(other)`

如果两个几何对象的 DE-9IM 交集矩阵为 `T*F**FFF*`，则返回 `True`。

#### `GEOSGeometry.equals_exact(other, tolerance=0)`

如果两个几何对象在指定的容差范围内完全相等，则返回 `True`。`tolerance` 值应该是一个浮点数，表示比较中的误差容差，例如，`poly1.equals_exact(poly2, 0.001)` 将在千分之一的单位内进行比较相等。

#### `GEOSGeometry.intersects(other)`

如果 [`GEOSGeometry.disjoint()`](#django.contrib.gis.geos.GEOSGeometry.disjoint) 为 `False`，则返回 `True`。

#### `GEOSGeometry.overlaps(other)`

如果两个几何对象的 DE-9IM 交集矩阵为 `T*T***T**` （对于两个点或两个表面）或 `1*T***T**` （对于两个曲线），则返回 `True`。

#### `GEOSGeometry.relate_pattern(other, pattern)`

如果此几何对象和其他几何对象的 DE-9IM 交集矩阵中的元素与给定的 `pattern` 匹配（一个由字母 {`T`, `F`, `*`, `0`} 组成的九个字符的字符串），则返回 `True`。

#### `GEOSGeometry.touches(other)`

如果两个几何对象的 DE-9IM 交集矩阵为 `FT*******`、`F**T*****` 或 `F***T****`，则返回 `True`。

#### `GEOSGeometry.within(other)`

如果两个几何对象的 DE-9IM 交集矩阵为 `T*F**F***`，则返回 `True`。

#### 拓扑方法

#### `GEOSGeometry.buffer(width, quadsegs=8)`

返回一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)，表示距离此几何对象小于或等于给定的 `width` 的所有点。可选的 `quadsegs` 关键字设置用于近似一个四分之一圆的段数（默认值为 8）。

#### `GEOSGeometry.buffer_with_style(width, quadsegs=8, end_cap_style=1, join_style=1, mitre_limit=5.0)`

与 [`buffer()`](#django.contrib.gis.geos.GEOSGeometry.buffer) 相同，但允许自定义缓冲区的样式。

- `end_cap_style` 可以是 round（`1`）、flat（`2`）或 square（`3`）。
- `join_style` 可以是 round（`1`）、mitre（`2`）或 bevel（`3`）。
- Mitre ratio limit（`mitre_limit`）仅影响 mitred join style。

#### `GEOSGeometry.difference(other)`

返回一个表示构成此几何的点但不构成其他几何的 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)。

#### `GEOSGeometry.interpolate(distance)`

#### `GEOSGeometry.interpolate_normalized(distance)`

给定一个距离（浮点数），返回几何对象（[`LineString`](#django.contrib.gis.geos.LineString) 或 [`MultiLineString`](#django.contrib.gis.geos.MultiLineString)）中距离最近的点（或最近的点）。标准化版本将距离作为介于 0（起点）和 1（终点）之间的浮点数。

与 [`GEOSGeometry.project()`](#django.contrib.gis.geos.GEOSGeometry.project) 的相反操作。

#### `GEOSGeometry.intersection(other)`

返回一个表示此几何对象和其他几何对象共享的点的 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)。

#### `GEOSGeometry.project(point)`

#### `GEOSGeometry.project_normalized(point)`

返回从几何对象（[`LineString`](#django.contrib.gis.geos.LineString) 或 [`MultiLineString`](#django.contrib.gis.geos.MultiLineString)）的起点到在几何对象上投影的点（即距离给定点最近的线上的点）的距离（浮点数）。标准化版本将距离作为介于 0（起点）和 1（终点）之间的浮点数返回。

与 [`GEOSGeometry.interpolate()`](#django.contrib.gis.geos.GEOSGeometry.interpolate) 的相反操作。

#### `GEOSGeometry.relate(other)`

返回表示此几何对象与其他几何对象之间拓扑关系的 DE-9IM 交集矩阵（字符串）。

#### `GEOSGeometry.simplify(tolerance=0.0, preserve_topology=False)`

返回一个新的 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)，使用 Douglas-Peucker 算法简化到指定的容差。较高的容差值意味着输出中的点较少。如果没有提供容差，则默认为 0。

默认情况下，此函数不保持拓扑关系。例如，[`Polygon`](#django.contrib.gis.geos.Polygon) 对象可以被分割，折叠成线，或消失。[`Polygon`](#django.contrib.gis.geos.Polygon) 的孔可以被创建或消失，线可能会相交。通过指定 `preserve_topology=True`，结果将具有与输入相同的维度和组件数量；然而，这会显著减慢处理速度。

#### `GEOSGeometry.sym_difference(other)`

返回一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)，其中包含此几何对象中不在其他几何中的点以及其他几何中不在此几何中的点。

#### `GEOSGeometry.union(other)`

返回一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)，表示此几何对象和其他几何对象中的所有点。

#### 拓扑属性

#### `GEOSGeometry.boundary`

返回边界作为一个新分配的几何对象。

#### `GEOSGeometry.centroid`

返回一个 [`Point`](#django.contrib.gis.geos.Point) 对象，表示几何对象的几何中心。不能保证该点位于几何对象的内部。

#### `GEOSGeometry.convex_hull`

返回包含几何中所有点的最小 [`Polygon`](#django.contrib.gis.geos.Polygon)。

#### `GEOSGeometry.envelope`

返回一个表示此几何的边界包围框的 [`Polygon`](#django.contrib.gis.geos.Polygon)。请注意，如果输入几何对象是一个点，它也可以返回一个 [`Point`](#django.contrib.gis.geos.Point)。

#### `GEOSGeometry.point_on_surface`

计算并返回一个保证位于此几何对象内部的 [`Point`](#django.contrib.gis.geos.Point)。

#### `GEOSGeometry.unary_union`

计算此几何对象的所有元素的并集。

结果遵循以下约定：

- 对一组 [`LineString`](#django.contrib.gis.geos.LineString) 进行并集操作将完全节点化和融合线段。
- 对一组 [`Polygon`](#django.contrib.gis.geos.Polygon) 进行并集操作将始终返回一个 [`Polygon`](#django.contrib.gis.geos.Polygon) 或 [`MultiPolygon`](#django.contrib.gis.geos.MultiPolygon) 几何对象（与 [`GEOSGeometry.union()`](#django.contrib.gis.geos.GEOSGeometry.union) 不同，如果拓扑崩溃发生，可能返回较低维度的几何对象）。

#### 其他属性和方法

#### `GEOSGeometry.area`

此属性返回几何对象的面积。

#### `GEOSGeometry.extent`

此属性返回几何对象的范围，以 4 元组形式表示，包括 `(xmin, ymin, xmax, ymax)`。

#### `GEOSGeometry.clone()`

此方法返回原始几何对象的克隆 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)。

#### `GEOSGeometry.distance(geom)`

返回此几何对象与给定的 `geom` （另一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象）之间的最近点之间的距离。

> **Note**
>
> GEOS 距离计算是线性的，换句话说，即使 SRID 指定地理坐标系，GEOS 不会执行球面计算。

#### `GEOSGeometry.length`

返回此几何对象的长度（例如，对于 [`Point`](#django.contrib.gis.geos.Point)，长度为 0，对于 [`LineString`](#django.contrib.gis.geos.LineString)，长度为线段的长度，对于 [`Polygon`](#django.contrib.gis.geos.Polygon)，长度为多边形的周长）。

#### `GEOSGeometry.prepared`

返回此几何对象内容的 GEOS `PreparedGeometry`。`PreparedGeometry` 对象针对 contains、intersects、covers、crosses、disjoint、overlaps、touches 和 within 操作进行了优化。有关更多信息，请参阅 [准备好的几何对象](#prepared-geometries) 文档。

#### `GEOSGeometry.srs`

返回与几何对象的 SRID 对应的 [`SpatialReference`](/zh-hans/4.2/ref/contrib/gis/gdal/#django.contrib.gis.gdal.SpatialReference) 对象，如果没有则返回 `None`。

#### `GEOSGeometry.transform(ct, clone=False)`

根据给定的坐标转换参数（`ct`）来转换几何对象，参数可以是整数 SRID、空间参考 WKT 字符串、PROJ 字符串、[`SpatialReference`](/zh-hans/4.2/ref/contrib/gis/gdal/#django.contrib.gis.gdal.SpatialReference) 对象或 [`CoordTransform`](/zh-hans/4.2/ref/contrib/gis/gdal/#django.contrib.gis.gdal.CoordTransform) 对象。默认情况下，几何对象会原地转换，不返回任何内容。但是如果设置了 `clone` 关键字参数，则不会修改几何对象，而是返回一个经过转换的几何对象的克隆。

> **Note**
>
> 如果没有安装 GDAL，或者几何对象的 SRID 为 `None` 或小于 0，则会引发 [`GEOSException`](#django.contrib.gis.geos.GEOSException)。如果使用 [`CoordTransform`](/zh-hans/4.2/ref/contrib/gis/gdal/#django.contrib.gis.gdal.CoordTransform) 对象调用，则不会对几何对象的 SRID 强加任何约束。

#### `GEOSGeometry.make_valid()`

> **New in Django 4.1**

返回一个有效的 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 等效对象，尽量不丢失输入的顶点。如果几何对象已经有效，则原样返回。这类似于数据库函数 [`MakeValid`](/zh-hans/4.2/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.MakeValid)。需要 GEOS 3.8。

#### `GEOSGeometry.normalize(clone=False)`

将此几何对象转换为规范形式。如果设置了 `clone` 关键字参数，则不会修改几何对象，而是返回一个规范化的几何对象的克隆：

```pycon
>>> g = MultiPoint(Point(0, 0), Point(2, 2), Point(1, 1))
>>> print(g)
MULTIPOINT (0 0, 2 2, 1 1)
>>> g.normalize()
>>> print(g)
MULTIPOINT (2 2, 1 1, 0 0)
```

> **Changed in Django 4.1**
>
> 添加了 `clone` 参数。

### `Point`

#### `class Point(x=None, y=None, z=None, srid=None)`

可以使用表示点的组件坐标或单个坐标序列来实例化 `Point` 对象。例如，以下方式是等效的：

```pycon
>>> pnt = Point(5, 23)
>>> pnt = Point([5, 23])
```

可以通过不传递参数或传递一个空序列来实例化空的 `Point` 对象。以下方式是等效的：

```pycon
>>> pnt = Point()
>>> pnt = Point([])
```

### `LineString`

#### `class LineString(*args, **kwargs)`

可以使用坐标序列或 [`Point`](#django.contrib.gis.geos.Point) 对象作为参数来实例化 `LineString` 对象。例如，以下方式是等效的：

```pycon
>>> ls = LineString((0, 0), (1, 1))
>>> ls = LineString(Point(0, 0), Point(1, 1))
```

此外，还可以通过传递单个坐标序列或 [`Point`](#django.contrib.gis.geos.Point) 对象的序列来创建 `LineString` 对象：

```pycon
>>> ls = LineString(((0, 0), (1, 1)))
>>> ls = LineString([Point(0, 0), Point(1, 1)])
```

可以通过不传递参数或传递一个空序列来实例化空的 `LineString` 对象。以下方式是等效的：

```pycon
>>> ls = LineString()
>>> ls = LineString([])
```

#### `closed`

返回此 `LineString` 是否闭合。

### `LinearRing`

#### `class LinearRing(*args, **kwargs)`

`LinearRing` 对象的构造方式与 [`LineString`](#django.contrib.gis.geos.LineString) 对象完全相同，但坐标必须是 *闭合* 的，也就是说，第一个坐标必须与最后一个坐标相同。例如：

```pycon
>>> ls = LinearRing((0, 0), (0, 1), (1, 1), (0, 0))
```

请注意，`(0, 0)` 是第一个和最后一个坐标 -- 如果它们不相等，就会引发错误。

#### `is_counterclockwise`

返回此 `LinearRing` 是否为逆时针方向。

### `Polygon`

#### `class Polygon(*args, **kwargs)`

`Polygon` 对象可以通过传入代表多边形环的参数来实例化。这些参数必须要么是 [`LinearRing`](#django.contrib.gis.geos.LinearRing) 实例，要么是用于构建 [`LinearRing`](#django.contrib.gis.geos.LinearRing) 的序列：

```pycon
>>> ext_coords = ((0, 0), (0, 1), (1, 1), (1, 0), (0, 0))
>>> int_coords = ((0.4, 0.4), (0.4, 0.6), (0.6, 0.6), (0.6, 0.4), (0.4, 0.4))
>>> poly = Polygon(ext_coords, int_coords)
>>> poly = Polygon(LinearRing(ext_coords), LinearRing(int_coords))
```

#### `classmethod from_bbox(bbox)`

从给定的边界框返回一个多边形对象，边界框是由 `(xmin, ymin, xmax, ymax)` 组成的 4 元组。

#### `num_interior_rings`

返回此几何对象中内部环的数量。

> **比较多边形**
>
> 请注意，可以直接使用 `<` 或 `>` 比较 `Polygon` 对象，但由于比较是通过多边形的 [`LineString`](#django.contrib.gis.geos.LineString) 进行的，所以意义不大（但是一致且快速）。您始终可以使用 [`area`](#django.contrib.gis.geos.GEOSGeometry.area) 属性强制进行比较：
>
> ```pycon
> >>> if poly_1.area > poly_2.area:
> ...     pass
> ...
> ```

## 几何集合

### `MultiPoint`

#### `class MultiPoint(*args, **kwargs)`

`MultiPoint` 对象可以通过传入 [`Point`](#django.contrib.gis.geos.Point) 对象作为参数，或者传入包含 [`Point`](#django.contrib.gis.geos.Point) 对象的单个序列来实例化：

```pycon
>>> mp = MultiPoint(Point(0, 0), Point(1, 1))
>>> mp = MultiPoint((Point(0, 0), Point(1, 1)))
```

### `MultiLineString`

#### `class MultiLineString(*args, **kwargs)`

`MultiLineString` 对象可以通过传入 [`LineString`](#django.contrib.gis.geos.LineString) 对象作为参数，或者传入包含 [`LineString`](#django.contrib.gis.geos.LineString) 对象的单个序列来实例化：

```pycon
>>> ls1 = LineString((0, 0), (1, 1))
>>> ls2 = LineString((2, 2), (3, 3))
>>> mls = MultiLineString(ls1, ls2)
>>> mls = MultiLineString([ls1, ls2])
```

#### `merged`

返回一个代表此 `MultiLineString` 中所有组件线合并的 [`LineString`](#django.contrib.gis.geos.LineString)。

#### `closed`

只有当所有元素都闭合时返回 `True`。

### `MultiPolygon`

#### `class MultiPolygon(*args, **kwargs)`

`MultiPolygon` 对象可以通过传入 [`Polygon`](#django.contrib.gis.geos.Polygon) 对象作为参数，或者传入包含 [`Polygon`](#django.contrib.gis.geos.Polygon) 对象的单个序列来实例化：

```pycon
>>> p1 = Polygon(((0, 0), (0, 1), (1, 1), (0, 0)))
>>> p2 = Polygon(((1, 1), (1, 2), (2, 2), (1, 1)))
>>> mp = MultiPolygon(p1, p2)
>>> mp = MultiPolygon([p1, p2])
```

### `GeometryCollection`

#### `class GeometryCollection(*args, **kwargs)`

`GeometryCollection` 对象可以通过传入其他 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 作为参数，或者传入包含 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 对象的单个序列来实例化：

```pycon
>>> poly = Polygon(((0, 0), (0, 1), (1, 1), (0, 0)))
>>> gc = GeometryCollection(Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly)
>>> gc = GeometryCollection((Point(0, 0), MultiPoint(Point(0, 0), Point(1, 1)), poly))
```

## 准备好的几何对象

要获得一个准备好的几何对象，请访问 [`GEOSGeometry.prepared`](#django.contrib.gis.geos.GEOSGeometry.prepared) 属性。一旦您有了一个 `PreparedGeometry` 实例，它下面列出的空间谓词方法可以与其他 `GEOSGeometry` 对象一起使用。使用准备好的几何对象进行操作可以快几个数量级 -- 准备的几何越复杂，操作的速度提升就越大。有关更多信息，请参考 [GEOS 准备好的几何页面](https://trac.osgeo.org/geos/wiki/PreparedGeometry)。

例如：

```pycon
>>> from django.contrib.gis.geos import Point, Polygon
>>> poly = Polygon.from_bbox((0, 0, 5, 5))
>>> prep_poly = poly.prepared
>>> prep_poly.contains(Point(2.5, 2.5))
True
```

### `PreparedGeometry`

#### `class PreparedGeometry`

`PreparedGeometry` 上的所有方法都接受一个 `other` 参数，该参数必须是一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 实例。

#### `contains(other)`

#### `contains_properly(other)`

#### `covers(other)`

#### `crosses(other)`

#### `disjoint(other)`

#### `intersects(other)`

#### `overlaps(other)`

#### `touches(other)`

#### `within(other)`

## 几何工厂

#### `fromfile(file_h)`

**参数:** `file_h` (a Python `file` object or a string path to the file) -- 包含空间数据的输入文件

**返回类型:** 一个对应于文件中空间数据的 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)

例如：

```pycon
>>> from django.contrib.gis.geos import fromfile
>>> g = fromfile("/home/bob/geom.wkt")
```

#### `fromstr(string, srid=None)`

**参数:** - `string` ([`str`](https://docs.python.org/3/library/stdtypes.html#str)) -- 包含空间数据的字符串
- `srid` ([`int`](https://docs.python.org/3/library/functions.html#int)) -- 空间参考标识符（SRID）

**返回类型:** 一个对应于字符串中空间数据的 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry)

`fromstr(string, srid)` 等价于 [`GEOSGeometry(string, srid)`](#django.contrib.gis.geos.GEOSGeometry)。

例如：

```pycon
>>> from django.contrib.gis.geos import fromstr
>>> pnt = fromstr("POINT(-90.5 29.5)", srid=4326)
```

## I/O 对象

### 读取器对象

读取器 I/O 类从给定给它们的 WKB 和/或 WKT 输入中的 `read(geom)` 方法返回一个 [`GEOSGeometry`](#django.contrib.gis.geos.GEOSGeometry) 实例。

#### `class WKBReader`

例如：

```pycon
>>> from django.contrib.gis.geos import WKBReader
>>> wkb_r = WKBReader()
>>> wkb_r.read("0101000000000000000000F03F000000000000F03F")
<Point object at 0x103a88910>
```

#### `class WKTReader`

例如：

```pycon
>>> from django.contrib.gis.geos import WKTReader
>>> wkt_r = WKTReader()
>>> wkt_r.read("POINT(1 1)")
<Point object at 0x103a88b50>
```

### 写入器对象

所有写入器对象都具有一个 `write(geom)` 方法，该方法返回给定几何对象的 WKB 或 WKT。此外，[`WKBWriter`](#django.contrib.gis.geos.WKBWriter) 对象还具有可用于更改字节顺序或包括 SRID 值的属性（即 EWKB）。

#### `class WKBWriter(dim=2)`

`WKBWriter` 提供对其输出的最大控制。默认情况下，当调用其 `write` 方法时，它返回符合 OGC 标准的 WKB。然而，它具有允许创建 EWKB 的属性，这是 WKB 标准的一个超集，包含附加信息。有关 `dim` 参数的更多详细信息，请参阅 [`WKBWriter.outdim`](#django.contrib.gis.geos.WKBWriter.outdim) 文档。

#### `write(geom)`

将给定几何对象的 WKB 返回为 Python 的 `buffer` 对象。示例：

```pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> pnt = Point(1, 1)
>>> wkb_w = WKBWriter()
>>> wkb_w.write(pnt)
<read-only buffer for 0x103a898f0, size -1, offset 0 at 0x103a89930>
```

#### `write_hex(geom)`

以十六进制返回几何对象的 WKB。示例：

```pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> pnt = Point(1, 1)
>>> wkb_w = WKBWriter()
>>> wkb_w.write_hex(pnt)
'0101000000000000000000F03F000000000000F03F'
```

#### `byteorder`

这个属性可以设置来改变几何表示的字节顺序。

| 字节顺序值 | 描述 |
| --- | --- |
| 0 | 大端字节序（例如，与 RISC 系统兼容） |
| 1 | 小端字节序（例如，与 x86 系统兼容） |

例如：

```pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
>>> pnt = Point(1, 1)
>>> wkb_w.write_hex(pnt)
'0101000000000000000000F03F000000000000F03F'
>>> wkb_w.byteorder = 0
'00000000013FF00000000000003FF0000000000000'
```

#### `outdim`

此属性可以设置为更改几何表示的输出维度。换句话说，如果您有一个三维几何对象，可以将其设置为 3，以便在 WKB 中包含 Z 值。

| Outdim 值 | 描述 |
| --- | --- |
| 2 | 默认情况下，输出 2D WKB。 |
| 3 | 输出 3D WKB。 |

例如：

```pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
>>> wkb_w.outdim
2
>>> pnt = Point(1, 1, 1)
>>> wkb_w.write_hex(pnt)  # By default, no Z value included:
'0101000000000000000000F03F000000000000F03F'
>>> wkb_w.outdim = 3  # Tell writer to include Z values
>>> wkb_w.write_hex(pnt)
'0101000080000000000000F03F000000000000F03F000000000000F03F'
```

#### `srid`

将此属性设置为布尔值，以指示几何对象的 SRID 是否应包含在 WKB 表示中。示例：

```pycon
>>> from django.contrib.gis.geos import Point, WKBWriter
>>> wkb_w = WKBWriter()
>>> pnt = Point(1, 1, srid=4326)
>>> wkb_w.write_hex(pnt)  # By default, no SRID included:
'0101000000000000000000F03F000000000000F03F'
>>> wkb_w.srid = True  # Tell writer to include SRID
>>> wkb_w.write_hex(pnt)
'0101000020E6100000000000000000F03F000000000000F03F'
```

#### `class WKTWriter(dim=2, trim=False, precision=None)`

这个类允许输出几何对象的 WKT 表示。有关构造函数参数的详细信息，请参阅 [`WKBWriter.outdim`](#django.contrib.gis.geos.WKBWriter.outdim)、[`trim`](#django.contrib.gis.geos.WKTWriter.trim) 和 [`precision`](#django.contrib.gis.geos.WKTWriter.precision) 属性。

#### `write(geom)`

返回给定几何对象的 WKT。示例：

```pycon
>>> from django.contrib.gis.geos import Point, WKTWriter
>>> pnt = Point(1, 1)
>>> wkt_w = WKTWriter()
>>> wkt_w.write(pnt)
'POINT (1.0000000000000000 1.0000000000000000)'
```

#### `outdim`

查看 [`WKBWriter.outdim`](#django.contrib.gis.geos.WKBWriter.outdim) 。

#### `trim`

此属性用于启用或禁用修剪不必要的小数位。

```pycon
>>> from django.contrib.gis.geos import Point, WKTWriter
>>> pnt = Point(1, 1)
>>> wkt_w = WKTWriter()
>>> wkt_w.trim
False
>>> wkt_w.write(pnt)
'POINT (1.0000000000000000 1.0000000000000000)'
>>> wkt_w.trim = True
>>> wkt_w.write(pnt)
'POINT (1 1)'
```

#### `precision`

此属性控制坐标的四舍五入精度；如果设置为 `None`，则禁用四舍五入。

```
>>> from django.contrib.gis.geos import Point, WKTWriter
>>> pnt = Point(1.44, 1.66)
>>> wkt_w = WKTWriter()
>>> print(wkt_w.precision)
None
>>> wkt_w.write(pnt)
'POINT (1.4399999999999999 1.6599999999999999)'
>>> wkt_w.precision = 0
>>> wkt_w.write(pnt)
'POINT (1 2)'
>>> wkt_w.precision = 1
>>> wkt_w.write(pnt)
'POINT (1.4 1.7)'
```

**脚注**

[^1]: 请参阅 [PostGIS EWKB、EWKT 和规范形式](https://postgis.net/docs/using_postgis_dbmanagement.html#EWKB_EWKT)，PostGIS 文档第 4.1.2 章。

## 配置

### `GEOS_LIBRARY_PATH`

一个字符串，指定 GEOS C 库的位置。通常情况下，只有在 GEOS C 库位于非标准位置时才使用此设置（例如，`/home/bob/lib/libgeos_c.so`）。

> **Note**
>
> 这个配置必须是 **C** 共享库的 *完整* 路径；换句话说，你要使用 `libgeos_c.so`，而不是 `libgeos.so`。

## 异常

#### `exception GEOSException`

基本的 GEOS 异常，表示与 GEOS 相关的错误。
