Add ConvertCoordinates to lib folder
parent
9e63e40dab
commit
abdd70c6fa
|
@ -0,0 +1,210 @@
|
|||
/**
|
||||
* Co-ordinate conversion resources.
|
||||
*
|
||||
* @author j433866 [j433866@gmail.com]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import geohash from "ngeohash";
|
||||
import mgrs from "mgrs";
|
||||
|
||||
/**
|
||||
* Co-ordinate formats
|
||||
*/
|
||||
export const FORMATS = [
|
||||
"Degrees Minutes Seconds",
|
||||
"Degrees Decimal Minutes",
|
||||
"Decimal Degrees",
|
||||
"Geohash",
|
||||
"Military Grid Reference System"
|
||||
];
|
||||
|
||||
/**
|
||||
* Convert a given latitude and longitude into a different format.
|
||||
* @param {string} inLat - Input latitude to be converted. Use this for supplying single values for conversion (e.g. geohash)
|
||||
* @param {string} inLong - Input longitude to be converted
|
||||
* @param {string} inFormat - Format of the input coordinates
|
||||
* @param {string} outFormat - Format to convert to
|
||||
* @param {number} precision - Precision of the result
|
||||
* @returns {string[]} Array containing the converted latitude and longitude
|
||||
*/
|
||||
export function convertCoordinates (inLat, inLong, inFormat, outFormat, precision) {
|
||||
let convLat = inLat;
|
||||
let convLong = inLong;
|
||||
if (inFormat === "Geohash") {
|
||||
const hash = geohash.decode(inLat);
|
||||
convLat = hash.latitude.toString();
|
||||
convLong = hash.longitude.toString();
|
||||
} else if (inFormat === "Military Grid Reference System") {
|
||||
const result = mgrs.toPoint(inLat.replace(" ", ""));
|
||||
convLat = result[1];
|
||||
convLong = result[0];
|
||||
} else {
|
||||
convLat = convertSingleCoordinate(inLat, inFormat, "Decimal Degrees", 15).split("°");
|
||||
convLong = convertSingleCoordinate(inLong, inFormat, "Decimal Degrees", 15).split("°");
|
||||
}
|
||||
|
||||
if (outFormat === "Geohash") {
|
||||
convLat = geohash.encode(parseFloat(convLat), parseFloat(convLong), precision);
|
||||
} else if (outFormat === "Military Grid Reference System") {
|
||||
convLat = mgrs.forward([parseFloat(convLong), parseFloat(convLat)], precision);
|
||||
} else {
|
||||
convLat = convertSingleCoordinate(convLat.toString(), "Decimal Degrees", outFormat, precision);
|
||||
convLong = convertSingleCoordinate(convLong.toString(), "Decimal Degrees", outFormat, precision);
|
||||
}
|
||||
|
||||
return [convLat, convLong];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input - The input co-ordinate to be converted
|
||||
* @param {string} inFormat - The format of the input co-ordinates
|
||||
* @param {string} outFormat - The format which input should be converted to
|
||||
* @param {boolean} returnRaw - When true, returns the raw float instead of a String
|
||||
* @returns {string|{Object}} The converted co-ordinate result, as either the raw object or a formatted string
|
||||
*/
|
||||
export function convertSingleCoordinate (input, inFormat, outFormat, precision, returnRaw = false){
|
||||
let converted;
|
||||
precision = Math.pow(10, precision);
|
||||
const convData = splitInput(input);
|
||||
// Convert everything to decimal degrees first
|
||||
switch (inFormat) {
|
||||
case "Degrees Minutes Seconds":
|
||||
if (convData.length < 3) {
|
||||
throw "Invalid co-ordinates format.";
|
||||
}
|
||||
converted = convDMSToDD(convData[0], convData[1], convData[2], precision);
|
||||
break;
|
||||
case "Degrees Decimal Minutes":
|
||||
if (convData.length < 2) {
|
||||
throw "Invalid co-ordinates format.";
|
||||
}
|
||||
converted = convDDMToDD(convData[0], convData[1], precision);
|
||||
break;
|
||||
case "Decimal Degrees":
|
||||
if (convData.length < 1) {
|
||||
throw "Invalid co-ordinates format.";
|
||||
}
|
||||
converted = convDDToDD(convData[0], precision);
|
||||
break;
|
||||
default:
|
||||
throw "Unknown input format selection.";
|
||||
}
|
||||
|
||||
// Convert from decimal degrees to the output format
|
||||
switch (outFormat) {
|
||||
case "Decimal Degrees":
|
||||
break;
|
||||
case "Degrees Minutes Seconds":
|
||||
converted = convDDToDMS(converted.degrees);
|
||||
break;
|
||||
case "Degrees Decimal Minutes":
|
||||
converted = convDDToDDM(converted.degrees, precision);
|
||||
break;
|
||||
default:
|
||||
throw "Unknown output format selection.";
|
||||
}
|
||||
if (returnRaw) {
|
||||
return converted;
|
||||
} else {
|
||||
return converted.string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split up the input using a space, and sanitise the result
|
||||
* @param {string} input - The input data to be split
|
||||
* @returns {number[]} An array of the different items in the string, stored as floats
|
||||
*/
|
||||
function splitInput (input){
|
||||
const split = [];
|
||||
|
||||
input.split(" ").forEach(item => {
|
||||
// Remove any character that isn't a digit
|
||||
item = item.replace(/[^0-9.-]/g, "");
|
||||
if (item.length > 0){
|
||||
split.push(parseFloat(item, 10));
|
||||
}
|
||||
});
|
||||
return split;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Degrees Minutes Seconds to Decimal Degrees
|
||||
* @param {number} degrees - The degrees of the input co-ordinates
|
||||
* @param {number} minutes - The minutes of the input co-ordinates
|
||||
* @param {number} seconds - The seconds of the input co-ordinates
|
||||
* @param {number} precision - The precision the result should be rounded to
|
||||
* @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDMSToDD (degrees, minutes, seconds, precision){
|
||||
const converted = new Object();
|
||||
converted.degrees = degrees + (minutes / 60) + (seconds / 3600);
|
||||
converted.string = (Math.round(converted.degrees * precision) / precision) + "°";
|
||||
return converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Decimal Degrees Minutes to Decimal Degrees
|
||||
* @param {number} degrees - The input degrees to be converted
|
||||
* @param {number} minutes - The input minutes to be converted
|
||||
* @param {number} precision - The precision which the result should be rounded to
|
||||
* @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDMToDD (degrees, minutes, precision) {
|
||||
const converted = new Object();
|
||||
converted.degrees = degrees + minutes / 60;
|
||||
converted.string = ((Math.round(converted.degrees * precision) / precision) + "°");
|
||||
return converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Decimal Degrees to Decimal Degrees
|
||||
* Doesn't affect the input, just puts it into an object
|
||||
* @param {number} degrees - The input degrees to be converted
|
||||
* @param {number} precision - The precision which the result should be rounded to
|
||||
* @returns {{string: string, degrees: number}} An object containing the raw converted value (obj.degrees), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDToDD (degrees, precision) {
|
||||
const converted = new Object();
|
||||
converted.degrees = degrees;
|
||||
converted.string = Math.round(converted.degrees * precision) / precision + "°";
|
||||
return converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Decimal Degrees to Degrees Minutes Seconds
|
||||
* @param {number} decDegrees - The input data to be converted
|
||||
* @returns {{string: string, degrees: number, minutes: number, seconds: number}} An object containing the raw converted value as separate numbers (.degrees, .minutes, .seconds), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDToDMS (decDegrees) {
|
||||
const degrees = Math.floor(decDegrees);
|
||||
const minutes = Math.floor(60 * (decDegrees - degrees));
|
||||
const seconds = Math.round(3600 * (decDegrees - degrees) - 60 * minutes);
|
||||
|
||||
const converted = new Object();
|
||||
converted.degrees = degrees;
|
||||
converted.minutes = minutes;
|
||||
converted.seconds = seconds;
|
||||
converted.string = degrees + "° " + minutes + "' " + seconds + "\"";
|
||||
return converted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert Decimal Degrees to Degrees Decimal Minutes
|
||||
* @param {number} decDegrees - The input degrees to be converted
|
||||
* @param {number} precision - The precision the input data should be rounded to
|
||||
* @returns {{string: string, degrees: number, minutes: number}} An object containing the raw converted value as separate numbers (.degrees, .minutes), and a formatted string version (obj.string)
|
||||
*/
|
||||
function convDDToDDM (decDegrees, precision) {
|
||||
const degrees = Math.floor(decDegrees);
|
||||
const minutes = decDegrees - degrees;
|
||||
const decMinutes = Math.round((minutes * 60) * precision) / precision;
|
||||
|
||||
const converted = new Object();
|
||||
converted.degrees = degrees;
|
||||
converted.minutes = decMinutes;
|
||||
converted.string = degrees + "° " + decMinutes + "'";
|
||||
return converted;
|
||||
}
|
Loading…
Reference in New Issue