export interface ParsedAddress { city: string; street: string; house: string; fullAddress: string; } const NOMINATIM_HEADERS = { 'User-Agent': 'LendryID/1.0 (contact@lendry.ru)', Accept: 'application/json' }; export async function reverseGeocode(lat: number, lng: number): Promise { try { const url = `https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${encodeURIComponent(String(lat))}&lon=${encodeURIComponent(String(lng))}&accept-language=ru`; const response = await fetch(url, { headers: NOMINATIM_HEADERS }); if (!response.ok) return null; const data = (await response.json()) as { display_name?: string; address?: Record; }; const addr = data.address ?? {}; const city = addr.city || addr.town || addr.village || addr.municipality || addr.state || ''; const street = addr.road || addr.pedestrian || addr.footway || addr.neighbourhood || ''; const house = addr.house_number || ''; return { city, street, house, fullAddress: data.display_name ?? formatParsed(city, street, house) }; } catch { return null; } } export async function forwardGeocode(query: string): Promise<{ lat: number; lng: number; parsed: ParsedAddress } | null> { const trimmed = query.trim(); if (!trimmed) return null; try { const url = `https://nominatim.openstreetmap.org/search?format=jsonv2&q=${encodeURIComponent(trimmed)}&limit=1&accept-language=ru`; const response = await fetch(url, { headers: NOMINATIM_HEADERS }); if (!response.ok) return null; const data = (await response.json()) as Array<{ lat: string; lon: string; display_name?: string; address?: Record; }>; const first = data[0]; if (!first) return null; const addr = first.address ?? {}; const city = addr.city || addr.town || addr.village || addr.municipality || ''; const street = addr.road || addr.pedestrian || ''; const house = addr.house_number || ''; return { lat: Number(first.lat), lng: Number(first.lon), parsed: { city, street, house, fullAddress: first.display_name ?? formatParsed(city, street, house) } }; } catch { return null; } } function formatParsed(city: string, street: string, house: string) { const parts = []; if (city) parts.push(`г. ${city}`); if (street || house) parts.push([street, house].filter(Boolean).join(', ')); return parts.join(', '); }