Python|shp文件逐图斑自动生成地块界址点信息表——OGR库实现

工作中,有时需要从面shp文件中导出拐点坐标,并生成土地报批标准格式TXT文件或界址点信息表。ArcGIS中可以通过工具提取出拐点坐标,但是无法自动生成我们需要的成果格式,需要手动录入。今天分享基于Python中OGR与DOCX两个库制作的一个简易转换工具,输入shp矢量文件后可批量自动生成shp中每个图斑(地块)命名的界址点信息表。

工具界面如下图所示,两个输入参数分别为:1.输入shp文件,2.界址点信息表存放文件夹。

下面的视频演示了该工具的使用方法:

20230423171118

下面,分别重点介绍一下ArcGIS中提取面要素拐点坐标与转换工具的主要实现方法两方面内容。

一、ArcGIS中面要素拐点坐标提取

ArcGIS|shp文件提取图斑拐点坐标信息https://mp.csdn.net/mp_blog/creation/editor/130336177

二、自动转换工具实现

下面介绍一下通过Python编程方式实现提取拐点坐标,并自动逐图斑生成界址点坐标信息表。

1.创建图斑编号命名的word

使用docx库创建一个word文档,然后在文档里面首先插入标题,并设置字体、颜色、行间距以及对齐方式,然后合并前两行指定的单元格,输入表头信息,最后保存word模板。

代码如下:

#创建文档对象
doc = Document()
#设置全局样式
doc.styles['Normal'].font.size = Pt(14)  # 四号字号对应磅值14
doc.styles['Normal'].font.name = 'Times New Roman'
doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'黑体')

# 添加一个标题
head0 = doc.add_heading(level=1)
head0.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
head0.style.font.size = Pt(22)
head0.style.font.color.rgb = RGBColor(0, 0, 0)
head0.paragraph_format.line_spacing = 1
title_run = head0.add_run(u'地块界址点坐标信息表')
title_run.font.name = 'Times New Roman'
title_run.font.bold = False
# 设置中文字体
title_run.element.rPr.rFonts.set(qn('w:eastAsia'), u'黑体')
table = doc.add_table(rows=25, cols=4, style='Table Grid')
table.alignment = WD_TABLE_ALIGNMENT.CENTER  # 设置表格为居中对齐(在文档中位置)

# 行单元格合并
table.cell(0, 0).merge(table.cell(1, 0))
table.cell(0, 0).text = u"点号"
table.cell(0, 1).merge(table.cell(0, 2))
table.cell(0, 1).text = u"点坐标"
table.cell(0, 3).merge(table.cell(1, 3))
table.cell(0, 3).text = u"备注"
table.cell(1, 1).text = u"X/米"
table.cell(1, 2).text = u"Y/米"
table.style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

生成的界址点信息表word模板如下:

2.读取图斑拐点坐标并写入表格

使用OGR库读取shp文件,获取面图层,然后依次遍历获取各个图斑的几何对象,然后依次取得组成每个面几何的环里面所有拐点坐标,写入word模板中的表格即可,同时提取JCBH字段属性值后四位作为地块编号,填充标题。

3.完整代码

# -*- coding: utf-8 -*-
# @Time    : 2023/4/23 11:57
# @Author  : 药菌

from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from osgeo import ogr, gdal
from docx import Document
from docx.shared import Inches, Cm, Pt, RGBColor
from docx.oxml.ns import qn
import os, sys

#注册所有的驱动
ogr.RegisterAll()
#为了支持中文路径
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
#为了使属性表字段支持中文
gdal.SetConfigOption("SHAPE_ENCODING", "GBK")

def createWord(filename):
    doc = Document()
    doc.styles['Normal'].font.size = Pt(14)  # 四号字号对应磅值14

    # 添加一个标题
    head0 = doc.add_heading(level=1)
    head0.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    head0.style.font.size = Pt(22)
    head0.style.font.color.rgb = RGBColor(0,0,0)
    head0.paragraph_format.line_spacing = 1

    title_run = head0.add_run(u'_____地块界址点坐标信息表')
    title_run.font.name = 'Times New Roman'
    title_run.font.bold = False
    # 设置中文字体
    title_run.element.rPr.rFonts.set(qn('w:eastAsia'), u'黑体')

    table = doc.add_table(rows=25, cols=4, style='Table Grid')
    table.alignment = WD_TABLE_ALIGNMENT.CENTER  # 设置表格为居中对齐(在文档中位置)

    # 行单元格合并
    table.cell(0, 0).merge(table.cell(1, 0))
    table.cell(0, 0).text = u"点号"
    #table.cell(0, 0).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    table.cell(0, 1).merge(table.cell(0, 2))
    table.cell(0, 1).text = u"点坐标"

    table.cell(0, 3).merge(table.cell(1, 3))
    table.cell(0, 3).text = u"备注"

    table.cell(1, 1).text = u"X坐标"
    table.cell(1, 2).text = u"Y坐标"
    table.style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    #保存文档
    doc.save(filename)


#shp导出界址点文件
def GetPointInfosDOCX(shpname, fieldname):
    #得到上级目录
    dirname = os.path.dirname(filename)
    os.chdir(dirname)
    #读取shp文件
    dataSource = ogr.Open(shpname, 0)
    if dataSource is None:
        sys.exit('could not open shp file')
    layer = dataSource.GetLayer(0)

    # 获取要素坐标几何信息
    for feature in layer:
        # 获取编号字段属性
        jcbh = feature.GetField(fieldname)
        if jcbh == "":
            sys.exit('could get fieldname')

        #创建文档对象
        doc = Document()
        #设置全局样式
        doc.styles['Normal'].font.size = Pt(14)  # 四号字号对应磅值14
        doc.styles['Normal'].font.name = 'Times New Roman'
        doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'黑体')

        # 添加一个标题
        head0 = doc.add_heading(level=1)
        head0.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        head0.style.font.size = Pt(22)
        head0.style.font.color.rgb = RGBColor(0, 0, 0)
        head0.paragraph_format.line_spacing = 1
        title_run = head0.add_run(u'地块界址点坐标信息表')
        title_run.font.name = 'Times New Roman'
        title_run.font.bold = False
        # 设置中文字体
        title_run.element.rPr.rFonts.set(qn('w:eastAsia'), u'黑体')
        table = doc.add_table(rows=25, cols=4, style='Table Grid')
        table.alignment = WD_TABLE_ALIGNMENT.CENTER  # 设置表格为居中对齐(在文档中位置)

        # 行单元格合并
        table.cell(0, 0).merge(table.cell(1, 0))
        table.cell(0, 0).text = u"点号"
        table.cell(0, 1).merge(table.cell(0, 2))
        table.cell(0, 1).text = u"点坐标"
        table.cell(0, 3).merge(table.cell(1, 3))
        table.cell(0, 3).text = u"备注"
        table.cell(1, 1).text = u"X/米"
        table.cell(1, 2).text = u"Y/米"
        table.style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

        # 完善表头
        title = doc.paragraphs[0]
        title.runs[0].text = str(jcbh)[-4:] + title.runs[0].text

        #表格开始编辑的行数
        m = 2

        # 获取几何对象
        geom = feature.geometry()
        print(geom.GetGeometryName())

        #if geom.GetGeometryName() == "LINESTRING":
            #linering = geom

        # 获取几何对象子几何对象个数
        geomeCounts = geom.GetGeometryCount()
        for i in range(geomeCounts):
            # 获取面要素第一个几何对象:线
            linering = geom.GetGeometryRef(i)
            print(u"第{}个环的拐点坐标如下:".format(i + 1))
            #获取拐点坐标
            print(u"拐点总数:{}".format(linering.GetPointCount()))
            for j in range(0, linering.GetPointCount()):
                x = linering.GetX(j)
                y = linering.GetY(j)
                print("表格总共{}行,第{}行坐标导入。。。。".format(len(table.rows),m))
                if m < len(table.rows):
                    #将坐标写入表格中
                    table.cell(m, 0).text = "J" + str(j + 1)
                    table.cell(m, 1).text = str(round(x, 4))
                    table.cell(m, 2).text = str(round(y, 4))
                    table.cell(m, 3).text = str(i+1)
                else:
                    #行不够时添加行
                    row_cells = table.add_row().cells
                    row_cells[0].text = "J" + str(j)
                    row_cells[1].text = str(round(x, 4))
                    row_cells[2].text = str(round(y, 4))
                    row_cells[3].text = str(i + 1)
                m += 1

                # print("第{}个点坐标: X:{} Y:{}".format(i+1, x, y))
                pass
        #print("================================================")

        #保存当前图斑的界址点表格
        doc_name = str(jcbh)[-4:] + u"界址点坐标信息表.docx"
        doc.save(doc_name)

    dataSource.Destroy()
    pass

if __name__ == '__main__':
    #filename = u'E:\\0编程学习\\python\\GDAL\\data\\610881神木市\\610881神木市-demo.shp'
    filename = u'E:\\0编程学习\\python\\GDAL\\data\\610881神木市\\demo1.shp'
    #GetPointInfosDOCX(filename, 'JCBH')
    createWord(u'E:\\0编程学习\\python\\GDAL\\data\\610881神木市\\demo.docx')
    pass

4.结果

生成的界址点坐标信息表如下,备注栏里面的数字为环编号。

上面是提取拐点坐标并生成界址点信息表的主要思路及代码。转换工具界面完整代码下方*扫码获取。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遥感与地理信息

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值