Files
CheckTheethKids/lib/consultorios/geocoding_service.dart
Carlos Correia 89b27e5e86 CTK 1.1.0
2026-07-22 01:34:26 +01:00

53 lines
1.7 KiB
Dart

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;
}
}
}