Getting Started

Basic Usage

Use query to send an Overpass QL query to the Overpass API. Results are returned as an OverpassResponse containing typed elements.

using OverpassAPI

r = query("node[amenity=cafe](35.9,-79.1,36.1,-78.8); out geom;")

[out:json] is automatically prepended if not already present.

Query Builder

The OQL object lets you build queries with Julia syntax instead of writing raw Overpass QL strings. Use dot syntax to select element types and bracket syntax to add tag filters:

# Keyword syntax (clean, no quotes on keys)
OQL.node[amenity = "cafe"]

# Multiple filters
OQL.node[amenity = "cafe", cuisine = "coffee"]

# Regex matching (Julia regex literals)
OQL.node[name = r"^Starbucks"i]

# Tag exists (positional string)
OQL.way["building"]

# Mix and chain freely
OQL.node[amenity = "cafe"]["wifi"]

Pass a QLStatement directly to query:

r = query(OQL.node[amenity = "cafe"],
          bbox=Extent(X=(-79.1, -78.8), Y=(35.9, 36.1)))

The out keyword controls the output mode (default :geom):

r = query(OQL.way[building = "yes"], bbox=ext, out=:center)

For keys with special characters (e.g. addr:street), use the Pair syntax:

OQL.node["addr:street" => "Main St"]

Bounding Boxes with Extents.Extent

Instead of manually formatting (south,west,north,east) strings, pass an Extents.Extent to the bbox keyword:

using Extents

ext = Extent(X=(-79.1, -78.8), Y=(35.9, 36.1))

# Works with both raw QL strings and OQL statements
r = query("node[amenity=cafe]; out geom;", bbox=ext)
r = query(OQL.node[amenity = "cafe"], bbox=ext)

Filtering Elements

Use the convenience functions to filter by element type:

nodes(r)      # Vector{Node}
ways(r)       # Vector{Way}
relations(r)  # Vector{Relation}

OverpassResponse is also iterable:

length(r)       # total element count
collect(r)      # Vector{Element}
for e in r
    # ...
end

Accessing Tags

Use bracket syntax directly on elements:

n = first(nodes(r))
n["amenity"]                    # "cafe"
n["name"]                       # "Joe Van Gogh"
get(n, "phone", "unknown")     # safe access with default
haskey(n, "website")            # check if tag exists
keys(n)                         # all tag keys

Getting Geometry with out geom

To get full coordinate geometry on Ways and Relations, use out geom in your query (this is the default when using OQL):

r = query(OQL.way[building = "yes"], bbox=ext)

w = first(ways(r))
w.geometry  # Vector{LatLon} with coordinates

Without out geom, Ways only contain node ID references (node_ids) and no coordinate data.

GeoInterface Integration

All geometry types implement GeoInterface.jl traits:

  • Node and LatLon implement PointTrait
  • Way implements LineStringTrait (when geometry is available)
using GeoInterface
const GI = GeoInterface

n = Node(id=1, lat=40.748, lon=-73.985)
GI.x(n)  # -73.985 (longitude)
GI.y(n)  # 40.748  (latitude)

Extents.extent is implemented for Node, LatLon, and Way:

using Extents
Extents.extent(w)  # Extent(X=(-74.1, -73.9), Y=(40.0, 40.2))

This means OverpassAPI types work with any package in the Julia geospatial ecosystem.