目录[-]

在使用CAD管线信息搭建MIKE模型时,需要利用CAD插件yaotool对CAD数据进行提取,提取后往往需要进行处理才可使用,为提高建模效率,故使用python设计代码。

代码在经过多个功能设计完毕后,进行优化重构,并编写用户界面,效果如下:

jmpy1

功能主要围绕三个核心功能:

1:排水管线端点断连检查

通过计算线段端点之间非零最短距离,可以判断是否存在肉眼难以观察到的细微断连,经过优化后,计算时间大大减少,即使上千条管线,也可以几秒内计算出结果。

管线txt文本是通过CAD插件yaotool的线功能下的写出pl线按钮进行生成。

yao3

yao4

2:高程坐标位置校正

管线的标注高程,如果直接提取进行使用,由于高程都是引线标注,导致位置无法对应,通过计算附近距离最短的管线端点,可以对高程点进行位置进行校正。

高程txt文件使用CAD插件增强插件进行提取。

zqcj1

zqcj3

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()