GOQL

GOQL (Geo-Object Query Language) is a concise query syntax used by GeoDesk to select OpenStreetMap features based on their type and tags. Its syntax is similar to MapCSS, which in turn is modeled after CSS (Cascading Style Sheets). GOQL is used across all GeoDesk components: the GOL Tool, and the Python, Java, and C++ SDKs.
Overview
A GOQL query consists of one or more selectors. Each selector specifies a feature type followed by zero or more tag clauses enclosed in square brackets. The selector filters features from a Geo-Object Library (GOL), returning only those that match the specified type and tag constraints.
A basic example:
na[amenity=restaurant]
This selects all nodes and areas tagged with amenity=restaurant.
Feature Types
Every selector begins with one or more type identifiers:
| Identifier | Meaning | |
|---|---|---|
n |
Nodes | |
w |
Ways (excluding areas) | |
a |
Areas (can be ways or relations) | |
r |
Relations (excluding areas) | |
* |
Any type |
Type identifiers can be combined. For example, na selects both nodes and areas — this is the most common combination, as points of interest in OSM are often mapped as either points or polygons.
Examples:
n[emergency=fire_hydrant] nodes only w[highway] linear ways only a[leisure=park] areas only (ways or relations) r[route=bicycle] non-area relations only na[tourism=museum] nodes and areas *[name] any type with a name tag
Tag Clauses
Tag clauses filter features by their tag keys and values. If multiple tag clauses are specified, the feature must satisfy all of them (logical AND).
Presence Test
A unary tag clause tests for the presence of a tag. The tag's value must not be no:
w[highway] ways that have a highway tag (value is not "no") r[route][ref] relations with both route and ref tags
Prefix with ! to negate (test for absence, or no):
w[highway=residential][!oneway] residential streets that are not one-way *[!name] features without a name tag
Exact Match
Use = to match a specific tag value:
na[amenity=pub]
Use != to exclude specific values:
w[highway][highway!=motorway,primary] highways except motorways and primary roads a[leisure=pitch][sport!=soccer] sports pitches that are not soccer fields
Multiple Values
Multiple values can be listed in a single tag clause, separated by commas (logical OR):
na[amenity=restaurant,pub,cafe]
This is equivalent to writing three separate selectors:
na[amenity=restaurant], na[amenity=pub], na[amenity=cafe]
Numeric Comparisons
Numeric tag values can be compared using >=, <=, >, and <:
na[place=city][population>=1000000] cities with at least one million inhabitants w[highway][maxspeed < 30] roads with speed limit below 30
Wildcard String Matching
Use the * wildcard for partial string matches. Matching is always case-sensitive:
na[name=The*] matches "The Best", "Theater" na[name="The *"] matches "The Best" but not "Theater" na[name=*land] matches "bland", "New Zealand" na[name=*eat*] matches "eatery", "Beat", "Theater"
Strings containing characters other than letters, numbers, or underscores must be enclosed in matching single or double quotes:
na[amenity=pub][name="The King's Head"]
Regular Expressions
For more sophisticated string matching, use the ~ operator (or !~ to negate):
na[name~".[Ee]at."]
Multiple Selectors
A query can contain multiple selectors separated by commas. A feature is included in the result if it matches any of the selectors (logical OR):
na[amenity=restaurant], na[amenity=pub], na[amenity=cafe]
Quick Reference
| Query | Description |
|---|---|
w[highway] |
Linear ways with a highway tag (excluding 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
|
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 are not soccer fields |
na[amenity=pub][name="*King*"] |
Pubs with "King" in their name |
na[amenity=pub][name~".[Kk]ing."] |
Pubs matching a regular expression (e.g. "The King's Head", "The Barking Dog") |
na[place=city][population>=1000000] |
Cities with a population of at least one million |
Usage
GOQL queries are used consistently across all GeoDesk components.
GOL Tool (command line)
gol query france na[tourism=hotel]
Python
for hotel in france("na[tourism=hotel]"):
print(hotel.name)
Java
for (Feature hotel : france.select("na[tourism=hotel]"))
System.out.println(hotel.stringValue("name"));
C++
for (Feature hotel : france("na[tourism=hotel]"))
std::cout << hotel["name"] << std::endl;
See Also
- GeoDesk
- Geo-Object Library — the GOL file format
- MapCSS — a related selector syntax for map styling
- Overpass QL — query language for the Overpass API
- Map features — OSM tagging conventions