My Google Summer of Code 2026 project was Category Support in Nominatim.
The goal was to replace Nominatim’s single class/type representation with a proper categories field so that one OSM object can carry multiple categories. For eg, an object tagged as both a hotel and a restaurant can now be represented in one row with categories such as:
osm.tourism.hotel
osm.amenity.restaurant
What was completed
- Added the PostgreSQL
ltree[]categories column to the main Nominatim tables. - Generated multiple categories from OSM tags during import while keeping the existing
classandtypefields for compatibility. - Updated ranking, triggers, migrations, and related database logic to use categories.
- Replaced the old
place_classtype_*search tables with category-based search using indexed queries. - Removed the old
place_classtype_*table creation and maintenance code. - Added category filters to the search API.
- Updated the SQLite adaptor and tests for category data.
- Updated the documentation for the category system and its API behaviour.
Pull requests
- #4106: Add ltree categories column for multi-tag OSM object support - merged
- #4146: Use ltree categories column instead of place_classtype tables - merged
- #4163: Remove the place_classtype tables - merged
- #4164: Add category filters to the search API - merged
- #4166: Update the documentation for the category series - documentation PR
Querying by category
The search API can now accept category filters. For example:
/search?q=restaurant+Berlin&include=osm.amenity.restaurant
/search?q=Berlin&include=osm.amenity
/search?q=hotel+Berlin&include=osm.tourism.hotel&include=osm.amenity.restaurant
/search?q=restaurant+Berlin&exclude=osm.amenity.fast_food
A parent category such as osm.amenity can match categories below it, so a query can include restaurants, cafes, bars, and other amenities without listing every child category separately.




