March 2008
Oracle Spatial User Conference
Oracle Spatial User Conference
March 13, 2008
Sheraton Seattle Hotel
Seattle, Washington USA
Trevor QuinnPrincipal DeveloperSystalex Corporation
March 2008
Oracle Spatial User Conference
Web Mapping with Virtual Earth and Oracle in EPA's Grant Tracking Systems
March 2008
Oracle Spatial User Conference
• GRTS: EPA's Grant Reporting and Tracking System for EPA's Non-Point Source Reduction Grants• Enterprise web application• Tracks grant activities, budgeting, performance,
and results. Not a GIS application per se.• Mapping streamlines user interface, allows users to
more easily find grants, summarize program data, and enter locational information about grants
• Microsoft Virtual Earth is now an agency approved geospatial technology
Project BackgroundMarch 2008
Oracle Spatial User Conference
Technologies Used
• Microsoft Virtual Earth SDK 6• JavaScript/AJAX: Prototype 1.6 and
Scriptaculous• Oracle 10g Locator• Oracle Application Express 3.0• Oracle MapViewer (WMS) • PL/SQL (feature processing) • Java 1.4 (WMS tile server)
March 2008
Oracle Spatial User Conference
Overview
• Concepts and Implementation• Tiles: Deploying a custom tile server for Virtual
Earth (or Google Maps) • Reflecting WMS as Virtual Earth tiles• Caching tiles
• Features: Passing data between Virtual Earth and Oracle 10g
• Enabling AJAX calls in Oracle Application Express• Generating and parsing GeoJSON for Virtual Earth• Submitting features to the database as WKT
• Demonstration
March 2008
Oracle Spatial User Conference
Data Flow OverviewMarch 2008
Oracle Spatial User Conference
WMS Virtual Earth Tile Cache
Web browser
Oracle 10g
APEX 3.0
JDBCImage files
Image files
Features (GeoJSON and WKT)
TilesDeploying a custom tile server
March 2008
Oracle Spatial User Conference
Tiles
• VE tiles are 256px-by-256px quadtree-indexed image files that together form a grid of a map in Google's Mercator-projected geographic coordinate system
• Any map that matches or approximates this projection can be broken up into usable tiles (including WMS)
March 2008
Oracle Spatial User Conference
TilesMarch 2008
Oracle Spatial User Conference
Image reproduced from Microsoft MSDN website
Sample VE Tiles and Their Quad CodesMarch 2008
Oracle Spatial User Conference
0320
0212300
02310103012123
Reflecting WMS as Tile Images
• We need a process for converting a VE tile request into a WMS request and returning the result
• This process must be callable through a URL, passed to Virtual Earth's JavaScript API
• Once provided the URL, the VE API will overlay WMS tiles on the VE background at a matching scale (with user-specified transparency)
March 2008
Oracle Spatial User Conference
Overlaying WMS Tiles on Virtual EarthMarch 2008
Oracle Spatial User Conference
Virtual Earth
WMS
Combined
Tile Serving Process (without Caching)March 2008
Oracle Spatial User Conference
WMS VE Tile Cache BrowserOracle
10g
Tile request(HTTP Get)
WMS request(HTTP Get)JDBC
queries
JDBC result sets
PNG fileresponse (HTTP)
Forwarded PNG fileresponse (HTTP)
Reflecting WMS as Tile ImagesMarch 2008
Oracle Spatial User Conference
AddTileLayer: function(mapName, opacity){ var tileSourceSpec = new VETileSourceSpecification(mapName, "http://aruba.systalex.com/WMSTileServer/?MAP_NAME=" + mapName + "&VE_QUAD_CODE=%4"); tileSourceSpec.NumServers = 1; tileSourceSpec.Opacity= opacity; this.map.AddTileLayer(tileSourceSpec, false); },
VE replaces with a quadtree tile code based on scale and extent of current map view(023, 121122, 13, etc.)
VE Tile Cache ServletMarch 2008
Oracle Spatial User Conference
public Box QuadKeyToBox(String quadString, int x, int y, int zoomLevel) { char c = quadString.charAt(0); int tileSize = 2 << (18 - zoomLevel - 1); if (c == '0') { y = y - tileSize; } else if (c == '1') { y = y - tileSize; x = x + tileSize; } else if (c == '3') { x = x + tileSize; } if (quadString.length() > 1) { return QuadKeyToBox(quadString.substring(1), x, y, zoomLevel + 1); } else{ return new Box(x, y, tileSize, tileSize); }}// Then convert Box x and y values to WGS84 latitude and longitude
VE Tile Cache Java servlet (adapted from Active Web Solutions C# source)
Tile Serving Process (with Caching)March 2008
Oracle Spatial User Conference
WMS VE Tile Cache BrowserOracle
10g
Tile request(HTTP Get)
Forwarded PNG fileresponse (HTTP)
(Tile in local cache)
Caching Tiles in the VE Tile Cache ServletMarch 2008
Oracle Spatial User Conference
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... File f = new File(dir, quadKey + ".png"); if (!f.exists()) { // If the image is not already cached, make call to WMS BufferedImage bi = ImageIO.read(buildURL(ml, quadKey)); ImageIO.write(bi, "png", response.getOutputStream()); f.createNewFile(); // Write the image to the designated tile cache folder on the server ImageIO.write(bi, "png", f); } else { // Otherwise, just display the image from cache ImageIO.write(ImageIO.read(f), "png", response.getOutputStream()); } }
Servlet HTTP response source code fragment:
FeaturesPassing data between Virtual
Earth and Oracle 10g
March 2008
Oracle Spatial User Conference
Adding Features to the WMS Overlay in Virtual EarthMarch 2008
Oracle Spatial User Conference
Feature Serving ProcessMarch 2008
Oracle Spatial User Conference
Browser
AJAX feature request (HTTP Get)
JSON response(HTTP)PL/SQL Process
in Oracle 10gHTTP Server
AJAX feature request
JSON response(HTTP)
Serving Features to Virtual EarthMarch 2008
Oracle Spatial User Conference
/** * Makes an AJAX request to the database for a feature corresponding to a * drainage area ID. * * @param {Object} drainageAreaId * @return {Object} drainageArea */function LoadDrainageArea(drainageAreaId){ var ajaxRequest = new htmldb_Get(null, $('pFlowId').value,'APPLICATION_PROCESS=LoadDrainageArea',0); ajaxRequest.add('P1131_PRJDRAR_SEQ',drainageAreaId); drainageArea = ajaxRequest.get(); ajaxRequest = null; return drainageArea;}
An AJAX request to run an APEX PL/SQL process:
Serving Features to Virtual EarthMarch 2008
Oracle Spatial User Conference
DECLARECURSOR map_cur IS SELECT * FROM drain_area_map m WHERE m.id = :P1131_ID;htp.prn('{');htp.prn(' "type": "FeatureCollection",');htp.prn(' "features": [');BEGIN FOR v_map IN map_cur LOOP htp.prn(' {'); htp.prn(' "type": "Feature",'); htp.prn(' "id": "' || v_map.prjdrarmap_seq || '",'); htp.prn(' "geometry": {'); htp.prn(' "type": "MultiPoint",'); htp.prn(' "coordinates": [ [' || v_map.geo_start.sdo_point.x || ', ' || v_map.geo_start.sdo_point.y || '],' || ' [' || v_map.geo_end.sdo_point.x || ', ' || v_map.geo_end.sdo_point.y || '] ]'); htp.prn(' "properties": {'); ... htp.prn(' }'); htp.prn(' }'); END LOOP;END;
The APEX PL/SQL process that queries for and returns features:
Serving Features to Virtual EarthMarch 2008
Oracle Spatial User Conference
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "id": "112322", "geometry": { "type": "MultiPoint", "coordinates": [ [102.0, 0.0], [103.0, 1.0] ] }, "properties": { "Stream name": "Miller Creek", "Inserted by": "John Wilson" "Inserted date": "03-MAR-2007" } }, ... ]}
The JSON representation of features:
Serving Features to Virtual EarthMarch 2008
Oracle Spatial User Conference
function GeoJSONCollection2VEShape(geoJSONCollection) { for (var i = 0; i < geoJSONCollection.features.length; i++) { feature = geoJSONCollection.features[i]; switch (feature.geometry.type) { case "MultiPoint": for (var j = 0; j < feature.geometry.coordinates.length; j++) { coordinate = feature.geometry.coordinates[j]; latLong = new VELatLong(coordinate[1], coordinate[0]); var shape = new VEShape(VEShapeType.Pushpin, latLong); shape.SetDescription(Object.toJSON(feature.properties)); veShapeArray.push(shape); } break; this.GetVEShapeArray = function() { return veShapeArray; }}...var converter = new GeoJSONCollection2VEShape(geoJSONFeatureCollection); var veShapeArray = converter.GetVEShapeArray();VEShapeLayer.addShape(veShapeArray[0]);
Parsing JSON and displaying in Virtual Earth
Submitting Features to the Database from Virtual EarthMarch 2008
Oracle Spatial User Conference
• A similar process is used for submitting features to the database from Virtual Earth (create AJAX call on client, create PL/SQL process in database)
• When creating features for database submission, forming WKT is easier than JSON, because Oracle Spatial has:
SDO_UTIL.FROM_WKTGEOMETRY( geometry IN CLOB) RETURN SDO_GEOMETRY;
D E M O N S T R A T I O N
Web Mapping with Virtual Earth and Oracle 10g in EPA's Grant Tracking
Systems
Resources
• MSDN Building Your Own Tile Server: http://msdn2.microsoft.com/en-us/library/bb545006.aspx
• Accessing WMS from Virtual Earth by Rob Blackwell of Active Web Solutions Ltd. http://viavirtualearth.com/vve/Articles/WMS.ashx
• Video demonstration of the Virtual Earth in the EPA grant tracking application:http://www.systalex.com/capabilities/web_dev.html
March 2008
Oracle Spatial User Conference