Return nearest parish/polygon for points in the sea near the coast

When a point falls in the sea within a country boundary (e.g. Scotland
Q22 or England Q21) but not within any specific parish, find the nearest
civil parish or high-admin-level polygon within ~0.15 degrees (~10-17km).

- Add get_nearest_scotland_code() for Scottish civil parishes
- Add Polygon.nearest() for general OSM polygon lookup
- Use .limit(1).scalar() in scotland.py for cleaner returns
This commit is contained in:
Edward Betts 2026-02-12 18:19:17 +00:00
parent 7235df4cad
commit 90b009fc90
3 changed files with 74 additions and 3 deletions

View file

@ -136,6 +136,36 @@ def lat_lon_to_wikidata(lat: float, lon: float) -> dict[str, typing.Any]:
if admin_level >= 7:
return {"elements": elements, "result": result}
# Point is in Scotland but not in a specific parish — try nearest parish
if result.get("wikidata") == "Q22":
nearby_code = scotland.get_nearest_scotland_code(lat, lon)
if nearby_code:
rows = wikidata.lookup_scottish_parish_in_wikidata(nearby_code)
add_missing_commons_cat(rows)
hit = wikidata.commons_from_rows(rows)
if hit:
nearby_result = wikidata.build_dict(hit, lat, lon)
if not nearby_result.get("missing"):
return {"elements": elements, "result": nearby_result}
# Point is in a broad area (e.g. country) — try nearest specific polygon
nearby = model.Polygon.nearest(lat, lon)
if nearby and nearby.tags:
tags: typing.Mapping[str, str] = nearby.tags
al = get_admin_level(tags)
hit = (
hit_from_wikidata_tag(tags)
or hit_from_ref_gss_tag(tags)
or hit_from_name(tags, lat, lon)
)
if hit:
hit["admin_level"] = al
hit["element"] = nearby.osm_id
hit["geojson"] = typing.cast(str, nearby.geojson_str)
nearby_result = wikidata.build_dict(hit, lat, lon)
if not nearby_result.get("missing"):
return {"elements": elements, "result": nearby_result}
row = wikidata.geosearch(lat, lon)
if row:
hit = wikidata.commons_from_rows([row])