[//]: # (WARNING: this file is automatically generated. Please find the sources at the bottom and edit those sources)

Tags format
=============

When creating the `json` file describing your layer or theme, you'll have to add a few tags to describe what you want.
This document gives an overview of what every expression means and how it behaves in edge cases.

If the schema-files note a type [`TagConfigJson`](https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/src/Models/ThemeConfig/Json/TagConfigJson.ts), you can use one of these values.

In some cases, not every type of tags-filter can be used. For example,  _rendering_ an option with a regex is
fine (`"if": "brand~[Bb]randname", "then":" The brand is Brandname"`); but this regex can not be used to write a value
into the database. The theme loader will however refuse to work with such inconsistencies and notify you of this while
you are building your theme.

Example
-------

This example shows the most common options on how to specify tags:

```json
{
  "and": [
    "key=value",
    {
      "or": [
        "other_key=value",
        "other_key=some_other_value"
      ]
    },
    "key_which_should_be_missing=",
    "key_which_should_have_a_value~*",
    "key~.*some_regex_a*_b+_[a-z]?",
    "height<1"
  ]
}
```

## `=` strict equality

Strict equality is denoted by `key=value`. This key matches __only if__ the keypair is present exactly as stated.

**Only normal tags (eventually in an `and`) can be used in places where they are uploaded**. Normal tags are used in the `mappings` of a [TagRendering] (unless `hideInAnswer` is specified), they are used in `addExtraTags` of [Freeform] and are used in the `tags`-list of a preset.

If a different kind of tag specification is given, your theme will fail to parse.

### Table of contents

1. [= strict equality](#=-strict-equality)
  - [If key is not present](#if-key-is-not-present)
  - [Removing a key](#removing-a-key)
2. [!= strict not equals](#!=-strict-not-equals)
  - [If key is present](#if-key-is-present)
3. [~ Value matches regex](#~-value-matches-regex)
4. [~i~ Value matches case-invariant regex](#~i~-value-matches-case-invariant-regex)
5. [!~ Value should not match regex](#!~-value-should-not-match-regex)
6. [!~i~ Value does not match case-invariant regex](#!~i~-value-does-not-match-case-invariant-regex)
7. [~~ Key and value should match given regex](#~~-key-and-value-should-match-given-regex)
8. [~i~~ Key and value should match a given regex; value is case-invariant](#~i~~-key-and-value-should-match-a-given-regex-value-is-case-invariant)
9. [!~i~~ Key and value should match a given regex; value is case-invariant](#!~i~~-key-and-value-should-match-a-given-regex-value-is-case-invariant)
10. [:= Substitute ... {some_key} ... and match key](#=-substitute-...-{some_key}-...-and-match-key)
11. [!:= Substitute {some_key} should not match key](#!=-substitute-{some_key}-should-not-match-key)
12. [<= >= < > Logical comparators](#<=->=-<->-logical-comparators)
13. [Logical operators](#logical-operators)

### If key is not present

If you want to check if a key is not present, use `key=` (pronounce as *key is empty*). A tag collection will match this
if `key` is missing or if `key` is a literal empty value.

### Removing a key

If a key should be deleted in the OpenStreetMap-database, specify `key=` as well. This can be used e.g. to remove a
fixme or value from another mapping if another field is filled out.

## `!=` strict not equals

To check if a key does _not_ equal a certain value, use `key!=value`. This is converted behind the scenes
to `key!~^value$`

If `key` is not present or empty, this will match too.

### If key is present

This implies that, to check if a key is present, `key!=` can be used. This will only match if the key is present and not
empty.

## `~` Value matches regex

A tag can also be tested against a regex with `key~regex`. Note that this regex __must match__ the entire value. If the
value is allowed to appear anywhere as substring, use `key~.*regex.*`.
The regex is put within braces as to prevent runaway values.

Use `key~*` to indicate that any value is allowed. This is effectively the check that the attribute is present (defined _and_ not empty).
Regexes will match the newline character with `.` too - the `s`-flag is enabled by default.

## `~i~` Value matches case-invariant regex

A tag can also be tested against a regex with `key~i~regex`, where the case of the value will be ignored. The regex is still matched against the _entire_ value

## `!~` Value should _not_ match regex

A tag can also be tested against a regex with `key!~regex`. This filter will match if the value does *not* match the regex. 
 If the
value is allowed to appear anywhere as substring, use `key~.*regex.*`.
The regex is put within braces as to prevent runaway values.

## `!~i~` Value does *not* match case-invariant regex

A tag can also be tested against a regex with `key~i~regex`, where the case of the value will be ignored. The regex is still matched against the _entire_ value (thus: a `^` and `$` are automatically added to start and end). This filter returns true if the value does *not* match

## `~~` Key and value should match given regex

Both the `key` and `value` part of this specification are interpreted as regexes, both the key and value must completely match their respective regexes (thus: a `^` and `$` are automatically added to start and end)

## `~i~~` Key and value should match a given regex; value is case-invariant

Similar to ~~, except that the value is case-invariant

## `!~i~~` Key and value should match a given regex; value is case-invariant

Similar to !~~, except that the value is case-invariant

## `:=` Substitute `... {some_key} ...` and match `key`

**This is an advanced feature - use with caution**

Some tags are automatically set or calculated - see [CalculatedTags](CalculatedTags.md) for an entire overview. If one
wants to apply such a value as tag, use a substituting-tag such, for example`survey:date:={_date:now}`. Note that the
separator between key and value here is `:=`. The text between `{` and `}` is interpreted as a key, and the respective
value is substituted into the string.

One can also append, e.g. `key:={some_key} fixed text {some_other_key}`.

An assigning tag _cannot_ be used to query OpenStreetMap/Overpass.

If using a key or variable which might not be defined, add a condition in the mapping to hide the option. This is
because, if `some_other_key` is not defined, one might actually upload the literal text `key={some_other_key}` to OSM -
which we do not want.

To mitigate this, use:

```json
{
    "mappings": [
        {
            "if":"key:={some_other_key}",
            "then": "...",
            "hideInAnswer": "some_other_key="
        }
    ]
}
```

One can use `key!:=prefix-{other_key}-postfix` as well, to match if `key` is _not_ the same
as `prefix-{other_key}-postfix` (with `other_key` substituted by the value)

## `!:=` Substitute `{some_key}` should not match `key`

See `:=`, except that this filter is inverted

## `<=` `>=` `<` `>` Logical comparators
If the value of a tag is a number (e.g. `key=42`), one can use a filter `key<=42`, `key>=35`, `key>40` or `key<50` to
match this, e.g. in conditions for renderings. These tags cannot be used to generate an answer nor can they be used to
request data upstream from overpass.

Note that the value coming from OSM will first be stripped by removing all non-numeric characters. For
example, `length=42 meter` will be interpreted as `length=42` and will thus match `length<=42` and `length>=42`. In
special circumstances (e.g. `surface_area=42 m2` or `length=100 feet`), this will result in erronous
values (`surface=422` or if a length in meters is compared to). However, this can be partially alleviated by using '
Units' to rewrite to a default format.

Dates can be compared with the same expression: `somekey<2022-06-22` will match if `somekey` is a date and is smaller
then 22nd june '22.

## Logical operators

One can combine multiple tags by using `and` or `or`, e.g.:

```json
{
  "osmTags": {
    "or": [
      "amenity=school",
      "amenity=kindergarten"
    ]
  }
}
```


This document is autogenerated from [src/Logic/Tags/TagUtils.ts](https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/src/Logic/Tags/TagUtils.ts)
