爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 6842|回复: 6

[混合编程] 网格点插值站点循环多个时次

[复制链接]

新浪微博达人勋

发表于 2016-1-11 20:51:39 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
此程序为网格点数据插值到站点,一个时次。
请大神指点在哪里加循环,改为4个时次的循环


  1. !   双线性插值,格点到站点,考虑权重  !
  2. !      modifioed from    mofangbao(清风) by djj!   

  3. !===================================================!
  4. program bilineargird2stn
  5. integer,parameter::oldx=97,oldy=61    !格点数据xy向网格点数
  6. integer,parameter::newxy=1308          !站点数
  7. integer,parameter::time=4    !时间层次
  8. real,parameter::oldLon_start=100.0,oldLat_start=20.0,oldInterpx=0.25,oldInterpy=0.25  !格点数据起始经纬度和格距
  9. real oldVal(oldx,oldy),newVal(newxy),newPoint(newxy,2)  !分别是:格点数据,站点数据,站点数据经纬度,newVal的点顺序和nowPoint中的对应
  10. character*8 ::stid
  11. integer::i,j,k
  12. logical isFirst   !判断是否第一个时次
  13. isFirst=.true.      !后面无需手动修改此值,程序会自动修改


  14. !!读取站点经纬度
  15. open(27,file='C:\PCGrADS\win32\st1308-2.txt')
  16. do i=1,newxy
  17.     read(27,*) stid,newPoint(i,2),newPoint(i,1)  !先经度后纬度
  18. enddo
  19. close(27)


  20. !!读取网格点数据
  21. open(29,file='C:\PCGrADS\win32\24cma2015081619.grib',form='binary')
  22. read(29)  ((oldVal(i,j),i=1,oldx),j=1,oldy)
  23. close(29)


  24. !do k=1,4
  25. !!调用插值程序,这里只哟一个时次,因此没有循环
  26. call getNewVal(oldVal,newVal,oldLon_start,oldLat_start,oldInterpx,oldInterpy,newPoint,isFirst)
  27. open(25,file='C:\PCGrADS\win32\grid2stn.txt')
  28. do i=1,newxy
  29. write(25,*) newVal(i)
  30. enddo
  31. end




  32. subroutine getNewVal(oldVal,newVal,oldLon_start,oldLat_start,oldInterpx,oldInterpy,newPoint,isFirst)
  33. integer,parameter::oldx=97,oldy=61,newxy=1308
  34. real::oldLon_strat,oldLat_strat
  35. real,parameter::undef=-999.0  
  36. real::oldInterpx,oldInterpy      
  37. integer pos(newxy,4),nstart,nend  !weight 1,2是左侧点和右侧点的分别权重,3,4是下面点和上面点分别的权重
  38. real tmpVal_up,tmpVal_down !本次纬向下方和纬向上方的线性插值结果以及权重
  39. real::weight(newxy,4)
  40. real newLon,newLat,weight_end  !本次插值的新点位置,以及返回的权重
  41. real oldVal(oldx,oldy),newVal(newxy),newPoint(newxy,2)  !旧值,新值,新点经纬度
  42. logical isfirst  !是否第一个时次,只有第一个时次需要计算四周格点分布以及权重,后面的套用即可

  43. if(isfirst)then
  44. !获取新点的四周的点以及每个点的权重
  45. do i=1,newxy
  46.   newLon=newPoint(i,1)

  47. ! print*,newLon,oldLon_start
  48.   call getPosAndWeight(newLon,oldLon_start,nstart,nend,weight_end,oldInterpx,isFirst)
  49.   !print*,newLon,nstart,nend,weight_end
  50.   if(nend>oldx)then
  51.     if(nstart==oldx)then
  52.       pos(i,1)=nstart
  53.       pos(i,2)=nstart
  54.       weight(i,1)=1
  55.       weight(i,2)=0
  56.     else
  57.       pos(i,1)=-1
  58.       pos(i,2)=-1  !超出了原来格点的范围,标记为无效值
  59.       weight(i,1)=-1
  60.       weight(i,2)=-1
  61.     endif
  62.   else
  63.     pos(i,1)=nstart
  64.     pos(i,2)=nend
  65.     weight(i,1)=1-weight_end
  66.     weight(i,2)=weight_end
  67.   endif

  68. !print*, pos(i,1),pos(i,2)
  69. !write(*,*) weight(i,1),weight(i,2)


  70.   newLat=newPoint(i,2)
  71. ! write(*,*) newLat,oldLat_start
  72.   call getPosAndWeight(newLat,oldLat_start,nstart,nend,weight_end,oldInterpy,isFirst)

  73.   if(nend>oldy)then
  74.     if(nstart==oldy)then
  75.       pos(i,3)=nstart
  76.       pos(i,4)=nstart
  77.       weight(i,3)=1
  78.       weight(i,4)=0
  79.     else
  80.       pos(i,3)=-1
  81.       pos(i,4)=-1  !超出了原来格点的范围,标记为无效值
  82.       weight(i,3)=-1
  83.       weight(i,4)=-1
  84.     endif
  85.   else
  86.     pos(i,3)=nstart
  87.     pos(i,4)=nend
  88.     weight(i,3)=1-weight_end
  89.     weight(i,4)=weight_end
  90.   endif

  91. !print*, pos(i,3),pos(i,4)
  92. !write(*,*) weight(i,3),weight(i,4)  
  93. !pause   
  94. enddo
  95. endif



  96. !开始插值
  97. do i=1,1308
  98.   if(pos(i,1)<0 .or.pos(i,3)<0)then
  99.     newval(i)=-999.0
  100.   else
  101.     !先做纬向插值
  102.     if(pos(i,1)==undef .or. pos(i,2)==undef .or. pos(i,3)==undef .or. pos(i,4)==undef)then
  103.       newVal(i)=-9999.0
  104.     else
  105.       if(oldVal(pos(i,1),pos(i,3))>0.and.oldVal(pos(i,2),pos(i,3))>0) tmpVal_down=weight(i,1)*oldVal(pos(i,1),pos(i,3))+weight(i,2)*oldVal(pos(i,2),pos(i,3))
  106.       if(oldVal(pos(i,1),pos(i,3))>0.and.oldVal(pos(i,2),pos(i,3))<0) tmpVal_down=oldVal(pos(i,1),pos(i,3))
  107.       if(oldVal(pos(i,1),pos(i,3))<0.and.oldVal(pos(i,2),pos(i,3))>0) tmpVal_down=oldVal(pos(i,2),pos(i,3))
  108.       if(oldVal(pos(i,1),pos(i,3))<0.and.oldVal(pos(i,2),pos(i,3))<0) tmpVal_down=-999.0
  109.       if(oldVal(pos(i,1),pos(i,4))>0.and.oldVal(pos(i,2),pos(i,4))>0) tmpVal_up=weight(i,1)*oldVal(pos(i,1),pos(i,4))+weight(i,2)*oldVal(pos(i,2),pos(i,4))
  110.       if(oldVal(pos(i,1),pos(i,4))<0.and.oldVal(pos(i,2),pos(i,4))>0) tmpVal_up=oldVal(pos(i,2),pos(i,4))
  111.       if(oldVal(pos(i,1),pos(i,4))>0.and.oldVal(pos(i,2),pos(i,4))<0) tmpVal_up=oldVal(pos(i,1),pos(i,4))
  112.       if(oldVal(pos(i,1),pos(i,4))<0.and.oldVal(pos(i,2),pos(i,4))<0) tmpVal_up=-999.0
  113.       if(tmpVal_down>0.and.tmpVal_up>0) then
  114.         newVal(i)=weight(i,3)*tmpVal_down+weight(i,4)*tmpVal_up
  115.       else if(tmpVal_down>0.and.tmpVal_up<0) then
  116.         newVal(i)=tmpVal_down
  117.       else if(tmpVal_down<0.and.tmpVal_up>0) then
  118.         newVal(i)=tmpVal_up
  119.       else
  120.         newVal(i)=-999.0
  121.       endif
  122.     endif
  123.   endif
  124. enddo


  125. open(25,file='C:\PCGrADS\win32\weight.txt')
  126. do i=1,1308
  127. write(25,*) weight(i,:)
  128. enddo
  129. close(25)
  130. endsubroutine

  131. !计算某个方向的两侧的点以及后侧点(上方点)的权重
  132. subroutine  getPosAndWeight(newPos,oldstart,nstart,nend,weight,oldInterp,isfirst)
  133. integer nstart,nend  !两侧点
  134. real newPos,weight,oldInterp
  135. real oldstart   
  136. logical isfirst
  137. !离的近的点权重大,但是占的距离比重小,所以权重=1-距离比重,经纬度从0开始,但是标号从1开始,所以加1
  138. print*,newPos,oldstart,oldInterp
  139. nstart=int((newPos-oldstart)/oldInterp)+1
  140. nend=nstart+1
  141. weight=(newPos-(nstart-1)*oldInterp-oldstart)/oldInterp  !  |---|-------|  此表达式计算的是后一段的权重(前一段的距离比重),该段总长为interp
  142. isfirst=.false.
  143. endsubroutine
复制代码


Source1.f90

5.3 KB, 阅读权限: 30, 下载次数: 11, 下载积分: 金钱 -5

程序

密码修改失败请联系微信:mofangbao

新浪微博达人勋

0
早起挑战累计收入
发表于 2016-1-11 20:57:03 | 显示全部楼层
这个。。。让别人花钱给你解决问题,也是醉了。。。如果楼主是想奖励帮助你的人,应该发悬赏帖
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2016-1-11 21:27:58 | 显示全部楼层
mofangbao 发表于 2016-1-11 20:57
这个。。。让别人花钱给你解决问题,也是醉了。。。如果楼主是想奖励帮助你的人,应该发悬赏帖

原谅我吧,第一次发帖。我是想奖励帮助我的人,可是也不知道怎么弄。还麻烦大神帮我看一下,谢谢
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-3-8 20:23:49 | 显示全部楼层
没数据,没办法进行
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2016-5-7 14:26:02 | 显示全部楼层
不错   支持!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2020-7-27 17:14:21 | 显示全部楼层
楼主你好,最近也在做格点插值站点,请问问题解决了吗
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2020-7-27 17:35:05 | 显示全部楼层
加一个时间循环吧
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表