Skip to main content Link Search Menu Expand Document (external link)

Geo-Object Query Language (GOQL)

GOQL is a concise syntax for describing queries in terms of feature type and tags. It is similar to MapCSS, which in turn is modeled after the original CSS (the Cascading Style Sheets used with HTML).

A query is composed of one or more selectors, which work like their CSS counterparts — but instead of elements and their attributes, they filter features based on their type and tags.

Type must be one or more of the following:

n

Nodes

w

Ways (except areas)

a

Areas (can be ways or relations)

r

Relations (except areas)

*

Any type

Type identifiers can be combined. For example, na selects both nodes and areas — this is the most common combo, as points-of-interest in OSM are often represented as points or polygons.

To select all element types, use the wildcard *.

To further constrain features, add one or more tag clauses, which function like CSS attribute selectors:

na[amenity=restaurant]

The above selects all nodes and areas that have an amenity tag whose value is restaurant. If multiple tag clauses are specified, the feature must fulfill all of them. For example, this query finds all sushi restaurants that offer takeaway and have a website:

na[amenity=restaurant][cusine=sushi][takeaway][website]

Tag clauses may appear in any order.

A unary tag clause tests for presence of a tag (whose value must not be no). Prepend it with ! to negate it. For example, to find residential streets that are not one-way:

w[highway=residential][!oneway]

Strings that contain characters other than letters, numbers or underscores must be quoted (matching single or double quotes):

na[amenity=pub][name="The King's Head"]

For partial string matches, use the wildcard *:

na[name=The*]       /* "The Best", "Theater"       */
na[name="The *"]    /* "The Best"                  */
na[name=*land]      /* "bland", "New Zealand"      */
na[name=*eat*]      /* "eatery", "Beat", "Theater" */

String matching is always case-sensitive.

For more sophisticated string matching, use regular expressions (using the operator ~ or !~):

na[name~".[Ee]at."]      

TODO: more RegEx examples

A query can contain multiple selectors, separated by commas:

na[amenity=restaurant], na[amenity=pub], na[amenity=cafe]

The above can be simplified by specifying multiple values in a single tag clause:

na[amenity=restaurant,pub,cafe]

Quick Reference

w[highway]

Linear ways that have a highway tag (except highway=no)

w[highway][!oneway]

Highways that are not one-way

w[highway][highway!=motorway,primary]

Highways except motorways and primary roads

*[!name]

Any feature without a name tag

r[route][ref][network]

Non-area relations with route, ref and network tags (whose values must not be no)

na[amenity=bar,pub,fast_food]

Nodes and areas that are bars, pubs or fast-food restaurants

a[leisure=pitch][sport!=soccer]

Sports pitches that aren’t soccer fields

na[amenity=pub][name="*King*"]

Pubs with King in their name (simple string match)

na[amenity=pub][name=~".[Kk]ing."]

Regular expression that selects pubs named The King's Head as well as The Barking Dog

na[place=city][population>=1000000]

Cities whose population is at least one million

How to Use GOQL Queries

On the command line (using the GOL Tool):

$ gol query france na[tourism=hotel] 

In Java:

for(Feature hotel : france.select("na[tourism=hotel]"))
    ...

In Python:

for hotel in france("na[tourism=hotel]"):
    ...

In C++:

for(Feature hotel : france("na[tourism=hotel]"))
    ...