diff --git a/package.json b/package.json index c6b91376..774ff6f9 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "loglevel-message-prefix": "^3.0.0", "moment": "^2.22.2", "moment-timezone": "^0.5.21", + "ngeohash": "^0.6.0", "node-forge": "^0.7.5", "node-md6": "^0.1.0", "notepack.io": "^2.1.3", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 66663f4a..75bdcb36 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -53,7 +53,9 @@ "To MessagePack", "From MessagePack", "To Braille", - "From Braille" + "From Braille", + "To Geohash", + "From Geohash" ] }, { diff --git a/src/core/operations/FromGeohash.mjs b/src/core/operations/FromGeohash.mjs new file mode 100644 index 00000000..1010da11 --- /dev/null +++ b/src/core/operations/FromGeohash.mjs @@ -0,0 +1,43 @@ +/** + * @author gchq77703 [] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import geohash from "ngeohash"; + +/** + * From Geohash operation + */ +class FromGeohash extends Operation { + + /** + * FromGeohash constructor + */ + constructor() { + super(); + + this.name = "From Geohash"; + this.module = "Default"; + this.description = "Converts Geohash strings into Lat / Long coordinates. For example, ww8p1r4t8 becomes 37.8324,112.5584."; + this.infoURL = "https://wikipedia.org/wiki/Geohash"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const coords = geohash.decode(input); + return [coords.latitude, coords.longitude].join(","); + } + +} + +export default FromGeohash; diff --git a/src/core/operations/ToGeohash.mjs b/src/core/operations/ToGeohash.mjs new file mode 100644 index 00000000..826145ae --- /dev/null +++ b/src/core/operations/ToGeohash.mjs @@ -0,0 +1,51 @@ +/** + * @author gchq77703 [] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import geohash from "ngeohash"; + +/** + * To Geohash operation + */ +class ToGeohash extends Operation { + + /** + * ToGeohash constructor + */ + constructor() { + super(); + + this.name = "To Geohash"; + this.module = "Default"; + this.description = "Converts Lat / Long coordinates into a Geohash string. For example, 37.8324,112.5584 becomes ww8p1r4t8."; + this.infoURL = "https://wikipedia.org/wiki/Geohash"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Precision", + type: "number", + value: 9 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [precision] = args; + + input = input.replace(/ /g, ""); + if (input === "") return ""; + return geohash.encode(...input.split(",").map(num => parseFloat(num)), precision); + } + +} + +export default ToGeohash; diff --git a/test/index.mjs b/test/index.mjs index 8cf69732..5d0ce3ff 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -64,6 +64,8 @@ import "./tests/operations/SetUnion"; import "./tests/operations/SymmetricDifference"; import "./tests/operations/TranslateDateTimeFormat"; import "./tests/operations/Magic"; +import "./tests/operations/ToGeohash.mjs"; +import "./tests/operations/FromGeohash.mjs"; let allTestsPassing = true; const testStatusCounts = { diff --git a/test/tests/operations/FromGeohash.mjs b/test/tests/operations/FromGeohash.mjs new file mode 100644 index 00000000..3dbe85ae --- /dev/null +++ b/test/tests/operations/FromGeohash.mjs @@ -0,0 +1,56 @@ +/** + * To Geohash tests + * + * @author gchq77703 + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "From Geohash", + input: "ww8p1r4t8", + expectedOutput: "37.83238649368286,112.55838632583618", + recipeConfig: [ + { + op: "From Geohash", + args: [], + }, + ], + }, + { + name: "From Geohash", + input: "ww8p1r", + expectedOutput: "37.83416748046875,112.5604248046875", + recipeConfig: [ + { + op: "From Geohash", + args: [], + }, + ], + }, + { + name: "From Geohash", + input: "ww8", + expectedOutput: "37.265625,113.203125", + recipeConfig: [ + { + op: "From Geohash", + args: [], + }, + ], + }, + { + name: "From Geohash", + input: "w", + expectedOutput: "22.5,112.5", + recipeConfig: [ + { + op: "From Geohash", + args: [], + }, + ], + }, +]); diff --git a/test/tests/operations/ToGeohash.mjs b/test/tests/operations/ToGeohash.mjs new file mode 100644 index 00000000..bf3e9858 --- /dev/null +++ b/test/tests/operations/ToGeohash.mjs @@ -0,0 +1,56 @@ +/** + * To Geohash tests + * + * @author gchq77703 + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "To Geohash", + input: "37.8324,112.5584", + expectedOutput: "ww8p1r4t8", + recipeConfig: [ + { + op: "To Geohash", + args: [9], + }, + ], + }, + { + name: "To Geohash", + input: "37.9324,-112.2584", + expectedOutput: "9w8pv3ruj", + recipeConfig: [ + { + op: "To Geohash", + args: [9], + }, + ], + }, + { + name: "To Geohash", + input: "37.8324,112.5584", + expectedOutput: "ww8", + recipeConfig: [ + { + op: "To Geohash", + args: [3], + }, + ], + }, + { + name: "To Geohash", + input: "37.9324,-112.2584", + expectedOutput: "9w8pv3rujxy5b99", + recipeConfig: [ + { + op: "To Geohash", + args: [15], + }, + ], + }, +]);