Python Shapefile Library(PyShp)为Esri Shapefile文件格式提供读写支持。Shapefile格式是由Esri创建的一种流行的地理信息系统矢量数据格式。Shapefile文件用于描述几何体对象:点,折线与多边形。
Shapefile文件指的是一种文件存储的方法,实际上该种文件格式是由多个文件组成的。其中,要组成一个Shapefile,有三个文件是必不可少的,它们分别是".shp", ".shx"与 ".dbf"文件。表示同一数据的一组文件其文件名前缀应该相同。例如,存储一个关于湖的几何与属性数据,就必须有lake.shp,lake.shx与lake.dbf三个文件。而其中“真正”的Shapefile的后缀为shp,然而仅有这个文件数据是不完整的,必须要把其他两个附带上才能构成一组完整的地理数据。除了这三个必须的文件以外,还有八个可选的文件,使用它们可以增强空间数据的表达能力。所有的文件名都必须遵循MS DOS的8.3文件名标准(文件前缀名8个字符,后缀名3个字符,如shapefil.shp),以方便与一些老的应用程序保持兼容性,尽管现在许多新的程序都能够支持长文件名。此外,所有的文件都必须位于同一个目录之中。
pyshp github地址:https://github.com/GeospatialPython/pyshp
pyshp官方文档主页:https://pypi.org/project/pyshp/
from ctypes import pointer
import shapefile
# Shape types are represented by numbers between 0 and 31 as defined
# by the shapefile specification and listed below.
# It is important to note that the numbering system has several reserved numbers
# that have not been used yet,
# therefore the numbers of the existing shape types are not sequential:
# NULL = 0
# POINT = 1
# POLYLINE = 3
# POLYGON = 5
# MULTIPOINT = 8
# POINTZ = 11
# POLYLINEZ = 13
# POLYGONZ = 15
# MULTIPOINTZ = 18
# POINTM = 21
# POLYLINEM = 23
# POLYGONM = 25
# MULTIPOINTM = 28
# MULTIPATCH = 31
# The field names of a shapefile are available as soon as you read a shapefile.
# You can call the "fields" attribute of the shapefile as a Python list.
# Each field is a Python list with the following information:
# Field name: the name describing the data at this column index.
# Field type: the type of data at this column index. Types can be:
# "C": Characters, text.
# "N": Numbers, with or without decimals.
# "F": Floats (same as "N").
# "L": Logical, for boolean True/False values.
# "D": Dates.
# "M": Memo, has no meaning within a GIS and is part of the xbase spec instead.
# Field length: the length of the data found at this column index.
# Older GIS software may truncate this length to 8 or 11 characters for "Character" fields.
# Decimal length: the number of decimal places found in "Number" fields.
def write_points_shp(file_dir, points):
point_w = shapefile.Writer(file_dir, shapefile.POINT)
point_w.autoBalance = True
# point: 0: x
# 1: y
# 2: z
# 3: id
# 4: name
# 5: class
point_w.field('IMAGE_ID', 'N')
point_w.field('IMAGE_NAME', 'C')
point_w.field('CLASS', 'N') # point belong to which class
for ptid, point in points.items():
point_w.point(point[0], point[1])
point_w.record(IMAGE_ID=ptid, IMAGE_NAME=point[4], CLASS=point[5])
point_w.close()
def write_lines_shp(file_dir, lines):
line_w = shapefile.Writer(file_dir, shapeType=shapefile.POLYLINE)
line_w.autoBalance = True
# line: 0: point1 []
# 1: point2 []
# 2: point1_id
# 3: point2_id
# 4: id
# 5: class, 0 stands for inter_line
line_w.field('LINE_ID', 'N')
line_w.field('CLASS', 'N')
for liid, line in lines.items():
line_w.line([line[0], line[1]])
line_w.record(LINE_ID=line[4], CLASS=line[5])
line_w.close()