#!/DOCUMENT_ROOT/OCEAN_PLANET/SUPPORT_PROGRAMS/perl # Get the document root from the path to perl. ($dr) = $^X =~ m@^(.*)/OCEAN_PLANET/@; require "$dr/OCEAN_PLANET/SUPPORT_PROGRAMS/cgi-lib.pl"; $ENV{'RGBDEF'} = '/usr/lib/X11/rgb.txt'; $images = "$dr/OCEAN_PLANET/IMAGES"; $tmpimages = "$dr/OCEAN_PLANET/USER_LOCATIONS"; $url = '/ocean_planet_scripts/locator.pl'; $sp = "$dr/OCEAN_PLANET/SUPPORT_PROGRAMS"; $mark = "$sp/markmap"; $ppm = "$sp/giftopnm -quiet"; $quant = "$sp/ppmquant -quiet 256"; $gif = "$sp/ppmtogif -quiet"; $asin = "$sp/asin"; %map = ( 'A',pack('a32S4Cf3S','locator_world.gif',24,24,512,256,0,0.0,0.0,360.0,128), 'B',pack('a32S4Cf3S','locator_africa.gif',24,24,300,300,1,20.0,0.0,80.0,150), 'C',pack('a32S4Cf3S','locator_asia.gif',24,24,300,300,1,120.0,30.0,52.0,150), 'D',pack('a32S4Cf3S','locator_australia.gif',24,24,300,300,1,140.0,-20.0,75.0,150), 'E',pack('a32S4Cf3S','locator_europe.gif',24,24,300,300,1,20.0,50.0,49.0,150), 'F',pack('a32S4Cf3S','locator_india.gif',24,24,300,300,1,75.0,25.0,53.5,150), 'G',pack('a32S4Cf3S','locator_n_america.gif',24,24,300,300,1,-100.0,50.0,53.5,150), 'H',pack('a32S4Cf3S','locator_oceania.gif',24,24,300,300,1,-180.0,-10.0,79.0,150), 'I',pack('a32S4Cf3S','locator_s_america.gif',24,24,300,300,1,-60.0,-20.0,80.0,150) ); # Check the program input. if(scalar(@ARGV) != 1){ &servererr("Wrong number of arguments, client may not support ISMAP."); } ($x,$comma,$y) = split(/(\,)/, $ARGV[0]); if($comma ne ','){ &servererr("Your client doesn't support image mapping properly."); } $PI = atan2(1,1) * 4; # Trick ReadParse $ENV{'QUERY_STRING'} = substr($ENV{'PATH_INFO'},1); &ReadParse; ($f,$x0,$y0,$w,$h,$p,$clon,$clat,$s,$o) = unpack('A32S4Cf3S',$map{$in{'rgn'}}); # Get input image width and height. ($width,$height) = &gifdim("$images/$f"); $width && $height || &servererr("Could not read GIF image: $f"); # Make a temporary output filename consisting of the input name with a # process ID and timecode added and an extension of '.gif' . $out = $f; $out =~ s/(.*)\.gif$/$1_$$_$^T.gif/; # Project (x,y) to (lat,lon). &project; # Generate an image file that will be removed after three minutes. # Use the csh to redirect stderr output to /dev/null . system(<<"--"); $ppm $images/$f | $mark $x $y | $quant | $gif > $tmpimages/$out /bin/csh -c 'echo "rm $tmpimages/$out" | at now + 3 minutes >& /dev/null' -- # Remove older information. $_ = $in; s/lat\=[^&]*\&?//; s/lon\=[^&]*\&?//; s/pid\=[^&]*\&?//; s/tim\=[^&]*\&?//; print <<"--"; Location: $url?lat=$lat&lon=$lon&pid=$$&tim=$^T&$_ -- ############################################################################### ################### Subroutines ##################### ############################################################################### # Get the dimensions of a GIF file sub gifdim{ local($file) = @_; local($bytes); open(FILE,$file) || return(); read(FILE,$bytes,10); close(FILE); $bytes =~ s/^GIF8[79]a// || return(); # Check for GIF header $bytes =~ s/(.)(.)(.)(.)/$2$1$4$3/ || return(); # Swap bytes unpack("S2",$bytes); } #------------------------------------------------------------------------------ # Projection subroutine sub project{ local($xx,$yy,$rho,$r,$c,$cosc,$sinc,$cosphi,$sinphi,$tmp); # Restrict to map portion of image. $x = $x0 if($x < $x0); $x = $x0 + $w - 1 if($x > $x0 + $w - 1); $y = $y0 if($y < $y0); $y = $y0 + $h - 1 if($y > $y0 + $h - 1); $xx = $x - $x0 - $w/2; $yy = $h/2 - $y + $y0; if($p == 0){ # Plate Carree $r = $w/$s; $lon = $clon + $xx/$r; $lon += 360.0 if($lon < -180.0); $lon -= 360.0 if($lon > 180.0); $lat = $clat + $yy/$r; } elsif($p == 1){ # Azimuthal equidistant $r = $w / ($s * $PI / 180.0); $rho = sqrt($xx*$xx + $yy*$yy); $c = $rho / $r; $cosc = cos($c); $sinc = sin($c); $rclat = $clat * $PI / 180.0; $rclon = $clon * $PI / 180.0; $cosphi = cos($rclat); $sinphi = sin($rclat); if($clat == 90){ $lon = ($rclon + atan2($xx,-$yy)) * 180.0 / $PI; } elsif($clat == -90){ $lon = ($rclon + atan2($xx,$yy)) * 180.0 / $PI; } else{ $lon = $rclon + atan2($xx*$sinc, $rho*$cosphi*$cosc - $yy*$sinphi*$sinc); $lon *= 180.0 / $PI; } if($rho == 0.0){ $lat = $clat; } else{ $tmp = $cosc * $sinphi + $yy * $sinc * $cosphi / $rho; $lat = `$asin $tmp`; $lat *= 180.0 / $PI; } } } #------------------------------------------------------------------------------ # Report an error to the user and exit. sub servererr{ local($msg) = @_; print <<"--"; Content-type: text/html
$msg -- exit(-1); }