Fact-Finding with MapViewer
By Liujian Qian and Jayant Sharma
Map answers with Oracle Application Server 10g.
For years people have been able to enter an address into a Web site and get a map of that location. Adding a map to an address gives that location additional context beyond the street name and address number.
Maps of business information can add value to names and numbers as well and are now finding their way into analysis, planning, and user interfaces for many kinds of business and reporting applications.
This article presents an overview of Oracle Application Server 10g MapViewer and a sample application—including a description of the datasets, database, and Oracle Application Server Containers for J2EE (OC4J) setup—that uses MapViewer to display active location-based information.
The sample application is a pure HTML Web application that displays active location-based information, including a company's field offices and its head count, on a map, as shown in Figure 1. Each field office is represented by a graduated circle whose color and size are determined by the office's head count. As the user moves the cursor over a field office location, an info-tip window displays selected attributes of the office. Additional possible operations include drilling down on a field office for more information and finding the nearest field office for any given location (such as a customer address) on the map.
Overview of MapViewer
MapViewer is a component of Oracle Application Server 10g. It is a lightweight yet powerful servlet for visualizing geospatial data managed by Oracle Spatial. This includes thematic mapping of business data by associated geographies.
A map is made up of a set of themes (or layers). Each theme is a query containing a spatial column (of type SDO_GEOMETRY ) and other columns in its SELECT list and has a styling rule specifying its presentation. MapViewer receives a map request and renders a map image, using the styles and styling rules stored in the database.
You can deploy MapViewer on Oracle Application Server 10g or in a standalone OC4J instance.
MapViewer Application Architecture
A MapViewer application consists of
Content managed by Oracle Spatial, such as the street network, administrative boundaries, and office locations
The Web client may optionally use the MapViewer client Java library or JSP tag library to simplify the process of submitting map requests, handling the response, managing user interaction with the map image, and maintaining state—such as the current map center point and scale—between requests. This process is demonstrated in the following sample Web application.
The easiest way to get started with MapViewer is to download the Quick Start kit for Oracle Application Server 10g 10.1.2 MapViewer from the Oracle Technology Network (OTN). It contains a preconfigured standalone OC4J with MapViewer.
Load the Data
The following are the MapViewer themes for the sample application:
The definitions of such themes are usually stored in each database user's dictionary view ( USER_SDO_THEMES ). You can also create dynamic themes based on queries constructed at runtime and have the results of such queries displayed on a map. This process is illustrated in the jview.jsp demonstration that is part of the MapViewer Quick Start kit.
The base themes are all in the sample demonstration dataset (mvdemo.dmp), available at the MapViewer site on OTN. This dataset includes spatial information for U.S. states, counties, highways, and cities.
The data for this article's sample application is in the MapViewer.zip archive. MapViewer.zip contains the field_offices.dmp file—an export of the FIELD_OFFICES table from the user MVDEMO . MapViewer.zip also contains the oramap.zip file, which includes the application's source code, scripts, libraries, and an Oracle JDeveloper 10g workspace. Finally, MapViewer.zip includes a readme file.
After you import the mvdemo.dmp and field_offices .dmp files, run the style_theme.sql script to create the required styles and themes.
How to Run the Application
Open the workspace file, oramap.jws, in Oracle JDeveloper (9.0.5 or later), and browse the source code. With a MapViewer service running (with mapviewer.ear deployed in a standalone OC4J and loaded on startup) locally, run the JSP file main.jsp under the project named Project. You need to add MapViewer's Java client library, $OC4J_HOME/j2ee/home/applications/mapviewer/web/WEB-INF/lib/mvclient.jar, to your project's library path.
Alternatively, to run the application without Oracle JDeveloper, copy everything in the oramap/Project/public_html directory to a new directory in your deployed MapViewer location (such as $OC4J_HOME/j2ee/home/applications/mapviewer/web/oramap) and, with the MapViewer service running, point your browser to http://localhost:8888/mapviewer/oramap/main.jsp.
All the application code is in files contained in the oramap/Project/public_html directory. The main files are
Because this sample application's purpose is to illustrate the client API usage, both presentation logic and core application code reside in main.jsp. When developing larger-scale Web applications, you should use a mature application framework, such as Oracle Application Development Framework (ADF).
The myicons directory contains all the icons used by the toolbar and map legend, and the legend.xml file contains the map request for the map legend.
What's in main.jsp
The main.jsp file contains the most important code in the sample application. The primary code sections of the main.jsp file are (in order)
This code flow generally applies to any MapViewer-based Web application. The application sends a map request to MapViewer and presents the result map. An end user performs certain actions on the map, and the application sends a new request to the MapViewer server and presents a new result map.
The complete main.jsp file text is included here.
<%@ page import=
It sends map requests and processes responses from a MapViewer server.
The following is the customizable function customMapClicked() :
It ensures that a new request is submitted, with the proper parameters, when a user clicks anywhere on the map (except on HTML image map areas). Mouse-click event handlers defined in toolbar.js call this function.
Clicking on an HTML image map area on the map, such as on a field office marker, calls the following function on the client side:
function areaClicked(event, info)
The info parameter contains the essential attributes of the field office. The FIELD OFFICE theme definition specifies these parameters. Customizing the areaClicked function allows for more-sophisticated processing, such as opening a new report or creating charts about the identified map feature.
Next in the environment setup section of main.jsp, you declare two DIV objects named tbar_rect and infotip_window in the HTML header. You use tbar_rect to support zooming to an area within a box and infotip_window to display the info-tip window.
The preparing parameters section of main.jsp declares variables and obtains parameter values used in constructing a map request. The key input parameter, action, holds the current user-selected map action. Its value ( pan, zoomin, zoomout, zoombox , or id ) indicates which action MapViewer should perform.
The variable mvurl specifies the location of the MapViewer server. Assume that MapViewer is deployed to a local standalone OC4J instance, and hence use the URL http://localhost:8888/mapviewer/omserver.
Other parameters in the preparing parameters section of main.jsp include the center point of the map and the size (in decimal degrees from the top to the bottom of the map). If the user has previously clicked on the map, the location of the mouse click (in the device coordinate system relative to the image) is also obtained from the input HTTP request. With this information, you request a new MapViewer map.
Rendering a New Map
The code in the "rendering a new map" section of main.jsp sets up a map request and sends it to the MapViewer server. Most of the map-related logic, as well as your custom geospatial queries, are performed here with the client Java API.
To render a new map, you first obtain two references to MapViewer client instances from the current user session. Normally only one such client is required to send map requests and receive responses. The sample application, however, uses the new HTML image map support, so you need a separate MapViewer client to send a slightly different map request.
Creating new MapViewer clients. For a new browser session or if you cannot obtain an existing MapViewer client instance—because, for example, the session expires—you create new client instances, using the code in Listing 1.
Code Listing 1: Creating client instances
if (mv == null || newSession) // new session
clkmv.setDeviceSize(new Dimension(width, height));
The two MapViewer client instances (also called handles or beans ) are mv and lkmv . The first, mv , serves as the main client for constructing and sending regular map requests, whereas clkmv sends HTML image map-related requests.
Themes and styles: How field offices are displayed. The client mv map request includes three predefined themes. The key theme is FIELD OFFICE, which is defined in USER_SDO_THEMES:
SQL> select base_table,
The result of the query is
So FIELD_OFFICES is the base table for this theme, and the LOCATION column contains the location of each office.
The STYLING_RULES definition specifies that the HEADCOUNT, NAME , and LOCATION columns are queried from FIELD_OFFICES . It also stipulates that the result is sorted in descending order of HEADCOUNT value. This is important, because you represent field offices by using circles of varying sizes determined by the HEADCOUNT value. If two office locations are very close to each other, you want MapViewer to render the larger circle first and then the smaller one on top.
A feature is labeled only when the numeric value supplied in the LABEL column is greater than 0. The <label> element above has a condition "headcount - 250," so MapViewer labels an office only if its head count is greater than 250.
The clkmv client's sole purpose is to send a map request containing the FIELD OFFICE CLK theme. It is very similar to the FIELD OFFICE theme used by the mv client, except that this one sorts the offices in ascending order of head count, so that the larger HTML image map areas generated for the field offices come after smaller ones in the area list. The FIELD OFFICE CLK theme also has a <hidden_info> element:
MapViewer retrieves the columns queried in the <hidden_info> element as part of the query and includes them in the map response.
The mv client asks the server to render the map into a PNG file, save it on the server host, and return a URL for the image file that is presented in the browser. The clkmv client, however, uses a Scalable Vector Graphics (SVG) file format as follows:
These two methods tell MapViewer to create an SVG map for the request and return an SVG document containing map data in the device coordinate system. The coordinates are used for generating the HTML image map areas.
Having created the two clients, you call the run() method, which sends the request to the server. The clients wait for the response and extract relevant information, such as the generated map image URL, using accessor methods.
Now that you know how the map content and format are specified, it's time to consider how the field offices' locations are rendered. The two field office themes' styling rules reference a style named OFFICE_STYLE, which is a bucket-based—or advanced—style. OFFICE_STYLE contains a set of buckets, each corresponding to a value range, such as 250 < headcount < 500, with a primitive style, such as a red circle. For the FIELD OFFICE themes, each office's head count value determines its bucket and style.
Processing user actions. The action parameter in main.jsp contains the user interaction information. If the value of the action is pan, zoomin, zoomout , or zoombox , you reissue the map request, by calling the corresponding methods, such as pan() , with the new center and size parameters. You always call the methods on both clients, so the HTML image map generated by clkmv is in sync with the displayed map image.
Processing the ID function. The ID action is initiated when an end user clicks on the ID button on the toolbar and then clicks anywhere on the map. The actual processing takes place on the server side.
Listing 2 shows the relevant code segment for processing an ID action.
Code Listing 2: Processing an ID action
//add a leader line from user click to nearest office
mv.run(); // reissue map request to draw a PIN marker
The code in Listing 2 first finds the field office nearest to the user-specified location, using the identify() method. The input parameters are the name of the target table ( FIELD_OFFICES ) to search against, the list of columns to return, and the mouse click location in the screen coordinate system.
Next, the code determines the ground coordinates corresponding to the mouse click location:
Point2D p2 = mv.getUserPoint(
Then the code adds a PIN marker symbol at that location:
Next, the code adds a line connecting these two locations to the new map:
Because you are adding only the PIN and line features to the new map, it's wasteful to regenerate the entire thing. So you simply set the previous map as the backdrop, temporarily disable all other themes, and issue the map request as follows:
Once you have generated the new map, you reenable the themes and clean up the PIN and line features:
At this point, you have a new map, have fetched the attributes for the nearest office, and are ready to present the information.
Presenting the Result Page
The presenting-the-result-page section of main.jsp contains simple HTML tags. The toolbar is shown in Listing 3.
Code Listing 3: Presenting the result page toolbar
<!-- Left column : toolbar and map image -->
The statement <%@ include file="toolbar.html" %> lays out the toolbar buttons. A valid button icon file must be selected for each button and reflect its current status (that is, whether it is clicked on). The JSP code in Listing 3 loops through the list of button names and chooses the proper icon image file from the myicons directory. If a button, such as "pan," is clicked on, you use the <button_name>_dn.png file (in this case, pan_dn.png). These filenames are picked up by the toolbar.html file.
Presenting the Generated Map Image
The code in Listing 4 presents the generated map image.
Code Listing 4: Presenting the map
This code is essentially an HTML <img> tag, with the image src obtained from mv through the getGeneratedMapImageURL() method. It uses an HTML image map named omv_infomap, whose contents are returned from the method call getThemeAsHTMLAreas() on clkmv and placed between the <MAP> tags before the <img> tag. Finally the <img> tag is surrounded by various <DIV> elements, including infotip_window and tbar_rect, for info-tip window and box-based zoom, respectively.
MapViewer gives Web application developers a versatile means of integrating and visualizing business data with maps. It uses the capability included with Oracle 10g to manage geographic mapping data and hides the complexity of spatial data queries and the cartographic rendering process from application developers.