Search code examples
openstreetmapoverpass-api

How can I make keys optional in Overpass API queries / osm-scripts?


I found

<osm-script output="json" timeout="25">
  <!-- gather results -->
  <union>
    <!-- query part for: “waterway=*” -->
    <query type="way">
      <has-kv k="amenity" v="parking"/>
      <bbox-query {{bbox}}/>
    </query>
  </union>
  <!-- print results -->
  <print mode="body"/>
  <recurse type="down"/>
  <print mode="skeleton" order="quadtile"/>
</osm-script>

to give many parking spots (but not considering streets where you can park at the border - might be a lack of available information).

It does, however, also give private parking spots.

When I add

<has-kv k="access" v="public"/>

it removes the private ones, but also a couple of public ones that seem not to have the attribute. Is there a way to (a) "subtract" elements (e.g. <has-kv k="access" v="private"/>) or (b) make the presence of a key (e.g. access) optional but enforce a value (e.g. public) if it is public?


Solution

  • You can use the negation operator:

    <has-kv k="access" modv="not" v="private"/>
    

    Your whole query with the negation from above:

    <osm-script output="json" timeout="25">
      <!-- gather results -->
      <union>
        <!-- query part for: “waterway=*” -->
        <query type="way">
          <has-kv k="amenity" v="parking"/>
          <has-kv k="access" modv="not" v="private"/>
          <bbox-query {{bbox}}/>
        </query>
      </union>
      <!-- print results -->
      <print mode="body"/>
      <recurse type="down"/>
      <print mode="skeleton" order="quadtile"/>
    </osm-script>
    

    Or in more readable OverpassQL:

    [timeout:25]
    [out:json]
    ;
    (
      way
        ["amenity"="parking"]
        ["access"!="private"]
        {{bbox}};
    );
    out;
    >;
    out skel qt;