Viewing contents of file '../idllib/contrib/buie/digit.pro'
;+
; NAME:
; digit
; PURPOSE: (one line)
; Digitize from a displayed gif file.
; DESCRIPTION:
; CATEGORY:
; Image display
; CALLING SEQUENCE:
; digit, image, outfile
; INPUTS:
; image : Image to be displayed. May be a string scalar containing the
; name of a GIF file to be loaded and displayed, or an image
; array to be displayed.
; outfile : File into which collected points are saved.
; OPTIONAL INPUT PARAMETERS:
; KEYWORD INPUT PARAMETERS:
; NATURAL = If set, the natural screen coordinates are used. No
; control points are solicited and no coordinate
; transformations are computed.
; NOSCALE = If set, the image is displayed without being scaled.
; ROTATE = Rotation angle (in degrees) for the gif image. Allowed
; values are 90, 180, and 270 counterclockwise.
; OUTPUTS:
; KEYWORD OUTPUT PARAMETERS:
; XVEC, YVEC = If both of these keywords are present, the collected
; coordinates are returned as vectors to the variables
; specified in the keywords. The collected coordinates are
; always written to the output file.
; COMMON BLOCKS:
; SIDE EFFECTS:
; RESTRICTIONS:
; PROCEDURE:
; Unless the 'NATURAL' keyword is specified, four control points and four
; associated values are requested in order to define the x and y axes and
; scale factors.
; The first two points are the x-axis control points (and their values) and
; the second two are the y-axis control points (and their values).
; Control vectors are computed from the requested control points and
; coordinate transformations are computed using simple vector algebra.
; MODIFICATION HISTORY:
; Written by Doug Loucks, Lowell Observatory, April, 1993.
; 94/10/04 - MWB - moved cr to front of print statement (v3.6 bug workaround)
;-
PRO digit, image, outfile, NATURAL=natural, NOSCALE=noscale, ROTATE=in_angle, $
XVEC=xvec, YVEC=yvec
; Check for required parameters.
IF N_PARAMS() NE 2 THEN BEGIN
MESSAGE, 'digit, image, outfile', /INFO
RETURN
ENDIF
image_size = SIZE( image )
IF image_size[0] EQ 0 AND image_size[1] EQ 7 THEN BEGIN
; Parameter is a scalar string. If the file exists, load it into a local
; variable.
IF NOT exists( image ) THEN BEGIN
MESSAGE, 'File ' + image + ' does not exist.', /INFO
RETURN
ENDIF
read_gif, image, l_image
type = 7
ENDIF ELSE BEGIN
; Parameter should be an array of rank 2.
IF badpar( image, [1,2,3,4,5], 2, CALLER='% DIGIT: (image) ', $
TYPE=type ) THEN RETURN
ENDELSE
; Check the output file name.
IF outfile EQ '' OR outfile EQ ' ' THEN BEGIN
MESSAGE, 'outfile parameter must be non-blank.', /INFO
RETURN
ENDIF
; Define a few ASCII control characters.
bel = STRING( 7B )
cr = STRING( 13B )
lf = STRING( 10B )
; Initialize the coordinate vectors.
xvec = [ 0.0 ]
yvec = [ 0.0 ]
IF type EQ 7 THEN BEGIN
; The image parameter is a scalar string containing a GIF filename.
image_size = SIZE( l_image )
ENDIF ELSE BEGIN
image_size = SIZE( image )
ENDELSE
wsize = FLOAT( [ !d.x_size, !d.y_size ] )
IF KEYWORD_SET( in_angle ) THEN angle=in_angle ELSE angle=0
CASE angle OF
90 : BEGIN
isize = [ image_size[2], image_size[1] ]
direction = 1
END
180 : BEGIN
isize = [ image_size[1:2] ]
direction = 2
END
270 : BEGIN
isize = [ image_size[2], image_size[1] ]
direction = 3
END
ELSE : BEGIN
isize = [ image_size[1:2] ]
direction = 0
END
ENDCASE
sf = MIN( wsize / FLOAT(isize) )
;PRINT, 'Scale factor: ', sf
; Display the image.
nscale = KEYWORD_SET( noscale )
CASE nscale OF
0 : BEGIN
; Display the image, scaled to fit into the IDL draw window.
IF type EQ 7 THEN BEGIN
; Image parameter is a string scalar containing a GIF filename. The
; file was loaded into a local image array.
TVSCL,CONGRID( ROTATE(l_image,direction), isize[0]*sf, isize[1]*sf, $
/INTERP )
ENDIF ELSE BEGIN
; Image parameter is an image array.
TVSCL,CONGRID( ROTATE(image,direction), isize[0]*sf, isize[1]*sf, $
/INTERP )
ENDELSE
END
1 : BEGIN
; Display the image without scaling.
IF type EQ 7 THEN BEGIN
; Image parameter is a string scalar containing a GIF filename. The
; file was loaded into a local image array.
TVSCL, ROTATE( l_image, direction )
ENDIF ELSE BEGIN
; Image parameter is an image array.
TVSCL, ROTATE( image, direction )
ENDELSE
END
ENDCASE
IF NOT KEYWORD_SET( natural ) THEN BEGIN
; Coordinate transformations will be computed.
; Ask for the x-axis control points and their associated values.
!mouse.button = 0
WHILE !mouse.button NE 1 DO BEGIN
PRINT, 'First x-axis control point (left=accept, right=exit).' + bel
CURSOR, xa1, ya1, WAIT=3, /DEVICE
IF !mouse.button EQ 4 THEN RETURN
ENDWHILE
READ, '... x-value for this point>' + bel, x1
PRINT, ''
!mouse.button = 0
WHILE !mouse.button NE 1 DO BEGIN
PRINT, 'Second x-axis control point (left=accept, right=exit).' + bel
CURSOR, xa2, ya2, WAIT=3, /DEVICE
IF !mouse.button EQ 4 THEN RETURN
ENDWHILE
READ, '... x-value for this point>' + bel, x2
PRINT, ''
; Compute the x-axis control vectors and magnitudes.
va1 = [ xa2-xa1, ya1-ya1 ]
vb1 = [ xa2-xa2, ya2-ya1 ]
vc1 = va1 + vb1
;
magva1 = SQRT( TOTAL( va1*va1 ) )
magvb1 = SQRT( TOTAL( vb1*vb1 ) )
magvc1 = SQRT( TOTAL( vc1*vc1 ) )
; Compute the x-axis scale factor.
sx = ( x2-x1 ) / magvc1
; Ask for the y-axis control points and their associated values.
!mouse.button = 0
WHILE !mouse.button NE 1 DO BEGIN
PRINT, 'First y-axis control point (left=accept, right=exit).' + bel
CURSOR, xb1, yb1, WAIT=3, /DEVICE
IF !mouse.button EQ 4 THEN RETURN
ENDWHILE
READ, '... y-value for this point>' + bel, y1
PRINT, ''
!mouse.button = 0
WHILE !mouse.button NE 1 DO BEGIN
PRINT, 'Second y-axis control point (left=accept, right=exit).' + bel
CURSOR, xb2, yb2, WAIT=3, /DEVICE
IF !mouse.button EQ 4 THEN RETURN
ENDWHILE
READ, '... y-value for this point>' + bel, y2
PRINT, ''
; Compute the y-axis control vectors and magnitudes.
va2 = [ xb2-xb1, yb2-yb2 ]
vb2 = [ xb1-xb1, yb2-yb1 ]
vc2 = va2 + vb2
magva2 = SQRT( TOTAL( va2*va2 ) )
magvb2 = SQRT( TOTAL( vb2*vb2 ) )
magvc2 = SQRT( TOTAL( vc2*vc2 ) )
; Compute the y-axis scale factor.
sy = ( y2-y1 ) / magvc2
ENDIF
PRINT, 'Left mouse button enters points, middle button enters a blank line.'
PRINT, '... right mouse button to exit.'
ON_ERROR, 2
fmt = "($,a,'x=',G20.4,4X,'y=',G20.4)"
; Begin the main loop for tracking the mouse cursor and collecting the points.
npts = 0
!mouse.button = 0
WHILE !mouse.button NE 4 DO BEGIN
; Track the cursor position in device coordinates.
CURSOR, xm, ym, 2, /DEVICE
IF KEYWORD_SET( natural ) THEN BEGIN
; Use actual device coordinates.
x = xm
y = ym
ENDIF ELSE BEGIN
; Compute the coordinates from the coordinate transformation vectors.
va = [ xm-xa1, ya1-ya1 ]
magva = SQRT( TOTAL( va*va ) )
magvb = magva * ( magvb1 / magva1 )
vb = [ xm-xm, magvb ]
v = va + vb
magv = SQRT( TOTAL( v*v ) )
IF xm-xa1 LT 0 THEN x=x1-(sx*magv) ELSE x=x1+(sx*magv)
vb = [ xb1-xb1, ym-yb1 ]
magvb = SQRT( TOTAL( vb*vb ) )
magva = magvb * ( magva2 / magvb2 )
va = [ magva, ym-ym ]
v = vb + va
magv = SQRT( TOTAL( v*v ) )
IF ym-yb1 LT 0 THEN y=y1-(sy*magv) ELSE y=y1+(sy*magv)
ENDELSE
IF !mouse.button eq 1 or !mouse.button eq 2 THEN BEGIN
; Left (or middle) mouse button pressed.
IF !mouse.button EQ 1 THEN BEGIN
; Left mouse button pressed.
; Save the position into the output file and move to a new print line.
PRINT, lf, x, y, FORMAT=fmt
GET_LUN, lu
OPENW, lu, outfile, /APPEND
PRINTF, lu, x, y, FORMAT='(G20.4,4X,G20.4)'
FREE_LUN, lu
xvec = [ xvec, x ]
yvec = [ yvec, y ]
npts = npts + 1
ENDIF ELSE BEGIN
; Middle mouse button pressed. Move to a new print line and put a
; blank line into the output file.
PRINT, ' '
OPENW, lu, outfile, /APPEND
PRINTF, lu
FREE_LUN, lu
ENDELSE
WHILE ( !mouse.button NE 0 ) DO BEGIN
CURSOR, xx, yy, 4, /DEVICE
ENDWHILE
ENDIF
PRINT, cr, x, y, FORMAT=fmt
ENDWHILE
PRINT, FORMAT='(/)'
PRINT, 'Selected points saved to file ' + outfile + '.'
IF KEYWORD_SET( xvec ) AND KEYWORD_SET( yvec ) AND npts GT 0 THEN BEGIN
xvec = xvec[ 1 : npts ]
yvec = yvec[ 1 : npts ]
ENDIF
END