<apidoc:module name="GML" subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions" 
  xmlns:apidoc="http://marklogic.com/xdmp/apidoc"
  xmlns="http://www.w3.org/1999/xhtml" lib="gml"
>
<apidoc:summary access="public" subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
<p>The GML module provides support for geospatial queries using GML
markup. 
</p>
<p>To use the GML module as part of your own XQuery module, include the
following line in your XQuery prolog:
</p>
<p><code>import module namespace gml = "http://www.opengis.net/gml"
         at "/MarkLogic/geospatial/gml.xqy";</code></p>
<p>The library namespace prefix <code>gml</code> is <em>not</em> predefined
in the server.</p>
</apidoc:summary>

<apidoc:function name="point" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
  Create a cts:point value from a GML Point element.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="point" type="element(gml:Point)">
    A Point element.
    </apidoc:param>
  </apidoc:params>
  <apidoc:return> cts:point </apidoc:return>
  <apidoc:example><pre xml:space="preserve"><![CDATA[
  xquery version "1.0-ml";
  import module namespace gml = "http://www.opengis.net/gml"
         at "/MarkLogic/geospatial/gml.xqy";

  gml:point(<gml:Point><gml:pos>12.5 -127.24</gml:pos></gml:Point>)
  ]]></pre>
  </apidoc:example>
</apidoc:function>

<apidoc:function name="box" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
	  Create a <code>cts:box</code> value from a GML Envelope element.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="box" type="element(gml:Envelope)">
    An Envelope element.
    </apidoc:param>
  </apidoc:params>
  <apidoc:return>cts:box</apidoc:return>
  <apidoc:example><pre xml:space="preserve"><![CDATA[
  xquery version "1.0-ml";
  import module namespace gml = "http://www.opengis.net/gml"
         at "/MarkLogic/geospatial/gml.xqy";

  gml:box(
     <gml:Envelope>
       <gml:lowerCorner>12.5 -127.24</gml:lowerCorner>
       <gml:upperCorner>30 -122.24</gml:upperCorner>
     </gml:Envelope>)
  ]]></pre>
  </apidoc:example>
</apidoc:function>

<apidoc:function name="circle" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
	  Create a <code>cts:circle</code> value from a radius and GML Point 
	  element.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="radius" type="xs:double">
    The radius of the circle, in miles.
    </apidoc:param>
    <apidoc:param name="center" type="element(gml:Point)">
    A Point element representing the center of the circle.
    </apidoc:param>
  </apidoc:params>
  <apidoc:return>cts:circle</apidoc:return>
  <apidoc:example><pre xml:space="preserve"><![CDATA[
  xquery version "1.0-ml";
  import module namespace gml = "http://www.opengis.net/gml"
         at "/MarkLogic/geospatial/gml.xqy";

  gml:circle(47, <gml:Point><gml:pos>12.5 -127.24</gml:pos></gml:Point>)
  ]]></pre>
  </apidoc:example>
</apidoc:function>

<apidoc:function name="polygon" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
	  Create a <code>cts:polygon</code> value from a sequence of GML 
	  Point elements or a GML Polygon element.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="polygon-or-points" type="element()+">
    A sequence of Point elements representing the vertices of the polygon or a Polygon element..
    </apidoc:param>
  </apidoc:params>
  <apidoc:return>cts:polygon</apidoc:return>
  <apidoc:example><pre xml:space="preserve"><![CDATA[
  xquery version "1.0-ml";
  import module namespace gml = "http://www.opengis.net/gml"
         at "/MarkLogic/geospatial/gml.xqy";

  gml:polygon((
    <gml:Point><gml:pos>12.5 -127.24</gml:pos></gml:Point>,
    <gml:Point><gml:pos>15.25 -127.8</gml:pos></gml:Point>,
    <gml:Point><gml:pos>13.45 -126.1</gml:pos></gml:Point>,
    <gml:Point><gml:pos>12.5 -127.24</gml:pos></gml:Point>
  ))
  ]]></pre>
  </apidoc:example>
</apidoc:function>

<apidoc:function name="polygon" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
	  Create a <code>cts:polygon</code> value from a GML Polygon 
	  element.  The polygon returned represents the exterior polygon.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="polygon-or-points" type="element()+">
    A Polygon element representing the polygon.
    </apidoc:param>
  </apidoc:params>
  <apidoc:return>cts:polygon</apidoc:return>
  <apidoc:example><pre xml:space="preserve"><![CDATA[
  xquery version "1.0-ml";
  import module namespace gml = "http://www.opengis.net/gml"
         at "/MarkLogic/geospatial/gml.xqy";

  gml:polygon(
    <gml:Polygon><gml:exterior><gml:LinearRing>
    <gml:pos>12.5 -127.24</gml:pos>
    <gml:pos>15.25 -127.8</gml:pos>
    <gml:pos>13.45 -126.1</gml:pos>
    <gml:pos>12.5 -127.24</gml:pos>
    </gml:LinearRing></gml:exterior></gml:Polygon>
  )
  ]]></pre>
  </apidoc:example>
</apidoc:function>

<apidoc:function name="interior-polygon" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
	  Create a sequence of <code>cts:polygon</code> values from a 
	  GML Polygon element.  The polygons returned represent the 
	  interior polygons, if any.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="polygon" type="element(gml:Polygon)">
    A Polygon element representing the polygon.
    </apidoc:param>
  </apidoc:params>
  <apidoc:return>cts:polygon*</apidoc:return>
  <apidoc:example><pre xml:space="preserve"><![CDATA[
  xquery version "1.0-ml";
  import module namespace gml = "http://www.opengis.net/gml"
         at "/MarkLogic/geospatial/gml.xqy";

  (: Returns empty; no interior :)
  gml:interior-polygon(
    <gml:Polygon><gml:exterior><gml:LinearRing>
    <gml:pos>12.5 -127.24</gml:pos>
    <gml:pos>15.25 -127.8</gml:pos>
    <gml:pos>13.45 -126.1</gml:pos>
    <gml:pos>12.5 -127.24</gml:pos>
    </gml:LinearRing></gml:exterior></gml:Polygon>
  )
  ]]></pre>
  </apidoc:example>
</apidoc:function>

<apidoc:function name="geospatial-query" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
	  Returns a <code>cts:query</code> matching points within given regions.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="regions" type="cts:region*">
    One or more geographic boxes, circles, polygons, or points. 
    Where multiple boxes,
    circles, polygons, or points are specified, the query matches if any
    box, circle, polygon, or
    point matches.
    </apidoc:param>
    <apidoc:param name="options" type="xs:string*" optional="true">
    Options to this query.  The default is ().
    <p>Options include:</p>
      <blockquote>
        <dl>
        <dt>"coordinate-system=wgs84"</dt>
        <dd>Use the WGS84 coordinate system.</dd>
        <!--
        <dt>"unit=miles"</dt>
        <dd>Distance (for circles) is measured in miles.</dd>
        -->
        <dt>"boundaries-included"</dt>
        <dd>Points on boxes' and circles' boundaries are counted as matching.  This is the default.</dd>
        <dt>"boundaries-excluded"</dt>
        <dd>Points on boxes' and circles' boundaries are not counted as matching.</dd>
        <dt>"boundaries-latitude-excluded"</dt>
        <dd>Points on boxes' latitude boundaries are not counted as matching.</dd>
        <dt>"boundaries-longitude-excluded"</dt>
        <dd>Points on boxes' longitude boundaries are not counted as matching.</dd>
        <dt>"boundaries-south-excluded"</dt>
        <dd>Points on the boxes' southern boundaries are not counted as matching.</dd>
        <dt>"boundaries-west-excluded"</dt>
        <dd>Points on the boxes' western boundaries are not counted as matching.</dd>
        <dt>"boundaries-north-excluded"</dt>
        <dd>Points on the boxes' northern boundaries are not counted as matching.</dd>
        <dt>"boundaries-east-excluded"</dt>
        <dd>Points on the boxes' eastern boundaries are not counted as matching.</dd>
        <dt>"boundaries-circle-excluded"</dt>
        <dd>Points on circles' boundary are not counted as matching.</dd>
      </dl></blockquote>
    </apidoc:param>
    <apidoc:param name="weight" type="xs:double?" optional="true">
    A weight for this query.  The default is 1.0.
    </apidoc:param>
  </apidoc:params>
  <apidoc:return>cts:query</apidoc:return>
<apidoc:usage>
<p>The point value is expressed in the content of the element as a pair
of numbers, separated by whitespace and punctuation (excluding decimal points
and sign characters).
</p>
<p>Point values and boundary specifications of boxes are given in degrees
relative to the WGS84 coordinate system.  Southern latitudes and Western 
longitudes take negative values.  Longitudes will be wrapped to the range 
(-180,+180) and latitudes will be clipped to the range (-90,+90).  
</p>
<p>If the northern boundary of a box is south of the southern boundary, no 
points will  match. However, longitudes wrap around the globe, so that if 
the western boundary is east of the eastern boundary,
then the box crosses the anti-meridian.
</p>
<p>Special handling occurs at the poles, as all longitudes exist at latitudes 
+90 and -90.
</p>
</apidoc:usage>
<apidoc:example><pre xml:space="preserve"><![CDATA[
xquery version "1.0-ml";

(: create a document with test data :)
xdmp:document-insert("/points.xml",
<root xmlns:gml="http://www.opengis.net/gml">
  <item><gml:Point><gml:pos>10.5 30.0</gml:pos></gml:Point></item>
  <item><gml:Point><gml:pos>15.35 35.34</gml:pos></gml:Point></item>
  <item><gml:Point><gml:pos>5.11 40.55</gml:pos></gml:Point></item>
</root> );

xquery version "1.0-ml";
import module namespace gml = "http://www.opengis.net/gml"
   at "/MarkLogic/geospatial/gml.xqy";

cts:search(doc("/points.xml")//item, 
  gml:geospatial-query(
    gml:box(
      <gml:Envelope>
        <gml:lowerCorner>10.0 35.0</gml:lowerCorner>
        <gml:upperCorner>20.0 40.0</gml:upperCorner>
      </gml:Envelope>) ))
(:
  returns the following node: 
  <item><gml:Point><gml:pos>15.35 35.34</gml:pos></gml:Point></item>
:)
,

cts:search(doc("/points.xml")//item, 
  gml:geospatial-query(gml:box(
    <gml:Envelope>
      <gml:lowerCorner>10.0 40.0</gml:lowerCorner>
      <gml:upperCorner>20.0 35.0</gml:upperCorner>
    </gml:Envelope>
  )))
(:
  returns the following nodes (wrapping around the Earth):
  <item><gml:Point><gml:pos>10.5 30.0</gml:pos></gml:Point></item>
:)
 
]]></pre>
  </apidoc:example>
</apidoc:function>

<apidoc:function name="geospatial-query-from-elements" type="gml" lib="gml" 
	subcategory="GML" bucket="XQuery Library Modules" category="Geospatial Supporting Functions">
  <apidoc:summary>
	  Returns a <code>cts:query</code> matching points within given 
	  regions.
  </apidoc:summary>
  <apidoc:params>
    <apidoc:param name="regions" type="element()*">
    One or more geographic boxes, circles, polygons, or points, represented
    as GML elements.
    Where multiple boxes,
    circles, polygons, or points are specified, the query matches if any
    box, circle, polygon, or
    point matches.
    </apidoc:param>
    <apidoc:param name="options" type="xs:string*" optional="true">
    Options to this query.  The default is ().
    <p>Options include:</p>
      <blockquote>
        <dl>
        <dt>"coordinate-system=wgs84"</dt>
        <dd>Use the WGS84 coordinate system.</dd>
        <!--
        <dt>"unit=miles"</dt>
        <dd>Distance (for circles) is measured in miles.</dd>
        -->
        <dt>"boundaries-included"</dt>
        <dd>Points on boxes' and circles' boundaries are counted as matching.  This is the default.</dd>
        <dt>"boundaries-excluded"</dt>
        <dd>Points on boxes' and circles' boundaries are not counted as matching.</dd>
        <dt>"boundaries-latitude-excluded"</dt>
        <dd>Points on boxes' latitude boundaries are not counted as matching.</dd>
        <dt>"boundaries-longitude-excluded"</dt>
        <dd>Points on boxes' longitude boundaries are not counted as matching.</dd>
        <dt>"boundaries-south-excluded"</dt>
        <dd>Points on the boxes' southern boundaries are not counted as matching.</dd>
        <dt>"boundaries-west-excluded"</dt>
        <dd>Points on the boxes' western boundaries are not counted as matching.</dd>
        <dt>"boundaries-north-excluded"</dt>
        <dd>Points on the boxes' northern boundaries are not counted as matching.</dd>
        <dt>"boundaries-east-excluded"</dt>
        <dd>Points on the boxes' eastern boundaries are not counted as matching.</dd>
        <dt>"boundaries-circle-excluded"</dt>
        <dd>Points on circles' boundary are not counted as matching.</dd>
      </dl></blockquote>
    </apidoc:param>
    <apidoc:param name="weight" type="xs:double?" optional="true">
    A weight for this query.  The default is 1.0.
    </apidoc:param>
  </apidoc:params>
  <apidoc:return>cts:query</apidoc:return>
<apidoc:usage>
<p>The point value is expressed in the content of the element as a pair
of numbers, separated by whitespace and punctuation (excluding decimal points
and sign characters).
</p>
<p>Point values and boundary specifications of boxes are given in degrees
relative to the WGS84 coordinate system.  Southern latitudes and Western 
longitudes take negative values.  Longitudes will be wrapped to the range 
(-180,+180) and latitudes will be clipped to the range (-90,+90).  
</p>
<p>If the northern boundary of a box is south of the southern boundary, no 
points will  match. However, longitudes wrap around the globe, so that if 
the western boundary is east of the eastern boundary,
then the box crosses the anti-meridian.
</p>
<p>Special handling occurs at the poles, as all longitudes exist at latitudes 
+90 and -90.
</p>
<p>This function will take into account interior polygons, if any, and properly
construct the query to account for them.
</p>
</apidoc:usage>
<apidoc:example><pre xml:space="preserve"><![CDATA[
xquery version "1.0-ml";

(: create a document with test data :)
xdmp:document-insert("/points.xml",
<root xmlns:gml="http://www.opengis.net/gml">
  <item><gml:Point><gml:pos>10.5 30.0</gml:pos></gml:Point></item>
  <item><gml:Point><gml:pos>15.35 35.34</gml:pos></gml:Point></item>
  <item><gml:Point><gml:pos>5.11 40.55</gml:pos></gml:Point></item>
</root> );

xquery version "1.0-ml";
import module namespace gml = "http://www.opengis.net/gml"
   at "/MarkLogic/geospatial/gml.xqy";

cts:search(doc("/points.xml")//item, 
  gml:geospatial-query-from-elements(
      <gml:Envelope>
        <gml:lowerCorner>10.0 35.0</gml:lowerCorner>
        <gml:upperCorner>20.0 40.0</gml:upperCorner>
      </gml:Envelope>) )
(:
  returns the following node: 
  <item><gml:Point><gml:pos>15.35 35.34</gml:pos></gml:Point></item>
:)
,

cts:search(doc("/points.xml")//item, 
  gml:geospatial-query-from-elements(
    <gml:Envelope>
      <gml:lowerCorner>10.0 40.0</gml:lowerCorner>
      <gml:upperCorner>20.0 35.0</gml:upperCorner>
    </gml:Envelope>) )
(:
  returns the following nodes (wrapping around the Earth):
  <item><gml:Point><gml:pos>10.5 30.0</gml:pos></gml:Point></item>
:)
 
 
]]></pre>
  </apidoc:example>
</apidoc:function>
</apidoc:module>
