From 496c40bb241ca79a10372a6345dd1bf0c1f0dfd0 Mon Sep 17 00:00:00 2001 From: Shinigami Date: Mon, 2 Jan 2023 15:32:13 +0100 Subject: [PATCH] refactor(location): nearbyGPSCoordinate options (#1682) Co-authored-by: ST-DDT --- src/modules/location/index.ts | 108 ++++++++++++++++--- test/__snapshots__/location.spec.ts.snap | 126 +++++++++++++++++++++++ test/location.spec.ts | 21 +++- 3 files changed, 237 insertions(+), 18 deletions(-) diff --git a/src/modules/location/index.ts b/src/modules/location/index.ts index 4e25cbb955c..ab472658b3d 100644 --- a/src/modules/location/index.ts +++ b/src/modules/location/index.ts @@ -1,4 +1,5 @@ import type { Faker } from '../..'; +import { deprecated } from '../../internal/deprecated'; /** * Module to generate addresses and locations. @@ -368,6 +369,27 @@ export class LocationModule { ); } + /** + * Generates a random GPS coordinate within the specified radius from the given coordinate. + * + * @param options The options for generating a GPS coordinate. + * @param options.origin The original coordinate to get a new coordinate close to. + * If no coordinate is given, a random one will be chosen. + * @param options.radius The maximum distance from the given coordinate to the new coordinate. Defaults to `10`. + * @param options.isMetric If `true` assume the radius to be in kilometers. If `false` for miles. Defaults to `false`. + * + * @example + * faker.location.nearbyGPSCoordinate() // [ 33.8475, -170.5953 ] + * faker.location.nearbyGPSCoordinate({ origin: [33, -170] }) // [ 33.0165, -170.0636 ] + * faker.location.nearbyGPSCoordinate({ origin: [33, -170], radius: 1000, isMetric: true }) // [ 37.9163, -179.2408 ] + * + * @since 8.0.0 + */ + nearbyGPSCoordinate(options?: { + origin?: [latitude: number, longitude: number]; + radius?: number; + isMetric?: boolean; + }): [latitude: number, longitude: number]; /** * Generates a random GPS coordinate within the specified radius from the given coordinate. * @@ -382,14 +404,74 @@ export class LocationModule { * faker.location.nearbyGPSCoordinate([33, -170], 1000, true) // [ 37.9163, -179.2408 ] * * @since 8.0.0 + * + * @deprecated Use `faker.location.nearbyGPSCoordinate({ origin, radius, isMetric })` instead. */ nearbyGPSCoordinate( coordinate?: [latitude: number, longitude: number], - radius: number = 10, - isMetric: boolean = false + radius?: number, + isMetric?: boolean + ): [latitude: number, longitude: number]; + /** + * Generates a random GPS coordinate within the specified radius from the given coordinate. + * + * @param options The options for generating a GPS coordinate. + * @param options.origin The original coordinate to get a new coordinate close to. + * If no coordinate is given, a random one will be chosen. + * @param options.radius The maximum distance from the given coordinate to the new coordinate. Defaults to `10`. + * @param options.isMetric If `true` assume the radius to be in kilometers. If `false` for miles. Defaults to `false`. + * @param legacyRadius Deprecated, use `options.radius` instead. + * @param legacyIsMetric Deprecated, use `options.isMetric` instead. + * + * @example + * faker.location.nearbyGPSCoordinate() // [ 33.8475, -170.5953 ] + * faker.location.nearbyGPSCoordinate({ origin: [33, -170] }) // [ 33.0165, -170.0636 ] + * faker.location.nearbyGPSCoordinate({ origin: [33, -170], radius: 1000, isMetric: true }) // [ 37.9163, -179.2408 ] + * + * @since 8.0.0 + */ + nearbyGPSCoordinate( + options?: + | [latitude: number, longitude: number] + | { + origin?: [latitude: number, longitude: number]; + radius?: number; + isMetric?: boolean; + }, + legacyRadius?: number, + legacyIsMetric?: boolean + ): [latitude: number, longitude: number]; + nearbyGPSCoordinate( + options: + | [latitude: number, longitude: number] + | { + origin?: [latitude: number, longitude: number]; + radius?: number; + isMetric?: boolean; + } = {}, + legacyRadius: number = 10, + legacyIsMetric: boolean = false ): [latitude: number, longitude: number] { - // If there is no coordinate, the best we can do is return a random GPS coordinate. - if (coordinate === undefined) { + if (Array.isArray(options)) { + deprecated({ + deprecated: + 'faker.location.nearbyGPSCoordinate(coordinate, radius, isMetric)', + proposed: + 'faker.location.nearbyGPSCoordinate({ origin, radius, isMetric })', + since: '8.0', + until: '9.0', + }); + options = { origin: options }; + } + + const { + origin, + radius = legacyRadius, + isMetric = legacyIsMetric, + } = options; + + // If there is no origin, the best we can do is return a random GPS coordinate. + if (origin == null) { return [this.latitude(), this.longitude()]; } @@ -414,22 +496,22 @@ export class LocationModule { const distanceInDegree = distanceInKm / kmPerDegree; // in ° - const newCoordinate: [latitude: number, longitude: number] = [ - coordinate[0] + Math.sin(angleRadians) * distanceInDegree, - coordinate[1] + Math.cos(angleRadians) * distanceInDegree, + const coordinate: [latitude: number, longitude: number] = [ + origin[0] + Math.sin(angleRadians) * distanceInDegree, + origin[1] + Math.cos(angleRadians) * distanceInDegree, ]; // Box latitude [-90°, 90°] - newCoordinate[0] = newCoordinate[0] % 180; - if (newCoordinate[0] < -90 || newCoordinate[0] > 90) { - newCoordinate[0] = Math.sign(newCoordinate[0]) * 180 - newCoordinate[0]; - newCoordinate[1] += 180; + coordinate[0] = coordinate[0] % 180; + if (coordinate[0] < -90 || coordinate[0] > 90) { + coordinate[0] = Math.sign(coordinate[0]) * 180 - coordinate[0]; + coordinate[1] += 180; } // Box longitude [-180°, 180°] - newCoordinate[1] = (((newCoordinate[1] % 360) + 540) % 360) - 180; + coordinate[1] = (((coordinate[1] % 360) + 540) % 360) - 180; - return [newCoordinate[0], newCoordinate[1]]; + return [coordinate[0], coordinate[1]]; } /** diff --git a/test/__snapshots__/location.spec.ts.snap b/test/__snapshots__/location.spec.ts.snap index ffe73ffd3f4..5f67809a36c 100644 --- a/test/__snapshots__/location.spec.ts.snap +++ b/test/__snapshots__/location.spec.ts.snap @@ -46,6 +46,48 @@ exports[`location > 42 > nearbyGPSCoordinate > noArgs 1`] = ` ] `; +exports[`location > 42 > nearbyGPSCoordinate > only isMetric 1`] = ` +[ + -22.5828, + 106.7555, +] +`; + +exports[`location > 42 > nearbyGPSCoordinate > only radius 1`] = ` +[ + -22.5828, + 106.7555, +] +`; + +exports[`location > 42 > nearbyGPSCoordinate > with origin and isMetric 1`] = ` +[ + 37.05058762889859, + -13.05029562250138, +] +`; + +exports[`location > 42 > nearbyGPSCoordinate > with origin and radius 1`] = ` +[ + 37.122112668351875, + -13.121407798779614, +] +`; + +exports[`location > 42 > nearbyGPSCoordinate > with origin, radius and isMetric 1`] = ` +[ + 37.075875092904894, + -13.075437119965613, +] +`; + +exports[`location > 42 > nearbyGPSCoordinate > with radius and isMetric 1`] = ` +[ + -22.5828, + 106.7555, +] +`; + exports[`location > 42 > ordinalDirection > noArgs 1`] = `"Northwest"`; exports[`location > 42 > ordinalDirection > with abbr = false 1`] = `"Northwest"`; @@ -124,6 +166,48 @@ exports[`location > 1211 > nearbyGPSCoordinate > noArgs 1`] = ` ] `; +exports[`location > 1211 > nearbyGPSCoordinate > only isMetric 1`] = ` +[ + 77.1337, + -14.7545, +] +`; + +exports[`location > 1211 > nearbyGPSCoordinate > only radius 1`] = ` +[ + 77.1337, + -14.7545, +] +`; + +exports[`location > 1211 > nearbyGPSCoordinate > with origin and isMetric 1`] = ` +[ + 36.98215379643012, + -12.962972893442156, +] +`; + +exports[`location > 1211 > nearbyGPSCoordinate > with origin and radius 1`] = ` +[ + 36.95691638741659, + -12.910610595257708, +] +`; + +exports[`location > 1211 > nearbyGPSCoordinate > with origin, radius and isMetric 1`] = ` +[ + 36.97323069464518, + -12.944459340163235, +] +`; + +exports[`location > 1211 > nearbyGPSCoordinate > with radius and isMetric 1`] = ` +[ + 77.1337, + -14.7545, +] +`; + exports[`location > 1211 > ordinalDirection > noArgs 1`] = `"Southwest"`; exports[`location > 1211 > ordinalDirection > with abbr = false 1`] = `"Southwest"`; @@ -202,6 +286,48 @@ exports[`location > 1337 > nearbyGPSCoordinate > noArgs 1`] = ` ] `; +exports[`location > 1337 > nearbyGPSCoordinate > only isMetric 1`] = ` +[ + -42.8356, + 21.7907, +] +`; + +exports[`location > 1337 > nearbyGPSCoordinate > only radius 1`] = ` +[ + -42.8356, + 21.7907, +] +`; + +exports[`location > 1337 > nearbyGPSCoordinate > with origin and isMetric 1`] = ` +[ + 37.05004958398222, + -13.003788641630877, +] +`; + +exports[`location > 1337 > nearbyGPSCoordinate > with origin and radius 1`] = ` +[ + 37.12082442834317, + -13.009146139144832, +] +`; + +exports[`location > 1337 > nearbyGPSCoordinate > with origin, radius and isMetric 1`] = ` +[ + 37.07507884069983, + -13.00568330041608, +] +`; + +exports[`location > 1337 > nearbyGPSCoordinate > with radius and isMetric 1`] = ` +[ + -42.8356, + 21.7907, +] +`; + exports[`location > 1337 > ordinalDirection > noArgs 1`] = `"Northwest"`; exports[`location > 1337 > ordinalDirection > with abbr = false 1`] = `"Northwest"`; diff --git a/test/location.spec.ts b/test/location.spec.ts index 567ec148c8d..3a7d958d0ea 100644 --- a/test/location.spec.ts +++ b/test/location.spec.ts @@ -72,7 +72,18 @@ describe('location', () => { }); t.describe('nearbyGPSCoordinate', (t) => { - t.it('noArgs').it('near origin', [0, 0]); + t.it('noArgs') + .it('near origin', { origin: [0, 0] }) + .it('with origin and radius', { origin: [37, -13], radius: 15 }) + .it('with origin, radius and isMetric', { + origin: [37, -13], + radius: 15, + isMetric: true, + }) + .it('with origin and isMetric', { origin: [37, -13], isMetric: true }) + .it('with radius and isMetric', { radius: 15, isMetric: true }) + .it('only radius', { radius: 12 }) + .it('only isMetric', { isMetric: true }); }); t.it('state').it('stateAbbr'); @@ -286,11 +297,11 @@ describe('location', () => { const latitude1 = +faker.location.latitude(); const longitude1 = +faker.location.longitude(); - const coordinate = faker.location.nearbyGPSCoordinate( - [latitude1, longitude1], + const coordinate = faker.location.nearbyGPSCoordinate({ + origin: [latitude1, longitude1], radius, - isMetric - ); + isMetric, + }); expect(coordinate.length).toBe(2); expect(coordinate[0]).toBeTypeOf('number');