fix(etl): гео-проход — префикс «г Екатеринбург» адресам без города (#2177 остаток) #2245
2 changed files with 34 additions and 2 deletions
|
|
@ -841,14 +841,21 @@ def find_geo_matches(db: Session, *, max_distance_m: float = GEO_MAX_DISTANCE_M)
|
|||
geo_cache: dict[str, tuple[float, float] | None] = {}
|
||||
|
||||
def _geocode(addr: str) -> tuple[float, float] | None:
|
||||
"""Геокод с кэшем + лимитом вызовов. None при отсутствии/лимите."""
|
||||
"""Геокод с кэшем + лимитом вызовов. None при отсутствии/лимите.
|
||||
|
||||
Адреса objective_lots идут БЕЗ города («ул. Гидрострой, д. 2а») —
|
||||
DaData на таком отдаёт qc_geo=5 (нет координат): прод-прогон 2026-07-03
|
||||
дал confirmed=0/45 именно из-за этого. Объектив покрывает только ЕКБ →
|
||||
безопасно префиксуем городом, если его нет в строке.
|
||||
"""
|
||||
if addr in geo_cache:
|
||||
return geo_cache[addr]
|
||||
if report.dadata_calls >= GEO_DADATA_CALL_LIMIT:
|
||||
report.call_limit_hit = True
|
||||
return None
|
||||
query = addr if "екатеринбург" in addr.lower() else f"г Екатеринбург, {addr}"
|
||||
report.dadata_calls += 1
|
||||
coords = clean_address(addr)
|
||||
coords = clean_address(query)
|
||||
geo_cache[addr] = coords
|
||||
return coords
|
||||
|
||||
|
|
|
|||
|
|
@ -598,6 +598,31 @@ def test_geo_ambiguous_resolves_to_nearest() -> None:
|
|||
assert abs(gm.distance_m - 150.0) < 10.0
|
||||
|
||||
|
||||
def test_geo_geocode_prefixes_city_when_missing() -> None:
|
||||
"""Адреса без города префиксуются «г Екатеринбург, » перед DaData (qc_geo=5 фикс);
|
||||
адрес с городом уходит как есть."""
|
||||
near_lat, near_lon = _offset_coords(_DOMRF_LAT, _DOMRF_LON, 100.0)
|
||||
calls: list[str] = []
|
||||
|
||||
mock_db = _make_geo_db(
|
||||
objective_rows=[("Уникальный", ["Девелопер"], 7001)],
|
||||
taken_names=[],
|
||||
domrf_rows=[(301, 'ЖК "Уникальный"', "ООО Другой")],
|
||||
address_rows=[("Уникальный", "ул. Гидрострой, д. 2а")],
|
||||
coord_rows=[(301, _DOMRF_LAT, _DOMRF_LON)],
|
||||
)
|
||||
|
||||
def _fake_geocode(addr: str) -> tuple[float, float]:
|
||||
calls.append(addr)
|
||||
return (near_lat, near_lon)
|
||||
|
||||
with patch(_CLEAN_ADDRESS_PATH, side_effect=_fake_geocode):
|
||||
report = find_geo_matches(mock_db, max_distance_m=500)
|
||||
|
||||
assert calls == ["г Екатеринбург, ул. Гидрострой, д. 2а"]
|
||||
assert len(report.confirmed) == 1
|
||||
|
||||
|
||||
def test_geo_ambiguous_partial_geocode_does_not_blind_confirm() -> None:
|
||||
"""ambiguous, один кандидат геокодится в 100 м, второй НЕ геокодится вовсе →
|
||||
НЕ confirm (reject partial_geocode): «один в радиусе» — артефакт отсутствия
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue