From e07206fad0caf6064a68cf145258a8915496b965 Mon Sep 17 00:00:00 2001 From: Jack Greenlee Date: Mon, 19 Aug 2024 01:23:23 -0400 Subject: [PATCH] use the server-side geocoded addresses for place names Since the server now fills in geocoded_address (we may later change this to reverse_geocode), we will only need to perform a client-side nominatim request for unprocessed trips. If either field is present, we'll use that; otherwise schedule a request like before. Updated types: -Since the CompositeTrip type definition is based on the return type of Timeline.readAllCompositeTrips, which is after "unpacking", start_confirmed_place and end_confirmed_place are simply ConfirmedPlace, not BEMData -ConfirmedPlace.location is a `Point`, (having `coordinates`) not just a generic `Geometry` -added geocoded_address and reverse_geocode, both as optional since it depends on https://github.com/e-mission/e-mission-server/pull/973 --- www/js/diary/addressNamesHelper.ts | 31 +++++++++++++++++++++++++++--- www/js/types/diaryTypes.ts | 12 +++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/www/js/diary/addressNamesHelper.ts b/www/js/diary/addressNamesHelper.ts index de3db47ea..8e157900b 100644 --- a/www/js/diary/addressNamesHelper.ts +++ b/www/js/diary/addressNamesHelper.ts @@ -77,6 +77,23 @@ import Bottleneck from 'bottleneck'; import { displayError, logDebug } from '../plugin/logger'; import { CompositeTrip } from '../types/diaryTypes'; +export type NominatimResponse = { + address: { + road?: string; + pedestrian?: string; + suburb?: string; + neighbourhood?: string; + hamlet?: string; + city?: string; + town?: string; + county?: string; + state?: string; + postcode?: string; + country?: string; + country_code?: string; + }; +}; + let nominatimLimiter = new Bottleneck({ maxConcurrent: 2, minTime: 500 }); export const resetNominatimLimiter = () => { const newLimiter = new Bottleneck({ maxConcurrent: 2, minTime: 500 }); @@ -128,7 +145,7 @@ async function fetchNominatimLocName(loc_geojson) { status = ${response.status}; data = ${JSON.stringify(data)}`); localStorage.setItem(coordsStr, JSON.stringify(data)); - publish(coordsStr, data); + publish(coordsStr, JSON.stringify(data)); } catch (error) { if (!nominatimError) { nominatimError = error; @@ -139,8 +156,16 @@ async function fetchNominatimLocName(loc_geojson) { // Schedules nominatim fetches for the start and end locations of a trip export function fillLocationNamesOfTrip(trip: CompositeTrip) { - nominatimLimiter.schedule(() => fetchNominatimLocName(trip.end_loc)); - nominatimLimiter.schedule(() => fetchNominatimLocName(trip.start_loc)); + [trip.start_confirmed_place, trip.end_confirmed_place].forEach((place) => { + if (place?.geocoded_address || place?.reverse_geocode) { + const coordsStr = place.location.coordinates.toString(); + const data = place.reverse_geocode || { address: place.geocoded_address }; + localStorage.setItem(coordsStr, JSON.stringify(data)); + publish(coordsStr, JSON.stringify(data)); + } else { + nominatimLimiter.schedule(() => fetchNominatimLocName(place.location)); + } + }); } // a React hook that takes a trip or place and returns an array of its address names diff --git a/www/js/types/diaryTypes.ts b/www/js/types/diaryTypes.ts index 53b618be0..c959dc944 100644 --- a/www/js/types/diaryTypes.ts +++ b/www/js/types/diaryTypes.ts @@ -2,6 +2,7 @@ and user input objects. As much as possible, these types parallel the types used in the server code. */ +import { NominatimResponse } from '../diary/addressNamesHelper'; import { BaseModeKey, MotionTypeKey } from '../diary/diaryHelper'; import useDerivedProperties from '../diary/useDerivedProperties'; import { VehicleIdentity } from './appConfigTypes'; @@ -32,8 +33,13 @@ export type ConfirmedPlace = { exit_fmt_time: string; // ISO string e.g. 2023-10-31T12:00:00.000-04:00 exit_local_dt: LocalDt; exit_ts: number; // Unix timestamp + + // one of these depending on what we decide to keep on the server + geocoded_address?: NominatimResponse['address']; + reverse_geocode?: NominatimResponse; + key: string; - location: Geometry; + location: Point; origin_key: string; raw_places: ObjectId[]; source: string; @@ -96,7 +102,7 @@ export type CompositeTrip = { confirmed_trip: ObjectId; distance: number; duration: number; - end_confirmed_place: BEMData; + end_confirmed_place: ConfirmedPlace; end_fmt_time: string; end_loc: Point; end_local_dt: LocalDt; @@ -113,7 +119,7 @@ export type CompositeTrip = { raw_trip: ObjectId; sections: SectionData[]; source: string; - start_confirmed_place: BEMData; + start_confirmed_place: ConfirmedPlace; start_fmt_time: string; start_loc: Point; start_local_dt: LocalDt;