Last active
August 16, 2023 20:33
-
-
Save tcha-tcho/dcd1dc5ebafaa7ffba1c842cd3210d30 to your computer and use it in GitHub Desktop.
code to place on Pelias
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
const http = require('node:http'); | |
const url = require('url'); | |
function getData(req) { | |
return new Promise((resolve, reject) => { | |
const queryObject = url.parse(req.url, true).query; | |
let body = ''; | |
function res() { | |
resolve(Object.assign({}, JSON.parse(body||'{}'), queryObject)); | |
} | |
if (req.method === 'POST') { | |
req.on('data', function (data) { | |
body += data; | |
// Too much POST data, kill the connection! | |
// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB | |
if (body.length > 1e6) { | |
req.connection.destroy(); | |
} | |
}); | |
req.on('end', () => res()); | |
} else { | |
res(); | |
} | |
}); | |
} | |
function fetch(url, body) { | |
return new Promise( function (resolve, reject) { | |
function send(txt) { | |
resolve( txt[0] === "{" || txt[0] === "[" ? JSON.parse(txt) : txt ); | |
}; | |
http.get(url, (res) => { | |
const { statusCode } = res; | |
const contentType = res.headers['content-type']; | |
let error; | |
// Any 2xx status code signals a successful response but | |
// here we're only checking for 200. | |
if (statusCode !== 200) { | |
reject('Request Failed.\n' + | |
`Status Code: ${statusCode}`); | |
} else if (!/^application\/json/.test(contentType)) { | |
reject('Invalid content-type.\n' + | |
`Expected application/json but received ${contentType}`); | |
}; | |
if (error) { | |
console.error(error.message); | |
// Consume response data to free up memory | |
res.resume(); | |
return; | |
} | |
res.setEncoding('utf8'); | |
let rawData = ''; | |
res.on('data', (chunk) => { rawData += chunk; }); | |
res.on('end', () => { | |
try { | |
const parsedData = JSON.parse(rawData); | |
resolve(parsedData); | |
} catch (e) { | |
reject(e.message) | |
} | |
}); | |
}).on('error', (e) => { | |
reject(`Got error: ${e.message}`); | |
}); | |
}); | |
}; | |
const getAddress = (address, lat, lng, radius, pos) => { | |
radius = radius || 1; | |
return new Promise( function (resolve, reject) { | |
app.runMiddleware('/v1/search/structured',{query:{ | |
"address": address | |
,"boundary.circle.lat": lat | |
,"boundary.circle.lon": lng | |
,"boundary.circle.radius": radius | |
}},function(responseCode,body,headers){ | |
resolve(body) | |
}); | |
}) | |
// const query = `address=${address}&boundary.circle.lat=${lat} | |
// &boundary.circle.lon=${lng}&boundary.circle.radius=${radius}` | |
// return fetch(`http://49.13.0.204:4000/v1/search/structured?${query}`) | |
}; | |
const setInterpolationCache = (data) => { | |
// TODO: create this at Interpolation server | |
}; | |
const setAllAddresses = (data, cb) => { | |
let toSearch = {}; | |
for (let pos in data) { | |
if (data[pos].street && ( | |
typeof data[pos] !== "object" | |
|| !data[pos].city | |
|| data[pos].city == "no_city" | |
|| !data[pos].region | |
|| !data[pos].country | |
)) { | |
const arr = pos.split(","); | |
toSearch[data[pos].street] = [data[pos].street, arr[0]/*lat*/, arr[1]/*lat*/, undefined, pos]; | |
}; | |
}; | |
const keys = Object.keys(toSearch); | |
let len = keys.length; | |
if (len === 0) { | |
cb(data); | |
return; | |
} | |
keys.forEach(street => { | |
getAddress.apply({}, toSearch[street]).then(res => { | |
const pos = toSearch[street][4]; | |
const properties = res.features[0].properties; | |
// data[pos].district = properties; | |
data[pos].city = properties.county; | |
data[pos].region = properties.region_a || properties.region; | |
data[pos].country = properties.country_code || properties.country; | |
res.features[0].properties | |
// {"street":"avenida tiradentes","city":"no_city","district":null,"region":null,"maxspeed":"50"} | |
// > >>>>>>>>>>> -23.277854,-47.289813 { | |
// > id: 'polyline:51616', | |
// > gid: 'openstreetmap:street:polyline:51616', | |
// > layer: 'street', | |
// > source: 'openstreetmap', | |
// > source_id: 'polyline:51616', | |
// > country_code: 'BR', | |
// > name: 'Avenida Tiradentes', | |
// > street: 'Avenida Tiradentes', | |
// > confidence: 1, | |
// > match_type: 'exact', | |
// > accuracy: 'centroid', | |
// > country: 'Brazil', | |
// > country_gid: 'whosonfirst:country:85633009', | |
// > country_a: 'BRA', | |
// > macroregion: 'Southeast', | |
// > macroregion_gid: 'whosonfirst:macroregion:1511777411', | |
// > region: 'Sao Paulo', | |
// > region_gid: 'whosonfirst:region:85682041', | |
// > region_a: 'SP', | |
// > county: 'Itu', | |
// > county_gid: 'whosonfirst:county:102061603', | |
// > localadmin: 'Itu', | |
// > localadmin_gid: 'whosonfirst:localadmin:404566613', | |
// > locality: 'Itu', | |
// > locality_gid: 'whosonfirst:locality:101962741', | |
// > label: 'Avenida Tiradentes, Itu, SP, Brazil' | |
// > } | |
// setInterpolationCache(data[street]); | |
len--; | |
if (len <= 0) cb(data); | |
}); | |
}) | |
}; | |
const processBulk = async ( req, res ) => { | |
getData(req).then(data => { | |
if (!data.positions) { | |
data.positions = data.lat+','+data.lon | |
} | |
let positions = data.positions; | |
if (typeof positions === 'string') { | |
positions = positions.split(';'); | |
} | |
function ready(data) { | |
res.setHeader('Access-Control-Allow-Origin', '*'); | |
const cors = 'Origin, X-Requested-With, Content-Type, Accept'; | |
res.setHeader('Access-Control-Allow-Headers', cors); | |
setAllAddresses(data, function(all) { | |
res.json( all ); | |
}); | |
}; | |
let len = positions.length; | |
let count = 0; | |
// http://138.201.191.140:4300/street/bulk/geojson?positions=-23.277854,-47.289813 | |
const query = `positions=${data.positions}&first_match=true` | |
fetch(`http://138.201.191.140:4300/street/bulk/geojson?${query}`) | |
.then(ready).catch(e => console.error(e)) | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment