Some simple vector math where you get the hypotenuse (with the vectorDistance function), can result in a solution for this.
function closestLocation(targetLocation, locationData) {
function vectorDistance(dx, dy) {
return Math.sqrt(dx * dx + dy * dy);
}
function locationDistance(location1, location2) {
var dx = location1.latitude - location2.latitude,
dy = location1.longitude - location2.longitude;
return vectorDistance(dx, dy);
}
return locationData.reduce(function(prev, curr) {
var prevDistance = locationDistance(targetLocation , prev),
currDistance = locationDistance(targetLocation , curr);
return (prevDistance < currDistance) ? prev : curr;
});
}
var data = {
"Locations": {
"Location": [
{
"id": "3066",
"latitude": "57.6494",
"longitude": "-3.5606",
"name": "Kinloss"},
{
"id": "3080",
"latitude": "57.077",
"longitude": "-2.836",
"name": "Aboyne"},
{
"id": "3091",
"latitude": "57.206",
"longitude": "-2.202",
"name": "Aberdeen Dyce"},
{
"id": "3134",
"latitude": "55.907",
"longitude": "-4.533",
"name": "Glasgow/Bishopton"},
{
"id": "3136",
"latitude": "55.515",
"longitude": "-4.585",
"name": "Prestwick Rnas"},
{
"id": "3144",
"latitude": "56.326",
"longitude": "-3.729",
"name": "Strathallan"}
]
}
},
targetLocation = {
latitude: 56,
longitude: -5
},
closest = closestLocation(targetLocation, data.Locations.Location);
// closest is now the location that is closest to the target location
If you need to support older web browsers that don’t know how to do the Array.reduce() method, you can get polyfills from http://www.calormen.com/polyfill/polyfill.js or you can just use the part of that code directly related to providing the reduce functionality itself:
// ES5 15.4.4.21 Array.prototype.reduce ( callbackfn [ , initialValue ] )
// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce
if (!Array.prototype.reduce) {
Array.prototype.reduce = function (fun /*, initialValue */) {
"use strict";
if (this === void 0 || this === null) { throw new TypeError(); }
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== "function") { throw new TypeError(); }
// no value to return if no initial value and an empty array
if (len === 0 && arguments.length === 1) { throw new TypeError(); }
var k = 0;
var accumulator;
if (arguments.length >= 2) {
accumulator = arguments[1];
} else {
do {
if (k in t) {
accumulator = t[k++];
break;
}
// if array contains no values, no initial value to return
if (++k >= len) { throw new TypeError(); }
}
while (true);
}
while (k < len) {
if (k in t) {
accumulator = fun.call(undefined, accumulator, t[k], k, t);
}
k++;
}
return accumulator;
};
}