A Look at Google Earth API

Google’s earth viewer plugin is available for use in browsers on Windows and Vista, but not yet Linux or Mac. This latest addition to Google’s family of APIs (yet another beta) lets developers make use of the nifty 3D navigation found in the standalone Google Earth. However, as a plugin the developer now has more control using javascript with html or other server side frameworks such as asp .NET. http://code.google.com/apis/earth/
Here is the handy API reference:
http://code.google.com/apis/earth/documentation/reference/index.html

The common pattern looks familiar to Map API users: get a key code for the Google served js library and add some initialization javascript along with a map <div> as seen in this minimalist version.

<html>
  <head>
  <script src=”http://www.google.com/jsapi?key=…keycode…”
  type=”text/javascript”>
  </script>

<script>

var ge = null;
  google.load(“earth”, “1″);

function pageLoad() {
  google.earth.createInstance(“map3d”, initCallback, failureCallback);
  }

function initCallback(object) {
  ge = object;
  ge.getWindow().setVisibility(true);
  var options = ge.getOptions();
  options.setStatusBarVisibility(true);
  ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
  }

function failureCallback(object) {
  alert(‘load failed’);
  }
  </script>
  <head>
  <body onload=”pageLoad()”>
  <div id=’map3d’></div>
  </body>
</html>
Listing 1 – minimalist Google Earth API in html

This is rather straightforward with the exception of a strange error when closing the browser:

Google explains:
“We’re working on a fix for that bug. You can temporarily disable script debugging in Internet Options –> Advanced Options to keep the messages from showing up.”

…. but the niftiness is in the ability to build your own pages around the api. Instead of using Google Earth links in the standalone version, we can customize a service tailored to very specific desires. For example this experimental Shp Viewer lets a user upload his shape file with a selected EPSG coordinate system and then view it over 3D Google Earth along with some additional useful layers like PLSS from USGS and DRG topo from TerraServer.


Fig 2 – a quarter quad shp file shown over Google Earth along with a USGS topo index layer

In the above example, clicking on a topo icon triggers a ‘click’ event listener, which then goes back to the server to fetch a DRG raster image from TerraServer via a java proxy servlet.

  .
  .
case ‘usgstile’:
  url = server + “/ShpView/usgstile.kml”;
  usgstilenlink = CreateNetLink(“TopoLayer”, url, false);
  ge.getGlobe().getFeatures().appendChild(usgstilenlink);

google.earth.addEventListener(usgstilenlink, “click”, function(event) {
  event.preventDefault();
  var topo = event.getTarget();
  var data = topo.getKml();
  var index = data.substr(data.indexOf(“<td>index</td>”) + 20, 7);
  var usgsurl = server + “/ShpView/servlet/GetDRG?name=” +
  topo.getName() + “&index=” + index;
  loadKml(usgsurl);
  });
  break;
  .
  .
  .
  function loadKml(kmlUrl) {
  google.earth.fetchKml(ge, kmlUrl, function(kmlObject) {
  if (kmlObject) {
  ge.getFeatures().appendChild(kmlObject);
  } else {
  alert(‘Bad KML’);
  }
  });
  }
Listing 2 – addEventListener gives the developer some control of user interaction

In addition to the ‘addEventListener’ the above listing shows how easily a developer can use ‘getKML’ to grab additional attributes out of a topo pologon. Google’s ‘fetchKML’ simplifies life when grabbing kml produced by the server. My first pass on this used XMLHttpRequest directly like this:

  var req;

function loadXMLDoc(url) {
  if (window.XMLHttpRequest) {
  req = new XMLHttpRequest();
  req.onreadystatechange = processReqChange;
  req.open(“GET”, url, true);
  req.send(null);
  // branch for IE6/Windows ActiveX version
  } else if (window.ActiveXObject) {
  req = new ActiveXObject(“Microsoft.XMLHTTP”);
  if (req) {
  req.onreadystatechange = processReqChange;
  req.open(“GET”, url, true);
  req.send();
  }
  }
 }

function processReqChange() {
  if (req.readyState == 4) {
  if (req.status == 200) {
  var topo = ge.parseKml(req.responseText);
  ge.getFeatures().appendChild(topo);
  } else {
  alert(“Problem retrieving the XML data:\n” + req.statusText);
  }
  }
  }
Listing 3 – XMLHttpRequest alternative to ‘fetchKml’

However, I ran into security violations due to running the tomcat Java servlet proxy out of a different port from my web application in IIS. Rather than rewrite the GetDRG servlet in C# as an asmx, I discovered the Google API ‘fetchKML’, which is more succinct anyway, and nicely bypassed the security issue.


Fig 3 – Google Earth api with a TerraServer DRG loaded by clicking on USGS topo polygon

And using the Google 3D navigation


Fig 4 – Google Earth api with a TerraServer DRG using the nifty 3D navigation

Of course in this case 3D is relatively meaningless. Michigan is absurdly flat. A better example of the niftiness of 3D requires moving out west like this view of Havasupai Point draped over the Grand Canyon, or looking at building skp files in major metro areas as in the EPA viewer.


Fig 5 – Google Earth api with a TerraServer DRG Havasupai Point in more meaningful 3D view

This Shp Viewer experiment makes use of a couple other interesting technologies. The .shp file set (.shp, .dbf, .shx) is uploaded to the server where it is then loaded into PostGIS and added to the geoserver catalog. Once in the catalog the features are available to kml reflector for pretty much automatic use in Google Earth api. As a nice side effect the features can be exported to all of geoserver’s output formats pdf, svg, RSS, OpenLayers, png, geotiff, but minus the inimitable background terrain of Google Earth.

ogr2ogr is useful for loading the furnished .shp files into PostGIS where it is accessible to Geoserver and the also very useful kml_reflector. PostGIS + Geoserver + Google Earth API is a very powerful stack for viewing map data. There is also a nice trick for adding Geoserver featureTypes to the catalog programmatically. I used the Java version after writing out the featureType info.xml to geoserver’s data directory. Eventually, work on the Restful configuration version of Geoserver may make this kind of catalog reloading easier.

Summary:
Wow I like 3D and I especially like 3D I have control over. Google Earth API is easy to add into an html page and event listeners give developers some control over features added to the 3D scene. Coupled with the usual suspects in the GIS stack, PostgreSQL /PostGIS and Geoserver, it is relatively easy to make very useful applications. I understand though that real control freaks will want to look at WWjava.

If anyone would like to see a prototype UI of their data using this approach please email

This entry was posted in Uncategorized by admin. Bookmark the permalink.

Comments are closed.