Wednesday, October 29, 2008

Generating map legends

In this article we will show at least 3 different ways of generating a map legend. The first two are based on MapViewer's XML API, while the 3rd one is pure HTML and the most flexible. All the examples have been tested against the sample MVDEMO data source.

Approach 1: manually specifying legend entries

In this approach, we create a map legend image by specifying a map legend element in MapViewer's XML request. Inside the element, we add one legend entry for each style to be displayed as well as some description text. The trick here is to leave MapViewer nothing else to render: no center point, no map bounding box, and no base map or themes either. When MapViewer sees such an otherwise empty map request, it will know to generate an image that is just big enough to contain all the legend entries.

The following is one such sample XML request.

<?xml version="1.0" standalone="yes"?>
<map_request datasource="mvdemo" format="PNG_STREAM">
<legend bgstyle="fill:#ffffff;stroke:#ff0000" profile="MEDIUM" position="SOUTH_EAST">
<column>
<entry text="Map Legend" is_title="true" />
<entry style="M.STAR" text="center point" />
<entry style="M.CITY HALL 3" text="cities" />
<entry style="M.CITY HALL 4" text="big cities" />
<entry style="C.ROSY BROWN STROKE" text="state boundary" />
<entry style="L.PH" text="interstate highway" />
<entry style="L.FERRY" text="ferry" />
<entry is_separator="true" />
<entry text="County population:" />
<entry style="V.COUNTY_POP_DENSITY" tab="1" />
</column>
</legend>

</map_request>

The above request results the following legend image:



Approach 2: Fully automatic embedded map legend

In this approach, we want to display a map legend as part of the map itself, while without specifying any legend entries. Lets look at the such a map request:

<?xml version="1.0" standalone="yes"?>
<map_request
title="Oracle LBS MAP"
basemap="demo_map"
datasource = "mvdemo"
width="640"
height="480"
bgcolor="#a6cae0"
antialiase="false"
format="PNG_STREAM">
<center size="0.15">
<geoFeature render_style="m.star"
radius="1600,4800"
label="A Place"
text_style="t.Street Name" >
<geometricProperty typeName="center">
<Point srsName="SDO:8307">
<coordinates>-122.2615, 37.5266</coordinates>
</Point>
</geometricProperty>
</geoFeature>
</center>

<legend bgstyle="fill:#ffffff;stroke:#ff0000" profile="MEDIUM" position="SOUTH_EAST">
</legend>

</map_request>

As you can see, the above request specifies a legend element without any actual legend entries inside it. So how will MapViewer create the legend in this case? It actually will look up all the themes that are visible on the result map, and displays all the styles that are used by these themes in the legend area. This is great if you are just feeling lazy and would rather MapViewer handle everything for you. The following is the map with the automatic legend:



For more information about these two approaches and the (sometimes limited) customization options, please check out MapViewer's User Guide.


Approach 3: Full manual mode


If you are an advanced user, you most likely will want more than the two approaches we just mentioned. No worries. In the 3rd approach, we will leverage a new MapViewer request to achieve complete control of legend customization and layout. Basically, with a recent MapViewer release (such as 10.1.3.3 for WebLogic), you can now request a 'sample' image of any style from Mapviewer. A typical request URL for a style image looks like this:

http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=M.STAR&w=25&h=25&ds=mvdemo

For the above URL, MapViewer will generate and stream back an image 25 pixels wide and high that shows the style named "M.STAR" from the "mvdemo" data source.

With this kind of style image URL, we can use the regular HTML table and <img> tags to fully customize what, where and how legend entries are displayed. For instance, to replicate the sample legend in Approach 1, we can use the following simple HTML table (you can also use CSS constructs to achieve much fancier layout if you so desire):


<TABLE>
<TR>
<TD>
<Font size="+1" color="blue">Basic Features:</FONT>
</TD>
<TD>
</TD>
</TR>
<TR>
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=M.STAR&w=25&h=25&ds=elocation">
</TD>
<TD>
map center
<TD>
</TR>
<TR>
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=M.CITY+HALL+3&w=25&h=25&ds=mvdemo">
</TD>
<TD>
cities
</TD>
</TR>
<TR>
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=M.CITY+HALL+4&w=25&h=25&ds=mvdemo">
</TD>
<TD>
big cities
</TD>
</TR>
<TR>
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=C.ROSY+BROWN+STROKE&w=34&h=34&ds=mvdemo">
</TD>
<TD>
state boundary
</TD>
</TR>
<TR>
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=L.PH&w=45&h=15&ds=mvdemo">
</TD>
<TD>
interstate highway
</TD>
</TR>
<TR>
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=L.FERRY&w=45&h=15&ds=mvdemo">
</TD>
<TD>
ferry
</TD>
</TR>
<TR> <!-- a separator -->
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/myicons/t.gif" height="15" width="1">
</TD>
<TD>

</TD>
</TR>
<TR>
<TD colspan="2">
<FONT size="+1" color="blue">County Population Density:</FONT>
</TD>
</TR>
<TR>
<TD>
<img src="http://sdolnx2.us.oracle.com:7777/mapviewer/omserver?sty=V.COUNTY_POP_DENSITY&w=180&h=175&ds=mvdemo">
</TD>
<TD>
</TD>
</TR>
</TABLE>

The following is what you will see in a browser:

Tuesday, October 21, 2008

MapViewer for WebLogic kit updated

The latest MapViewer release, version 10.1.3.3 for WebLogic, just saw an update yesterday. Please go to http://www.oracle.com/technology/software/products/mapviewer/index.html for immediate download.

This kit is released under the same bundle name (mapviewer10133wls.zip) but the MapViewer component (mapviewer.ear) in it has been updated to include a few last minute bug fixes. If you have experienced issues with Oracle Maps when doing very fast zooming operations, such as FOI features throwing errors or base map tiles disappearing, then you want to download and deploy this latest kit.

Note again that while this kit is certified on WebLogic Servers, you can also deploy it to all 10.1.3.* versions of OC4J standalone and Oracle App Server. This kit also supersedes all previously released MapViewer 11g previews in functionality and stability.

thanks

LJ

Monday, October 6, 2008

Displaying labels on your FOI objects

You probably noticed that by default, none of the clickable Feature of Interest objects displayed on your map has any label text on it. So how to add labels to your FoIs? There are different approaches based on how your FOI objects are created, and also their geometric types.


Adding an index label to your markers

If your theme-based FOI layer is composed of exclusively Point-type objects (markers), you have an option to automatically attach a sequence number or letter to each marker displayed on the map. This is very useful if all you want to do is to index each marker object and be able to cross-reference them in a list that shows the same objects in a tabular form. The method you will use is MVThemeBasedFOI.enableMarkerSequence( enabled, type). Please check out the online API doc for details on this method. The following screenshot shows how such a map looks like:



Note that in order to make the index number or letter inside each marker visible, you need to make sure the Marker style used by your theme is big enough for the label. Also make sure the color of the text is set to a different color of the marker itself. In the above map, the theme uses a circle Marker style, and it is filled with red color. So you need to make sure it does not use a red color for its text. To change the text color (and font/size if needed), open the Marker style in Map Builder, click the Marker Text button and change the text color. This is shown in the following screen shot:




Individual marker FOI objects

If you manually create and place individual FOI objects on the map, for instance by using the MVFOI.createMarkerFOI() and mapview.addFOI() methods, then it is very easy to add label text to each marker. It is shown in the built-in Oracle Maps tutorial mapviewer/fsmc/tutorial/samples/FOIMarker.html. Look for the statement containing setHTMLElement("#1",20,20), which is the exact method you will use to set a label on top of the marker you are creating.


Theme-based FOI layer

If you are displaying a pre-defined theme based FOI layer, and you want to display a label on each feature of interest, there is a method on MVThemeBasedFOI that does just that: enableLabels(true). Note that this method will work provided the following conditions are met:
1. The theme has label enabled (in other words, if you submit this theme in a plain XML map request the resulted map image should display labels on your theme).
2. The features are of polygon type. If your FOIs are of linestring or point type, the method enableLabels() does nothing for you, unless you enable whole-image rendering for the FOI layer.

Dynamic theme based FOI layer

If you are displaying a JDBC/Dynamic theme based FOI layer, and want to display a label on each feature, simply call the same MVThemeBasedFOI.enableLabels(true) method on your FOI layer. You just need to make sure that your dynamic theme actually contains a label column in its SELECT list, and tell MapViewer the name of that label column as well as the labeling style to be used. As an example, I modified the buffer theme in the built-in tutorial /mapviewer/fsmc/tutorial/samples/jdbcThemeBasedFOI.html to display the label "A1" on each buffer zone:

function updateBuffer()
{
...

baseQuery = "select 'A1' as label, sdo_geom.sdo_buffer(A.location, "+radius+
", 0.005, 'unit=mile arc_tolerance=0.005') location "+
" from "+theme+" A" ;
var theme = '<themes>' +
'<jdbc_query asis="true" spatial_column="location" jdbc_srid="8307" ' +
'render_style="'+bufferStyle+'" datasource="mvdemo" label_column="label" label_style="T.CITY NAME" >' + baseQuery +
'</jdbc_query></theme></themes>' ;
buffertheme = new MVThemeBasedFOI('buffertheme',theme);
buffertheme.setBringToTopOnMouseOver(true);
buffertheme.enableLabels(true);
mapview.addThemeBasedFOI(buffertheme);

...
}