Fork me on GitHub

GDAL笔记-chapter6

这一章是利用OGR处理几何要素。

首先介绍一下OGR常量表示的不同几何类型。其中注意线wkbLineString\多边形环wkbLinearRing,特别注意多边形环用于多边形中。

点      wkbPoint
多点      wkbMultiPoint
线      wkbLineString
多线     wkbMultiLineString
多边形环  wkbLinearRing
面       wkbPolygon
多面     wkbMultiPolygon
几何集合  wkbGeometryCollection

1.点

from osgeo import ogr
firepit = ogr.Geometry(ogr.wkbPoint)   #create a null geometry
firepit.AddPoint(59.5, 11.5)   #add a point
firepit.SetPoint(59.5, 10)     #rewrite a point

2.多点

###创建多点集合类型
faucets = ogr.Geometry(ogr.wkbMultiPoint)
faucet = ogr.Geometry(ogr.wkbPoint)
faucet.AddPoint(67.5, 16)
faucets.AddGeometry(faucet)
faucet.AddPonit(12, 34)      #重用几何对象,单点会覆盖前点
faucets.AddGeometry(faucet)  #重用几何对象
faucet.AddPoint(0, 12)
faucets.AddGeometry(faucet)
####GetGeometryRef获取点的索引进行更新
faucets.GetGeometryRef(1).AddPoint(75, 32)  #获取多点几何对象的索引,并且更新坐标
for i in range(faucets.GetGeometryCount()):  #遍历所有点
    pt = faucets.GetGeometryRef(i)
    pt.AddPoint(pt.GetX()+2, pt.GetY())

3.线

####创建线
sidewalk = ogr.Geometry(ogr.wkbLineString)
sidewalk.AddPoint(54, 12)
sidewalk.AddPoint(56, 23)
sidewalk.AddPoint(12, 23)
sidewalk.SetPoint(2, 12, 12)   #改变索引为2的点的坐标
#GetGeometryCount确定几何形状集合中包含的几何图形数目
for i in range(sidewalk.GetPointCount()): 
    sidewalk.SetPoint(i, sidewalk.GetX(i), sidewalk.GetY(i)+2)    #GetPointCount方法返回单一几何类型的顶点个数

4.由后向前插入线的顶点可以不用更改索引号

#插入点时候,由后向前插入不用更改索引
vertices = line.GetPoints()
vertices[26:26] = [(12, 23)]
vertices[19:19] = [(11, 13),(14, 56), (12, 97)]
vertices[11:11] = [(28, 23)]
vertices[5:5] = [(12, 53)]
new_line = ogr.Geometry(ogr.wkbLineString)
for vertex in vertices:
    new_line.AddPoint(*vertex)

#不创建副本直接新增点
vertices = sidewalk.GetPoints()
vertices[2:2] = [(12, 45)]
for i in range(len(vertices)):
    sidewalk.SetPoint(i, *vertices[i])   #原来的线缺少一个新点,SetPoint方法在请求的索引处新增了一个点,初始化为(0,0),然后再更新

5.从线图层中创建点图层

检查新图层是否存在--获取线图层--获取线图层空间参考并且创建点图层--通过schema获取属性列表,创建点图层属性字段--获取图层定义并创建点图层要素--创建点图层几何体--遍历线图层要素,获取键值对元组--

遍历线要素的点--点要素添加几何体--点图层添加要素

#从线创建点
def line_to_point_layer(ds, line_name, pt_name):
    if ds.GetLayer(pt_name):
        ds.DeleteLayer(pt_name)
    line_lyr = ds.GetLayer(line_name)   #获取线图层
    sr = line_lyr.GetSpatialRef()  #获取线图层的空间参考
    pt_lyr = ds.CreateLayer(pt_name, sr, ogr.wkbPoint)  #创建点图层
    pt_lyr.CreateFields(line_lyr.schema)  #创建点图层的属性字段,lne_lyr.schema获取属性列表
    pt_feat = ogr.Feature(pt_lyr.GetLayerDefn())  #获取图层定义,创建点图层要素
    pt_geom = ogr.Geometry(ogr.wkbPoint)  #创建点图层几何体
    for line_feat in line_lyr:  #遍历线图层的每个要素
        atts = line_feat.items()  #获取线要素的键值对元组
        for fld_name in atts.keys(): #遍历属性值
            pt_feat.SetField(fld_name, atts[fld_name])  #复制属性值
        for coords in line_feat.geometry().GetPoints():  #遍历线要素的点
                pt_geom.AddPoint(*coords)
                pt_feat.SetGeometry(pt_geom)  #点图层添加几何体
                pt_lyr.CreateFeature(pt_feat)  #点图层添加要素

6.多线

#创建多线
path1 = ogr.Geometry(ogr.wkbLineString)
path1.AddPoint( 0, 0 )
path1.AddPoint( 0, 0 )
path1.AddPoint( 0, 0)

path2 = ogr.Geometry(ogr.wkbLineString)
path2.AddPoint( 0, 0)
path2.AddPoint( 0, 0)
path2.AddPoint( 0, 0)

paths = ogr.Geometry(ogr.wkbMultiLineString)
paths.AddGeometry(path1)
paths.AddGeometry(path2)

paths.GetGeometryRef(0).SetPoint(2, 63, 22)  #GetGeometry获取多线中的第1条线,SetPoint更新第三个点
paths.GetGeometryRef()  #获取多线中的线

#移动多线的每个点
for i in range(paths.GetGeometryCount()):  #首先遍历多线的单线
    path = paths.GetGeometryRef(i)
    for j in range(path.GetPointCount()):  #然后遍历单线的每个点
        path.SetPoint(j, path.GetX(j)+2, path.GetY(j)-3)

7.多边形(由环构成,最后需要CloseRings闭合)

#创建多边形
ring = ogr.Geometry(ogr.wkbLinearRing)  #先创建环
ring.AddPoint(56, 57)
ring.AddPoint(52, 51)
ring.AddPoint(52, 53)
ring.AddPoint(56, 53)
yard = ogr.Geometry(ogr.wkbPolygon)  #创建多边形几何体并且添加环
yard.AddGeometry(ring)
yard.CloseRings()  #闭合多边形

#多边形修改顶点
ring = yard.GetGeometryRef(0)
for i in range(ring.GetPointCount()):
    ring.SetPoint(i, ring.GetX(i)-5, ring.GetY(i))

ring = yard.GetGeometryRef(0) #到环
vertices = ring.GetPoints()
vertices[2:3] = ((90, 26),(90, 16))
for i in range(len(vertices)):
    ring.SetPoint(i, *vertices[i])

8.从多边形图层创建线图层的函数

 

#从多边形图层创建线图层的函数
def poly_to_line_layer(ds, poly_name, line_name):
    if ds.GetLayer(line_name):
        ds.DeleteLayer(line_name)
    poly_lyr = ds.GetLayer(poly_name)
    sr = poly_lyr.GetSpatialRef()
    line_lyr = ds.CreateLayer(line_name, sr, ogr.wkbLineString)  #线图层,不是环
    line_lyr.CreateFields(poly_lyr.schema)
    line_feat = ogr.Feature(line_lyr.GetLayerDefn())
    for poly_feat in poly_lyr:
        atts = poly_feat.items()
        for fld_name in atts.key():
            line_feat.SetField(fld_name, atts[fld_name])
        poly_geom = poly_feat.GetGeometry() 
        for i in range(poly_geom.GetGeometryCount()):
            ring = poly_geom.GetGeometryRef(i)
            line_geom = ogr.Geometry(ogr.wkbLineString)
            for coords in ring.GetPoints():
                line_geom.AddPoint(*coords)
            line_feat.SetGeometry(line_geom)
            line_lyr.CreateFeature(line_feat)

 

9.复合多边形

#复合多边形
box1 = ogr.Geometry(ogr.wkbLinearRing)   #
box1.AddPoint(0, 0)
box1.AddPoint(0, 0)
box1.AddPoint(0, 0)
garden1 = ogr.Geometry(ogr.wkbPolygon)
garden1.AddGeometry(box1)

box2 = ogr.Geometry(ogr.wkbLinearRing)
box2.AddPoint(0, 0)
box2.AddPoint(0, 0)
box2.AddPoint(0, 0)
garden2 = ogr.Geometry(ogr.wkbPolygon)
garden2.AddGeometry(box2)

gardens = ogr.Geometry(ogr.wkbMultiPolygon)  #创建复合多边形几何体并添加多边形
gardens.AddGeometry(garden1)
gardens.AddGeometry(garden2)
gardens.CloseRings()   #闭合多边形

#更新复合多边形顶点
for i in range(gardens.GetGeometryCount()):
    ring = gardens.GetGeometryRef(i).GetGeometryRef(0) #第一个GetGeometryRef从复合多边形中获取多边形,第二个GetGeometryRef获取多边形的环
    for j in range(ring.GetPoints()):
        ring.SetPoint(j, ring.GetX(j)+1, ring.GetY(j)+2)

10.带洞的多边形

#创建带洞的多边形
lot = ogr.Geometry(ogr.wkbLinearRing)  #
lot.AddPoint(0, 0)
lot.AddPoint(0, 0)
lot.AddPoint(0, 0)

house = ogr.Geometry(ogr.wkbLinearRing)
house.AddPoint(0, 0)
house.AddPoint(0, 0)
house.AddPoint(0, 0)

yard = ogr.Geometry(ogr.wkbPolygon)
yard.AddGeometry(lot)
yard.AddGeometry(house)
yard.CloseRings()

#更新带洞多边形的点
for i in range(yard.GetGeometryCount()):  #先遍历环
    ring = yard.GetGeometryRef(i)
    for j in range(ring.GetPointCount):  #取点
        ring.SetPoint(j, ring.GetX(j)-5, ring.GetY(j))

 

posted @ 2020-03-24 22:27  Rser_ljw  阅读(1040)  评论(0编辑  收藏  举报