From bb67c78163bff98652d0812be6062119836a25a2 Mon Sep 17 00:00:00 2001 From: Matthew Oslan Date: Sat, 6 Jun 2020 15:57:16 -0400 Subject: [PATCH] Add geocoder cache --- .gitignore | 1 + routes/geocoders/Geocoder.ts | 40 +++++++++++++++++++++++++++++++++++- routes/weather.ts | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5952f55..2afc654 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ baselineEToData/*.png baselineEToData/*.tif baselineEToData/dataPreparer[.exe] observations.json +geocoderCache.json diff --git a/routes/geocoders/Geocoder.ts b/routes/geocoders/Geocoder.ts index 44640b0..80e5c6d 100644 --- a/routes/geocoders/Geocoder.ts +++ b/routes/geocoders/Geocoder.ts @@ -1,11 +1,49 @@ +import fs = require("fs"); + import { GeoCoordinates } from "../../types"; export abstract class Geocoder { + + private static cacheFile: string = __dirname + "/../../../geocoderCache.json"; + + private cache: Map; + + public constructor() { + // Load the cache from disk. + if ( fs.existsSync( Geocoder.cacheFile ) ) { + this.cache = new Map( JSON.parse( fs.readFileSync( Geocoder.cacheFile, "utf-8" ) ) ); + } else { + this.cache = new Map(); + } + + // Write the cache to disk every 5 minutes. + setInterval( () => { + this.saveCache(); + }, 5 * 60 * 1000 ); + } + + private saveCache(): void { + fs.writeFileSync( Geocoder.cacheFile, JSON.stringify( Array.from( this.cache.entries() ) ) ); + } + /** * Converts a location name to geographic coordinates. * @param location A location name. * @return A Promise that will be resolved with the GeoCoordinates of the specified location, or rejected with a * CodedError. */ - public abstract geocodeLocation( location: string ): Promise; + protected abstract geocodeLocation( location: string ): Promise; + + /** + * Converts a location name to geographic coordinates, first checking the cache and updating it if necessary. + */ + public async getLocation( location: string ): Promise { + if ( this.cache.has( location ) ) { + return this.cache.get( location ); + } + + const coords: GeoCoordinates = await this.geocodeLocation( location ); + this.cache.set( location, coords ); + return coords; + } } diff --git a/routes/weather.ts b/routes/weather.ts index 591b921..0afe94e 100644 --- a/routes/weather.ts +++ b/routes/weather.ts @@ -57,7 +57,7 @@ export async function resolveCoordinates( location: string ): Promise< GeoCoordi const split: string[] = location.split( "," ); return [ parseFloat( split[ 0 ] ), parseFloat( split[ 1 ] ) ]; } else { - return GEOCODER.geocodeLocation( location ); + return GEOCODER.getLocation( location ); } }