subroutine greg_grid(line,error)
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>greg_grid
  !---------------------------------------------------------------------
  ! @ private
  ! Support routine for command
  !  GRID Step [/LABEL] [/ALTERNATE]
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: line   !
  logical,          intent(inout) :: error  ! Logical error flag
  ! Local
  integer(kind=4), parameter :: optalter=1  ! /ALTERNATE
  !
  if (sic_present(optalter,0)) then
    call galac(line,error)
  else
    call gridmp(line,error)
  endif
  !
end subroutine greg_grid
!
subroutine gridmp(line,error)
  use phys_const
  use gbl_message
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>gridmp
  use greg_wcs
  !---------------------------------------------------------------------
  ! @ private
  ! Support routine for command
  !  GRID Step [/LABEL]
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: line   !
  logical,          intent(inout) :: error  ! Logical error flag
  ! Global
  external :: gdraw
  ! Local
  character(len=*), parameter :: rname='GRID'
  real(kind=8), parameter :: precision=1.0d-10
  character(len=20) :: ch,steps
  character(len=80) :: chain
  real(kind=8) :: step,ra,dec,stepd
  integer(kind=4) :: i,nstep,imax,imin,nc,nra,ndec,raused,decused,ier
  real(kind=8), allocatable :: ralist(:),declist(:)
  integer(kind=4), parameter :: optlabel=2
  !
  nra = 0
  ndec = 0
  !
  steps = '15'  ! Default 15 deg
  call sic_ch(line,0,1,steps,nc,.false.,error)
  if (error)  return
  call sic_sexa(steps,nc,stepd,error)
  if (error)  return
  step = stepd*pi/180.d0
  if (step.eq.0.d0)  goto 20
  !
  ! Search for RA grid
  if (ramin.lt.0.d0) then
    imin = -int(-ramin/step)-1
  else
    imin = int(ramin/step)
  endif
  if (ramax.lt.0.d0) then
    imax = -int(-ramax/step)
  else
    imax = int(ramax/step)+1
  endif
  allocate(ralist(imax-imin+1),stat=ier)
  if (failed_allocate(rname,'RA list',ier,error))  return
  do i=imin,imax
    ra = dble(i)*step
    if (ra.le.ramin-precision .or. ra.ge.ramax+precision)  cycle
    !
    ra = max(ramin,min(ra,ramax))
    if (abs(ra-ramax).lt.precision) then
      if ((ramax-ramin-2.d0*pi).lt.precision) then
        if (gproj%type.eq.p_gnomonic .or. gproj%type.eq.p_ortho)  exit
      endif
    endif
    !
    nra = nra+1
    ralist(nra) = ra
  enddo
  !
  call gr_segm('MERIDIAN',error)
  do i=1,nra
    ra = ralist(i)
    call meridien(ra,grelocate,gdraw,error)
    if (error) then
      if (i_system.eq.type_eq .or. i_system.eq.type_ic) then
        call sexag(ch,ra,24)
        chain = 'RA '//ch
      elseif (i_system.eq.type_un) then
        write(chain,100) 'absolute X',ra*180.d0/pi
      elseif (i_system.eq.type_ga) then
        write(chain,100) 'Lii',ra*180.d0/pi
      else
        write(chain,'(A)') 'System not supported'
      endif
      call greg_message(seve%w,'GRID',chain)
      error = .false.
    endif
  enddo
  call gtsegm_close(error)
  !
20 continue
  if (sic_present(0,2)) then
    call sic_ch(line,0,2,steps,nc,.false.,error)
    if (error)  return
    call sic_sexa(steps,nc,stepd,error)
    if (error)  return
    step = stepd*pi/180.d0
  endif  ! Else step unchanged
  if (step.eq.0.d0)  return
  !
  ! Search for DEC grid
  nstep = int(pi/step)/2
  allocate(declist(2*nstep+1))
  if (failed_allocate(rname,'DEC list',ier,error))  return
  do i=-nstep,nstep
    dec = dble(i)*step
    if (dec.le.decmin-precision .or. dec.ge.decmax+precision)  cycle
    !
    dec = max(decmin,min(dec,decmax))
    !
    ndec = ndec+1
    declist(ndec) = dec
  enddo
  !
  call gr_segm('PARALLEL',error)
  do i=1,ndec
    dec = declist(i)
    call parallele(dec,grelocate,gdraw,error)
    if (error) then
      if (i_system.eq.type_un) then
        write(chain,100) 'absolute Y',dec*180.d0/pi
      elseif (i_system.eq.type_eq .or. i_system.eq.type_ic) then
        call sexag(ch,dec,360)
        chain = 'Dec '//ch
      elseif (i_system.eq.type_ga) then
        write(chain,100) 'Bii',dec*180.d0/pi
      else
        write(chain,'(A)') 'System not supported'
      endif
      call greg_message(seve%w,'GRID',chain)
      error = .false.
    endif
    !
  enddo
  call gtsegm_close(error)
  !
  if (sic_present(optlabel,0)) then
    ! Labels
    decused = min(2,ndec)  ! Put RA labels on the 2nd parallel
    do i=1,nra
      call grid_label(gproj,ralist(i),declist(decused),.true.,error)
      if (error)  return
    enddo
    raused = max(nra-1,1)  ! Put DEC labels on the before last meridian
    do i=1,ndec
      if (i.eq.decused)  cycle  ! Avoid overlapping labels
      call grid_label(gproj,ralist(raused),declist(i),.false.,error)
      if (error)  return
    enddo
  endif
  !
100 format('Spline failed at ',a,1x,f12.6)
end subroutine gridmp
!
subroutine galac(line,error)
  use gbl_message
  use phys_const
  use gwcs_types
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>galac
  use greg_wcs
  !---------------------------------------------------------------------
  ! @ private
  ! Support routine for command GRID
  !  Plot a Lii/Bii grid onto a RA-DEC plot or Vice-Versa
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: line   !
  logical,          intent(inout) :: error  !
  ! Local
  character(len=*), parameter :: rname='GRID'
  real(kind=8), parameter :: precision=1.0d-10
  real(kind=8) :: angal,xpole,ypole,gxpole,gypole,dpole
  real(kind=8) :: a1,d1
  logical :: north_up
  type(projection_t) :: oldproj
  !
  ! Check if I know what to do
  if (i_system.eq.type_un) then
    call greg_message(seve%e,rname,'System is UNKNOWN')
    error = .true.
    return
  endif
  !
  ! Check if I know how to do it
  if (gproj%type.ne.p_gnomonic  .and. gproj%type.ne.p_ortho .and.  &
      gproj%type.ne.p_azimuthal .and. gproj%type.ne.p_stereo) then
    call greg_message(seve%w,rname,'Galactic-Equatorial not supported in '//  &
    'this projection')
    return
  endif
  !
  ! Change the projection center to appropriate one in alternate system
  if (i_system.eq.type_ic) then
    call greg_message(seve%w,rname,'Can not convert to ICRS')
    return
  elseif (i_system.eq.type_eq) then
    if (i_equinox.eq.equinox_null) then
      call greg_message(seve%w,rname,  &
        'Can not convert to Equatorial system with unset equinox')
      return
    endif
    ! Galactic coordinates of projection center
    call equ_gal(gproj%a0,gproj%d0,i_equinox,a1,d1,error)
    if (error)  return
    ! Find which pole is up
    if (gproj%type.eq.p_gnomonic .or. gproj%type.eq.p_ortho) then
      north_up = lever(pi*0.5d0,d1).gt.0.d0
    else
      north_up = .true.
    endif
    ! Equatorial coordinates of Galactic pole
    if (north_up) then
      call gal_equ(0.d0,pi*0.5d0,gxpole,gypole,i_equinox,error)
    else
      call gal_equ(0.d0,-pi*0.5d0,gxpole,gypole,i_equinox,error)
    endif
    if (error)  return
  elseif (i_system.eq.type_ga) then
    ! Equatorial coordinates of projection center. Use arbitrary equinox.
    call gal_equ(gproj%a0,gproj%d0,a1,d1,i_equinox_def,error)
    if (error)  return
    ! Find which pole is up
    if (gproj%type.eq.p_gnomonic .or. gproj%type.eq.p_ortho) then
      north_up = lever(pi*0.5d0,d1).gt.0.d0
    else
      north_up = .true.
    endif
    ! Galactic coordinates of pole
    if (north_up) then
      call equ_gal(0.d0,pi*0.5d0,i_equinox_def,gxpole,gypole,error)
    else
      call equ_gal(0.d0,-pi*0.5d0,i_equinox_def,gxpole,gypole,error)
    endif
    if (error)  return
  endif
  !
  ! Relative coordinates of alternate pole
  call abs_to_rel(gproj,gxpole,gypole,xpole,ypole,1)
  dpole = sqrt(xpole**2+ypole**2)
  if (dpole.ge.precision) then
    angal = atan2(xpole,ypole)
    if (.not.north_up) angal = pi+angal
  else
    angal = 0.d0
  endif
  !
  ! Change the projection to the alternate system
  oldproj = gproj
  i_system = 5-i_system
  call gwcs_projec(a1,d1,angal,gproj%type,gproj,error)
  call setrem
  call gridmp(line,error)
  !
  ! Change back the projection to the normal system
  i_system = 5-i_system
  gproj = oldproj
  call setrem
  !
end subroutine galac
!
subroutine meridien(ra,myrelocate,mydraw,error)
  use gildas_def
  use phys_const
  use gbl_message
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>meridien
  use greg_kernel
  use greg_wcs
  !---------------------------------------------------------------------
  ! @ private
  !  Plot the meridian at a given RA
  !---------------------------------------------------------------------
  real(kind=8), intent(in)    :: ra          ! Right ascension of meridian
  external                    :: myrelocate  !
  external                    :: mydraw      !
  logical,      intent(inout) :: error       ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='MERIDIAN'
  integer(kind=size_length), parameter :: nstep=21
  real(kind=8), parameter :: precision=1.0d-10
  real(kind=8) :: x(nstep),y(nstep),z,d(nstep),a(nstep),delta1
  real(kind=8) :: y1,y2,slope,ypole,sp,tp,cp
  integer(kind=4) :: i
  !
  select case (gproj%type)
  case (p_none)
    ! No projection. Straight line from (RA,DECMIN) to (RA,DECMAX)
    call relocate(ra,guy1)
    call draw(ra,guy2)
    !
  case (p_cartesian)
    ! Meridians are straight lines from South Pole to North pole
    call abs_to_rel(gproj,ra,-pi/2.d0,x(1),y(1),1)
    call abs_to_rel(gproj,ra, pi/2.d0,x(2),y(2),1)
    call relocate(x(1),y(1))
    call draw(x(2),y(2))
    !
  case (p_gnomonic)
    ! Gnomonic : Straight line from (RA,0) to Pole
    ypole = min(gproj%spole,gproj%npole)
    if (abs(gproj%angle).le.precision) then
      if (abs(ra-gproj%a0).lt.precision) then
        call relocate(0.d0,guy1)
        call draw(0.d0,guy2)
      elseif (abs(gproj%d0)-pi*0.5d0 .ge. -precision) then
        call abs_to_rel(gproj,ra,1.d0,x(1),y(1),1)
        slope = (y(1)-ypole) / x(1)
        y1 = (gux1-x(1))*slope + y(1)
        y2 = gux2*slope + ypole
        call relocate(gux1,y1)
        call draw(gux2,y2)
      elseif (abs(gproj%d0).gt.precision) then
        call abs_to_rel(gproj,ra,0.d0,x(1),y(1),1)
        slope = (y(1)-ypole) / x(1)
        y1 = (gux1-x(1))*slope + y(1)
        y2 = gux2*slope + ypole
        call relocate(gux1,y1)
        call draw(gux2,y2)
      else
        call abs_to_rel(gproj,ra,0.d0,x(1),y(1),1)
        call relocate(x(1),guy1)
        call draw(x(1),guy2)
      endif
    else
      call abs_to_rel(gproj,ra,pi*0.25d0,x(1),y(1),1)
      call abs_to_rel(gproj,ra,pi*0.45d0,x(2),y(2),1)
      if (x(2).ne.x(1)) then
        slope = (y(2)-y(1))/(x(2)-x(1))
        y1 = (gux1-x(1))*slope + y(1)
        y2 = (gux2-x(1))*slope + y(1)
        call relocate(gux1,y1)
        call draw(gux2,y2)
      else
        call relocate(x(1),guy1)
        call draw(x(1),guy2)
      endif
    endif
    !
  case (p_ortho)
    ! Orthographic : In general these are conics
    if (abs(ra-gproj%a0).le.precision) then
      sp = sin(gproj%angle)
      cp = cos(gproj%angle)
      if (gproj%d0.ge.0.d0) then
        call relocate(-sp,-cp)
        call draw(gproj%npole*sp,gproj%npole*cp)
      else
        call relocate(-sp,-cp)
        call draw(gproj%spole*sp,gproj%spole*cp)
      endif
    elseif (abs(abs(ra-gproj%a0)-pi).le.precision) then
      sp = sin(gproj%angle)
      cp = cos(gproj%angle)
      if (gproj%d0.ge.0.d0) then
        call relocate(sp,cp)
        call draw(gproj%npole*sp,gproj%npole*cp)
      else
        call relocate(sp,cp)
        call draw(gproj%spole*sp,gproj%spole*cp)
      endif
    else
      goto 1000
    endif
    !
  case (p_azimuthal)
    ! Azimuthal (Schmidt)
    if (abs(ra-gproj%a0).le.precision) then
      sp = pi*sin(gproj%angle)
      cp = pi*cos(gproj%angle)
      call relocate(-sp,-cp)
      call draw(sp,cp)
    else
      do i=1,nstep
        d(i) = (2*i-nstep-1)*(pi*0.5d0-precision)/(nstep-1)
        a(i) = ra
      enddo
      call abs_to_rel(gproj,a,d,x,y,nstep)
      call plcurv(nstep,x,y,z,accurd,'CUBIC_SPLINE','POLYGONAL_LENGTH',.false.,  &
        myrelocate,mydraw,error)
    endif
    !
  case (p_stereo)
    ! Stereo
    if (abs(ra-gproj%a0).le.precision) then
      tp = tan(gproj%angle)
      call relocate(guy1*tp,guy1)
      call draw(guy2*tp,guy2)
    elseif (pi-abs(ra-gproj%a0).le.precision) then
      continue
    elseif (abs(0.5*pi-abs(gproj%d0)).ge.precision) then
      do i=1,nstep
        d(i) = (2*i-nstep-1)*(pi*0.5d0-precision)/(nstep-1)
        a(i) = ra
      enddo
      call abs_to_rel(gproj,a,d,x,y,nstep)
      call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','NUMBERING',.false.,  &
      myrelocate,mydraw,error)
    else
      tp = 2*max(abs(gux1),abs(gux2),abs(guy1),abs(guy2))
      cp = tp*cos(gproj%angle+ra-gproj%a0)
      sp = tp*sin(gproj%angle+ra-gproj%a0)
      call relocate(0.0d0,0.0d0)
      call draw(sp,cp)
    endif
    !
  case (p_lambert)
    ! Lambert
    if (abs(ra-gproj%a0).le.precision) then
      sp = 2.0*sin(gproj%angle)
      cp = 2.0*cos(gproj%angle)
      call relocate(-sp,-cp)
      call draw(sp,cp)
    else
      do i=1,nstep
        d(i) = (2*i-nstep-1)*(pi*0.5d0-precision)/(nstep-1)
        a(i) = ra
      enddo
      call abs_to_rel(gproj,a,d,x,y,nstep)
      call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','POLYGONAL_LENGTH',  &
      .false.,myrelocate,mydraw,error)
    endif
    !
  case (p_aitoff,p_radio)
    ! Aitoff equal area : all sky is visible
    ! Stupid radio projection : in principle also...
    if (abs(ra-gproj%a0).lt.precision) then
      sp = sin(gproj%angle)
      cp = cos(gproj%angle)
      call relocate(gproj%spole*sp,gproj%spole*cp)
      call draw(gproj%npole*sp,gproj%npole*cp)
    else
      do i=1,nstep
        d(i) = (pi*0.5d0-precision)/(nstep-1)*(2*i-nstep-1)
        a(i) = ra
      enddo
      call abs_to_rel(gproj,a,d,x,y,nstep)
      call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','NUMBERING',.false.,  &
      myrelocate,mydraw,error)
    endif
    !
  case (p_mollweide)
    ! Meridians are arcs of ellipse
    do i=1,nstep
      d(i) = (pi*0.5d0)/(nstep-1)*(2*i-nstep-1)
      a(i) = ra
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep)
    call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','POLYGONAL_LENGTH',.false.,  &
      myrelocate,mydraw,error)
    !
  case (p_ncp)
    ! Meridians are straight lines from Equator to North pole
    call abs_to_rel(gproj,ra,   0.d0,x(1),y(1),1)
    call abs_to_rel(gproj,ra,pi/2.d0,x(2),y(2),1)
    call relocate(x(1),y(1))
    call draw(x(2),y(2))
    !
  case default
    call greg_message(seve%e,rname,'Kind of projection not supported')
    error = .true.
    return
    !
  end select
  return
  !
  ! Else go from Delta1 to PI/2 or from PI/2 to -Delta1, depending
  ! on whether the North or South poles are visible.
  !
1000 continue
  if (gproj%d0.ge.0.d0) then
    delta1 = atan (cos(ra-gproj%a0)*tan(gproj%d0-pi*0.5d0))
    do i=1,nstep
      d(i) = delta1 + (pi*0.5-delta1)/(nstep-1)*(i-1)
      a(i) = ra
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep)
    call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','NUMBERING',.false.,  &
     myrelocate,mydraw,error)
  else
    delta1 = atan (cos(ra-gproj%a0)*tan(pi*0.5d0+gproj%d0))
    do i=1,nstep
      d(i) = delta1 - (pi*0.5+delta1)/(nstep-1)*(i-1)
      a(i) = ra
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep)
    call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','NUMBERING',.false.,  &
     myrelocate,mydraw,error)
  endif
  !
end subroutine meridien
!
subroutine parallele(dec,myrelocate,mydraw,error)
  use gildas_def
  use phys_const
  use gbl_message
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>parallele
  use greg_kernel
  use greg_wcs
  !---------------------------------------------------------------------
  ! @ private
  !  Draw a parallel
  !---------------------------------------------------------------------
  real(kind=8), intent(in)    :: dec         ! Declination
  external                    :: myrelocate  !
  external                    :: mydraw      !
  logical,      intent(inout) :: error       ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='PARALLEL'
  integer(kind=size_length), parameter :: nstep=21
  real(kind=8), parameter :: precision=1.0d-10
  real(kind=8) :: x(nstep),y(nstep),z,d(nstep),a(nstep)
  real(kind=8) :: h,sp,cp
  integer(kind=4) :: i
  character(len=20) :: variable
  !
  select case (gproj%type)
  case (p_none)
    ! No projection: straight lines
    call relocate(gux1,dec)
    call draw(gux2,dec)
    !
  case (p_gnomonic)
    ! Gnomonic
    variable = 'POLYGONAL_LENGTH'
    goto 1000
    !
  case (p_ortho)
    ! Orthographic
    variable = 'NUMBERING'
    goto 1000
    !
  case (p_azimuthal,p_lambert)
    ! Azimuthal and Lambert
    if (dec.eq.pi*0.5d0) then
      sp = sin(gproj%angle)*gproj%npole
      cp = cos(gproj%angle)*gproj%npole
      call relocate(sp,cp)
      call draw(sp,cp)
    elseif (dec.eq.-pi*0.5d0) then
      sp = sin(gproj%angle)*gproj%spole
      cp = cos(gproj%angle)*gproj%spole
      call relocate(sp,cp)
      call draw(sp,cp)
    else
      variable = 'POLYGONAL_LENGTH'
      if (abs(dec+gproj%d0).le.precision) then
        h = min(max((gproj%a0-ramin),(ramax-gproj%a0)),pi-1.d1*precision)
      else
        h = min(max((gproj%a0-ramin),(ramax-gproj%a0)),pi)
      endif
      if (h.ne.pi) then
        do i=1,nstep
          a(i) = gproj%a0 + (2*i-nstep-1)*h/(nstep-1)
          d(i) = dec
        enddo
        call abs_to_rel(gproj,a,d,x,y,nstep)
        call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE',variable,.false.,  &
        myrelocate,mydraw,error)
      else
        do i=1,nstep-1
          a(i) = gproj%a0 + (2*i-nstep-1)*h/(nstep-1)
          d(i) = dec
        enddo
        call abs_to_rel(gproj,a,d,x,y,nstep-1)
        x(nstep) = x(1)
        y(nstep) = y(1)
        call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','POLYGONAL_LENGTH',  &
        .true.,myrelocate,mydraw,error)
      endif
    endif
    !
  case (p_stereo)
    ! Stereographic
    if (dec.eq.pi*0.5d0) then
      sp = sin(gproj%angle)*gproj%npole
      cp = cos(gproj%angle)*gproj%npole
      call relocate(sp,cp)
      call draw(sp,cp)
    elseif (dec.eq.-pi*0.5d0) then
      sp = sin(gproj%angle)*gproj%spole
      cp = cos(gproj%angle)*gproj%spole
      call relocate(sp,cp)
      call draw(sp,cp)
    else
      variable = 'POLYGONAL_LENGTH'
      if (abs(dec+gproj%d0).le.precision) then
        h = min(max((gproj%a0-ramin),(ramax-gproj%a0)),pi-0.01d0)
        variable = 'NUMBERING'
      else
        h = min(max((gproj%a0-ramin),(ramax-gproj%a0)),pi)
      endif
      if (h.ne.pi) then
        do i=1,nstep
          a(i) = gproj%a0 + (2*i-nstep-1)*h/(nstep-1)
          d(i) = dec
        enddo
        call abs_to_rel(gproj,a,d,x,y,nstep)
        call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE',variable,.false.,  &
        myrelocate,mydraw,error)
      else
        do i=1,nstep-1
          a(i) = gproj%a0 + (2*i-nstep-1)*h/(nstep-1)
          d(i) = dec
        enddo
        call abs_to_rel(gproj,a,d,x,y,nstep-1)
        x(nstep) = x(1)
        y(nstep) = y(1)
        call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','POLYGONAL_LENGTH',  &
        .true.,myrelocate,mydraw,error)
      endif
    endif
    !
  case (p_aitoff)
    variable = 'NUMBERING'
    h = min(max((gproj%a0-ramin),(ramax-gproj%a0)),pi)
    do i=1,nstep
      a(i) = gproj%a0 + (2*i-nstep-1)*h/(nstep-1)
      d(i) = dec
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep)
    call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE',variable,.false.,myrelocate,  &
    mydraw,error)
    !
  case (p_radio)
    call abs_to_rel(gproj,gproj%a0,dec,x(1),y(1),1)
    h = pi*cos(dec)
    call relocate(x(1)-h,y(1))
    call draw(x(1)+h,y(1))
    !
  case (p_mollweide,p_cartesian)
    ! Parallels are straight lines
    call abs_to_rel(gproj,gproj%a0-pi,dec,x(1),y(1),1)
    call abs_to_rel(gproj,gproj%a0+pi,dec,x(2),y(2),1)
    call relocate(x(1),y(1))
    call draw(x(2),y(2))
    !
  case (p_ncp)
    ! Parallels are ellipsoids centered on North pole
    do i=1,nstep
      a(i) = gproj%a0 + (2*i-nstep-1)*pi/(nstep-1)
      d(i) = dec
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep)
    call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE','NUMBERING',.false.,myrelocate,  &
      mydraw,error)
    !
  case default
    call greg_message(seve%e,rname,'Kind of projection not supported')
    error = .true.
    return
    !
  end select
  return
  !
  ! Determine up time
1000 continue
  if (abs(dec).gt.0.5*pi) return
  if (0.5*pi-abs(dec).lt.precision) then
    h = lever(dec,gproj%d0)
    if (h.lt.0.d0) return
    call abs_to_rel(gproj,gproj%a0,dec,x(1),y(1),1)
    call relocate(x(1),y(1))
    call draw(x(1),y(1))
    return
  endif
  h = lever(dec,gproj%d0)
  if (h.lt.0.d0) then
    return
  elseif (h.lt.precision) then
    call abs_to_rel(gproj,gproj%a0,dec,x(1),y(1),1)
    call relocate(x(1),y(1))
    call draw(x(1),y(1))
  elseif (h.gt.pi+precision .and. ipole.ne.0) then
    do i=1,nstep-1
      a(i) = gproj%a0 + (2*i-nstep-1)*pi/(nstep-1)
      d(i) = dec
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep-1)
    x(nstep)=x(1)
    y(nstep)=y(1)
    call plcurv (nstep,x,y,z,accurd,'CUBIC_SPLINE',variable,.true.,myrelocate,  &
     mydraw,error)
  elseif (gproj%type.eq.p_gnomonic) then
    h = min(max((gproj%a0-ramin),(ramax-gproj%a0)),0.8d0*h)
    do i=1,nstep
      a(i) = gproj%a0 + (2*i-nstep-1)*h/(nstep-1)
      d(i) = dec
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep)
    call plcurv(nstep,x,y,z,accurd,'CUBIC_SPLINE',variable,.false.,myrelocate,  &
     mydraw,error)
  else
    h = min(max((gproj%a0-ramin),(ramax-gproj%a0)),h)
    do i=1,nstep
      a(i) = gproj%a0 + (2*i-nstep-1)*h/(nstep-1)
      d(i) = dec
    enddo
    call abs_to_rel(gproj,a,d,x,y,nstep)
    call plcurv(nstep,x,y,z,accurd,'CUBIC_SPLINE',variable,.false.,myrelocate,  &
     mydraw,error)
  endif
  !
end subroutine parallele
!
subroutine grid_label(proj,ra,dec,dora,error)
  use gildas_def
  use phys_const
  use greg_dependencies_interfaces
  use greg_interfaces, except_this=>grid_label
  use greg_kernel
  use greg_wcs
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  type(projection_t), intent(in)    :: proj    ! Projection description
  real(kind=8),       intent(in)    :: ra,dec  ! [rad]
  logical,            intent(in)    :: dora    ! Do RA or DEC?
  logical,            intent(inout) :: error   !
  ! Local
  real(kind=8) :: x,y,x1,x2,y1,y2,off,orien,shift,incsquare,lang
  character(len=commandline_length) :: comm
  character(len=64) :: text
  integer(kind=4) :: nc,oform
  !
  off = rad_per_sec/10.d0  ! +-0.1 arcsec to compute the tangent
  incsquare = gux*guy
  shift = 0.8d0*cdef/sqrt(abs(incsquare))  ! The label is furthered from the line by 0.8 char
  !
  if (dora) then
    ! Compute position of 2 near values along RA so that we can define
    ! the tangent
    call abs_to_rel(proj,ra,dec-off,x1,y1,1)
    call abs_to_rel(proj,ra,dec+off,x2,y2,1)
    !
    if (i_system.eq.type_eq .or. i_system.eq.type_ic) then
      call gag_cflabh(text,ra*hang_per_rad*3600d0,nc,0,format_sexage_hour,.false.)
    else  ! type_ga, type_un
      call sic_spanum(text,ra*deg_per_rad,0,oform,nc,0.d0,15,5)
    endif
    !
  else
    ! Compute position of 2 near values along DEC so that we can define
    ! the tangent
    call abs_to_rel(proj,ra-off,dec,x1,y1,1)
    call abs_to_rel(proj,ra+off,dec,x2,y2,1)
    !
    if (i_system.eq.type_eq .or. i_system.eq.type_ic) then
      call gag_cflabh(text,dec*sec_per_rad,nc,0,format_sexage_degree,.false.)
    else
      call sic_spanum(text,dec*deg_per_rad,0,oform,nc,0.d0,15,5)
    endif
    !
    !
  endif
  !
  orien = text_angle(x1,x2,y1,y2)
  if (incsquare.lt.0.d0) orien = -orien  ! Indirect trigonometric direction
  !
  ! Compute the position of the text, a bit away from its line
  call abs_to_rel(proj,ra,dec,x,y,1)
  lang = line_angle(x1,x2,y1,y2)
  x = x + shift*cos(lang)
  y = y + shift*sin(lang)
  !
  write(comm,'(A,F0.6,1X,F0.6,1X,3A,F0.4,A)')  &
    'DRAW TEXT ',x,y,'"',text(1:nc),'" 5 ',orien,' /USER RADIAN /CLIP'
  call gr_exec(comm)
  !
contains
  function line_angle(x1,x2,y1,y2)
    ! Return the angle of the line [x1,y1] to [x2,y2]
    real(kind=8) :: line_angle  ! [rad]
    real(kind=8), intent(in) :: x1,x2,y1,y2
    line_angle = modulo(atan2(y2-y1,x2-x1),pi)    ! Modulo in the range [0:pi[
    if (guy.gt.0.d0)  line_angle = line_angle-pi  ! Range [-pi:0[
  end function line_angle
  function text_angle(x1,x2,y1,y2)
    ! Return the angle so that text is perpendicular to the line
    ! [x1,y1] to [x2,y2]
    real(kind=8) :: text_angle  ! [deg]
    real(kind=8), intent(in) :: x1,x2,y1,y2
    real(kind=8) :: ang
    ang = atan2(y2-y1,x2-x1)*deg_per_rad-90.d0
    ! Modulo in the range [-90:+90[
    text_angle = modulo(ang+90.d0,180.d0)-90.d0
  end function text_angle
end subroutine grid_label
