import os
from osgeo import ogr
driver=ogr.GetDriverByName('ESRI Shapefile')
for out_shp in ['/tmp/foo.shp', '/tmp/foo1.shp', '/tmp/foo2.shp', '/tmp/foo3.shp', '/tmp/foo4.shp']:
if os.path.exists(out_shp):
driver.DeleteDataSource(out_shp)
import fiona
with fiona.open('/data/gdata/prov_capital.shp') as c:
rec = next(iter(c))
rec['id'] = '-1'
rec['properties']['CNTRY_NAME'] = 'Gondor'
/tmp/ipykernel_55/2107533988.py:5: FionaDeprecationWarning: instances of this class -- CRS, geometry, and feature objects -- will become immutable in fiona version 2.0 rec['id'] = '-1' /tmp/ipykernel_55/2107533988.py:6: FionaDeprecationWarning: instances of this class -- CRS, geometry, and feature objects -- will become immutable in fiona version 2.0 rec['properties']['CNTRY_NAME'] = 'Gondor'
注意上面的用法,在 Fiona 2.0 后,不可以用这种方法修改对象。
from fiona import os
os.system("cp /data/gdata/prov_capital.* /tmp")
0
注意,在文件修改前要拷贝备份。
这样,坐标参考系统、 .format
与文件架构就定义完成,所以他不能以只读方式打开,也不能是 'a'
模式。
新的记录用 fiona.collection.Collection.write
的方式写在文件最尾处,因此,该文件的长度就从 48
增加到了 49
。
import os, stat
shp_file = '/tmp/prov_capital'
os.chmod(shp_file + '.shp', stat.S_IRUSR + stat.S_IWUSR)
os.chmod(shp_file + '.dbf', stat.S_IRUSR + stat.S_IWUSR)
os.chmod(shp_file + '.shx', stat.S_IRUSR + stat.S_IWUSR)
with fiona.open(shp_file + '.shp', 'a') as c:
print(len(c))
34
你写入的记录必须匹配文件模式(因为一个文件包含一个记录型)。如果不是的话,会出现 ValueError
的异常。
with fiona.open(shp_file + '.shp', 'a') as c:
c.write({'properties': {'foo': 'bar'}})
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
若忽略一个记录的ID值,可能就会被下一个生成的值替换掉。如果你只是读文件,仅参考上面的即可,
shp_file = '/tmp/prov_capital'
os.chmod(shp_file + '.shp', stat.S_IRUSR + stat.S_IWUSR)
os.chmod(shp_file + '.dbf', stat.S_IRUSR + stat.S_IWUSR)
os.chmod(shp_file + '.shx', stat.S_IRUSR + stat.S_IWUSR)
with fiona.open('/tmp/prov_capital.shp') as c:
records = list(c) # records = c.next()
records[-1]['id']
'33'
records[-1]['properties']['name']
'澳门'
你可能还会看到ID值为 '-1'
,这记录有时可能会被 '48'
替换掉。
fiona.collection.Collection.
是文件集的唯一记录。
fiona.collection.Collection.writerecords
的写入会成为序列值(或迭代器)。
with fiona.open('/data/gdata/prov_capital.shp') as c:
rec = next(iter(c))
with fiona.open('/tmp/prov_capital.shp', 'a') as c:
c.writerecords([rec, rec,rec])
print(len(c))
37
with fiona.open('/data/gdata/prov_capital.shp') as source:
source_driver = source.driver
source_crs = source.crs
source_schema = source.schema
print(source_driver)
ESRI Shapefile
source_crs
CRS.from_epsg(4326)
from pprint import pprint
pprint(source_schema)
{'geometry': 'Point', 'properties': {'lat': 'float:13.11', 'lon': 'float:13.11', 'name': 'str:100'}}
现在创建一个新文件。
c = fiona.open( '/tmp/foo.shp', 'w', driver=source_driver, crs=source_crs, schema=source_schema)
len(c)
0
c.closed
False
len(c)
0
由于对源架构的性能有要求,可以在写入的模式集中使用同一命令,书面文件的字段可与源文件使用同一命令。
ogrinfo '/tmp/foo.shp' foo -so
INFO: Open of `/tmp/foo.shp'
using driver `ESRI Shapefile' successful.
fiona.collection.Collection.meta
属性可以使复制文件元属性更加容易。
source = fiona.open('/data/gdata/prov_capital.shp')
sink = fiona.open('/tmp/foo2.shp', 'w', **source.meta)
{'bar': 'int', 'foo': 'str'}.keys()
dict_keys(['bar', 'foo'])
{'properties': {'bar': 'int', 'foo': 'str'}}
模式可生成 Shapefile ,第一个字段是 foo
,第二个字段是 bar
。
如果你想要把 bar
作为第一个字段,你必须用一个属性列表项。
另外,要注意在 schema
要声明 geometry
,其类型为 Polygon
,注意大小写。
c = fiona.open( '/tmp/foo3.shp', 'w',schema={'properties': [('bar', 'int'), ('foo', 'str')], 'geometry': 'Polygon'}, driver = 'ESRI Shapefile')
或者使用 OrderedDict
:
from collections import OrderedDict
schema_props = OrderedDict([('bar', 'int'), ('foo', 'str')])
c = fiona.open('/tmp/foo4.shp','w',schema={'properties': schema_props, 'geometry': 'Polygon'}, driver = 'ESRI Shapefile')