UNPKG

@mapbox/sexagesimal

Version:

parse coordinates in sexagesimal form

108 lines (83 loc) 2.67 kB
module.exports = element; module.exports.pair = pair; module.exports.format = format; module.exports.formatPair = formatPair; module.exports.coordToDMS = coordToDMS; function element(input, dims) { var result = search(input, dims); return (result === null) ? null : result.val; } function formatPair(input) { return format(input.lat, 'lat') + ' ' + format(input.lon, 'lon'); } // Is 0 North or South? function format(input, dim) { var dms = coordToDMS(input, dim); return dms.whole + '° ' + (dms.minutes ? dms.minutes + '\' ' : '') + (dms.seconds ? dms.seconds + '" ' : '') + dms.dir; } function coordToDMS(input, dim) { var dirs = { lat: ['N', 'S'], lon: ['E', 'W'] }[dim] || ''; var dir = dirs[input >= 0 ? 0 : 1]; var abs = Math.abs(input); var whole = Math.floor(abs); var fraction = abs - whole; var fractionMinutes = fraction * 60; var minutes = Math.floor(fractionMinutes); var seconds = Math.floor((fractionMinutes - minutes) * 60); return { whole: whole, minutes: minutes, seconds: seconds, dir: dir }; } function search(input, dims) { if (!dims) dims = 'NSEW'; if (typeof input !== 'string') return null; input = input.toUpperCase(); var regex = /^[\s\,]*([NSEW])?\s*([\-|\—|\―]?[0-9.]+)[°º˚]?\s*(?:([0-9.]+)['’′‘]\s*)?(?:([0-9.]+)(?:''|"|”|″)\s*)?([NSEW])?/; var m = input.match(regex); if (!m) return null; // no match var matched = m[0]; // extract dimension.. m[1] = leading, m[5] = trailing var dim; if (m[1] && m[5]) { // if matched both.. dim = m[1]; // keep leading matched = matched.slice(0, -1); // remove trailing dimension from match } else { dim = m[1] || m[5]; } // if unrecognized dimension if (dim && dims.indexOf(dim) === -1) return null; // extract DMS var deg = m[2] ? parseFloat(m[2]) : 0; var min = m[3] ? parseFloat(m[3]) / 60 : 0; var sec = m[4] ? parseFloat(m[4]) / 3600 : 0; var sign = (deg < 0) ? -1 : 1; if (dim === 'S' || dim === 'W') sign *= -1; return { val: (Math.abs(deg) + min + sec) * sign, dim: dim, matched: matched, remain: input.slice(matched.length) }; } function pair(input, dims) { input = input.trim(); var one = search(input, dims); if (!one) return null; input = one.remain.trim(); var two = search(input, dims); if (!two || two.remain) return null; if (one.dim) { return swapdim(one.val, two.val, one.dim); } else { return [one.val, two.val]; } } function swapdim(a, b, dim) { if (dim === 'N' || dim === 'S') return [a, b]; if (dim === 'W' || dim === 'E') return [b, a]; }