Web Feature Service Implementation Specification

OpenGIS Consortium Inc.

1.0.0

WARNING: The Open GIS Consortium (OGC) releases this specification to the public without warranty. It is subject to change without notice. This specification is currently under active revision by the OGC Technical Committee.

Requests for clarification and/or revision can be made by contacting the OGC at .

Permission to use, copy, and distribute this document in any medium for any purpose and without fee or royalty is hereby granted, provided that you include the above list of copyright holders and the entire text of this NOTICE.

We request that authorship attribution be provided in any software, documents, or other items or products that you create pursuant to the implementation of the contents of this document, or any portion thereof.

No right to create modifications or derivatives of OGC documents is granted pursuant to this license. However, if additional requirements (as documented in the Copyright FAQ at http://www.opengis.org/legal/ipr_faq.htm) are satisfied, the right to create modifications or derivatives is sometimes granted by the OGC to individuals complying with those requirements.

THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.

The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to this document or its contents without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders.

RESTRICTED RIGHTS LEGEND. Use, duplication, or disclosure by government is subject to restrictions as set forth in subdivision (c)(1)(ii) of the Right in Technical Data and Computer Software Clause at DFARS 252.227.7013

OpenGIS® is a trademark or registered trademark of Open GIS Consortium, Inc. in the United States and in other countries.

This document does not represent a commitment to implement any portion of this specification in any company's products.

OGC® Legal, IPR and Copyright Statements are found at http://www.opengis.org/legal/ipr.htm

The companies listed below have granted the Open GIS Consortium, Inc. (OGC) a nonexclusive, royalty-free, paid up, worldwide license to copy and distribute this document and to modify this document and distribute copies of the modified version.

Revision History
Revision 1.0.02002-09-19
Address RFC comments.
Revision 0.0.7?
Reformat document for RFC Re-Submission; Add use of XPath expressions for refering to complex attributes.
Revision 0.0.6?
Prepare for RFC Submission
Revision 0.0.5?
Define a capabilities section.
Revision 0.0.4?
Add support for arithmetic expressions.
Revision 0.0.3?
Add support for functions.
Revision 0.0.2?
Correct typographic errors.
Revision 0.0.1?
First version derived from the Open GIS Web Feature Server Specification [14]

The following companies submitted this specification to the OGC as a Request for Comment:

CubeWerx Inc. Edric Keighan 200 Rue Montcalm, Suite R-13 Hull, Quebec Canada J8Y 3B5 Intergraph Corp. Jonathan Clark 1881 Campus Commons Drive Reston, VA 20191 U.S.A IONIC Software Serge Margoulies 128 Avenue de l'Observatoire B-4000 LIEGE Belgium Laser-Scan Ltd. Peter Woodsford 101 Cambridgbe Science Park Milton Road Cambridge CB4 0FY U.K.

All questions regarding this submission should be directed to the Editor or to the WWW Mapping SIG chair:

Panagiotis A. Vretanos CubeWerx, Inc. 200 Rue Montcalm, Suite R-13 Hull, Quebec J8Y 3B5 CANADA +1 416 701 1985

Allan Doyle (WWW Mapping SIG Chair) International Interfaces, Inc. 948 Great Plain Ave. PMB-182 Needham, MA 02492 USA +1 781 433 2695

Additional contributors

Rob Atkinson (Social Change Online) Craig Bruce (CubeWerx) Jonathan Clark (Intergraph) Adrian Cuthbert (SpotOn MOBILE) Paul Daisey (U.S. Census) Ignacio Guerrero (Intergraph) Sandra Johnson (Mapinfo) Edric Keighan (CubeWerx) Ron Lake (Galdos Systems Inc.) Jeff Lansing (Polexis) Seb Lessware (Laser-Scan Ltd.) Marwa Mabrouk (ESRI) Serge Margoulies (Ionic) Brian May (CubeWerx) Richard Martell (Galdos Systems Inc.) Aleksander Milanovic (Glados Systems Inc.) Dimitri Monie (Ionic) Paul Pilkington (Laser-Scan Ltd.) Keith Pomakis (CubeWerx) Lou Reich (NASA) Carl Reed (Open GIS Consortium) Martin Schaefer (Cadcorp Ltd.) Bernard Snyers (Ionic) Daniel Specht (TEC) James T. Stephens (Lockheed Martin) Glenn Stowe (CubeWerx) Milan Trninic (Galdos Systems Inc.) Peter Woodsford (Laser-Scan Ltd.) Arliss Whitesize (BAE Systems)

A filter expression is a construct used to constraints the property values of an object type for the purpose of identifying a subset of object instances to be operated upon in some manner.

The intent of this document is to describe an XML encoding of the OGC Common Catalog Query Language (CQL) [2] as a system neutral representation of a query predicate. Using the numerous XML tools available today, such an XML representation can be easily validated, parsed and then transformed into whatever target language is required to retrieve or modify object instances stored in some a persistent object store. For example, an XML encoded filter could be transformed into a WHERE clause for a SQL SELECT statement to fetch data stored in a SQL-based relational database. Similarly, and XML encoded filter expression could be transformed into an XPath or XPointer expression for fetching data from XML documents.

A large class of OpenGIS® web based service require the ability to express filter expressions in XML.

Relation to other OGC web services. The filter encoding described in this document is a common component that can be used by a number of OGC web services. Any service that requires the ability to query objects from a web-accessible repository can make use of the XML filter encoding described in this document. For example, a web feature service may use the XML filter encoding in a GetFeature operation to define query constraints. Other services based of the web feature service, such as Gazetteer or the Web Registry Service, could also make use of this filter encoding.

  1. Bradner, Scott, "RFC 2119 Key words for use in RFCs to Indicate Requirement Levels," March 1997, ftp://ftp.isi.edu/in-notes/rfc2119.txt.

  2. Percivall, George, ed., "The OpenGIS® Abstract Specification, Topic 12: Service Architecture", 2002

  3. Kottman, C., ed., "The OpenGIS® Abstract Specification, Topic 13: Catalog Services", Version 4, 1999

  4. Enloe, Yonsook, Nebert, Doug, Stphens, Larry (eds.), "OpenGIS® Implementation Specification #99-051s: Catalog Interface Implementation Specification, Version 1.0", 1999

  5. OpenGIS® Implementation Specification #99-049, "OpenGIS® Simple Features Specification For SQL, Revision 1.1", May 1999

  6. Vretanos, Panagiotis (ed.), "OpenGIS® Implementation Specification #01-067: Filter Encoding Implementation Specification", May 2001

  7. Bray, Paoli, Sperberg-McQueen, eds., "Extensible Markup Language (XML) 1.0", 2nd edition, October 2000, W3C Recommendation, http://www.w3.org/TR/2000/REC-xml.

  8. Beech, David, Maloney, Murry, Mendelson, Noah, Thompson, Harry S., "XML Schema Part 1: Structures", May 2001, W3C Recommendation, http://www.w3c.org/TR/xmlschema-1.

  9. Bray, Hollander, Layman, eds., "Namespaces In XML", January 1999, W3C Recommendation, http://www.w3.org/TR/2000/REC-xml-names.

  10. Clark, James, DeRose, Steve, "XML Path Language (XPATH), Version 1.0", November 1999, W3C Recommendation, http://www.w3c.org/TR/XPath.

  11. Berners-Lee, T., Fielding, N., and Masinter, L., "Uniform Resource Identifiers (URI): Generic Syntax", IETF RFC 2396, http://www.ietf.org/rfc/rfc2396.txt.

  12. Cox, S., Cuthbert, A., Lake, R., and Martell, R. (eds.), "OpenGIS Implementation Specification #02-009: OpenGIS® Geography Markup Language (GML) Implementation Specification, version 2.1.1", April 2002

  13. Fielding et. al., "Hypertext Transfer Protocol - HTTP/1.1," IETF RFC 2616, June 1999, http://www.ietf.org/rfc/rfc2616.txt.

Properties of an object may be mapped, in XML, to elements or attributes of elements. Thus it is required that a filter expression be able to address properties encoded as XML elements or attributes.

The XML Path Language [10] specification is a language for addressing parts of a XML document or in the case of this specification for referencing feature properties encoded as XML elements or attributes.

This specification does not require that a filter expression processor support the full XPath language. In order to keep the implementation entry cost as low as possible, this specification mandates that a filter expression processor must support the following subset of the XPath language:

Example

To practically illustrate the use of XPath expressions for referencing simple and complex properties of an object (encoded as elements or attributes), consider the fictitious GML feature Person defined by the following XML Schema document:

<?xml version="1.0" ?>
<schema
   targetNamespace="http://www.cubewerx.com/myns"
   xmlns:myns="http://www.cubewerx.com/myns"
   xmlns:gml="http://www.opengis.net/gml"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns="http://www.w3.org/2001/XMLSchema"
   elementFormDefault="qualified"
   version="1.0">

   <import namespace="http://www.opengis.net/gml"
           schemaLocation="../gml/2.1/feature.xsd"/>

   <element name="Person" type="myns:PersonType"
            substitutionGroup="gml:_Feature"/>
   <complexType name="PersonType">
      <complexContent>
         <extension base="gml:AbstractFeatureType">
            <sequence>
               <element name="LastName" nillable="true">
                  <simpleType>
                     <restriction base="string">
                        <maxLength value="30"/>
                     </restriction>
                  </simpleType>
               </element>
               <element name="FirstName" nillable="true">
                  <simpleType>
                     <restriction base="string">
                        <maxLength value="10"/>
                     </restriction>
                  </simpleType>
               </element>
               <element name="Age" type="integer" nillable="true"/>
               <element name="Sex" type="string"/>
               <element name="Spouse">
                  <complexType>
                     <attribute name="sin" type="xsd:anyURI" use="required" />
                  </complexType>
               </element>
               <element name="Location" 
                        type="gml:PointPropertyType"
                        nillable="true"/>
               <element name="Address" type="myns:AddressType" nillable="true"/>
            </sequence>
            <attribute name="sin" type="xsd:anyURI" use="required"/>
         </extension>
      </complexContent>
   </complexType>

   <complexType name="AddressType">
      <sequence>
         <element name="StreetName" nillable="true">
            <simpleType>
               <restriction base="string">
                  <maxLength value="30"/>
               </restriction>
            </simpleType>
         </element>
         <element name="StreetNumber" nillable="true">
            <simpleType>
               <restriction base="string">
                  <maxLength value="10"/>
               </restriction>
            </simpleType>
         </element>
         <element name="City" nillable="true">
            <simpleType>
               <restriction base="string">
                  <maxLength value="30"/>
               </restriction>
            </simpleType>
         </element>
         <element name="Province" nillable="true">
            <simpleType>
               <restriction base="string">
                  <maxLength value="30"/>
               </restriction>
            </simpleType>
         </element>
         <element name="PostalCode" nillable="true">
            <simpleType>
               <restriction base="string">
                  <maxLength value="15"/>
               </restriction>
            </simpleType>
         </element>
         <element name="Country" nillable="true">
            <simpleType>
               <restriction base="string">
                  <maxLength value="30"/>
               </restriction>
            </simpleType>
         </element>
      </sequence>
   </complexType>
</schema>

Note that the property Address is a complex property of type AddressType. An example instance of the feature Person might be:

<?xml version="1.0" ?>
<myns:Person
   sin="111222333" 
   xmlns:myns="http://www.opengis.net/myns"
   xmlns:gml="http://www.opengis.net/gml"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.opengis.net/myns Person.xsd">

   <myns:LastName>Smith</myns:LastName>
   <myns:FirstName>Fred</myns:FirstName>
   <myns:Age>35</myns:Age>
   <myns:Sex>Male</myns:Sex>
   <myns:Spouse sin="444555666" />
   <myns:Location>
      <gml:Point><gml:coordinates>15,15</gml:coordinates></gml:Point>
   </myns:Location>
   <myns:Address>
      <myns:StreetName>Main St.</myns:StreetName>
      <myns:StreetNumber>5</myns:StreetNumber>
      <myns:City>SomeCity</myns:City>
      <myns:Province>SomeProvince</myns:Province>
      <myns:PostalCode>X1X 1X1</myns:PostalCode>
      <myns:Country>Canada</myns:Country>
   </myns:Address>
</myns:Person>

Using XPath [10] expressions, each property of a Person feature can be referenced. Table 1 shows the XPath expressions that may be used to reference all the properties of the Person feature as well as the corresponding value of each property.

Notice that each relative location paths may begin with the root element name of the property being referenced or with the root element name of the object, Person. Each step of the path is composed of the abbreviated child:: axis specifier (i.e. the axis specifier child:: is omitted) and the name of the specified property which is of node type element.

In addition, the sin [1] attribute on the <Person> and <Spouse> elements is referenced using the following XPath [10] expressions:

Person/@sin
Person/Spouse/@sin

In these cases the final step of the path contains the abbreviated axis specifier attribute:: (i.e. @) and the node type is attribute (i.e. sin in this case).

The XML encoding for spatial operators is defined by the following XML Schema fragment:

<xsd:element name="Equals" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Disjoint" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Touches" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Within" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Overlaps" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Crosses" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Intersects" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Contains" 
             type="ogc:BinarySpatialOpType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="DWithin" 
             type="ogc:DistanceBufferType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="Beyond" 
             type="ogc:DistanceBufferType" substitutionGroup="ogc:spatialOps"/>
<xsd:element name="BBOX" 
             type="ogc:BBOXType" substitutionGroup="ogc:spatialOps"/>

<xsd:complexType name="SpatialOpsType" abstract="true"/>
<xsd:element name="spatialOps" type="ogc:SpatialOpsType" abstract="true"/>

<xsd:complexType name="BinarySpatialOpType">
   <xsd:complexContent>
      <xsd:extension base="ogc:SpatialOpsType">
         <xsd:sequence>
            <xsd:element ref="ogc:PropertyName"/>
            <xsd:choice>
               <xsd:element ref="gml:_Geometry"/>
               <xsd:element ref="gml:Box"/>
         </xsd:sequence>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="BBOXType">
   <xsd:complexContent>
      <xsd:extension base="ogc:SpatialOpsType">
         <xsd:sequence>
            <xsd:element ref="ogc:PropertyName"/>
            <xsd:element ref="gml:Box"/>
         </xsd:sequence>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="DistanceBufferType">
   <xsd:complexContent>
      <xsd:extension base="ogc:SpatialOpsType">
         <xsd:sequence>
            <xsd:element ref="ogc:PropertyName"/>
            <xsd:element ref="gml:_Geometry"/>
            <xsd:element name="Distance" type="ogc:DistanceType"/>
         </xsd:sequence>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="DistanceType" mixed="true">
   <xsd:attribute name="units" type="xsd:anyURI" use="required"/>
</xsd:complexType>

As defined in this specification, spatial operators are used to test whether the value of a geometric property, referenced using the name of the property, and a literal geometric value satisfy the spatial relationship implied by the operator. For example, the <Overlap> operator evaluates whether the value of the specified geometric property and the specified literal geometric value spatially overlap. Literal geometric values are expressed using GML [12].

The <BBOX> element is defined as a convenient and more compact way of encoding the very common bounding box constraint based on the gml:Box geometry. It is equivalent to the spatial operation <Not><Disjoint> ... </Disjoint></Not> meaning that the <BBOX> operator should identify all geometries that spatially interact with the box in some manner.

The Bounding Box (BBOX) is a set of four comma-separated decimal, scientific notation, or integer values (if integers are provided where floating point is needed, the decimal point is assumed at the end of the number). These values specify the minimum X, minimum Y, maximum X, and maximum Y ranges, in that order, expressed in units of the SRS of the feature type(s) begin queried. The four bounding box values indicate the outside edges of a rectangle, as in Figure 5; minimum X is the left edge, maximum X the right, minimum Y the bottom, and maximum Y the top.

The semantics of the other operators Equals, Disjoint, Touches, Within, Overlaps, Crosses, Intersects, and Contains are defined in section 3.2.19.2 of the OpenGIS® Simple Feature Specification for SQL [5].

The spatial operators DWithin and Beyond test whether the value of a geometric property is within or beyond a specified distance of the specified literal geometric value. Distance values are expressed using the <Distance> element. The content of the <Distance> element represents the magnitude of the distance and the units attribute is used to specify the units of measure. The units attribute is of type anyURI so that it may be used to reference a units dictionary. For example, the following XML fragment:

<Distance unit="http://www.uomdict.com/uom.html#meters">10</Distance>

encodes a distance value of 10 meters. The semantics of these operators are defined in section 4 of the OpenGIS Catalog Interface Implementation Specification [4].

The XML encoding for comparison operators is defined by the following XML Schema fragment:

<xsd:element name="PropertyIsEqualTo"
             type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsNotEqualTo"
             type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsLessThan"
             type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsGreaterThan"
             type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsLessThanOrEqualTo"
             type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsGreaterThanOrEqualTo"
             type="ogc:BinaryComparisonOpType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsLike" 
             type="ogc:PropertyIsLikeType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsNull" 
             type="ogc:PropertyIsNullType" substitutionGroup="ogc:comparisonOps"/>
<xsd:element name="PropertyIsBetween" 
             type="ogc:PropertyIsBetweenType" substitutionGroup="ogc:comparisonOps"/>

<xsd:complexType name="ComparisonOpsType" abstract="true"/>
<xsd:element name="comparisonOps" type="ogc:ComparisonOpsType" abstract="true"/>

<xsd:complexType name="BinaryComparisonOpType">
   <xsd:complexContent>
      <xsd:extension base="ogc:ComparisonOpsType">
         <xsd:sequence>
            <xsd:element ref="ogc:expression" minOccurs="2" maxOccurs="2"/>
         </xsd:sequence>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="PropertyIsLikeType">
   <xsd:complexContent>
      <xsd:extension base="ogc:ComparisonOpsType">
         <xsd:sequence>
            <xsd:element ref="ogc:PropertyName"/>
            <xsd:element ref="ogc:Literal"/>
         </xsd:sequence>
         <xsd:attribute name="wildCard" type="xsd:string" use="required"/>
         <xsd:attribute name="singleChar" type="xsd:string" use="required"/>
         <xsd:attribute name="escape" type="xsd:string" use="required"/>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="PropertyIsNullType">
   <xsd:complexContent>
      <xsd:extension base="ogc:ComparisonOpsType">
         <xsd:choice>
            <xsd:element ref="ogc:PropertyName"/>
            <xsd:element ref="ogc:Literal"/>
         </xsd:choice>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="PropertyIsBetweenType">
   <xsd:complexContent>
      <xsd:extension base="ogc:ComparisonOpsType">
         <xsd:sequence>
            <xsd:element ref="ogc:expression"/>
            <xsd:element name="LowerBoundary" type="ogc:LowerBoundaryType"/>
            <xsd:element name="UpperBoundary" type="ogc:UpperBoundaryType"/>
         </xsd:sequence>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="LowerBoundaryType">
   <xsd:choice>
      <xsd:element ref="ogc:expression"/>
   </xsd:choice>
</xsd:complexType>

<xsd:complexType name="UpperBoundaryType">
   <xsd:sequence>
      <xsd:element ref="ogc:expression"/>
   </xsd:sequence>
</xsd:complexType>

The Common Catalog Query Language [4] defines a standard set of comparison operators. In addition to the standard set (=,<,>,>=,<=,<>) of comparison operators, this specification defines the elements <PropertyIsLike>, <PropertyIsBetween> and <PropertyIsNull>.

The <PropertyIsLike> element is intended to encode a character string comparison operator with pattern matching. The pattern is defined by a combination of regular characters, the wildCard character, the singleChar character, and the escapeChar character. The wildCard character matches zero or more characters. The singleChar character matches exactly one character. The escapeChar character is used to escape the meaning of the wildCard, singleChar and escapeChar itself.

The <PropertyIsNull> element encodes an operator that checks to see if the value of its content is NULL. A NULL is equivalent to no value present. The value 0 is a valid value and is not considered NULL.

The <PropertyIsBetween> element is defined as a compact way of encoding a range check. The lower and upper boundary values are inclusive.

The XML encoding for arithmetic expressions is defined by the following XML Schema fragment:

<xsd:element name="Add"
             type="ogc:BinaryOperatorType"
             substitutionGroup="ogc:expression"/>
<xsd:element name="Sub"
             type="ogc:BinaryOperatorType"
             substitutionGroup="ogc:expression"/>
<xsd:element name="Mul"
             type="ogc:BinaryOperatorType"
             substitutionGroup="ogc:expression"/>
<xsd:element name="Div"
             type="ogc:BinaryOperatorType"
             substitutionGroup="ogc:expression"/>
<xsd:complexType name="BinaryOperatorType">
   <xsd:complexContent>
      <xsd:extension base="ogc:ExpressionType">
         <xsd:sequence>
            <xsd:element ref="ogc:expression" minOccurs="2" maxOccurs="2"/>
         </xsd:sequence>
      </xsd:extension>
   </xsd:complexContent>
</xsd:complexType>

The <Add> element encodes the operation of addition and contains the arguments which can be any expression that validates according to this specification.

The <Sub> element encodes the operation of subtraction where the second argument is subtracted from the first. The <Sub> element contains the argument when can be any expression that validates according to this specification.

The <Mul> element encodes the operation multiplication. The <Mul> element contains the two argument to be multiplied which can be any expression that validates according to this specification.

The <Div> element encodes the operation of division where the first argument is divided by the second argument. The <Div> element contains the arguments which can be any valid expression that validates according to this specification. The second argument or expression cannot evaluate to zero.

This section of the document defines a capabilities schema that can be included in the capabilities document of services that use filter encoding. The documents describes what specific filter capabilities are supported by a service. For example, a web feature service that uses filter encoding would include this fragment in its capabilities document to advertise what filter capabilities it supports.

Filter capabilities are divided into two categories: spatial capabilities and scalar capabilities. The following XML Schema fragment defines the root element of the filter capabilities:

<xsd:element name="Filter_Capabilities">
   <xsd:complexType>
      <xsd:sequence>
         <xsd:element name="Spatial_Capabilities"
                      type="ogc:Spatial_CapabilitiesType"/>
         <xsd:element name="Scalar_Capabilities"
                      type="ogc:Scalar_CapabilitiesType"/>
      </xsd:sequence>
   </xsd:complexType>
</xsd:element>

A service that supports spatial filtering would include a spatial capabilities section. Spatial capabilities include the ability to filter spatial data based on the definition of a bounding box (BBOX) as well as the ability to process the spatial operators defined by CQL [4] and the Simple Features for SQL [5] specification: Equals, Disjoint, Touches, Within, Overlaps, Crosses, Intersects, Contains, DWithin and Beyond. Spatial capabilities are encoded according to the following XML Schema fragment:

<xsd:complexType name="Spatial_CapabilitiesType">
   <xsd:sequence>
      <xsd:element name="Spatial_Operators"
                  type="ogc:Spatial_OperatorsType"/>
   </xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Spatial_OperatorsType">
   <xsd:choice maxOccurs="unbounded">
      <xsd:element ref="ogc:Equals"/>
      <xsd:element ref="ogc:Disjoint"/>
      <xsd:element ref="ogc:Touches"/>
      <xsd:element ref="ogc:Within"/>
      <xsd:element ref="ogc:Overlaps"/>
      <xsd:element ref="ogc:Crosses"/>
      <xsd:element ref="ogc:Intersect"/>
      <xsd:element ref="ogc:Contains"/>
      <xsd:element ref="ogc:DWithin"/>
      <xsd:element ref="ogc:Beyond"/>
      <xsd:element ref="ogc:BBOX"/>
   </xsd:choice>
</xsd:complexType>

Scalar capabilities include the ability to process logical expressions, comparisons and arithmetic operations including the ability to process a list of named functions. The following XML Schema defines how scalar capabilities are encoded:

<xsd:complexType name="Scalar_CapabilitiesType">
   <xsd:choice maxOccurs="unbounded">
      <xsd:element ref="ogc:Logical_Operators"/>
      <xsd:element name="Comparison_Operators"
                   type="ogc:Comparison_OperatorsType"/>
      <xsd:element name="Arithmetic_Operators"
                   type="ogc:Arithmetic_OperatorsType"/>
   </xsd:choice>
</xsd:complexType>

The <Logical_Operators> element is used to indicate that the filter can process And, Or and Not operators.

The <Comparison_Operators> element is used to indicate what types of comparison operators are supported by a service. The <Simple_Comparisons> element is used to indicate that the operators =, <, <=, >, >= are supported. The elements <Like>, <Between> and <NullCheck> are used to indicate that the service can support the operators LIKE, BETWEEN and NULL.

The <Arithmetic_Operators> element is used to indicate what arithmetic operators the a service can support. The contained element <Simple_Arithmetic> is used to indicate that the service can support addition, subtraction, multiplication and division. The contained element <Functions> is used to list the function names that are supported and the number of arguments each function requires. Function arguments are encoded as nested elements within the <Function> tag as defined in Section 15, Encoding Functions.

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
   targetNamespace="http://www.opengis.net/ogc"
   xmlns:ogc="http://www.opengis.net/ogc"
   xmlns:gml="http://www.opengis.net/gml"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   elementFormDefault="qualified">

  <xsd:element name="Add"
               type="ogc:BinaryOperatorType"
               substitutionGroup="ogc:expression"/>
  <xsd:element name="Sub"
               type="ogc:BinaryOperatorType"
               substitutionGroup="ogc:expression"/>
  <xsd:element name="Mul"
               type="ogc:BinaryOperatorType"
               substitutionGroup="ogc:expression"/>
  <xsd:element name="Div"
               type="ogc:BinaryOperatorType"
               substitutionGroup="ogc:expression"/>
  <xsd:element name="PropertyName"
               type="ogc:PropertyNameType"
               substitutionGroup="ogc:expression"/>
  <xsd:element name="Function"
               type="ogc:FunctionType"
               substitutionGroup="ogc:expression"/>
  <xsd:element name="Literal"
               type="ogc:LiteralType"
               substitutionGroup="ogc:expression"/>

  <xsd:element name="expression" type="ogc:ExpressionType" abstract="true"/>

  <xsd:complexType name="ExpressionType" abstract="true"/>
  <xsd:complexType name="BinaryOperatorType">
    <xsd:complexContent>
      <xsd:extension base="ogc:ExpressionType">
        <xsd:sequence>
          <xsd:element ref="ogc:expression" minOccurs="2" maxOccurs="2"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:complexType name="FunctionType">
    <xsd:complexContent>
      <xsd:extension base="ogc:ExpressionType">
        <xsd:sequence>
          <xsd:element ref="ogc:expression"
                       minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:complexType name="LiteralType">
    <xsd:complexContent mixed="true">
      <xsd:extension base="ogc:ExpressionType">
        <xsd:sequence>
          <xsd:any minOccurs="0"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <xsd:complexType name="PropertyNameType">
    <xsd:complexContent mixed="true">
      <xsd:extension base="ogc:ExpressionType"/>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
   targetNamespace="http://www.opengis.net/ogc"
   xmlns:ogc="http://www.opengis.net/ogc"
   xmlns:gml="http://www.opengis.net/gml"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   elementFormDefault="qualified">

   <xsd:include schemaLocation="expr.xsd" />
   <xsd:import namespace="http://www.opengis.net/gml" 
               schemaLocation="../../gml/2.1/geometry.xsd"/>
 
   <!-- ============================================= -->
   <!-- FILTER EXPRESSION                             -->
   <!-- ============================================= -->
   <xsd:element name="FeatureId" type="ogc:FeatureIdType"/>
   <xsd:element name="Filter" type="ogc:FilterType"/>
 
   <!-- ============================================= -->
   <!-- COMPARISON OPERATORS                          -->
   <!-- ============================================= -->
   <xsd:element name="comparisonOps"
                type="ogc:ComparisonOpsType" abstract="true"/>
   <xsd:element name="PropertyIsEqualTo"
                type="ogc:BinaryComparisonOpType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsNotEqualTo"
                type="ogc:BinaryComparisonOpType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsLessThan"
                type="ogc:BinaryComparisonOpType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsGreaterThan"
                type="ogc:BinaryComparisonOpType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsLessThanOrEqualTo"
                type="ogc:BinaryComparisonOpType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsGreaterThanOrEqualTo"
                type="ogc:BinaryComparisonOpType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsLike"
                type="ogc:PropertyIsLikeType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsNull"
                type="ogc:PropertyIsNullType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:element name="PropertyIsBetween"
                type="ogc:PropertyIsBetweenType"
                substitutionGroup="ogc:comparisonOps"/>
   <xsd:complexType name="ComparisonOpsType" abstract="true"/>
 
   <!-- ============================================= -->
   <!-- SPATIAL OPERATORS (sec 3.2.19.2 99-049)       -->
   <!-- ============================================= -->
   <xsd:element name="spatialOps"
                type="ogc:SpatialOpsType" abstract="true"/>
   <xsd:element name="Equals"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Disjoint"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Touches"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Within"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Overlaps"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Crosses"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Intersects"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Contains"
                type="ogc:BinarySpatialOpType"
                substitutionGroup="ogc:spatialOps"/>
   <!-- These operatons are from sec 4.2 of OpenGIS Catalog Interface -->
   <xsd:element name="DWithin"
                type="ogc:DistanceBufferType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:element name="Beyond"
                type="ogc:DistanceBufferType"
                substitutionGroup="ogc:spatialOps"/>
   <!-- This is a convenience operator to allow simple BBOX queries -->
   <xsd:element name="BBOX"
                type="ogc:BBOXType"
                substitutionGroup="ogc:spatialOps"/>
   <xsd:complexType name="SpatialOpsType" abstract="true"/>
 
   <!-- ============================================= -->
   <!-- LOGICAL OPERATORS                             -->
   <!-- ============================================= -->
   <xsd:element name="logicOps"
                type="ogc:LogicOpsType" abstract="true"/>
   <xsd:element name="And"
                type="ogc:BinaryLogicOpType"
                substitutionGroup="ogc:logicOps"/>
   <xsd:element name="Or"
                type="ogc:BinaryLogicOpType"
                substitutionGroup="ogc:logicOps"/>
   <xsd:element name="Not"
                type="ogc:UnaryLogicOpType"
                substitutionGroup="ogc:logicOps"/>
   <xsd:complexType name="LogicOpsType" abstract="true"/>
 
   <!-- ============================================= -->
   <!-- COMPLEX TYPES                                 -->
   <!-- ============================================= -->
   <xsd:complexType name="FilterType">
      <xsd:choice>
         <xsd:element ref="ogc:spatialOps"/>
         <xsd:element ref="ogc:comparisonOps"/>
         <xsd:element ref="ogc:logicOps"/>
         <xsd:element ref="ogc:FeatureId" maxOccurs="unbounded"/>
      </xsd:choice>
   </xsd:complexType>
   <xsd:complexType name="FeatureIdType">
      <xsd:attribute name="fid" type="xsd:anyURI" use="required"/>
   </xsd:complexType>
   <xsd:complexType name="BinaryComparisonOpType">
      <xsd:complexContent>
         <xsd:extension base="ogc:ComparisonOpsType">
            <xsd:sequence>
               <xsd:element ref="ogc:expression" minOccurs="2" maxOccurs="2"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="PropertyIsLikeType">
      <xsd:complexContent>
         <xsd:extension base="ogc:ComparisonOpsType">
            <xsd:sequence>
               <xsd:element ref="ogc:PropertyName"/>
               <xsd:element ref="ogc:Literal"/>
            </xsd:sequence>
            <xsd:attribute name="wildCard" type="xsd:string" use="required"/>
            <xsd:attribute name="singleChar" type="xsd:string" use="required"/>
            <xsd:attribute name="escape" type="xsd:string" use="required"/>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="PropertyIsNullType">
      <xsd:complexContent>
         <xsd:extension base="ogc:ComparisonOpsType">
            <xsd:choice>
               <xsd:element ref="ogc:PropertyName"/>
               <xsd:element ref="ogc:Literal"/>
            </xsd:choice>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="PropertyIsBetweenType">
      <xsd:complexContent>
         <xsd:extension base="ogc:ComparisonOpsType">
            <xsd:sequence>
               <xsd:element ref="ogc:expression"/>
               <xsd:element name="LowerBoundary" type="ogc:LowerBoundaryType"/>
               <xsd:element name="UpperBoundary" type="ogc:UpperBoundaryType"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="LowerBoundaryType">
      <xsd:choice>
         <xsd:element ref="ogc:expression"/>
      </xsd:choice>
   </xsd:complexType>
   <xsd:complexType name="UpperBoundaryType">
      <xsd:sequence>
         <xsd:element ref="ogc:expression"/>
      </xsd:sequence>
   </xsd:complexType>
   <xsd:complexType name="BinarySpatialOpType">
      <xsd:complexContent>
         <xsd:extension base="ogc:SpatialOpsType">
            <xsd:sequence>
               <xsd:element ref="ogc:PropertyName"/>
               <xsd:choice>
                  <xsd:element ref="gml:_Geometry"/>
                  <xsd:element ref="gml:Box"/>
               </xsd:choice>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="BBOXType">
      <xsd:complexContent>
         <xsd:extension base="ogc:SpatialOpsType">
            <xsd:sequence>
               <xsd:element ref="ogc:PropertyName"/>
               <xsd:element ref="gml:Box"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="DistanceBufferType">
      <xsd:complexContent>
         <xsd:extension base="ogc:SpatialOpsType">
            <xsd:sequence>
               <xsd:element ref="ogc:PropertyName"/>
               <xsd:element ref="gml:_Geometry"/>
               <xsd:element name="Distance" type="ogc:DistanceType"/>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="DistanceType" mixed="true">
      <xsd:attribute name="units" type="xsd:string" use="required"/>
   </xsd:complexType>
   <xsd:complexType name="BinaryLogicOpType">
      <xsd:complexContent>
         <xsd:extension base="ogc:LogicOpsType">
            <xsd:choice minOccurs="2" maxOccurs="unbounded">
               <xsd:element ref="ogc:comparisonOps"/>
               <xsd:element ref="ogc:spatialOps"/>
               <xsd:element ref="ogc:logicOps"/>
            </xsd:choice>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
   <xsd:complexType name="UnaryLogicOpType">
      <xsd:complexContent>
         <xsd:extension base="ogc:LogicOpsType">
            <xsd:sequence>
               <xsd:choice>
                  <xsd:element ref="ogc:comparisonOps"/>
                  <xsd:element ref="ogc:spatialOps"/>
                  <xsd:element ref="ogc:logicOps"/>
               </xsd:choice>
            </xsd:sequence>
         </xsd:extension>
      </xsd:complexContent>
   </xsd:complexType>
</xsd:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
   targetNamespace="http://www.opengis.net/ogc"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:ogc="http://www.opengis.net/ogc"
   elementFormDefault="qualified">

   <xsd:complexType name="Arithmetic_OperatorsType">
      <xsd:choice maxOccurs="unbounded">
         <xsd:element ref="ogc:Simple_Arithmetic"/>
         <xsd:element name="Functions" type="ogc:FunctionsType"/>
      </xsd:choice>
   </xsd:complexType>
   <xsd:element name="BBOX">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Between">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Beyond">
      <xsd:complexType/>
   </xsd:element>
   <xsd:complexType name="Comparison_OperatorsType">
      <xsd:choice maxOccurs="unbounded">
         <xsd:element ref="ogc:Simple_Comparisons"/>
         <xsd:element ref="ogc:Like"/>
         <xsd:element ref="ogc:Between"/>
         <xsd:element ref="ogc:NullCheck"/>
      </xsd:choice>
   </xsd:complexType>
   <xsd:element name="Contains">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Crosses">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Disjoint">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Equals">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Filter_Capabilities">
      <xsd:complexType>
         <xsd:sequence>
            <xsd:element name="Spatial_Capabilities"
                         type="ogc:Spatial_CapabilitiesType"/>
            <xsd:element name="Scalar_Capabilities"
                         type="ogc:Scalar_CapabilitiesType"/>
         </xsd:sequence>
      </xsd:complexType>
   </xsd:element>
   <xsd:complexType name="Function_NameType">
      <xsd:simpleContent>
         <xsd:extension base="xsd:string">
            <xsd:attribute name="nArgs" type="xsd:string" use="required"/>
         </xsd:extension>
      </xsd:simpleContent>
   </xsd:complexType>
   <xsd:complexType name="Function_NamesType">
      <xsd:sequence maxOccurs="unbounded">
         <xsd:element name="Function_Name" type="ogc:Function_NameType"/>
      </xsd:sequence>
   </xsd:complexType>
   <xsd:complexType name="FunctionsType">
      <xsd:sequence>
         <xsd:element name="Function_Names" type="ogc:Function_NamesType"/>
      </xsd:sequence>
   </xsd:complexType>
   <xsd:element name="Intersect">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Like">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Logical_Operators">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="NullCheck">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Overlaps">
      <xsd:complexType/>
   </xsd:element>
   <xsd:complexType name="Scalar_CapabilitiesType">
      <xsd:choice maxOccurs="unbounded">
         <xsd:element ref="ogc:Logical_Operators"/>
         <xsd:element name="Comparison_Operators"
                      type="ogc:Comparison_OperatorsType"/>
         <xsd:element name="Arithmetic_Operators"
                      type="ogc:Arithmetic_OperatorsType"/>
      </xsd:choice>
   </xsd:complexType>
   <xsd:element name="Simple_Arithmetic">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Simple_Comparisons">
      <xsd:complexType/>
   </xsd:element>
   <xsd:complexType name="Spatial_CapabilitiesType">
      <xsd:sequence>
         <xsd:element name="Spatial_Operators"
                      type="ogc:Spatial_OperatorsType"/>
      </xsd:sequence>
   </xsd:complexType>
   <xsd:complexType name="Spatial_OperatorsType">
      <xsd:choice maxOccurs="unbounded">
         <xsd:element ref="ogc:BBOX"/>
         <xsd:element ref="ogc:Equals"/>
         <xsd:element ref="ogc:Disjoint"/>
         <xsd:element ref="ogc:Intersect"/>
         <xsd:element ref="ogc:Touches"/>
         <xsd:element ref="ogc:Crosses"/>
         <xsd:element ref="ogc:Within"/>
         <xsd:element ref="ogc:Contains"/>
         <xsd:element ref="ogc:Overlaps"/>
         <xsd:element ref="ogc:Beyond"/>
      </xsd:choice>
   </xsd:complexType>
   <xsd:element name="Touches">
      <xsd:complexType/>
   </xsd:element>
   <xsd:element name="Within">
      <xsd:complexType/>
   </xsd:element>
</xsd:schema>