なお、次元変数の複製は copyfrom と url が異なるファイルに
載っている場合に行なわれる。これは netCDF/an を想定したものだが
ほかのファイル形式が追加されたときには変更を要するかもしれない。
subroutine GTVarCreateCopyC(var, url, copyfrom, copyvalue, overwrite, err)
implicit none
intrinsic trim
type(GT_VARIABLE), intent(out) :: var
character(len = *), intent(in) :: url
type(GT_VARIABLE), intent(inout) :: copyfrom
logical, intent(in), optional :: copyvalue
logical, intent(in), optional :: overwrite
logical, intent(out), optional :: err
type(GT_VARIABLE), allocatable :: vDimSource(:)
type(GT_VARIABLE), allocatable :: vDimDest(:)
integer :: i, nd, stat
logical :: myerr
character(STRING) :: vpart, upart, desturl
character(TOKEN) :: xtype
continue
call beginsub('gtvarcreatecopy', 'url=%c copyfrom=%d', c1=trim(url), i=(/copyfrom%mapid/))
stat = 0
myerr = .FALSE.
!-----------------------------------------------------------------
! コピーする変数の次元をコピー先のファイルに作成
!-----------------------------------------------------------------
!----- コピー元 copyfrom の次元変数の取得 -----
call Inquire(copyfrom, alldims=nd)
allocate(vDimSource(nd), vDimDest(nd), stat=stat)
if (stat /= 0) goto 999
desturl = url
!----- コピー元 copyfrom の各次元情報を vDimSource に取り出し, -----
!----- それをコピー先 desturl へコピーしてその次元 ID を -----
!----- vDimDest に返してもらう. -----
do, i = 1, nd
call Open(vDimSource(i), copyfrom, dimord=i, count_compact=.TRUE., err=myerr)
call GTVarCopyDim(to=vDimDest(i), from=vDimSource(i), target=desturl)
end do
!-----------------------------------------------------------------
! 変数作成
!-----------------------------------------------------------------
!----- url に変数名が無い場合, コピー元の変数名を使用 -----
call UrlSplit(url, var=vpart)
if (vpart == "") then
call Inquire(copyfrom, url=upart)
call UrlSplit(upart, var=vpart)
desturl = trim(desturl) // GT_ATMARK // trim(vpart)
end if
!----- 実際に変数作成 -----
call Inquire(copyfrom, xtype=xtype)
call Create(var, trim(desturl), dims=vDimDest, xtype=xtype, overwrite=overwrite, err=myerr)
if (myerr) goto 990
call copy_attr(to=var, from=copyfrom, err=myerr)
if (myerr) goto 990
if (present(copyvalue)) then
if (copyvalue) then
call GTVarCopyValue(to=var, from=copyfrom)
endif
endif
do, i = 1, nd
call Close(vDimSource(i))
call Close(vDimDest(i))
end do
990 continue
deallocate(vDimSource, vDimDest, stat=stat)
999 continue
if (stat /= 0) then
call StoreError(GT_ENOMEM, "GTVarCreateCopy", err)
else if (present(err)) then
err = myerr
else if (myerr) then
call DumpError
end if
call endsub('gtvarcreatecopy', 'result=%d', i=(/var%mapid/))
contains
! from と同じ内容の次元変数を URL target で示される変数の作成時に
! 次元として使えるように to に複写。
! なるべく再オープンで済まそうとする。
! 複写する場合もなるべく次元名を合わせようとする。
!
subroutine GTVarCopyDim(to, from, target)
type(GT_VARIABLE), intent(out):: to
type(GT_VARIABLE), intent(inout):: from
character(len = *), intent(in):: target
character(len = string):: url, file, dimname
character(len = token):: xtype
logical:: growable, myerr
integer:: length
call beginsub('gtvarcopydim', 'from=%d target=<%c>', i=(/from%mapid/), c1=trim(target))
!----- 同じファイル上にコピーする場合は参照カウンタを1つ回すだけ -----
call Inquire(var=from, url=url)
if (trim(url) .onthesamefile. trim(target)) then
call Open(to, from, dimord=0)
call endsub('gtvarcopydim', 'dup-handle')
return
endif
!----- 異なるファイル上にコピーする場合, 既に次元変数 from が -----
!----- target の次元変数として含まれるかチェック -----
call UrlSplit(target, file=file)
if (LookupEquivalent(to, from, file)) then
!----- 含まれる場合はそれで終了 -----
call endsub('gtvarcopydim', 'equivalent-exists')
return
else
!----- 含まれない場合次元変数 from を target 上に作成 -----
! 次元変数 from が無制限次元である場合には長さを 0 に
call Inquire(var=from, growable=growable, allcount=length)
if (growable) length = 0
call Inquire(var=from, xtype=xtype, name=dimname)
!
url = urlmerge(file, dimname)
call Create(to, trim(url), length, xtype, err=myerr)
if (myerr) then
! 指定名称でうまくいかない場合は自動生成名にする
call Create(to, trim(file), length, xtype)
endif
call copy_attr(to, from, myerr)
call GTVarCopyValue(to, from)
call endsub('gtvarcopydim', 'created')
return
endif
end subroutine