Plain-language parcel search
The flagship of the Zonio platform is search in the user's own words. It is available as the search_parcels MCP tool and as POST /search/natural-language in the REST API.
"Flat plots over 2 ha near Rzeszów, zoned for industry,
within 5 km of a 110 kV substation and outside Natura 2000"
How a query is answered
Understand
A language model trained on Polish planning vocabulary extracts the region, the asset type, and every criterion. It knows that "zoned for industry" means MPZP categories P, PU and P/U, that "flat" is a slope threshold, that "near the A4" is a distance to a specific road, and that "bez Natury" means outside Natura 2000.
Ground
Every named thing is resolved against the database, never guessed: places to TERYT codes (asking when "Ostrów" is ambiguous), roads and substations to features, zone words to the normalised zoning taxonomy. If the request matches a scenario, the scenario's legal criteria are added: for a large PV farm on farmland, for example, the soil-class rules.
Compile
The interpretation becomes the same structured request you could send to POST /search/parcels: hard filters, ranking signals and weights. No SQL is ever generated by the model; filters come from a fixed, tested catalogue.
Search
The query runs on PostGIS in EPSG:2180 with spatial indexes, walking candidates largest-first and stopping early, so a national search typically returns in under two seconds.
Explain
The response carries the interpretation, the assumptions that were made, a why list for each result, and the coverage of every criterion. The agent can show the user exactly what was searched and offer to adjust it.
The interpretation is part of the answer
"interpretation": {
"region": { "teryt": "1863", "name": "Rzeszów", "unit_type": "powiat" },
"scenario": null,
"request": {
"region": "1863",
"filters": {
"area_sqm": { "min": 20000 },
"zoning": { "categories": ["industrial", "commercial_services"] },
"slope_pct": { "max": 5 },
"near": [{ "layer": "power_substations", "within_m": 5000, "where": { "voltage_kv_gte": 110 } }],
"exclude": [{ "layer": "env_layers", "kinds": ["natura2000"], "buffer_m": 0 }]
}
},
"assumptions": [
"\"near Rzeszów\" was read as powiat Rzeszów (1816) plus the city (1863).",
"\"flat\" was read as mean slope ≤ 5 %."
]
}Your application can replay interpretation.request against POST /search/parcels to page, tweak a slider or save the search, deterministically and without another model call.
What it understands
| Users say | Zonio searches |
|---|---|
| "buildable", "pod zabudowę" | Residential / service MPZP zones, or Plan Ogólny zones that allow building |
| "flat", "płaska" | Mean slope ≤ 5 % (tunable) |
| "empty", "vacant", "niezabudowana" | No BDOT10k building footprint |
| "near a substation", "blisko GPZ" | ≤ 10 km to a substation ≥ 110 kV |
| "with grid capacity" | DSO-published available capacity ≥ requested MW |
| "near public transport" | ≤ 800 m to a stop |
| "no protected nature" | Outside Natura 2000, national/landscape parks, reserves |
| "not in a flood zone" | Outside 1 % and 0.2 % flood-risk areas |
| "cheap" | Ranked by median RCN price per m² in the gmina |
| "state-owned", "KOWR" | Overlaps KOWR agricultural property stock |
| "for a data centre", "for BESS", … | The matching scenario |
Writing good queries
- Name the place. A voivodeship, powiat or gmina keeps results relevant; without one, the whole country is searched.
- Give numbers when you have them. "Over 2 ha" beats "large".
- Say what the land is for. "For a 5 MW PV farm" adds the legal criteria that matter for that asset.
- Read the coverage. A criterion marked
missingwas not checked in that region, so treat matches as unscreened on it.