戻る
気象庁CD(月報)からのアメダス読みだし
(Fortran90)
read_amedas.f90 プログラムのダウンロード
Subject: アメダスデータ読みだしソフト
Date: Fri, 22 May 2009 19:29:13 +0900
研究室の皆さん、特に薛君
玉川です。薛君の学会発表にむけて、今アメダスデータを読んでいると思いますが、
読みだしのソフトを書いてみました。
急いで書いているので、何かバグがあるかも知れませんが、
一応、動いているようなので、送ります。
添付のソフト read_amedas.f90 を
どこかにおいて、そこに、データCDの amedas フォルダを
コピーしてください。
そして、read_amedas.f90 をコンパイルして
./a.out > datafile
と動かすと、若干のメッセージの後に
year, month, day, hour
と聞かれますから、必要な 年月日をいれてください。
(もちろん 2007 8 まではこれしかないですが)
そうすると datafile に
write(*,*) find, pnum(i), lat(i), lon(i), windsp, winddir, temp, prec, sun
でメッセージが書かれます。
find : 1 しかないはず
pnum(i) : 地点番号
lat(i) : latitude
lon(i): longitude
windsp : 風速 (m/s)
winddir : 風向 (0-360度) 0 が北,90度が東
temp : 気温
prec : 雨量
sun : 日照
です。
若干注意して使ってください。
この出力を加工すれば、GMTで図が書けると思います。
例えば
awk '{print $4, $3, $5, $6}' < datafile > datafile2
で、lon lat windsp winddir のデータが並ぶ出力が datafile2 に
得られると思います。
P.S. バグってたら直してください。
--------------------------------------------------------------------------------
〒 501-1193 岐阜市柳戸1-1
岐阜大学 流域圏科学研究センター
玉川一郎 (e-mail: tama@green.gifu-u.ac.jp)
phone/fax 兼用: 058-293-2430
WWW: http://tama.green.gifu-u.ac.jp/~tama
--------------------------------------------------------------------------------
! maybe ....
! bt I. Tamagawa 2009 May
implicit none
integer, parameter :: maxpoint = 20000
integer :: pnum(maxpoint), windtemp(maxpoint), pointnum
real :: lat(maxpoint), lon(maxpoint)
character(len=1024) :: amdmaster, datafile
integer :: i, find
integer :: year, month, day, hour
real :: windsp, winddir, temp, prec, sun
amdmaster = 'amedas/amdmaster.index'
write(0,*) trim(amdmaster)
! read madmaster.index
call readindex( amdmaster, pnum, lat, lon, windtemp, maxpoint, pointnum)
write(0,*) 'read ', trim(amdmaster), pointnum
call select_newest( pnum, lat, lon, windtemp, maxpoint, pointnum)
write(0,*) 'select last record for each point', pointnum
write(0,*) 'year, month, day, hour'
read(*,*) year, month, day, hour
do i=1, pointnum
write(datafile, "('amedas/hourly/',i0.4, i0.2,'/area',i0.2,'/ah',i0.5,'_', i0.4, i0.2,'.csv')") &
year, month, &
int(pnum(i)/1000), pnum(i), year, month
! write(*,*) datafile
if( windtemp(i) == 1 ) then
call readdata( datafile, year, month, day, hour, windsp, winddir, temp, prec, sun, find )
if(find == 1 ) then
write(*,*) find, pnum(i), lat(i), lon(i), windsp, winddir, temp, prec, sun
end if
end if
end do
end
subroutine readindex( amdmaster, pnum, lat, lon, windtemp, maxpoint, pointnum)
character(len=*) :: amdmaster
integer :: maxpoint, pointnum
integer :: pnum(maxpoint), windtemp(maxpoint)
real :: lat(maxpoint), lon(maxpoint)
integer :: lat1, lon1
real :: lat2, lon2
integer :: ios=0
integer :: count = -2 ! skip first 2 line
character(len=1024) :: buf
integer :: prec, windspeed, temp, sunshine, snow_depth
open( file=trim(amdmaster), &
status='old', unit = 10, err = 900 )
write(0,*) 'open ', trim(amdmaster)
do while(ios == 0 )
read(10,'(a)', iostat=ios ) buf
count = count +1
! write(0,*) count
if( count > maxpoint) then
write(0,*) ' Too many data, change maxpoint'
stop
end if
! write(0,*) count, 'QQ: ', buf
if( count > 0 ) then
! write(0,*) count, buf(1:5), ':', buf(75:90)
read(buf(1:5), '(i5)') pnum(count)
read(buf(75:90), * ) lat1, lat2, lon1, lon2
lat(count) = lat1 + lat2/60.0
lon(count) = lon1 + lon2/60.0
read(buf(103:112), *) prec, windspeed, temp, sunshine, snow_depth
if( windspeed == 1 .AND. temp == 1 ) then
windtemp(count) = 1
else
windtemp(count) = 0
endif
end if
!write(0,*) count, buf(103:112)
! write(0,*) count, pnum(count), lat(count), lon(count), &
! prec, windspeed, temp, sunshine, snow_depth
end do
pointnum = count
close(10)
! write(0,*) trim(buf)
return
900 write(0,*) 'Can not open ', amdmaster
stop
end
subroutine select_newest( pnum, lat, lon, windtemp, maxpoint, pointnum)
integer :: pointnum
integer :: pnum(maxpoint), windtemp(maxpoint)
real :: lat(maxpoint), lon(maxpoint)
integer :: i, j
j=1
do i=2, pointnum
if( pnum(i) /= pnum(i-1) ) then
j=j+1
end if
! write(0,*) 'i,j', i, j
pnum(j) = pnum(i)
lat(j) = lat(i)
lon(j) = lon(i)
windtemp(j) = windtemp(i)
end do
write(0,*) pointnum, '==>', j
pointnum = j
end
subroutine readdata( datafile, year, month, day, hour, windsp, winddir, temp, prec, sun, find )
implicit none
character(len=*) :: datafile
integer :: year, month, day, hour
real :: windsp, winddir, temp, prec, sun
character(len=1024) :: buf
integer :: i, ios=0
integer :: dday, dhour, dpfl, dwdfl, dwsfl
real :: dprec, dwinddir, dwindsp, dtemp, dsun
integer :: dtfl, dsfl
integer :: find
find = 0
open( file = datafile, unit = 20, status='old', err = 999 )
do i=1,4 ! skip 4 lines
read(20,'(a)') buf
end do
do while( ios== 0 )
read(20, *, iostat = ios, end=910) dday, dhour, dprec, dpfl, dwinddir, dwdfl, dwindsp, dwsfl, &
dtemp, dtfl, dsun, dsfl
write(0,*) dday, dhour, dprec, dwinddir, dwindsp, dtemp, dsun
if( dday == day .AND. dhour == hour ) then
! write(*,*) 'FIND!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
windsp = dwindsp
! 16: N,
if(dwinddir /= 16 ) then
winddir = (dwinddir)*(360.0/16.0)
else
winddir = 0
end if
temp = dtemp
prec = dprec
sun = dsun
find = 1
close(20)
return
goto 910
end if
end do
910 close(20)
if(find == 0 ) then
write(0,*) 'Can not find data'
windsp = -9999 ; winddir = -9999 ; temp = -9999 ; prec = -9999 ; sun = -9999
stop
endif
return
999 write(0,*) 'Can not open ', datafile
windsp = -9999 ; winddir = -9999 ; temp = -9999 ; prec = -9999 ; sun = -9999
end