#2.0 新增程序运行结果功能、新增坡度坡向计算功能、修改窗口名字为GIS地理信息系统、新增显示colorbar,且修复了colorbar多次显示bug
import tkinter as tk
from tkinter import *
from tkinter import filedialog
import numpy as np
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk
class GIS_GUI:
def __init__(self):
self.root=tk.Tk() #创建主窗体
self.root.title('GIS地理信息系统') #加标题
self.root.geometry('1000x800')
self.label_set()
self.text_set()
self.button_set()
self.canvas_set()
self.root.mainloop()
def Slope_Aspect(self):
'''
输入参数:data:asc文件数据
方法功能:计算坡度坡向,并输出坡度坡向矩阵
'''
#得出cellsize数据,number为数值数据
cellsize = int(self.data[4][1])
number = self.data[6:]
#将列表数据转换为浮点型数组数据
number_arr = np.matrix(number,dtype=np.float64)
#矩阵的扩充,调整参数为边缘补充,并得出行列
number_matrix_0 = np.pad(number_arr,(1,1),'edge')
row,column = np.shape(number_matrix_0)
#利用坡度坡向计算公式,计算出每一点的坡度坡向,并保存在矩阵当中
Slope = np.ones((int(self.data[1][1]),int(self.data[0][1])))*-9999
Aspect = np.ones((int(self.data[1][1]),int(self.data[0][1])))*-9999
for i in range(1,row-1):
for j in range(1,column-1):
flag1=[0]*9
flag1[0]=1 if abs(number_matrix_0[i][j]-int(self.data[5][1])) < 1 else 0
flag1[1]=1 if abs(number_matrix_0[i][j-1]-int(self.data[5][1]))<1 else 0
flag1[2]=1 if abs(number_matrix_0[i][j+1]-int(self.data[5][1]))<1 else 0
flag1[3]=1 if abs(number_matrix_0[i-1][j]-int(self.data[5][1]))<1 else 0
flag1[4]=1 if abs(number_matrix_0[i-1][j-1]-int(self.data[5][1]))<1 else 0
flag1[5]=1 if abs(number_matrix_0[i-1][j+1]-int(self.data[5][1]))<1 else 0
flag1[6]=1 if abs(number_matrix_0[i+1][j]-int(self.data[5][1]))<1 else 0
flag1[7]=1 if abs(number_matrix_0[i+1][j-1]-int(self.data[5][1]))<1 else 0
flag1[8]=1 if abs(number_matrix_0[i+1][j+1]-int(self.data[5][1]))<1 else 0
if sum(flag1)<1 :
slope_we = ((2*number_matrix_0[i][j-1] + number_matrix_0[i-1][j-1] + number_matrix_0[i+1][j-1] ) - ( 2*number_matrix_0[i][j+1] + number_matrix_0[i-1][j+1] + number_matrix_0[i+1][j+1] ))/(8*cellsize)
slope_sn = ((2*number_matrix_0[i+1][j] + number_matrix_0[i+1][j-1] + number_matrix_0[i+1][j-1] ) - ( 2*number_matrix_0[i-1][j] + number_matrix_0[i-1][j-1] + number_matrix_0[i-1][j+1] ))/(8*cellsize)
Slope[i-1][j-1] = np.sqrt(slope_we**2+slope_sn**2)*180/np.pi
if slope_we != 0:
Aspect[i-1][j-1] = (slope_sn/slope_we)*180/np.pi
if (slope_we > 0) & (slope_sn > 0):
Aspect[i-1][j-1] = np.arctan(Aspect[i-1][j-1])
if (slope_we > 0) & (slope_sn <= 0):
Aspect[i-1][j-1] = np.arctan(Aspect[i-1][j-1]*-1) + 90
if (slope_we < 0) & (slope_sn >= 0):
Aspect[i-1][j-1] = np.arctan(Aspect[i-1][j-1]*-1) + 270
if (slope_we < 0) & (slope_sn < 0):
Aspect[i-1][j-1] = np.arctan(Aspect[i-1][j-1]) + 180
if (slope_we == 0) & (slope_sn < 0):
Aspect[i-1][j-1] = 180
if (slope_we == 0) & (slope_sn > 0):
Aspect[i-1][j-1] = 0
self.Slope = Slope
self.Aspect = Aspect
self.var.set('坡度坡向计算完毕')
def draw_dem(self):
#清空画布
self.f.clear()
self.Figure = self.f.add_subplot(111)
#转换为数值数据
data = self.data[6:]
#将数据转换为np矩阵
data = np.array(data,dtype=np.float64)
real_data = data[data!=-9999]
dem = self.Figure.imshow(data,cmap='hsv',vmin=0,vmax=np.max(real_data))
self.f.colorbar(dem)
self.c.draw()
self.toolbar.update()
self.var.set('高程图像绘制完毕')
def draw_slope(self):
#清空画布
self.f.clear()
self.Figure = self.f.add_subplot(111)
#转换为数值数据
data = self.Slope[6:]
#将数据转换为np矩阵
data = np.array(data,dtype=np.float64)
real_data = data[data!=-9999]
slope = self.Figure.imshow(data,cmap='hsv',vmin=0,vmax=np.max(real_data))
self.f.colorbar(slope)
self.c.draw()
self.toolbar.update()
self.var.set('坡度图像绘制完毕')
def draw_aspect(self):
#清空画布
self.f.clear()
self.Figure = self.f.add_subplot(111)
#转换为数值数据
data = self.Aspect[6:]
#将数据转换为np矩阵
data = np.array(data,dtype=np.float64)
real_data = data[data!=-9999]
aspect = self.Figure.imshow(data,cmap='hsv',vmin=0,vmax=np.max(real_data))
self.f.colorbar(aspect)
self.c.draw()
self.toolbar.update()
self.var.set('坡向图像绘制完毕')
#清空画布
def draw_clean(self):
self.Figure.clear()
self.c.draw()
self.var.set('画布清空成功')
#图像显示功能
def create_form(self,figure):
#把绘制的图形显示到tkinter窗口上
self.canvas=FigureCanvasTkAgg(figure,self.root)
#更新画布
self.canvas.draw()
#显示matlabplot工具栏
toolbar =NavigationToolbar2Tk(self.canvas, self.root)
toolbar.update()
self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)
#文件打开功能
def open_file(self):
#调用askopenfile方法获取单个打开的文件
sfname = filedialog.askopenfilename(title='打开单个文件',
filetypes=[('asc文件', '*.asc'),("文本文件", "*.txt"), ('Python源文件', '*.py')], # 处理的文件类型
initialdir='g:/')# 初始目录
return sfname
#text内容显示,与数据读取
def data_read(self):
#按行全部打开文件
name=self.open_file()
self.data=[]
with open(name) as c:
content = c.readlines()
for line in content:
self.t.insert('end',line)
line = line.split()
self.data.append(line)
self.var.set('读取成功')
#button清除文本框
def move(self):
self.t.delete('1.0','end')
#定义label框(程序运行结果显示)
def label_set(self):
self.var=tk.StringVar()
self.l = tk.Label(self.root,bg='green',textvariable=self.var,text='result',height=5,width=15,font=('Arial',12)).pack(side='top', anchor='ne',fill=X,expand=1)
#定义画布
def canvas_set(self):
self.f = Figure(dpi=300)
self.Figure = self.f.add_subplot(111)
self.c = FigureCanvasTkAgg(self.f, self.root)
self.c.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
self.toolbar =NavigationToolbar2Tk(self.c, self.root)
#定义文本框
def text_set(self):
self.t = tk.Text(self.root,height=30,)
self.t.pack(side='left', expand='no', anchor='w', fill='y')
#定义按钮
def button_set(self):
self.b1 =tk.Button(self.root,text='打开单个文件',command=self.data_read).pack(side='top', anchor='nw')
self.b2 = tk.Button(self.root,text='绘制高程图',command=self.draw_dem).pack(side='top',anchor='nw')
self.b3 = tk.Button(self.root, text = "清空文本框", command = self.move).pack(side='top', anchor='nw')
self.b4 = tk.Button(self.root,text='清空画板',command=self.draw_clean).pack(side='top',anchor='nw')
self.b5 = tk.Button(self.root,text='计算坡度坡向',command=self.Slope_Aspect).pack(side='top',anchor='nw')
self.b6 = tk.Button(self.root,text='绘制坡度图',command=self.draw_slope).pack(side='top',anchor='nw')
self.b7 = tk.Button(self.root,text='绘制坡向图',command=self.draw_aspect).pack(side='top',anchor='nw')
if __name__=="__main__":
window=GIS_GUI()