overpassql/fixes/fix_elevation.js

68 lines
2.6 KiB
JavaScript

/**
* Usage:
*
* node fix_elevation.js <OSM_RELATION_ID> [<ELEVATION_THRESHOLD>]
*
* Examples:
* node fix_elevation.js 349001
* node fix_elevation.js 349014 150
*/
const [, , area, THRESHOLD = 50] = process.argv
const DEFAULT_DECIMALS = 6
const ELEVATION_API = 'https://api.open-elevation.com/api/v1/lookup'
// const ELEVATION_API = 'http://0.0.0.0/api/v1/lookup'
const OVERPASS_API = 'https://overpass-api.de/api/interpreter'
const OVERPASS_QUERY = `[out:json][timeout:25];area(id:${36e8 + +area})->.searchArea;node["ele"](area.searchArea);out;`
function round (num, decimalPlaces = DEFAULT_DECIMALS) {
const p = Math.pow(10, decimalPlaces)
const n = (num * p) * (1 + Number.EPSILON)
return Math.round(n) / p
}
async function main () {
const { elements } = await fetch(OVERPASS_API, {
method: 'post',
body: 'data=' + encodeURIComponent(OVERPASS_QUERY),
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
}
}).then(response => response.ok && response.json())
if (!elements) return console.error(`No elements found from ${OVERPASS_API}`)
// prepare POST data request: https://github.com/Jorl17/open-elevation/blob/master/docs/api.md#post-apiv1lookup
const locations = elements.map(x => ({ latitude: round(x.lat), longitude: round(x.lon) }))
const { results } = await fetch(ELEVATION_API, {
method: 'post',
body: JSON.stringify({ locations }),
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
}
}).then(response => response.ok && response.json())
if (!results) return console.error(`No results found from ${ELEVATION_API}`)
const errors = elements.reduce((acc, x) => {
const t = results.find(y => y.latitude === round(+x.lat) && y.longitude === round(+x.lon))
if (!t) return acc
if (+x.tags.ele + +THRESHOLD >= +t.elevation && +x.tags.ele - +THRESHOLD <= +t.elevation) return acc
return [...acc, { osm: +x.tags.ele, strm: t.elevation, error: (Math.abs(t.elevation - +x.tags.ele) / t.elevation).toLocaleString(undefined, { style: 'percent' }), url: `https://www.openstreetmap.org/${x.type}/${x.id}`, type: x.type, id: x.id }]
// return [...acc, { osm: +x.tags.ele, strm: t.elevation, url: `https://www.openstreetmap.org/${x.type}/${x.id}`, type: x.type, id: x.id, 'ref:ine': x.tags['ref:ine'] }]
}, [])
console.table(errors, ['osm', 'strm', 'error', 'url'])
console.log('\nEnlace JOSM:\nhttp://localhost:8111/load_object?new_layer=true&objects=' + errors.map(x => x.type[0] + x.id).join(','))
console.log('\nJSON de actualización:\n' + JSON.stringify(Object.fromEntries(errors.map(x => [x.id, x.strm]))))
return errors
}
main()