cql_tutorial.rst 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. .. _cql_tutorial:
  2. CQL and ECQL
  3. =============
  4. CQL (Common Query Language) is a query language created by the OGC for the `Catalogue Web Services specification <http://www.opengeospatial.org/standards/cat>`_.
  5. Unlike the XML-based Filter Encoding language, CQL is written using a familiar text-based syntax.
  6. It is thus more readable and better-suited for manual authoring.
  7. However, CQL has some limitations. For example it cannot encode id filters, and it requires an attribute to be on the left side of any comparison operator.
  8. For this reason, GeoServer provides an extended version of CQL called ECQL.
  9. ECQL removes the limitations of CQL, providing a more flexible language with stronger similarities with SQL.
  10. GeoServer supports the use of both CQL and ECQL in WMS and WFS requests, as well as in GeoServer's SLD :ref:`dynamic symbolizers <pointsymbols>`.
  11. Whenever the documentation refers to CQL, ECQL syntax can be used as well (and if not, please report that as a bug!).
  12. This tutorial introduces the CQL/ECQL language by example.
  13. For a full reference, refer to the :ref:`filter_ecql_reference`.
  14. Getting started
  15. ---------------
  16. The following examples use the ``topp:states`` sample layer shipped with GeoServer.
  17. They demonstrate how CQL filters work by using the WMS :ref:`CQL_FILTER vendor parameter<wms_vendor_parameters>` to alter the data displayed by WMS requests.
  18. The easiest way to follow the tutorial is to open the GeoServer Map Preview for the ``topp:states`` layer.
  19. Click on the *Options* button at the top of the map preview to open the advanced options toolbar.
  20. The example filters can be entered in the *Filter: CQL* box.
  21. .. figure:: gettingStarted.png
  22. :align: center
  23. *topp:states preview with advanced toolbar open.*
  24. The attributes used in the filter examples are those included in the layer.
  25. For example, the following are the attribute names and values for the Colorado feature:
  26. .. list-table::
  27. * - **Attribute**
  28. - **states.6**
  29. * - STATE_NAME
  30. - Colorado
  31. * - STATE_FIPS
  32. - 08
  33. * - SUB_REGION
  34. - Mtn
  35. * - STATE_ABBR
  36. - CO
  37. * - LAND_KM
  38. - 268659.501
  39. * - WATER_KM
  40. - 960.364
  41. * - PERSONS
  42. - 3294394.0
  43. * - FAMILIES
  44. - 854214.0
  45. * - HOUSHOLD
  46. - 1282489.0
  47. * - MALE
  48. - 1631295.0
  49. * - FEMALE
  50. - 1663099.0
  51. * - WORKERS
  52. - 1233023.0
  53. * - DRVALONE
  54. - 1216639.0
  55. * - CARPOOL
  56. - 210274.0
  57. * - PUBTRANS
  58. - 46983.0
  59. * - EMPLOYED
  60. - 1633281.0
  61. * - UNEMPLOY
  62. - 99438.0
  63. * - SERVICE
  64. - 421079.0
  65. * - MANUAL
  66. - 181760.0
  67. * - P_MALE
  68. - 0.495
  69. * - P_FEMALE
  70. - 0.505
  71. * - SAMP_POP
  72. - 512677.0
  73. Simple comparisons
  74. ----------------------
  75. Let's get started with a simple example. In CQL arithmetic and comparisons
  76. are expressed using plain text. The filter ``PERSONS > 15000000`` will select states that
  77. have more than 15 million inhabitants:
  78. .. figure:: more15M.png
  79. :align: center
  80. *PERSONS > 15000000*
  81. The full list of comparison operators is: ``=``, ``<>``, ``>``, ``>=``, ``<``, ``<=``.
  82. To select a range of values the BETWEEN operator can be used: ``PERSONS BETWEEN 1000000 AND 3000000``:
  83. .. figure:: between.png
  84. :align: center
  85. *PERSONS BETWEEN 1000000 AND 3000000*
  86. Comparison operators also support text values. For instance, to select only the state of California, the filter is
  87. ``STATE_NAME = 'California'``.
  88. More general text comparisons can be made using the ``LIKE`` operator. ``STATE_NAME LIKE 'N%'`` will extract all states starting with an "N":
  89. .. figure:: startn.png
  90. :align: center
  91. *STATE_NAME LIKE 'N%'*
  92. It is also possible to compare two attributes with each other. ``MALE > FEMALE`` selects the
  93. states in which the male population surpasses the female one (a rare occurrence):
  94. .. figure:: malefemale.png
  95. :align: center
  96. *MALE > FEMALE*
  97. Arithmetic expressions can be computed using the ``+, -, *, /`` operators.
  98. The filter ``UNEMPLOY / (EMPLOYED + UNEMPLOY) > 0.07`` selects all states whose unemployment ratio is above 7% (remember the sample data is very old, so don't draw any conclusion from the results!)
  99. .. figure:: employ.png
  100. :align: center
  101. *UNEMPLOY / (EMPLOYED + UNEMPLOY) > 0.07*
  102. Id and list comparisons
  103. -----------------------
  104. If we want to extract only the states with specific feature ids we can use the ``IN`` operator without specifying any attribute, as in ``IN ('states.1', 'states.12')``:
  105. .. figure:: idfilter.png
  106. :align: center
  107. *IN ('states.1', 'states.12')*
  108. If instead we want to extract the states whose name is in a given list we can use the ``IN`` operator specifying an attribute name, as in ``STATE_NAME IN ('New York', 'California', 'Montana', 'Texas')``:
  109. .. figure:: statenames.png
  110. :align: center
  111. *STATE_NAME IN ('New York', 'California', 'Montana', 'Texas')*
  112. .. warning::
  113. `Note <https://gis.stackexchange.com/a/475826/68995>`_: `id` is one of a few `reserved keywords <https://github.com/geotools/geotools/blob/2058be01323c3dea23d6df4d84b623be7f0b4102/modules/library/cql/src/main/jjtree/ECQLGrammar.jjt#L180>`_ in ECQL and thus an attribute (or database column) named `id` must be quoted, e.g. `"id"`
  114. Filter functions
  115. ------------------------
  116. CQL/ECQL can use any of the :ref:`filter functions <filter_function_reference>` available in GeoServer.
  117. This greatly increases the power of CQL expressions.
  118. For example, suppose we want to find all states whose name contains an "m", regardless of letter case. We can use the ``strToLowerCase`` to turn all the state names to lowercase and then use a like comparison: ``strToLowerCase(STATE_NAME) like '%m%'``:
  119. .. figure:: mstates.png
  120. :align: center
  121. *strToLowerCase(STATE_NAME) like '%m%'*
  122. Geometric filters
  123. ------------------
  124. CQL provides a full set of geometric filter capabilities. Say, for example, you want to display only the states that intersect the (-90,40,-60,45) bounding box.
  125. The filter will be ``BBOX(the_geom, -90, 40, -60, 45)``
  126. .. figure:: bbox.png
  127. :align: center
  128. *BBOX(the_geom, -90, 40, -60, 45)*
  129. Conversely, you can select the states that do *not* intersect the bounding box with the filter: ``DISJOINT(the_geom, POLYGON((-90 40, -90 45, -60 45, -60 40, -90 40)))``:
  130. .. figure:: disjoint.png
  131. :align: center
  132. *DISJOINT(the_geom, POLYGON((-90 40, -90 45, -60 45, -60 40, -90 40)))*
  133. The full list of geometric predicates is: ``EQUALS``, ``DISJOINT``, ``INTERSECTS``, ``TOUCHES``, ``CROSSES``, ``WITHIN``, ``CONTAINS``, ``OVERLAPS``, ``RELATE``, ``DWITHIN``, ``BEYOND``.