subroutine map_center(line,task,huv,shift,newabs,error)
  use gkernel_interfaces
  use gkernel_types
  use image_def
  use gbl_message
  use imager_interfaces, only : map_message
  !---------------------------------------------------------------------
  ! @ private
  !
  ! IMAGER
  !
  ! Support for commands which can interpret MAP_CENTER-like string syntax.
  !   UV_MAP,  UV_SHIFT,  UV_DEPROJECT
  ! Decode the phase center and rotation parameters, either from
  ! the MAP_CENTER string, or (if present) from the command 
  ! line arguments.
  !
  ! The MAP_CENTER string can be specified by LET MAP_CENTER,
  !
  ! The syntax can be
  !   PosX PosY UNIT [[ANGLE] AngleValue]
  !   ANGLE AngleValue [PosX PosY UNIT]
  !---------------------------------------------------------------------
  character(len=*), intent(in) :: line     ! Command line
  character(len=*), intent(in) :: task     ! Task name
  type(gildas), intent(inout) :: huv       ! UV data set
  logical, intent(out) :: shift            ! Must shift data ?
  real(kind=8), intent(inout) :: newabs(3) ! Shifting coordinates
  logical, intent(inout) :: error          ! Error flag
  !
  real(kind=8), parameter :: pi=3.14159265358979323846d0
  real(kind=8), parameter :: sec_to_rad=pi/180d0/3600D0
  !
  type(projection_t) :: proj
  integer, parameter :: munit=6
  character(len=8) :: angle_type(munit), kunit
  character(len=32) :: argum
  real(kind=8) :: angle_scale(munit), off(2), dra, ddec, pang
  integer :: iunit, n, narg
  integer :: ikey, ira, idec, iang
  data angle_type /'ABSOLUTE','SECONDS','MINUTES','DEGREES','RADIANS','ANGLE'/
  !
  angle_scale = [0.d0,pi/180d0/3600d0,pi/180d0/60d0,pi/180d0,1.d0,pi/180d0]  
  !
  ! Decode the command line syntax
  !   COMMAND  PosX PosY UNIT [[ANGLE] AngleValue]
  !   COMMAND  ANGLE AngleValue [PosX PosY UNIT]
  !
  iang = 0
  ira = 0
  idec = 0
  ikey = 0
  !
  shift = .false.
  narg = sic_narg(0)
  !
  newabs = [huv%gil%a0,huv%gil%d0,huv%gil%pang]
  pang = huv%gil%pang
  !
  ! No argument, no shift to do...
  select case(narg)
  case (0)
    return
  case (2)    ! ANGLE Value
    call sic_ke(line,0,1,argum,n,.true.,error)
    call sic_ambigs(task,argum,kunit,iunit,angle_type(6:6),1,error)
    iang = 2
  case (3)    ! Ox Oy UNIT
    ikey = 3
    ira = 1
    idec = 2
  case (4)    ! Ox Oy UNIT ANGLE
    ikey = 3
    ira = 1
    idec = 2
    iang = 4
  case (5)    ! Two possibilities
    ! ANGLE AngVal Ox Oy UNIT
    !   or
    ! Ox Oy UNIT ANGLE AngVal
    !
    call sic_ke(line,0,1,argum,n,.true.,error)
    if (argum(1:1).ne.'A') then
      call sic_ke(line,0,4,argum,n,.true.,error)
      if (argum(1:1).ne.'A') error = .true.
      iang = 5
      ira = 1
      idec = 2
      ikey = 3
    else
      iang = 2
      ira = 3
      idec = 4
      ikey = 5
    endif
    if (.not.error) then
      call sic_ambigs(task,argum,kunit,iunit,angle_type(6:6),1,error)
    endif
    !
  case default
    error = .true.
  end select 
  if (error) then
    call map_message(seve%e,task,'Invalid syntax '//trim(line))
    return
  endif
  !
  ! Angle
  if (iang.ne.0) then
    call sic_r8(line,0,iang,pang,.true.,error) 
    if (error) return
    ! 
    pang = pang*angle_scale(munit)
    if (abs(pang-huv%gil%pang).le.sec_to_rad) then
      shift = .false.
      pang = huv%gil%pang
    else
      shift = .true.
    endif
  endif
  !
  if (ikey.ne.0) then
    call sic_ke(line,0,ikey,argum,n,.true.,error)
    if (error) return
    call sic_ambigs(task,argum,kunit,iunit,angle_type,5,error)
    if (error) return
    !
    if (kunit.eq.'ABSOLUTE') then
      call sic_ch(line,0,ira,argum,n,.true.,error)
      call sic_decode(argum,dra,24,error)
      if (error) then
        call map_message(seve%e,task,'Input conversion error on RA phase center '//argum)
        return
      endif
      call sic_ch(line,0,idec,argum,n,.true.,error)
      call sic_decode(argum,ddec,360,error)
      if (error) then
        call map_message(seve%e,task,'Input conversion error on Dec phase center '//argum)
        return
      endif
      newabs(1) = dra
      newabs(2) = ddec
    else
      call sic_r8(line,0,ira,off(1),.true.,error)
      call sic_r8(line,0,idec,off(2),.true.,error)
      off = off*angle_scale(iunit)
      ! Projection 
      call gwcs_projec(huv%gil%a0,huv%gil%d0,huv%gil%pang,huv%gil%ptyp,proj,error)
      call rel_to_abs (proj,off(1),off(2),newabs(1),newabs(2),1)
    endif
    !
    shift = .true.
    !
  endif
  !
  newabs(3) = pang
  !
  call print_change_header('MAP_CENTER', huv, newabs, shift)
  !
end subroutine map_center
!
subroutine print_change_header(task,huv,newabs,shift)
  use image_def
  use gkernel_interfaces, only : rad2sexa
  use imager_interfaces, only : map_message
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !   IMAGER
  ! Debugging routine
  !---------------------------------------------------------------------  
  character(len=*), intent(in) :: task
  type(gildas), intent(in) :: huv
  real(kind=8), intent(in) :: newabs(3)
  logical, intent(in) :: shift
  !
  character :: cra*14, cdec*14, cang*8
  real(8), parameter :: pi=acos(-1d0)
  !
  call rad2sexa(huv%gil%a0,24,cra)
  call rad2sexa(huv%gil%d0,360,cdec)
  write (cang,'(F8.2)') huv%gil%pang*180./pi
  call map_message(seve%i,task,'Old projection '//cra//cdec//cang)
  call rad2sexa(newabs(1),24,cra)
  call rad2sexa(newabs(2),360,cdec)
  write (cang,'(F8.2)') newabs(3)*180./pi
  call map_message(seve%i,task,'New projection '//cra//cdec//cang)
  if (newabs(3).ne.huv%gil%pang) then
    call map_message(seve%i,task,'Rotation to new angle '//cang)
  else
    call map_message(seve%i,task,'No incremental rotation')
  endif
  !
end subroutine print_change_header
!
!
subroutine map_query (line,task,map,goon,error) 
  use gbl_message
  use gkernel_interfaces
  use gkernel_types
  use image_def
  use clean_arrays
  use clean_default
  !---------------------------------------------------------------------
  ! @ private
  !
  ! Support for commands
  !   UV_MAP ?
  !     Display the imaging parameters
  ! or
  !   UV_MAP 
  !     Set the arguments for the phase center and rotation parameters
  !     if MAP_CENTER is not empty
  !---------------------------------------------------------------------
  character(len=*), intent(inout) :: line  ! Command line
  character(len=*), intent(in) :: task  ! Task name
  type(uvmap_par), intent(in) :: map    ! Mapping parameters 
  logical, intent(inout) :: goon        ! Continue or Return after ?
  logical, intent(inout) :: error       ! Error flag
  !
  character(len=1), parameter :: question_mark='?'
  !
  integer :: narg,nline,n,i,nlast,nopt,nt,nm
  character(len=32) :: argum,comm,topic
  character(len=128) :: string, chain
  !
  narg = sic_narg(0)
  goon = .true.
  !
  narg = sic_narg(0) 
  if (narg.gt.0) then
    ! Check the special ? argument
    call sic_ch(line,0,1,argum,nm,.false.,error)
    if (argum(1:1).eq.question_mark) then
      if (sic_present(0,2)) then
        call sic_ch(line,0,2,topic,nt,.true.,error)
        chain = 'HELP '//task//topic
      else
        chain = "@ i_uv_map "//argum
      endif
      call exec_program(chain)
      goon = .false.
    else if (narg.eq.2) then
      call sic_ch(line,0,2,argum,nm,.false.,error)
      if (argum(1:1).eq.question_mark) then
        call sic_ch(line,0,1,topic,nt,.true.,error)
        chain = 'HELP '//task//topic
        call exec_program(chain)
        goon = .false.
      endif    
    endif
  else if (narg.eq.0) then
    !
    ! Reset the command line if MAP_CENTER is non null
    call sic_get_char('MAP_CENTER',string,n,error)
    if (n.eq.0) return
    !
    call sic_upper(string)
    nopt = sic_mopt()
    nline = len_trim(line)
    nlast = nline
    do i=1,nopt
      if (sic_present(i,0)) then
        nlast = min(nlast,sic_start(i,0))
      endif
    enddo
    if (nlast.ne.nline)  then
      line = line(1:nlast-1)//trim(string)//line(nlast-1:)
    else
      nline = nline+2 ! Skip a space
      line(nline:) = string
    endif
    nline = len_trim(line)
    call sic_analyse(comm,line,nline,error)
  endif
end subroutine map_query
