自动影像库配准程序

看到生产部竟然派专人开始折腾影像图,我真的要吐血了。。。 

 

#!/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-

posted @ 2009-11-16 16:47  听风  阅读(420)  评论(0编辑  收藏  举报