Oracle® Application Server 10g MapViewer User's Guide 10g (9.0.4) Part Number B10559-01 |
|
This chapter describes the JavaBean-based MapViewer API. This API exposes all capabilities of MapViewer through a single JavaBean, oracle.spatial.mapclient.MapViewer
. This bean is a lightweight client that handles all communications with the actual MapViewer service running on the middle tier on behalf of a user making map requests.
All communications between the bean and the actual MapViewer service follow a request/response model. Requests are always sent as XML documents to the service. Depending on the type and nature of a request, the response received by the bean is either an XML document or some binary data. However, using the MapViewer bean is easier than manipulating XML documents for forming and sending MapViewer requests, as well as for extracting information from the responses.
The bean delegates most of map data processing and rendering to the MapViewer service. All the bean does is formulate user requests into valid MapViewer XML requests and send them to a MapViewer service for processing.
The MapViewer bean can be created and used in either server-side objects such as JavaServer Pages (JSP) and servlets, or in client-side objects such as Java applets or standalone Java applications. The bean is a lightweight class that maintains an active HTTP connection to the MapViewer service and the current map request and map response objects. In most cases, you will create only one MapViewer bean and use it for all subsequent tasks; however, you can create more than one bean and use these beans simultaneously. For example, you may need to create a Web page where a small overview map displays the whole world and a large map image displays a more detailed map of the region that is selected on the overview map. In this case, it is probably easier to create two MapViewer beans, one dedicated to the smaller overview map, and the other to the larger detail map.
Figure 4-1 shows some possible usage scenarios for the MapViewer bean.
The MapViewer bean can communicate, through the HTTP protocol, with the MapViewer service, in several usage scenarios, the following of which are shown in Figure 4-1:
In all usage models, the same JavaBean class is used, and most of its methods apply. However, some methods work or are useful only in a JSP HTML-based context, and other methods work or are useful only in an interactive standalone Java application or applet context (thick clients). For example, consider the following methods of the bean:
Both methods extract the generated map image information from a response received from a MapViewer service; however, the first method returns the actual binary image data that is a java.awt.BufferedImage
class, and the second method returns an HTTP URL string to the generated map image that is stored in the host running the MapViewer service. Clearly, if your application is a JavaServer Page, you should use the second method, because otherwise the JSP page will not know how to handle the BufferedImage
. However, if you are programming a standalone Java application where you have a Java panel or window for displaying the map, you can use the first method to get the actual image and render it inside your panel or window, plus any other features that you may have created locally and want to render on top of the map.
The set of methods that are only applicable in the thick client context, which are designed to achieve optimal performance for such clients, are described in more detail in Section 4.3.9.
Before you can use the MapViewer JavaBean, the MapViewer mvclient.jar
library must be in a directory that is included in the CLASSPATH definition. After you deploy the mapviewer.ear
file in OC4J or Oracle Application Server, the mvclient.jar
file is located in the $MAPVIEWER/web/WEB-INF/lib
directory. ($MAPVIEWER
is the base directory that the mapviewer.ear
file is unpacked into by OC4J. In a typical OC4J installation, if you placed the mapviewer.ear
file in $OC4J_HOME/j2ee/home/applications
, the base directory for unpacked MapViewer is $OC4J_HOME/j2ee/home/applications/mapviewer
.)
Before you use the MapViewer JavaBean, you should examine the javadoc documentation and try the JSP demo:
http://host:port/mapviewer/mapclient
In this format, host and port indicate where OC4J or Oracle Application Server listens for incoming requests.
http://host:port/mapviewer/demo/mapinit.jsp
In this format, host and port indicate where OC4J or Oracle Application Server listens for incoming requests. This JSP page confirms the MapViewer service URL and then proceeds to the real demo page, map.jsp
.
To use the MapViewer bean, you must create the bean (see Section 4.3.1), after which you can invoke methods to do the following kinds of operations:
The sections about methods for kinds of operations provide introductory information about what the bean can do. For detailed descriptions of each method, including its parameters and return type, see the javadoc documentation (described in Section 4.2).
The first step in any planned use of the MapViewer bean is to create the bean, as shown in the following example:
import oracle.spatial.mapclient.MapViewer; MapViewer mv = new MapViewer("http://my_corp.com:8888/mapviewer/omserver");
The only parameter to the constructor is a URL to an actual MapViewer service. Unless you change it to something else using setServiceURL
, the MapViewer service at this URL will receive all subsequent requests from this bean. When a MapViewer bean is created, it contains an empty current map request. There are a few parameters in the current request that are initialized with default values, such as the width and height of the map image and the background color for maps. These default values are explained in the XML API element and attribute descriptions in Chapter 3.
As explained in Chapter 3, a map request can have many parameters that affect the final look of the generated map image. When you use the MapViewer JavaBean, such parameters can be set through a group of methods whose names start with set. Each of these parameters has a corresponding method that starts with get. For example, setAntiAliasing
sets antialiasing on or off, and getAntiAliasing
returns the current antialiasing setting.
The methods for setting parameters of the current map request include the following:
setAntiAliasing(boolean aa)
specifies whether or not the map should be rendered using the antialiasing technique.
setBackgroundColor(java.awt.Color bg)
sets the background color for the map to be generated.
setBackgroundImageURL(java.lang.String bgImgUrl)
sets the URL for the background image to be rendered in the map.
setBaseMapName(java.lang.String name)
sets the name of the base map to be rendered before any explicitly added themes.
setCenter(double cx, double cy)
sets the center point for this map request. The coordinates must be in the user data space.
setCenterAndSize(double cx, double cy, double size)
sets the map center and size for the map to be generated. All data must be in the user data space.
setDefaultStyleForCenter(String defRenderStyleName, String defLabelStyleName, String defLabel, double[] defRadii)
sets the default styling and labeling information for the center (point) of the map. Each subsequent map generated will have its center point rendered and optionally labeled with circles of the specified radii.
setDataSourceName(java.lang.String name)
sets the name of the data source to be used when loading data for the map.
setDeviceSize(java.awt.Dimension dsz)
sets the image dimension of the map to be generated.
setImageFormat(int f)
sets the image format that MapViewer should use when generating the map. For JSP pages, you should always set it to PNG_URL
or GIF_URL
.
setMapLegend(java.lang.String legendSpec)
sets the map legend (in XML format) to be plotted with current map. The legend must be specified in the legendSpec
parameter, in the format for the <legend>
element that is documented in Section 3.2.10.
setMapTitle(java.lang.String title)
sets the map title for the map to be generated.
setServiceURL(java.lang.String url)
sets the MapViewer service URL.
setSize(double size)
sets the height (size) in the user data space for the map to be generated.
setWebProxy(java.lang.String proxyHost, java.lang.String proxyPort)
sets the Web proxy to be used when connecting to the MapViewer service. This is needed only if there is a firewall between the Web service and this bean.
Besides specifying a base map to be included in a map request, you can add themes or individual point and linear features, such as a point of interest or a dynamically generated route, to the current map request. The themes can be predefined themes whose definitions are stored in the database, or dynamic themes where you supply the actual query string when you add the theme to the current request.
There are two kinds of dynamic themes: one retrieves geometric data (JDBC theme) and the other retrieves image data (image theme). For dynamic themes and features, you must explicitly specify the styles you want to be used when rendering them. Being able to add dynamic themes and features gives you flexibility in adapting to application development needs.
The methods for adding themes or features to the current map request have names that start with add, and they include the following:
addImageTheme
and its variants add an image theme, for which you must supply the query string for retrieving the image data to be rendered as part of the map.
addJDBCTheme
and its variants add a JDBC theme, for which you must supply the query string for retrieving the geometric data.
addPredefinedTheme
and its variants add a predefined theme to the current map request.
addThemesFromBaseMap(java.lang.String basemap)
adds all predefined themes in the specified base map to the current map request. This has an advantage over setBaseMapName
, in that you can manipulate the themes for the current map request, as explained in Section 4.3.4.
addPointFeature(double x, double y, java.lang.String styleName, java.lang.String label, java.lang.String labelStyleName, double[] radius)
adds a single feature that is a point to the current map request. This point will be rendered using the supplied rendering style on the map after all themes have been rendered. You can optionally supply a labeling text to be drawn alongside your point feature. You can also supply an array of radii (the units are always in meters), in which case a series of circles will be drawn centering on the point. The coordinates x
and y
must be in the user data space. There is no limit to the number of point features you can add.
addLinearFeature(double[] coordinates, java.lang.String styleName, java.lang.String label, java.lang.String labelStyleName)
adds a single linear feature (line string) to the current map request. You must specify a rendering style, and you can specify the labeling text and text style for drawing the label. The coordinates must be in the user data space. There is no limit to the number of linear features you can add.
You can remove all added point and linear features by calling removeAllPointFeature
s and removeAllLinearFeatures
, respectively.
After you add themes using any of the methods that start with add, you can manipulate them, performing such operations as listing their names, moving them up or down in rendering order for the current request, and even disabling themes and enabling themes that had been disabled. However, you cannot manipulate themes that are implicitly included when you set a base map (using the setBaseMapName
method), because the list of themes in the base map is not actually included until the MapViewer service processes the request.
The methods for manipulating themes in the current map request include the following:
hasThemes
checks to see if the current map request has any explicitly added themes. For example, if you have only set the name of the base map in the current request, but have not added any other theme through one of the add*Theme methods, this method returns FALSE
.
getThemeNames
returns an ordered list of names of themes that have been explicitly added to the current map request.
setThemeEnabled(boolean v, java.lang.String themeName)
sets a specified theme to be enabled or disabled in the current map request.
enableThemes(java.lang.String[] themes)
enables all themes whose names appear in the supplied list.
setAllThemesEnabled(boolean v)
sets all themes to be enabled or disabled.
getEnabledThemes
gets a list of all themes that are currently enabled.
getActiveTheme(double currentScale)
gets the name of the active theme, that is, the top theme on the current display map.
setThemeScale(java.lang.String name, double minScale, double maxScale)
sets the minimum and maximum scale values for displaying a theme.
deleteTheme(java.lang.String name)
deletes an explicitly added theme from the current map request.
getThemePosition(java.lang.String name)
returns the position in the rendering sequence of an explicitly added theme.
moveThemeDown(int index)
moves a theme down one position in the list of themes to be rendered, so that it is rendered later.
moveThemeUp(int index)
moves a theme up one position in the list of themes to be rendered, so that it is rendered sooner.
setLabelAlwaysOn(java.lang.String name, Boolean labelalwaysOn)
controls whether or not MapViewer labels all features in a theme even if two or more labels will overlap in the display of a theme. (MapViewer always tries to avoid overlapping labels.) If labelalwaysOn
is TRUE
, MapViewer displays the labels for all features even if two or more labels overlap. If labelalwaysOn
is FALSE
, when it is impossible to avoid overlapping labels, MapViewer disables the display of one or more labels so that no overlapping occurs.
As an application developer, you typically issue a new map request as a result of certain user input (such as a mouse click on the currently displayed map) or after you have modified some aspect of the map request (such as setting a new background color). In fact, you can issue a map request any time you want, as long as you do not overwhelm the middle-tier MapViewer service with too many rapid requests from the MapViewer bean or beans. The MapViewer service tries to process requests in the order in which they arrive; if you send a second request before receiving the response from the first one, MapViewer continues to process the first request completely before starting to process the second request.
Any modifications to the current map request, such as changing to a new background color or moving a theme down in the rendering sequence, do not take effect in the map display until you send the map request, at which time the MapViewer service actually receives the request and processes it.
The methods for sending a map request to the MapViewer service include the following:
run
sends the current map request to the MapViewer service, and obtains a map response as sent back by the MapViewer service.
pan(int x, int y)
pans to the specified device point. Each coordinate is in the screen/display unit, in this case, pixel.
zoomIn(double factor)
zooms in on the map without changing the other map request parameters.
zoomIn(int x, int y, double factor)
zooms in on the specified device point.
zoomIn(int x1, int y1, int x2, int y2)
zooms in on the specified device rectangle.
zoomOut(double factor)
zooms out on the current map without changing the other map request parameters.
zoomOut(int x, int y, double factor)
zooms out and recenters the current map.
Each of these methods assembles a single XML map request document based on all properties of the current map request, and then sends it to the MapViewer service. After the MapViewer bean receives the response from the MapViewer service, the bean does any the necessary postprocessing and makes the response ready for your use.
As an alternative to using these methods, you can formulate an XML request string outside the bean, and then use the sendXMLRequest(java.lang.String req)
method to send the request to the MapViewer service. However, if you use this method, you are responsible for receiving and unpacking the response using the getXMLResponse
method, and for parsing and interpreting the response string yourself. The state of the bean remains unchanged, because the methods are only making use of the bean's capability to open an HTTP connection to send and receive documents over the connection.
All methods described in this section throw an exception if any unrecoverable error occurs during the transmission of the request or response, or in the MapViewer service during processing. You are responsible for taking care of such exceptions in any way you consider appropriate, such as by trying the request again or by reporting the problem directly to the user.
You can extract information, such as the generated map image or the URL for the image, from the current map response. The methods for extracting information from the map response include the following:
getGeneratedMapImageURL
returns the URL to the currently generated map image in the application server. You must have set the image format to FORMAT_PNG_URL
or FORMAT_GIF_URL
using the setImageFormat
method.
getGeneratedMapImage
returns the actual map image data contained in the response from the MapViewer service. You must have set the image format to FORMAT_RAW_COMPRESSED
using the setImageFormat
method. The getGeneratedMapImage
method is primarily used in thick clients, although you may also use it in a JavaServer Page or a servlet (for example, to save the image in a format that is not supported by MapViewer).
getMapMBR
returns the MBR (minimum bounding rectangle) for the currently generated map, in the user's data space.
getMapRequestString
returns the last submitted map request in XML format.
The MapViewer bean has methods that you can use to obtain information about the data source for the MapViewer service to which the bean is connected, and to query the mapping metadata. The methods for obtaining information about the data source and the mapping metadata include the following:
dataSourceExists(java.lang.String dsrc)
checks if a given data source exists in (that is, is known to) the MapViewer service.
addDataSource(....)
adds a data source to the MapViewer service.
addImageMarkerFromURL(java.lang.String gifURL, java.lang.String styleName)
adds a GIF image as a marker symbol to the current style cache of the MapViewer service.
It is often necessary to query nonspatial attributes that are associated with the spatial features being displayed in the current map image. For example, assume that you just issued a map request to draw a map of all customer locations within a certain county or postal code. The next logical step is to find more information about each customer being displayed in the resulting map image. In the JSP or HTML environment, because you get only an image back from the MapViewer service, you will need another round-trip to the service to fetch the nonspatial information requested by the user. This section describes a set of methods that can help you do just that. (You can, however, obtain both the nonspatial attribute values of a certain theme and the resulting map image in a single request when the bean is used in a standalone Java application or applet environment, as described in Section 4.3.9.)
A typical situation is that the user clicks on a feature on the displayed map and wants to find out more (nonspatial attributes) about the feature being "identified." This action can be essentially implemented using a query with the desired nonspatial attributes in its SELECT list, and a spatial filter as its WHERE clause. The spatial filter is an Oracle Spatial SQL operator that checks if the geometries in a table column (the column of type SDO_GEOMETRY in the customer table) spatially interact with a given target geometry (in this case, the user's mouse-click point). The spatial filter in the WHERE clause of the query selects and returns only the nonspatial attributes associated with the geometries that are being clicked on by the user.
You will need to call an Oracle Spatial operator to perform the filtering; however, you can use the MapViewer bean-based API to obtain information, and to preassemble the spatial filter string to be appended to the WHERE clause of your query. The identify
method simplifies the task even further.
The methods for querying nonspatial attributes in the current map window include the following:
getSpatialFilter(java.lang.String spatialColumn, int srid, boolean pre9i)
returns a spatial filter string that can be used as a WHERE clause condition in formulating your own queries in the current map window context. The spatial filter evaluates to TRUE
for any geometries that are being displayed in the entire map window. You can use this method to obtain information about every spatial feature of a theme that is being displayed.
getSpatialFilter(java.lang.String spatialColumn, int srid, double xl, double yl, double xh, double yh, boolean pre9i)
returns a spatial filter string that can be used as a query condition in formulating your queries in the given window. This filter evaluates to TRUE
for all geometries that interact with the supplied (xl,yl, xh,yh)
data window. The window is not in device or screen coordinate space, but in the user's data space; therefore, you must first call the getUserPoint
method to convert the user's mouse-click point to a point in the user data space before using the getSpatialFilter
method.
getUserPoint(int x, int y)
returns the user data space point corresponding to the mouse click.
getWhereClauseForAnyInteract(java.lang.String spatialColumn, int srid, double x, double y)
returns geometries that have any interaction with a specified point in the user's data space. This provides a WHERE clause string that will use a more precise spatial filtering method than the one provided by the getSpatialFilter
method.
getWhereClauseForAnyInteract(java.lang.String spatialColumn, int srid, double xl, double yl, double xh, double yh)
returns the WHERE clause that can be used to find geometries that have any interaction with the specified user space window. It is similar to the getSpatialFilter
method, but uses a more precise version of the Oracle Spatial filtering method.
doQuery
and variants execute a supplied SQL query and return an array of strings representing the result set. These are convenient methods to issue your own query without manually opening a JDBC connection to the database from the bean.
doQueryInMapWindow
and variants are extensions of doQuery
and its variants. They automatically subject the user-supplied query to a spatial filtering process using the current map window.
identify
and variants provide a convenient method for identifying nonspatial attributes. This is desirable if you do not need more flexibility and control over how a nonspatial attribute query should be formulated. As with the doQuery
methods, all identify
methods return a double String
array that contains the result set of the query.
When you use the MapViewer bean in a JavaServer Page in an HTML file, a second round-trip to the MapViewer service is needed to obtain nonspatial attributes of features being displayed. It is also true that with a JavaServer Page in an HTML file, even if most themes remain unchanged from one map request to the next (such as when zooming in to the center of a map), all themes must still be reprocessed each time the MapViewer service processes the page, which causes the data for each theme to be retrieved again from the database. (This is mainly due to the stateless nature of the MapViewer service and the insufficient mechanism provided in the JSP context for handling user interaction, which must be based on the request/response model.)
However, when you are working in a thick client environment, such as with J2SE (Java 2 Platform Standard Edition) applications and applets, you can reduce the processing and bandwidth overhead when using the bean. This is primarily because in such environments you have greater control of how content (including the map) should be displayed, you can better respond to the user's interaction, and you can devote more resources to maintaining the states on the client side.
A key optimization available only to the thick client context is live features. Basically, a live feature is a spatial feature that originates from the MapViewer service but exists in the thick client. Each live feature contains the actual shape representing the geometry data, and a set of nonspatial attributes that the user might be interested in. To obtain live features, a thick client must set its parent theme to be "clickable." When a map request is sent to the MapViewer service with a clickable theme, MapViewer does not attempt to render features for that theme in the resulting map. Rather, the set of features that would have been drawn as part of the map is returned to the requesting client as an array of live feature objects. The rest of the map is still rendered and transmitted as a single image to the client. After the client has received both the live features and the base image, it must render the live features on top of the accompanying map image, using one of the methods described later in this section.
One of the benefits of using live features is that the thick client will not need to issue a request for the clickable theme every time a map request is sent. For example, if the request is to zoom in to the current map, the client can determine for each live feature if it should be displayed in the zoomed-in map image. Another, and probably more significant, advantage is that the nonspatial attributes for all features displayed in the map are now readily available to the user. For example, as the user moves the mouse over a range of features on the map, the thick client can immediately get the corresponding nonspatial attributes and display them in a pop-up window that follows the mouse trail. No round-trip to the MapViewer service is needed for this type of action, and the feedback to the user is more responsive.
The methods that are optimal for thick clients include the following:
drawLiveFeatures(java.awt.Graphics2D g2, java.awt.Color stroke, java.awt.Color fill, double pointRadius, double strokeWidth)
draws all live features that are returned to this client from MapViewer.
getLiveFeatureAttrs(int x, int y, int tol)
gets the nonspatial attributes of the feature being clicked on by the user.
hasLiveFeatures
checks if there are any live (clickable) features.
getNumLiveFeatures
returns the number of live features currently available.
highlightFeatures
and variants highlight all live features that are intersecting the user-specified rectangle. These methods also let you specify the style for highlighting features.
isClickable(java.lang.String themeName)
checks if the specified theme is clickable (that is, if users can click on the theme to get its attributes).
setClickable(boolean v, java.lang.String themeName)
sets the theme clickable (so that its features will be available to the client as live features that users can click on and get attributes of).
To obtain a set of features and keep them live at the thick client, you must first call setClickable
to set the theme whose features you want to be live. Then, after you issue the current map request, the bean processes the response from the MapViewer service, which (if it succeeded) contains both a base map image and an array of LiveFeature
instances. You can then call getGeneratedMapImage
to get and draw the base image, and use drawLiveFeatures
to render the set of live features on top of the base map. If the user clicks or moves the mouse over a certain position on the map, you can use the highlightFeatures
method to highlight the touched features on the map. You can also use the getLiveFeatureAttrs
method to obtain the associated nonspatial attributes of the features being highlighted. You do not have direct access to the LiveFeature
instances themselves.
The behavior of calling the methods described in this section in the context of JSP pages is not defined.
|
![]() Copyright © 2001, 2003 Oracle Corporation. All Rights Reserved. |
|