Skip to main content

Amenity queries

An amenity query asks for the nearest instance of a generic category. The user doesn't care which gas station — they care which one is closest, open, or cheapest. The geocoder's job is to translate a category label into a set of candidate locations and rank them.

What amenity queries look like

QueryCategoryImplicit constraints
gas stationamenity=fuelNearest to user's location
water fountainamenity=drinking_waterNearest, publicly accessible
ATMamenity=atmNearest, preferably in-network
restroomamenity=toiletsNearest, publicly accessible, open
mailboxamenity=post_boxNearest, collection time not passed
playgroundleisure=playgroundNearest, open to public
pharmacyamenity=pharmacyNearest, open now
hospitalamenity=hospitalNearest, emergency department
bicycle parkingamenity=bicycle_parkingNearest, secure
EV charging stationamenity=charging_stationNearest, compatible plug, available
pho near mecuisine=vietnameseNearest Vietnamese restaurant
coffee shopamenity=cafeNearest, open

The query has two parts: a category (what kind of thing) and an implicit location constraint (near where the user is, or near a specified place). The category is the hard part — the geocoder must map the user's words to a category taxonomy.

The category-taxonomy problem

"Gas station" in English maps to amenity=fuel in OSM's taxonomy. "Gas station" in Australian English ("servo") maps to the same tag. "Petrol station" in British English also maps to the same tag. The same physical thing — a place that sells fuel for vehicles — has multiple names, and the geocoder must recognize all of them.

The problem compounds across languages: ガソリンスタンド (gasorin sutando, Japanese), 加油站 (jiāyóuzhàn, Chinese), Tankstelle (German), station-service (French). Every language has its own word for "gas station." A geocoder that only recognizes English amenity names is useless for most of the world's population.

At first glance you'd expect the geocoder to translate here, rendering "gas station" into French before it searches. But translation is the wrong lens. "Gas station", "servo", Tankstelle, and station-service all point at one underlying category, the way English "road", Spanish "camino", and Japanese "通り" (do-ri) all name the same kind of thing. The geocoder maps each label to a shared, language-independent category (amenity=fuel) and searches that. Ask for a gas station or a servo, and it finds the same pumps.

How traditional geocoders handle amenity queries

Nominatim (OSM's geocoder) handles amenity queries well because OSM tags every amenity with a standardized key-value pair. amenity=fuel maps to every gas station in OSM. Nominatim's search API accepts free-text queries and matches them against OSM tags and names. gas station near Paris returns OSM-tagged fuel stations near Paris.

The limitation: Nominatim only searches OSM. If a gas station is not in OSM, it doesn't exist to Nominatim. OSM's amenity coverage is excellent in Western Europe and sparse in much of the rest of the world. A query for gas station in rural India may return nothing because no one has mapped the gas stations there.

Google's Places API handles amenity queries through Google's proprietary place taxonomy. The API accepts a type parameter (e.g., gas_station, atm, pharmacy) and returns ranked results. Google's taxonomy is larger and more consistent than OSM's, but it is proprietary — you cannot inspect how a category is defined, add new categories, or correct misclassifications.

Pelias has partial amenity support. Pelias indexes OSM amenities as part of its gazetteer and exposes a /v1/search endpoint with a categories parameter that maps to OSM tags (e.g., categories=food filters to amenity=restaurant/cafe/fast_food). For queries without the explicit parameter, Pelias tokenizes to [gas] [station] and searches the gazetteer by text — this works when an OSM feature's name or category text matches, but misses when the user's term differs from OSM's taxonomy. The category endpoint is the right idea but limited to a fixed set of mappings that doesn't cover regional variants or slang.

What Mailwoman does today

Mailwoman's parser will see gas station and try to classify the tokens as address components. The kind classifier (Stage 2.5) may recognize the input as a non-address query (no numbers, no street suffixes, no state abbreviations) and flag it as kind=unknown, but there is no kind=amenity classification path.

The resolver (Stage 6) indexes WOF administrative places, not OSM amenities. A search for gas station in the current resolver returns nothing — WOF does not have gas stations.

Amenity queries are out of scope for Mailwoman's current architecture. They require:

  • A category alias table mapping user-facing labels to OSM tags (or another taxonomy).
  • A POI index (OSM amenities, franchise locations, or a commercial dataset).
  • A proximity resolver that can answer "nearest X to location Y" queries.

These are planned for a future phase but are not part of the current implementation.

See also