如何从JSON数据中使用纬度和经度查找最近的位置

10
我正在尝试制作一个网站,要求用户提供位置信息,然后使用GeoLocation查找距离其位置最近的位置(100米半径),并在HTML中显示结果。
我尝试过的方法。
$.getJSON("places.json", function (data) {
        for (var i = 0; i < data.length; i++) {
            if ((data[i].lat - poslat) > 0.00200 || (data[i].lng - poslng) > 0.00200) {
            return data[i];
        }

        html += '<p>' + data[i].location + ' - ' + data[i].code + '</p>';
        $('#nearbystops').append(html);
    }
});

地点.json

[
{
"code": "0001",
"lat": "1.28210155945393",
"lng": "103.81722480263163",
"location": "Stop 1"
},
{
"code": "0003",
"lat": "1.2777380589964",
"lng": "103.83749709165197",
"location": "Stop 2"
},
{
"code": "0002",
"lat": "1.27832046633393",
"lng": "103.83762574759974",
"location": "Stop 3"
}
]

提前感谢您!:)


poslatposlong是用户的位置吗? - Reinstate Monica Cellio
是的 :) poslat(纬度)poslong(经度)。 - Leng D
这里有一个很好的例子:https://stackoverflow.com/a/56112370/4701635 - Paresh Barad
3个回答

26

为了计算两个坐标之间的距离,不能直接相减。这样可以得到在一个正方形内的坐标。虽然这可能是可行的,但大多数人更想通过半径搜索位置。以下这个函数可以实现这一点...

function distance(lat1, lon1, lat2, lon2, unit) {
    var radlat1 = Math.PI * lat1/180
    var radlat2 = Math.PI * lat2/180
    var theta = lon1-lon2
    var radtheta = Math.PI * theta/180
    var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
    if (dist > 1) {
        dist = 1;
    }
    dist = Math.acos(dist)
    dist = dist * 180/Math.PI
    dist = dist * 60 * 1.1515
    if (unit=="K") { dist = dist * 1.609344 }
    if (unit=="N") { dist = dist * 0.8684 }
    return dist
}

这是我从这里拷贝的常见代码...

https://www.geodatasource.com/developers/javascript

这里是它在你的示例中被使用...

function distance(lat1, lon1, lat2, lon2, unit) {
  var radlat1 = Math.PI * lat1/180
  var radlat2 = Math.PI * lat2/180
  var theta = lon1-lon2
  var radtheta = Math.PI * theta/180
  var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
  if (dist > 1) {
    dist = 1;
  }
  dist = Math.acos(dist)
  dist = dist * 180/Math.PI
  dist = dist * 60 * 1.1515
  if (unit=="K") { dist = dist * 1.609344 }
  if (unit=="N") { dist = dist * 0.8684 }
  return dist
}

var data = [{
    "code": "0001",
    "lat": "1.28210155945393",
    "lng": "103.81722480263163",
    "location": "Stop 1"
}, {
    "code": "0003",
    "lat": "1.2777380589964",
    "lng": "103.83749709165197",
    "location": "Stop 2"
}, {
    "code": "0002",
    "lat": "1.27832046633393",
    "lng": "103.83762574759974",
    "location": "Stop 3"
}];

var html = "";
var poslat = 1.28210155945393;
var poslng = 103.81722480263163;

for (var i = 0; i < data.length; i++) {
    // if this location is within 0.1KM of the user, add it to the list
    if (distance(poslat, poslng, data[i].lat, data[i].lng, "K") <= 0.1) {
        html += '<p>' + data[i].location + ' - ' + data[i].code + '</p>';
    }
}

$('#nearbystops').append(html);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="nearbystops"></div>


如何使用HTML5地理位置实现这个功能。我明白你的想法,但是我无法让它工作。 - Leng D
我不明白你在问什么。你所需要做的就是提供数据和用户的纬度/经度值(你说你已经有了)。 - Reinstate Monica Cellio
现在懂了!谢谢Archer! - Leng D

3

为了计算两个点(纬度、经度)之间的距离,使用 TypeScript 实现了 Haversine 公式函数。

//There are 6200 points in the JSON file
import data from './json/test.json';

let radians = function (degree: number) {

  // degrees to radians
  let rad: number = degree * Math.PI / 180;

  return rad;
}

const haversine = (lat1: number, lon1: number, lat2: number, lon2: number) => {

  let dlat, dlon, a, c, R: number;

  R = 6372.8; // km
  dlat = radians(lat2 - lat1);
  dlon = radians(lon2 - lon1);
  lat1 = radians(lat1);
  lat2 = radians(lat2);
  a = Math.sin(dlat / 2) * Math.sin(dlat / 2) + Math.sin(dlon / 2) * Math.sin(dlon / 2) * Math.cos(lat1) * Math.cos(lat2)
  c = 2 * Math.asin(Math.sqrt(a));
  return R * c;
}

let test = function () {
  const keys = Object.keys(data);

  let count: number = keys.length;
  for (var _i = 0; _i < count; _i++) {
    var _dummy: number = haversine(
      36.12, -86.67, data[_i].position.lat, data[_i].position.lng);
  }

}

你能描述一下 R = 6372.8; // km 是什么吗? - Rahman Haroon
1
@RahmanHaroonrau 这是地球的半径,因为地球不是平的^^,这样可以考虑到地球的球形形状。 - AldegarRızvan

3

使用HTML5地理位置获取当前用户的位置,并在100米范围内查找最近的位置。

包括并使用以下谷歌地图库

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry"> </script>


代码片段

//calculates distance between two points in km's
function calcDistance(p1, p2) {
  return (google.maps.geometry.spherical.computeDistanceBetween(p1, p2) / 1000).toFixed(2);
}

function getPosition(position) {
  var userPosition = {
    lat: position.coords.latitude,
    lng: position.coords.longitude
  };

  $.getJSON("places.json", function(data) {
    for (var i = 0; i < data.length; i++) {

      var p1 = new google.maps.LatLng(userPosition.lat, userPosition.lng);
      var p2 = new google.maps.LatLng(data[i].lat, data[i].lng);

      var distance = calcDistance(p1, p2) * 1000;

      if ((distance * 1000) <= 100) {
        html += '<p>' + data[i].location + ' - ' + data[i].code + '</p>';
        $('#nearbystops').append(html);
      }

    }

  })
}

// get user's current latitude & longitude
function getLocation() {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(getPosition);
  } else {
    alert("Geolocation is not supported by this browser.");
  }
}

getLocation();

谢谢Shiv Kumar Baghel!我会将这个作为其他项目的参考 :) - Leng D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接