import 'dart:convert'; import 'package:http/http.dart' as http; /// Geocoding de moradas via Nominatim (OpenStreetMap) — converte texto /// livre em coordenadas. Serviço gratuito e público; a política de uso da /// Nominatim exige no máximo ~1 pedido/segundo e um `User-Agent` /// identificável, por isso só chamamos isto quando o utilizador guarda a /// morada (nunca em cada abertura de ecrã). class GeocodingService { const GeocodingService._(); static const String _endpoint = 'https://nominatim.openstreetmap.org/search'; static const String _userAgent = 'CheckTeethKids/1.0 (caducorreia740@gmail.com)'; /// Devolve as coordenadas da morada, ou `null` se a Nominatim não /// encontrar nenhum resultado, a ligação falhar ou expirar o tempo /// limite — quem chama decide como reagir (ex.: mostrar erro no campo). static Future<({double lat, double lon})?> geocodeAddress( String address, ) async { final uri = Uri.parse(_endpoint).replace( queryParameters: { 'q': address, 'format': 'jsonv2', 'limit': '1', }, ); try { final response = await http .get(uri, headers: {'User-Agent': _userAgent}) .timeout(const Duration(seconds: 12)); if (response.statusCode != 200) return null; final results = jsonDecode(response.body); if (results is! List || results.isEmpty) return null; final first = results.first; if (first is! Map) return null; final lat = double.tryParse('${first['lat']}'); final lon = double.tryParse('${first['lon']}'); if (lat == null || lon == null) return null; return (lat: lat, lon: lon); } catch (_) { return null; } } }