From 14c7339ed0060eeca9c3725ff2cc07e6f57b92e8 Mon Sep 17 00:00:00 2001 From: liamcottle Date: Thu, 3 Oct 2024 09:41:57 +1300 Subject: [PATCH] implement function to set integer position precision in bits --- src/utils/position_util.js | 22 ++++++++++++++++++++++ src/utils/position_util.test.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/utils/position_util.js b/src/utils/position_util.js index a3e4f05..6824b0b 100644 --- a/src/utils/position_util.js +++ b/src/utils/position_util.js @@ -1,5 +1,27 @@ class PositionUtil { + /** + * Obfuscates the provided latitude or longitude down to the provided precision in bits. + * This is based on the same logic in the official meshtastic firmware. + * https://github.com/meshtastic/firmware/blob/0a93261c0646f93aea518cc0599e547e9dc0e997/src/modules/PositionModule.cpp#L187 + */ + static setPositionPrecision(latitudeOrLongitudeInteger, precision) { + + // check if we should use the provided precision + if(precision > 0 && precision < 32){ + + // apply bitmask to reduce precision of position to wanted bits + latitudeOrLongitudeInteger = latitudeOrLongitudeInteger & (0xFFFFFFFF << (32 - precision)); + + // we want the imprecise position to be the middle of the possible location + latitudeOrLongitudeInteger += (1 << (31 - precision)); + + } + + return latitudeOrLongitudeInteger; + + } + /** * Truncates the provided latitude or longitude to a maximum of x decimal places * e.g: 12.3456789 with 2 decimal places would be 12.34 diff --git a/src/utils/position_util.test.js b/src/utils/position_util.test.js index 70cf615..f00d3bd 100644 --- a/src/utils/position_util.test.js +++ b/src/utils/position_util.test.js @@ -16,3 +16,32 @@ test('can truncate string position to provided decimal places', () => { expect(PositionUtil.truncateDecimalPlaces("123", 2)).toBe("123"); expect(PositionUtil.truncateDecimalPlaces("1234.", 2)).toBe("1234"); }); + +test('can set integer position precision to provided bits', () => { + + // these tests are using the auckland sky tower position + // auckland sky tower: -36.84844007222091, 174.76221115261924 + // the outputs we are expecting, are the same values returned by the code in the meshtastic firmware + // https://github.com/meshtastic/firmware/blob/0a93261c0646f93aea518cc0599e547e9dc0e997/src/modules/PositionModule.cpp#L187 + + // set precision to 32 bits (within 0 meters) + // -36.8484400, 174.7622111 -> -36.8484400, 174.7622111 + expect(PositionUtil.setPositionPrecision(-368484400, 32)).toBe(-368484400); + expect(PositionUtil.setPositionPrecision(1747622111, 32)).toBe(1747622111); + + // set precision to 16 bits (within ~364 meters) + // -36.8484400, 174.7622111 -> -36.8476160, 174.7615744 + expect(PositionUtil.setPositionPrecision(-368484400, 16)).toBe(-368476160); + expect(PositionUtil.setPositionPrecision(1747622111, 16)).toBe(1747615744); + + // set precision to 13 bits (within ~2.9 kilometers) + // -36.8484400, 174.7622111 -> -36.8312320, 174.7714048 + expect(PositionUtil.setPositionPrecision(-368484400, 13)).toBe(-368312320); + expect(PositionUtil.setPositionPrecision(1747622111, 13)).toBe(1747714048); + + // set precision to 11 bits (within ~11.6 kilometers) + // -36.8484400, 174.7622111 -> -36.8050176, 174.7976192 + expect(PositionUtil.setPositionPrecision(-368484400, 11)).toBe(-368050176); + expect(PositionUtil.setPositionPrecision(1747622111, 11)).toBe(1747976192); + +});