> For the complete documentation index, see [llms.txt](https://olivers-expression-lab.gitbook.io/filter-expressions-in-fme/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://olivers-expression-lab.gitbook.io/filter-expressions-in-fme/logical-operators.md).

# Logical Operators

In previous chapters we learned how to do different attributive and spatial queries.&#x20;

Let's combine them by using Logical Operators.

## OR

Let's start with the **OR-Operator** (logical disjunction).

We will use the parking decks-WFS provided by Hanseatic City of Hamburg we already used in [Comparison Operators](/filter-expressions-in-fme/comparison-operators.md).

| Parameter      | Value                                                                                                        |
| -------------- | ------------------------------------------------------------------------------------------------------------ |
| WFS URL        | <https://qs-geodienste.hamburg.de/HH_WFS_Verkehr_opendata?SERVICE=WFS>                                       |
| Version        | 2.0.0                                                                                                        |
| Features Types | verkehr\_parkhaeuser                                                                                         |
| Max Features   | leave blank                                                                                                  |
| xmlns          | de.hh.up="<https://registry.gdi-de.org/id/de.hh.up>"                                                         |
|                | <p>preise (de) = fees (en)<br>kostenlos (de) = free of charge (en)<br>keine Gebühr (de) = no charge (en)</p> |

The services provides an attribute called "preise", i.e. fees.

First, we will look for all parking decks, which can be used free of charge (**kostenlos**), at least for some time (half an hour or an hour).

The word "kostenlos" occurs in different mixtures like

* 1\. Stunde **kostenlos**|2. Stunde 1,20 EUR | jede weitere Std. 1,50 EUR|Tageshöchstsatz k. A.
* 1\. Stunde **kostenlos**|jede weitere Std. 1,50 EUR|Tageshöchstsatz 15,00 EUR
* halbe Stunde: **kostenlos**|2. halbe Stunde: 0,50 EUR|2. Stunde: 1,00 EUR| (...)

Remember what we learned in [Comparison Operators](/filter-expressions-in-fme/comparison-operators.md) about **Wildcards** using the **PropertyIsLike**-Operator.

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:de.hh.up="https://registry.gdi-de.org/id/de.hh.up">
		<fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>*kostenlos*</fes:Literal>
		</fes:PropertyIsLike>
</fes:Filter>
```

Using this filter expression, the service will return **5** features (at the time of publication of this chapter):

* 10047 Elbe Einkaufszentrum (EEZ)
* 10076 Alstertal Einkaufszentrum (AEZ) Ost
* 10094 Harburg Carree
* 10116 Alstertal Einkaufszentrum (AEZ) Mitte
* 10117 Alstertal Einkaufszentrum (AEZ) West

Next, we will look for all parking decks with no charges (**keine Gebühren**) using the well-known **PropertyIsEqualTo**-Operator.

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:de.hh.up="https://registry.gdi-de.org/id/de.hh.up">
		<fes:PropertyIsEqualTo>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>keine Gebühren</fes:Literal>
		</fes:PropertyIsEqualTo>
</fes:Filter>
```

The WFS will return **3** additional features:

* 10089 Sander Markt
* 10090 Frascatiplatz
* 10091 Lohbrügger Marktplatz

Instead of sending two separate (disjoined) requests, we can combine them into one single request using the OR-Operator as shown below:

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:de.hh.up="https://registry.gdi-de.org/id/de.hh.up">
	<fes:Or>
		<fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>*kostenlos*</fes:Literal>
		</fes:PropertyIsLike>
		<fes:PropertyIsEqualTo>
			<fes:ValueReference>de.hh.up:preise</fes:ValueReference>
			<fes:Literal>keine Gebühren</fes:Literal>
		</fes:PropertyIsEqualTo>
	</fes:Or>
</fes:Filter>
```

The only simple trick is to **embrace your expressions** (to be precise, the conditions within the expression) **by the logical operator** needed, i.e.

```
OR
    CONDITION 1
    CONDITION 2
    ...
/OR
```

```
AND
    CONDITION 1
    CONDITION 2
    ...
/AND
```

If you're a programmer, this may be unfamiliar for you because you normally connect conditions by logical operators like this:

```
CONDITION 1 OR CONDITION 2 OR CONDITION 3
```

So please keep in mind: logical operators embrace conditions within filter expressions.

## AND

Recapitulating what we have learned, using other logical operators is really easy:

* take two or more filter expressions&#x20;
* make sure, that they are working stand-alone (please test them!)&#x20;
* combine them by enclosing them by logical operators

To do so, we will have a look at the **AND-Operator** (logical conjunction) using a mining-WFS provided by Federal State of Brandenburg.

| Parameter      | Value                                                                                                      |
| -------------- | ---------------------------------------------------------------------------------------------------------- |
| WFS URL        | <https://inspire.brandenburg.de/services/bergbau_wfs?> (mining)                                            |
| Version        | 2.0                                                                                                        |
| Features Types | bgberechtig (mining rights)                                                                                |
| Max Features   | leave blank                                                                                                |
| xmlns          | <p>fes="<http://www.opengis.net/fes/2.0>"<br>app="<http://www.deegree.org/app>"</p>                        |
|                | <p>inhaber (de) = holder (en)<br>bodenschatz\_kurz (de) = resource, abbr. (en)<br>Ton (de) = clay (en)</p> |

First, we want to get all mining rights in Brandenburg owned by the company called "BVVG Bodenverwertungs- und -verwaltungs GmbH".

```xml
<fes:Filter
    xmlns:fes="http://www.opengis.net/fes/2.0"
    xmlns:app="http://www.deegree.org/app">
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:inhaber</fes:ValueReference>
		<fes:Literal>BVVG Bodenverwertungs- und -verwaltungs GmbH</fes:Literal>
	</fes:PropertyIsEqualTo>
</fes:Filter>
```

The WFS will return 35 polygon features.

Next, we're interested in all clay pits.

```xml
<fes:Filter
    xmlns:fes="http://www.opengis.net/fes/2.0"
    xmlns:app="http://www.deegree.org/app">
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:bodenschatz_kurz</fes:ValueReference>
		<fes:Literal>Ton</fes:Literal>
	</fes:PropertyIsEqualTo>
</fes:Filter>
```

We will get 29 polygon features.

If we want to see only the clay pits owned by BVVG, we have to put all of this together using the **AND-Operator**.

```xml
<fes:Filter
    xmlns:fes="http://www.opengis.net/fes/2.0"
    xmlns:app="http://www.deegree.org/app">
   <fes:And>
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:inhaber</fes:ValueReference>
		<fes:Literal>BVVG Bodenverwertungs- und -verwaltungs GmbH</fes:Literal>
	</fes:PropertyIsEqualTo>
	<fes:PropertyIsEqualTo>
		<fes:ValueReference>app:bodenschatz_kurz</fes:ValueReference>
		<fes:Literal>Ton</fes:Literal>
	</fes:PropertyIsEqualTo>
   </fes:And>
</fes:Filter>
```

The WFS will return 7 polygon features.

## Good to know #4

You may ask yourself: is it possible to combine both

1. Comparison Operators
2. Spatial Operators

???

The answer is: yes, it is possible!

To demonstrate it, just copy the **BBOX-Expression** from [Spatial Operators](/filter-expressions-in-fme/spatial-operators.md#bbox)

```xml
<fes:Filter
	xmlns:fes="http://www.opengis.net/fes/2.0"
	xmlns:gml="http://www.opengis.net/gml/3.2">
  <fes:BBOX>
        <gml:Envelope srsName="urn:ogc:def:crs:EPSG::25832">
          <gml:lowerCorner>367441.62 5620100.532</gml:lowerCorner>
          <gml:upperCorner>367619.15 5620254.767</gml:upperCorner>
       </gml:Envelope>
   </fes:BBOX>
</fes:Filter>
```

Next, create a **PropertyIsLike-Expression** like this

```xml
<fes:Filter 
   xmlns:fes="http://www.opengis.net/fes/2.0"
   xmlns:cp="http://inspire.ec.europa.eu/schemas/cp/4.0">
   <fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
      <fes:ValueReference>cp:nationalCadastralReference</fes:ValueReference>
      <fes:Literal>054302026*</fes:Literal>
   </fes:PropertyIsLike>
</fes:Filter>
```

Check, if both expressions are running stand-alone.

If so, please combine them using the **AND-Operator**:

```xml
<fes:Filter 
   xmlns:fes="http://www.opengis.net/fes/2.0"
   xmlns:cp="http://inspire.ec.europa.eu/schemas/cp/4.0">
   <fes:And>
   <fes:PropertyIsLike wildCard='*' singleChar='.' escapeChar='!'>
      <fes:ValueReference>cp:nationalCadastralReference</fes:ValueReference>
      <fes:Literal>054302026*</fes:Literal>
   </fes:PropertyIsLike>
   <fes:BBOX>
        <gml:Envelope srsName="urn:ogc:def:crs:EPSG::25832">
          <gml:lowerCorner>367441.62 5620100.532</gml:lowerCorner>
          <gml:upperCorner>367619.15 5620254.767</gml:upperCorner>
       </gml:Envelope>
   </fes:BBOX>
   </fes:And>
</fes:Filter>
```

What's the difference?

See for yourself!

<figure><img src="/files/FrPCx8f51EjMMwwpmt6i" alt=""><figcaption><p>Original BBOX</p></figcaption></figure>

<figure><img src="/files/EUCJ0Cse1Pdwu8axGUQB" alt=""><figcaption><p>BBOX combined with attribute filter</p></figcaption></figure>
