使用地理定位使用 JavaScript(组合脚本)向 Web 访问者显示最近的位置

Use Geolocation Show Nearest Location to Web Visitor using JavaScript (COMBINING SCRIPTS)

我目前正在重做我公司的网站。如果有人加载我们新站点的任何页面,在位置精确图标旁边的顶部栏中显示离他们最近的位置或在企业服务半径 (±20mi) 内的位置,那将是非常酷的。几天来我一直在寻找如何找到实现这一目标的方法,而 JavaScript 似乎是实现这一目标的唯一方法。我是 JS 的新手,所以我不确定完成它的最佳方法。

我需要组合以下脚本,这些脚本可以单独完美运行,但目前不能组合在一起。

////// SCRIPT 1 /////////
function geoFindMe() {

  const status = document.querySelector('#status');
  const mapLink = document.querySelector('#map-link');

  mapLink.href = '';
  mapLink.textContent = '';

  function success(position) {
    const latitude  = position.coords.latitude;
    const longitude = position.coords.longitude;

    status.textContent = '';
    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
    mapLink.textContent = `Latitude: ${latitude} °, Longitude: ${longitude} °`;
  }

  function error() {
    status.textContent = 'Unable to retrieve your location';
  }

  if (!navigator.geolocation) {
    status.textContent = 'Geolocation is not supported by your browser';
  } else {
    status.textContent = 'Locating…';
    navigator.geolocation.getCurrentPosition(success, error);
  }

}

document.querySelector('#find-me').addEventListener('click', geoFindMe);


//////////// SCRIPT 2 ////////////

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 = [{
        "lat": "36.5983825",
        "lng": "-82.1828577",
        "location": "Bristol"
    }, {
        "lat": "36.7053664",
        "lng": "-81.999551",
        "location": "Abingdon"
    }, {
        "lat": "35.9120595",
        "lng": "-84.0979276",
        "location": "West Knoxville"
    }, {
        "lat": "35.8718708",
        "lng": "-83.5642387",
        "location": "Sevierville"
    }];

    var html = "";
    var poslat = 36.5983825;
    var poslng = -82.1828577;
    
    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, "M") <= 20) {
            html += '<a href="/' + data[i].location + '" target="_blank"><i class="icon-location"></i>' + data[i].location + '</a> ';
        }
    }
    
    $('#nearestLocation').append(html);
///// SCRIPT 1 //////<br><br>

<button id = "find-me">Show my location</button><br/>
<p id = "status"></p>
<a id = "map-link" target="_blank"></a>

///// SCRIPT 2 //////<br><br>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="nearestLocation"></div>
<br>
<br>

脚本 1 根据请求获取用户的当前位置,脚本 2 将给定的 lat/long 与其余位置进行比较,以找到 20 英里半径内最近的集合。

我们在 U.S 中有 14 个地点。只有,这就是为什么我们需要使用 GeoLocation 而不是 GeoIP。 GeoIP 对我们来说不够准确。

postlat 和 postlng 是脚本 2 用来与给定的 lat/lng 坐标进行比较的,脚本 1 可以提供这些,我只是无法让它们一起工作以实现相同的共同目标。

谢谢!

附件是我正在寻找的解决方案,以防其他人处于同样的困境。请记住,这只有在您的 HTML 5 网站上有有效的 SSL 证书时才会起作用。

var lat = 0;
var lng = 0;
function geoFindMe() {

  const status = document.querySelector('#status');
  const mapLink = document.querySelector('#map-link');

  mapLink.href = '';
  mapLink.textContent = '';

  function success(position) {
    const latitude  = position.coords.latitude;
    const longitude = position.coords.longitude;

    status.textContent = '';
    mapLink.href = ``;
    mapLink.textContent = ``;
    lat = position.coords.latitude;
    lng = position.coords.longitude;
    showNearestLocations();
  }

  function error() {
    status.textContent = 'Unable to retrieve your location';
  }

  if (!navigator.geolocation) {
    status.textContent = 'Geolocation is not supported by your browser';
  } else {
    status.textContent = 'Locating…';
    navigator.geolocation.getCurrentPosition(success, error);
  }

}

document.querySelector('#find-me').addEventListener('click', geoFindMe);


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
    }

function showNearestLocations() {
    var data = [{
        "lat": 36.5983825,
        "lng": -82.1828577,
        "location": "Bristol",
        "link": "bristol",
    }, {
        "lat": 36.7053664,
        "lng": -81.999551,
        "location": "Abingdon",
        "link": "abingdon",
    }, {
        "lat": 35.9120595,
        "lng": -84.0979276,
        "location": "West Knoxville",
        "link": "west-knoxville",
    }, {
        "lat": 35.8718708,
        "lng": -83.5642387,
        "location": "Sevierville",
        "link": "sevierville",
    }];

    var html = "";
    var poslat = lat;
    var poslng = lng;
    
    var found = false;
    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, "M") <= 20) {
            html += '<a href="/' + data[i].link + '" target="_blank"><i class="icon-location"></i>' + data[i].location + '</a> ';
          found = true;
        }
    }
    
    $('#nearestLocation').html(html);
    if (!found) {
      $('#nearestLocation').html("no near location found");
    }
}
#map-link {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id = "find-me">Show my nearest locations</button> <span id="nearestLocation"></span><p id = "status"></p>
<a id = "map-link" target="_blank"></a>