This tutorial builds a four-level map drilldown system in JSP using strategies similar to those in the Building a Map Drilldown System tutorial. The process is complicated somewhat because of the nature of zip code maps, which can cover very small areas in large cities, but very large rural areas.
The goal is to build a system that drills progressively down from a United States map to a map of each zip code. Although this tutorial is limited to a four-level U.S.zip-code implementation, the strategies in this tutorial can be applied to create any map drilldown system. The tutorial is divided into the following sections:
To keep this tutorial simple, it does not connect to any data (although connecting to data is discussed at the end of the tutorial). Also, the example code in this tutorial is for JSP only. However, with minor syntax changes you can follow along in any Corda Server-supported Web scripting language.
The sample code in this tutorial is provided in JSP only, but it can be tweaked to other languages fairly easily.
The ITXML file is <document_root>\image_templates\examples\maps\drilldownUS.itxml. The JSP code is <product_root>\Server\dev_tools\JSP\drilldownUS.jsp. Translations of this Web page into other Corda-supported Web application environments are available in their respective <product_root>\Server\dev_tools directory.
This tutorial assumes that the Web server, Corda Server™, and Corda Builder™ are all running on the same machine. If this is not the case, make appropriate adjustments, such as uploading the ITXML file or JSP to the appropriate server, and changing the server address in the JSP.
Note: A similar, but less complicated tutorial based on ASP can be found in Building a Map Drilldown System.
Before starting this tutorial, test your environment by publishing a basic map to the Web application server, as described in Publishing the Project in the Corda Builder User Guide.
This tutorial requires the U.S. Zip Code map package from the Corda® Technologies Web site (http://www.corda.com/download/maps), which must be purchased separately.
Note: You can create a three-level drilldown system in JSP using this tutorial with the OptiMap-included maps, but not a four-level drilldown system.
Review the information about dynamic objects (see Dynamic Objects) and drilldown (see Building Drilldown).
For more information about how zip code maps work, see Setting Data for Aggregated Shapes in the Corda 7 Map Guide.
This tutorial creates a four-level map drilldown system for U.S. zip codes using one Image Template file and one Web page. This tutorial takes approximately 30 minutes.
To create a basic map drilldown system
Start Corda Builder and create a new Image Template file.
Click the Dynamic Object button on the toolbar, or select Edit > Create Dynamic Object to add a dynamic object.
You may want to resize the dynamic object since the size of the maps you publish are created the same size as the dynamic object in the Image Template file.
Add other objects as needed.
Add any other objects that you want, including textboxes and shapes.
Note: To add a legend, make sure you select the dynamic object.
Test the Image Template file using Preview With PCScript.
Click the Edit PCScript button in the Corda Builder toolbar and enter the following PCScript into the main window:
dynamic.setITXMLAttributes(file-name='shared\maps\US\US_State.itxml' object-name='US_State')
This PCScript tells Corda Server the location (shared\maps\US\US_State.itxml), relative to <document_root>, and name (US_State) of the map with which to replace the dynamic object.
Click the Preview with PCScript button, which displays a map of the United States.

Note: Legends aren't displayed until after you specify data.
Save the Image Template file.
Save the Image Template file's JSP Sample Code to the Web server.
To do this, click the Sample Code button in the Corda Builder toolbar. Select JSP (Java* Embedder) from the Sample Code For pull-down menu (or the appropriate scripting technology for your environment). Make any necessary changes to the server address and image type, and click Save Code to File. Specify a file name, and save it to the Web server (for example, C:\Program Files\Apache Tomcat 4.1\Webapps\ROOT).
Open the file you just saved in a text editor.
Insert ITXML to specify the map to insert in the dynamic object.
To do this, add two ITXML statements to the file. First, define a variable to hold the ITXML string to send to Corda Server. Add this line of code immediately before the CordaEmbedder object declaration (i.e., the line that begins CordaEmbedder myImage...). For example:
String mapsource="<cit:dynamic-map-object name="dynamic" file-name='shared\maps\US\US_State.itxml' object-name='US_State'/>";
The variable is mapsource, and the dynamic object is dynamic. This ITXML string specifies the location and name of the map to insert into the dynamic object. For more information about object names, see Object Names in the Corda Builder User Guide.
Second, send this string to Corda Server using the addITXML command, as shown in the preceding line of code. Insert this line somewhere before calling getEmbeddingHTML. For example:
myImage.addITXML(mapsource);
Important: Make sure the JSP page does not contain any PCScript definitions. Set the pcScript variable to an empty string (""), or it may interfere with the tutorial.
Save the JSP file, and test it to make sure it loads the map of the United States.
For example, if you saved the JSP file to the Web Application server's ROOT directory, and the Web application server runs on port 8080, test the JSP by browsing to http://localhost:8080/drilldownUS.jsp .
Define variables in the JSP file to represent the map location and map name.
Place these definitions before the map source ITXML definition in Step 8. For example:
String maplocation = "shared/maps/US/";
String mapname = "US_State";
Rewrite the map source ITXML string to make use of the map location and name variables.
For the file-name attribute, combine the map location and map name, followed by .itxml . For the object-name attribute, just use the map name. For example:
String mapsource="<cit:dynamic-map-object name=’dynamic’ file-name='" + maplocation + mapname + ".itxml' object-name='" + mapname + "'/>";
Once you have made these changes, save the JSP and test it again to make sure there are no error messages.
Insert an if-then clause that overrides the map name and location based on information from the Web page's query string.
The query string is passed to the Web page from the drilldown command, and contains two pieces of information: the nameclass, which specifies the current level of the drilldown system (e.g., State); and the map, which specifies the map to show.
Note: Creating a query string is discussed in Step 13.
Retrieve this information from the query string using the request.getParameter method. The following example returns the nameclass (the current drilldown level):
request.getParameter("nameclass")
Note: The methods for retrieving query string parameters vary greatly by scripting language. Consult the scripting language documentation for more information.
This tutorial sample has several levels of maps. The top level is the default level (the U.S. map), so it doesn't require an if-then clause. The second level is the State, so an if-then clause checks to see if nameclass is State. If it is, it makes appropriate changes to the map name and location. For example:
String nameclass = request.getParameter("nameclass");
if ((nameclass != null) && nameclass.equals("State")) {
maplocation += "State_County/";
mapname = request.getParameter("map");
}
Note: Place this code after the default map name and map location definitions, but before the map source definition.
Each line of code does the following:
First line: Checks the query string for the value of nameclass. If nameclass does not exist, or is not equal to State, the remaining lines are ignored.
Second line: Reassigns the map location to the directory that contains the state map to display (in this case the State_County directory inside of the root map directory (shared\maps\US\State_County\).
Third line: Reassigns the map name to the value of the map parameter in the query string.
Fourth line: Closes the if-then clause.
The code sample below provides the complete JSP code:
JSP for a Map Drilldown System (2 Levels)
<%@ page language="java" contentType="text/html" %>
<%@ page import="com.corda.CordaEmbedder" %>
<html>
<head>
<title>JSP Example</title>
</head>
<body>
<h1>Your image will appear below</h1>
<!-- Begin Embedder Code -->
<%
String pcScript = "";
String maplocation = "shared/maps/US/";
String mapname = "US_State";
String nameclass = request.getParameter("nameclass");
if ((nameclass != null) && nameclass.equals("State")) {
maplocation += "State_County/";
mapname = request.getParameter("map");
}
String mapsource = "<dynamic-map-object name=\"dynamic\" file-name='" + maplocation + mapname + ".itxml' object-name='" + mapname + "'/>";
CordaEmbedder myImage = new CordaEmbedder();
myImage.externalServerAddress = "http://<server_address>:2001";
myImage.internalCommPortAddress = "http://localhost:2002";
myImage.imageTemplate = "examples/maps/drilldownUS.itxml";
myImage.userAgent = request.getHeader("USER-AGENT");
myImage.width = 480;
myImage.height = 360;
myImage.returnDescriptiveLink = true;
myImage.language = "EN";
myImage.pcScript = pcScript;
myImage.outputType = "FLASH";
myImage.addITXML(mapsource);
%>
<%= myImage.getEmbeddingHTML() %>
<!-- End Embedder Code -->
</body>
</html>
Save the JSP file, and test it by requesting a state map
To request a state map, request the same Web page from Step 9, adding the appropriate query string.
The query string syntax is as follows:
?parameter1=<value 1>¶meter2=<value 2>...¶metern=<value n>
For example, to request a map of Texas, enter the following in a Web browser:
http://localhost:8080/drilldownUS.jsp?nameclass=State&map=TX
In Corda Builder, open the Image Template file and access the dynamic object's properties in Object Properties.
From the Object List, expand the Dynamic object and select Areas. In Object Properties, browse to Default Shape > Drilldown > URL.
Insert the following in the URL attribute:
Javascript:window.location.replace(window.location.pathname+"?nameclass=%_NAMECLASS&map=%_NAME");%_JS_ENCODE
In operation, the macros in the URL string are replaced with real values in the map on a state-by-state basis, producing drilldown destinations like that used in Step 13.
Save the Image Template file.
Reload the main Web page (from Step 9). Click on any state to drill down to a detailed map of that state.
You have created a two-level drilldown system. The following steps add two more drilldown levels.
Below the first if-then statement, add an else if statement to handle the County level of the drilldown system.
This time, check for the County nameclass. When in the County level, request maps from the Zip/County_Zip folder. For example:
else if ((nameclass != null) && nameclass.equals("County")) {
maplocation += "Zip/County_Zip/";
mapname = request.getParameter("map");
}
Note: If you do not have the zip code maps, append "County" to the maplocation parameter instead of "Zip/County_Zip." You cannot proceed with this tutorial beyond the next step.
Reload the main Web page (entered in Step 9). Now click a county to open a detailed map of that county.
The detailed county maps are subdivided into zip codes—one shape for each zip code. However, heavily populated counties might instead be divided into 3-digit zip code regions. For example, Harris county (48201.itxml) in Texas has a zip code region shape named 770xx instead of separate shapes for each zip code that begins with 770 .
Add another else if statement to handle the aggregate zip code regions in the drilldown system.
This time, check for the Zip Group nameclass. When in the Zip Group level, request maps from the Zip/Zip3Digit_Zip folder. For example:
else if ((nameclass != null) && nameclass.equals("Zip Group")) {
maplocation += "Zip/Zip3Digit_Zip/";
mapname = request.getParameter("map");
}
From the Object List, expand the Dynamic object and select Areas. In Object Properties, browse to Default Shape > Drilldown > URL2.
Insert the following in the URL2 attribute:
Javascript:window.location.replace(window.location.pathname+"?nameclass=%_NAMECLASS&map=%_NAME");%_JS_ENCODE
Step 15 added a global drilldown string to automatically drilldown to the next map level using the URL attribute in the Drilldown tag for our default shape property. However, aggregate shapes do not use the standard URL attribute for drilldown. Instead, they look for a URL2 attribute.
Note: For this tutorial, both URL and URL2 drilldown to the same location.
Save the changes to the Image Template file and JSP, then reload the main Web page (the address from Step 9). Click a zip code region to open a detailed map of that zip code region.
Add code to the last two levels to eliminate drilldown.
Even though this is the bottom level of the map drilldown system, the maps assume they can drilldown to another level. This is because the global drilldown string is still active. To disable drilldown on the lowest level, manually override the global drilldown string.
To do this, create an empty drilldown string at the top of the page, and pass it as an argument to a myImage.addITXML call right after myImage.addITXML(mapsource).
In the last two else if clauses, add the following code to eliminate drilldown.
ITXML to eliminate drilldown effects
drilldown="<cit:dynamic-map-object name="dynamic">
<cit:layer name="Areas">
<cit:default-shape>
<cit:drilldown url=””/>
</cit:default-shape>
</cit:layer>
</cit:dynamic-map-object>
Note that this doesn't eliminate drilldown from the aggregate zip code shapes on the third level because it does not override the URL2 attribute. However it does eliminate drilldown from regular zip code shapes on the third level, since it sets the URL attribute to an empty string.
Save the changes to ther JSP, and reload the main Web page (from Step 9). The bottom level of the map system should no longer be enabled for drilldown.
The example below includes the complete code for this tutorial:
JSP Code for a Zip-Code Map Drilldown System (Complete)
<%@ page language="java" contentType="text/html" %>
<%@ page import="com.corda.CordaEmbedder" %>
<html>
<head>
<title>JSP Example</title>
</head>
<body>
<h1>Your image will appear below</h1>
<!-- Begin Embedder Code -->
<%
String pcScript = "";
String maplocation = "shared/maps/US/";
String mapname = "US_State";
String drilldown = "";
String nameclass = request.getParameter("nameclass");
if ((nameclass != null) && nameclass.equals("State")) {
maplocation += "State_County/";
mapname = request.getParameter("map");
}
else if ((nameclass != null) && nameclass.equals("County")) {
maplocation += "Zip/County_Zip/";
mapname = request.getParameter("map");
drilldown="<cit:dynamic-map-object name="dynamic">
<cit:layer name="Areas">
<cit:default-shape>
<cit:drilldown url="/">
</cit:default-shape>
</cit:layer>
</cit:dynamic-map-object>}
else if ((nameclass != null) && nameclass.equals("Zip Group")) {
maplocation += "Zip/Zip3Digit_Zip/";
mapname = request.getParameter("map");
drilldown="<cit:dynamic-map-object name="dynamic">
<cit:layer name="Areas">
<cit:default-shape>
<cit:drilldown url="/">
</cit:default-shape>
</cit:layer>
</cit:dynamic-map-object> }
String mapsource = "<DynamicObject Name='dynamic' file-name='" + maplocation + mapname + ".itxml' object-name='" + mapname + "'/>";
CordaEmbedder myImage = new CordaEmbedder();
myImage.externalServerAddress = "http://<server_address>:2001";
myImage.internalCommPortAddress = "http://localhost:2002";
myImage.imageTemplate = "examples/maps/drilldownUS.itxml";
myImage.userAgent = request.getHeader("USER-AGENT");
myImage.width = 540;
myImage.height = 330;
myImage.returnDescriptiveLink = true;
myImage.language = "EN";
myImage.pcScript = pcScript;
myImage.outputType = "FLASH";
myImage.addITXML(mapsource);
myImage.addITXML(drilldown);
%>
<%= myImage.getEmbeddingHTML() %>
<!-- End Embedder Code -->
</body>
</html>
Note: For a review of important tutorial concepts, see Conceptual Review
Look back to Step 12 of the tutorial. This step retrieves several parameters from the query string. These parameters specify the map to load, but can also determine the query to perform on the database.
For example, the following query provides data for the state of Texas:
SELECT County,sum(Sales-Expenditures) FROM Revenue WHERE Date between #7/1/2003# and #7/31/2003# AND State = 'TX' GROUP BY County
Make this query dynamic by using the map name variable. Thus, in the if-then statement for the State name class, assign a variable named query to the following value.
query = "SELECT County,sum(Sales-Expenditures) FROM Revenue WHERE Date between #7/1/2003# and #7/31/2003# AND State = '" & mapname & "' GROUP BY County"
Later in the ITXML code, send this query to Corda Server using the Corda Embedder setMapDBQuery method, as follows:
myImage.setMapDBQuery(mapname, "areas", "", "Revenue", "", "", query);
Note: For more information about aggregated shapes, see Setting Data for Aggregated Shapes in the Corda 7 Map Guide.
If the information passed in the query string is insufficient for determining the correct query, each map item has a number of extra properties that define secondary information for that item.
Use these properties in drilldown statements to pass information from level to level. Access these properties through the %_LONGNAME and %_CODE macros, which work just like the %_NAME and %_NAMECLASS macros in Step 15 of the tutorial.
For example, to use complete state names (as opposed to abbreviations) for the query statement, pass the LongName property as another parameter in the drilldown statement:
drilldown="<cit:dynamic-map-object name="dynamic">
<cit:layer name="Areas">
<cit:default-shape>
<cit:drilldown url=”drilldownUS.asp?nameclass=%_NAMECLASS&map=%_NAME&longname=%_LONGNAME”/>
</cit:default-shape>
</cit:layer>
</cit:dynamic-map-object>
Access the state name by looking up the longname parameter in the query string, similar to looking up the map and nameclass parameters in Step 12.