Last active
June 8, 2020 15:03
-
-
Save janbaykara/1e982b6af957c3e2b13849960799d2df to your computer and use it in GitHub Desktop.
Postcodes.io API batch consumer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(async () => { | |
const postcodeQueries = await bulk_postcode_geo(data.map(d => d.postcode).filter(Boolean)) | |
})() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fetch from 'node-fetch' | |
function chunk_array<T>(array: T[], chunk: number): T[] { | |
var i,j,temparray; | |
var arrayOfArrays = [] | |
for (i=0,j=array.length; i<j; i+=chunk) { | |
temparray = array.slice(i,i+chunk); | |
arrayOfArrays.push(temparray) | |
} | |
return arrayOfArrays | |
} | |
function batch_and_aggregate(arr_limit) { | |
return function decorator <OFn extends (...args: any) => any>(original_fn: OFn) { | |
return async function resulting_fn(arr) { | |
var batches = chunk_array(arr, arr_limit) | |
const results = await Promise.all<ReturnType<OFn>>(batches.map(batch => original_fn(batch))) | |
return results.reduce((arr, res) => arr.concat(res), []) | |
} | |
} | |
} | |
// const normalise_postcode = (str: string) => str.trim().replace(/ \s+/mig, '').toUpperCase() | |
export const bulk_postcode_geo = batch_and_aggregate(100)(async (postcodes) => { | |
// var postcodes = postcodes.map(normalise_postcode) | |
var response = await fetch('https://api.postcodes.io/postcodes', { | |
method: "POST", | |
body: JSON.stringify({ postcodes }), | |
headers: { 'Content-Type': 'application/json' } | |
}) | |
var status = response.status | |
var data = await response.json() as PostcodeBatchResult | |
var result = data.result | |
if (status !== 200 || !result) { | |
console.log(status, data, result) | |
throw new Error(`Failed to bulk geocode ${postcodes}`) | |
} | |
return result | |
}) | |
// | |
export interface PostcodeBatchResult { | |
status: number; | |
result: ResultElement[]; | |
} | |
export interface ResultElement { | |
query: string; | |
result: ResultResult; | |
} | |
export interface ResultResult { | |
postcode: string; | |
quality: number; | |
eastings: number; | |
northings: number; | |
country: string; | |
nhs_ha: string; | |
longitude: number; | |
latitude: number; | |
european_electoral_region: string; | |
primary_care_trust: string; | |
region: string; | |
lsoa: string; | |
msoa: string; | |
incode: string; | |
outcode: string; | |
parliamentary_constituency: string; | |
admin_district: string; | |
parish: string; | |
admin_county: null | string; | |
admin_ward: string; | |
ced: null | string; | |
ccg: string; | |
nuts: string; | |
codes: Codes; | |
} | |
export interface Codes { | |
admin_district: string; | |
admin_county: string; | |
admin_ward: string; | |
parish: string; | |
parliamentary_constituency: string; | |
ccg: string; | |
ccg_id: string; | |
ced: string; | |
nuts: string; | |
} |
Fuzzing logic
const [latitude, longitude] = offsetCoordinates([result.latitude, result.longitude], 500)
export const offsetCoordinates = (input: [number, number], offsetMeters = 100) => {
const [lat, lon] = input
//Earth’s radius, sphere
const R=6378137
//offsets in meters
const direction = Math.random() > 0.5 ? 1 : -1
const latitudeLean = Math.random()
const longitudeLean = 1 - latitudeLean
const dn = offsetMeters * latitudeLean * direction
const de = offsetMeters * longitudeLean * direction
//Coordinate offsets in radians
const dLat = dn / R
const dLon = de / (R * Math.cos (Math.PI *lat/180))
//OffsetPosition, decimal degrees
const latO = lat + dLat * 180/Math.PI
const lonO = lon + dLon * 180/Math.PI
const output = [latO, lonO]
return output
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
LRU consumer code: