---
title: "Places and Geo Search · RUAL Documentation"
description: "Search the built-in places dataset, filter by proximity and enrich your own documents with it."
canonical: https://docs.rual.nl/blueprints/places
language: en
---

# Places and Geo Search

Search the built-in places dataset, ask radius and map questions, filter your own documents by what is nearby, and enrich them with it. All offline, against data shipped with the node.

The `places_*` and `geo_point_*` blocks answer location questions against datasets on the node itself: no API keys, no per-call cost, no request leaving the building. Lookups are fast enough to run inside loops and over whole inventories. This guide covers the search and filtering flow; [Location Blocks](https://docs.rual.nl/reference/location-blocks) lists every block with its pins, and [`places_dataset_info`](https://docs.rual.nl/block-types/places/places_dataset_info) tells you which dataset release your node serves and whether it is `loaded` at all.

### 1. Text Search

[`places_search`](https://docs.rual.nl/block-types/places/places_search) (search places) is the one search box over both points of interest and settlements. It handles accents (`Bréda` finds `Breda`), typos (`amsterdm centraal`), and partial words as the user types, and collapses duplicate records from the source data. The outputs are a ranked `results` array, the `best` match and a `count`.

- `near` plus `bias_radius_m` biases ranking toward a point without excluding anything farther away.

- `limit`, `typo_tolerance` and `min_confidence` tune how much comes back and how forgiving the matching is.

- `kinds` and `categories` restrict the search to points of interest, settlements, or specific category groups.

A typed query, typos and all, goes into [search places](https://docs.rual.nl/block-types/places/places_search). A [from city](https://docs.rual.nl/block-types/geopoint/geo_point_from_city) point biases the ranking toward Breda, a [number](https://docs.rual.nl/block-types/number/number_default) caps the result count, and [get fields](https://docs.rual.nl/block-types/object/object_field_getter_multiple) reads the name off the best match for the reply.

![Studio canvas example for the search places block: one search box over every place.](https://docs.rual.nl/canvas-examples/places_search.png)

### 2. Radius and Map Questions

Three blocks answer "what is here", each for a different question:

| Block | Answers | Notes |
| --- | --- | --- |
| [`places_nearest`](https://docs.rual.nl/block-types/places/places_nearest) (nearest places) | The closest points of interest to a geo point, ordered by distance, each with its distance in metres. | Leave `max_distance` empty for an unbounded search and apply your own cutoff later. |
| [`places_within`](https://docs.rual.nl/block-types/places/places_within) (places within radius) | Every point of interest inside a radius, nearest first. | Compare `count` with `raw_count` to see how much duplication the source data carries at that spot; `truncated` flags a capped result. |
| [`places_in_bbox`](https://docs.rual.nl/block-types/places/places_in_bbox) (places in bounding box) | Every point of interest inside a bounding box: the block for rendering what is currently on a map screen. | Results carry no distance (a box has no query point); use the nearest block when you need distances. |

### 3. Categories

The source dataset ships roughly 1700 raw categories, far too many to show a user, so they are folded into curated groups with Dutch and English labels. [`places_categories`](https://docs.rual.nl/block-types/places/places_categories) (list place categories) lists those groups, the block to build a category dropdown from. [`places_resolve_category`](https://docs.rual.nl/block-types/places/places_resolve_category) (resolve place category) goes the other way: free text such as `kroeg` or `supermarkt` becomes a category group id, with a `confidence` score and `alternatives` when a word spans several groups. Plurals are handled, so `kroegen` and `bars` just work.

### 4. Typed Filters, From Sentence to Result

[`places_parse_query`](https://docs.rual.nl/block-types/places/places_parse_query) (parse places query) turns typed Dutch or English into a structured filter: `binnen 300m van een basisschool` becomes a proximity filter, `niet bij scholen` a negated one, `minimaal 3 kroegen binnen 500m` carries a minimum count. Two blocks consume that filter:

- [`places_match`](https://docs.rual.nl/block-types/places/places_match) (match places filter) tests one geo point against the filter. Its `distance_m` and `count` come back even when nothing matched, so you can re-answer a different radius without another call.

- [`places_filter`](https://docs.rual.nl/block-types/places/places_filter) (filter by places) keeps or removes items of a whole list by the filter, reading each item's point from `point_path`. With `annotate` it writes the distance onto each item instead of removing anything.

### 5. Enrich and Facet Your Own Documents

[`places_enrich`](https://docs.rual.nl/block-types/places/places_enrich) (enrich with nearby places) adds the nearest place per category to every item in a list in one call, no iterator needed. The usual pipeline: query your documents with [`function_search`](https://docs.rual.nl/block-types/storage/function_search), run the enrich block, then write the result back with [`mutations_set_bp_field_multiple`](https://docs.rual.nl/block-types/mutations/mutations_set_bp_field_multiple) and [`function_update_document_mutations`](https://docs.rual.nl/block-types/storage/function_update_document_mutations). After that an ordinary range query filters on the stored distances, and the expensive proximity work happens once per document instead of once per page view.

[`places_facet`](https://docs.rual.nl/block-types/places/places_facet) (facet counts by places) answers "412 properties near a hospital" in one block: it counts how many items of a list are near each category. An item with three hospitals nearby still counts once, which is what a facet over your own inventory means. [`places_density`](https://docs.rual.nl/block-types/places/places_density) (place density) profiles a single spot instead: totals, per km², and a classification.

### 6. Geo Point Helpers

Every places block takes or returns a `geo_point`. The helpers create, check and resolve them:

- [`geo_point_lat_lng_to_point`](https://docs.rual.nl/block-types/geopoint/geo_point_lat_lng_to_point) builds a point from two numbers; [`geo_point_to_lat_lng`](https://docs.rual.nl/block-types/geopoint/geo_point_to_lat_lng) splits one back out.

- [`geo_point_from_city`](https://docs.rual.nl/block-types/geopoint/geo_point_from_city) resolves a city name to its centre point plus radius, optionally constrained by country code and province.

- [`geo_point_reverse_geocode`](https://docs.rual.nl/block-types/geopoint/geo_point_reverse_geocode) resolves a point to the nearest street, city, province and country.

- [`geo_point_snap`](https://docs.rual.nl/block-types/geopoint/geo_point_snap) pins a point onto the nearest road or railway and reports how far it moved; [`geo_point_nearby`](https://docs.rual.nl/block-types/geopoint/geo_point_nearby) checks whether such a network is within a given distance.

- [`geo_point_validate`](https://docs.rual.nl/block-types/geopoint/geo_point_validate) checks a point holds a valid latitude and longitude before you trust it.

### Notes From Practice

- Store a place id when you want to refer to it later and re-resolve it with [`places_get`](https://docs.rual.nl/block-types/places/places_get) (get place by id). Branch on its `found` pin: an id can disappear between dataset releases, and not finding it is a successful lookup, not an error.

- Results carry a confidence; raising `min_confidence` trades recall for precision on messy source data.

- All of this runs offline, so there is no rate limit to design around. The cost is dataset freshness: check the release with the dataset info block when results look stale.

### Frequently asked

**Does the RUAL places search need an API key?**

No. The places blocks run offline against an Overture dataset shipped with the node, so there is no API key, no rate limit and no per-call cost, and lookups are fast enough to run inside loops.

**How do I search places by typed text in RUAL?**

Use places_search. One search box covers points of interest and settlements, tolerates typos and accents, and can bias results toward a geo point without excluding farther matches. The results array, the best match and a count come back ranked.

**How do I filter my own documents by nearby places in RUAL?**

Turn a typed sentence into a filter with places_parse_query, then apply it with places_filter to keep or remove items of a list, or places_match to test a single point. To make the result queryable later, run places_enrich once and write the nearest-place distances back onto the documents.
