#!c:\perl\bin\perl.exe
# Copyright (c) 1997 Massachusetts Institute of Technology.
# All rights reserved.
#
# Perl script for browsing Digital Orthophotos.
# Major Revision History:
# April 1996: Initial csh version up, using pre-tiled images. (John Evans)
# Aug/Sep 1996: "Seamless" views, using a new pnmcut; image downloads. (John Evans)
# Feb/Apr 1997: GeoTIFF support (Andrew Wheeler) and CGI library.
# April 1998: Image lookups in a database (Dan Martin and John Evans)
# Summer 1998: Facelift and
-based seamless viewport (Pam Mukerji)
# July, 1998: Dynamic overviews and "you are here" (Nii Lartey Dodoo)
# October, 1998: Truly seamless views w/ multi_tiffcut and then tiffmosaic.c
##### User-selectable options ##################################
# Check these two settings - else the client might not work
$WMTVER = '1.0'; # Default WMT interface version number
# (Set to nothing for "classic" MITortho interface)
@ZOOMLEVELS = (1, 2, 5, 10, 20, 50, 100, 200, 400, 800, 1600); # Valid zoom levels
%LAYERS = ('coast' => 'DOQQ', '1992_1993' => '\'92-\'93 DOQQs', '1998_1999' => '\'98-\'99 DOQQs', 'michigan_drg' => 'DRG', 'michigan_dem' => 'DEM', 'lmpds_56' => 'LMPDS \'56', 'lmpds_61' => 'LMPDS \'61', 'lmpds_88' => 'LMPDS \'88', 'lmpds_99' => 'LMPDS \'99');
%SERVER = ('coast' => 'http://ortho.lic.wisc.edu/server.cgi',
'1992_1993' => 'http://ortho.lic.wisc.edu/server.cgi',
'1998_1999' => 'http://ortho.lic.wisc.edu/server.cgi',
'michigan_drg' => 'http://ortho.lic.wisc.edu/server.cgi',
'michigan_dem' => 'http://ortho.lic.wisc.edu/server.cgi',
'lmpds_56' => 'http://ortho.lic.wisc.edu/server.cgi',
'lmpds_61' => 'http://ortho.lic.wisc.edu/server.cgi',
'lmpds_88' => 'http://ortho.lic.wisc.edu/server.cgi',
'lmpds_99' => 'http://ortho.lic.wisc.edu/server.cgi');
# Make sure the Web page displays the right coordinate system
$COORD_SYS = "NAD 83 Zone 16";
# Specify the client's default image request
$DEF_X0=437219; # Center of default view: easting...
$DEF_Y0=4924706; # ... and northing
$DEF_ZOOMLEVEL = 400; # Default zoom level (screen:image pixels);
$DEF_PWIDTH= 500; # Default viewport: width & height
$DEF_PHEIGHT= 500; # in pixels, and in meters on the ground
# This setting can be safely ignored
$OVERLAP = 5; # Percent overlap when going N, S, E, W
##### End user-selectable options ############################
# Initialize a CGI structure
use CGI;
use File::Basename;
$query = new CGI;
$form_preamble = $query->startform(-method=>GET, -action=>"$SCRIPT");
$SCRIPT=basename($0); # Stash this script's name for self-reference later
# (Dir. path is relative to the Web-root)
# Initialize form variables.
# Check for debug flag (verbose output) first:
if ($debug = $query->param('debug')) {
$|=1; # Make sure diagnostics go out in sync
print $query->header; # Send out HTTP header early
# Make this setting stick through the remainder of the session
$debugvar = "";
} else {$debugvar='';}
# Set a session-id which persists through successive queries.
# (Not used at present)
# $sessionid = $query->param('uid') || $$;
# Set WMT-inteface version number:
$wmtver = $query->param('wmtver') || $WMTVER;
# Get the requested data layer (Wasn't used previously)
$layer = $query->param('layer') || 'coast';
# Zoom level (screen:image pixels); sensible default
$zoom = $query->param('zoom') || $DEF_ZOOMLEVEL;
# Find closest image-pyramid level ($zl) if in-between:
$zl = $#ZOOMLEVELS; $prevzoom = $ZOOMLEVELS[$zl];
for ($z = $#ZOOMLEVELS; $z >= 0; $z--) {
$midpoint = sqrt ($ZOOMLEVELS[$z]*$prevzoom);
if ($zoom <= $midpoint) {$zl = $z;} else {last;}
$prevzoom = $ZOOMLEVELS[$z];
}
$debug && print "Zoom: $zoom m/pixel; nearest level is $zl -> $ZOOMLEVELS[$zl] m/pixel. \n";
# But don't "snap" the actual zoom level to that one
# Desired action:
$action = $query->param('action') || "nop"; # default is "Nop"
# Viewport width & height in pixels on screen:
$pwidth = $query->param('pwidth') || $DEF_PWIDTH;
$pheight = $query->param('pheight') || $DEF_PHEIGHT;
# Center of current view (in geographic coordinates):
$x0 = $query->param('x0') || $DEF_X0;
$y0 = $query->param('y0') || $DEF_Y0;
$debug && print "zoom=$zoom, view center (x=$x0, y=$y0),",
# "layer=$layer,"
"width=$pwidth, height=$pheight, action=$action ";
#------------------------------------------------------------------
# Based on the action specified, determine the next image's
# geographic coordinates:
#------------------------------------------------------------------
# First, treat actions that use a mouseclick
if ($action eq "pan" or $action =~ /^zoom/) {
# Recenter view on mouseclick (x,y) (default is middle of viewport):
$xclick = $query->param('x') || $pwidth/2;
$yclick = $query->param('y') || $pheight/2;
$debug && print " zoom=$zoom, (nearest level is $ZOOMLEVELS[$zl]). ",
"You clicked on $xclick, $yclick to recenter at ";
$x0 = int ($x0 - $zoom * ($pwidth/2 - $xclick));
$y0 = int ($y0 + $zoom * ($pheight/2 - $yclick));
$debug && print "($x0, $y0) in geographic coordinates; ";
}
if ($action =~ /^zoom/) {
($whereto = $action) =~ s/^zoom//; # parse out "zoom" prefix
$debug && print "whereto=$whereto; ";
if ($whereto eq "in") {
$debug && print "Zooming IN from zoom level $zl -> $zoom m pixels ";
if ($zoom > $ZOOMLEVELS[0]) {
$zl-- if $zoom <= $ZOOMLEVELS[$zl];
$zoom = $ZOOMLEVELS[$zl];
}
if ($zoom > $ZOOMLEVELS[0]) { $zichecked = "CHECKED"; }
else { $rcchecked = "CHECKED"; }
}
elsif ($whereto eq "out") {
$debug && print "Zooming OUT from zoom level $zl -> $zoom m pixels ";
if ($zoom <= $ZOOMLEVELS[$#ZOOMLEVELS]) {
$zl++ if ($zoom >= $ZOOMLEVELS[$zl]);
$zoom = $ZOOMLEVELS[$zl];
}
if ($zoom <= $ZOOMLEVELS[$#ZOOMLEVELS]) { $zochecked = "CHECKED"; }
else { $rcchecked = "CHECKED"; }
}
else { # "zoom50", "zoom20", etc.
$debug && print "whereto=$whereto; ";
$debug && print "Zooming directly from zoom level $zl -> $zoom m pixels ";
$zl = 0;
for ($z = $#ZOOMLEVELS; $z >= 0; $z--) {
$zl = $z if $whereto <= $ZOOMLEVELS[$z];
}
$zoom = $ZOOMLEVELS[$zl];
$rcchecked = "CHECKED";
} # Done with zoom actions
$debug && print "to zoom level $zl -> $zoom m pixels. \n";
} else {
$rcchecked = "CHECKED"; # Recenter is default next action
}
# Switching layers: parse out "layer" prefix
if ($action =~ /^layer/) {
($layer = $action) =~ s/^layer//;
}
# This if() clause covers lateral movements w/o a mouseclick:
if ($action =~ /^north/ or $action =~ /^south/
or $action =~ /east$/ or $action =~ /west$/ ) {
$lateral = 1; $debug && print "Going ";
}
if ($action =~ /^north/ ) { # N, NE, NW
$deltay = 1; $debug && print "North";
}
elsif ($action =~ /^south/ ) { # S, SW, SW
$deltay = -1; $debug && print "South";
}
if ($action =~ /east$/ ) { # E, NE, SE
$deltax = 1; $debug && print "East";
}
elsif ($action =~ /west$/ ) { # W, NW, SW
$deltax = -1; $debug && print "West";
}
if ($lateral) {
$debug && print ": resetting (x0, y0) to ";
$x0 = $x0 + $deltax * (1 - $OVERLAP/100)*$pwidth*$zoom;
$y0 = $y0 + $deltay * (1 - $OVERLAP/100)*$pheight*$zoom;
$debug && print "{$x0, $y0). \n";
}
# Viewport width and height, in geographic units (e.g. meters):
$gwidth = $pwidth * $zoom;
$gheight = $pheight * $zoom;
###### Store state string (no $action); it gets used a lot here.
$state = "zoom=${zoom}&x0=${x0}&y0=${y0}&gwidth=${gwidth}&gheight=${gheight}"
. "&pwidth=${pwidth}&pheight=${pheight}&layer=$layer";
$state .= "&debug=${debug}" if $debug;
# Set Query-String for map server
# OGC-WMT 0.0.1 server interface kicks in on non-blank 'wmtver'
if ($wmtver) {
@bbox = ($x0-$gwidth/2, $y0-$gheight/2,
$x0+$gwidth/2, $y0+$gheight/2);
$imgrequest = "wmtver=$wmtver&request=map"
. "&bbox=$bbox[0],$bbox[1],$bbox[2],$bbox[3]"
. "&width=$pwidth&height=$pheight&layers=$layer";
$state .= "&wmtver=$wmtver"; # Carry version ID along
} else { # "Classic" interface x0,y0,width,height,zoom
$imgrequest = $state;
}
@directions = ("north", "south", "east", "west",
"northeast", "northwest", "southeast", "southwest");
foreach $dir (@directions) {
$link{$dir} = "";
$get{$dir} = $link{$dir}
. "";
}
# Put an asterisk next to current zoom level and layer name
${'zoom'.$zoom.'_selected'} = "*";
${'layer'.$layer.'_selected'} = "*";
# "Zoom in" radio button (if not zoomed in all the way):
$zoomin = ""
. " Zoom IN " if ($zoom > $ZOOMLEVELS[0]);
# "Zoom out" radio button (if not zoomed out all the way):
$zoomout = ""
. " Zoom OUT " if ($zoom < $ZOOMLEVELS[$#ZOOMLEVELS]);
$debug && print "New zoom=$zoom, xclick=$xclick, yclick=$yclick,",
"x0=$x0, y0=$y0, pwidth=$pwidth, pheight=$pheight, gwidth=$gwidth,",
"gheight=$gheight \n";
# OK, now dump the form to stdout for the browser.
#------------------------------------------------------------------
print $query->header unless $debug; # If debug, we already did this around line 50
print <MIT/NRCS DOQQ Server: $zoom m/pixel, center (x,y)=($x0,$y0)
MIT/NRCS DOQQ server: $zoom m/pixel, center (x,y) = ($x0,$y0) UTM Zone 16, NAD83
$form_preamble
$debugvar
$link{'northwest'}NW
$link{'north'}N
$link{'northeast'}NE
$link{'west'}W
$link{'east'}E
$link{'southwest'}SW
$link{'south'}S
$link{'southeast'}SE
Click on the image to
Recenter image
$zoomin
$zoomout
or to set a scale of
EndForm1
############## Radio buttons for zoom levels
foreach $z (reverse @ZOOMLEVELS) {
print ""
. " ${z}m pixels "
. " ${'zoom'.${z}.'_selected'} \n";
}
print '(* Current zoom level)';
# ... and for layer names
foreach $l (keys %LAYERS) {
print '"
. " $LAYERS{$l} ${'layer'.${l}.'_selected'} \n";
}
############## ... and back to the here-document
print <* Current layer)
You may have to navigate to active
imagery when changing layers!