目录[-]
在使用CAD管线信息搭建MIKE模型时,需要利用CAD插件yaotool对CAD数据进行提取,提取后往往需要进行处理才可使用,为提高建模效率,故使用python设计代码。
代码在经过多个功能设计完毕后,进行优化重构,并编写用户界面,效果如下:
功能主要围绕三个核心功能:
1:排水管线端点断连检查
通过计算线段端点之间非零最短距离,可以判断是否存在肉眼难以观察到的细微断连,经过优化后,计算时间大大减少,即使上千条管线,也可以几秒内计算出结果。
管线txt文本是通过CAD插件yaotool的线功能下的写出pl线按钮进行生成。
2:高程坐标位置校正
管线的标注高程,如果直接提取进行使用,由于高程都是引线标注,导致位置无法对应,通过计算附近距离最短的管线端点,可以对高程点进行位置进行校正。
高程txt文件使用CAD插件增强插件进行提取。
3:代码
#作者:冯桂和
from tkinter import filedialog
from tkinter import *
from tkinter import messagebox
import tkinter as tk
import os
import time
#制作输出目录,以时间命名
cunchu=os.getcwd()
shijian=time.strftime('%m%d-%H∶%M', time.localtime())
shuchumulu=r'{}\{}'.format(cunchu,shijian)
#创建主窗口
win=tk.Tk()
#设置窗口标题
win.title("管线建模小工具-冯桂和")
#设置窗口大小
win.geometry('800x800+400+100')
#全局变量
PLNodeSum=2 #线段端点个数
fxy=[] #线段端点不重复坐标
groundlist=[] #地面高程二维列表
invertlist=[] #井底高程二维列表
#检查是否打开文件用
b4if=0
b5if=0
b6if=0
#创建按钮函数
def b1():
global PLNodeSum
global fxy
global b4if
#pl——txt
#pllist——txt列表
#plnum——标识数
#plxy——三维列表[[[x1][y1],[[x2][y2]],[[x3,y3],[[x4][y4]]
#everyxy——节点所有不重复坐标
#fxy——端点不重复坐标
global answerpl
#打开txt文件,获取文件路径
my_filetypes = [ ('text files', '.txt')]
answerpl = filedialog.askopenfilename(filetypes=my_filetypes)
if answerpl=='':
pass #取消打开文件
else:
try:
f=open(answerpl,'r',encoding='utf-8') #根据路径打开文件
pl=f.read() #txt内容写至pl
f.close()
pllist=pl.split('\n') #将内容进行分割成列表pllist
del pllist[-1] #删除最后一行空内容
plnum=[] #新建一个列表plnum存储每条PL线段数作为标识符
k=0
while k<len(pllist)-1:
j=int(pllist[k])
plnum.append(j)
k=k+j+1
plxy=[] #新建一个列表plxy,存储每段坐标,一维是一条多段线,二维是该多段线的xy坐标,三维是x和y坐标
sum=1
for i in range(len(plnum)):
length=plnum[i]
a=[]
for i in range(length):
b=pllist[i+sum]
b=b.split(' ')
for i in range(2):
b[i]=float(b[i])
a.append(b)
sum=sum+length+1
plxy.append(a)
lab_textb1.delete(0, "end")
lab_textb1.insert(END,len(plnum))
lab_textb2.delete(0, "end")
lab_textb2.insert(END,len(pllist)-len(plnum))
everyxy=pl.split('\n')
del everyxy[-1]
ii=-1
for i in reversed(plnum):
ii=ii-int(i)
everyxy.pop(ii)
everyxy=set(everyxy)
lab_textb3.delete(0, "end")
lab_textb3.insert(END,len(everyxy))
fxy=[]
for i in range(len(plxy)):
str1='{},{}'.format(plxy[i][0][0],plxy[i][0][1])
str2='{},{}'.format(plxy[i][-1][0],plxy[i][-1][1])
fxy.append(str1)
fxy.append(str2)
fxy=set(fxy)
fxy=list(fxy)
PLNodeSum=len(fxy)
lab_textb4.delete(0, "end")
lab_textb4.insert(END,len(fxy))
sumlength=0
for i in range(len(plxy)):
for j in range(len(plxy[i])-1):
x1=plxy[i][j][0]
y1=plxy[i][j][1]
x2=plxy[i][j+1][0]
y2=plxy[i][j+1][1]
sumone=round(pow(pow(x1-x2,2)+pow(y1-y2,2),0.5),3)
sumlength=sumlength+sumone
lab_textb5.delete(0, "end")
lab_textb5.insert(END,round(sumlength,3))
b4if=1
except ValueError:
#检测文本格式出错后输出提示
text1.insert(END,'格式错误!正确格式为:\n')
text1.insert(END,'段数标识符\nx1坐标\ty1坐标\n例如:')
text1.insert(END,'\n2\n1487.55776539 1128.97416601\n1490.54061987 1129.51908026\n2\n1485.88133218 1128.47169398\n1487.33736081 1128.90810484\n')
text1.see("end")
def b2():
global PLNodeSum
global groundlist
global b5if
#ground——文本内容
#groundlist——文本分割后二维列表
#groundgroundheight——高程列表
my_filetypes = [ ('text files', '.txt')]
answerground = filedialog.askopenfilename(filetypes=my_filetypes)
if answerground=='':
pass
else:
try:
f=open(answerground,'r',encoding='utf-8')
ground=f.read() #TXT内容写至ground
f.close()
groundlist=ground.split('\n')
del groundlist[-1]
for i in range(len(groundlist)):
groundlist[i]=groundlist[i].split(' ')
for i in range(len(groundlist)):
for j in range(groundlist[i].count('')):
groundlist[i].remove('')
for i in range(len(groundlist)):
for j in range(len(groundlist[i])):
groundlist[i][j]=float(groundlist[i][j])
lab_textd1.delete(0, "end")
lab_textd1.insert(END,len(groundlist))
groundheightb=[]
for i in range(len(groundlist)):
groundheightb.append(groundlist[i][2])
lab_textd2.delete(0, "end")
lab_textd2.insert(END,max(groundheightb))
lab_textd3.delete(0, "end")
lab_textd3.insert(END,min(groundheightb))
lab_textd4.delete(0, "end")
lab_textd4.insert(END,round(max(groundheightb)-min(groundheightb),2))
if PLNodeSum==0:
lab_textd5.delete(0, "end")
lab_textd5.insert(END,'未加载多段线')
else:
lab_textd5.delete(0, "end")
lab_textd5.insert(END,len(groundlist)-PLNodeSum)
b5if=1
except ValueError:
text1.insert(END,'格式错误!正确格式为:\n')
text1.insert(END,'x1坐标\ty1坐标\t高程值\n例如:')
text1.insert(END,'\n1267.098 1170.569 12.01\n1900.235 1001.148 12.04\n2394.086 918.464 12.06\n')
text1.see("end")
def b3():
global PLNodeSum
global invertlist
global b6if
#invert——文本内容
#invertlist——文本分割后二维列表
#invertheight——高程列表
my_filetypes = [ ('text files', '.txt')]
answerinvert = filedialog.askopenfilename(filetypes=my_filetypes)
if answerinvert=='':
pass
else:
try:
f=open(answerinvert,'r',encoding='utf-8')
invert=f.read() #TXT内容写至ground
f.close()
invertlist=invert.split('\n')
del invertlist[-1]
for i in range(len(invertlist)):
invertlist[i]=invertlist[i].split(' ')
for i in range(len(invertlist)):
for j in range(invertlist[i].count('')):
invertlist[i].remove('')
for i in range(len(invertlist)):
for j in range(len(invertlist[i])):
invertlist[i][j]=float(invertlist[i][j])
lab_textf1.delete(0, "end")
lab_textf1.insert(END,len(invertlist))
invertheight=[]
for i in range(len(invertlist)):
invertheight.append(invertlist[i][2])
lab_textf2.delete(0, "end")
lab_textf2.insert(END,max(invertheight))
lab_textf3.delete(0, "end")
lab_textf3.insert(END,min(invertheight))
lab_textf4.delete(0, "end")
lab_textf4.insert(END,round(max(invertheight)-min(invertheight),2))
if PLNodeSum==0:
lab_textf5.delete(0, "end")
lab_textf5.insert(END,'未加载多段线')
else:
lab_textf5.delete(0, "end")
lab_textf5.insert(END,len(invertlist)-PLNodeSum)
b6if=1
except ValueError:
text1.insert(END,'格式错误!正确格式为:\n')
text1.insert(END,'x1坐标\ty1坐标\t高程值\n例如:')
text1.insert(END,'\n1267.098 1170.569 12.01\n1900.235 1001.148 12.04\n2394.086 918.464 12.06\n')
text1.see("end")
def b4():
global b4if
if b4if==0:
text1.insert(END,'未打开多段线txt文件!\n')
text1.see("end")
else:
wucha=10
global fxy
fxy11=fxy.copy()
for i in range(len(fxy11)):
fxy11[i]=fxy11[i].split(',')
fxy11[i][0]=float(fxy11[i][0])
fxy11[i][1]=float(fxy11[i][1])
fxy22=fxy11.copy()
lengthxy=[]
for i in range(len(fxy11)):
for j in range(len(fxy11)):
if (fxy11[i][0]-fxy22[j][0])>=wucha:
lengthxy.append(100)
elif (fxy11[i][1]-fxy22[j][1])>=wucha:
lengthxy.append(100)
elif (fxy11[i][1]-fxy22[j][1]==0 and fxy11[i][0]-fxy22[j][0]==0):
lengthxy.append(100)
else:
x1=fxy11[i][0]
y1=fxy11[i][1]
x2=fxy22[j][0]
y2=fxy22[j][1]
lengthxy.append(round(pow(pow(x1-x2,2)+pow(y1-y2,2),0.5),8))
geshu=tk.simpledialog.askinteger(title= "输入个数",prompt = "端点最短距离个数(整数)",initialvalue=5)
if geshu==None:
geshu=5
for i in range(geshu):
minlen=min(lengthxy)
weizhi=lengthxy.index(minlen)%len(fxy11)
out='距离{}:{}\n{},{}\n'.format(i+1,minlen,fxy11[weizhi][0],fxy11[weizhi][1])
text1.insert(END,out)
lengthxy[lengthxy.index(minlen)]=100
minlen=min(lengthxy)
weizhi=lengthxy.index(minlen)%len(fxy11)
out='{},{}\n'.format(fxy11[weizhi][0],fxy11[weizhi][1])
text1.insert(END,out)
lengthxy[lengthxy.index(minlen)]=100
text1.insert(END,'------------------------------------------------------------------------------------')
text1.see("end")
def b5():
global groundlist
global fxy
global b4if
global b5if
if b5if==0:
text1.insert(END,'未打开地面高程点txt文件!\n')
text1.see("end")
elif b4if==0:
text1.insert(END,'未打开多段线txt文件!\n')
text1.see("end")
else:
groundlist2=groundlist.copy()
fxy2=fxy.copy()
for i in range(len(fxy2)):
fxy2[i]=fxy2[i].split(',')
for i in range(len(fxy2)):
for j in range(len(fxy2[i])):
fxy2[i][j]=float(fxy2[i][j])
for i in range(len(groundlist)):
x1=groundlist[i][0]
y1=groundlist[i][1]
xylength=[]
xycalculation=[]
for j in range(len(fxy2)):
x2=fxy2[j][0]
y2=fxy2[j][1]
xylength.append(pow(pow(x1-x2,2)+pow(y1-y2,2),0.5))
xylengthmin=min(xylength)
xylengthminlocation=xylength.index(xylengthmin)
groundlist2[i][0]=fxy2[xylengthminlocation][0]
groundlist2[i][1]=fxy2[xylengthminlocation][1]
outgroundtxt=''
for i in range(len(groundlist2)):
outgroundtxt='{}{}\t{}\t{}\n'.format(outgroundtxt,groundlist2[i][0],groundlist2[i][1],groundlist2[i][2])
if not os.path.exists(shuchumulu):
os.makedirs(shuchumulu)
f=open('{}\\高程:井地面校正后.txt'.format(shuchumulu),'w',encoding='utf-8')
f.write(outgroundtxt)
f.close()
text1.insert(END,'《高程:井地面校正后.txt》已存储至:\n{}\n'.format(shuchumulu))
checkxyz=outgroundtxt.split('\n')
del checkxyz[-1]
checkxy=checkxyz.copy()
for i in range(len(checkxy)):
checkxy[i]=checkxy[i].split('\t')
repeatxy=[]
for i in range(len(checkxy)):
for j in range(i,len(checkxy)):
if i==j:
pass
elif (checkxy[i][0]==checkxy[j][0] and checkxy[i][1]==checkxy[j][1]):
xx=checkxy[i][0]
yy=checkxy[i][1]
repeatxy.append('{},{}'.format(xx,yy))
if len(repeatxy)>0:
text1.insert(END,'发现校正后有位置重复,重复点如下:\n')
repeatout='\n'.join(repeatxy)
text1.insert(END,'{}\n'.format(repeatout))
text1.see("end")
def b6():
global invertlist
global fxy
global b4if
if b6if==0:
text1.insert(END,'未打开井底高程点txt文件!\n')
text1.see("end")
elif b4if==0:
text1.insert(END,'未打开多段线txt文件!\n')
text1.see("end")
else:
invertlist2=invertlist.copy()
fxy2=fxy.copy()
for i in range(len(fxy2)):
fxy2[i]=fxy2[i].split(',')
for i in range(len(fxy2)):
for j in range(len(fxy2[i])):
fxy2[i][j]=float(fxy2[i][j])
for i in range(len(invertlist)):
x1=invertlist[i][0]
y1=invertlist[i][1]
xylength=[]
xycalculation=[]
for j in range(len(fxy2)):
x2=fxy2[j][0]
y2=fxy2[j][1]
xylength.append(pow(pow(x1-x2,2)+pow(y1-y2,2),0.5))
xylengthmin=min(xylength)
xylengthminlocation=xylength.index(xylengthmin)
invertlist2[i][0]=fxy2[xylengthminlocation][0]
invertlist2[i][1]=fxy2[xylengthminlocation][1]
outgroundtxt=''
for i in range(len(invertlist2)):
outgroundtxt='{}{}\t{}\t{}\n'.format(outgroundtxt,invertlist2[i][0],invertlist2[i][1],invertlist2[i][2])
if not os.path.exists(shuchumulu):
os.makedirs(shuchumulu)
f=open('{}\\高程:井内底校正后.txt'.format(shuchumulu),'w',encoding='utf-8')
f.write(outgroundtxt)
f.close()
text1.insert(END,'《高程:井内底校正后.txt》已存储至:\n{}\n'.format(shuchumulu))
checkxyz=outgroundtxt.split('\n')
del checkxyz[-1]
checkxy=checkxyz.copy()
for i in range(len(checkxy)):
checkxy[i]=checkxy[i].split('\t')
repeatxy=[]
for i in range(len(checkxy)):
for j in range(i,len(checkxy)):
if i==j:
pass
elif (checkxy[i][0]==checkxy[j][0] and checkxy[i][1]==checkxy[j][1]):
xx=checkxy[i][0]
yy=checkxy[i][1]
repeatxy.append('{},{}'.format(xx,yy))
if len(repeatxy)>0:
text1.insert(END,'发现校正后有位置重复,重复点如下:\n')
repeatout='\n'.join(repeatxy)
text1.insert(END,'{}\n'.format(repeatout))
text1.see("end")
#创建按钮
width1=20
groundheight1=1
Button1=tk.Button(win,text='选择多段线文件',width=width1, height=groundheight1,command=b1,font=('微软雅黑',15))
Button2=tk.Button(win,text='选择地面高程文件',width=width1, height=groundheight1,command=b2,font=('微软雅黑',15))
Button3=tk.Button(win,text='选择井底高程文件',width=width1, height=groundheight1,command=b3,font=('微软雅黑',15))
Button1.grid(row=0,column=0,padx=5,pady=8)
Button2.grid(row=0,column=1,padx=5,pady=8)
Button3.grid(row=0,column=2,padx=5,pady=8)
Button4=tk.Button(win,text='断连检查',width=width1, height=groundheight1,command=b4,font=('微软雅黑',15))
Button5=tk.Button(win,text='地面坐标校正',width=width1, height=groundheight1,command=b5,font=('微软雅黑',15))
Button6=tk.Button(win,text='井底坐标校正',width=width1, height=groundheight1,command=b6,font=('微软雅黑',15))
Button4.grid(row=6,column=0,padx=5,pady=8)
Button5.grid(row=6,column=1,padx=5,pady=8)
Button6.grid(row=6,column=2,padx=5,pady=8)
#创建单行文本即输入框
lab_texta1=tk.Label(win,text='总条数:',font=('微软雅黑',15),justify='left',padx=10)
lab_textb1=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texta2=tk.Label(win,text='总段数:',font=('微软雅黑',15),justify='left',padx=10)
lab_textb2=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texta3=tk.Label(win,text='节点数:',font=('微软雅黑',15),justify='left',padx=10)
lab_textb3=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texta4=tk.Label(win,text='端点数:',font=('微软雅黑',15),justify='left',padx=10)
lab_textb4=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texta5=tk.Label(win,text='总长度:',font=('微软雅黑',15),justify='left',padx=10)
lab_textb5=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texta1.grid(row=1,column=0,padx=10,pady=8,sticky="w")
lab_textb1.grid(row=1,column=0,padx=10,pady=8,sticky="e")
lab_texta2.grid(row=2,column=0,padx=10,pady=8,sticky="w")
lab_textb2.grid(row=2,column=0,padx=10,pady=8,sticky="e")
lab_texta3.grid(row=3,column=0,padx=10,pady=8,sticky="w")
lab_textb3.grid(row=3,column=0,padx=10,pady=8,sticky="e")
lab_texta4.grid(row=4,column=0,padx=10,pady=8,sticky="w")
lab_textb4.grid(row=4,column=0,padx=10,pady=8,sticky="e")
lab_texta5.grid(row=5,column=0,padx=10,pady=8,sticky="w")
lab_textb5.grid(row=5,column=0,padx=10,pady=8,sticky="e")
lab_textc1=tk.Label(win,text='总点数:',font=('微软雅黑',15),justify='left',padx=10)
lab_textd1=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_textc2=tk.Label(win,text='最高点:',font=('微软雅黑',15),justify='left',padx=10)
lab_textd2=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_textc3=tk.Label(win,text='最低点:',font=('微软雅黑',15),justify='left',padx=10)
lab_textd3=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_textc4=tk.Label(win,text='极差值:',font=('微软雅黑',15),justify='left',padx=10)
lab_textd4=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_textc5=tk.Label(win,text='量差值:',font=('微软雅黑',15),justify='left',padx=10)
lab_textd5=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_textc1.grid(row=1,column=1,padx=10,pady=8,sticky="w")
lab_textd1.grid(row=1,column=1,padx=10,pady=8,sticky="e")
lab_textc2.grid(row=2,column=1,padx=10,pady=8,sticky="w")
lab_textd2.grid(row=2,column=1,padx=10,pady=8,sticky="e")
lab_textc3.grid(row=3,column=1,padx=10,pady=8,sticky="w")
lab_textd3.grid(row=3,column=1,padx=10,pady=8,sticky="e")
lab_textc4.grid(row=4,column=1,padx=10,pady=8,sticky="w")
lab_textd4.grid(row=4,column=1,padx=10,pady=8,sticky="e")
lab_textc5.grid(row=5,column=1,padx=10,pady=8,sticky="w")
lab_textd5.grid(row=5,column=1,padx=10,pady=8,sticky="e")
lab_texte1=tk.Label(win,text='总点数:',font=('微软雅黑',15),justify='left',padx=10)
lab_textf1=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texte2=tk.Label(win,text='最高点:',font=('微软雅黑',15),justify='left',padx=10)
lab_textf2=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texte3=tk.Label(win,text='最低点:',font=('微软雅黑',15),justify='left',padx=10)
lab_textf3=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texte4=tk.Label(win,text='极差值:',font=('微软雅黑',15),justify='left',padx=10)
lab_textf4=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texte5=tk.Label(win,text='量差值:',font=('微软雅黑',15),justify='left',padx=10)
lab_textf5=tk.Entry(win,font=('微软雅黑',15),width = 13)
lab_texte1.grid(row=1,column=2,padx=10,pady=8,sticky="w")
lab_textf1.grid(row=1,column=2,padx=10,pady=8,sticky="e")
lab_texte2.grid(row=2,column=2,padx=10,pady=8,sticky="w")
lab_textf2.grid(row=2,column=2,padx=10,pady=8,sticky="e")
lab_texte3.grid(row=3,column=2,padx=10,pady=8,sticky="w")
lab_textf3.grid(row=3,column=2,padx=10,pady=8,sticky="e")
lab_texte4.grid(row=4,column=2,padx=10,pady=8,sticky="w")
lab_textf4.grid(row=4,column=2,padx=10,pady=8,sticky="e")
lab_texte5.grid(row=5,column=2,padx=10,pady=8,sticky="w")
lab_textf5.grid(row=5,column=2,padx=10,pady=8,sticky="e")
#创建多行文本控件
text1=tk.Text(win,width=40,height=10,font=('微软雅黑',15))
text1.place(x=10,y=380,width=760,height=400)
#显示主窗口
win.mainloop()