updates on google app api key removal
This commit is contained in:
90
src/utils/addressSearch.js
Normal file
90
src/utils/addressSearch.js
Normal file
@@ -0,0 +1,90 @@
|
||||
// Free OSM Nominatim geocoder — replaces Google Places Autocomplete /
|
||||
// react-geocode across the console. No API key required. Nominatim's usage
|
||||
// policy caps the public endpoint at ~1 req/sec; Astryx's `Typeahead`
|
||||
// debounces queries internally (see `debounceMs` at each call site) and
|
||||
// `createAddressSearchSource` aborts any still-in-flight request whenever a
|
||||
// newer query supersedes it.
|
||||
const NOMINATIM_SEARCH_URL = 'https://nominatim.openstreetmap.org/search';
|
||||
|
||||
// Builds a Google-Places-shaped `address_components` array (each entry
|
||||
// `{ long_name, short_name, types: [] }`) from Nominatim's flat `address`
|
||||
// object, so existing call sites' `place.address_components.forEach(...)`
|
||||
// type-switch parsing keeps working unchanged.
|
||||
const buildAddressComponents = (addr = {}) => {
|
||||
const components = [];
|
||||
const push = (longName, types) => {
|
||||
if (longName) components.push({ long_name: longName, short_name: longName, types });
|
||||
};
|
||||
push(addr.house_number, ['street_number']);
|
||||
push(addr.road || addr.pedestrian, ['route']);
|
||||
push(addr.suburb || addr.neighbourhood || addr.quarter, ['sublocality_level_1', 'sublocality']);
|
||||
push(addr.city_district || addr.county, ['administrative_area_level_3']);
|
||||
push(addr.city || addr.town || addr.village, ['locality']);
|
||||
push(addr.state, ['administrative_area_level_1']);
|
||||
push(addr.country, ['country']);
|
||||
push(addr.postcode, ['postal_code']);
|
||||
return components;
|
||||
};
|
||||
|
||||
// Shapes a Nominatim result close enough to a Google Places `place` object
|
||||
// (name, formatted_address, geometry.location.lat()/lng(), address_components)
|
||||
// that call sites only needed mechanical edits, not rewrites, when swapping
|
||||
// off Google.
|
||||
export const toPlace = (result) => ({
|
||||
formatted_address: result.display_name,
|
||||
name: result.display_name?.split(',')[0] || '',
|
||||
geometry: {
|
||||
location: {
|
||||
lat: () => parseFloat(result.lat),
|
||||
lng: () => parseFloat(result.lon)
|
||||
}
|
||||
},
|
||||
address_components: buildAddressComponents(result.address)
|
||||
});
|
||||
|
||||
const buildParams = (query, bias) => {
|
||||
const params = new URLSearchParams({ q: query, format: 'json', addressdetails: '1', limit: '5' });
|
||||
if (bias?.lat && bias?.lng) {
|
||||
const d = 0.5; // ~55km box around the operator's zone — soft bias, not a hard filter
|
||||
params.set('viewbox', `${bias.lng - d},${bias.lat + d},${bias.lng + d},${bias.lat - d}`);
|
||||
}
|
||||
return params;
|
||||
};
|
||||
|
||||
// Builds a `SearchSource` for Astryx's `<Typeahead searchSource={...} />` —
|
||||
// each result is `{ id, label, auxiliaryData }` where `auxiliaryData` is the
|
||||
// `toPlace`-shaped object call sites parse via `address_components`.
|
||||
export function createAddressSearchSource({ bias } = {}) {
|
||||
let controller = null;
|
||||
return {
|
||||
async search(query) {
|
||||
if (!query) return [];
|
||||
controller?.abort();
|
||||
controller = new AbortController();
|
||||
try {
|
||||
const params = buildParams(query, bias);
|
||||
const res = await fetch(`${NOMINATIM_SEARCH_URL}?${params.toString()}`, {
|
||||
headers: { Accept: 'application/json' },
|
||||
signal: controller.signal
|
||||
});
|
||||
if (!res.ok) return [];
|
||||
const results = await res.json();
|
||||
return (results || []).map((result) => ({
|
||||
id: String(result.place_id),
|
||||
label: result.display_name,
|
||||
auxiliaryData: toPlace(result)
|
||||
}));
|
||||
} catch (err) {
|
||||
if (err.name === 'AbortError') return [];
|
||||
console.error('address search error:', err);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
bootstrap() {
|
||||
return [];
|
||||
},
|
||||
cancel() {
|
||||
controller?.abort();
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user