"The interactive map is a computer-assisted form of map presentation that attempts to mimic the display of mental maps in the mind. ... Ultimately, the interactive map is an extention of the human ability to visualize places and distributions. Peterson, M.P. (1995) Interactive and Animated Cartography, Prentice-Hall, p. 45.
This hands-on workshop provides an overview of interactive mapping on the web. The focus will be on the tools, concepts, and principles of design of interactive maps and their distribution through the World Wide Web. Topics include types of interactive maps, software for their creation, HTML, and JavaScript. New developments in interactive multimedia presentation though the World Wide Web, including QuickTime VR, Shockwave, and VRML, will also be reviewed. The HTML exercises use Netscape Communicator and a text-editor (NotePad or SimpleText). The latter and most difficult part of the workshop deals exclusively with JavaScript. The session is intended for anyone interested in gaining hands-on experience in interactive web mapping applications.
- easy. You have to work with the computer and software. It won't always work right and it will make you feel stupid.
- an opportunity to listen and relax, and occasionally write some margin notes into your workbook.
- about creating an on-line GIS (although I'll talk about this at the end).
- about Java, although exercises use JavaScript.
- here today, gone tomorrow. The materials will remain available at: http://maps.unomaha.edu/Workshops/InteractiveMap.html
We will have occasional breaks in an effort to maintain our sanity. However, we'll be working with the Windows operating system so I wouldn't hold out too much hope for our sanity.
Most of the problems that I deal with during the workshop are related to the operating system -- not to the software that I'm demonstrating. I need your help if you know the operating system well. Please help the other participants that sit close-by to you with problems that they are having.
The incorporation of interaction in the display of maps may be viewed as a major accomplishment of the computer-era in cartography. Certainly, interaction has pervaded all forms of mapping, whether it is with a database of a geographic information system, a multimedia atlas on a CD-ROM, or street maps on the World Wide Web. A characteristic shared by all of these forms of mapping is the control that the user has over the resultant map.
... interactivity is not new in cartography. In fact, it may be as old as cartography itself. While we don't know when the first map was made, it was very likely a product of an interaction between two individuals. It may have been much like the "paper-napkin map" of today - the kind of map that is drawn on any piece of scrap paper when words fail as one tries to explain where something is located. A common characteristic of these maps is that the person for whom the map is being made will ask questions that affect how the map is drawn. For example, the person might ask where a particular landmark is located to provide a point of reference. The map becomes a product of interaction when the maker of the map includes the landmark. It is likely that the first map was a product of this type of interaction.
The first and third stages are both interactive, differing in how the interaction is achieved - human vs. computer. What do we call the intervening period? In geology, the time period in which we live is commonly referred to as an "interglacial," i.e., the time between major glacial events. In a similar sense, cartography may be seen as having been in an "interinteractive" period - a period when static maps were the norm. The ice is still melting from this period.
Most of the necessary software for producing interactive maps is on the Web. The trick is knowing where the software is located, how to download, and install. Follow these steps to set up the work environment:
This folder will contain all of the workshop programs and files. We will delete this folder at the end of the day.
The browser program displays web documents. We will use the latest version of Netscape. Netscape comes in two versions. The Navigator version simply displays web pages. The larger Communicator version displays web pages, handles e-mail and other Internet functions, and includes an authoring program called Composer.
Plug-ins add functionality to the browser. The following plug-ins are required for the workshop. These plug-ins are small and should download and install quickly.
Adobe Acrobat: This plug-in displays Adobe Acrobat files within the browser window. Acrobat files use a Postscript-like file structure called Page Description Format or PDF. The advantage of this file structure is that it can display maps at a higher resolution.
Adobe Acrobat and SVG
Apple QuickTime: A QuickTime file consist of a series of frames that can be displayed in quick succession
Microsoft MediaPlayer: Microsoft's QuickTime
MacroMedia:
VRML - Choose one of the following.
Silicon Graphics Cosmo - Cosmo encompasses software products for creating and viewing interactive multimedia and tools for developing interactive applications.
The Netscape Navigator Communicator program includes HTML authoring. A number of other HTML authoring programs are available that you might want to try. Word processors like Microsoft Word include an HTML output option but have limited functionality for graphics and interaction. There are a variety of HTML authoring programs. Some of the options are listed below:
HTML Page Layout
High-Level
An image mapping program maps out "hot spots" on GIF images. HTML authoring programs include this functionality. Other stand-alone programs are also available that perform this task.
- Mapedit (available for 18 different operating systems; choose the appropriate one)
These programs process graphics files. Some may no longer be free. Download only those that are cost-free or demos.
- Adobe Photoshop This is the major image-oriented (raster-based) graphics program.
- Paint Shop Pro (An easy to use graphics editor that has nearly as many features as Adobe Photoshop.)
- EyeCandy (Includes 21 Photoshop plug-ins that take the drudgery out of creating glossy graphical effects.)
- Mr. Sid Compression and delivery.
These programs allow you to assemble a series of GIF images to create an animated GIF.
Other GIF animation software:
- GIFmation for Mac (from Yves Piguet in Switzerland; download my be slow; description)
These programs allow you to assemble as series of pictures or video clips into a movie.
This is an object-oriented (vector-based) graphics program. You need to fill out the registration form to download. The size of the download is 12 MB. Downloading and installing this program takes about 10 minutes.
Web graphics is limited by the raster format.
Large multimedia authoring programs are commonly used for interactive mapping. Director is the leading program for multimedia authoring (the ESRI of multimedia). Used extensively for the creation of CD-ROM content, Macromedia's Shockwave plug-in is bringing Director files to the web. The program is available for both Mac and PC although the Mac version is more stable.
Map Examples:
Maps on the web can be categorized as static (non-changing), interactive, and animated. Because of lower resolution in screen display as compared to printed materials, most of the effort has been concentrated on interactive and, to some extent, animated maps.
Finding maps:
Online Map Database
Mr. Oddens, a map librarian in the Netherlands, keeps track of maps available through the Internet. You can search his online database.www.google.com - Image tab
Static Maps
Scanned Maps
Scanned Map - GIF Image 1340x847 pixels (raster file)
Perry Casteneda Map Library
Public-domain maps, mostly from the US Government.CIA Maps
In both JPEG and PDF format. PDF maps print better.Election Maps
Demographic Maps - US
Adobe Acrobat
Map of Europe (Postscript vector file)
If Netscape tells you that the plug-in was not found or immediately starts to save the file to your hard-drive, the Adobe Acrobat plug-in was not installed properly.
Massachussets General Hospital
This site contains a PDF map of the hospitals main campus, a driving map that shows how to get to the campus, and a map of the main floor of the main campus.
Maps in Acrobat PDF format
Maps used in Dr. Peterson's World Regional CourseSVG Maps
CartoNet - An overview of cartographic applications of SVG.
SVG Map - An example of an SVG Map
Updated Static Maps:
Weather Display #1: These maps are shown by Macintosh IIcx computer in a display case at the Durham Science Building at the University of Nebraska at Omaha. The computer, purchased in 1987, only has 8 MB of memory and has been displaying weather maps continuously since the Fall of 1998. The maps are updated every 30 minutes.
Weather Display #2: These maps are also shown in a display case at the Durham Science Building at the University of Nebraska at Omaha.
Earthquakes
Interactive Maps - Serverside
MapBlast Street-Level Mapping of U.S. (5 million maps a day)
MapQuest
MapsOnUs
Yahoo Maps
Earth View Home Page
Mouse-over - JavaScript
- Omaha Crime
- Austria #1 - Technical University of Vienna
- Austria #2 - Technical University of Vienna
- Austria #3 - Technical University of Vienna
Maps in Flash
Census Data Mapping - Java
- Ciesin - includes a Java and non-Java interactive demographic mapping system
- ESRI - ESRI's interactive census mapping site
- Nebraska Bureau of Business Research
GIS-based - ESRI
Other ESRI examples
Example Animations:
This will be a good test to see if your animation plug-ins are installed correctly. The following animations use either the QuickTime or MPEG plug-in. If you have not installed these plug-ins, the following animations will not work.
- Weather Animation | (description)
- Fly-Through Animation (7.4 MB)
- San Francisco Bay area from 1800-1990 (446 KB, MPEG, description)
- Nebraska by county between 1954-1987 (264 KB, QuickTime, description)
- Generalization Cartographic Animation (578 KB, QuickTime, description)
- Omaha Animation of Age Groups (664 KB, QuickTime, description)
- Classification Animation (50 KB, QuickTime, description)
- Classification Animation with Sound (1.4 MB, QuickTime, description)
Example Interactive Animations:
Apple QuickTime VR
Outside VR
- Apple R&D
- Fort Point, San Fransisco
- Monument Valley
- Glacier National Park
- Tahiti (Belvedere)
- Tahiti (Moorea)
- Melbourne Cricket Grounds
Inside VR
Looking-in VR
Example Sounds:
Martin Luther King | John F. Kennedy
HTML (hypertext mark-up language) controls the formatting of web pages. It is a text-based formatting language that is very similar to early word-processors like WordStar. Codes are inserted in the document that control the formatting of the text and the hyperlinks. The following guides describe the language:
A Beginner's Guide to HTML
Advanced HTML: How Do They Do That With HTML?
Most web page designers avoid HTML Editors (WYSIWYG programs to help you create HTML documents) and "hard-code" their documents with a text editor. It is useful to become familiar with at least some of the HTML codes, as will be demonstrated with this exercise:
Step 1: Use a text editor to type in the following. If using a word processor, remember to save as "Text Only." Use "EX1.html" as the file name.
<HTML>
<HEAD>
<TITLE>Exercise #1: HTML Text File</TITLE>
</HEAD>
<BODY>
<H1>What is Multimedia?</H1>
Multimedia combines multiple forms of media in the communication of information, such as audio, video, graphics, animation and computer data.
<p>The Internet has been described in many ways. In the simplest sense, the Internet may be thought of as a system for transferring files between computers.
</BODY>
</HTML>Notice how the codes are all surround by the < and > characters. Also notice the HEAD section and the BODY section of the document.
Step 2: In Netscape, use the Open File command in File menu to open the EX1.html file. Notice how the text in the TITLE line is displayed in the top of the window. Also notice that the <H1> command makes the text larger.
Step 1: Downloading a GIF file:
Save the following file in the same directory as your "EX1.html" file.
US Population Density (Save the file as "USpopden.gif".)
Any graphic image that is included on a web page is a separate file and can be downloaded to your computer. In this case, we will download a map to incorporate into our simple web page.
To save the graphic to your disk, hold the mouse button down on the Mac or click on the right button on the PC and wait for the save file dialog.
Step 2: Add the text displayed here in bold to your "EX1.html" file. Save as EX2.html.
<HTML>
<HEAD>
<TITLE>Exercise #1: HTML Text File</TITLE>
</HEAD>
<BODY>
<H2>What is Multimedia?</H2>
Multimedia combines multiple forms of media in the communication of information, such as audio, video, graphics, animation and computer data.
<p><H2>What is Internet?</H2>
The Internet has been described in many ways. In the simplest sense, the Internet may be thought of as a system for transferring files between computers.
<p>
Graphical illustrations form an important part of the web, as with this thematic map of the U.S.
<br>
<IMG SRC="USpopden.gif">
</BODY>
</HTML>
Extra Time? The IMG tag has several options. Look at the HTML documentation and try some of these options, i.e., change size, move to the right side of the page, outline, etc.)
Client-side Image Maps This webpage explains how to make a client-side image map as well as a little bit about the difference between client side and server side image mapping.
Exercise:
Find pixels coordinates of a rectangle and polygon for the illustration below:
Step 1: Download this graphic.
Question: Why are the colors dithered (not solid) in this illustration?
Step 2: Find the coordinates that outline the rectangle and the polygon.
Instructions for finding the coordinates in Photoshop:
Step A: In File / Preferences / Units, change to 'Pixel'
Step B: Open the Window / Palettes / Info Window.
Step C: Write down the coordinates for the outline of a rectangle and a polygon (vertices only).Step 3: Type the following into a text editor. Change the coordinates in bold in the AREA statements to match the coordinates that you determined from an image editing program. Name the file EX2.html and place in the same directory as the GIF file that you downloaded.
<HTML>
<HEAD>
<TITLE>Exercise #1: Client-side Image Map</TITLE>
</HEAD>
<BODY><A NAME="Error">
<P>
This is an example of an client-side image map.
<IMG SRC="Mayoral.GIF" USEMAP="#areadef">
</BODY>
<MAP NAME="areadef"><AREA SHAPE="rect" COORDS="152,308,168,323" HREF="ClickedRect.html">
<AREA SHAPE="poly" COORDS="282,329,275,316,273,300,270,291,290,289,290,320,281,330" HREF="ClickedPoly.html">
<AREA SHAPE="default" HREF="Error.html">
</MAP>
</HTML>
Step 4: Create the ClickedRect.html, ClickedPoly.hmtl file, and Error.html files as follows:
ClickedRect.html
<HTML>
<HEAD>
<TITLE>Exercise #1: This is the ClickedRect file</TITLE>
</HEAD>
<BODY><H1> You clicked on the rectangle! </H1>
</BODY>
</HTML>________________________________________________________
ClickedPoly.html
<HTML>
<HEAD>
<TITLE>Exercise #1: This is the ClickedPoly file</TITLE>
</HEAD>
<BODY><H1> You clicked on the polygon! </H1>
</BODY>
</HTML>________________________________________________________
Error.html
<HTML>
<HEAD>
<TITLE>Exercise #1: This is the Error file</TITLE>
</HEAD>
<BODY><H1> ERROR: You did not click on a valid area! </H1>
</BODY>
</HTML>
Step 5: In Netscape, open the EX2.html file using File / Open File. Pass the mouse over the rectangle and polygon and notice how the URL changes to the name of the files ClickedME.html and ClickedME2.html respectively. Click on the polygon to see if the appropriate file is displayed.
------
These are the coordinates of the rectangle and polygon:
Rectangle Polygon x y x y 42 149 215 149 42 79 236 106 148 79 275 83 148 148 316 83 373 125 327 133 320 140 322 167 271 173 229 162
What is JavaScript?
JavaScript is a scripting language, similar to a programming language. The primary difference is that JavaScript is interpreted by the web browser. JavaScript can be used to develop interactive web pages that check user input into forms, change the look of web pages, or display informative messages in the status bar of a web browser. Here are three links about JavaScript:
- Coding
- A site that contains an archive of different scripts as well as various tips that are updated weekly. It also provides access to an online book about JavaScript and coding as well as information on adding Dynamic HTML to websites.
- Tutorial
- The site is has reviews of QuickTime VR, VRML, Shockwave, Java, Real Audio, JavaScript, and Sizzler as well as tutorials and examples of each.
- Information
- Contains links to other Java sites, a tutorial, and free Voodoo software
A JavaScript example:
function hiLiter(imgBase,imgSwap)
// TASK: SWAP IMAGES
// imgBase - name of the document image to be replaced
// imgSwap - name of the image object to be swapped in
{
if (browserVersion == 1)
{
document.images[imgBase].src = eval(imgSwap + ".src")
}
}
// END -->
</SCRIPT>In the following exercise, we will create a simple JavaScript that will alternate between these four frames:
<HTML><HEAD><TITLE>Sample Javascript</TITLE><SCRIPT LANGUAGE="JavaScript"><!--// TEST: BROWSER VERSIONagent = navigator.userAgentbrowserVersion = 1
if (agent.indexOf("a/3",6) == -1)
{browserVersion = 1}
if (browserVersion == 1)// TASK: PRELOAD IMAGES{picker_n = new Image(200,200);picker_n.src = "picker.gif";red_n = new Image(200,200);red_n.src = "red.gif";blue_n = new Image(200,200);blue_n.src = "blue.gif";yellow_n = new Image(200,200);yellow_n.src = "yellow.gif";}function hiLiter(imgBase,imgSwap)// TASK: SWAP IMAGES// imgBase - name of the document image to be replaced// imgSwap - name of the image object to be swapped in{if (browserVersion == 1){document.images[imgBase].src = eval(imgSwap + ".src")}}// END --></SCRIPT></HEAD><BODY BGCOLOR="white"><A NAME="top"><CENTER><IMG SRC="picker.gif" NAME="map" WIDTH=200 HEIGHT=200 ALT="ThePicker" USEMAP="#mousemap" BORDER=0></CENTER></BODY><MAP NAME="mousemap"><AREA SHAPE="rect" COORDS="50,25,96,66" HREF="#top"onMouseOver="hiLiter('map','red_n'); window.status='Red'; returntrue"><AREA SHAPE="rect" COORDS="50,73,96,117" HREF="#top"onMouseOver="hiLiter('map','blue_n'); window.status='Blue'; returntrue"><AREA SHAPE="rect" COORDS="51,123,96,166" HREF="#top"onMouseOver="hiLiter('map','yellow_n'); window.status='Yellow';return true"><AREA SHAPE="rect" COORDS="1,175,200,200" HREF="#top"onMouseOver="hiLiter('map','picker_n'); window.status='Picker';return true"></MAP></HTML>
Extra Time? Check out GeoWeb Java Corner
What is JavaScript?
JavaScript is not Java!
Running JavaScript
Embedding JavaScript into a HTML-page
JavaScript code is embedded directly into the HTML-page. In order to see how this works we are going to look at some examples (based on an JavaScript tutorial at http://rummelplatz.uni-mannheim.de/~skoch/js/):
|
|
|
|
| 1) |
<html>
<body>
<br>
This is a normal HTML document.
<br>
<script language="JavaScript">
document.write("This is JavaScript!")
</script>
<br>
Back in HTML again.
</body>
</html>
|
This is a normal HTML document. This is JavaScript! Back in HTML again. |
| 2) |
|
Welcome to my homepage! This is JavaScript! Welcome to my homepage! This is JavaScript! Welcome to my homepage! This is JavaScript! |
| 3) |
<html>
<head>
<script language="JavaScript">
<!-- hide
function calculation() {
var x= 12;
var y= 5;
var result= x + y;
alert(result);
}
// -->
</script>
</head>
<body>
<form>
<input type="button" value="Calculate"
onClick="calculation()">
</form>
</body>
</html>
|
17 |
| 4) |
<html> <frameset rows="50%,50%"> <frame src="page1.html" name="frame1"> <frame src="page2.html" name="frame2"> </frameset> </html> |
two frames with contents of page1.html in the first and page2.html in the second. |
| 5) |
<frameset cols="50%,50%">
<frameset rows="50%,50%">
<frame src="cell.html">
<frame src="cell.html">
</frameset>
<frameset rows="33%,33%,33%">
<frame src="cell.html">
<frame src="cell.html">
<frame src="cell.html">
</frameset>
</frameset>
|
Create a file called cell.html first. <html> <h1> Happy Returns </h1> </html> Result: many Happy Returns |
| 6) |
<html>
<head>
<script language="JavaScript">
<!-- hide
function openWin() {
myWin= open("bla.htm");
}
// -->
</script>
</head>
<body>
<form>
<input type="button" value="Open new window"
onClick="openWin()">
</form>
</body>
</html>
|
Opening new browser windows is a great feature of JavaScript. You can either load a new document (for example a HTML-document) to the new window or you can create new documents (on-the-fly). We will first have a look at how we can open a new window, load a HTML-page to this window and then close it again. |
| 7) |
<html>
<script language="JavaScript">
<!-- hide
function closeIt() {
close();
}
// -->
</script>
<center>
<form>
<input type=button value="Close it"
onClick="closeIt()">
</form>
</center>
</html>
|
You can close windows through JavaScript. For this you need the close() method. Let's open a new window as shown before. |
| 8) |
<html>
<head>
<script language="JavaScript">
<!-- hide
function openWin3() {
myWin= open("", "displayWindow",
"width=500,height=400,status=yes,
toolbar=yes,menubar=yes");
// open document for further output
myWin.document.open();
// create document
myWin.document.write("<html><head><title>On-the-fly");
myWin.document.write("</title></head><body>");
myWin.document.write("<center><font size=+3>");
myWin.document.write
("This HTML-document has been created ");
myWin.document.write("with the help of JavaScript!");
myWin.document.write("</font></center>");
myWin.document.write("</body></html>");
// close the document - (not the window!)
myWin.document.close();
}
// -->
</script>
</head>
<body>
<form>
<input type=button value="On-the-fly"
onClick="openWin3()">
</form>
</body>
</html>
|
A nice feature of JavaScript is being able to create documents on-the-fly. This means you can let your JavaScript code create a new HTML-page. Furthermore you can create other documents - like VRML-scenes etc.. You can output these documents in a separate window or in a frame. First we will create a simple HTML-document that will be displayed in a new window. You can see that we open a new browser window first. As you can see the first argument is an empty string " " - this means we do not specify an URL. The browser should not open an existing document - instead JavaScript create it. |
| 9) |
<html>
<head>
<script language="JavaScript">
<!-- hide
function statbar(txt) {
window.status = txt;
}
// -->
</script>
</head>
<body>
<form>
<input type="button" name="look" value="Write!"
onClick="statbar('Hi! This is the statusbar!');">
<input type="button" name="erase" value="Erase!"
onClick="statbar('');">
</form>
</body>
</html>
|
JavaScript programs can write to the statusbar. This is the bar at the bottom of your browser window. All you have to do is to assign a string to window.status. This example shows you two buttons which can be used to write to the statusbar and to erase the text again. What is new is that we use txt inside the brackets of the function name. This means the string we passed along to the function is stored in the variable txt. Passing variables to functions is an often used way for making functions more flexible. You can pass several values to functions - you just have to separate them with commas. The string txt is displayed on the statusbar through window.status = txt. Erasing the text on the statusbar is done by assigning an empty string to window.status. |
| 10) |
<script language="JavaScript">
<!-- hide
function timer() {
setTimeout("alert('Time is up!')", 3000);
}
// -->
</script>
...
<form>
<input type="button" value="Timer" onClick="timer()">
</form>
|
With the help of timeouts (or timer) you can let the computer execute some code after a certain period of time. If you press this button a window will pop-up after 3 seconds: setTimeout() is a method of the window-object. It sets a timeout. The first argument is the JavaScript code which shall be executed after a certain time. In our case this argument is "alert('Time is up!')". Please note that the JavaScript code has to be inside quotes. The second argument tells the computer when the code shall be executed. You have to specify the time in number of milliseconds (3000 milliseconds = 3 seconds). |
| 11) |
<html>
<head>
<script language="JavaScript">
<!-- hide
// define the text of the scroller
var scrtxt = "This is JavaScript! " +
"This is JavaScript! " +
"This is JavaScript!";
var length = scrtxt.length;
var width = 100;
var pos = -(width + 2);
function scroll() {
// display the text at the right
// position and set a timeout
// move the position one step further
pos++;
// calculate the text which shall be displayed
var scroller = "";
if (pos == length) {
pos = -(width + 2);
}
// if the text hasn't reached
// the left side yet we have to
// add some spaces - otherwise
// we have to cut of the first
// part of the text (which moved
// already across the left border
if (pos < 0) {
for (var i = 1; i <= Math.abs(pos); i++) {
scroller = scroller + " ";}
scroller = scroller +
scrtxt.substring(0, width - i + 1);
}
else {
scroller = scroller +
scrtxt.substring(pos, width + pos);
}
// assign the text to the statusbar
window.status = scroller;
// call this function again
// after 100 milliseconds
setTimeout("scroll()", 100);
}
// -->
</script>
</head>
<body onLoad="scroll()">
Your HTML-page goes here.
</body>
</html>
|
Now that you know how to write to the statusbar and how timeouts work we will have a look at scrollers. You might already know about the moving text-strings in the statusbar. Many pages implement this feature. Scrollers are quite easy to implement. We have to write a text to the statusbar. After a short period of time we have to write the same text to the statusbar - but we have to move it a little bit to the left side. If we repeat this over and over again the user gets the impression of a moving text. The main part of the scroll() function is needed for calculating which part of the text is being displayed. In order to start the scroller we are using the onLoad event-handler of the <body> tag. This means the function scroll() will be called right after the HTML-page has been loaded. We call the scroll() function with the onLoad property. The first step of the scroller is being calculated and displayed. At the end of the scroll() function we set a timeout. This causes the scroll() function to be executed again after 100 milliseconds. The text is moved one step forward and another timeout is set. This goes on forever. |
| 12) |
<html>
<head>
<script Language="JavaScript">
<!-- hide
var timeStr, dateStr;
function clock() {
now= new Date();
// time
hours= now.getHours();
minutes= now.getMinutes();
seconds= now.getSeconds();
timeStr= "" + hours;
timeStr+=
((minutes < 10) ? ":0" : ":") + minutes;
timeStr+=
((seconds < 10) ? ":0" : ":") + seconds;
document.clock.time.value = timeStr;
// date
date= now.getDate();
month= now.getMonth()+1;
year= now.getYear();
dateStr= "" + month;
dateStr+= ((date < 10) ? "/0" : "/") + date;
dateStr+= "/" + year;
document.clock.date.value = dateStr;
Timer= setTimeout("clock()",1000);
}
// -->
</script>
</head>
<body onLoad="clock()">
<form name="clock">
Time:
<input type="text" name="time" size="8"
value=""><br>
Date:
<input type="text" name="date" size="8"
value="">
</form>
</body>
</html>
|
Here we use getHours() to display the time and date specified in our Date-object now. You can see that we are adding 1900 to the year. The method getYear() returns the number of years since 1900. This means if the year is 1999 it will return 99 if the year is 2010 it will return 110 - not 10! If we add 1900 we won't have the year 2000 problem. Remember that we have to increment the number we receive through getMonth() by one. This script does not check whether the number of minutes is less than 10. This means you can get a time which looks like this: 14:3 which actually means 14:03. |
| 13) |
<script language="JavaScript">
<!-- hide
myArray= new Array();
myArray[0]= "first element";
myArray[1]= "second element";
myArray[2]= "third element";
for (var i= 0; i< 3; i++) {
document.write(myArray[i] + "<br>");
}
// -->
</script>
|
Arrays are very important. Just think of an example where you want to store 100 different names. You could define 100 variables and assign the different names to them. This is very complicated. Arrays can be seen as many variables bundled together. You can access them through one name and a number. Let's say our array iscalled names. Then we can access the first name through names[0]. The second name is called name[1] and so on. You can create a new array through myArray= new Array(). Now you can assign values to this array: myArray[0]= 17; myArray[1]= "Stefan"; myArray[2]= "Koch"; JavaScript arrays are really flexible. You do not have to bother about the size of the array - its size is being set dynamically. If you write myArray[99]= "xyz" the size of the array gets 100 elements (a JavaScript array can only grow - it hasn't got the ability to shrink. So keep your arrays as small as possible.). It doesn't matter if you store numbers, strings or other objects in an array. |
| 14) |
<html>
<head>
<script language="JavaScript">
<!-- Hide
function test1(form) {
if (form.text1.value == "")
alert("Please enter a string!")
else {
alert("Hi "+form.text1.value+"! Form input ok!");
}
}
function test2(form) {
if (form.text2.value == "" ||
form.text2.value.indexOf('@', 0) == -1)
alert("No valid e-mail address!");
else alert("OK!");
}
// -->
</script>
</head>
<body>
<form name="first">
Enter your name:<br>
<input type="text" name="text1">
<input type="button" name="button1"
value="Test Input" onClick="test1(this.form)">
<P>
Enter your e-mail address:<br>
<input type="text" name="text2">
<input type="button" name="button2"
value="Test Input" onClick="test2(this.form)">
</body>
</html>
|
Forms are widely used on the Internet. The input is often sent back to the server or via mail to a certain e-mail account. But how can you be certain that a valid input was done by the user? With the help of JavaScript the form input can easily be checked before sending it over the Internet. The example HTML-page containd two text-elements. The user has to write his name into the first and an e-mail address into the second element. You can enter anything into the form elements and then push the button. Also try to enter nothing and then push the button. |
| 15) |
<form method=post action=
"mailto:your.address@goes.here"
enctype="text/plain">
Do you like this page?
<input name="choice" type="radio"
value="1">Not at all.<br>
<input name="choice" type="radio"
value="2" CHECKED>Waste of time.<br>
<input name="choice" type="radio"
value="3">Worst site of the Net.<br>
<input name="submit" type="submit" value="Send">
</form>
|
Submitting form input The easiest way is to submit the form input via e-mail. If you want the form input to be handled by the server you need to use CGI (Common Gateway Interface). This allows you to process the form input automatically. |
| 16) |
<a href="#"
onMouseOver="document.myImage2.src='img2.gif'"
onMouseOut="document.myImage2.src='img1.gif'">
<img src="img1.gif" name="myImage2" width=160
height=50 border=0></a>
Save these Image files:
img1.gif
img2.gif
|
Changing images on user-initiated events: You can create nice effects by changing images as a reaction to certain events. You can, for example, change images when the mouse cursor is being moved over a certain area. |
| 17) |
<html>
<head>
<script language="JavaScript">
<!-- hide
// ok, we have a JavaScript browser
var browserOK = false;
var pics;
// -->
</script>
<script language="JavaScript1.1">
<!-- hide
// JavaScript 1.1 browser - oh yes!
browserOK = true;
pics = new Array();
// -->
</script>
<script language="JavaScript">
<!-- hide
// number of (changing) images on web-page
var objCount = 0;
function preload(name, first, second) {
// preload images and place them in an array
if (browserOK) {
pics[objCount] = new Array(3);
pics[objCount][0] = new Image();
pics[objCount][0].src = first;
pics[objCount][1] = new Image();
pics[objCount][1].src = second;
pics[objCount][2] = name;
objCount++;
}
}
function on(name){
if (browserOK) {
for (i = 0; i < objCount; i++) {
if (document.images[pics[i][2]] != null)
if (name != pics[i][2]) {
// set back all other pictures
document.images[pics[i][2]].src =
pics[i][0].src;
} else {
// show the second image because
// cursor moves across this image
document.images[pics[i][2]].src =
pics[i][1].src;
}
}
}
}
function off(){
if (browserOK) {
for (i = 0; i < objCount; i++) {
// set back all pictures
if (document.images[pics[i][2]] != null)
document.images[pics[i][2]].src =
pics[i][0].src;
}
}
}
// preload images - you have to specify
// which images should be preloaded
// and which Image-object on the wep-page
// they belong to (this is the first
// argument). Change this part if you want
// to use different images (of course
// you have to change the body part of
// the document as well)
preload("link1", "img1f.gif", "img1t.gif");
preload("link2", "img2f.gif", "img2t.gif");
preload("link3", "img3f.gif", "img3t.gif");
// -->
</script>
<head>
<body>
<a href="link1.htm" onMouseOver="on('link1')"
onMouseOut="off()">
<img name="link1" src="link1f.gif"
width="140" height="50" border="0"></a>
<a href="link2.htm" onMouseOver="on('link2')"
onMouseOut="off()">
<img name="link2" src="link2f.gif"
width="140" height="50" border="0"></a>
<a href="link3.htm" onMouseOver="on('link3')"
onMouseOut="off()">
<img name="link3" src="link3f.gif"
width="140" height="50" border="0"></a>
</body>
</html>
|
This script puts all images in an array pics. The preload() function which is called in the beginning builds up this array. You can see that we call the preload() function like this: preload("link1", "img1f.gif",
"img1t.gif");
This means that the script should load the two images img1f.gif and img1t.gif. The first image is the image which should be displayed when the mousecursor isn't inside the image area. When the user moves the mousecursor across the image area the second image is shown. With the first argument "img1" of the call of the preload() function we specify which Image-object on the web-page the two preloaded images belong to. If you look into the <body> part of our example you will find an image with the name img1. We use the name of the image (and not its number) in order to be able to change the order of the pictures without changing the script. The two functions on() and off() are being called through the event-handlers onMouseOver and onMouseOut. As images cannot react to the events MouseOver and MouseOut we have to put a link around the images. As you can see the on() function sets back all other images.
This is necessary because it could happen that several images
are highlighted (the event MouseOut does not occur for example
when the user moves the cursor from an image directly outside
the window). Save these image files:
|
| 18) |
<html> <layer name=pic z-index=0 left=200 top=100> <img src="img.gif" width=160 height=120> </layer> <layer name=txt z-index=1 left=200 top=100> <font size=+4> <i> Layers-Demo </i> </font> </layer> </html> Save this image: img.gif You can see that we use the property z-index. This defines in which order the layers appear - i.e. in our case you tell the browser if the text will appear above or below the image. The layer with the highest z-index number will be displayed on top. You do not have to use 0 and 1 for the z-index - every positive integer is ok. |
Layers allows absolute positioning of objects like images. The layers options also you to move objects on your HTML-page and hide them What exactly are layers? This can be explained quite easily: you take several sheets of paper. On one paper you write a text. On another one you draw an image. Write some text besides an image on a third paper and so on. Now, put these sheets of paper on a table. Let's say every paper is a layer. From this aspect a layer is some kind of container. It can contain objects - i.e., in this case text and images. Layers that can contain several different objects - like images, forms, text etc. - can be placed on your HTML-page and can be moved around. If you move a layer, all objects contained in this layer will follow this movement. Layers can overlap each other like papers on a table. Every layer can have transparent parts. If you put a hole in paper - a transparent part of the image - and the contents of the underlying paper shines through. |
| name="layerName" | The name of the layer |
| left=xPosition | The horizontal position of the top left corner |
| top=yPosition | The vertical position of the top left corner |
| z-index=layerIndex | Index number of layer |
| width=layerWidth | Width of the layer in pixel |
| clip="x1_offset, y1_offset, x2_offset, y2_offset" | Defines the area of the layer which shall be displayed |
| above="layerName" | Defines above which layer this layer will appear |
| below="layerName" | Defines below which layer this layer will appear |
| Visibility=show|hide|inherit | The visibility of the layer |
| bgcolor="rgbColor" | The background color - either name of a standard color or RGB values |
| background="imageURL" | Background image |
| 1) |
<html>
<head>
<script language="JavaScript">
<!-- hide
function showHide() {
if (document.layers["myLayer"].visibility == "show")
document.layers["myLayer"].visibility= "hide"
else document.layers["myLayer"].visibility= "show";
}
// -->
</script>
</head>
<body>
<ilayer name=myLayer visibility=show>
<font size=+1 color="#0000ff"><i>
This text is inside a layer</i></font>
</ilayer>
<form>
<input type="button" value="Show/Hide layer"
onClick="showHide()">
</form>
</body>
</html>
|
There are several layer-properties which can be changed through JavaScript. This example presents a button which lets you hide and display one layer.
The button calls the function showHide(). You can see that this function accesses the property visibility of the layer-object myLayer. Through assigning "show" or "hide" to document.layers["myLayer"].visibility you can show or hide the layer. Please note that "show" and "hide" are strings - not reserved keywords, i.e., you cannot write document.layers["myLayer"].visibility= show. The <ilayer> tag is used instead of the <layer> tag because the layer is put in the flow of the document. |
| 2) |
<html>
<head>
<script language="JavaScript">
<!-- hide
function move() {
if (pos < 0) direction= true;
if (pos > 200) direction= false;
if (direction) pos++
else pos--;
document.layers["myLayer2"].left= pos;
}
// -->
</script>
</head>
<body onLoad="setInterval('move()', 20)">
<ilayer name=myLayer2 left=0>
<font size=+1 color="#0000ff">
<i>This text is inside a layer</i></font>
</ilayer>
</body>
</html>
|
The properties left and top define the position of the layer. You can assign new values to these properties in order to set the position of the layer. The following line sets the horizontal position of the layer to 200 (in pixels): document.layers["myLayer2"].left= 200; To program a moving layer, we create a layer called myLayer2. You can see that we are using onLoad inside the <body> tag. We need to start the scrolling of the layer as soon as the page is loaded. We use setInterval() inside the onLoad event-handler. This can be used to call a function over and over again in a certain time interval. setInterval() works almost the same - but you have to call it only once. Through setInterval() we are calling the function move() every 20 milliseconds. The function move() sets the layer to a certain position. As we call this function over and over again we get a fluent scrolling of the text. All we have to do in the function move() is to calculate the position of the layer and assign this value to document.layers["myLayer2"].left= pos. |
| 3) |
<p>
<ilayer name=myLayer3 left=0 top=40 z-index=201>
<font size=+1 color="#0000ff">
<i>This text is inside a layer</i></font>
</ilayer>
<ilayer name=myLayer4 z-index=200>
<img src="img.gif" width=160 height=120>
</ilayer>
|
This example demonstrates that layers can overlap: |
| 4) |
<html>
<head>
<script language="JavaScript">
<!-- hide
var middleX, middleY, pos;
function start() {
// get size of image
var width=
document.layers["imgLayer"].document.davinci.width;
var height=
document.layers["imgLayer"].document.davinci.height;
// calculate pixel in the middle of image
middleX= Math.round(width/2);
middleY= Math.round(height/2);
// starting position
pos= 0;
// start it!
show();
}
function show() {
// increase size of clipping area
pos+= 2; // step size
document.layers["imgLayer"].clip.left= middleX- pos;
document.layers["imgLayer"].clip.top= middleY- pos;
document.layers["imgLayer"].clip.right= middleX+ pos;
document.layers["imgLayer"].clip.bottom= middleY+ pos;
// check if the whole image has been displayed
if (!((pos > middleX) && (pos > middleY)))
setTimeout("show()", 20);
}
// -->
</script>
</head>
<body>
<ilayer name="imgLayer" clip="0,0,0,0">
<img name=davinci src="davinci.jpg" width=209
height=264>
</ilayer>
<form>
<input type=button value="Start" onClick="start()">
</form>
</body>
</html>
|
It is possible to change the clipping region of an image through JavaScript. For this you change the properties clip.left, clip.top, clip.right and clip.bottom of the Layer-object. Just assign a new pixel value to one of these properties and the clipping region will change. The following example changes the clipping region dynamically. The user gets the impression that the image is being built up slowly. The button in the <body>-part calls the function start(). First we have to calculate at which position we should start - this is the pixel in the middle of the image. We store the x and y values of this pixel in the variables middleX and middleY. Then the function show() is called. This function sets the clipping region depending on the variables middleX, middleY and pos. The variable pos is incremented everytime the show() function is called. This means the clipping region gets bigger every time. At the end of show() we set a timeout with setTimeout() - like this the show() function is being called over and over again. This process stops as soon as the whole image is displayed.
|
| 5) |
<html>
<head>
<script language="JavaScript">
<!-- hide
// starting position
var pos0= 0;
var pos1= -10;
var pos2= -10;
// moving?
var move0= true;
var move1= false;
var move2= false;
// direction?
var dir0= false;
var dir1= false;
var dir2= true;
function startStop(which) {
if (which == 0) move0= !move0;
if (which == 1) move1= !move1;
if (which == 2) move2= !move2;
}
function move() {
if (move0) {
// move parentLayer
if (dir0) pos0--
else pos0++;
if (pos0 < -100) dir0= false;
if (pos0 > 100) dir0= true;
document.layers["parentLayer"].left= 100 + pos0;
}
if (move1) {
// move parentLayer
if (dir1) pos1--
else pos1++;
if (pos1 < -20) dir1= false;
if (pos1 > 20) dir1= true;
document.layers["parentLayer"].layers["layer1"].top=
10 + pos1;
}
if (move2) {
// move parentLayer
if (dir2) pos2--
else pos2++;
if (pos2 < -20) dir2= false;
if (pos2 > 20) dir2= true;
document.layers["parentLayer"].layers["layer2"].top=
10 + pos2;
}
}
// -->
</script>
</head>
<body onLoad="setInterval('move()', 20)">
<ilayer name=parentLayer left=100 top=0>
<layer name=layer1 z-index=10 left=0 top=-10>
This is the first layer
</layer>
<layer name=layer2 z-index=20 left=200 top=-10>
This is the second layer
</layer>
<br><br>
This is the parent layer
</ilayer>
<form>
<input type="button" value="Move/Stop parentLayer"
onClick="startStop(0);">
<input type="button" value="Move/Stop layer1"
onClick="startStop(1);">
<input type="button" value="Move/Stop layer2"
onClick="startStop(2);">
</form>
</body>
</html>
|
We have already seen that a layer can contain several different objects. They can even contain other layers. There are several reasons for using nested layers. The first example uses a layer (called parentLayer) which
contains two other layers (layer1 and layer2). These buttons will start and stop the movement of the layers. You can see that moving the layer parentLayer also affects the other two layers. But moving the layer layer1 (or layer2) only affects this layer. This demonstrates that you can define groups of objects through nested layers. |
| 6) |
<html>
<head>
<script language="JavaScript">
<!-- hide
var pos= 0; // starting position
var direction= false;
function moveNclip() {
if (pos<-180) direction= true;
if (pos>40) direction= false;
if (direction) pos+= 2
else pos-= 2;
document.layers["clippingLayer"].layers["imgLayer"].top=
100 + pos;
}
// -->
</script>
</head>
<body onLoad="setInterval('moveNclip()', 20);">
<ilayer name="clippingLayer" z-index=0
clip="20,100,200,160" top=0 left=0>
<ilayer name="imgLayer" top=0 left=0>
<img name=davinci src="davinci.jpg"
width=209 height=264>
</ilayer>
</ilayer>
</body>
</html>
|
We have seen how to define a clipping region. The following example uses a clipping region and a moving image. What we want to achieve is that the clipping region is fixed - i.e., it does not follow the movement of the image. |
| 7a) |
Save this file as India.gif: Hotspot for Calcutta:
|
Save both files to your disk. Define two layers and make a mouseover on the dot for Calcutta (coordinates given) that displays the Calcutta GIF file. Move the Calcutta text so that it is positioned properly. |
| 7b) |
Layer to display when mouse is over hotspot for Calcutta. Save this file as Calcutta.gif |
What is VRML?
VRML (Virtual Reality Modeling Language) is an open, extensible, industry-standard scene description language for 3-D scenes, or worlds, on the Internet. With VRML and Netscape's Live3D, you can author and view distributed, interactive 3-D worlds that are rich with text, images, animation, sound, music, and even video. VRML 1.0 supports worlds with relatively simple animations while VRML 2.0 (still in development) supports complex 3-D animations, simulations, and behaviors by allowing Java and JavaScript programmers to write scripts that act upon VRML objects.
Earth in VRML
The Small Things that we Make Large From a speech given to the Department of Land Information Royal Melbourne Institute of Technology Melbourne, Australia August 1998
"The last of my three experiences in Australia happened in Kakadu National Park in the Northern Territory. On one of the ranger guided tours of the aboriginal petroglyphs in the park, a park ranger explained how closely the language of the local aboriginal group is tied to the land. The livelihood of the people was so dependent on the land that almost every word described some aspect of it.He went on to relay the story of a researcher who was driving a group of three aboriginal men on a country road where they lived. As they drove along, the three started to sing a song that described the countryside in which they were driving. When the car started to move along more swiftly, one of the men kicked the back of the driver's seat and shouted: "Slow down! We can't sing that fast."
"Slow down! We can't sing that fast."
I cannot even imagine a song that would describe a landscape, much less one where the speed of traverse would have any effect on how fast it was sung or even whether it could be sung.
"Slow down! We can't sing that fast."
From our highly trained perspective as surveyors and cartographers or students thereof, it would be easy to dismiss such a song as being primitive and useless. It doesn't mesh with how we describe the world, it probably lacks accuracy in our sense of the word, and of what use can it be?
I have been doing research on maps for over 20 years and, in the process, thinking about ways to improve maps so that they convey a better and truer representation of the environment. I have to tell you that I'm becoming increasingly skeptical about whether our current cartographic products communicate any useful information, especially the kind of information that effectively captures a place. For example, I viewed a great many maps of Australia before I arrived here, but nothing prepared me for what I encountered. All those maps that I looked at could just as well have been of another continent. Beyond the relative locations of the larger cities, the maps provided little information that meshed with my experiences here.
It may be that our maps developed for other purposes and were not intended as a way for people to learn about the world. Denis Wood argues in "The Power of Maps," that maps developed as an instrument of governments to wage war and assess taxes. Indeed, the United States uses detailed maps of the terrain, prepared at great expense, to precisely guide cruise missiles to their targets. With this type of mindset about the function of maps, it's not surprising that they are not useful descriptors of place.
"Slow down! We can't sing that fast."
It's good to be reminded that we don't know everything. Sometimes our attitude about knowledge reminds me of a friend who admitted to once being conceited. But, he went on, he had worked on that minor personality flaw, and now he was perfect."
Thank you attending this workshop. The page with all of the exercises and links will remain available at:
http://maps.unomaha.edu/Workshops/InteractiveMap.html.
You are welcome to visit this site at any time in the future. Changes and additions are always being made to the document.