Skip to content

Instantly share code, notes, and snippets.

@tcha-tcho
Last active August 16, 2023 20:33
Show Gist options
  • Save tcha-tcho/dcd1dc5ebafaa7ffba1c842cd3210d30 to your computer and use it in GitHub Desktop.
Save tcha-tcho/dcd1dc5ebafaa7ffba1c842cd3210d30 to your computer and use it in GitHub Desktop.
code to place on Pelias
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