5

So I'm trying to get a good list of embassies from Overpass, here's my initial query:

[out:json];
(
    node["amenity"="embassy"];
    way["amenity"="embassy"];
    relation["amenity"="embassy"]
);
out tags; 

However this query has some issues to it. I'm looking for embassies, but this query also includes UN missions, consulates, ambassador's residence, anything else in the diplomatic tag. A naive fix for this would be to add ["diplomatic"="embassy"] but after searching through the results of my initial query, I've noticed that there are actual "embassies" without any diplomatic tag.

So this comes to my question, can I modify my query to make a boolean-like filters to check for "embassy" only if "diplomatic" tag exists or ["tag"="value_A"||"value_B"] or ["tag_A"&&"tag_B"] and so on?

0

1 Answer 1

8

We can formulate the answer in different ways:

Option 1:

Basically, you want to remove those amenity=embassy from your current result list, which have a diplomatic value that is not embassy (assuming they have a diplomatic tag at all).

For this purpose, I used the - (difference) operator to reduce the current result set for each node, way and relation:

[out:json];
(
 ( node[amenity=embassy]; -  node[amenity=embassy][diplomatic][diplomatic!=embassy]; );
 ( way[amenity=embassy];  -  way[amenity=embassy][diplomatic][diplomatic!=embassy];  );
 ( rel[amenity=embassy];  -  rel[amenity=embassy][diplomatic][diplomatic!=embassy];  );
);
out tags; 

overpass turbo link: http://overpass-turbo.eu/s/mXx


Option 2:

This alternative approach effectively returns the same result, but may be a bit easier to understand. In the following query, we create a union of

  • all elements with amenity=embassy, but no diplomatic tag, and
  • all elements with amenity=embassy and diplomatic=embassy
[out:json];
(
  node[amenity=embassy][!diplomatic];
  node[amenity=embassy][diplomatic=embassy];
  way[amenity=embassy][!diplomatic];
  way[amenity=embassy][diplomatic=embassy];
  rel[amenity=embassy][!diplomatic];
  rel[amenity=embassy][diplomatic=embassy];
);
out tags; 

overpass turbo link: http://overpass-turbo.eu/s/mY8


Option 3:

Since version 0.7.54 (released March 2017), there's a new option to specify an (if: ...) filter, which finally supports boolean expressions. The query above can be written in the following way:

  • is_tag checks, if a specific tag exists
  • t["diplomatic"] returns the value of a diplomatic tag.
[out:json];
(
  node[amenity=embassy]
      (if:!is_tag("diplomatic") || 
          (is_tag("diplomatic") && t["diplomatic"] == "embassy"));

  way[amenity=embassy]
      (if:!is_tag("diplomatic") || 
          (is_tag("diplomatic") && t["diplomatic"] == "embassy"));

  rel[amenity=embassy]
      (if:!is_tag("diplomatic") || 
          (is_tag("diplomatic") && t["diplomatic"] == "embassy"));
);
out tags; 

overpass turbo link: http://overpass-turbo.eu/s/nr6


Option 4:

You can also try the overpass turbo wizard, if you don't want to fiddle around with those details.

In overpass turbo wizard, you can easily create the query mentioned in Option 2 above using the following expression:

(amenity=embassy and diplomatic!=*) or (amenity=embassy and diplomatic=embassy) global

Now, that's something easily digestible at last.

2
  • One last question, if I went with option 1 and wanted to add more filters (e.g. remove all embassies that don't have a name tag), what would the syntax for that look like? I've been trying to add more difference operators within the union but it seems that the queries don't work like equations do. Feb 24, 2017 at 6:35
  • 1
    Rather than removing those embassies without a name, I'd suggest to adjust the original resultset by writing node[amenity=embassy][name]; instead of node[amenity=embassy]; (see: overpass-turbo.eu/s/mYU for the full query). Chaining multiple difference operators can become quite cumbersome, as it supports only two operarands: So, the form (.a; - .b;); as in Option 1 needs to be extended to something like ( ( .a; - .b; ); - .c; ); and further extending to ( ( ( .a; - .b; ); - .c; ); - .d; );
    – mmd
    Feb 24, 2017 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.