自动影像库配准程序
看到生产部竟然派专人开始折腾影像图,我真的要吐血了。。。
#!/usr/bin/env python # -*- coding:utf-8 -*- # file: Coord4Grid.py # Version: 3.0 # by Lee, 2009-11-16 '''配准图幅自动生成坐标模板 根据输入的图幅计算该图四个角的坐标值,从而生成模板文件。 先根据国家标准分幅的图幅号计算坐标,即考虑在1:5000形式下的比例尺算法。 计算公式: 经度=(数字码-31)*6度+(列号-1)*1.875分 纬度=(字符码-1)*4+(4度/1.25分-行号)*1.25分 再根据ABCD的分法取四个小图幅的坐标并格式化成需要的模板形式。 2.0改进: 通过研究ArcMap配准后生成都jgw格式内容: 1、X-Scale(一个像元的大小) 2、旋转项 3、旋转项 4、负的Y-Scale(一个像元的大小) 5、转换项,即左上角X坐标 6、转换项,即左上角Y坐标 发现只要计算出一个像元代表的度数大小,再算出左上角的经纬度即可 难点是我们的ABCD分幅还玩外扩充了一部分,通过大量测量和分析得出扩充大小 1、3368×2381像素的图幅: X轴 左边扩充226px,右边219.25px Y轴 上边扩充229.5px,下边204.5px 2、2246×1588像素的格式:X轴左边扩充150px X轴 左边扩充150.5px,右边146px Y轴 上边扩充153px,下边137px 3.0改进 使用OO机制并且GUI化(基于Tk) ''' import os import string from Tkinter import * class Coord4Grid: '''定义实现获取坐标和偏移量等参数值的类''' def __init__(self, grid, type): self.grid = grid self.type = type self.dis_lng = 0.03125 # 经差1.875分,统一转换为度数 self.dis_lat = 0.0208333333333333 # 维差1.25分 def coordinate(self, graphnum): '''计算国家标准分幅西南角坐标值,graphnum为国家标准1:5000分幅号(e.g. F49H045179)''' a = ord(graphnum[0])-64 # 字符码6(F) b = int(graphnum[1:3]) # 数字码49 c = int(graphnum[4:7]) # 行号45 d = int(graphnum[7:10]) # 列号179 # 西南角坐标 lng = (b-31)*6 + (d-1)*self.dis_lng lat = (a-1)*4 + (4/self.dis_lat - c)*self.dis_lat return lng,lat def get_coord(self, gis): '''根据华业龙图分幅标准,计算1:2500比例下左下角和右上角(红线交叉处)坐标''' if len(gis) != 11: return 0,0,0,0 coord = self.coordinate(gis[0:-1]) #获取1:5000分幅坐标 # 西南角(左下角)坐标 lng_left = coord[0] lat_bottom = coord[1] # 东北角(右上角)坐标 lng_right = lng_left + self.dis_lng lat_upper = lat_bottom + self.dis_lat # 中心坐标(方便再分幅使用) lng_mid = (lng_left+lng_right)/2 lat_mid = (lat_bottom+lat_upper)/2 # 根据分幅返回西南和东北(左下和右上角)坐标 if gis[-1] == 'A': return lng_left,lat_mid,lng_mid,lat_upper if gis[-1] == 'B': return lng_mid,lat_mid,lng_right,lat_upper if gis[-1] == 'C': return lng_left,lat_bottom,lng_mid,lat_mid if gis[-1] == 'D': return lng_mid,lat_bottom,lng_right,lat_mid return 0,0,0,0 def get_corner_coord(self, grid, type): '''计算整个图幅左上角坐标''' center_grid = self.get_coord(grid) # 获取图幅中心红线区域两角坐标 left_up_x = center_grid[0] # 红线左上角经度 left_up_y = center_grid[3] # 红线左上角纬度 # 获取整个图幅左上角坐标 if type == '1': corner_x = left_up_x - self.dis_lng/2/(3368-226-219.25)*226 corner_y = left_up_y + self.dis_lat/2/(2381-229.5-204.5)*229.5 dis_x = self.dis_lng/2/(3368-226-219.25) dis_y = self.dis_lat/2/(2381-229.5-204.5) return dis_x,dis_y,corner_x,corner_y if type == '2': corner_x = left_up_x - self.dis_lng/2/(2246-150.5-146)*150.5 corner_y = left_up_y + self.dis_lat/2/(1588-153-137)*153 dis_x = self.dis_lng/2/(2246-150.5-146) dis_y = self.dis_lat/2/(1588-153-137) return dis_x,dis_y,corner_x,corner_y def final_format(self): '''格式化输出内容(唯一的出口函数)''' grid_out = self.get_corner_coord(self.grid, self.type) return '''\ %s 0.0000000000 0.0000000000 -%s %s %s ''' % (grid_out[0], grid_out[1], grid_out[2],grid_out[3]) # 创建Tkinter实例,用于实现界面效果 root = Tk() root.geometry("400x300") # 定义窗体大小 root.title("影像自动配置") # Caption def Enter(): '''执行配准功能函数''' path = text_path.get() # 获取路径 if path: type = str(v.get()) # 获取分辨率模式 if type in ['1','2']: Run(path, type) # 执行 else: listbox.insert(END, '请选择影像分辨率模式!!') else: listbox.insert(END, '请给出影像所在地址!!') def ReturnInsert(event): Enter() def Run(path, grid_type): '''执行主函数,根据路径和类型进行校准文件的生成''' graphs_original = os.listdir(path) # 原始目录文件信息 graphs = [] for name in graphs_original: if string.lower(name[-4:]) == '.jpg': graphs.append(name[:-4]) # 过滤剩下jpg文件 for code in graphs: listbox.insert(END, '........... '+code+' ...........') out = file(path + "\\" + code + '.jgw', 'w') photo = Coord4Grid(code, grid_type) out.write(photo.final_format()) # 输出配准文件 out.close() listbox.insert(END, '') listbox.insert(END, '完成!饭也OK啦,可以米西啦!') listbox.insert(END, '') # 窗体框架 labelframe = Frame(root) # 文件夹路径 textframe = Frame(root) # 影像分辨率模式 listframe = Frame(root) # 日志提示输出 # 窗体部件 label_path = Label(labelframe, text='输入影像文件夹的路径:') text_path = Entry(labelframe) label_type = Label(textframe, text='选择影像的分辨率模式:') v=IntVar() # 定义单选按钮使用的变量 v.set('1') # 默认选择第一个 radio_big = Radiobutton(textframe, text='3368×2381', variable = v, value=1) radio_small = Radiobutton(textframe, text='2246×1588', variable = v, value=2) enter_button = Button(textframe, text=" 执行 ", command=Enter) #执行按钮 scrollbar = Scrollbar(listframe, orient=VERTICAL) listbox = Listbox(listframe, yscrollcommand=scrollbar.set, selectmode=EXTENDED) scrollbar.configure(command=listbox.yview) # 定义list并将scroll绑定上去 # 绑定回车事件到执行函数 text_path.bind("", ReturnInsert) # 绑定控件到窗体 label_path.pack(side=LEFT) text_path.pack(side=LEFT, fill=X, expand=1) label_type.pack(side=LEFT) radio_big.pack(side=LEFT) radio_small.pack(side=LEFT) listbox.pack(side=LEFT,fill=BOTH, expand=1) scrollbar.pack(side=RIGHT, fill=Y) labelframe.pack(fill=X) textframe.pack(fill=X) listframe.pack(fill=BOTH, expand=1) enter_button.pack(side=RIGHT) # 执行体 root.mainloop()
上面脚本执行没有问题,没有做严格的测试。另外用py2exe打包老是出问题,我也抑郁了。。。
-End-