基于TIN三角网生成不光滑等值线

  • 等值线功能实现
  • 等值点插值
  • TIN 边界边查找
  • 单个三角形内生长等值线
  • 一条等值线生成
  • 按等高距生成全部等值线
  • 可视化结果
  • 可视化代码
  • 等值线(未平滑)
  • 全部代码


等值线功能实现

等值点插值

在一条边上按照高程值线性插值,计算出待插值高程的x,y坐标,并将插值的结果实例成一个点类,方便统一管理,如下所示:

#插值函数
def Interpolation(edge,n,i):
    if(edge.BeginPoint.H>edge.EndPoint.H):
            Hmax=edge.BeginPoint
            Hmin=edge.EndPoint
    elif(edge.BeginPoint.H<edge.EndPoint.H):
        Hmin=edge.BeginPoint
        Hmax=edge.EndPoint
    if (n>Hmin.H and n<Hmax.H):
        dy=Hmax.Y-Hmin.Y
        dx=Hmax.X-Hmin.X
        linescale=(n-Hmin.H)/(Hmax.H-Hmin.H)
        x=Hmin.X+linescale*dx
        y=Hmin.Y+linescale*dy
        name="{0}-{1}".format(n,i)
        eqpoint=Point(name,x,y,n)
        return eqpoint
    else:
        return 0

TIN 边界边查找

遍历TIN的每个三角形边,我们认为具有邻接三角形的边在TIN内部,不具有邻接三角形的边是边界边。我们的数据特点是只具有开曲线,所以找到边界边作为某条等值线的生成起点至关重要,代码如下:

#边界边列表
def BorderTri(Triangle_List):
    Border_list=[]
    for i in range(0,len(Triangle_List)):
        if (len(Triangle_List[i].BaseLine.Belonging_Triangle)==1):
            Border_list.append(Triangle_List[i].BaseLine)
        if (len(Triangle_List[i].newLine1.Belonging_Triangle)==1):
            Border_list.append(Triangle_List[i].newLine1)
        if (len(Triangle_List[i].newLine2.Belonging_Triangle)==1):
            Border_list.append(Triangle_List[i].newLine2)
    return  Border_list

单个三角形内生长等值线

在定位的三角形内生长等值线,根据一个三角形有且仅有两个等值点,在三角形的另外两条边上插值第二个等值点,并将所在的边作为新的生长起点,如下所示:

#一个三角形内生长等值线
def Grow_Eq(triangle,eqedge,n):
    point=0
    edges=[triangle.BaseLine,triangle.newLine1,triangle.newLine2]
    for edge in edges:
        if(edge==eqedge):
            continue
        else:
            point=Interpolation(edge,n,edge.Belonging_Triangle[0])
            if(point!=0):
                break
    return edge,point

一条等值线生成

从边界边的一侧按单个三角形生长等值线,直至生长到TIN对侧的另一条边界边一条等值线生长完成。

#查找等值点 输出等值线序列点
def Equivalent_point(Triangle_List,n):
    point=0
    eqlinelist=[]
    Border_list=bor=BorderTri(Triangle_List)
    for borderedge in Border_list:
        edge=borderedge
        point=Interpolation(edge,n,edge.Belonging_Triangle[0])
        if(point!=0):
            eqlinelist.append(point)
            break
    #根据邻接三角形生成等值线
    index=edge.Belonging_Triangle[0]
    [edge,point]=Grow_Eq(Triangle_List[index],edge,n)
    eqlinelist.append(point)
    while(len(edge.Belonging_Triangle)==2):
        index=edge.Belonging_Triangle[1]
        [edge,point]=Grow_Eq(Triangle_List[index],edge,n)
        eqlinelist.append(point)
    return eqlinelist

按等高距生成全部等值线

在TIN的最低点到最高点的高程范围内,按照一定的等高距,由低到高逐步生成每条等值线,直至全局等值线生成,代码如下:

# 全局等高线
def Contour_Line(Point_List,Triangle_List,d):
    eqlinlists=[]
    Hmax=EPSILON
    Hmin=1/EPSILON
    for p in Point_List:
        if(p.H>Hmax):
            Hmax=p.H
        if(p.H<Hmin):
            Hmin=p.H
    n=Hmin+d
    while(n<Hmax):
        eqlinlist=Equivalent_point(Triangle_List,n)
        eqlinlists.append(eqlinlist)
        n=n+d
    return eqlinlists

可视化结果

可视化代码

'''*******************窗体********************'''
# 生成一个窗体界面 命名为window
window=tk.Tk()
window.title('TIN')
window.geometry('1000x750')

# 在窗体上生成一块画布 用于绘制导线图
canvas = tk.Canvas(window,width=800,height=600,bg = 'white')
canvas.place(x=190,y=10)

#画等值线
def Draw_Equivalent_line(eqpointlists,Point_List):
    xyminmax=XYMinMax(Point_List)
    for eqpointlist in eqpointlists:
        for i in range(0,len(eqpointlist)-1):
            gxgy1=GaussToScreenCor(xyminmax,eqpointlist[i].X,eqpointlist[i].Y)
            gxgy2=GaussToScreenCor(xyminmax,eqpointlist[i+1].X,eqpointlist[i+1].Y)
            oval = canvas.create_oval(gxgy1[0]-1, gxgy1[1]-1, gxgy1[0]+1, gxgy1[1]+1)
            ova2 = canvas.create_oval(gxgy1[0]-1, gxgy1[1]-1, gxgy1[0]+1, gxgy1[1]+1)
            Connect_Point(gxgy1,gxgy2,'red')

#********调试********
path="D:\等高线点数据.txt"
point_list=ReadDataTXT(path)
Net=CreatTIN(point_list)
Draw_TIN(point_list,Net[0])
eqs=Contour_Line(point_list,Net[1],30)
Draw_Equivalent_line(eqs,point_list)
window.mainloop()
'''*******************所有代码在此之上********************'''

等值线(未平滑)

python等值线 python等值线文件生成论文_python等值线

全部代码

#插值函数
def Interpolation(edge,n,i):
    if(edge.BeginPoint.H>edge.EndPoint.H):
            Hmax=edge.BeginPoint
            Hmin=edge.EndPoint
    elif(edge.BeginPoint.H<edge.EndPoint.H):
        Hmin=edge.BeginPoint
        Hmax=edge.EndPoint
    if (n>Hmin.H and n<Hmax.H):
        dy=Hmax.Y-Hmin.Y
        dx=Hmax.X-Hmin.X
        linescale=(n-Hmin.H)/(Hmax.H-Hmin.H)
        x=Hmin.X+linescale*dx
        y=Hmin.Y+linescale*dy
        name="{0}-{1}".format(n,i)
        eqpoint=Point(name,x,y,n)
        return eqpoint
    else:
        return 0
#边界边列表
def BorderTri(Triangle_List):
    Border_list=[]
    for i in range(0,len(Triangle_List)):
        if (len(Triangle_List[i].BaseLine.Belonging_Triangle)==1):
            Border_list.append(Triangle_List[i].BaseLine)
        if (len(Triangle_List[i].newLine1.Belonging_Triangle)==1):
            Border_list.append(Triangle_List[i].newLine1)
        if (len(Triangle_List[i].newLine2.Belonging_Triangle)==1):
            Border_list.append(Triangle_List[i].newLine2)
    return  Border_list
#一个三角形内生长等值线
def Grow_Eq(triangle,eqedge,n):
    point=0
    edges=[triangle.BaseLine,triangle.newLine1,triangle.newLine2]
    for edge in edges:
        if(edge==eqedge):
            continue
        else:
            point=Interpolation(edge,n,edge.Belonging_Triangle[0])
            if(point!=0):
                break
    return edge,point
#查找等值点 输出等值线序列点
def Equivalent_point(Triangle_List,n):
    point=0
    eqlinelist=[]
    Border_list=bor=BorderTri(Triangle_List)
    for borderedge in Border_list:
        edge=borderedge
        point=Interpolation(edge,n,edge.Belonging_Triangle[0])
        if(point!=0):
            eqlinelist.append(point)
            break
    #根据邻接三角形生成等值线
    index=edge.Belonging_Triangle[0]
    [edge,point]=Grow_Eq(Triangle_List[index],edge,n)
    eqlinelist.append(point)
    while(len(edge.Belonging_Triangle)==2):
        index=edge.Belonging_Triangle[1]
        [edge,point]=Grow_Eq(Triangle_List[index],edge,n)
        eqlinelist.append(point)
    return eqlinelist
# 全局等高线
def Contour_Line(Point_List,Triangle_List,d):
    eqlinlists=[]
    Hmax=EPSILON
    Hmin=1/EPSILON
    for p in Point_List:
        if(p.H>Hmax):
            Hmax=p.H
        if(p.H<Hmin):
            Hmin=p.H
    n=Hmin+d
    while(n<Hmax):
        eqlinlist=Equivalent_point(Triangle_List,n)
        eqlinlists.append(eqlinlist)
        n=n+d
    return eqlinlists
'''*******************窗体********************'''
# 生成一个窗体界面 命名为window
window=tk.Tk()
window.title('TIN')
window.geometry('1000x750')

# 在窗体上生成一块画布 用于绘制导线图
canvas = tk.Canvas(window,width=800,height=600,bg = 'white')
canvas.place(x=190,y=10)

# 画出数据点
def Draw_Point(Point_List):
    xyminmax=XYMinMax(Point_List)
    for point in Point_List:
        gxgy=GaussToScreenCor(xyminmax,point.X,point.Y)
        oval = canvas.create_oval(gxgy[0]-1, gxgy[1]-1, gxgy[0]+1, gxgy[1]+1)
        #canvas.create_text(gxgy[0]-13,gxgy[1],text=point.PointName)

# 画出TIN网
def Connect_Point(list1,list2,color):
    line = canvas.create_line(list1[0], list1[1],list2[0],list2[1],fill = color)
def Draw_TIN(Point_List,Line_List):
    xyminmax=XYMinMax(Point_List)
    for line in Line_List:
        gxgy1=GaussToScreenCor(xyminmax,line.BeginPoint.X,line.BeginPoint.Y)
        gxgy2=GaussToScreenCor(xyminmax,line.EndPoint.X,line.EndPoint.Y)
        oval = canvas.create_oval(gxgy1[0]-1, gxgy1[1]-1, gxgy1[0]+1, gxgy1[1]+1)
        ova2 = canvas.create_oval(gxgy1[0]-1, gxgy1[1]-1, gxgy1[0]+1, gxgy1[1]+1)
        Connect_Point(gxgy1,gxgy2,'black')
#画等值线
def Draw_Equivalent_line(eqpointlists,Point_List):
    xyminmax=XYMinMax(Point_List)
    for eqpointlist in eqpointlists:
        for i in range(0,len(eqpointlist)-1):
            gxgy1=GaussToScreenCor(xyminmax,eqpointlist[i].X,eqpointlist[i].Y)
            gxgy2=GaussToScreenCor(xyminmax,eqpointlist[i+1].X,eqpointlist[i+1].Y)
            oval = canvas.create_oval(gxgy1[0]-1, gxgy1[1]-1, gxgy1[0]+1, gxgy1[1]+1)
            ova2 = canvas.create_oval(gxgy1[0]-1, gxgy1[1]-1, gxgy1[0]+1, gxgy1[1]+1)
            Connect_Point(gxgy1,gxgy2,'red')
#********调试********
path="D:\等高线点数据.txt"
point_list=ReadDataTXT(path)
Draw_Point(point_list)
Net=CreatTIN(point_list)
Draw_TIN(point_list,Net[0])
eqs=Contour_Line(point_list,Net[1],10)
Draw_Equivalent_line(eqs,point_list)
window.mainloop()
'''*******************所有代码在此之上********************'''