如何检查坐标是不是在以公里为单位的半径范围内?

Posted

技术标签:

【中文标题】如何检查坐标是不是在以公里为单位的半径范围内?【英文标题】:How to check if coords are within a radius in km?如何检查坐标是否在以公里为单位的半径范围内? 【发布时间】:2019-03-01 23:28:01 【问题描述】:

给定一个带有坐标json

var centerLat = 51.6000;
var centerLng = 12.8000;

var posts = [
  
    name: 'PostA',
    latitude: '52.5167',
    longitude: '13.3833',
  ,
  
    name: 'PostB',
    latitude: '52.9667',
    longitude: '13.7167',
  ,
  
    name: 'PostC',
    latitude: '26.7767',
    longitude: '18.4567',
  
];

我在this link 上找到了haversine 公式,我如何检查我从json 获得的给定latlng 的列表是否在radius 的5 公里 使用 haversine

function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) 
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;


function deg2rad(deg) 
  return deg * (Math.PI/180)

【问题讨论】:

有趣的问题...但是你有没有尝试过? 距离中心点5公里? @LouysPatriceBessette 我试过这个使用 pytagoras 但我想使用 hasrsine 但我不知道。 gist.github.com/Thibaut-B/56071bcc8207fa11be90 @RandyCasburn 抱歉,是的,我已经提供了一些随机中心点的更新,谢谢 那么,你有haversine函数和一个中心点,是什么阻止你对数组中的每个点执行一次函数? 【参考方案1】:

您可以这样做来过滤城市,您提供的数据相距太远,以获得结果中的任何内容我已经移动了 centerLatcenterLng 我已经记录了最近城市的数组结尾。

function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) 
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2 - lat1); // deg2rad below
  var dLon = deg2rad(lon2 - lon1);
  var a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  var d = R * c; // Distance in km
  return d;


function deg2rad(deg) 
  return deg * (Math.PI / 180)


var centerLat = 52.5167;
var centerLng = 13.3933;

var posts = [
    name: 'PostA',
    latitude: '52.5167',
    longitude: '13.3833',
  ,
  
    name: 'PostB',
    latitude: '52.9667',
    longitude: '13.7167',
  ,
  
    name: 'PostC',
    latitude: '26.7767',
    longitude: '18.4567',
  
];

let closePosts = [];

posts.forEach((post) => 
  if (getDistanceFromLatLonInKm(centerLat, centerLng, post.latitude, post.longitude) < 5) 
    closePosts.push(post);
  
);

console.log(closePosts)

【讨论】:

嘿,非常感谢,有道理。你为什么使用 (city) tho? 我猜我从你的问题中复制了数据,当你称它为城市时。我会将其更新为帖子以更好地反映您的答案。 非常感谢,另一方面,为什么 haversine 比 pytagoras 更好?就错误距离而言,误差范围是多少?抱歉,只是问一下,以防你知道。谢谢 @rob.m 据我了解,这是因为半正弦考虑了地球的曲率,而 pytagoras 在二维平面上测量,这里有一个很好的答案。 haversine vs pytagoras 我只是注销每个帖子的距离,为了显示距离,数组closePosts 包含帖子。我将删除控制台日志以使结果更清晰。【参考方案2】:

只需将其添加到您的代码中就足够了。

posts.forEach(post => 
  const distance = getDistanceFromLatLonInKm(centerLat, centerLng, post.latitude, post.longitude);
  if (distance <= 200) 
    console.log(`Distance to $post.name: $distance km`);
  
);

但我建议多清理一下代码。我使用 200 而不是 5,因为您的示例没有产生结果。

这是一个重构的 sn-p。

const posts = [
  
    name: 'Berlin',
    latitude: '52.520008',
    longitude: '13.404954',
  ,
  
    name: 'Hamburg',
    latitude: '53.551086',
    longitude: '9.993682',
  ,
  
    name: 'München',
    latitude: '48.135124',
    longitude: '11.581981',
  ,
  
    name: 'Lübeck',
    latitude: '53.865467',
    longitude: '10.686559',
  ,
  
    name: 'Schwerin',
    latitude: '53.635502',
    longitude: '11.401250',
  ,
];

function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) 
  const R = 6371; // Radius of the earth in km
  const dLat = deg2rad(lat2-lat1); // deg2rad below
  const dLon = deg2rad(lon2-lon1);
  const a =
        Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
        Math.sin(dLon/2) * Math.sin(dLon/2)
      ;
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  const d = R * c; // Distance in km
  return d;


function deg2rad(deg) 
  return deg * (Math.PI/180);


function findClosePosts(location, radius, posts) 
  return posts.filter((post) =>
    // find close points within the radius of the location, but exclude the location itself from results
    getDistanceFromLatLonInKm(location.latitude, location.longitude, post.latitude, post.longitude) <= radius && location !== post);


function findLocationByName(name, posts) 
  return posts.find((post) => post.name === name);


const hamburg = findLocationByName('Hamburg', posts);
const closePosts = findClosePosts(hamburg, 200, posts);
console.log(closePosts);

【讨论】:

非常感谢,我确实使用了我刚刚在这里输入的 rnadomc oords,不知道它们的实际距离是多少 :) 这看起来比其他答案简单得多,不确定要使用什么,但谢谢很多:)

以上是关于如何检查坐标是不是在以公里为单位的半径范围内?的主要内容,如果未能解决你的问题,请参考以下文章

在原点的给定半径范围内和外部生成随机坐标

使用 google s2 库 - 查找圆圈内某个级别的所有 s2 单元,给定 lat/lng 和以英里/公里为单位的半径

如何使用geofire查询检查10公里半径内是不是存在firebase用户

如何在世界地图上准确地绘制半径以公里为单位的圆

如何将距离(以公里为单位)添加到以度和分钟为单位的位置坐标中,以获得 Java 中的新位置坐标?

在百度地图中,已知圆的圆心坐标、 和圆的半径(单位:米),怎么计算圆的坐标范围?