爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 5913|回复: 10

[求助] 坐标转换

[复制链接]

新浪微博达人勋

发表于 2012-4-29 16:46:04 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 godenflame135 于 2012-4-29 23:34 编辑

想问一下我这个程序中输入相同纬度,不同经度时,为什么转换的结果 r 不相同呢?是程序写的有错误吗?

  • program cal_r

  • implicit none
  • character       :: grid
  • real                 ::    lat,  lon,  r,s
  • real,external    ::    ezlh_convert

  • write(*,*) ezlh_convert('Nl', 80., 10., r, s)
  •       write(*,*) r,s
  • end
  •      
  • function ezlh_convert(grid, lat, lon, r, s)
  • character*(*) grid
  • real lat, lon, r, s
  • !
  • ! convert geographic coordinates (spherical earth) to
  • ! azimuthal equal area or equal area cylindrical grid coordinates
  • !
  • ! status = ezlh_convert (grid, lat, lon, r, s)
  • !
  • ! input : grid - projection name '[NSM][lh]'
  • !               where l = "low"  = 25km resolution
  • !                     h = "high" = 12.5km resolution
  • !  lat, lon - geo. coords. (decimal degrees)
  • !
  • ! output: r, s - column, row coordinates
  • !
  • ! result: status = 0 indicates normal successful completion
  • !   -1 indicates error status (point not on grid)
  • !
  • !--------------------------------------------------------------------------
  •       integer cols, rows, scale
  • real Rg, phi, lam, rho
  • ! radius of the earth (km), authalic sphere based on International datum
  • parameter (RE_km = 6371.228)
  • ! nominal cell size in kilometers
  • parameter (CELL_km = 25.067525)
  • ! scale factor for standard paralles at +/-30.00 degrees
  • parameter (COS_PHI1 = .866025403)
  • parameter (PI = 3.141592653589793)
  • rad(t) = t*PI/180.
  • deg(t) = t*180./PI
  • ezlh_convert = -1
    if ((grid(1:1).eq.'N').or.(grid(1:1).eq.'S')) then
  •    cols = 721
  •    rows = 721
  • else if (grid(1:1).eq.'M') then
  •    cols = 1383
  •    rows = 586
  • else
  •    print *, 'ezlh_convert: unknown projection: ', grid
  •    return
  • endif
  • if (grid(2:2).eq.'l') then
  •    scale = 1
  • else if (grid(2:2).eq.'h') then
  •    scale = 2
  • else
  •    print *, 'ezlh_convert: unknown projection: ', grid
  •    return
  • endif
  •         Rg = scale * RE_km/CELL_km
    !
  • ! r0,s0 are defined such that cells at all scales
  • ! have coincident center points
  • !
  •         r0 = (cols-1)/2. * scale
  •         s0 = (rows-1)/2. * scale
  • phi = rad(lat)
  •         lam = rad(lon)
  • if (grid(1:1).eq.'N') then
  •    rho = 2 * Rg * sin(PI/4. - phi/2.)
  •    r = r0 + rho * sin(lam)
  •    s = s0 + rho * cos(lam)
  • else if (grid(1:1).eq.'S') then
  •    rho = 2 * Rg * cos(PI/4. - phi/2.)
  •    r = r0 + rho * sin(lam)
  •    s = s0 - rho * cos(lam)
  •         else if (grid(1:1).eq.'M') then
  •           r = r0 + Rg * lam * COS_PHI1
  •           s = s0 - Rg * sin(phi) / COS_PHI1
  • endif
    ezlh_convert = 0
  • return
  • end


  • 纬度40,经度10的时候结果是397.30444 ,571.5638

    纬度80,经度10的时候结果是367.6932,403.6304

    纬度90,经度10的时候结果是360.000,360.000
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

    发表于 2012-4-29 20:12:46 | 显示全部楼层

    回帖奖励 +1 金钱

    提醒一下,论坛支持语法加亮等功能,贴代码的时候能用一下更便于别人阅读~
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

     楼主| 发表于 2012-4-29 20:30:15 | 显示全部楼层

    哦~谢谢!我暂时还不太了解论坛的功能,以后注意
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

     楼主| 发表于 2012-4-29 22:23:12 | 显示全部楼层
    问题解决了啊~~
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

    发表于 2012-4-29 22:27:55 | 显示全部楼层
    水草 发表于 2012-4-29 22:23
    问题解决了啊~~

    怎么解决的呢,发上来大家一起学习一下呗
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

    发表于 2012-4-29 23:50:39 | 显示全部楼层
    水草 发表于 2012-4-29 20:30
    哦~谢谢!我暂时还不太了解论坛的功能,以后注意

    已高显!
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

    发表于 2012-4-29 23:58:12 | 显示全部楼层
    水草 发表于 2012-4-29 22:23
    问题解决了啊~~

    怎么解决的,说说?
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

     楼主| 发表于 2012-4-30 12:40:59 | 显示全部楼层
    topmad 发表于 2012-4-29 22:27
    怎么解决的呢,发上来大家一起学习一下呗

    我上面那个程序是想把地理坐标转化成格点坐标,这样转化的结果是格点会出现小数,取舍很麻烦,无法准确的找出需要的格点,所以我那个思路就是错的!正确的思路应该是把格点坐标先转化成地理坐标,然后把在需要的地理区域的格点挑出来,我说的是不是很混乱?
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

     楼主| 发表于 2012-4-30 12:45:00 | 显示全部楼层
    godenflame135 发表于 2012-4-29 23:58
    怎么解决的,说说?

    这个程序本身是没有错的,但我这个思路是错的。应该是先把格点坐标转化成地理坐标,再选择需要的格点数据
    密码修改失败请联系微信:mofangbao

    新浪微博达人勋

     楼主| 发表于 2012-4-30 12:57:01 | 显示全部楼层
    这是北半球EASE-grid的格点坐标转化成地理坐标的程序
    [code] implicit none
          character grid
            integer a
            real r,s,lat,lon
            real,external::ezlh_inverse
          open(2,file='E:\geo.txt')
          open(3,file='E:\selectedgrid.txt')
            do r=1,721
              do s=1,721
              a=ezlh_inverse ('Nl', r, s, lat, lon)
              write(2,*) lat,lon
              if(lat>=40.0)then
                if(lon>=10.0.and.lon<=140.0)then
              write(3,*) r,s
                end if
              end if
              end do
            end do
            close(2)
            close(3)
            end
            function ezlh_inverse (grid, r, s, lat, lon)
            character*(*) grid
            real r, s, lat, lon
    C
    C        convert azimuthal equal area or equal area cylindrical
    C        grid coordinates to geographic coordinates (spherical earth)
    C
    C        status = ezlh_inverse (grid, r, s, lat, lon)
    C
    C        input : grid - projection name '[NSM][lh]'
    C               where l = "low"  = 25km resolution
    C                     h = "high" = 12.5km resolution
    C                r, s - grid column and row coordinates
    C
    C        output: lat, lon - geo. coords. (decimal degrees)
    C
    C        result: status = 0 indicates normal successful completion
    C                        -1 indicates error status (point not on grid)
    C
    C--------------------------------------------------------------------------
            integer cols, rows, scale
            real Rg, phi, lam, rho
            real gamma, beta, epsilon, x, y
            real sinphi1, cosphi1

    C        radius of the earth (km), authalic sphere based on International datum
            parameter (RE_km = 6371.228)
    C        nominal cell size in kilometers
            parameter (CELL_km = 25.067525)

    C       scale factor for standard paralles at +/-30.00 degrees
            parameter (COS_PHI1 = .866025403)

            parameter (PI = 3.141592653589793)
            rad(t) = t*PI/180.
            deg(t) = t*180./PI

            ezlh_inverse = -1

            if ((grid(1:1).eq.'N').or.(grid(1:1).eq.'S')) then
              cols = 721
              rows = 721
            else if (grid(1:1).eq.'M') then
              cols = 1383
              rows = 586
            else
              print *, 'ezlh_inverse: unknown projection: ', grid
              return
            endif

            if (grid(2:2).eq.'l') then
              scale = 1
            else if (grid(2:2).eq.'h') then
              scale = 2
            else
              print *, 'ezlh_inverse: unknown projection: ', grid
              return
            endif

            Rg = scale * RE_km/CELL_km

            r0 = (cols-1)/2. * scale
            s0 = (rows-1)/2. * scale

            x = r - r0
            y = -(s - s0)

            if ((grid(1:1).eq.'N').or.(grid(1:1).eq.'S')) then
              rho = sqrt(x*x + y*y)
              if (rho.eq.0.0) then
                if (grid(1:1).eq.'N') lat = 90.0
                if (grid(1:1).eq.'S') lat = -90.0
                lon = 0.0
              else
                if (grid(1:1).eq.'N') then
                  sinphi1 = sin(PI/2.)
                  cosphi1 = cos(PI/2.)
                  if (y.eq.0.) then
                    if (r.le.r0) lam = -PI/2.
                    if (r.gt.r0) lam = PI/2.
                  else
                    lam = atan2(x,-y)
                  endif
                else if (grid(1:1).eq.'S') then
                  sinphi1 = sin(-PI/2.)
                  cosphi1 = cos(-PI/2.)
                  if (y.eq.0.) then
                    if (r.le.r0) lam = -PI/2.
                    if (r.gt.r0) lam = PI/2.
                  else
                    lam = atan2(x,y)
                  endif
                     endif
                gamma = rho/(2 * Rg)
                if (abs(gamma).gt.1.) return
                c = 2 * asin(gamma)
                beta = cos(c) * sinphi1 + y * sin(c) * (cosphi1/rho)
                if (abs(beta).gt.1.) return
                phi = asin(beta)
                lat = deg(phi)
                lon = deg(lam)
              endif

            else if (grid(1:1).eq.'M') then
    C
    C          allow .5 cell tolerance in arcsin function
    C          so that grid coordinates which are less than .5 cells
    C          above 90.00N or below 90.00S are given a lat of 90.00
    C
              epsilon = 1 + 0.5/Rg
              beta = y*COS_PHI1/Rg
              if (abs(beta).gt.epsilon) return
              if (beta.le.-1.) then
                phi = -PI/2.
              else if (beta.ge.1.) then
                phi = PI/2.
              else
                phi = asin(beta)
              endif
              lam = x/COS_PHI1/Rg
              lat = deg(phi)
              lon = deg(lam)
            endif

            ezlh_inverse = 0
            return
            end[code]
    密码修改失败请联系微信:mofangbao
    您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

    本版积分规则

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

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

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