读取矢量数据
读取矢量数据的方式就是上一章所讲的两种方法。
操作图层
现在要明白矢量数据的文件组织结构。
shp
—>layer
—>feature
—>geometry
—>wkt
一个shp
文件中是只包含一个layer
的;
layer
就是同一个要素的集合,比如点集合、线集合、面集合,一个城市所有的学校为点集合;
feature
指代单个的点线面之类的geometry
,比如学校点集合中的某一个学校就是一个要素,在属性表中表示为一行数据;
geometry
的组织方式就是wkt
。
__author__ = 'He XK'
from osgeo import ogr
if __name__ == '__main__':
shp_filename = 'shp/province_1.shp'
driver = ogr.GetDriverByName('ESRI Shapefile')
shp = driver.Open(shp_filename)
print(shp.GetLayerCount()) # 1
# 获取图层
layer = shp.GetLayer(0)
# 获取图层要素
print(layer.GetFeatureCount()) # 37
print(layer.GetGeomType()) # 3
print(layer.GetExtent()) # (-3349547.371448596, 1834629.4342002147, 699750.9271820501, 5953688.75950143)
操作图层首先需要获取layer
,通过layer = shp.GetLayer(0)
,顺序从0开始,默认是0,所有的shp
也只能有一个layer
。
可以查看图层的要素数量、图层范围等信息。
获取图层属性
layer_info = layer.GetLayerDefn()
for i in range(layer_info.GetFieldCount()):
defn = layer_info.GetFieldDefn(i)
print(defn.GetName(),defn.GetWidth(),defn.GetType(),defn.GetPrecision()) # NAME 32 4 0
显示图层属性表中的字段,貌似只显示除了必带字段之外的内容。
GetLayerDefn(Layer self)
函数,获取这个layer
的信息表格,获取的layer_info
定义于FeatureDefn
类;所以,查看layer
表的信息,就需要去获取FeatureDefn
的内容。
GetType
函数返回enum [OGRwkbGeometryType]
,这样的一个常数列表集合,其中包含了所有了wkb
文件格式,包括wkbPoint
、wkbLineString
、wkbPolygon
等。本例中加载的shp
是全国行政区划图,序列给4,就是指向wkbPolygon
。
注意:这个图层属性,并不是要素的属性,只是大概的讲述整个表的组织方式,读取要素属性通过Feature
。
图层属性一般没有什么重要信息。
获取要素Feature信息
这个是获取shp
中属性表的重要方式。
# 获取单个要素
feature = layer.GetFeature(0)
print(feature.GetFID(), feature.GetField(0))
# 读取多个要素
i = 0
layer.ResetReading()
while i < layer.GetFeatureCount():
features = layer.GetNextFeature()
i += 1
print(features.GetFID(), features.GetField(0),features.GetFieldCount())
feature = layer.GetFeature(0)
可以获取指定顺序的单个要素,必须指定要素的顺序;
feature.GetFID()
可以获取要素的默认ID;
feature.GetField(0)
整个属性表中的其他Field
字段通过这个方法获得,参数指定Field
的顺序;该方法也可以直接输入Field
的名称,比如:
print(feature.GetField('name')) # 北京市
单个或指定要素的获取通过GetFeature
,貌似没有一个方法可以获取指定值的要素,好像有SQL的函数;
以下方法循环读取Feature
:
layer.GetFeatureCount()
获取当前图层的要素总数;
features = layer.GetNextFeature()
读取下一条要素并指定对象,第一次使用会从头开始,这时要素的值全部存储在对象中;
layer.ResetReading()
重置当前图层的要素读取的顺序,既要素重新从第一条开始。
feature.GetFieldCount()
可以获取该要素的所有字段数目;
所以可以实现读取shp
属性表的全部内容。
有许多关于Feature
的方法,其中带Field
字段的为属性操作,带Geometry
字段的为几何操作。
print(feature.keys()) # ['NAME']
print(feature.items()) # {'NAME': '北京市'}
字典的键值对对于Feature
可以使用,说明Feature
是一个字典形式的对象。
所以也可以用keys
和items
的方法获取要素属性。
获取要素的几何形状
# 获取几何形状
geom = feature.GetGeometryRef()
print(geom.GetGeometryCount()) # 1
print(geom.GetGeometryName()) # POLYGON
print(geom.GetPointCount()) # 0
print(geom.GetGeometryType()) # 3
print(geom.ExportToWkt()[:40]) # POLYGON ((532409.515326496 4453207.10754
geom = feature.GetGeometryRef()
可以获取当前要素的几何形状;
geom.GetGeometryCount()
可以获取当前几何的数量;
geom.GetGeometryName()
可以获取当前几何的类型名称;
geom.GetPointCount()
可以获取当前几何的点个数,为什么一整个多边形会是0个点 ??
geom.ExportToWkt()
可以获取当前几何的WKT格式,但是是一个字符串集合。
如果文件是点或者线,还可以直接获取要素的XY坐标。
# 点
print(geom.GetGeometryCount()) # 0
print(geom.GetGeometryName()) # POINT
print(geom.GetPointCount()) # 1
print(geom.GetGeometryType()) # 1
print(geom.ExportToWkt()) # POINT (496203.822960446 3301564.31432952)
print(geom.GetX(0), geom.GetY(0), geom.GetZ(0)) # 496203.8229604459 3301564.3143295236 0.0
print(geom.GetX(0), geom.GetY(0), geom.GetZ(0))
矢量文件的投影参数信息
print(layer.GetSpatialRef()) # 投影参数信息
print(layer.GetExtent()) # 边界矩形信息
print(geom.GetEnvelope()) # 某一个要素的几何,获取几何的边界信息。
print(geom.GetSpatialReference()) # 这个和图层的GetSpatialRef一致
关闭数据与释放内存
对于栅格文件,貌似没有这个步骤,但是对于矢量文件却有。
当前我们声明了一个shp
,一个layer
,一个feature
,一个geom
,许多个features
,需要在使用完毕后进行关闭,释放资源。
geom.Destroy()
feature.Destroy()
layer.Destroy()
shp.Destroy()
具有Destroy
的类对象:
osgeo.ogr.DataSource
osgeo.ogr.Feature
osgeo.ogr.FeatureDefn
osgeo.ogr.FieldDefn
osgeo.ogr.Geometry
基本上ogr
的所有类型都具备Destroy
。