Thursday, March 26, 2009

Rotating map symbols using oriented points

Oracle Spatial supports the notion of oriented points, which are sdo_geometry points that contain additional coordinates of the end point for the orientation vector from the point itself, with values between -1 and 1. For instance, you can create an oriented point using the following SQL statement:

INSERT INTO cola_markets VALUES(
91,
'oriented_point',
SDO_GEOMETRY(
2001,
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1,1, 3,1,0),
SDO_ORDINATE_ARRAY(12,14, 0.3,0.2))
);

The 12,14 identifies the physical coordinates of the point; and the 0.3,0.2 identifies the x and y coordinates (assuming 12,14 as the origin) of the end point of the orientation vector. The resulting orientation vector slopes upward at about a 34-degree angle, as illustrated in this figure:



(The above description and figure are copied from the Oracle Spatial User's Guide).

MapViewer has built-in support for such oriented points. What this means, is that if you apply a MARKER or TEXT style to such points (via a theme defined on the points table for instance), the MARKER (map symbol) or text itself will be oriented on the map according to the angle of its underlying data point, for every displayed data point.

To better illustrate this support, I have created a simple Oracle Maps demo that displays the included oriented_points table in your MVDEMO sample data set, using a pin symbol.


<html>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
<META NAME="GENERATOR" CONTENT="JDBC Demo">
<link rel="stylesheet" type="text/css" href="../t.css" />

<script language="Javascript" src="/mapviewer/fsmc/jslib/oraclemaps.js"></script>
<SCRIPT TYPE="text/javascript">
var mapview;
var orientedtheme;
var baseQuery;
var baseURL = "http://"+document.location.host+"/mapviewer";
var mapCenterLon = -122.49;
var mapCenterLat = 37.5106;
var mapZoom = 3;
var mpoint = MVSdoGeometry.createPoint(mapCenterLon,mapCenterLat,8307);
function on_load_mapview()
{
mapview = new MVMapView(document.getElementById("map"), baseURL);
var basemap = new MVMapTileLayer("mvdemo.demo_map");
mapview.addMapTileLayer(basemap);
mapview.setCenter(mpoint);
mapview.setZoomLevel(mapZoom);

orientedtheme= createOrientedTheme();

mapview.addThemeBasedFOI(orientedtheme);

var nav = new MVNavigationPanel() ;
var navPan = new MVMapDecoration(nav,0,0,null,null,4,4) ;
mapview.addMapDecoration(navPan) ;

mapview.display();
}

var pinMarker = "M.CYAN PIN" ;

function createOrientedTheme()
{
baseQuery= "select shape from oriented_points";
var theme = "<themes><theme name='a_dynamic_theme' >" +
"<jdbc_query asis='true' spatial_column='shape' jdbc_srid='8307' " +
"render_style='"+pinMarker+"' datasource='mvdemo'>" + baseQuery +
"</jdbc_query></theme></themes>" ;
var theme = new MVThemeBasedFOI('oriented-theme',theme);
theme.setBringToTopOnMouseOver(true);
return theme;
}

</SCRIPT>
</HEAD>

<BODY onload= javascript:on_load_mapview()>
<h3>Displaying oriented points</h3>
<div id="map" style=" width: 90%; height: 100%;">

</BODY>
</html>



If you save the above code as an HTML file in your MapViewer web directory, then open it from a browser, you will see four pin symbols, rotated according to the angles of the four oriented points from the table.


No comments: