import fiona
c = fiona.open('/data/gdata/prov_capital.shp')
hits = list(c.items(bbox=(-5.0, 55.0, 0.0, 60.0)))
len(hits)
0
迭代器与切割参数itertools.islice
的 stop
或 start, stop[, step]
的功能相同。要想查找迭代器的前两个参数,暂停即可。
hits = c.items(2, bbox=(-5.0, 55.0, 0.0, 60.0))
len(list(hits))
0
要想得到迭代器第三到第五个参数,启动和停止即可。
hits = c.items(2, 5, bbox=(-5.0, 55.0, 0.0, 60.0))
len(list(hits))
0
要想过滤属性值,可使用Python的内置 :py:func:filter
和:py:keyword:lambda
函数 ,或者你也可以用单一属性的过滤功能,返回值为 True
or False
。
def pass_positive_area(rec):
return rec['properties'].get('AREA', 0.0)>0.0
c = fiona.open('/data/gdata/prov_capital.shp')
hits = filter(pass_positive_area, c)
len(list(hits))
0
import subprocess
import os
if not os.path.exists('/tmp/data'):
os.mkdir('/tmp/data')
cmd1 = 'ogr2ogr /tmp/data/ /data/gdata/GSHHS_c.shp GSHHS_c -nln foo'
cmd2 = 'ogr2ogr /tmp/data/ /data/gdata/GSHHS_c.shp GSHHS_c -nln bar'
subprocess.call(cmd1, shell=True)
subprocess.call(cmd2, shell=True)
Warning 1: Value 50654050.694499999 of field area of feature 1765 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 50654050.694499999 of field area of feature 1766 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 29220969.727000002 of field area of feature 1767 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 20154740.09 of field area of feature 1768 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 17534164.066799998 of field area of feature 1769 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 13919140.565400001 of field area of feature 3501 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 50654050.694499999 of field area of feature 1765 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 50654050.694499999 of field area of feature 1766 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 29220969.727000002 of field area of feature 1767 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 20154740.09 of field area of feature 1768 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 17534164.066799998 of field area of feature 1769 not successfully written. Possibly due to too larger number with respect to field width Warning 1: Value 13919140.565400001 of field area of feature 3501 not successfully written. Possibly due to too larger number with respect to field width
0
一个数据源层可以用函数fiona.listlayers
列一下,写法是 listlayers()
。在 Shapefile格式的情况下,层的名称需匹配文件库的名称。
import fiona
fiona.listlayers('/data/gdata')
['GSHHS_c', 'GSHHS_h', 'GSHHS_l_L1', 'county_popu', 'hyd2_4l', 'prov_capital', 'region_popu', 'region_popu2', 'shape_towns', 'spatial_filter', 'world_pt', 'world_spatial_filter']
不像OGR,Fiona没有层与数据源的分类。要想访问层,需用数据源路径打开一个集,并用 layer
来指定该层。
import pprint
datasrc_path = '/data/gdata'
for name in fiona.listlayers(datasrc_path):
with fiona.open(datasrc_path, layer=name) as c:
pprint.pprint(c.schema)
{'geometry': 'Polygon', 'properties': {'Shape_Area': 'float:19.11', 'Shape_Leng': 'float:19.11', 'area': 'float:19.11', 'id': 'str:80', 'level': 'int:10', 'parent_id': 'int:10', 'sibling_id': 'int:10', 'source': 'str:80'}} {'geometry': 'Polygon', 'properties': {'Shape_Area': 'float:19.11', 'Shape_Leng': 'float:19.11', 'area': 'float:19.11', 'id': 'str:80', 'level': 'int:10', 'parent_id': 'int:10', 'sibling_id': 'int:10', 'source': 'str:80'}} {'geometry': 'Polygon', 'properties': {'area': 'float:24.15', 'id': 'str:80', 'level': 'int:10', 'parent_id': 'int:10', 'sibling_id': 'int:10', 'source': 'str:80'}} {'geometry': 'Polygon', 'properties': {'AREA': 'float:13.11', 'NAME': 'str:60', 'PAC': 'int:10', 'POPU': 'float:13.11', 'Shape_Area': 'float:19.11', 'Shape_Leng': 'float:19.11'}} {'geometry': 'LineString', 'properties': {'FNODE_': 'int:11', 'GBCODE': 'int32:6', 'HYD2_4M_': 'int:11', 'HYD2_4M_ID': 'int:11', 'LENGTH': 'float:12.3', 'LEVEL_LAKE': 'int32:1', 'LEVEL_RIVE': 'int32:1', 'LPOLY_': 'int:11', 'NAME': 'str:60', 'RPOLY_': 'int:11', 'TNODE_': 'int:11'}} {'geometry': 'Point', 'properties': {'lat': 'float:13.11', 'lon': 'float:13.11', 'name': 'str:100'}} {'geometry': 'Polygon', 'properties': {'code2': 'int32:5', 'code4': 'int32:5', 'name': 'str:50', 'pname': 'str:50', 'popu': 'float:13.11'}} {'geometry': 'Polygon', 'properties': {'code2': 'int32:5', 'code4': 'int32:5', 'name': 'str:50', 'pname': 'str:50', 'popu': 'float:13.11'}} {'geometry': 'Point', 'properties': {'County': 'int32:1', 'LocalCounc': 'int32:1', 'Name': 'str:62', 'PK_UID': 'int32:4', 'Peoples': 'int32:7', 'Region': 'int32:1'}} {'geometry': 'Polygon', 'properties': {'FID': 'int:11'}} {'geometry': 'Point', 'properties': {'AREA': 'float:17.2', 'CAT': 'int:16', 'CNTRY_NAME': 'str:80', 'FIPS_CNTRY': 'str:80', 'ORIG_FID': 'int:10', 'POP_CNTRY': 'float:17.2'}} {'geometry': 'Polygon', 'properties': {'Shape_Area': 'float:19.11', 'Shape_Leng': 'float:19.11', 'area': 'float:19.11', 'id': 'str:80', 'level': 'int:10', 'parent_id': 'int:10', 'sibling_id': 'int:10', 'source': 'str:80'}}
原版本中图层还可以由索引来指定。现在似乎不行了。
# for i, name in enumerate(fiona.listlayers(datasrc_path)):
# print(i,name)
# with fiona.open(datasrc_path, layer=i) as c:
# print(len(c))
0 GSHHS_c
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[13], line 3 1 for i, name in enumerate(fiona.listlayers(datasrc_path)): 2 print(i,name) ----> 3 with fiona.open(datasrc_path, layer=i) as c: 4 print(len(c)) File /opt/conda/lib/python3.12/site-packages/fiona/env.py:457, in ensure_env_with_credentials.<locals>.wrapper(*args, **kwds) 454 session = DummySession() 456 with env_ctor(session=session): --> 457 return f(*args, **kwds) File /opt/conda/lib/python3.12/site-packages/fiona/__init__.py:342, in open(fp, mode, driver, schema, crs, encoding, layer, vfs, enabled_drivers, crs_wkt, ignore_fields, ignore_geometry, include_fields, wkt_version, allow_unsupported_drivers, opener, **kwargs) 339 path = _parse_path(fp) 341 if mode in ("a", "r"): --> 342 colxn = Collection( 343 path, 344 mode, 345 driver=driver, 346 encoding=encoding, 347 layer=layer, 348 ignore_fields=ignore_fields, 349 include_fields=include_fields, 350 ignore_geometry=ignore_geometry, 351 wkt_version=wkt_version, 352 enabled_drivers=enabled_drivers, 353 allow_unsupported_drivers=allow_unsupported_drivers, 354 **kwargs 355 ) 356 elif mode == "w": 357 colxn = Collection( 358 path, 359 mode, (...) 372 **kwargs 373 ) File /opt/conda/lib/python3.12/site-packages/fiona/collection.py:226, in Collection.__init__(self, path, mode, driver, schema, crs, encoding, layer, vsi, archive, enabled_drivers, crs_wkt, ignore_fields, ignore_geometry, include_fields, wkt_version, allow_unsupported_drivers, **kwargs) 224 if self.mode == "r": 225 self.session = Session() --> 226 self.session.start(self, **kwargs) 227 elif self.mode in ("a", "w"): 228 self.session = WritingSession() File fiona/ogrext.pyx:887, in fiona.ogrext.Session.start() ValueError: Null layer: <closed Collection '/data/gdata:gdata', mode 'r' at 0x7f39c04d55e0> gdata
若没有指定层, fiona.open
会返回第一层的开放集 。
with fiona.open(datasrc_path) as c:
c.name == fiona.listlayers(datasrc_path)[0]
要打开一个只读的shapefile,最简单的方法就是 fiona.open
函数,可以把其文件名作为一个命名图层的数据源。
如:
fiona.open('/tmp/foo.shp', 'r', layer='foo')
在实践中,依靠隐含的第一层和默认 'r'
模式是很实用的。
'wah' not in fiona.listlayers(datasrc_path)
True
datasrc_path = '/tmp/data'
with fiona.open(datasrc_path, layer='bar') as c:
with fiona.open(datasrc_path, 'w', layer='wah', **c.meta) as d:
d.write(next(iter(c)))
fiona.listlayers(datasrc_path)
['foo', 'bar', 'wah']
在 'w'
模式中,如果指定的话,会覆盖原有的层,就像是Python的open
功能似的。
'wah' in fiona.listlayers(datasrc_path)
True
with fiona.open(datasrc_path, layer='bar') as c:
with fiona.open(datasrc_path, 'w', layer='wah', **c.meta) as d:
pass