KML Modules: Services

in Technical


As I mentioned on HighEarthOrbit, I’ll start blogging about the OGC OWS-5 KML 3 effort here on the Mapufacture blog. We’ll be implementing the proposed standards on Mapufacture and pushing the edge of the GeoWeb. These posts will be fairly technical, which is why I’ve made a new category “Technical” - so if you want just these posts, subscribe to that category - or the opposite if you don’t want the nitty-gritty details of KML. If you need to catch up on what this is all about, check out my first post on KML 3.

So far I’ve covered the modules: Core, Styling, and Metadata. Another important one is the Services module. This defines how KML can link to external resources like OpenSearch, WFS, WMS, or others.

What are the use cases for the Service link?

  • Load KML geometry based on location and a search term from a search service like Mapufacture
  • Ground imagery from a WMS such as GeoServer
  • Streaming sensor data like from GeoBliki
  • Loading GML and a styling SLD from a WFS such as Galdos suggests

You may have noticed that the examples I gave in the use-cases above include the participants of the OGC OWS-5 Agile Geography thread. Just a small insight into the priority of use-cases when developing a format. However, if you have your own use cases, speak up now in the comments or your blog (and tag your posts/links with ogckml so we can easily pull them up).

Current NetworkLinks

Anyways, a KML link currently looks like:

<NetworkLink>
  <name>NE US Radar</name>
  <flyToView>1</flyToView>
  <Link>
    <href>
        http://www.example.com/geotiff/NE/MergedReflectivityQComposite.kml
    </href>
    <refreshMode>onInterval</refreshMode>
    <refreshInterval>30</refreshInterval>
    <viewRefreshMode>onStop</viewRefreshMode>
    <viewRefreshTime>7</viewRefreshTime>
    <viewFormat>
        BBOX=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth];
        CAMERA=[lookatLon],[lookatLat],[lookatRange],[lookatTilt],[lookatHeading];
        VIEW=[horizFov],[vertFov],[horizPixels],[vertPixels],[terrainEnabled]
    </viewFormat>
  </Link>
</NetworkLink>

KML 2.2 already lets you specify a base URL, and by default appends a BBOX parameter based on your current viewing window in a client like GoogleEarth. You can also optionally append on other view parameters that allow you to optimize your server results.

There are a few problems with the current service link definition. You are limited in what optional parameters you can include in your URL. You can’t template time parameters, geographic bounds other than bounding box (such as point/distance or polygon), or the service type.

There is a rather hidden way to add WMS layers currently to GoogleEarth. Go to “Add” -> “Image Overlay…”. click the “Refresh” tab, then click “WMS Parameters”. You can then choose a WMS server and add some layers. However, this method just builds up the WMS query for you and isn’t really part of the KML spec, but just a feature of GoogleeEarth.

Full Featured Network Links

To look at options, we investigated the current Web Context Service (WCS) definition, which includes methods for linking to WFS and WMS services. We then pared this down to be simpler, but kept he functionality for specifying the type of service, version, and other parameters:

<Server service="OGC:WMS" version="1.1.1" title=""
href="http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi"/>

By specifying the service type, OGC:WMS, clients can then determine if they support the service (they know how to build urls and parse the response), and also what a fully formed request looks like. For example, WMS requires appending various parameters for coordinate reference system, request type, format, and so on. By saying OGC:WMS, and being in a KML document, a lot of this information can be inferred.

In addition, we investigated supporting OpenSearch-Geo and -Time based templating for more generic searches.

Here is a possible example OpenSearch (or really any templatable URL):


<Server service="opensearch" version="1.1"
  title="Mapufacture keyword search" href="http://mapufacture.com/search.kml"/>
<viewFormat>dtstart=[timeStart]&dtend=[timeEnd]&keyword=[keyword]
  &bounds=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]</viewFormat>
<param name="keyword" editable="true">pizza</param>

What this shows is extending the viewFormat to include template parameters for time bounding (which GoogleEarth already supports in the GUI), and also using the existing BBOX template definition. By default, all params would be appended in as keyword=value pairs to the URL.

However, we’ve also considered adding the ability to extend the template with other parameters, keyword in this case, and also specified that it was editable, so the service would let the user change it via a UI and reinsert it into the URL to retrieve an updated KML document.

Imagine a KML client that parses these service definitions and sees that there are optional parameters such as “keyword”, “tags”, layer-type, or username, and then displays an input box for users to easily alter this value and request new data, without having to modify the service URL in the KML itself.

Here is a possible full KML 3 document with a WMS and OpenSearch service definition:


<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.x">
<NetworkLink>
  <name>WMS Link</name>
  <description>generates
   http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?...
    VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG:4326&WIDTH=512
    &HEIGHT=512&LAYERS=BNDTXT_1M:Foundation,ROADL_1M:Foundation
    &STYLES=black,0xaa1818&TRANSPARENT=TRUE&FORMAT=image/gif
    &BBOX=WSEN
  </description>
  <Region>
    <gml:envelope>
      <gml:lowerCorner>42.943 -71.032 500</gml:lowerCorner>
      <gml:upperCorner>43.039 -69.856 5000</gml:upperCorner>
    </gml:envelope>
  </Region>
  <Link>
  <Server service="OGC:WMS" version="1.1.1" title=""
    href="http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi"/>
    <viewRefreshMode>onStop</viewRefreshMode>
    <viewBoundScale>0.75</viewBoundScale>
    <param name="LAYERS">BNDTXT_1M:Foundation,ROADL_1M:Foundation</param>
    <param name="STYLES">black,0xaa1818</param>
    <param name="FORMAT">image/gif</param>
    <param name="KEYWORD" editable="true">Interstate</param>
  </Link>
</NetworkLink>
<NetworkLink>
  <name>OpenSearch service</name>
  <description>
    generates http://mapufacture.com/search.kml?keyword=pizza&bbox=wsen
  </description>
  <Link>
    <Server service="opensearch" version="1.1" ...
      title="" href="http://mapufacture.com/search.kml"/>
    <viewRefreshMode>onStop</viewRefreshMode>
    <viewBoundScale>0.75</viewBoundScale>
    <viewFormat>
      dtstart=[timeStart]&dtend=[timeEnd]&keyword=[keyword]
        &bounds=[bboxWest],[bboxSouth],[bboxEast],[bboxNorth]
    </viewFormat>
    <param name="keyword" editable="true">pizza</param>
  </Link>
</NetworkLink>
</kml>

This demonstrated a couple of additional concepts that already exist in KML (but now using the GML spec) such as <Region/> that specifies the available region that this network link applies to. Don’t bother (in fact, please don’t) query outside of this region because the service doesn’t have meaningful data.

Does this cover your use cases? Tim Schaub has brought up some good points on how to handle encoding of the parameter values, especially when trying to parse comma separated values in non-well-formed strings (that may include commas as part of a name, but shouldn’t be parsed on).

More soon on the possibilities of using KML 2.x/3 as a ‘context document’ and also KML 3D.