예제 #1
0
def pic2data(pathname,region,factor = 'CR'):
    try:
        '''各区域对应图例坐标、左上角、右下角经纬度'''
        '''图片分辨率改变时修改这里的图例位置'''
        region_all={'AECN':(523,537,597,793,113.506,38.8444,124.2670,23.1044), #华东
                    'ACCN':(722,333,798,589,103.626,35.3322,120.005,24.0566), #华中
                    'ACHN':(948,613,1021,869,65.6571,46.4849,126.862,13.061),#全国
                    'ANCN':(725,5  ,799,261,104.643,43.0878,122.636,31.1917), #华北
                    'ANEC':(723,564,797,820,114.539,54.224,131.91,36.3301), #东北
                    'ABCJ':(884,98 ,955,348,96.4697,34.7539,126.494,25.0003), #长江流域
                    'ABHH':(692,250,757,499,107.015,40.9176,123.65,30.4626), #黄淮流域
                    'ACES':(721,537,789,789,103.491,35.7671,128.508,13.2104), #东南沿海
                    'ASCN':(725,338,791,589,104.654,27.6771,121.318,16.104), #华南
                    'ANWC':(749,6  ,1017,255,65.4922,43.212,109.31,29.4932),#西北
                    'ASWC':(727,10 ,791,218,96.1597,34.8143,112.812,20.7235)  #西南
                    }
        #'R','CR'的颜色
        if factor in ['R','CR']:
            '''R & CR'''
            colors={(1, 160, 246, 255):12.5,
                    (0, 216, 0, 255):22.5,
                    (255, 0, 240, 255):62.5,
                    (231, 192, 0, 255):37.5,
                    (214, 0, 0, 255):52.5,
                    (192, 0, 0, 255):57.5,
                    (173, 144, 240, 255):72.5,
                    (150, 0, 180, 255):67.5,
                    (0, 236, 236, 255):17.5,
                    (255, 144, 0, 255):42.5,
                    (255, 0, 0, 255):47.5,
                    (1, 144, 0, 255):27.5,
                    (255, 255, 0, 255):32.5}
        #'''VIL的颜色'''
        elif factor == 'VIL':
            colors={(1, 255, 0, 255):12.5,
                    (0, 200, 0, 255):17.5,
                    (255, 0, 240, 255):57.5,
                    (231, 192, 0, 255):32.5,
                    (214, 0, 0, 255):47.5,
                    (192, 0, 0, 255):52.5,
                    (173, 144, 240, 255):72.5,
                    (0, 236, 236, 255):8.5,
                    (120, 0, 132, 255):67.5,
                    (255, 144, 0, 255):37.5,
                    (255, 0, 0, 255):42.5,
                    (216, 0, 156, 255):62.5,
                    (255, 255, 0, 255):27.5,
                    (1, 144, 0, 255):22.5}
        #'''OHP的颜色'''
        elif factor == 'OHP':
            colors={(255, 0, 240, 255):112.5, #100-125
                    (214, 0, 0, 255):69, #63-75
                    (192, 0, 0, 255):87.5,#75-100
                    (173, 144, 240, 255):130, #130-
                    (0, 236, 236, 255):17.5, #10-25
                    (255, 144, 0, 255):44, #38-50
                    (255, 0, 0, 255):56.5, #50-63
                    (0, 0, 246, 255):2.5, #0-5
                    (255, 255, 0, 255):31.5, #25-38
                    (1, 160, 246, 255):7.5} #5-10
        '''河流、行政边界、文字的颜色'''
        word_color=[(104, 104, 104, 255),
                    #(253, 255, 254, 255),
                    (204, 204, 204, 255),
                    (190, 232, 255, 255),
                    (156, 156, 156, 255),
                    (130, 130, 130, 255)]
        
        '''打开文件'''
        img_src = Image.open(pathname)
        img_size=img_src.size
        region_del=region_all[region]
        #定义和图片大小一致的0矩阵
        image_value=np.zeros((img_size[0],img_size[1]))
        src_strlist = img_src.load()
        '''获取格点数据,没有数据为0,河流、行政区域、文字数据为1'''
        for i in range(0,img_size[0],1):
            for j in range(0,img_size[1],1):
                if src_strlist[i,j] in colors: #是否有数据
                    image_value[i,j]=colors[src_strlist[i,j]]
                elif src_strlist[i,j] in word_color: #是否是河流等
                    image_value[i,j]=1
                else: #是不需要的点
                    image_value[i,j]=0
        '''找到图例并填充为0'''
        image_value[region_del[0]:region_del[2],region_del[1]:region_del[3]]=0
        
        '''对河流、文字、行政边界的点进行插值'''
        image_out=np.copy(image_value)
        for i in range(0,img_size[0],1):
            for j in range(0,img_size[1],1):
                #判断是否为河流等点
                if image_value[i,j]==1:
                    sum_value=0  #周围所有有效点的值的和
                    count_1=0    #附近河流等点的个数
                    count_0=0    #附近无效点的个数
                    count_c=0    #附近数据点的个数
                    #取该点周围8各点进行判断
                    for n in [(i-1,j-1),(i-1,j  ),(i-1,j+1),
                              (i  ,j-1),          (i  ,j+1),
                              (i+1,j-1),(i+1,j  ),(i+1,j+1)]:
                        if image_value[n] > 1:
                            count_c += 1
                            sum_value += image_value[n]
                        elif image_value[n] == 1:
                            count_1 += 1
                        else:
                            count_0 += 1
                    #周围没有数据点,且有无效点
                    if count_c == 0 and count_0 > 0:
                        image_out[i,j]=0
                    #有数据点
                    elif count_c >0:
                        try:
                            #数据点占多数
                            if count_c / count_0 > 0.5:
                                image_out[i,j]=sum_value/count_c
                            #数据点占少数
                            elif count_c / count_0 <= 0.5:
                                image_out[i,j]=0
                        #无效点个数可能为0
                        except ZeroDivisionError: 
                            image_out[i,j]=sum_value/count_c
                    #数据点和无效点都没有
                    elif count_1 == 8:
                        #判断再往外的一层
                        for n in [(i-2,j-2),(i-2,j-1),(i-2,j  ),(i-2,j+1),(i-2,j+2),
                                  (i-1,j-2)                              ,(i-1,j+2),
                                  (i  ,j-2)                              ,(i  ,j+2),
                                  (i+1,j-2)                              ,(i+1,j+2),
                                  (i+2,j-2),(i+2,j-1),(i+2,j  ),(i+2,j+1),(i+2,j+2)]:
                            if image_value[n] > 1:
                                count_c += 1
                                sum_value += image_value[n]
                            elif image_value[n] == 1:
                                count_1 += 1
                            else:
                                count_0 += 1
                        #没有数据点
                        if count_c == 0:
                            image_out[i,j]=0
                        #有数据点
                        elif count_c >0:
                            try:
                                #数据点占多数
                                if count_c / count_0 > 0.5:
                                    image_out[i,j]=sum_value/count_c
                                #数据点占少数
                                elif count_c / count_0 <= 0.5:
                                    image_out[i,j]=0
                            #无效点个数可能为0
                            except ZeroDivisionError: 
                                image_out[i,j]=sum_value/count_c
        '''坐标处理'''
        #转置
        image_out=np.transpose(image_out)
        #颠倒y
        image_out=image_out[::-1]
        #得到经纬度转换后的原始网格对应的经纬度信息
        lon,lat=get_latlon(region)    
        #生成离散点数据
        out_index=np.argwhere(image_out > 0)
        out_all=np.zeros((len(out_index),3))

        out_all[:,0]=lat[out_index[:,0],out_index[:,1]]
        out_all[:,1]=lon[out_index[:,0],out_index[:,1]]
        out_all[:,2]=image_out[out_index[:,0],out_index[:,1]]
        #返回坐标转换后的经纬度对应的数据
        return out_all
    #如果有问题则返回空list
    except:
        return []
예제 #2
0
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
region_all=['AECN', #华东
            'ACCN', #华中
#            'ACHN',#全国
            'ANCN', #华北
            'ANEC', #东北
            'ABCJ', #长江流域
            'ABHH', #黄淮流域
            'ACES', #东南沿海
            'ASCN', #华南
            'ANWC',#西北
            'ASWC'  #西南
            ]
lon,lat=get_latlon('ACHN')
#获取图像中的经纬度极值范围
#lon_min=np.min(lon)
#lon_max=np.max(lon)
#lat_min=np.min(lat)
#lat_max=np.max(lat)
dlon=0.04
dlat=0.04
lon_min = 108
lon_max = 132
lat_min = 20
lat_max = 40
#lon_min=latlon_domain[1]
#lon_max=latlon_domain[3]
#lat_min=latlon_domain[0]
#lat_max=latlon_domain[2]
예제 #3
0
def write_latlon(picfile,datafile):
    #从文件路径中提取关键字
    name=picfile.split('/')[-1]
    factor=name.split('_')[-2]
    region=name.split('_')[-1][0:4]
    datatime=name.split('_')[4]
    #生成输出文件名
    outname='MOP_'+region+'_'+'factor'+'_'+datatime+'.latlon'
    #获取全国地图的经纬度网格
    lon,lat=get_latlon('ACHN')
    #获取图像中的经纬度极值范围,生成0.04间隔的等经纬度网格
    lon_min1=int(np.min(lon)*100)//4/25
    lon_max1=int(np.max(lon)*100)//4/25 +0.04
    lat_min1=int(np.min(lat)*100)//4/25
    lat_max1=int(np.max(lat)*100)//4/25 +0.04
    #生成0.04格距的网格
    grid_x, grid_y = np.mgrid[lon_min1:lon_max1+0.04:0.04, lat_min1:lat_max1+0.04:0.04]
    #生成网格对应的空数据
    grid_z1=np.zeros([np.shape(grid_x)[0],np.shape(grid_x)[1]])
    #获得图像中对应的网格点的数值
    out_all=pic2data(picfile)
    #如果返回空集合,则返回1退出
    if out_all==[]:
        return 1
    #放大系数
    fdxs=10
    #乘以放大系数
    out_all[:,2]=out_all[:,2]*fdxs
    try:
        # In[] 打开文件读取latlon文件
        with open (datafile,'rb+') as f:
            #从256个字节开始往后读数据
            f.seek(256)
            #获得文件中头文件以外的数据大小
            datasize=os.path.getsize(datafile)-256
            #读取数据
            context1=f.read(datasize)
            #获取有数值的点的信息
            yxn=struct.unpack('h'*int(datasize/2),context1)
            #初始判断符为0
            panduan=0
            #读取原始latlon文件中数据,挨个读取yxn的数值并写入grid_z1中
            for i in yxn:
                #panduan为0则该值为y
                if panduan==0:
                    y=i
                    panduan+=1
                    continue
                #panduan为0则该值为x
                elif panduan==1:
                    x=i
                    panduan+=1
                    continue
                #panduan为0则该值为n
                elif panduan==2:
                    n0=0
                    n=i
                    panduan+=1
                    continue
                #panduan为0则该值为数值
                elif panduan==3:
                    grid_z1[x+n0,y]=i
                    n0+=1
                    if n0==n:
                        panduan=0
                    continue
            #将新的区域的数据写入latlon中
            for i in out_all:
                grid_z1[int(round((i[1]-lon_min1)/0.04)),
                            int(round((i[0]-lat_min1)/0.04))]=i[2]
            image_out=grid_z1
            #生成latlon文件数据
            out=[]
            for y in range(0,np.shape(grid_z1)[1],1): #y
                ifFirst=True
                for x in range(0,np.shape(grid_z1)[0],1):
                    if image_out[x,y] > 0:
                        if ifFirst:
                            if x!=np.shape(grid_z1)[0]-1:
                                ifFirst=False
                                out_tmp=[]
                                count=1
                                out_tmp.extend([image_out[x,y]])
                            else:
                                out.extend([y,x,1])
                                out.extend([image_out[x,y]])
                        else:
                            if x!=np.shape(grid_z1)[0]-1:
                                out_tmp.extend([image_out[x,y]])
                                count+=1
                            else:
                                out_tmp.extend([image_out[x,y]])
                                count+=1
                                out.extend([y,x-count+1,count])
                                out.extend(out_tmp)
                    elif image_out[x,y]==0 and not ifFirst:
                        out.extend([y,x-count,count])
                        out.extend(out_tmp)
                        ifFirst=True
            #加入结束判断符
            out.extend([-1,-1,-1])
            #将out转成二进制
            for i in out:
                try:
                    data_b+=struct.pack('h',int(i))
                except NameError:
                    data_b=struct.pack('h',int(i))
            #删除256以后的值
            f.truncate(256)
            #从256开始写入新的数据
            f.seek(256)
            f.write(data_b)
            return 0
    #不存在原始文件
    except FileNotFoundError:
        # In[]将新的区域的数据写入latlon中
        for i in out_all:
            grid_z1[int(round((i[1]-lon_min1)/0.04)),
                        int(round((i[0]-lat_min1)/0.04))]=i[2]   
        image_out=grid_z1
        #生成文件
        out=[]
        for y in range(0,np.shape(grid_z1)[1],1): #y
            ifFirst=True
            for x in range(0,np.shape(grid_z1)[0],1):
                if image_out[x,y] > 0:
                    if ifFirst:
                        if x!=np.shape(grid_z1)[0]-1:
                            ifFirst=False
                            out_tmp=[]
                            count=1
                            out_tmp.extend([image_out[x,y]])
                        else:
                            out.extend([y,x,1])
                            out.extend([image_out[x,y]])
                    else:
                        if x!=np.shape(grid_z1)[0]-1:
                            out_tmp.extend([image_out[x,y]])
                            count+=1
                        else:
                            out_tmp.extend([image_out[x,y]])
                            count+=1
                            out.extend([y,x-count+1,count])
                            out.extend(out_tmp)
                elif image_out[x,y]==0 and not ifFirst:
                    out.extend([y,x-count,count])
                    out.extend(out_tmp)
                    ifFirst=True   
        #加入结束判断符
        out.extend([-1,-1,-1])
        #将out转成二进制
        for i in out:
            try:
                data_b+=struct.pack('h',int(i))
            except NameError:
                data_b=struct.pack('h',int(i))
        
        # In[]'''生成文件头'''
        
        
        dataname= outname.encode('utf-8')+b'\x00'*(128-len(outname))
        varname =factor.encode('utf-8')+ b'\x00'*(32-len(factor))
        char    ='dBZ'.encode('utf-8')+ b'\x00'*(16-len('dBZ'))
        label   = 0 #unsigned short
        unitlen = 2 #short
        slat=lat_min1 #float
        wlon=lon_min1#float
        nlat=lat_max1#float
        elon=lon_max1#float
        clat=(slat+nlat)/2#float
        clon=(wlon+elon)/2#float
        rows=np.shape(grid_z1)[1] #	int
        cols=np.shape(grid_z1)[0] #	int
        dlat=0.04 #float
        dlon=0.04 #float
        nodata=0.0 #float
        levelbytes =0  #long
        levelnum=0 #short
        amp= fdxs #short
        compmode =1 #short 
        dates = 0 #unsigned short
        seconds= 0 #int
        min_value =  0 #short
        max_value =  0 #short
        #reserved = 
#        head =dataname + varname + char +struct.pack('Hh6f2i3fq3hHi2h6h', label,unitlen,slat,wlon,nlat,
#                                                     elon,clat,clon,rows,cols,0.04,0.04,nodata,
#                                                     levelbytes,levelnum,amp,compmode,
#                                                     dates,seconds,min_value,max_value,
#                                                     0,0,0,0,0,0);
        head =dataname + varname + char +struct.pack('Hh6f2i3fi3hHi2h6h', label,unitlen,slat,wlon,nlat,
                                                     elon,clat,clon,rows,cols,dlat,dlon,nodata,
                                                     levelbytes,levelnum,amp,compmode,
                                                     dates,seconds,min_value,max_value,
                                                     0,0,0,0,0,0);
        # In[] '''存储'''
        
        all_out=head+data_b
        #将二进制数据写入文件
        with open(datafile, 'wb') as f:
            f.write(all_out)
        return 0
예제 #4
0
def write_latlon(picfile, datafile):
    name = picfile.split('/')[-1]
    factor = name.split('_')[-2]
    region = name.split('_')[-1][0:4]
    datatime = name.split('_')[4]
    outname = 'MOP_' + region + '_' + 'factor' + '_' + datatime + '.latlon'
    lon, lat = get_latlon('ACHN')
    #获取图像中的经纬度极值范围,生成0.04间隔的等经纬度网格
    lon_min1 = int(np.min(lon) * 100) // 4 / 25
    lon_max1 = int(np.max(lon) * 100) // 4 / 25 + 0.04
    lat_min1 = int(np.min(lat) * 100) // 4 / 25
    lat_max1 = int(np.max(lat) * 100) // 4 / 25 + 0.04
    #生成0.04格距的网格
    grid_x, grid_y = np.mgrid[lon_min1:lon_max1 + 0.04:0.04,
                              lat_min1:lat_max1 + 0.04:0.04]
    #处理
    grid_z1 = np.zeros([np.shape(grid_x)[0], np.shape(grid_x)[1]])
    out_all = pic2data(picfile)
    if out_all == []:
        return 1

    try:
        with open(datafile, 'rb+') as f:
            f.seek(260)
            datasize = os.path.getsize(datafile) - 260
            context1 = f.read(datasize)
            yxn = struct.unpack('h' * int(datasize / 2), context1)
            panduan = 0
            for i in yxn:
                if panduan == 0:
                    y = i
                    panduan += 1
                    continue
                elif panduan == 1:
                    x = i
                    panduan += 1
                    continue
                elif panduan == 2:
                    n0 = 0
                    n = i
                    panduan += 1
                    continue
                elif panduan == 3:
                    grid_z1[x + n0, y] = i
                    n0 += 1
                    if n0 == n:
                        panduan = 0
                    continue
            for i in out_all:
                grid_z1[int(round((i[1] - lon_min1) / 0.04)),
                        int(round((i[0] - lat_min1) / 0.04))] = i[2]
            image_out = grid_z1
            #生成文件
            out = []
            for y in range(0, np.shape(grid_z1)[1], 1):  #y
                ifFirst = True
                for x in range(0, np.shape(grid_z1)[0], 1):
                    if image_out[x, y] > 0:
                        if ifFirst:
                            if x != np.shape(grid_z1)[0] - 1:
                                ifFirst = False
                                out_tmp = []
                                count = 1
                                out_tmp.extend([image_out[x, y]])
                            else:
                                out.extend([y, x, 1])
                                out.extend([image_out[x, y]])
                        else:
                            if x != np.shape(grid_z1)[0] - 1:
                                out_tmp.extend([image_out[x, y]])
                                count += 1
                            else:
                                out_tmp.extend([image_out[x, y]])
                                count += 1
                                out.extend([y, x - count + 1, count])
                                out.extend(out_tmp)
                    elif image_out[x, y] == 0 and not ifFirst:
                        out.extend([y, x - count, count])
                        out.extend(out_tmp)
                        ifFirst = True
            out.extend([-1, -1, -1])
            for i in out:
                try:
                    data_b += struct.pack('h', int(i))
                except NameError:
                    data_b = struct.pack('h', int(i))
            f.truncate(260)
            f.seek(260)
            f.write(data_b)
            return 0

    except FileNotFoundError:
        for i in out_all:
            grid_z1[int(round((i[1] - lon_min1) / 0.04)),
                    int(round((i[0] - lat_min1) / 0.04))] = i[2]
        image_out = grid_z1
        #生成文件
        out = []
        for y in range(0, np.shape(grid_z1)[1], 1):  #y
            ifFirst = True
            for x in range(0, np.shape(grid_z1)[0], 1):
                if image_out[x, y] > 0:
                    if ifFirst:
                        if x != np.shape(grid_z1)[0] - 1:
                            ifFirst = False
                            out_tmp = []
                            count = 1
                            out_tmp.extend([image_out[x, y]])
                        else:
                            out.extend([y, x, 1])
                            out.extend([image_out[x, y]])
                    else:
                        if x != np.shape(grid_z1)[0] - 1:
                            out_tmp.extend([image_out[x, y]])
                            count += 1
                        else:
                            out_tmp.extend([image_out[x, y]])
                            count += 1
                            out.extend([y, x - count + 1, count])
                            out.extend(out_tmp)
                elif image_out[x, y] == 0 and not ifFirst:
                    out.extend([y, x - count, count])
                    out.extend(out_tmp)
                    ifFirst = True
        out.extend([-1, -1, -1])
        for i in out:
            try:
                data_b += struct.pack('h', int(i))
            except NameError:
                data_b = struct.pack('h', int(i))

        # In[]
        '''生成文件头'''

        dataname = outname.encode('utf-8') + b'\x00' * (128 - len(outname))
        varname = factor.encode('utf-8') + b'\x00' * (32 - len(factor))
        char = 'dBZ'.encode('utf-8') + b'\x00' * (16 - len('dBZ'))
        label = 0  #unsigned short
        unitlen = 2  #short
        slat = lat_min1  #float
        wlon = lon_min1  #float
        nlat = lat_max1  #float
        elon = lon_max1  #float
        clat = (slat + nlat) / 2  #float
        clon = (wlon + elon) / 2  #float
        rows = np.shape(grid_z1)[1]  #	int
        cols = np.shape(grid_z1)[0]  #	int
        #dlat float
        #dlon float
        nodata = 0.0  #float
        levelbytes = 0  #long
        levelnum = 0  #short
        amp = 0  #short
        compmode = 1  #short
        dates = 0  #unsigned short
        seconds = 0  #int
        min_value = 0  #short
        max_value = 0  #short
        #reserved =
        #        head =dataname + varname + char +struct.pack('Hh6f2i3fq3hHi2h6h', label,unitlen,slat,wlon,nlat,
        #                                                     elon,clat,clon,rows,cols,0.04,0.04,nodata,
        #                                                     levelbytes,levelnum,amp,compmode,
        #                                                     dates,seconds,min_value,max_value,
        #                                                     0,0,0,0,0,0);
        head = dataname + varname + char + struct.pack(
            'Hh6f2i3fq3hHi2h6h', label, unitlen, slat * 1000, wlon * 1000,
            nlat * 1000, elon * 1000, clat * 1000, clon * 1000, rows, cols,
            0.04 * 1000, 0.04 * 1000, nodata, levelbytes, levelnum, amp,
            compmode, dates, seconds, min_value, max_value, 0, 0, 0, 0, 0, 0)
        # In[]
        '''存储'''
        all_out = head + data_b
        with open(datafile, 'wb') as f:
            f.write(all_out)
        return 0