Proposal 6.2: Capabilities Metadata

Author: Glenn Stowe, CubeWerx, gstowe@cubewerx.com
Author: Frank Warmerdam, 3i, warmerdam@pobox.com
Proposed: 2001/02/16
Last Edited: 2001/06/13
Status: Proposed

Summary

A mechanism is introduced to return version information, layer lists, and related metadata from drivers in a format inspired by the OGC WFS capabilities document.

Background

The current method used by OGDI to report the contents of a data store is a two step process. A function called GetDictionary returns a TCL/TK applet used to define a user interface, and a subsequent call to UpdateDictionary fills in the data in that applet.

There are two major issues with this approach.

  1. A client application not written in TCL/TK has no use for the applet provided by GetDictionary.
  2. There is no standard format for driver writers to use when reporting the content of their data store.
This leaves client application developers scrambling to recognize the many different dictionary formats returned by drivers, which violates the basic principal of OGDI. The main benefit of OGDI resides in the capability of accessing a variety of native formats by separating the client and server applications.

Approach

The OGC WFS capabilities document (as normally returned by a GetCapabilities request) is modified for our use, and will be returned by OGDI 3.1 compliant drivers when cln_UpdateDictionary("ogdi_capabilities") is called. Note that this is a required feature of 3.1 compliant OGDI drivers.

The existing OGC WFS standard should be referred to for background on tags not specifically added, altered or reinterpreted by this proposal. It is expected that this will become available on the public OGC web site (www.opengis.org) in coming months. In the meantime it is available under the member services area to OGC members.

In general terms, the OGC style capabilities document is intended to describe more about a data server than it is practical to return from the depths of an OGDI driver - keep in mind these documents are generated by the dyn_UpdateDictionary() call of individual drivers. As such, some of the general service description and capabilities information is not easily generated. Furthermore, as it will be implemented a client can't get the capabilities information till after connecting to the server so information such as the gltp url, or supported protocols isn't really valuable anymore.

This mismatch of levels motivates a number of items being made optional in this proposal that are requested by OGC WFS GetCapabilities operations. It is intended that the OGDI capabilities document being discussed in this proposal could be used to populate higher level services catalogs at which point much of the services and capabilities information would be filled in; however, that is not important to the most direct use under this proposal.

As well as ogdi_capabilities support, 3.1 drivers are required to return the same document with the FeatureTypeList element, and all subelements omitted when a cln_UpdateDictionary("ogdi_server_capabilities") request is made. This is intended to provide a mechanism for applications to perform version and extention negotiation with servers having many layers efficiently when layer information is not required.

Element Changes

  1. The OGDI_Capabilities element replaces the WFS_Capabilities element.

  2. The version attribute of the OGDI_Capabilities node now refers to the OGDI version supported by the driver, this is more fully defined in a following section.

  3. The Service element is made optional and generally will not be filled in by OGDI drivers.

  4. The Request element of Capability is made optional, and generally won't be filled by OGDI drivers. At some point in the future alternate definitions to the existing DCPType sub-elements will need to be defined, but they are not significant to low level use of the capabilities.

  5. The Extension element is introduced, and is used to list an extension (extensions are defined later).

  6. One or more Extensions may be included under Capability indicating extensions supported for all layers in the dataset.

  7. The Operation element should always, and only, contain the Query operation.

  8. The FeatureTypeList element can now have FeatureTypeList elements as children (to express heirarchy), and a Name element as a child (to name nodes in the heirarchy).

  9. The FeatureTypeList element is optional in the DTD. It is intended that a list should be provided for ogdi_capabilities but not included for ogdi_server_capabilities requests.

  10. The Name element (when used under FeatureType) will contain a name suitable to pass to cln_SelectLayer(). In cases where layers may contain query strings, the default query string selecting all features will be listed, for instance we might use buildnga@col(*) for a VRF layer.

  11. The SRS element will contain a coordinate system definition expressed in PROJ.4 syntax, as normally returned by cln_GetServerProjection() but prepended with PROJ4:. This is intended to treat PROJ4 as a pseudo-authority in OGC terms.

  12. Add the Family element (1 or more) which must contain one of Matrix, Image, Point, Text, Line, or Area as the text contents. One or more of these are used with each layer to indicate the list of family types existing in that layer.

  13. The LatLonBoundingBox has been made optional so that a eventually supporting un-georeferenced data will be possible.

  14. The BoundingBox element under FeatureType has been made manditory with semantics just like BoundingBox in WMS or except that the SRS element isn't accepted (the SRS is implicitly the one specified in the tag). Note that the x and y resolutions (resx, and resy) should be a divisor of the x and y extents of the bounding box. The resolution has no intended meaning in the case of vector layers (though it must still be provided).

  15. Add the QueryExpression element under FeatureType which is used to describe some information about substituting query strings in the layer name. This element is described more fully in a following section.

  16. One or more Extensions may be included under FeatureType indicating extensions supported for all layers in the dataset.

Versioning

The version is a textual representation of a numerical version number. It indicates the version of the OGDI specification supported by the driver/server.

Each legal version number will be defined by the 3i, with an associated specification document indicating the requirements for claiming to support that version.

Version numbers will be decimal values (such as "3.0", "3.1"), where a higher version number always implies that all capabilities of previous versions are supported. (This may be violated when the major version changes, for instance a switch from 3.x to 4.x). The version numbers will always be numerically comparable, so 3.10 is really just 3.1. If we want to have minor versions after 3.9 we might number them 3.91 rather than 3.10.

The version is returned as the value of the version attribute of the OGDI_Capabilities element.

Extensions

The extensions supported by a server are represented as a list of extension identifiers. The presence of the extension identifier indicates that this server (at least for the current datastore or layer) supports the indicated extensions.

The extension identifiers will conform to the following restrictions:

Extension applying to the whole datastore, or all layers may be returned as Extension elements under the Capability element. Extensions that only apply to some returned layers should be returned as children of the appropriate FeatureType element(s).

QueryExpression

The QueryExpression element is used to define some information about the query expression format for layers (FeatureTypes) that allow some sort of query expression to be passed in the layer name. The VRF driver is an example of where this might be used. It is intended to allow sophisticated clients to identify drivers allowing attribute queries without having an exaustive list of drivers available.

The QueryExpression element's contents (if present) are taken to be a textual description that may be shown to the user as a hint to help composing query expressions. The text is unstructured, but should be human readable.

The following attributes included with the QueryExpression:

  1. qe_prefix - REQUIRED: the portion of the layer name that preceeds the expression when forming the layer name.

  2. qe_suffix - REQUIRED: the portion of the layer name that follows the expression when forming the layer name.

  3. qe_format - OPTIONAL: an indentifier giving the format of the expression string. Currently only restricted_where is supported, but in the future other standardized formats for expressions may be added.

Note that the prefix and suffix data can be ignored when using the default form of the layer name, and the value from the Name element is used.

qe_format=restricted_where

The qe_format value restricted_where indicates the expression takes the form of the SQL WHERE clause with restrictions, the fields being the feature attributes. The following defines the manner in which the restricted where clauses can be constructed. Intepretation is according to the SQL standard.

The following production rules describe the syntax of restricted where conditions. Note that the SQL NOT operator is not available. Also, SQL regex and LIKE operators are not available.

@condition@ = @field_name@ @binary_operator@ @value@
           | "(" @condition@ ")" @binary_logical_operator@ "(" @condition@ ")"

@binary_operator@ = "<" | ">" | "<=" | ">=" | "<>" | "="

@binary_logical_operator@ = "AND" | "OR" 

@field_name@ = @string_token@

@value@ = @string_token@ | @numeric_value@ | @string_value@

@string_value@ = "'" @characters@ "'"
The @numeric_value@ item can be a normal integer, decimal or exponential number. The @characters@ can be any sequence of characters but may not containing single quotes. The @string_token@ starts with a character in a-z,A-Z and is followed by any number of characters in the set a-z,A-Z,0-9 and underscore.

OGDI_Capabilities DTD

A proposed DTD has been prepared for those wanting to validate OGDI_Capabilities documents, though it isn't anticipated that this would be used in normal practise. In normal practise extra elements should be gracefully ignored, to support forward compatibility.

GeoTIFF Example

Example: geotiff.xml

Notes:

  1. The version is set to "3.1", indicating the overall version of the driver.

  2. The Capability section is completly omitted since there is no pertinent information.

  3. Each layer has a PROJ.4 style SRS.

  4. Each layer can be accessed as either a Matrix or an Image, so both families are listed.

  5. There is an BoundingBox for each layer, showing it's extents, and resolution. In the past it wasn't possible to safely establish the extents and resolutions of particular layers from OGDI.

VRF Example

Example: vrf.xml

Note:

  1. Unlike the geotiff example, this document includes the optional Capability section so that the ogdi_unique_identity extension can be associated with the whole datastore.

  2. This example also demonstrates heirarchy, with two coverages (elev and col) represented as named sub FeatureTypeLists, each of which has more than one FeatureType representing the layers supported for that coverage.

  3. The VRF query expression is represented via a QueryExpression element. It has to be included with every layer, even though it is the same for all.

API Changes

This proposal does not require any changes or additions to the RPC prototcol or the list of possible entry points to a driver. The client api could also be left unchanged, but it is desirable to provide a standard (and simple) API for clients to collect information from capabilities documents without each client having the details of how to parse the capabilities document. Note that, clients may ignore this API, and get the capabilities document themselves. In fact, clients wanting to access all aspects of the capabilities document will need to do so, since this API is simplified and won't necessarily be extended when new capabilities are added to the capabilities document.

It is my intention that this API should be implemented in the client c-api as, either using an existing xml parser like expat, or a simple ad-hoc parser.

cln_GetVersion()

  ecs_Result *cln_GetVersion(int ClientID);
Returns the version string for the current driver. If the current driver does not return an "ogdi_capabilities" response, a value of "3.0" will be assumed and returned. The returned value is an ecs_Text structure, or error if something goes badly wrong.

cln_CheckExtension()

  int cln_CheckExtension(int ClientID, const char *extension, 
                         char *layer);
Returns TRUE if the given extension is supported on the indicated layer (or at the driver level if layer is NULL). Note that the layer name must be exactly the value is the Name element for that layer (FeatureType).

Even if a layer name is provided, this function will also check the driver wide capabilities. In the future it may be able to deduce that some extensions are supported if the version returned in the capabilities implies that it must. If an error occurs processing the capabilities document, this function will return FALSE. It is generally advised to use cln_GetVersion() before cln_CheckExtension() so that errors processing the capabilities can be properly captured and reported.

cln_GetLayerCapabilities()

typedef struct {
  char  *name;
  char  *title;
  char  *srs;
  int   families[MAX_FAMILIES];
  char  **parents;
  char  **extensions;

  int    ll_bounds_set;
  double ll_north;
  double ll_south;
  double ll_east;
  double ll_west;

  int    srs_bounds_set;
  double srs_north;
  double srs_south;
  double srs_east;
  double srs_west;
  double srs_nsres;
  double srs_ewres;

  int    query_expression_set;
  char	 *qe_prefix;
  char	 *qe_suffix;
  char	 *qe_format;
  char   *qe_description;

} ecs_LayerCapabilities;

const ecs_LayerCapabilities *cln_GetLayerCapabilities( int ClientID, 
                                                       int layer_id );
This function fetches a pointer to an internal structure defining all the information about the indicated layer. The structure is maintained within the client connection and should not be altered or freed by the caller.

The layer_id is a value between 0 and n-1 where n is the number of layers (FeatureTypes) defined in the capabilities document. NULL is returned if layer_id is out of the legal range. Callers are expected to call the function repeatedly, starting with a layer_id of zero till a NULL is returned to discover the number of layers available.

Compatibility Issues

  1. It is required that all OGDI 3.1 drivers/servers will return a valid OGDI_Capabilities document listing all available layers. This implies that no currently existing drivers will qualify as 3.1 drivers till they have been upgraded. This should be a relatively simple process.

  2. Clients wishing to take advantage of this capabilities will have to either implement their own support for parsing the capabilities document, or incorporate an OGDI 3.1 client source update with the client side parsing support. These clients will still need an adhoc mechanism to establish the layers of pre-3.1 drivers. Note that clients are not required to consult the capabilities document, if they require the user to supply the layer name(s) they are requesting.

  3. The client API and data model for layer discovery is significantly different than the current Global Geomatics cln_GetDictionary(), cln_GetToken() and cln_GetRequest() API. There is no concept of layer names being split into tokens for instance, with the exception of the replacability of the query expression. While it should be possible for Global Geomatics to generate reasonable results from their current API based on a capabilities document, it won't necessarily be a good fit.

  4. A few drivers (such as the grid driver, and the Global Geomatics Arc/Info driver with arbitrary joins from Info) will not be able to be represented smoothly using the proposed capabilities format, because the amount of variability possible in the layer names. However, even in these cases some level of support should be achievable.