Good morning! This morning, you will learn how to turn your Web page into a real visually driven point-and-click environment. Just put some glossy images on your Web page and let your mouse do the clicking. In this chapter, you will learn how to use image mapsany type of graphics image linked to a program that reads the coordinates of the mouse click and, from that information, directs the browser to a related URI. You will learn how image maps work to enhance your Web page, and you will learn about a new type of image mapclient-side image maps.
In particular, you will learn the following:
Image maps look really slick on your home page, and you can build them without any programming skills. The basic steps for creating a working image map follow:
Image maps link a graphics image with a program on the server that interprets the location of the mouse click and redirects the Web client to another URI based on that mouse click.
One really nice implementation of image maps is the virtual tourist program, which you can find at
http://wings.buffalo.edu/world/vt2/
At this site, they have a very nice image of the world separated into various regions that are separated by drawn-in polygons. Polygons are closed figures like a rectangle or a box that can have as many sides as required. So they usually end up being irregularly shaped objects, just like the ones you see in Figure 9.1, which is the Virtual Tourist's Map of the World.
Figure 9.1. The Virtual Tourist II Map of the World.
An image map usually is made up of regions, or hot spots, like this, as well as regions defined by circles, rectangles, and points. The actual image map is much less complex than a bunch of regions defined by circles, rectangles, and polygons, however. The image map itself is just any old image file that you happen to have taking up space on your hard disk or someone else's hard disk.
Don't forget that it doesn't take any longer for the browser to load an image off your hard drive than it does from some other server's hard drive. The Virtual Tourist II program makes use of this fact by loading its image of Madagascar from the Perry-Castaneda Library Map Collection at the University of Texas.
This library has a great collection of maps from all over the world, as shown in Figure 9.2, and can be reached at
http://www.lib.utexas.eduLibs/PCL/Map-collection/map-collection.htl
Figure 9.2. The Perry-Castaneda Library Map Collection.
When the Virtual Tourist loads up the map of Madagascar, it loads its image from the Perry-Castaneda library, and it is not an image map file.
Nothing prevents this image from being a map file except the HTML that defines the link to the map of Madagascar. The image of Madagascar is too big to fit onto a single screen, as shown in Figure 9.3, but image maps use the size of the image as a definition of the X,Y coordinates sent to your image map program, not the size of the screen displaying the image. The Madagascar image is approximately 985x1,250 pixels, as measured from the upper left corner to the lower right corner. Having a map that is bigger than the computer screen can make your Web clients uncomfortable, because they can't see all the information they need to make a decision in one screen. That's usually considered bad Human Factors design. But if you try to squish down the map of Madagascar into one screen, either you have to distort the image or you can't distinguish anything. So in this case, a large image is probably a good choice. Also remember that you might not be using images on your site. If that's the case, as it is here, you don't have any control over the image size.
Figure 9.3. A map of Madagascar.
You don't have to worry about your browser getting lost on where you're checking on the map. The browser knows the full size of the image and sends the X,Y coordinates of where the image was checked on, not where on-screen the mouse was clicked. Each mouse click sends to your CGI program the X,Y coordinates of the mouse click relative to the upper left corner of the image being clicked on. The coordinates are relative coordinates because all images, regardless of size or location on-screen, have the same starting X,Y coordinates of 0,0. The upper left corner coordinates are 0,0. All X,Y coordinates are in pixels. The X coordinate increases as your mouse moves from the left to the right of the image. The Y coordinate increases as your mouse moves from the top to the bottom of the image. So, if you had an image that was 600 pixels wide and 700 pixels tall, the coordinates of the upper left corner would be 600,0; the lower right corner would be 600,700; and the lower left corner would be 0,700.
The coordinates are sent as X,Y pairs separated by a comma when sent using the <IMG ISMAP> syntax and sent as name/value pairs, name.x and name.y, when using the HTML <FORM> <INPUT TYPE=IMAGE> syntax. As you would expect, the X coordinate is the first coordinate, followed by the Y coordinate.
Both coordinates are relative to the size of the image file and not the size of the screen. Therefore, if your image file is restricted by height and width commands, the X,Y coordinates passed to your program will be restricted to the maximum values in the Height and Width tags. If you do not restrict the height and width of the image, the maximum values for X and Y are not limited by the screen size. If the image scrolls vertically or horizontally, the browser will send the coordinates of the location selected on the image. This is very important, considering the wide variety of terminals available today. It is still very common to have a 14-inch monitor with 640x480 resolution, and the image that fits on that screen is wildly different than even the image that fills a 14-inch, 1,024x768 screen, much less one of the large 22-inch CAD-CAM user screens.
The coordinates are passed to your CGI program only when you add the ISMAP HTML attribute to the IMG HTML tag or the <INPUT TYPE=IMAGE> HTML Form tag. You can get these coordinates sent to you in a multiplicity of ways, which are discussed in the next section. As you learn about the existing image map program, remember that it is no more than another CGI program available for you to modify and enhance. You always can download the latest copy of the imagemap.c program from
http://hoohoo.ncsa.uiuc.edu/docs/tutorials/imagemap.txt
and modify it to fit your needs. So pay attention to the variety of ways in which you can get the X,Y coordinates of the mouse click, and consider how you might use them in your own customized CGI image map program.
Clicking on an image and getting the coordinates to a CGI program on the server can happen in more than one way. Most people just pass off this work to a predefined CGI program called imagemap.c on NCSA servers and htimage on CERN servers, but modifying or enhancing these programs to work within an HTML form or for other reasons isn't that difficult. In this section, you will learn how the X,Y coordinates are passed to the server and, with that knowledge, you can decide how those coordinates will be handled.
Listing 9.1 shows a short program that reads and prints the X and Y coordinates passed when the image map is clicked on. Figure 9.4 shows the output from Listing 9.1.
01: #!/usr/local/bin/perl
02: push (@INC, "/usr/local/business/http/accn.com/CGI-bin");
03: require("CGI-lib.pl");
04: &ReadParse(*stuff);
05: print &PrintHeader;
06: print "<html>\n";
07: print "<head> <title> Printing the x,y hot spot variables </title> </head>\n";
08: print "<body>\n";
09: print "<h3> The x,y coordinates of your mouse-click are: </h3> <hr noshade>";
10: print "x coordinate = $stuff{'xyhot.x'}<br>";
11: print "y coordinate = $stuff{'xyhot.y'}<br>";
12: print "</body>\n";
13: print "</html>\n";
Figure 9.4. The X,Y coordinates as received by the server.
The piece of HTML magic that makes all this work is the ISMAP tag added to any HTML image tag that is used as a hypertext reference or HTML Form action. The two valid types are the Web fill-out form <INPUT TYPE=IMAGE> tag and the IMG tag when used with an HTML anchor (<A>), which includes an href attribute.
When you use the Web fill-out form <INPUT TYPE=IMAGE NAME=xy-coordinates> tag, for example, the X and Y values of the mouse click pixel position in the graphics image are sent to your CGI program as name/value pairs. The X and Y values can be retrieved by using the name xy-coordinates.x for the X value and xy-coordinates.y for the Y value.
If you use the HTML anchor with a hypertext reference such as
<a href=http://www.accn.com/CGI-bin/xy-values.CGI> <img src=/images/madagascar.jpg ismap>
the X,Y coordinates values are sent in the query string as two integers separated by a comma. For example,
http://www.accn.com/CGI-bin/xy-values.CGI?125,845)
The X,Y coordinates are sent to the server only if your IMG link includes the ISMAP tag. The coordinate of the mouse click will not be sent if you do not include the ISMAP tags for a hypertext reference. This makes a lot of sense because if you don't direct the hypertext link to the image map program, the X,Y coordinates show up in the query string and you get the famous YUK! effect. This is something you wouldn't want to see every time someone clicked on an image.
The next few examples should help clarify the different results achieved when using the HTML ISMAP attribute.
In this example, the hypertext reference calls the NCSA image map program:
<a href=/CGI-bin/imagemap/mapfiles/mapfile.map> <image src-madagasc.jpg ISMAP> <a>
This hypertext reference creates an active link to the image map program passing and passes the image map program the X,Y coordinates of the mouse click. The X,Y coordinates are used by the image map program with the mapfile.map to call a URI defined in the mapfile.map. Both the image map program and the mapfile.map file are discussed in this chapter. The X,Y coordinates are not visible as query string data in the Location window, even though they are sent to the server as query string data.
In this example, the hypertext reference calls a custom CGI program that prints the X,Y values received:
<ahref=/cgibook/chap9/printvar.CGI> <image src=madagasc.jpg ISMAP> <a>
In this case, the hypertext link creates an active link with the image file. So when the image file is clicked on with the left mouse button, the X,Y coordinates of the mouse click are sent by the browser to the server in the query string. In this case, the X,Y coordinates do appear as query string data, as illustrated in Figure 9.4.
In this example, the hypertext reference calls a custom CGI program that prints the X,Y values received:
<a href="/cgibook/chap9/printvar.CGI"> <image src=madagasc.jpg width=950 height=500 ><a>
In this final example, using the href command, the X,Y coordinate data is not sent along with the URI because the ISMAP attribute is not included within the IMG command.
The alternatives when using the Web fill-out form <INPUT TYPE=IMAGE> are not necessarily intuitive, but are very consistent. To be consistent, you always should use the ISMAP tag, but in practice, with the Web fill-out form, the ISMAP tag has no impact on whether the X,Y coordinates are sent to the server. If the <INPUT TYPE=IMAGE>, the X,Y coordinates are sent to the browser. They are appended to the Name attribute of the <INPUT TYPE=IMAGE> field. That means they can be retrieved by your own CGI program as Name.x and Name.y, as shown earlier. The following two <INPUT> fields therefore have exactly the same effect:
<INPUT TYPE=IMAGE NAME=XY-COORDINATES ISMAP> <INPUT TYPE=IMAGE NAME= XY-COORDINATES>
Note: By the way, <ISMAP> is not case sensitive. In any of these links, <ismap> works just as well as <ISMAP>.
The two alternative input types work just fine in sending the coordinates to your own CGI program but fail miserably when you try to call the actual image map program. This means that in most cases you will not add image maps to your Web fill-out forms. If you are a C programmer, however, I think you will see that it would not be an overwhelming task to modify this program so that it works with Web fill-out forms. One possible modification is outlined in the next paragraph.
The image map program is freely available on the Net, so modifying the existing software is very reasonable. The part of the file that needs to be changed is included here as a program fragment in Listing 9.2. You want to make as small a change as possible, so changing how it loads up its input data is a prime candidate. This occurs where it checks for the number of incoming arguments. A test for the Request method of Post before line 11 could replace the assumption that the call is from a hypertext link. If the calling method is Post, the variables testpoint[x] and testpoint[y] could be set from the incoming name/value pairs of xy-coordinates.x and xy-coordinates.y. The rest of the program does not need to change.
01: int main(int argc, char **argv)
02: {
03: char input[MAXLINE], *mapname, def[MAXLINE], conf[MAXLINE], errstr[MAXLINE];
04: double testpoint[2], pointarray[MAXVERTS][2];
05: int i, j, k;
06: FILE *fp;
07: char *t;
08: double dist, mindist;
09: int sawpoint = 0;
10:
11: if (argc != 2)
12: servererr("Wrong number of arguments, client may not support ISMAP.");
13: mapname=getenv("PATH_INFO");
14:
15: if((!mapname) || (!mapname[0]))
16: servererr("No map name given. Please read the
17:HREF=\"http://hoohoo.ncsa.uiuc.edu/docs/setup/admin/Imagemap.html\">instructions</A>.<P>");
18:
19: mapname++;
20: if(!(t = strchr(argv[1],',')))
21: servererr("Your client doesn't support image mapping properly.");
22: *t++ = '\0';
23: testpoint[X] = (double) atoi(argv[1]);
24: testpoint[Y] = (double) atoi(t);
Of course, you're not limited to changing this program. Because you now understand that you can get the X,Y coordinates of the mouse click simply be adding an input type of image, you can build any type of image mapping program you want!
Now that you understand the limitations and possibilities that go with calling the image map program, take a look at how that program works on your server.
The NCSA httpd server uses a program called imagemap.c to determine what to do with the mouse-click coordinates sent to the server. Any image can be used with the image map program. The hypertext text reference points first to the image map program, and then includes extra path information. The extra path information tells the image map program where to find a map file. The map file is a plain text file that the image map program uses to determine what URI to call for each mouse click. This map file is explained in detail later in this chapter in the section "The Map File."
First, as you have seen from the previous examples, you must include an image with the ISMAP attribute added as part of the image command. Next, you must create a hypertext reference linking the image to the image map program.
If you are running an NCSA server or one of its clones, the image map directory should be in the public cgi-bin directory. Find out from your System Administrator where the public cgi-bin directory is located so you can add the complete path in the hypertext reference. On my server, I have a cgi-bin directory on my document root, so my path is simply href=/CGI-bin/imagemap. The NCSA documentation recommends using an absolute URI to reference the image map program, which would look like
http://www.server-name.com/CGI-bin/imagemap
That's step one of creating your hypertext link. Because the link actually is made up of the path to the image map program and the extra path info that points to your map file, you still need to add the extra path information. The extra path information is the full path to your image map file relative to your document root. In my case, I keep a map file directory below my document root, so the extra path information is /mapfiles/madagascar.map. The path to your directory needs to include your user name if you have a personal account on a commercial server. So the path to your image map file might look like this:
~username/mapfiles/mapfile.map
Remember to make sure your directory and file are readable and executable by the world. Otherwise, the image map program will not be able to open your map file. The full syntax of the URI linking the image map program to your inline image follows:
href://domain-name/<PATH-TO-IMAGEMAP-PROGRAM>/<PATH-TO-MAPFILE-FILE>
The PATH-TO-IMAGEMAP-PROGRAM should define the full path to the image map program and should end with the image map. According to the latest release notes of the image map program, the PATH-TO-MAPFILE-FILE can be relative to the document root or begin at a user's public HTML directory using the ~username syntax described earlier. An example of a valid hypertext reference to the image map program is
http://www.accn.com/CGI-bin/imagemap/mapfiles/madagascar.map
The <PATH-TO-IMAGEMAP-PROGRAM> is cgi-bin/imagemap and the <PATH-TO-MAPFILE-FILE> is mapfiles/madagascar.map.
The NCSA httpd server distributes the imagemap.c program as part of its server distribution. You can get the latest copy of the image map program from
http://hoohoo.ncsa.uiuc.edu/docs/tutorials/imagemap.txt
If you do this, you'll notice that this program has been in existence since 1993an eternity for anything on the Net. This program is written in the C language and is not terribly complex. If you get a copy of this program, you can modify it to suit your own needs and keep it in your local cgi-bin directory. The first part of the image map deals with figuring out where your image map file is and reading in the data in your image map file. This is the area where you could make enhancements. The second half and actually smaller portion of the program is the checking of the points against the defined circles, rectangles, and polygons of the image map file. I don't recommend changing this section, especially the polygon code, because determining whether a point is within a polygon can be relatively painful. Take a look at the code for yourself, shown in Listing 9.3. This is the real meat of the image map program. Most of the work is in determining whether the mouse click is in a polygon, a circle, or rectangle and point code is relatively straightforward.
01: int pointinrect(double point[2], double coords[MAXVERTS][2])
02: {
03: return ((point[X] >= coords[0][X] && point[X] <= coords[1][X]) &&
04: (point[Y] >= coords[0][Y] && point[Y] <= coords[1][Y]));
05: }
06:
07: int pointincircle(double point[2], double coords[MAXVERTS][2])
08: {
09: int radius1, radius2;
10:
11: radius1 = ((coords[0][Y] [ms] coords[1][Y]) * (coords[0][Y] [ms]
12: coords[1][Y])) + ((coords[0][X] [ms] coords[1][X]) * (coords[0][X] [ms]
13: coords[1][X]));
14: radius2 = ((coords[0][Y] [ms] point[Y]) * (coords[0][Y] [ms] point[Y])) +
15: ((coords[0][X] [ms] point[X]) * (coords[0][X] [ms] point[X]));
16: return (radius2 <= radius1);
17: }
18:
19: int pointinpoly(double point[2], double pgon[MAXVERTS][2])
20: {
21: int i, numverts, inside_flag, xflag0;
22: int crossings;
23: double *p, *stop;
24: double tx, ty, y;
25:
26: for (i = 0; pgon[i][X] != [ms]1 && i < MAXVERTS; i++)
27: ;
28: numverts = i;
29: crossings = 0;
30:
31: tx = point[X];
32: ty = point[Y];
33: y = pgon[numverts [ms] 1][Y];
34:
35: p = (double *) pgon + 1;
36: if ((y >= ty) != (*p >= ty)) {
37: if ((xflag0 = (pgon[numverts [ms] 1][X] >= tx)) ==
38: (*(double *) pgon >= tx)) {
39: if (xflag0)
40: crossings++;
41: }
42: else {
43: crossings += (pgon[numverts [ms] 1][X] [ms] (y [ms] ty) *
44: (*(double *) pgon [ms] pgon[numverts [ms] 1][X]) /
45: (*p [ms] y)) >= tx;
46: }
47: }
48:
49: stop = pgon[numverts];
50:
51: for (y = *p, p += 2; p < stop; y = *p, p += 2) {
52: if (y >= ty) {
53: while ((p < stop) && (*p >= ty))
54: p += 2;
55: if (p >= stop)
56: break;
57: if ((xflag0 = (*(p [ms] 3) >= tx)) == (*(p [ms] 1) >= tx)) {
58: if (xflag0)
59: crossings++;
60: }
61: else {
62: crossings += (*(p [ms] 3) [ms] (*(p [ms] 2) [ms] ty) *
63: (*(p [ms] 1) [ms] *(p [ms] 3)) / (*p [ms] *(p [ms] 2))) >= tx;
64: }
65: }
66: else {
67: while ((p < stop) && (*p < ty))
68: p += 2;
69: if (p >= stop)
70: break;
71: if ((xflag0 = (*(p [ms] 3) >= tx)) == (*(p [ms] 1) >= tx)) {
72: if (xflag0)
73: crossings++;
74: }
75: else {
76: crossings += (*(p [ms] 3) [ms] (*(p [ms] 2) [ms] ty) *
77: (*(p [ms] 1) [ms] *(p [ms] 3)) / (*p [ms] *(p [ms] 2))) >= tx;
78: }
79: }
80: }
81: inside_flag = crossings & 0x01;
82: return (inside_flag);
83: }
You can see the entire imagemap.c program in Appendix D. The first half of the program is much longer than the program fragment in Listing 9.3 and really is just dealing with figuring out what file to open and reading in the data. This is not as easy in C as it is in Perl. C is not nearly as helpful when it comes to doing data conversion as is Perl.
By now, you probably are ready to learn about the map file. This is the file that is pointed to by the extra path information in the URI. The map file is read by the image map program to determine what URI to point the browser toward based on the X,Y coordinates of the mouse click. Probably the most important thing to understand about the image map file is how it is interpreted by the image map program. The image map program doesn't spend a lot of time trying to figure out whether you want this mouse click to be in circle one or circle two. It looks at the first line in the image map file, and if the program determines that the mouse click is within this region, it prints a location response header with the URI defined in the image map file. The Location response header redirects the browser to another URI, making the mouse click act as if it is calling a different document.
Before you look at the exact syntax of the image map file, look at this summary on the actions of the image map program as seen from the server side:
The image map file tells the image map program what URI to call for a matching X,Y coordinate. The image map file itself is a simple text file that can be named anything you want, but it frequently has the file extension .map. Inside the NCSA server's version of the image map file you can include comments describing what each coordinate set is related to on the image file. All comments begin with a hash sign (#). The hash sign must begin the comment line flush against the left margin. Every other non-blank line describes the method used to find the X,Y coordinates, the URI, and the bounding coordinates of the method.
The syntax of active lines of the image map file follows:
METHOD URI Hot-Spot-coordinates
The method can be one of five choices defined in Table 9.1.
Method |
Meaning |
|
circle |
Defines an area described as a circle, which is mathematically defined as the center point X + Y coordinates, followed by any point on the edge of the circle X,Y coordinates. For example, |
|
Circle http://www.accn.com/cgi-bin/print-circle.cgi 450, 325 450, 325 | |
|
Default |
Default method that defines the action to take if a matching area is not found for the mouse click. Do not use the default method and point method together. The point method always overrides the default method. For example, |
|
default http://www.accn.com/nph-no-content.cgi | |
|
point |
Defines any point on the image in X,Y coordinates. The point method overrides the default method and is only selected if no other matching method can be found. You can have multiple points in your image map file. Each one is tested for the closest match to the mouse-click point. Each time the point method is checked by the image map program, a new default action may be selected. For example, |
|
point http://domain-name/path-filename 10,20 | |
|
poly |
Defines an area described as a polygon, which is mathematically defined as a series of vertices of X,Y coordinates that define a closed object made of no more than 100 vertices. For example, |
|
poly http://domain-name/path-filename 110,144 301,56 767,464 420,660 257,413 114,144 | |
|
The polygon code in the image map assumes a closed polygon, in which it assigns the value of the last point in the array of vertices to be equal to the value of the first point in the array of vertices. | |
|
rect |
Defines an area described as a rectangle, which is mathematically defined as the upper left X,Y coordinates and the lower right X,Y coordinates of the rectangle. For example, |
|
Rect http://domain-name/path-filename 230, 90 670, 575 |
The image map file can be named anything you like, but you cannot put it anywhere you want. Because the image map program uses the PATH_INFO environment variable to determine where to find the map file, you cannot place the image map file in the document root directory. If you place the image map file in the document root directory, there is nothing to append to the extra path information field of the URI.
The image map reference would look like
href://domain-name/CGI-bin/imagemap/
You can't add another forward slash (/). It's illegal and because the extra path information begins after the trailing forward slash (/), the PATH_INFO variable will be empty and the image map program will fail. However, you can put the image map file in a subdirectory below the document root. I recommend creating a subdirectory immediately below the document root called mapfiles. Then within the mapfiles directory, give each image map file a reasonable name associating it with the image and application the image map file is for. If you have lots of map files associated with many different applications, you might decide to create an image map file directory below each application.
Warning: Just remember, DO NOT put your image map file in the document root directory.
Following this description of what the image map is and how it works is some information on tools to help you build map files.
It is possible to make your image map operate more efficiently or quicker with a little discipline on your part. Even a cursory examination of the poly code in Listing 9.3 shows that the poly code contains several nested loops and requires much more calculations than the circle and rectangle code to determine whether a match is found. Just by choosing rectangles and circles over polygons, you will speed up the processing of your image maps on the server side. Don't avoid the polygon as a choice altogether. It's much more important to define regions that make sense to your Web client than it is to increase efficiency even by a few seconds. If you take a look at the world map shown in Figure 9.5, it just doesn't make sense to do this map configuration in anything other than polygons. Never chose efficiency over understandability.
The default URI in the map file presents you with an interesting problem. What do you do if your user clicks on your image map but doesn't select a valid region on your image map?
It is a server error to not have a default defined and have a mouse click that is not within a valid region. When you click on the world out in the middle of the ocean, you are sent to a textual version of the city.net Web site. I'm not sure if they are punishing me for clicking on their map in an unmarked region or if they figure that if I can't select a valid region with a mouse, I'm too stupid to use their map and I should be using text anyway. Actually, I'm sure that it is just a logical decision on the developers' part to move me to an area better suited to my talents. All kidding aside, links created by hypertext references always are faster, so moving the errant mouse clicker to a text input site is very reasonable.
I would have preferred a second or third option, however. Let's assume that because I'm on the WWW, I understand the point-and-click environment enough to not hurt myself. As a programmer, I then could interpret clicking on an invalid region of the image map as mostly a curiosity factor. Curiosity is a good thing as far as I am concerned, so I don't want to penalize my Web client any more than necessary. My client already is paying a penalty by having to wait for the image map program to run. So frequently, I choose one of two solutions. One involves not doing anything. Because it is an error to not have a default method defined in the image map file, you must have one defined for the default URI. If you define a default URI, however, the HTTP protocol requires that the URI provide a valid response header. In this solution, the program returns the No-Content response header sent by the non-parsed header script in Listing 9.4.
#!/usr/local/bin/perl print "Location: http://www.accn.com/cgibook/chap9/same.html\n\n";
The Web client has to wait for the image map program to run and figure out that nothing valid was selected, and then nothing happens. That is not necessarily the most enlightening response, but after clicking on a few areas that are not defined, most people will get tired of waiting for the image map program to run and then getting no response. They start clicking inside the lines and probably stay there from then on.
The map file still has one more secret to give up before you can make effective use of hot spots on your map. One of the problems you need to understand how to deal with is overlapping areas. This is a really common problem in dealing with all kinds of maps. Probably the easiest to imagine involves actually using a world mapfor example, the map of Europe shown in Figure 9.6. When someone views this map and wants to look at the city of Brussels or London or Paris, they should be able to click on that area and get the information they need about the city. That seems reasonable. But what do you do about the countries of Belgium, France, and the United Kingdom? If someone clicks within the general area of France, can you distinguish that from a click around the area of Paris or Bordeaux? The answer is a qualified yes.
Figure 9.6. Defining the hot spots of Europe.
A qualified yes because you need to think about how the map file is processed in order to make overlapping areas work. You don't want to present a confusing image to your Web client. And you want a consistent result from your program when someone clicks on your image. You can manage this by realizing that your map file is processed from top to bottom and that the image map program will return a hit on the first valid match it finds.
Think of a simple target made up of concentric circles. Each area overlaps the previous area, but if the bull's-eye area is the first region defined in your map file, any hits in the bull's-eye region are processed first and returned by the image map program. So, if you have defined your map file so that the bull's-eye region is followed by the 80s, then 60s, then 40s, and then 20s region, each click in the overlapping areas returns the correct hit. An example of such a map file is included in Listing 9.5. Notice that each region overlaps the one above it in the map file. The final rectangle region where no score is awarded overlaps all the previous regions.
Listing 9.5. A map file for creating a target.
default http://www.accn.com/target/you-missed-the-board.html circle http://www.accn.com/target/bullseye.html 475,375 475,350 circle http://www.accn.com/target/eighty.html 475,375 475,325 circle http://www.accn.com/target/sixty.html 475,375 475,290 circle http://www.accn.com/target/fourty.html 475,375 475,240 circle http://www.accn.com/target/twenty.html 475,375 475,190 rect http://www.accn.com/target/zero.html 205,130 743,650
Okay, lets go back to the more realistic example of mapping hot spots onto the European map shown in Figure 9.6. Now you really don't need a lot of fancy tools for building map files. They are only text files, and the format is relatively simple. This makes editing the map file easy once it is created, but creating all the points that go with the example map file of Europe would be too much work. I therefore use a program called Mapedit to build my map file, which is shown in Listing 9.6.
default http://www.accn.com/CGI-bin/return-same-location.CGI #Ireland circle http:/www.city.net/countries/ireland/dublin 219,703 223,691 #Switzerland circle http:/www.city.net/countries/switzerland/bern 493,948 501,936 poly bern 209,623 227,631 193,653 197,667 211,661 227,676 225,719 209,736 135,749 103,683 209,622 #United Kingdom circle http:/www.city.net/countries/united_kingdom/london 336,781 352,777 #Belgium circle http:/www.city.net/countries/belgium/brussels 423,812 425,823 #France circle http:/www.city.net/countries/france/paris 378,872 362,874 #France circle http:/www.city.net/countries/france/bordeaux 296,1006 303,1022 #Germany circle http:/www.city.net/countries/germany/berlin 613,750 613,765 #United Kingdom - This image overlaps with the city of #London. The circles that define the hot spots #for all cities in the United Kingdom must come before the polygon #that defines London poly http:/www.city.net/countries/united_kingdom 195,655 214,659 230,672 234,705 175,825 361,807 393,739 360,444 189,544 229,627 213,657 #Belgium- This image overlaps with the city of #Brussels. The circles that define the hot spots #for all cities in Belgium must come before the polygon #that defines Brussels. poly http:/www.city.net/countries/belgium 400,792 423,798 437,790 458,804 468,827 454,859 420,841 384,801 414,785 #France - This image overlaps with the cities Paris and #Bordueax. The circles that define the hot spots #for all cities in France must come before the polygon #that defines France poly http:/www.city.net/countries/france 386,801 392,815 420,841 445,857 471,871 505,879 487,923 478,925 453,961 471,983 465,1007 483,1051 464,1074 376,1093 253,1048 265,923 216,876 221,860 289,834 385,800 #Switzerland- This image overlaps with the city of #Bern. The circles that define the hot spots #for all cities in Switzerland must come before the polygon #that defines Bern poly http:/www.city.net/countries/switzerland 479,927 513,918 535,929 535,939 554,947 556,961 548,969 522,981 497,981 474,981 455,961 #475,929 #Germany- This image overlaps with the city of #Berlin. The circles that define the hot spots #for all cities in Germany must come before the polygon #that defines Berlin poly http:/www.city.net/countries/germany 481,726 515,680 607,683 626,709 650,805 591,833 630,880 604,902 615,924 531,924 487,918 #503,878 459,837 475,777 483,763 487,715
Mapedit is a WYSIWYG (What You See Is What You Get) editor for image map files. Mapedit is available at
http://sunsite.unc.edu/boutell/mapedit
but is not a freeware tool. This tool is copyrighted by Thomas Boutell, and single-user fees are $25. Mapedit enables you to designate the polygons, circles, and rectangles within the GIF and to specify a URL for each to link to. Take note that Mapedit only works with GIF files. You will have to convert your JPEG images back and forth between the two formats in order to use this tool.
Mapedit enables you to load your GIF image into a scrollable, resizable window and then draw polygons, circles, and rectangles on top of it, specifying a URL for each. Before you bring the Mapedit tool up, however, you should draw whatever clues you're giving to the person using your image mapwhich areas are hot spots. The Mapedit tool draws polygons, circles, and rectangles, but it doesn't modify the image itself. So when you save your changes in Mapedit, you are saving changes to the image map file that stores the coordinates of each figure you drew, but not a modified image file. This, of course, is a good thing. If you're designating hot spots on the European map (no pun intended), you don't really want the polygons you used to define a country's borders to obscure the map. The existing map has enough information to tell your Web visitor that clicking in France will bring up information on France.
However, if you have selected a couple of cities as hot spots, as shown in Figure 9.7, you want to provide extra information that indicates that clicking in this area will provide information on the city and not the country. When this is the case, you will need to use some other tool to modify your image, so that you can draw the permanent circles you see in Figure 9.7. I recommend Paint Shop Pro as a reasonably price shareware tool. If you're really desperate, you can even use the Paintbrush tool provided with MS-Windows; however, it only reads BMP files, so I don't recommend it. Drawing circles and squares and polygons is not very difficult. Just find a tool you are comfortable with that enables you to work with a variety of file formats and has some drawing capability.
Figure 9.7. Creating hot spots on the map.
When you start up Mapedit, pull down the File menu and choose Open/Create Map. A dialog box appears. You need to enter the file name you would like to give to your map, which should not already exist, and the file name of a GIF image the map will be of, which must exist. When you start out using the Mapedit program, it enables you to choose whether you want an NCSA or CERN image map file format. One nice feature of Mapedit is its capability to switch between the two image map file formats with almost zero effort. With Mapedit's Save As menu option, you just change the setting of the Style menu that appears to convert from NCSA to CERN or vise versa, and your image map file is converted to the new format. That's really nice and simple.
If the map file does not already exist, you are asked whether you want to create it. Click OK to continue. If the map does exist, Mapedit determines the server type of the file regardless of previous file settings.
Mapedit then loads your GIF image into memory, and you get a friendly reminder to pay Tom his $25 while you are waiting. This isn't the fastest program in the world, so be prepared for a small delay while the image is loading. When the image is loaded, it appears in the main Mapedit window, which should expand or shrink to suit the image. If the image is large, scroll bars for horizontal and vertical movement may appear. You can navigate the image by using the scroll bars; you also can resize the window arbitrarily.
Mapedit often dithers the incoming GIF image. This has no affect on the image itself because Mapedit will never change the GIF fileonly the image map file. Mapedit uses your system palette's colors to approximate the colors in the image as closely as possible.
Drawing the actual hot spots on your image map is relatively simple using Mapedit, which is the point anyway. You can create circles, rectangles, or polygons. You cannot designate a point with Mapedit; however, you can designate a default action.
Select Polygon from the Tools menu to begin drawing a polygonal hot spot. Now click the left mouse button at some point on the edge of an area of interest in the image. Move the mouse pointer to another point on the edge of the area of interest, tracing its outline. A "rubber-band" line follows your mouse from the point of the initial click. Click again at this second point. Continue clicking points until you have outlined all but the final connection back to the first point. (You do not need to hold down the mouse button.) If you don't like the way your polygon is turning out, you can press Esc to cancel it and then start over with the left mouse button. To complete the polygon, click the right mouse button. Another window appears, prompting you for the URL to which this polygon should link. If you don't yet know the URL, type a name that is meaningful to you so that you will be able to recognize it later. Also add any comments you want in the Comments window. Click OK or press Enter to continue. (The Enter key only has this effect in the URL window because multiple-line comments are allowed in the Comments window.)
The polygon now is traced in solid white and a final side between the last point and the first point is added automatically. (If the white outline is not easily visible on this image, try choosing Edit Sketch Color from the File menu.)
Creating rectangles is no more difficult; just select Rectangle from the Tools menu. Click the left mouse button in one corner of a rectangular region of interest in the image. Now move the mouse pointer to the opposite corner, tracing out a rectangle. (You do not need to hold down the mouse button.)
Click the right mouse button to accept the rectangle, and enter a URL for it as you did for the polygon. (Just as for polygons, you can use Esc to cancel the rectangle while you are tracing it out.)
Circles work just like rectangles, except that the left mouse click positions the center of the circle, and you then can move the mouse pointer to any point on the edge of the desired circle and click the right mouse button to accept it.
The default color of white for drawing your hot spot regions is not always a good choice. You can edit the hot spot color by choosing Edit Sketch Color from the File menu. You are presented with the standard color selection dialog box, in which you can click on a color of your choice. Look for a color that contrasts well with the colors present in your images.
Don't forget the default URL; remember that it is an error to create an image map file where a default is undefined and still possible. You won't see this error until you test your image map on your server. Then when you or someone else selects an area that has neither a hot spot region defined nor a default selection, you will get the error message shown in Figure 9.8.
Figure 9.8. The error message sent by the image map program when a default URI is undefined.
To set a default URL, pull down the File menu, choose Edit Default URL, and enter a default URL in the window that appears. Click OK or press Enter to accept it. On the other hand, you may want to get rid of the default URL completely. After you set a default URL, a Delete button appears in the Edit Default URL dialog box. Click this button to remove the default URL.
Note: The testing tool does not indicate when the default URL would be used. It was felt that not displaying anything clearly indicates that the click is not in any hot spot.
Often, you will not know the final URL for each hot spot at first, or you will want to change it. You can do so by choosing Test/Edit from the Tools menu, clicking in the hot spot in question, editing the URL that appears, and then clicking OK or pressing Enter. You also can edit in the Comments window at this time. (The Enter key does not dismiss the pop-up menu while in the Comments window; click the OK button instead.) Note that you can cut, copy, and paste in the URL window and URL Comments window using the Ctrl+X, Ctrl+C, and Ctrl+V shortcut keys (just as in all other Windows applications).
You will find the Test/Edit feature of Mapedit quite handy, especially if you end up creating overlapping hot spots as I have in the European map in Figure 9.9. This map has hot spots around Paris, Bordeaux, and all of France. In Figure 9.9, you can see the France region highlighted and the pop-up window associated with this hot spot. In the pop-up window, you can see that I haven't associated a URI with this hot spot yet. This feature enables you to sketch out how you want to build your image map before you have everything defined.
Figure 9.9. Using the Test/Edit feature of Mapedit.
Image maps are a wonderful tool but there is a better tool on the horizon. Client-side image maps are implemented in the Netscape 2.0b version, released for evaluation in October 1995. By the time you read this chapter, Netscape 2.0 with all of its extensions should be released, and one of those extensions should be client-side image maps.
There are several disadvantages to server-side image maps, but probably the largest is that a call to the server is required merely to determine where the link is directed. This really slows down performance. In addition, there is no way for a browser to provide visual feedback to the user showing where a portion of an image map leads before the user actually clicks on it.
Client-side image maps keep the advantages of a point-and-click graphical interface while getting rid of the burden of the server interface.
Adding a USEMAP attribute to an IMG element indicates that it is a client-side image map. The USEMAP attribute can be used with the ISMAP attribute to indicate that the image can be processed as either a client-side or server-side image map. The argument to USEMAP specifies which map to use with the image, in a format similar to the HREF attribute on anchors. The USEMAP attribute overrides the effect of an enclosing anchor (a) element. This allows backward compatibility with browsers that do not support client-side image maps. If the browser does not understand the USEMAP attribute, it performs the action in the anchor (a) hypertext reference (href). If the browser understands the USEMAP attribute, it ignores the anchor (a) hypertext reference and uses the URI referenced in the Map Area tags.
The syntax of the USEMAP attribute is USEMAP="map-filename#mapname" or USEMAP="#mapname". If the argument to USEMAP starts with a '#', then the browser uses the map name as a reference to a MAP tag inside the current file. Otherwise, the browser tries to find the USEMAP file on the local disk and then uses the map name to locate the specific map tag referenced in the USEMAP attribute.
This is a really nice feature because you now can use a common navigation banner across the top or bottom of your Web page and a common file to interpret that common navigation bar. This way, when you need to update the hot spots on your navigation banner, you can go to the common file and make your updates instead of going to all the Web pages that use that navigation banner and updating them one at a time.
An example of the USEMAP syntax follows:
<IMG src=/images/world.jpg USEMAP=#worldmap>
This example references the Map HTML tag that follows. This Map tag must be in the same file as the USEMAP attribute:
<MAP NAME="worldmap"> <AREA SHAPE="RECT" COORDS="10,10,150,150" HREF=" http://www.accn.com/world/Europe.html"> <AREA SHAPE="CIRCLE" COORDS="450,330,30" HREF=" http://www.accn.com/world/Asia.html"> <AREA SHAPE="POLYGON" COORDS="10,10,150,150,200,240" HREF="http://www.accn.com/world/nowhere.html"> </MAP>
The HTML Map tag has a closing </MAP>, and includes a Name attribute that defines the name of the map, whether the map file is in the same HTML file or in a separate HTML file, so that the map file can be referenced by an IMG element. The syntax is <MAP NAME="mapname">. Between the opening and closing Map tags, an arbitrary number of Area tags are allowed.
The Area tag can be used only within an opening and closing Map tag.
The Area tag is used to define the shape of the client-side hot spot and the resulting action when the hot spot is selected.
The shape of the hot spot is defined using the Shape attribute. The Internet draft, "A Proposed Extension to HTML: Client-Side Image Maps," written by James L. Seidman of Spyglass, Inc. (and where most of this information comes from), defines the shapes of circle, rectangle, polygon, and a nohref, which is used to define the default regions. However, Netscape's 2.0b release and Spyglass's Mosaic 2.1 only implement the rect shape. Maybe it got implemented because it is the only shape that is abbreviated. In addition, the draft document itself states that "It is inappropriate to use Internet-Drafts as reference material or to cite them other than as work in progress." And so it is, fortunately or unfortunately, depending on how you view it; the entire Internet is a "work in progress" and isn't waiting for any formality to move onto the next new frontier. I suspect that by the time you read this book, client-side image maps will be common to most browsers.
If an Area tag is defined without a shape attribute, the rect shape is assumed by the browser.
The COORDS tag describes the position of an area. As with the image map file, the coordinates of the hot spot are defined using image pixels as the units, with the origin at the upper left corner of the image.
For a rectangle, the coordinates are given as left,top,right,bottom. The rectangular region defined includes the lower right corner specified; to specify the entire area of a 100x100 image, for example, the coordinates would be 0,0,99,99.
For a circular region, the coordinates are given as center_x,center_y,radius, specifying the center and radius of the circle. All points up to and including those at a distance of radius points from the center are included.
For a polygonal region, the coordinates specify successive vertices of the region in the format x1,y1,x2,y2,...,xn,yn. If the first and last coordinates are not the same, a segment is inferred to close the polygon. The region includes the boundary lines of the polygon. For example, 20,20,30,40,10,40 specifies a triangle with vertices at (20,20) (30,40), and (10,40). No explicit limit is placed on the number of vertices, but a practical limit is imposed by the fact that HTML limits an attribute value to 1,024 characters.
The NOHREF attribute indicates that clicks in this region should perform no action. An HREF attribute specifies where a click in that area should lead. A relative anchor specification will be expanded using the URI of the map description as a base, instead of using the URI of the document from which the map description is referenced. If a BASE tag is present in the document containing the map description, that URI will be used as the base.
The NOHREF attribute seems to be redundant because the definition states that a mouse click in an undefined region results in no action from the browser.
In this chapter, you learned that image maps are graphical images used to direct your Web client to other resources. Image maps take the place of the more traditional textual links. Image maps take advantage of the old saying, "A picture is worth a thousand words." With well-designed image maps, you can efficiently direct your Web site visitors with one picture where paragraphs of text otherwise would have been required.
You should be cautious of overusing image maps, however. It takes longer to load images than text, and every click on an image map requires an extra connection to the server to define where the X,Y coordinates of the mouse click should send your Web site visitor. You also learned of a future solution to some of the down sides of image mapsnamely, the client-side image map. This new feature is just beginning to be used as this book is being written, but it shows great promise for increasing the use of image maps while decreasing some of the penalties of using image maps.
To turn an image into an active image map, all you need to do is add the ISMAP attribute of the IMG tag and link the image to the image map program. Then create a text file called an image map file that defines the hot-spot areas and the URI to call when a hot spot is selected.
Image maps can really enhance your Web site and generally are easy to install. So, grab an image file and spruce up your home page.
Q: I'm on a CERN server; what about me?
A: This chapter applies to you just as well, only the names are changed to confuse everyone. The Mapedit program enables you to switch between NCSA and CERN map file format, and the program name is htimage instead of image map. Most of the differences are very minor. You can learn more about the CERN image map format at
http://www.w3.org/hypertext/WWW/Daemon/User/CGI/HTImageDoc.html.
Q: I can't find the image map file on my server.
A: This is often a question for your Web Master. However, there are a couple of choices you can make here. First, the image map program is only a C file, so you can download it from the NCSA tutorial site defined earlier and just compile it into your own cgi-bin directory. Another choice is to use the Unix find command and search for the image map program.
To locate the image map program using the find command, enter the following command on the Unix command line:
find /usr -name imagemap -print
Q: I can't get the image map program to find my map file.
A: Do you have your map file in the top-level directory? This is a common mistake. Remember that the image map file uses the EXTRA_PATH_INFO environment variable. The top-level directory is illegal as a choice for your map file because you can't pass a forward slash (/) as EXTRA_PATH_INFO. Also remember that the image map program might not be in your document tree, and the EXTRA_PATH_INFO must include the full path to your map file.
Q: I really need to use polygons. Is there anything I can do to speed them up?
A: Sure. As I said earlier in this chapter, you really should use the most visually correct format for the hot spots on your image map. So using polygons makes sense quite often. You can speed up the processing of the polygon code simply by limiting the number of vertices in the polygon. It usually isn't required to make a very finely detailed polygon to outline even the borders of countries. When people want to look at the map of France, they usually are going to click in the middle of France and not the edge of France. If they are clicking out by the edges and get another country, I don't think you should feel too bad about that.
Q: I can't get the X,Y coordinates I want out of the Mapedit program. What should I do?
A: The map file is a simple text file, and you should edit it to redefine the exact X,Y coordinates you need for your hot spots. I personally only use the Mapedit program to approximate the X,Y coordinates I need. I then use my copy of Paint Shop Pro to determine the exact X,Y coordinates I want. At the bottom of this excellent shareware program, the X,Y pixel position your cursor is on in the image map is displayed. Just replace the X,Y coordinates in the map file with the ones on your screen. Don't over do this, though. Frequently it is not necessary to be exactly at the pixel in order to define good hot spot areas.