GoogleMaps + Cobol
GoogleMaps brought the ability to create geocoded applications to the rest of us , i.e. applications that can locate and show information in maps. Now it is time to bring this ability to OO Cobol.
Audience
This example is aimed to Powercobol users, though any OO Cobol compiler that supports Microsoft COM should be able to create a similar application.
Enter the Power
This article shows how to add (and control) a map directly from a Powercobol window. See below a sneak preview of our application running:

Before dig the OO Cobol code (which is so tiny that you probably would be disappointed) lets review GoogleMaps API and the proposed solution's architecture.
What is the Matr...err, Google Maps?
According to the Wikipedia Google Maps is a "web mapping service application and technology provided by Google, free (for non-commercial use), that powers many map-based services, including the Google Maps website, Google Ride Finder, Google Transit, and maps embedded on third-party websites via the Google Maps API. It offers street maps, a route planner for traveling by foot, car, or public transport and an urban business locator for numerous countries around the world".
Solution architecture
The proposed solution comprises three distinct, but complementary technologies:
1. PowerCobol (5.x or higher) which is the reason of this article
The Powercobol RAD environment provides all needed support to create rich application that easily integrates with state-of-art technologies such as Google Maps(tm).
2. A web page with Google Maps API and custom Javascript functions
The web page contains all needed information to show the map. The methods used to control the map goes here too.
3. Google Maps service
The Google Maps service provides the up-to-date map information.
The diagram below depict the architecture used in this application:
Desktop www.yoursite.com Google servers

The application life cycle is basically the following:
[1] The Powercobol app loads the web browser object passing the URL of the HTML web page that is hosted in this web site (www.100coolthings.net).
[2] The web page requested is loaded in the web browse. The page "onload" event calls the initialize() javascript function which intializes the Google Maps API and pass map start point parameters to the Google Maps Server
[3] Google Maps servers receives the parameters sent by the Google Maps API(tm) and use that info to build the map for the requested location
[4] The web browser shows the new location in the map object.
If the user select an address, the steps 3 and 4 are repeated.
Get your key
The first step to create a Google Maps compatible app is to get your Google Map key. Google requires a unique key per site. Using your Google account create the key for your site:
http://code.google.com/apis/maps/signup.html
The HTML/Javascript side of the Moon
The following HTML code was used in this example. It contains the neeed Javascript code to show the map. The Powercobol application call Javascript functions embedded in this page to control the map.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API Example: Extraction of Geocoding Data</title>
<script src="http://maps.google.com/maps?file=api&v=2.x&key=ABQIAAAA1fYlhLETaHs7Up3tAu74SBQhrvKIDPjhlAyAU9SYn_w3sPduyBTzQHqW6L7KZ36IOo4DSSs9_CMeyQ"
type="text/javascript"></script>
<script type="text/javascript">
var map;
var geocoder;
function initialize() {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(34, 0), 1);
map.setUIToDefault();
geocoder = new GClientGeocoder();
}
// addAddressToMap() is called when the geocoder returns an
// answer. It adds a marker to the map with an open info window
// showing the nicely formatted version of the address and the country code.
function addAddressToMap(response) {
map.clearOverlays();
if (!response || response.Status.code != 200) {
alert("Sorry, we were unable to geocode that address");
} else {
place = response.Placemark[0];
point = new GLatLng(place.Point.coordinates[1],
place.Point.coordinates[0]);
marker = new GMarker(point);
map.addOverlay(marker);
map.zoomIn(point, true, true);
marker.openInfoWindowHtml(place.address + '<br>' +
'<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
}
}
// showLocation() is called when you click on the Search button
// in the form. It geocodes the address entered into the form
// and adds a marker to the map at that location.
function showLocation() {
var address = document.forms[0].q.value;
geocoder.getLocations(address, addAddressToMap);
}
// findLocation is called by PowerCobol to look for a location based in the passed address
function findLocation(address) {
document.forms[0].q.value = address;
showLocation();
}
// drawCircle is called by PowerCobol to draw a circle in the map.
function drawCircle(lt0, lg0, lt1, lg1, borderColour, fillColour) {
var centerMarker = new GLatLng(lt0,lg0);
var radiusMarker = new GLatLng(lt1,lg1);
var normalProj = map.getCurrentMapType().getProjection();
var zoom = map.getZoom();
var centerPt = normalProj.fromLatLngToPixel(centerMarker, zoom);
var radiusPt = normalProj.fromLatLngToPixel(radiusMarker, zoom);
var circlePoints = Array();
with (Math) {
var radius = floor(sqrt(pow((centerPt.x-radiusPt.x),2) +
pow((centerPt.y-radiusPt.y),2)));
for (var a = 0 ; a < 361 ; a+=5 ) {
var aRad = a*(PI/180);
y = centerPt.y + radius * sin(aRad)
x = centerPt.x + radius * cos(aRad)
var p = new GPoint(x,y);
circlePoints.push(normalProj.fromPixelToLatLng(p, zoom));
}
circleLine2 = new GPolygon(circlePoints,borderColour,2, 1, fillColour,0.2);
map.addOverlay(circleLine2);
}
}
</script>
</head>
<body onload="initialize()" topmargin="0" leftmargin="0" marginheight="0" marginwidth="0">
<div id="map_canvas" style="width: 453px; height: 426px"></div>
<form action="#" onsubmit="showLocation(); return false;">
<input type="hidden" name="q" value="" />
</form>
</body>
</html>
PS: The HTML above was adapted from a Google's example.
The OO Cobol side of the Moon
Our Powercobol app defines a form with a web browser object within. This object essentially is an instance of IE (version 5.x). Supported versions of Powercobol are: 5, 6, 7, 8, 9 and 10.
Repository
The following declarations is required in the powercobol form Repository:
CLASS COM AS "*OLE"
Form Opened event:
INVOKE WebBrowser1 "Navigate" USING "http://www.100coolthings.net/Portals/3/GoogleMapsAPI.html"
Listview double-click event
The following code is required to define variables capable to deal with Web Browser ActiveX object:
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 webBrowserCom usage object reference COM.
01 document usage object reference COM.
01 parentWindow usage object reference COM.
In the Procedure Division of Listview double-click event we need to convert the Powercobol object(WebBrowser1) into a COM compatible object:
CALL "POWERCONVTOCOM" USING WebBrowser1 returning webBrowserCom
Now we need to get the Document.parentWindow object from WebBrowser1 instance:
invoke webBrowserCom "GET-Document" returning document
invoke document "GET-parentWindow" returning parentWindow
Finally we call the "execScript" method of parentWindows object passing the javascript function call as a parameter:
invoke parentWindow "execScript" using "findLocation('Colatina, ES, BR');" & x"00".
That's it! The code above is using a static string, but our example uses the selected ListView row to pass the address (see the actual code in the PPJ below). We can call any Javascript function, and even better; we can also receive the return of a function, allowing a complete integration between OO Cobol and a web page.
Now is your turn!
PS: You need to register in order to download this sample