>>> from env_helper import info; info()
页面更新时间: 2024-03-04 14:26:57
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

5.2. 格式的驱动,CRS,界限和图式

5.2.1. 数据的驱动

除了类似 file.namefile.modefile.closed 属性外, fiona.collection.Collection 有一个只读的 fiona.collection.Collection.driver 属性, 用于查看打开矢量数据的驱动格式。

>>> import fiona
>>> c = fiona.open('/gdata/prov_capital.shp')
>>> c.driver
'ESRI Shapefile'

5.2.2. 数据的投影参数及转换方法

矢量数据集的 Coordinate Reference System (CRS) 可通过只读的 fiona.collection.Collection.crs 属性来访问。 由于数据集的参数原因,可能会出现不同的结果。

>>> c.crs
CRS.from_epsg(4326)

{‘no_defs’: True, ‘ellps’: ‘WGS84’, ‘datum’: ‘WGS84’, ‘proj’: ‘longlat’}

>>> c.crs
CRS.from_epsg(4326)

CRS返回的结果,是对 PROJ.4 参数的映射。

fiona.crs 模块共有3个函数,以协助完成这些映射。 fiona.crs.to_string 函数是将映射转换到PROJ.4字符串中:

>>> from fiona.crs import to_string
>>> print(to_string(c.crs))
EPSG:4326

fiona.crs.from_string 为不可逆。

>>> from fiona.crs import from_string
>>> from_string("+datum=WGS84 +ellps=WGS84 +no_defs +proj=longlat")
CRS.from_epsg(4326)

fiona.crs.from_epsg 是EPSG代码CRS映射的一个快速方式。

>>> from fiona.crs import from_epsg
>>> from_epsg(3857)
CRS.from_epsg(3857)

5.2.3. 数据集中要素的数目、范围

可通过Python的 len 函数获取所有的收集记录。

>>> len(c)
34

收集记录的 minimum bounding rectangle (MBR) 或 bounds 可通过只读的 fiona.collection.Collection.bounds 属性来获取。

>>> c.bounds
(87.57610577000008, 19.97013978600006, 126.56611955000005, 45.69344403700006)

5.2.4. 数据图表(Schema)

最后,记录类型的 Schema (矢量文件是单一类型记录)可通过只读的 fiona.collection.Collection.schema 属性访问。 它有“几何”和“属性”参数 。 前者是一个字符串,后者是一个有序的库,具有相同命令的参数。

>>> from pprint import pprint
>>> import fiona
>>> c = fiona.open('/gdata/prov_capital.shp')
>>> pprint(c.schema)
{'geometry': 'Point',
 'properties': OrderedDict([('name', 'str:100'),
                            ('lat', 'float:13.11'),
                            ('lon', 'float:13.11')])}

保持架构简单

Fiona可减少更多的记录类型和模式。记录由数据组成。模型记录的是 id 关键词,模型映射与映射集的关键词一致。

>>> rec = next(c)
/tmp/ipykernel_198140/975926702.py:1: FionaDeprecationWarning: Collection.__next__() is buggy and will be removed in Fiona 2.0. Switch to next(iter(collection)).
  rec = next(c)
>>> rec = next(iter(c))
>>> set(rec.keys()) - set(c.schema.keys())
{'id'}
>>> set(rec['properties'].keys()) == set(c.schema['properties'].keys())
True

模式映射值也可以是字段类型,如 'Polygon''float''str' 。 相应的Python类型可以在 fiona.FIELD_TYPES_MAP 库中查到。

>>> pprint(fiona.FIELD_TYPES_MAP)
{'List[str]': typing.List[str],
 'bytes': <class 'bytes'>,
 'date': <class 'fiona.rfc3339.FionaDateType'>,
 'datetime': <class 'fiona.rfc3339.FionaDateTimeType'>,
 'float': <class 'float'>,
 'int': <class 'int'>,
 'int32': <class 'int'>,
 'int64': <class 'int'>,
 'str': <class 'str'>,
 'time': <class 'fiona.rfc3339.FionaTimeType'>}

字段类型

简而言之,他们的命名、类型与Python(或JavaScript)相近。‘str’与 ’unicode’混合功能只在Python3.0版本以下才会有。 Fiona记录的是Unicode字符串,其字段类型均命令为 ’str’。

>>> rec['properties']
<fiona.model.Properties at 0x7f29736ad9d0>
>>> type(rec['properties']['name'])
str
>>> c.schema['properties']['name']
'str:100'

字符串字段可限制最大宽度。 str:25 设置的就是不可以超过 25 个字符。 如果这个值用于打开文件,该值的属性就是将在 25 字符处截断。 默认宽度为80个字符,这意味着 strstr:80 属同一意思。

Fiona还有一个函数:可获取字符串属性宽度。

>>> from fiona import prop_width
>>> prop_width('str:25')
25
>>> prop_width('str')
80

另一个函数是可获取Python属性类型。

>>> from fiona import prop_type
>>> prop_type('int')
int
>>> prop_type('float')
float
>>> prop_type('str:25')
str

以上的例子针对于Python 3。Python 2'str'的性能是 'unicode'

几何类型

Fiona 支持 GeoJSON 和三维变异的几何类型,几何元素的架构值如下:

  • 线

  • 多边形

  • 点集合

  • 线集合

  • 面集合

  • 混合数据类型

  • 三维点

  • 三维线

  • 三维面

  • 三维点集合

  • 三维线集合

  • 三维面集合

  • 三维混合数据类型

后七个3D类型,只适用于集合模式。几何特征类型基本对应的是七个中的第一个。 例如, ’三维点 ’集 ,总是与几何式的点特性对应。这些几何坐标就是 (x, y, z) 元组。

注意,一个最常见的矢量数据格式,ESRI Shapefile,是没有’线集合’或’面集合’的图式结构。 因此,一个shapefile ‘面’ 可以是’面’,也可以是’面集合’。

5.2.5. 记录

Python的 dict 结构化与GeoJSON特征相似。Fiona可以自描述,其字段的命名包含在数据结构和字段中。数值字段的值类型就是 intfloat,不是字符串格式。

>>> import fiona
>>> from pprint import pprint
>>> c = fiona.open('/gdata/prov_capital.shp')
>>> rec = next(iter(c))
>>> rec
<fiona.model.Feature at 0x7f29736c0350>

此条数据记录与本源或其他外部资源的 fiona.collection 无关。它是完全独立的,使用任何方式都很安全。关闭集并不影响数据记录。

>>> c.close()
>>> rec['id']
'0'

记录ID

每一条记录都有 id号。根据GeoJSON规范,在数据文件中每一字符串都有相应且唯一的 id 值。

>>> c = fiona.open('/gdata/prov_capital.shp')
>>> rec = next(iter(c))
>>> rec['id']
'0'

OGR 模型中,ID号是长整数。因此在记录整数索引时,通常以字符串为表示形式。

记录属性

每条记录都有其 属性 ,其对应值就是一个映射,任一有序的库其映射值都特别精确。 映射属性与同源属性集的模式相同(见上文)。

>>> rec['properties']
<fiona.model.Properties at 0x7f29736c0490>

几何记录

每条记录都有几何属性,其对应值是类型与坐标映射。

>>> rec['geometry']
<fiona.model.Geometry at 0x7f29736c0950>

类型

坐标

单一(x,y)元组

线

(x,y)元组顶点列表

多边形

环列表[每个(x,y)元组列表]

点集合

点列表[每个(x,y)元组列表]

线集合

线列表[每个(x,y)元组列表]

面集合

多边形列表

Fiona,类似于GeoJSON格式,既有北半球的“北方”,又有笛卡尔的“X-Y”偏角。 上文说的元组值 (x, y),要么是(本初子午线的经度E、纬度N),要么是其他投影坐标系统(东,北)。

真正顺序是经-纬,而不是纬-经,尽管我们大多都在说 “纬度,经度” ,Fiona x,y 基本都是东向和北向,也就是 (经, 纬)。 先说经度,后说纬度,与GeoJSON规范保持一致。

点集理论和简易特性

在一个适当且干净的矢量数据文件中,几何映射是指几何对象由 point sets 组成,如下所示。

>>> from shapely.geometry import shape
>>> l1 = shape({'type': 'LineString', 'coordinates': [(0, 0), (2, 2)]})
>>> l2 = shape({'type': 'LineString', 'coordinates': [(0, 0), (1, 1), (2, 2)]})
>>> l1 == l2
False
>>> l1.equals(l2)
True

注解:Dirty数据,某些文件可能会包含矢量数据 invalid (在生成结果的质量控制不足时)或intention(“dirty”矢量保存到一个特殊的文件)。

Fiona不会清除dirty数据,所以你应该确保你所得到的是否为纯数据。