工作中,有时需要从面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.结果
生成的界址点坐标信息表如下,备注栏里面的数字为环编号。
上面是提取拐点坐标并生成界址点信息表的主要思路及代码。转换工具界面完整代码下方*扫码获取。