Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 4x 2x 4x 4x 3x 2x 2x 2x 1x 1x 1x 1x 1x 2x 2x 30x | import type { Logger } from 'pino';
import { logger as defaultLogger } from './logger.server';
export class NominatimGeocodingService {
/**
* Geocodes an address using the public Nominatim API.
* @param address The address string to geocode.
* @param logger A logger instance.
* @returns A promise that resolves to the coordinates or null if not found.
*/
async geocode(
address: string,
logger: Logger = defaultLogger,
): Promise<{ lat: number; lng: number } | null> {
const url = `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(address)}&format=json&limit=1`;
try {
const response = await fetch(url, { headers: { 'User-Agent': 'FlyerCrawler/1.0' } });
if (!response.ok) throw new Error(`Nominatim API returned status ${response.status}`);
const data = await response.json();
if (data && data.length > 0) {
const { lat, lon } = data[0];
logger.info(
{ address, result: { lat, lon } },
`[NominatimService] Successfully geocoded address`,
);
return { lat: parseFloat(lat), lng: parseFloat(lon) };
}
logger.warn({ address }, '[NominatimService] Geocoding failed or returned no results.');
return null;
} catch (error) {
logger.error(
{ err: error, address },
'[NominatimService] An error occurred while calling the Nominatim API.',
);
return null;
}
}
}
export const nominatimGeocodingService = new NominatimGeocodingService();
|