I have to admit that I’ve been a bit leary of Google Earth. It’s not just the lurking licensing issues, or the proprietary application install, or even the lack of event listeners, or accessible api. If I’m honest I have to admit I’m a bit jealous of the large infrastructure, the huge data repository, and the powerfully fun user interface. So this weekend I faced my fears and downloaded the current version, Google Earth 4.3.
I’m not really interested in the existing Google Earth stuff. There are lots of default layers available, but I want to see how I can make use of the cool interface and somehow adapt it as a control for my stuff. The easiest route to customization in GE is KML. KML was developed for XML interchange of Keyhole views before Google bought Keyhole and turned it in to Google Earth. Keeping the KML acronym does avoid some conflict since Keyhole Markup Language, KML, does not run into the namespace conflict with the other GML, OGC’s, that would result from Google Markup Language.
KML 2.2 has evolved much further than a simple interchange language with some features that can be adapted to customized GE applications. After looking over the KML 2.2 reference I started with a simple static KML file. I have a USGS topo index table in PostGIS that I wished to view over the Google terrain. PostGIS includes an AsKML function for converting Geometry to KML. Using Java I can write a JDBC query and embed the resulting geometry AsKML into a KML document. However adding a WMS layer in between the PostGIS and GE seemed like a better approach. Geoserver gives you a nice SOA approach with built in KML export functionality as well as custom styling through sld.
It is easy to set up Geoserver as a WMS layer over the PostGIS database containing my USGS topo index table. Geoserver has also included a KML export format for the WMS framework. So I simply add my table to the Geoserver Data Featuretype list. Now I can grab out a KML document with a WMS query like this:
This is simple, and the resulting kml provides a basic set of topo polygons complete with a set of clickable attribute tables at the polygon center points. The result is not especially beautiful or useful, but it is interesting to tilt the 3D view of the GE terrain and see that the polygons are draped onto the surface. It is also handy to have access to the topo attributes with the icon click. However, in order to be useful I need to make my kml a bit more interactive.
The next iteration was to create a simple folder kml with a <NetworkLink>:
<kml xmlns="http://earth.google.com/kml/2.1"> <Folder> <name>USGS Topo Map Index</name> <description> <![CDATA[ <h3>Map Tiles</h3> <p><font color="blue">index tile of 1:24000 scale <b> USGS topographic maps</b> 1/8 degree x 1/8 degree coverage</font> <a href='http://topomaps.usgs.gov/'> more information>> </a> </p> ]]> </description> <NetworkLink> <name>WMS USGS quad tiles</name> <Link> <href>http://rkgeorge-pc/GoogleTest/servlet/GetWMS</href> <httpQuery>layer=usgstile</httpQuery> <viewRefreshMode>onStop</viewRefreshMode> <viewRefreshTime>1</viewRefreshTime> <viewFormat>BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth] &CAMERA=[lookatLon],[lookatLat]</viewFormat> </Link> </NetworkLink> </Folder> </kml>
In this case the folder kml has a network link to a java servlet called GetWMS. The servlet handles building the GetMap WMS query with customized style sld loading so that now I can change my style as needed by editing a .sld file. The servlet then opens my usgstile query and feeds the resulting KML back to the kml folder’s <NetworkLink>. Since I have set the <viewRefreshMode> to onStop, each time I pan around the GE view I will generate a new call to the GetWMS servlet which builds a new GetMap call to Geoserver based on the current bbox view parameters.
This is more interesting and adds some convenient refresh capability, but views at a national or even state level are quickly overwhelmed with the amount of data being generated. The next iteration adds a <Region> element with a <LOD> subelement:
<Region> <LatLonAltBox> <north>70.125</north> <south>18.875</south> <east>-66.875</east> <west>-160.25</west> </LatLonAltBox> <Lod> <minLodPixels>30000</minLodPixels> <maxLodPixels>-1</maxLodPixels> </Lod> </Region> </font>
Now my refreshes only occur when zoomed in to a reasonable level of detail. The kml provides a layer of USGS topo tiles and associated attributes from my PostGIS table by taking advantage of the built in KML export feature of Geoserver’s WMS.
Fig 2 – Google Earth with <Region><LOD> showing USGS topo tiles
Unfortunately Google Earth 4.3 seems to disable the onStop refresh after an initial load of my usgstile subset, once a Region element with LOD is added. In GoogleEarth 4.2 I didn’t run into this problem. The work around appears to be a manual refresh of the menu subtree “WMS USGS quad tiles”. Once this refresh is done, pan and zoom refresh in the normally expected ‘onStop’ fashion. GE 4.3 is beta and perhaps this behavior/”feature” will be changed for final release.
Now I have a reasonable USGS tile query overlay. However, why just show the tiles. It is more useful to show the actual topo map. Fortunately the “web map of the future” from four or five years ago is still around “terraservice.net” Terra service is a Microsoft research project for serving large sets of imagery into the internet cloud. It was a reasonably successful precursor to what we see now as Google Map and Virtual Earth. The useful thing for me is that one of the imagery layers that this service provides as a WMS, is DRG, Digital Raster Graph. DRG is a seamless WMS of the USGS topo map scans in a pyramid using 1:250,000, 1:100,000, and 1:24000 scale scanned paper topos. Anyone doing engineering, hiking etc before 2000 is probably still familiar with the paper topo series which, once upon a time, was the gold standard map interface. Since then the USGS has fallen on harder times, but before they fall into utter obscurity they did manage to swallow enough new tech to produce the DRG map scans and let Microsoft load it into TerraService.net.
This means that the following url will give back a nice jpeg 1:24000 topo for Mt Champion in Colorado:
Armed with this bit of WMS capability I can add some more capability to my GoogleTest. First I added a new field to the usgstile database, which can be seen in the screen capture above. The new field simply makes a reference url to another servlet I wrote to build the terraservice WMS query and pull down the requested topo image. By setting the width and height parameters to 2000 I can get the full 1:24000 scale detail for a single 1/8 degree topo quad. My GetDRG servlet also conveniently builds the kml document to add the topo to my Google Earth menu:
<?xml version="1.0" encoding="UTF-8"?></font> <kml xmlns="http://earth.google.com/kml/2.2"> <Folder> <name>38106G1 Buena Vista East</name> <description>DRG Overlay of USGS Topo</description> <GroundOverlay> <name>Large-scale overlay on terrain</name> <description> <![CDATA[ <h3>DRG Overlay</h3> <p><font color="blue">index tile of 1:24000 scale <b> USGS topographic maps</b> 1/8 degree x 1/8 degree coverage</font> <a href='http://topomaps.usgs.gov/'>more information>></a> </p> ]]> </description> <Icon> <href>http://terraservice.net/ogcmap6.ashx?version=1.1.1&request=GetMap &Layers=DRG&Styles=&SRS=EPSG:4326&BBOX=-106.125,38.75,-106.0,38.875 &width=2000&height=2000&format=image/jpeg&Exceptions=se_blank</href> </Icon> <LatLonBox> <north>38.875</north> <south>38.75</south> <east>-106.0</east> <west>-106.125</west> <rotation>0</rotation> </LatLonBox> </GroundOverlay> </Folder> </kml>
The result is a ground clamped USGS topo over the Google Earth terrain. It is now available for some flying around at surface level in the cool GE interface. Also the DRG opacity can easily be adjusted to see the Google Earth imagery under DRG contours. The match up is pretty good but of course GE imagery will be more detailed at this stage. I also understand that Google is in the process of flying submeter LiDAR through out areas of the USA so we can expect another level in the terrain detail pyramid at some point as well.
This is all fun and hopefully useful for anyone needing to access USGS topo overlays. The technology pattern demonstrated though, can be used for just about any data resource.
1) data in an imagery coverage or a PostGIS database
2) Geoserver WMS/WCS SOA layer
3) KML produced by some custom servlets
This can be extremely useful. The Google Earth interface with all of its powerful capability is now available as a nice OWS interface for viewing OWS exposed layers which can be proprietary or public. For example here is an example of a TIGER viewer using this same pattern:
Fig 3 – TIGER 2007 view of El Paso County Colorado
Google Earth viewer does have a gotcha license, but it may be worth the license cost for the capability exposed. In addition, if Microsoft ever catches up to the KML 2.2 spec recently released as a final standard by the OGC, this same pattern will work conveniently in Virtual Earth and consequently in a browser through a recently announced future silverlight VE element. Lots of fun for view interfaces!
My next project is to figure out a way to use GE KML drawing capability to make a two way OWS using Geoserver transactional WFS, WFS-T.