All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m30s
Deploy Trade-In / build-backend (push) Successful in 1m47s
Deploy Trade-In / deploy (push) Successful in 1m1s
33 lines
1.8 KiB
Python
33 lines
1.8 KiB
Python
"""Геометрические хелперы scraper_kit — чистая математика, без `app.*` / БД.
|
||
|
||
Strangler-копия (#2133) bbox-констант/предикатов из `app.services.geocoder`,
|
||
используемых скрапперами как ingest-guard (валидация координат detail-страниц
|
||
перед записью). Здесь — только чистые функции; продуктовый geocoder (Nominatim /
|
||
Yandex запросы, БД) НЕ копируется.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
# ЕКБ bbox = (lat_min, lat_max, lon_min, lon_max).
|
||
# TIGHT — центр агломерации; WIDE — с приграничьем, но всё ещё отсекает
|
||
# Питер/Тюмень/Уфу (#1871). WIDE строго содержит TIGHT.
|
||
EKB_BBOX_TIGHT = (56.65, 56.95, 60.40, 60.85)
|
||
EKB_BBOX_WIDE = (56.6, 57.1, 60.3, 60.9)
|
||
|
||
|
||
def is_within_ekb_bbox(
|
||
lat: float, lon: float, bbox: tuple[float, float, float, float] = EKB_BBOX_TIGHT
|
||
) -> bool:
|
||
"""True если (lat, lon) внутри bbox (inclusive). bbox = (lat_min, lat_max, lon_min, lon_max)."""
|
||
lat_min, lat_max, lon_min, lon_max = bbox
|
||
return lat_min <= lat <= lat_max and lon_min <= lon <= lon_max
|
||
|
||
|
||
def is_within_ekb_bbox_wide(lat: float, lon: float) -> bool:
|
||
"""Ingest-guard: True если координаты в широком ЕКБ-bbox (#1871).
|
||
|
||
Используется для валидации координат из avito detail-страниц перед записью в БД.
|
||
Шире geocoder-tight, поэтому не режет легитимное приграничье, но отсекает не-ЕКБ
|
||
(Питер/Тюмень/Уфа).
|
||
"""
|
||
return is_within_ekb_bbox(lat, lon, EKB_BBOX_WIDE)
|