mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
feat(search): compose Google and Photon through an explicit provider service
This commit is contained in:
commit
57d7f9fc23
30 files changed
+1621
-151
No files matched your search
@@ -0,0 +1,66 @@
|
||||
/** Normalize a Google forward-geocode result without leaking its address shape. */
|
||||
export function normalizeGooglePlace(result) {
|
||||
const lat = result?.geometry?.location?.lat;
|
||||
const lng = result?.geometry?.location?.lng;
|
||||
if (
|
||||
!Number.isFinite(lat) ||
|
||||
!Number.isFinite(lng) ||
|
||||
Math.abs(lat) > 90 ||
|
||||
Math.abs(lng) > 180
|
||||
)
|
||||
return null;
|
||||
const types = Array.isArray(result.types) ? result.types : [];
|
||||
const resultTypes = new Set(types.map((type) => String(type).toLowerCase()));
|
||||
const components = Array.isArray(result.address_components)
|
||||
? result.address_components
|
||||
: [];
|
||||
// Address-only landmark results must retain the requested landmark identity.
|
||||
const canonical = components.find(
|
||||
(component) =>
|
||||
Array.isArray(component.types) &&
|
||||
component.types.some(
|
||||
(type) =>
|
||||
type !== 'political' && resultTypes.has(String(type).toLowerCase()),
|
||||
),
|
||||
);
|
||||
return {
|
||||
lat,
|
||||
lng,
|
||||
name: canonical?.long_name || '',
|
||||
label: result.formatted_address || '',
|
||||
types,
|
||||
viewport: result.geometry.bounds || result.geometry.viewport || null,
|
||||
};
|
||||
}
|
||||
|
||||
/** Construct Google geocoding with caller-owned transport and key selection. */
|
||||
export function createGoogleGeocoder({ request }) {
|
||||
return {
|
||||
async geocode(query, { bias = null, signal } = {}) {
|
||||
signal?.throwIfAborted();
|
||||
try {
|
||||
const response = await request(query, { bias, signal });
|
||||
signal?.throwIfAborted();
|
||||
// An unconfigured provider did not contribute a negative verdict.
|
||||
if (!response) return { place: null, answered: true };
|
||||
if (response.ok === false) return { place: null, answered: false };
|
||||
const data = await response.json();
|
||||
signal?.throwIfAborted();
|
||||
if (
|
||||
data?.status === 'ZERO_RESULTS' &&
|
||||
Array.isArray(data.results) &&
|
||||
data.results.length === 0
|
||||
)
|
||||
return { place: null, answered: true };
|
||||
const place =
|
||||
data?.status === 'OK'
|
||||
? normalizeGooglePlace(data.results?.[0])
|
||||
: null;
|
||||
return { place, answered: Boolean(place) };
|
||||
} catch {
|
||||
signal?.throwIfAborted();
|
||||
return { place: null, answered: false };
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user