Thursday, October 22, 2009

Google maps tiles in a MapViewer app

Earlier this year I posted an article on how to display MapViewer generated tiles in a Google Maps application. In this post I will discuss how to display Google Maps tiles in a MapViewer/Oracle Maps application.

Starting with MapViewer 11g Release 1, a built-in Google Maps tile layer class has been added to the MapViewer's JavaScript API. It is called MVGoogleTileLayer. Unfortunately it is not officially documented for 11g Release 1 (but will be in the upcoming patch and future releases).

This API class is a thin wrapper of the official Google Maps API, and as such you will need to get your own Google Maps key for your application.

The basic steps for displaying Google Maps in your Oracle Maps application are:

Step 1. Import the Google Maps JavaScript library

<script src="http://maps.google.com/maps?file=api&v=2&key=[your-Google-Maps-API-key]"
type="text/javascript"></script>

Again you will need to get your own Google Maps key from Google and set it in the above script tag.

Step 2. Add a Google Maps tile layer to the MVMapView object

mapview = new MVMapView(document.getElementById("map"), baseURL);
baseMap = new MVGoogleTileLayer() ;
mapview.addMapTileLayer(baseMap);

That's all it takes to display a basic Google Maps map in your MapViewer application.

You can also change the type of map you get from Google Maps. Here is an example:

var mapType = G_HYBRID_MAP;
basemap.setMapType(mapType) ;

Where basemap is a MVGoogleTileLayer instance. Note that G_HYBRID_MAP is a constant defined by the imported Google Maps API library and represents a hybrid Google Maps type. The full description for this method is:

setMapType(mapType)
This method sets the type of the map, which can be one of the following predefined Google Map types, G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP and G_PHYSICAL_MAP.

The only other method defined on the MVGoogleTileLayer class is getMapType(), which returns the current map type of the Google Maps being displayed.


Finally, as part of your application cleanup, please call Google Maps' clean-up method GUnload() (such as in the HTML page's unload event listener).

Monday, October 5, 2009

displaying table of longitude and latitude points

While in most cases your location data are stored in an Oracle database as SDO_GEOMETRY type, sometimes you may have certain point data stored simply as two numeric columns in a table (as longitude/latitude for instance). So how can you display these points using MapViewer? In this article I will present one of the more elegant options, namely using function-based index.

The overall steps are:
1. Create a database function that returns a SDO_GEOMETRY object from two numeric values.

2. Treat this function as a SDO_GEOMETRY column by creating an entry in the USER_SDO_GEOM_METADATA view.

3. Create a Spatial index on this function

4. Create a pre-defined theme in Map Builder for this function.

5. Profit.

Lets say we have an existing table CITIES in the schema SCOTT.

SQL> desc cities;
Name Null? Type
------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(100)
ALIASE VARCHAR2(500)
COUNTR VARCHAR2(100)
POP NUMBER
LON NUMBER
LAT NUMBER


Where the two columns LON and LAT represent each city's location.

So the first step is to create a function that generates an actual SDO_GEOMETRY object when supplied with a pair of (lon, lat).

Step 1. Create function

Execute the following while logged in as SCOTT:

create or replace function get_geometry(lon in number,
lat in number)
return SDO_GEOMETRY deterministic is
begin
return sdo_geometry(2001, 8307, sdo_point_type(lon, lat, NULL),NULL, NULL);
end;
/


Note that the function must be deterministic.

Step 2. Populate Spatial metadata view

Now that we have a function, we need to make Spatial and MapViewer treat it as if it's a real SDO_GEOMETRY column. All we need to do is insert an entry for this function in the USER_SDO_GEOM_METADATA view. Again execute the following as SCOTT:

insert into user_sdo_geom_metadata values('CITIES',
'scott.get_geometry(lon,lat)',
sdo_dim_array(
sdo_dim_element('Longitude', -180, 180, 0.005),
sdo_dim_element('Latitude', -90, 90, 0.005)),
8307);

commit;


Step 3. Create a Spatial index:
We now need to create a Spatial index on the function, just like with any SDO_GEOMETRY columns. Without a Spatial index, your SQL spatial queries won't work, and MapViewer cannot display them easily.

create index CITIES_SDX on
CITIES(get_geometry(lon,lat))
indextype is mdsys.spatial_index;


Step 4. Create a Map Builder theme

Open Map Builder, click Show Data to open the data navigator. You should find the CITIES table under the user SCOTT. Right click it and choose "Create Geometry Theme". You should see that the function we just created is already picked up as the Spatial column, as illustrated in this screen shot:



Go through the normal process and complete the theme creation. You now have a pre-defined MapViewer theme that can be used to display those (X,Y) data. You can also add this theme to your AJAX map as a FoI (Feature Of Interest) layer.