《Python地理空间分析指南 第2版》学习笔记-5.5Shapefile文件编辑-下
往期内容请看
《Python地理空间分析指南 第2版》学习笔记-5.5Shapefile文件编辑-上
《Python地理空间分析指南 第2版》学习笔记-5.5Shapefile文件编辑-中
5.5.5Shapefile文件合并
使用一组某城市分布于4个不同方位(西北、东北、西南和东南)的建筑物轮廓分布
图,合并成一幅。
方法一:shapefile文件合并
import glob
import shapefile
# 读取相同字符footprints_*shp的矢量文件
filename = glob.glob(r"footprints\footprints_*shp")
#创建要写入的对象
with shapefile.Writer(r"footprints\merge") as w:
r = None
for f in filename:
r = shapefile.Reader(f)
#写入字段
if not w.fields:
w.fields = list(r.fields)
#写入记录
for rec in r.records():
w.record(*list(rec))
#写入形状
for s in r.shapes():
w._shapeparts(parts =[s.points],shapeType=s.shapeType )
结果展示:
方法二:使用dfbpy合并Shapefile文件
OGR库和pyshp库都能读写dbf文件,因为dbf文件都是shapefile文件规范的一部分。dbf文件包含shapefile文件的属性和字段信息,但是OGR库和pyshp库只提供了对dbf文件的基本操作。若需要对dbf文件进行更复杂的操作,需要自己手动安装dbfpy3库。
dbfpy3-4.1.5-py2.py3-none-any.whl
import glob
import shapefile
from dbfpy3 import dbf
shp_files = glob.glob("footprints_*.shp")
w = shapefile.Writer(shp="merged.shp", shx="merged.shx")
# 新建merged.shp,将各个部分文件,循环写入merged.shp中
for f in shp_files:
print("Shp: {}".format(f))
r = shapefile.Reader(f)
# r = shapefile.Reader(shp=shpf)
for s in r.shapes():
w.poly([s.points])
w.close()
# 思路:
# Now we come back with dbfpy and merge the dbf files
dbf_files = glob.glob("*.dbf")
# Use the first dbf file as a template
template = dbf_files.pop(0)
merged_dbf_name = "merged.dbf"
# Copy the entire template dbf file to the merged file
merged_dbf = open(merged_dbf_name, "wb")
temp = open(template, "rb")
merged_dbf.write(temp.read())
merged_dbf.close()
temp.close()
# Now read each record from teh remaining dbf files
# and use the contents to create a new record in
# the merged dbf file.
db = dbf.Dbf(merged_dbf)
for f in dbf_files:
print("Dbf: {}".format(f))
dba = dbf.Dbf(f)
for rec in dba:
db_rec = db.newRecord()
for k, v in list(rec.asDict().items()):
db_rec[k] = v
db_rec.store()
db.close()
5.5.6Shapefile文件分割
有时,你也许需要从一个比较大的Shapefile文件中分割出一个特定的子文件,以便将重点放在感兴趣的部分。这些分割和子集化操作可以是空间方面的,也可以是感兴趣的特定属性方面
的。
下面的案例,根据区域对建筑物分布图进行过滤并将导出大约100平方米的建筑物分布图到一个新的Shapefile文件
中。
import shapefile
import utm
# 读取矢量面文件
r = shapefile.Reader(r"footprints\footprints_se")
# 创建新的矢量面对象 w
with shapefile.Writer(r"footprints\footprints_sp100", r.shapeType) as w:
# 将字段复制给w
w.fields = list(r.fields)
# 遍历r记录
for sr in r.shapeRecords():
utmPoints = []
for p in sr.shape.points:
x, y, band, zone = utm.from_latlon(p[1], p[0])
utmPoints.append([x, y])
# print(utmPoints)
# 计算每个矢量面的坐标
area = abs(shapefile.signed_area(utmPoints))
# print(area)
if area <= 100:
w.poly([sr.shape.points])
w.record(*list(sr.record))
# 结果验证
r = shapefile.Reader(r"footprints\footprints_se")
subset = shapefile.Reader(r"footprints\footprints_sp100")
print("总数:",r.numRecords)
print("子集:",subset.numRecords)
结果
总数: 26447
子集: 13331
footprints_se文件
footprints_sp100文件:建筑面积小于100平方米
结束语
《Python地理空间分析指南 第2版》学习笔记,仅供学习,如有侵权请联系删除。