-
-
Notifications
You must be signed in to change notification settings - Fork 339
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
reimplementation of getDistance and getCenter
- Loading branch information
1 parent
d4491e1
commit e7d48cf
Showing
10 changed files
with
208 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
# Breaking Changes in 3.0.0 | ||
|
||
- removed limitation to 8 decimal places in decimal coordinates | ||
- removed artificial limitation to 8 decimal places in decimal coordinates | ||
- `sexagesimal2decimal` was renamed to `sexagesimalToDecimal` | ||
- `getCenter()` is not returning the distance in addition to the center anymore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import getCenter from './getCenter'; | ||
|
||
const cities = { | ||
Berlin: { | ||
latitude: 52.518611, | ||
longitude: 13.408056, | ||
}, | ||
Boston: { | ||
latitude: 42.357778, | ||
longitude: '71° 3\' 34" W', | ||
}, | ||
Dortmund: { | ||
latitude: '51° 31\' 10.11" N', | ||
longitude: '7° 28\' 01" E', | ||
}, | ||
London: { | ||
latitude: "51° 31' N", | ||
longitude: "0° 7' W", | ||
}, | ||
Manchester: { | ||
latitude: "53° 29' N", | ||
longitude: "2° 14' W", | ||
}, | ||
NewYorkCity: { | ||
latitude: 40.715517, | ||
longitude: -73.9991, | ||
}, | ||
SanFrancisco: { | ||
latitude: 37.774514, | ||
longitude: -122.418079, | ||
}, | ||
Sydney: [151.210046, -33.869085], | ||
Moscow: { | ||
latitude: 55.751667, | ||
longitude: 37.617778, | ||
}, | ||
}; | ||
|
||
describe('getCenter', () => { | ||
it('gets the center of two points', () => { | ||
expect(getCenter([cities.Berlin, cities.Moscow])).toEqual({ | ||
longitude: 25.0332388360222, | ||
latitude: 54.74368339960522, | ||
}); | ||
expect(getCenter([cities.Sydney, cities.SanFrancisco])).toEqual({ | ||
longitude: -166.9272249630353, | ||
latitude: 2.6764932317022576, | ||
}); | ||
}); | ||
|
||
it('gets the center of multiple points', () => { | ||
const values = Object.values(cities); | ||
expect(getCenter(values)).toEqual({ | ||
latitude: 65.41916196002177, | ||
longitude: -28.01313266917171, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import toRad from './toRad'; | ||
import toDeg from './toDeg'; | ||
import getLatitude from './getLatitude'; | ||
import getLongitude from './getLongitude'; | ||
import { GeolibInputCoordinates } from './types'; | ||
|
||
// Calculates the center of a collection of points | ||
const getCenter = (points: GeolibInputCoordinates[]) => { | ||
if (Array.isArray(points) === false || points.length === 0) { | ||
return false; | ||
} | ||
|
||
const numberOfPoints = points.length; | ||
|
||
const sum = points.reduce( | ||
(acc, point) => { | ||
const pointLat = toRad(getLatitude(point)); | ||
const pointLon = toRad(getLongitude(point)); | ||
|
||
return { | ||
X: acc.X + Math.cos(pointLat) * Math.cos(pointLon), | ||
Y: acc.Y + Math.cos(pointLat) * Math.sin(pointLon), | ||
Z: acc.Z + Math.sin(pointLat), | ||
}; | ||
}, | ||
{ X: 0, Y: 0, Z: 0 } | ||
); | ||
|
||
const X = sum.X / numberOfPoints; | ||
const Y = sum.Y / numberOfPoints; | ||
const Z = sum.Z / numberOfPoints; | ||
|
||
return { | ||
longitude: toDeg(Math.atan2(Y, X)), | ||
latitude: toDeg(Math.atan2(Z, Math.sqrt(X * X + Y * Y))), | ||
}; | ||
}; | ||
|
||
export default getCenter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import getDistance from './getDistance'; | ||
|
||
describe('getDistance', () => { | ||
it('calculates the distance between any two points', () => { | ||
expect( | ||
getDistance( | ||
{ latitude: 52.518611, longitude: 13.408056 }, | ||
{ latitude: 51.519475, longitude: 7.46694444 } | ||
) | ||
).toEqual(421786); | ||
|
||
expect( | ||
getDistance( | ||
{ latitude: 52.518611, longitude: 13.408056 }, | ||
{ latitude: 51.519475, longitude: 7.46694444 }, | ||
100 | ||
) | ||
).toEqual(421800); | ||
|
||
expect( | ||
getDistance( | ||
{ latitude: 37.774514, longitude: -122.418079 }, | ||
{ latitude: 51.519475, longitude: 7.46694444 } | ||
) | ||
).toEqual(8967172); | ||
|
||
expect( | ||
getDistance([-122.418079, 37.774514], [7.46694444, 51.519475]) | ||
).toEqual(8967172); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import getLatitude from './getLatitude'; | ||
import getLongitude from './getLongitude'; | ||
import toRad from './toRad'; | ||
import { earthRadius } from './constants'; | ||
import { GeolibInputCoordinates } from './types'; | ||
|
||
// Calculates the distance between two points. | ||
// This method is simple but also more inaccurate | ||
const getDistance = ( | ||
from: GeolibInputCoordinates, | ||
to: GeolibInputCoordinates, | ||
accuracy: number = 1 | ||
) => { | ||
accuracy = | ||
typeof accuracy !== 'undefined' && !isNaN(accuracy) | ||
? Math.floor(accuracy) | ||
: 1; | ||
|
||
const distance = Math.round( | ||
Math.acos( | ||
Math.sin(toRad(getLatitude(to))) * | ||
Math.sin(toRad(getLatitude(from))) + | ||
Math.cos(toRad(getLatitude(to))) * | ||
Math.cos(toRad(getLatitude(from))) * | ||
Math.cos( | ||
toRad(getLongitude(from)) - toRad(getLongitude(to)) | ||
) | ||
) * earthRadius | ||
); | ||
|
||
return Math.floor(Math.round(distance / accuracy) * accuracy); | ||
}; | ||
|
||
export default getDistance; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import getLongitude from './getLongitude'; | ||
|
||
describe('getLongitude', () => { | ||
it('gets the longitude for a point', () => { | ||
expect(getLongitude({ lng: 1 })).toEqual(1); | ||
}); | ||
|
||
it('converts the longitude for a point to decimal', () => { | ||
expect(getLongitude({ lng: "71° 0'" })).toEqual(71); | ||
}); | ||
|
||
it('gets the longitude from a GeoJSON array', () => { | ||
expect(getLongitude([1, 2])).toEqual(1); | ||
}); | ||
|
||
it('does not convert to decimal if second parameter is set to true', () => { | ||
expect(getLongitude({ lng: "71° 0'" }, true)).toEqual("71° 0'"); | ||
}); | ||
|
||
it('gets the longitude from a GeoJSON array without conversion', () => { | ||
expect(getLongitude(["71° 0'", "71° 0'"], true)).toEqual("71° 0'"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { GeolibInputCoordinates, LongitudeKeys } from './types'; | ||
import { longitudeKeys } from './constants'; | ||
import getCoordinateKey from './getCoordinateKey'; | ||
import toDecimal from './toDecimal'; | ||
|
||
const getLongitude = (point: GeolibInputCoordinates, raw?: boolean) => { | ||
const latKey = getCoordinateKey(point, longitudeKeys); | ||
|
||
if (typeof latKey === 'undefined' || latKey === null) { | ||
return; | ||
} | ||
|
||
const value = point[latKey as keyof LongitudeKeys]; | ||
|
||
return raw === true ? value : toDecimal(value); | ||
}; | ||
|
||
export default getLongitude; |