GDAL API

`GDAL`__ 代表 Geospatial Data Abstraction Library,是 GIS 数据功能的一种多功能工具。GDAL 的一个子集是 `OGR`__ Simple Features Library,专门用于读取和写入各种标准格式的矢量地理数据。

GeoDjango 提供了 OGR 的一些功能的高级 Python 接口,包括读取和坐标转换矢量空间数据,以及对于栅格(图像)数据方面的有限支持。

备注

尽管模块名为 gdal,但目前 GeoDjango 仅支持 OGR 的一些功能以及 GDAL 的栅格功能的一部分。

概况

样本数据

在这里描述的 GDAL/OGR 工具旨在帮助您读取您的地理空间数据,但要使它们大多数工具有用,您必须拥有一些要处理的数据。如果您刚开始,还没有自己的数据可供使用,GeoDjango 测试包含许多数据集,您可以用于测试。您可以从以下位置下载它们:

$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/cities/cities.{shp,prj,shx,dbf}
$ wget https://raw.githubusercontent.com/django/django/main/tests/gis_tests/data/rasters/raster.tif

矢量数据源对象

DataSource

DataSource 是对 OGR 数据源对象的封装,支持使用一致的接口从各种 OGR 支持的地理空间文件格式和数据源中读取数据。每个数据源都由一个 DataSource 对象表示,其中包含一个或多个数据层。每个数据层,由 Layer 对象表示,包含一定数量的地理要素(Feature),以及关于该层中包含的要素类型(例如点、多边形等)的信息,以及与该层中每个要素相关联的任何附加字段(Field)的名称和类型的信息。

class DataSource(ds_input, encoding='utf-8')

DataSource 的构造函数只需要一个参数:您要读取的文件的路径。然而,OGR 还支持各种更复杂的数据源,包括数据库,可以通过传递特殊的名称字符串而不是路径来访问。有关更多信息,请参阅 `OGR Vector Formats`__ 文档。DataSource 实例的 name 属性提供了它所使用的底层数据源的 OGR 名称。

可选的 encoding 参数允许您指定源中字符串的非标准编码。通常在读取字段值时遇到 DjangoUnicodeDecodeError 异常时,这非常有用。

创建了您的 DataSource 之后,您可以通过访问 layer_count 属性或(等效地)使用 len() 函数来查找它包含多少层数据。有关访问数据层本身的信息,请参阅下一节:

>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource("/path/to/your/cities.shp")
>>> ds.name
'/path/to/your/cities.shp'
>>> ds.layer_count  # This file only contains one layer
1
layer_count

返回数据源中的层数。

name

返回数据源的名称。

Layer

class Layer

LayerDataSource 对象中的数据层的封装。您不会直接创建 Layer 对象。相反,您可以从 DataSource 对象中检索它们,后者本质上是包含 Layer 对象的标准 Python 容器。例如,您可以通过索引访问特定的层(例如 ds[0] 来访问第一个层),或者您可以在一个 for 循环中迭代容器中的所有层。Layer 本身充当几何要素的容器。

通常,给定层中的所有要素具有相同的几何类型。层的 geom_type 属性是一个 OGRGeomType,用于标识要素类型。我们可以使用它来打印出 DataSource 中每个层的一些基本信息:

>>> for layer in ds:
...     print('Layer "%s": %i %ss' % (layer.name, len(layer), layer.geom_type.name))
...
Layer "cities": 3 Points

示例输出来自上面加载的名为 "cities" 的城市数据源,显然包含一个名为 "cities" 的层,其中包含三个点要素。为简单起见,以下示例假定您已将该层存储在变量 layer 中:

>>> layer = ds[0]
name

返回数据源中此层的名称。

>>> layer.name
'cities'
num_feat

返回该层中的要素数量。与 len(layer) 相同:

>>> layer.num_feat
3
geom_type

返回层的几何类型,作为一个 OGRGeomType 对象:

>>> layer.geom_type.name
'Point'
num_fields

返回该层中的字段数量,即与该层中的每个要素相关联的数据字段的数量:

>>> layer.num_fields
4
fields

返回该层中每个字段的名称列表:

>>> layer.fields
['Name', 'Population', 'Density', 'Created']

返回该层中每个字段的数据类型列表。这些是 Field 的子类,下面将讨论这些子类:

>>> [ft.__name__ for ft in layer.field_types]
['OFTString', 'OFTReal', 'OFTReal', 'OFTDate']
field_widths

返回该层中每个字段的最大字段宽度列表:

>>> layer.field_widths
[80, 11, 24, 10]
field_precisions

返回该层中每个字段的数值精度列表。对于非数值字段,这是无意义的(并设置为零):

>>> layer.field_precisions
[0, 0, 15, 0]
extent

返回此图层的空间范围,作为一个 Envelope 对象:

>>> layer.extent.tuple
(-104.609252, 29.763374, -95.23506, 38.971823)
srs

返回与此图层关联的 SpatialReference 的属性:

>>> print(layer.srs)
GEOGCS["GCS_WGS_1984",
    DATUM["WGS_1984",
        SPHEROID["WGS_1984",6378137,298.257223563]],
    PRIMEM["Greenwich",0],
    UNIT["Degree",0.017453292519943295]]

如果 Layer 没有与之关联的空间参考信息,则返回 None

spatial_filter

可用于检索或设置此图层的空间过滤器的属性。空间过滤器只能使用 OGRGeometry 实例、4-元组范围或 None 进行设置。当使用非 None 值进行设置时,在对图层进行迭代时,只返回与过滤器相交的要素:

>>> print(layer.spatial_filter)
None
>>> print(len(layer))
3
>>> [feat.get("Name") for feat in layer]
['Pueblo', 'Lawrence', 'Houston']
>>> ks_extent = (-102.051, 36.99, -94.59, 40.00)  # Extent for state of Kansas
>>> layer.spatial_filter = ks_extent
>>> len(layer)
1
>>> [feat.get("Name") for feat in layer]
['Lawrence']
>>> layer.spatial_filter = None
>>> len(layer)
3
get_fields()

一个方法,返回图层中每个要素给定字段的值列表:

>>> layer.get_fields("Name")
['Pueblo', 'Lawrence', 'Houston']
get_geoms(geos=False)

一个方法,返回包含图层中每个要素的几何信息的列表。如果可选参数 geos 设置为 True,则几何信息将转换为 GEOSGeometry 对象。否则,它们将以 OGRGeometry 对象的形式返回:

>>> [pt.tuple for pt in layer.get_geoms()]
[(-104.609252, 38.255001), (-95.23506, 38.971823), (-95.363151, 29.763374)]
test_capability(capability)

返回一个布尔值,指示此图层是否支持给定的功能(一个字符串)。有效的功能字符串示例包括:'RandomRead''SequentialWrite''RandomWrite''FastSpatialFilter''FastFeatureCount''FastGetExtent''CreateField''Transactions''DeleteFeature''FastSetNextByIndex'

Feature

class Feature

Feature 包装了一个 OGR 要素。你不会直接创建一个 Feature 对象。相反,你可以从一个 Layer 对象中检索它们。每个要素由一个几何信息和一组包含附加属性的字段组成。字段的几何信息可通过其 geom 属性访问,该属性返回一个 OGRGeometry 对象。Feature 表现得像一个标准的 Python 容器,用于存储它的字段,它将它们作为 Field 对象返回:你可以通过索引或名称直接访问字段,或者你可以在要素的字段上进行迭代,例如在一个 for 循环中。

geom

返回此要素的几何信息,作为一个 OGRGeometry 对象:

>>> city.geom.tuple
(-104.609252, 38.255001)
get

一个方法,返回此要素指定字段(按名称)的值,而不是 一个 Field 包装对象:

>>> city.get("Population")
102121
geom_type

返回此要素的几何类型,作为一个 OGRGeomType 对象。在给定图层中,所有要素的几何类型都相同,与要素来自的 Layer 对象的 Layer.geom_type 属性相等。

num_fields

返回与此要素关联的数据字段数量。在给定图层中,所有要素的字段数量都相同,等同于要素来自的 Layer 对象的 Layer.num_fields 属性。

fields

返回与此要素关联的数据字段的名称列表。在给定图层中,所有要素的字段名称都相同,等同于要素来自的 Layer 对象的 Layer.fields 属性。

fid

返回图层中的要素标识符:

>>> city.fid
0
layer_name

返回要素来自的 Layer 的名称。在给定图层中,所有要素的图层名称都相同:

>>> city.layer_name
'cities'
index

一个方法,返回给定字段名称的索引。在给定图层中,所有要素的字段名称的索引都相同:

>>> city.index("Population")
1

Field

class Field
name

返回此字段的名称:

>>> city["Name"].name
'Name'
type

返回此字段的 OGR 类型,以整数形式表示。FIELD_CLASSES 字典将这些值映射到 Field 的子类:

>>> city["Density"].type
2
type_name

返回表示此字段数据类型的字符串名称:

>>> city["Name"].type_name
'String'
value

返回此字段的值。Field 类本身将值作为字符串返回,但每个子类都以最合适的形式返回值:

>>> city["Population"].value
102121
width

返回此字段的宽度:

>>> city["Name"].width
80
precision

返回此字段的数值精度。对于非数值字段,这是没有意义的(并且设置为零):

>>> city["Density"].precision
15
as_double()

将字段的值作为 double(浮点数)返回:

>>> city["Density"].as_double()
874.7
as_int()

将字段的值作为整数返回:

>>> city["Population"].as_int()
102121
as_string()

将字段的值作为字符串返回:

>>> city["Name"].as_string()
'Pueblo'
as_datetime()

将字段的值作为日期和时间组件的元组返回:

>>> city["Created"].as_datetime()
(c_long(1999), c_long(5), c_long(23), c_long(0), c_long(0), c_long(0), c_long(0))

Driver

class Driver(dr_input)

Driver 类在内部用于包装一个 OGR DataSource 驱动程序。

driver_count

返回当前已注册的 OGR 矢量驱动程序的数量。

OGR 几何对象

OGRGeometry

OGRGeometry 对象与 GEOSGeometry 对象具有类似的功能,它们都是对 OGR 内部几何表示的薄包装。因此,它们在使用 DataSource 时允许更高效地访问数据。与其 GEOS 对应物不同,OGRGeometry 支持空间参考系统和坐标转换:

>>> from django.contrib.gis.gdal import OGRGeometry
>>> polygon = OGRGeometry("POLYGON((0 0, 5 0, 5 5, 0 5))")
class OGRGeometry(geom_input, srs=None)

这个对象是 `OGR Geometry`__ 类的包装器。这些对象直接从给定的 geom_input 参数实例化,该参数可以是包含 WKT、HEX、GeoJSON、包含 WKB 数据的 buffer,或者是一个 OGRGeomType 对象。这些对象还可以从 Layer`(它又是 :class:`DataSource 的一部分)读取矢量数据时,从 Feature.geom 属性返回。

classmethod from_gml(gml_string)

从给定的 GML 字符串构造一个 OGRGeometry

classmethod from_bbox(bbox)

从给定的边界框(一个包含 4 个元素的元组)构造一个 Polygon

__len__()

返回一个 LineString 中的点数,一个 Polygon 中的环数,或一个 GeometryCollection 中的几何对象数。不适用于其他几何类型。

__iter__()

遍历一个 LineString 中的点,一个 Polygon 中的环,或一个 GeometryCollection 中的几何对象。不适用于其他几何类型。

__getitem__()

返回一个 LineString 中指定索引的点,一个 Polygon 中指定索引的内环,或一个 GeometryCollection 中指定索引的几何对象。不适用于其他几何类型。

dimension

返回几何图形的坐标维度数,例如点的维度为 0,线的维度为 1,依此类推:

>>> polygon.dimension
2
coord_dim

返回或设置此几何图形的坐标维度。例如,对于二维几何图形,值将为 2。

geom_count

返回此几何图形中的元素数量:

>>> polygon.geom_count
1
point_count

返回用于描述此几何图形的点的数量:

>>> polygon.point_count
4
num_points

point_count 的别名。

num_coords

point_count 的别名。

geom_type

返回此几何图形的类型,作为一个 OGRGeomType 对象。

geom_name

返回此几何图形类型的名称:

>>> polygon.geom_name
'POLYGON'
area

返回此几何图形的面积,对于不包含面积的几何图形,返回 0:

>>> polygon.area
25.0
envelope

返回此几何图形的包络,作为一个 Envelope 对象。

extent

返回此几何图形的包络作为一个 4-元组,而不是一个 Envelope 对象:

>>> point.extent
(0.0, 0.0, 5.0, 5.0)
srs

此属性控制此几何图形的空间参考,如果没有分配空间参考系统,则为 None。如果分配了空间参考系统,访问此属性将返回一个 SpatialReference 对象。它可以使用另一个 SpatialReference 对象或任何 SpatialReference 接受的输入进行设置。示例:

>>> city.geom.srs.name
'GCS_WGS_1984'
srid

返回或设置与此几何图形的 SpatialReference 相对应的空间参考标识符。如果没有与此几何图形关联的空间参考信息,或者无法确定 SRID,则返回 None

geos

返回与此几何图形对应的 GEOSGeometry 对象。

gml

返回此几何图形的 GML 格式的字符串表示:

>>> OGRGeometry("POINT(1 2)").gml
'<gml:Point><gml:coordinates>1,2</gml:coordinates></gml:Point>'
hex

返回此几何图形的 HEX WKB 格式的字符串表示:

>>> OGRGeometry("POINT(1 2)").hex
'0101000000000000000000F03F0000000000000040'
json

返回此几何图形的 JSON 格式的字符串表示:

>>> OGRGeometry("POINT(1 2)").json
'{ "type": "Point", "coordinates": [ 1.000000, 2.000000 ] }'
kml

返回此几何图形的 KML 格式的字符串表示。

wkb_size

返回用于容纳此几何图形的 WKB 表示的 WKB 缓冲区的大小:

>>> OGRGeometry("POINT(1 2)").wkb_size
21
wkb

返回一个包含此几何图形的 WKB 表示的 buffer

wkt

返回此几何图形的 WKT 格式的字符串表示:

ewkt

返回此几何图形的 EWKT 表示。

clone()

返回一个新的 OGRGeometry 克隆对象,与此几何图形对象相同。

close_rings()

如果此几何图形中有任何未封闭的环,此过程将通过将起始点添加到末尾来封闭它们:

>>> triangle = OGRGeometry("LINEARRING (0 0,0 1,1 0)")
>>> triangle.close_rings()
>>> triangle.wkt
'LINEARRING (0 0,0 1,1 0,0 0)'
transform(coord_trans, clone=False)

将此几何图形转换到不同的空间参考系统。可以采用 CoordTransform 对象、SpatialReference 对象或 SpatialReference 接受的任何其他输入(包括空间参考 WKT 和 PROJ 字符串,或整数 SRID)。

默认情况下,不返回任何内容,并且在原地转换几何图形。然而,如果将 clone 关键字设置为 True,则返回一个转换后的克隆几何图形。

intersects(other)

如果此几何图形与另一个几何图形相交,则返回 True,否则返回 False

equals(other)

如果此几何图形等同于另一个几何图形,则返回 True,否则返回 False

disjoint(other)

如果此几何图形与另一个几何图形在空间上不相交(即不相交),则返回 True,否则返回 False

touches(other)

如果此几何图形与另一个几何图形相邻接,则返回 True,否则返回 False

crosses(other)

如果此几何图形与另一个几何图形交叉,则返回 True,否则返回 False

within(other)

如果此几何图形包含在另一个几何图形内部,则返回 True,否则返回 False

contains(other)

如果此几何图形包含另一个几何图形,则返回 True,否则返回 False

overlaps(other)

如果此几何图形与另一个几何图形重叠,则返回 True,否则返回 False

boundary()

这个几何图形的边界,作为一个新的 OGRGeometry 对象。

convex_hull

包含此几何图形的最小凸多边形,作为一个新的 OGRGeometry 对象。

difference()

返回由此几何图形与另一个几何图形的差组成的区域,作为一个新的 OGRGeometry 对象。

intersection()

返回由此几何图形与另一个几何图形的交集组成的区域,作为一个新的 OGRGeometry 对象。

sym_difference()

返回由此几何图形与另一个几何图形的对称差组成的区域,作为一个新的 OGRGeometry 对象。

union()

返回由此几何图形与另一个几何图形的并集组成的区域,作为一个新的 OGRGeometry 对象。

tuple

返回点几何的坐标作为一个元组,线几何的坐标作为元组的元组,依此类推:

>>> OGRGeometry("POINT (1 2)").tuple
(1.0, 2.0)
>>> OGRGeometry("LINESTRING (1 2,3 4)").tuple
((1.0, 2.0), (3.0, 4.0))
coords

一个用于 tuple 的别名。

class Point
x

返回此点的 X 坐标:

>>> OGRGeometry("POINT (1 2)").x
1.0
y

返回此点的 Y 坐标:

>>> OGRGeometry("POINT (1 2)").y
2.0
z

返回此点的 Z 坐标,如果此点没有 Z 坐标,则返回 None

>>> OGRGeometry("POINT (1 2 3)").z
3.0
class LineString
x

返回此线中的 X 坐标列表:

>>> OGRGeometry("LINESTRING (1 2,3 4)").x
[1.0, 3.0]
y

返回此线中的 Y 坐标列表:

>>> OGRGeometry("LINESTRING (1 2,3 4)").y
[2.0, 4.0]
z

返回此线中的 Z 坐标列表,如果此线没有 Z 坐标,则返回 None

>>> OGRGeometry("LINESTRING (1 2 3,4 5 6)").z
[3.0, 6.0]
class Polygon
shell

返回此多边形的外壳或外部环,作为一个 LinearRing 几何体。

exterior_ring

shell 的别名。

centroid

返回一个代表此多边形的质心的 Point

class GeometryCollection
add(geom)

将一个几何体添加到此几何体集合中。不适用于其他几何体类型。

OGRGeomType

class OGRGeomType(type_input)

这个类允许以多种方式表示 OGR 几何类型:

>>> from django.contrib.gis.gdal import OGRGeomType
>>> gt1 = OGRGeomType(3)  # Using an integer for the type
>>> gt2 = OGRGeomType("Polygon")  # Using a string
>>> gt3 = OGRGeomType("POLYGON")  # It's case-insensitive
>>> print(gt1 == 3, gt1 == "Polygon")  # Equivalence works w/non-OGRGeomType objects
True True
name

返回 OGR 几何类型的简略字符串形式:

>>> gt1.name
'Polygon'
num

返回对应于 OGR 几何类型的数字:

>>> gt1.num
3
django

返回用于存储此 OGR 类型的 Django 字段类型(GeometryField 的子类),如果没有合适的 Django 类型,则返回 None

>>> gt1.django
'PolygonField'

Envelope

class Envelope(*args)

表示包含矩形边界框的最小和最大 X、Y 坐标的 OGR Envelope 结构。变量的命名与 OGR Envelope C 结构兼容。

min_x

最小 X 坐标的值。

min_y

最大 X 坐标的值。

max_x

最小 Y 坐标的值。

max_y

最大 Y 坐标的值。

ur

右上角坐标,表示为一个元组。

ll

左下角坐标,表示为一个元组。

tuple

表示包围盒的元组。

wkt

以 WKT 格式表示此包围盒的字符串。

expand_to_include(*args)

坐标系统对象

SpatialReference

class SpatialReference(srs_input)

空间参考对象在给定的 srs_input 上初始化,可以是以下之一:

  • OGC Well Known Text (WKT)(一个字符串)
  • EPSG 代码(整数或字符串)
  • PROJ 字符串
  • 一个用于常见标准的简写字符串('WGS84''WGS72''NAD27''NAD83'

例如:

>>> wgs84 = SpatialReference("WGS84")  # shorthand string
>>> wgs84 = SpatialReference(4326)  # EPSG code
>>> wgs84 = SpatialReference("EPSG:4326")  # EPSG string
>>> proj = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs "
>>> wgs84 = SpatialReference(proj)  # PROJ string
>>> wgs84 = SpatialReference(
...     """GEOGCS["WGS 84",
... DATUM["WGS_1984",
...      SPHEROID["WGS 84",6378137,298.257223563,
...          AUTHORITY["EPSG","7030"]],
...      AUTHORITY["EPSG","6326"]],
... PRIMEM["Greenwich",0,
...      AUTHORITY["EPSG","8901"]],
... UNIT["degree",0.01745329251994328,
...      AUTHORITY["EPSG","9122"]],
... AUTHORITY["EPSG","4326"]]"""
... )  # OGC WKT
__getitem__(target)

返回给定字符串属性节点的值,如果节点不存在则返回 None。还可以将元组作为参数传递,(target, child),其中 child 是 WKT 中属性的索引。例如:

>>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]'
>>> srs = SpatialReference(wkt)  # could also use 'WGS84', or 4326
>>> print(srs["GEOGCS"])
WGS 84
>>> print(srs["DATUM"])
WGS_1984
>>> print(srs["AUTHORITY"])
EPSG
>>> print(srs["AUTHORITY", 1])  # The authority value
4326
>>> print(srs["TOWGS84", 4])  # the fourth value in this wkt
0
>>> print(srs["UNIT|AUTHORITY"])  # For the units authority, have to use the pipe symbol.
EPSG
>>> print(srs["UNIT|AUTHORITY", 1])  # The authority value for the units
9122
attr_value(target, index=0)

给定目标节点(例如 'PROJCS')的属性值。索引关键字指定要返回的子节点的索引。

auth_name(target)

返回给定字符串目标节点的权限名称。

auth_code(target)

返回给定字符串目标节点的权限代码。

clone()

返回此空间参考对象的克隆。

identify_epsg()

此方法检查此 SpatialReference 的 WKT,并在适用的情况下添加 EPSG 权威节点。

from_esri()

将此空间参考从 ESRI 格式转换为 EPSG 格式。

to_esri()

将此空间参考转换为 ESRI 格式。

validate()

检查给定的空间参考是否有效,如果无效,将引发异常。

import_epsg(epsg)

从 EPSG 代码导入空间参考。

import_proj(proj)

从 PROJ 字符串导入空间参考。

import_user_input(user_input)
import_wkt(wkt)

从 WKT 导入空间参考。

import_xml(xml)

从 XML 导入空间参考。

name

返回此空间参考的名称。

srid

返回顶级权限的 SRID,如果未定义则返回 None

linear_name

返回线性单位的名称。

linear_units

返回线性单位的值。

angular_name

返回角度单位的名称。

angular_units

返回角度单位的值。

units

返回一个包含单位值和单位名称的 2 元组,并会自动确定是返回线性单位还是角度单位。

ellipsoid

返回此空间参考的椭圆参数的元组:(半长轴、半短轴和倒扁率)。

semi_major

返回此空间参考的椭圆体的半长轴。

semi_minor

返回此空间参考的椭圆体的半短轴。

inverse_flattening

返回此空间参考的椭圆体的倒扁率。

geographic

如果此空间参考是地理空间参考(根节点是 GEOGCS),则返回 True

local

如果此空间参考是本地空间参考(根节点是 LOCAL_CS),则返回 True

projected

如果此空间参考是投影坐标系统(根节点是 PROJCS),则返回 True

wkt

返回此空间参考的 WKT 表示。

pretty_wkt

返回 WKT 的 'pretty' 表示。

proj

返回此空间参考的 PROJ 表示。

proj4

SpatialReference.proj 的别名。

xml

返回此空间参考的 XML 表示。

CoordTransform

class CoordTransform(source, target)

表示坐标系统转换。它使用两个 SpatialReference 初始化,分别表示源坐标系统和目标坐标系统。当在不同的几何体上重复执行相同的坐标转换时,应使用这些对象:

>>> ct = CoordTransform(SpatialReference("WGS84"), SpatialReference("NAD83"))
>>> for feat in layer:
...     geom = feat.geom  # getting clone of feature geometry
...     geom.transform(ct)  # transforming
...

栅格数据对象

GDALRaster

GDALRaster 是对 GDAL 栅格源对象的包装,它支持使用一致的接口从各种 GDAL 支持的地理空间文件格式和数据源中读取数据。每个数据源由一个 GDALRaster 对象表示,其中包含一个或多个名为波段的数据层。每个波段,由一个 GDALBand 对象表示,包含地理参考的图像数据。例如,一个 RGB 图像由三个波段表示:一个用于红色,一个用于绿色,一个用于蓝色。

备注

对于栅格数据,栅格实例和其数据源之间没有区别。与几何体对象不同,GDALRaster 对象始终是数据源。可以使用相应的驱动程序在内存中实例化临时栅格,但它们与基于文件的栅格源具有相同的类。

class GDALRaster(ds_input, write=False)

GDALRaster 的构造函数接受两个参数。第一个参数定义了栅格源,第二个参数定义了是否应以写入模式打开栅格。对于新创建的栅格,第二个参数将被忽略,并且新栅格始终以写入模式创建。

第一个参数可以有三种形式:表示文件路径(文件系统或 GDAL 虚拟文件系统)的字符串或 Path,包含定义新栅格的值的字典,或者表示栅格文件的字节对象。

如果输入是一个文件路径,从那里打开栅格。如果输入是字典中的原始数据,需要参数 widthheightsrid。如果输入是一个字节对象,它将使用 GDAL 虚拟文件系统打开。

有关如何使用字典输入创建栅格图像的详细说明,请参阅 从数据创建栅格图像。有关如何在虚拟文件系统中创建栅格图像的详细说明,请参阅 使用 GDAL 的虚拟文件系统

以下示例展示了如何从不同的输入源创建栅格图像(使用 GeoDjango 测试中的示例数据;另请参阅 样本数据 部分)。

>>> from django.contrib.gis.gdal import GDALRaster
>>> rst = GDALRaster('/path/to/your/raster.tif', write=False)
>>> rst.name
'/path/to/your/raster.tif'
>>> rst.width, rst.height  # This file has 163 x 174 pixels
(163, 174)
>>> rst = GDALRaster({  # Creates an in-memory raster
...     'srid': 4326,
...     'width': 4,
...     'height': 4,
...     'datatype': 1,
...     'bands': [{
...         'data': (2, 3),
...         'offset': (1, 1),
...         'size': (2, 2),
...         'shape': (2, 1),
...         'nodata_value': 5,
...     }]
... })
>>> rst.srs.srid
4326
>>> rst.width, rst.height
(4, 4)
>>> rst.bands[0].data()
array([[5, 5, 5, 5],
       [5, 2, 3, 5],
       [5, 2, 3, 5],
       [5, 5, 5, 5]], dtype=uint8)
>>> rst_file = open('/path/to/your/raster.tif', 'rb')
>>> rst_bytes = rst_file.read()
>>> rst = GDALRaster(rst_bytes)
>>> rst.is_vsi_based
True
>>> rst.name  # Stored in a random path in the vsimem filesystem.
'/vsimem/da300bdb-129d-49a8-b336-e410a9428dad'
Changed in Django 4.2:

增加了对 pathlib.Path ds_input 的支持。

name

源的名称等同于输入文件路径或实例化时提供的名称。

>>> GDALRaster({'width': 10, 'height': 10, 'name': 'myraster', 'srid': 4326}).name
'myraster'
driver

用于处理输入文件的 GDAL 驱动程序的名称。对于从文件创建的 GDALRaster,驱动程序类型会自动检测。默认情况下,从头开始创建的栅格图像是内存中的栅格图像('MEM'),但可以根据需要进行更改。例如,可以使用 GTiff 创建 GeoTiff 文件。有关文件类型的列表,还可以查看 `GDAL 栅格格式`__ 列表。

内存中的栅格图像可以通过以下示例创建:

>>> GDALRaster({'width': 10, 'height': 10, 'srid': 4326}).driver.name
'MEM'

通过以下示例可以创建基于文件的 GeoTiff 栅格图像:

>>> import tempfile
>>> rstfile = tempfile.NamedTemporaryFile(suffix='.tif')
>>> rst = GDALRaster({'driver': 'GTiff', 'name': rstfile.name, 'srid': 4326,
...                   'width': 255, 'height': 255, 'nr_of_bands': 1})
>>> rst.name
'/tmp/tmp7x9H4J.tif'           # The exact filename will be different on your computer
>>> rst.driver.name
'GTiff'
width

源的宽度,以像素为单位(X 轴)。

>>> GDALRaster({'width': 10, 'height': 20, 'srid': 4326}).width
10
height

源的高度,以像素为单位(Y 轴)。

>>> GDALRaster({'width': 10, 'height': 20, 'srid': 4326}).height
20
srs

栅格图像的空间参考系统,作为一个 SpatialReference 实例。SRS 可以通过将其设置为另一个 SpatialReference 或提供 SpatialReference 构造函数接受的任何输入来更改。

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.srs.srid
4326
>>> rst.srs = 3086
>>> rst.srs.srid
3086
srid

栅格图像的空间参考系统标识符(SRID)。此属性是通过 srs 属性获取或设置 SRID 的快捷方式。

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.srid
4326
>>> rst.srid = 3086
>>> rst.srid
3086
>>> rst.srs.srid  # This is equivalent
3086
geotransform

用于地理参考源的仿射变换矩阵,表示为六个系数的元组,这些系数将像素/行坐标映射到地理参考空间,关系如下:

Xgeo = GT(0) + Xpixel * GT(1) + Yline * GT(2)
Ygeo = GT(3) + Xpixel * GT(4) + Yline * GT(5)

可以通过访问 origin (索引 0 和 3)、scale (索引 1 和 5)和 skew (索引 2 和 4)属性来获取相同的值。

默认值为 [0.0, 1.0, 0.0, 0.0, 0.0, -1.0]

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.geotransform
[0.0, 1.0, 0.0, 0.0, 0.0, -1.0]
origin

栅格图像在源的空间参考系统中的左上角原点坐标,表示为具有 xy 成员的点对象。

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.origin
[0.0, 0.0]
>>> rst.origin.x = 1
>>> rst.origin
[1.0, 0.0]
scale

用于地理参考栅格图像的像素宽度和高度,表示为具有 xy 成员的点对象。有关更多信息,请参阅 geotransform

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.scale
[1.0, -1.0]
>>> rst.scale.x = 2
>>> rst.scale
[2.0, -1.0]
skew

用于地理参考栅格图像的偏移系数,表示为具有 xy 成员的点对象。在北向图像的情况下,这些系数都为 0

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.skew
[0.0, 0.0]
>>> rst.skew.x = 3
>>> rst.skew
[3.0, 0.0]
extent

栅格图像源的范围(边界值),表示为源的空间参考系统中的 4 元组 (xmin, ymin, xmax, ymax)

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.extent
(0.0, -20.0, 10.0, 0.0)
>>> rst.origin.x = 100
>>> rst.extent
(100.0, -20.0, 110.0, 0.0)
bands

源的所有波段列表,表示为 GDALBand 实例。

>>> rst = GDALRaster({"width": 1, "height": 2, 'srid': 4326,
...                   "bands": [{"data": [0, 1]}, {"data": [2, 3]}]})
>>> len(rst.bands)
2
>>> rst.bands[1].data()
array([[ 2.,  3.]], dtype=float32)
warp(ds_input, resampling='NearestNeighbour', max_error=0.0)

返回此栅格图像的变形版本。

变形参数可以通过 ds_input 参数进行指定。使用 ds_input 与类构造函数的相应参数类似。它是一个具有目标栅格图像特征的字典。允许的字典键值包括 width、height、SRID、origin、scale、skew、datatype、driver 和 name(文件名)。

默认情况下,变形函数将大多数参数保持等于原始源栅格图像的值,因此只需要指定需要更改的参数。请注意,这包括驱动程序,因此对于基于文件的栅格图像,变形函数将在磁盘上创建一个新的栅格图像。

唯一与源栅格图像不同的参数是名称。栅格图像的默认名称是源栅格图像的名称附加上 '_copy' + source_driver_name。对于基于文件的栅格图像,建议提供目标栅格图像的文件路径。

用于变形的重采样算法可以通过 resampling 参数进行指定。默认值是 NearestNeighbor,其他允许的值包括 BilinearCubicCubicSplineLanczosAverageMode

max_error 参数可以用于指定在近似变换中允许的最大误差,以输入像素为单位进行测量。默认值为 0.0,表示精确计算。

对于熟悉 GDAL 的用户,此函数具有类似于 gdalwarp 命令行实用程序的功能。

例如,可以使用变形函数将栅格图像聚合到其原始像素比例的两倍:

>>> rst = GDALRaster({
...     "width": 6, "height": 6, "srid": 3086,
...     "origin": [500000, 400000],
...     "scale": [100, -100],
...     "bands": [{"data": range(36), "nodata_value": 99}]
... })
>>> target = rst.warp({"scale": [200, -200], "width": 3, "height": 3})
>>> target.bands[0].data()
array([[  7.,   9.,  11.],
       [ 19.,  21.,  23.],
       [ 31.,  33.,  35.]], dtype=float32)
transform(srs, driver=None, name=None, resampling='NearestNeighbour', max_error=0.0)

将此栅格图像转换为不同的空间参考系统(srs),可以是一个 SpatialReference 对象,或者是 SpatialReference 接受的任何其他输入(包括空间参考 WKT 和 PROJ 字符串,或整数 SRID)。

它会计算当前栅格图像在新的空间参考系统中的范围和比例,并使用 warp 函数对栅格图像进行变形。

默认情况下,使用源栅格图像的驱动程序,并且栅格图像的名称是原始名称附加上 '_copy' + source_driver_name。可以使用 drivername 参数指定不同的驱动程序或名称。

默认的重采样算法是 NearestNeighbour,但可以使用 resampling 参数进行更改。默认的允许的最大误差为 0.0,可以使用 max_error 参数进行更改。有关这些参数的详细信息,请参阅 warp 文档。

>>> rst = GDALRaster({
...     "width": 6, "height": 6, "srid": 3086,
...     "origin": [500000, 400000],
...     "scale": [100, -100],
...     "bands": [{"data": range(36), "nodata_value": 99}]
... })
>>> target_srs = SpatialReference(4326)
>>> target = rst.transform(target_srs)
>>> target.origin
[-82.98492744885776, 27.601924753080144]
info

返回一个包含栅格图像摘要的字符串。这相当于 `gdalinfo`__ 命令行实用程序。

metadata

这个光栅数据的元数据,以嵌套字典的方式表示。第一级键是元数据的领域。第二级包含来自每个领域的元数据项名称和值。

要设置或更新元数据项,请使用上面描述的嵌套结构将相应的元数据项传递给该方法。只有在指定的字典中的键才会被更新;其余的元数据保持不变。

要删除一个元数据项,请将元数据值设置为 None

>>> rst = GDALRaster({'width': 10, 'height': 20, 'srid': 4326})
>>> rst.metadata
{}
>>> rst.metadata = {'DEFAULT': {'OWNER': 'Django', 'VERSION': '1.0'}}
>>> rst.metadata
{'DEFAULT': {'OWNER': 'Django', 'VERSION': '1.0'}}
>>> rst.metadata = {'DEFAULT': {'OWNER': None, 'VERSION': '2.0'}}
>>> rst.metadata
{'DEFAULT': {'VERSION': '2.0'}}
vsi_buffer

这个光栅的 bytes 表示。对于不存储在 GDAL 虚拟文件系统中的光栅,返回 None

is_vsi_based

一个布尔值,指示此栅格是否存储在 GDAL 的虚拟文件系统中。

GDALBand

class GDALBand

GDALBand 实例不是显式创建的,而是通过其 bands 属性从一个 GDALRaster 对象中获取的。GDALBands 包含了栅格的实际像素值。

description

带的名称或描述,如果有的话。

width

像素单位下的带宽度(X轴)。

height

像素单位下的带高度(Y轴)。

pixel_count

这个带的总像素数等于 宽度 * 高度

statistics(refresh=False, approximate=False)

计算这个带的像素值统计信息。返回值是一个具有以下结构的元组:(最小值, 最大值, 平均值, 标准差)

如果 approximate 参数设置为 True,则可以基于概览或图像块的子集来计算统计信息。

如果 refresh 参数设置为 True,统计信息将直接从数据中计算,并且缓存将使用结果进行更新。

如果找到持久缓存值,将返回该值。对于使用持久辅助元数据(PAM)服务的栅格格式,统计信息可能会缓存在辅助文件中。在某些情况下,这些元数据可能与像素值不同步,或者导致返回先前调用的值,这些值不反映 approximate 参数的值。在这种情况下,使用 refresh 参数来获取更新的值并将其存储在缓存中。

对于空白带(其中所有像素值均为“无数据”),所有统计信息都将返回为 None

统计信息还可以通过直接访问 minmaxmeanstd 属性来获取。

min

带中的最小像素值(不包括“无数据”值)。

max

带中的最大像素值(不包括“无数据”值)。

mean

带中所有像素值的平均值(不包括“无数据”值)。

std

带中所有像素值的标准差(不包括“无数据”值)。

nodata_value

带的“无数据”值通常是一个特殊的标记值,用于标记无效数据的像素。这些像素通常不应显示,也不应对分析操作产生影响。

要删除现有的“无数据”值,将该属性设置为 None

datatype(as_string=False)

带中包含的数据类型,作为一个介于 0(未知)和 11 之间的整数常量。如果 as_stringTrue,则数据类型将作为一个字符串返回,可能的值包括:GDT_UnknownGDT_ByteGDT_UInt16GDT_Int16GDT_UInt32GDT_Int32GDT_Float32GDT_Float64GDT_CInt16GDT_CInt32GDT_CFloat32GDT_CFloat64

color_interp(as_string=False)

带的颜色解释,作为一个介于 0 和 16 之间的整数。如果 as_stringTrue,则颜色解释将作为一个字符串返回,可能的值包括:GCI_UndefinedGCI_GrayIndexGCI_PaletteIndexGCI_RedBandGCI_GreenBandGCI_BlueBandGCI_AlphaBandGCI_HueBandGCI_SaturationBandGCI_LightnessBandGCI_CyanBandGCI_MagentaBandGCI_YellowBandGCI_BlackBandGCI_YCbCr_YBandGCI_YCbCr_CbBandGCI_YCbCr_CrBandGCI_YCbCr_CrBand 也代表 GCI_Max,因为两者都对应整数 16,但只有 GCI_YCbCr_CrBand 作为字符串返回。

data(data=None, offset=None, size=None, shape=None)

访问 GDALBand 的像素值的访问器。如果不提供参数,则返回完整的数据数组。可以通过指定偏移和块大小的元组来请求像素数组的子集。

如果有 NumPy 可用,数据将作为 NumPy 数组返回。出于性能考虑,强烈建议使用 NumPy。

如果提供了 data 参数,数据将被写入 GDALBand。输入可以是以下类型之一 - 打包的字符串、缓冲区、列表、数组和 NumPy 数组。输入中的项目数通常应与带中的总像素数相对应,或者与特定像素值块的像素数相对应,如果提供了 offsetsize 参数的话。

如果输入中的项目数与目标像素块不同,必须指定 shape 参数。shape 是一个元组,指定了像素单位中输入数据的宽度和高度。然后,数据将被复制以更新所选块的像素值。这对于用单个值填充整个带非常有用。

例如:

>>> rst = GDALRaster({'width': 4, 'height': 4, 'srid': 4326, 'datatype': 1, 'nr_of_bands': 1})
>>> bnd = rst.bands[0]
>>> bnd.data(range(16))
>>> bnd.data()
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]], dtype=int8)
>>> bnd.data(offset=(1, 1), size=(2, 2))
array([[ 5,  6],
       [ 9, 10]], dtype=int8)
>>> bnd.data(data=[-1, -2, -3, -4], offset=(1, 1), size=(2, 2))
>>> bnd.data()
array([[ 0,  1,  2,  3],
       [ 4, -1, -2,  7],
       [ 8, -3, -4, 11],
       [12, 13, 14, 15]], dtype=int8)
>>> bnd.data(data='\x9d\xa8\xb3\xbe', offset=(1, 1), size=(2, 2))
>>> bnd.data()
array([[  0,   1,   2,   3],
       [  4, -99, -88,   7],
       [  8, -77, -66,  11],
       [ 12,  13,  14,  15]], dtype=int8)
>>> bnd.data([1], shape=(1, 1))
>>> bnd.data()
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]], dtype=uint8)
>>> bnd.data(range(4), shape=(1, 4))
array([[0, 0, 0, 0],
       [1, 1, 1, 1],
       [2, 2, 2, 2],
       [3, 3, 3, 3]], dtype=uint8)
metadata

此带的元数据。功能与 GDALRaster.metadata 相同。

从数据创建栅格图像

本节描述如何使用 ds_input 参数从头创建栅格图像。

当将一个包含新栅格定义参数的字典传递给 GDALRaster 构造函数时,将创建一个新的栅格图像。字典包含新栅格的定义参数,如原点、大小或空间参考系统。字典还可以包含像素数据和有关新栅格格式的信息。因此,生成的栅格可以是基于文件或基于内存的,这取决于指定的驱动程序。

在字典或 JSON 格式中,没有用于描述栅格数据的标准。因此,传递给 GDALRaster 类的字典输入的定义是特定于 Django 的。它受到 geojson 格式的启发,但当前的 geojson 标准仅限于矢量格式。

GDALRasterGDALBand 类的相应属性和方法的文档中可以找到创建栅格时使用不同键的示例。

ds_input 字典

要创建栅格, ds_input 字典中只需要几个必需的键:widthheightsrid。所有其他参数都具有默认值(请参阅下表)。可以传递到 ds_input 字典中的键列表与 GDALRaster 属性密切相关,但不完全相同。许多参数直接映射到这些属性;其他参数如下所述。

以下表格描述了可以在 ds_input 字典中设置的所有键。

默认 用法
srid 必须的 映射到 srid 属性。
width 必须的 映射到 width 属性。
height 必须的 映射到 height 属性。
driver MEM 映射到 driver 属性。
name '' 见以下
origin 0 映射到 origin 属性。
scale 0 映射到 scale 属性。
skew 0 映射到 width 属性。
bands [] 见以下
nr_of_bands 0 见以下
datatype 6 见以下
papsz_options {} 见以下
name

表示栅格的名称的字符串。在创建基于文件的栅格时,此参数必须是新栅格的文件路径。如果名称以 /vsimem/ 开头,则栅格将在 GDAL 的虚拟文件系统中创建。

datatype

表示所有波段的数据类型的整数。默认值为 6 (Float32)。新栅格的所有波段都必须具有相同的数据类型。值映射如下:

GDAL 像素类型 描述
1 GDT_Byte 八位无符号整数
2 GDT_UInt16 十六位无符号整数
3 GDT_Int16 十六位有符号整数
4 GDT_UInt32 三十二位无符号整数
5 GDT_Int32 三十二位有符号整数
6 GDT_Float32 三十二位浮点数
7 GDT_Float64 六十四位浮点数
nr_of_bands

表示栅格波段数量的整数。可以在创建时创建栅格而不传递波段数据。如果未指定波段数量,则会自动从 bands 输入的长度计算出来。在创建后无法更改波段数量。

bands

包含带有波段输入数据的 band_input 字典列表。生成的波段索引与提供的列表中的索引相同。波段输入字典的定义如下。如果未提供波段数据,则栅格波段的值将初始化为零数组,并且 "无数据" 值将设置为 None

papsz_options

一个包含栅格创建选项的字典。输入字典的键值对在创建栅格时传递给驱动程序。

可用选项是特定于驱动程序的,并在每个驱动程序的文档中进行了描述。

字典中的值不区分大小写,并在创建时自动转换为正确的字符串格式。

以下示例使用了 `GTiff 驱动程序`__ 中的一些可用选项。结果是一个具有内部平铺方案的压缩有符号字节栅格。内部瓦片的块大小为 23x23:

>>> GDALRaster(
...     {
...         "driver": "GTiff",
...         "name": "/path/to/new/file.tif",
...         "srid": 4326,
...         "width": 255,
...         "height": 255,
...         "nr_of_bands": 1,
...         "papsz_options": {
...             "compress": "packbits",
...             "pixeltype": "signedbyte",
...             "tiled": "yes",
...             "blockxsize": 23,
...             "blockysize": 23,
...         },
...     }
... )

band_input 字典

ds_input 字典中的 bands 键是一个包含 band_input 字典的列表。每个 band_input 字典可以包含像素值和要在新栅格的波段上设置的 "no data" 值。数据数组可以具有新栅格的全尺寸或更小。对于小于完整栅格的数组,sizeshapeoffset 键控制像素值。相应的键传递给 data() 方法。它们的功能与使用该方法设置波段数据的方式相同。以下表格描述了可以使用的键。

默认 用法
nodata_value None 映射到 nodata_value 属性
data nodata_value0 相同 传递给 data() 方法
size (宽度, 高度) 的栅格 传递给 data() 方法
shape 与尺寸相同 传递给 data() 方法
offset (0, 0) 传递给 data() 方法

使用 GDAL 的虚拟文件系统

GDAL 可以访问存储在文件系统中的文件,还支持虚拟文件系统,以抽象访问其他类型的文件,例如压缩、加密或远程文件。

使用基于内存的虚拟文件系统

GDAL 具有内置的基于内存的文件系统,允许将内存块视为文件。它可以用于从二进制文件缓冲区读取和写入 GDALRaster 对象。

这在 Web 上的情况下非常有用,因为栅格可能以缓冲区的形式从远程存储获取,或者从视图返回而无需写入磁盘。

当提供一个 bytes 对象作为输入,或者文件路径以 /vsimem/ 开头时,GDALRaster 对象将在虚拟文件系统中创建。

提供的输入作为 bytes 必须是文件的完整二进制表示。例如:

# Read a raster as a file object from a remote source.
>>> from urllib.request import urlopen
>>> dat = urlopen("http://example.com/raster.tif").read()
# Instantiate a raster from the bytes object.
>>> rst = GDALRaster(dat)
# The name starts with /vsimem/, indicating that the raster lives in the
# virtual filesystem.
>>> rst.name
'/vsimem/da300bdb-129d-49a8-b336-e410a9428dad'

要从头开始创建一个新的虚拟文件基础的栅格,使用 ds_input 字典表示并提供一个以 /vsimem/ 开头的 name 参数(有关字典表示的详细信息,请参阅 从数据创建栅格图像)。对于虚拟文件基础的栅格,vsi_buffer 属性返回栅格的 bytes 表示。

以下是如何创建一个栅格并将其作为文件返回到 HttpResponse 的方法:

>>> from django.http import HttpResponse
>>> rst = GDALRaster(
...     {
...         "name": "/vsimem/temporarymemfile",
...         "driver": "tif",
...         "width": 6,
...         "height": 6,
...         "srid": 3086,
...         "origin": [500000, 400000],
...         "scale": [100, -100],
...         "bands": [{"data": range(36), "nodata_value": 99}],
...     }
... )
>>> HttpResponse(rast.vsi_buffer, "image/tiff")

使用其他虚拟文件系统

根据 GDAL 的本地构建,可能支持其他虚拟文件系统。您可以通过在提供的路径前添加适当的 /vsi*/ 前缀来使用它们。有关更多详细信息,请参阅 GDAL 虚拟文件系统文档

压缩的栅格

不必解压缩文件并实例化生成的栅格,GDAL 可以直接使用 /vsizip//vsigzip//vsitar/ 虚拟文件系统访问压缩文件:

>>> from django.contrib.gis.gdal import GDALRaster
>>> rst = GDALRaster("/vsizip/path/to/your/file.zip/path/to/raster.tif")
>>> rst = GDALRaster("/vsigzip/path/to/your/file.gz")
>>> rst = GDALRaster("/vsitar/path/to/your/file.tar/path/to/raster.tif")
网络栅格

只要 GDAL 构建了这种能力,它可以透明地支持在线资源和存储提供商。

要访问一个无需身份验证的公共栅格文件,可以使用 /vsicurl/

>>> from django.contrib.gis.gdal import GDALRaster
>>> rst = GDALRaster("/vsicurl/https://example.com/raster.tif")
>>> rst.name
'/vsicurl/https://example.com/raster.tif'

对于商业存储提供商(例如 /vsis3/),系统应事先配置身份验证和可能的其他设置(请参阅 GDAL 虚拟文件系统文档 以查看可用选项)。

配置

GDAL_LIBRARY_PATH

一个字符串,用于指定 GDAL 库的位置。通常,只有在 GDAL 库位于非标准位置时才使用此设置(例如,/home/john/lib/libgdal.so)。

异常

exception GDALException

基本的 GDAL 异常,表示与 GDAL 相关的错误。

exception SRSException

当构造或使用空间参考系统对象时发生错误时引发的异常。

Back to Top