【问题标题】:Haversine Formula - Results Too HighHaversine 公式 - 结果太高
【发布时间】:2014-08-20 16:41:04
【问题描述】:

我正在使用Haversine 公式来计算地球上两点之间的距离。我有以下代码:

    var app = angular.module('app', []);
app.controller('firstCtrl', function($scope, $timeout) {
  var myLat, myLon, locLat, locLon;
  navigator.geolocation.watchPosition(GetLocation)

  $scope.ASiteLocs = [{
    "name": "IL5077 BRUSSELS",
    "styleUrl": "#waypoint",
    "Point": {
      "coordinates": "-90.58543899999999,38.955472,0"
    }
  }, {
    "name": "IL5076 KAMPSVILLE",
    "styleUrl": "#waypoint",
    "Point": {
      "coordinates": "-90.661923,39.29403,0"
    }
  }, {
    "name": "IL5146 CARROLLTON",
    "styleUrl": "#waypoint",
    "Point": {
      "coordinates": "-90.39965700000001,39.309142,0"
    }
  }, {
    "name": "IL5153 GREENFIELD",
    "styleUrl": "#waypoint",
    "Point": {
      "coordinates": "-90.208747,39.364077,0"
    }
  }];
  $scope.SSiteLocs = [];
  $scope.SiteLocs = $scope.SSiteLocs.concat($scope.ASiteLocs);
  repoSortOrder = "site.name";


  function GetLocation(location, myLat, myLon) {
    myLat = location.coords.latitude;
    myLon = location.coords.longitude;
    document.getElementById("lat").innerHTML = myLat;
     document.getElementById("lon").innerHTML = myLon;
    $timeout(function() {
      calculate();
    });

  }

  $scope.getCoordDistance = function(myLat, myLon, locLat, locLon) {
    var lat1 = locLat; //41.887055
    var lon1 = locLon; //-88.469233
    var lat2 = myLat; //41.888668
    var lon2 = myLon; //-87.640371

    var R = 3959;
    var x1 = lat2 - lat1;
    var dLat = x1 * Math.PI / 180;
    var x2 = lon2 - lon1;
    var dLon = x2 * Math.PI / 180;
    a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
      Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
      Math.sin(dLon / 2) * Math.sin(dLon / 2);
    c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;

  };


  angular.forEach($scope.SSiteLocs, function(object) {
    object.carrier = 'Sprint';
  });
  angular.forEach($scope.ASiteLocs, function(object) {
    object.carrier = 'AT&T';
  });
var i = 0;
locX = 1;
  var calculate = function() {
    angular.forEach($scope.SiteLocs, function(location) {
      var clength = location.Point.coordinates.length;
      if (location.Point.coordinates.substring(clength - 2, clength) === ",0") {
        location.Point.coordinates = location.Point.coordinates.substring(0, clength - 2).split(",");
        Lat = location.Point.coordinates[0];
        Lon = location.Point.coordinates[1];
        Com = ",";
        location.Point.coordinates = Lon.concat(Com, Lat);
      myLat = Number(document.getElementById("lat").innerHTML)
      myLon = Number(document.getElementById("lon").innerHTML)

      locLat = Lat;
      locLon = Lon;
      d = $scope.getCoordDistance(myLat, myLon, locLat, locLon);
      location.distance = d.toFixed(1);

    if(i < 15){
      console.log("********LOCATON " + locX + "***********")
      console.log("myCoords: " + myLat + "," + myLon);
      console.log("locCoords: " + locLat + "," + locLon);

      console.log("d: " + d);
      console.log("***************************")
      i++;
      locX++;

    }
    }

    });
  };


});

公式的结果最高可达 9-10,000 左右,而它们不应该接近那么高。如果我使用注释掉的坐标,它会正确返回(42.6 英里) 由于测试坐标有效,我知道这不是数学问题。有人知道是什么导致公式无法正常工作吗?
编辑
Here 是完整项目的一个笨蛋。如果这有帮助。
EDIT2
我发现了一些奇怪的东西,不同浏览器的结果不同,所以,chrome显示一组数字,IE显示另一组,等等。

【问题讨论】:

    标签: javascript angularjs geolocation coordinates haversine


    【解决方案1】:

    您的点坐标是经纬度

    BRUSSELS",
        "
        "Point": {
          "coordinates": "-90.58543899999999,38.955472
    

    在您的代码中

    Lat = location.Point.coordinates[0];
    Lon = location.Point.coordinates[1];
    

    在您的对象中更改它们(首选)请参阅 Google latlng class

    "Point": {
              "coordinates": "38.955472,-90.58543899999999
    

    Lat = location.Point.coordinates[1];
    Lon = location.Point.coordinates[0];
    

    您的设置距离约为 9000 英里,坐标转置距离约为 200

    【讨论】:

      【解决方案2】:

      除了 kirinthos 在他的回复中所说的之外,您还可以通过将结果与 Google 地图进行比较来轻松测试这一点。我的应用程序中有一个功能可以做到这一点。 point1 和 point2 参数是简单的 Latlng 对象。我想要以公里为单位的结果,所以我除以 1000。

      function calculateDistanceBetweenTwoPoints(point1, point2) {
          return (google.maps.geometry.spherical.computeDistanceBetween(point1, point2) / 1000).toFixed(2);
      }
      

      您的 HTML 页面中需要以下内容:

      <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,places"></script>
      

      【讨论】:

      • 我认为脚本标签中有错字。
      【解决方案3】:

      在这里,我不完全确定,没有对其进行测试,但看起来 GetLocation 函数通过将变量 myLat 和 myLon 声明为函数参数来覆盖它们的闭包范围,因此您正在分配位置的值。 coords.latitude 到函数作用域 myLat 变量中,而不是在代码块开头声明的 myLat。

      抛出一个console.log(myLat, myLon);进入 getCoordDistance 的开头并检查它们的值。我敢打赌,它们不是你所期望的。

      编辑:实际上可能是缺少分号之类的。这是您的代码的一个小 sn-p,经过重新校准,可以在 jsbin.com 等隔离环境中运行。它似乎工作正常。您缺少 4 个分号,因此除非此分配失败,否则它应该可以工作: myLon = Number(document.getElementById("lon").innerHTML)

      有人抱怨没有定义变量“i”和“locX”

      var myLat, myLon;
      
      var ASiteLocs = [{
          "name": "IL5077 BRUSSELS",
          "styleUrl": "#waypoint",
          "Point": {
            "coordinates": "-90.58543899999999,38.955472,0"
          }
        }, {
          "name": "IL5076 KAMPSVILLE",
          "styleUrl": "#waypoint",
          "Point": {
            "coordinates": "-90.661923,39.29403,0"
          }
        }, {
          "name": "IL5146 CARROLLTON",
          "styleUrl": "#waypoint",
          "Point": {
            "coordinates": "-90.39965700000001,39.309142,0"
          }
        }, {
          "name": "IL5153 GREENFIELD",
          "styleUrl": "#waypoint",
          "Point": {
            "coordinates": "-90.208747,39.364077,0"
          }
        }];
      
      var SSiteLocs = [];
      var SiteLocs = SSiteLocs.concat(ASiteLocs);
      
      function GetLocation(location, myLat, myLon) {
          myLat = location.coords.latitude;
          myLon = location.coords.longitude;
          document.getElementById("lat").innerHTML = myLat;
           document.getElementById("lon").innerHTML = myLon;
      
        }
      
      function getCoordDistance(myLat, myLon, locLat, locLon) {
          var lat1 = locLat; //41.887055
          var lon1 = locLon; //-88.469233
          var lat2 = myLat; //41.888668
          var lon2 = myLon; //-87.640371
      
          var R = 3959;
          var x1 = lat2 - lat1;
          var dLat = x1 * Math.PI / 180;
          var x2 = lon2 - lon1;
          var dLon = x2 * Math.PI / 180;
          a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
          c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
          var d = R * c;
          return d;
      
        };
      
      
      function calculate() {
          SiteLocs.forEach(function(location) {
            var clength = location.Point.coordinates.length;
            if (location.Point.coordinates.substring(clength - 2, clength) === ",0") {
              location.Point.coordinates = location.Point.coordinates.substring(0, clength - 2).split(",");
              Lat = location.Point.coordinates[0];
              Lon = location.Point.coordinates[1];
              Com = ",";
              location.Point.coordinates = Lon.concat(Com, Lat);
            myLat = -90.208747;
            myLon = 39.364077;
      
            locLat = Lat;
            locLon = Lon;
            d = getCoordDistance(myLat, myLon, locLat, locLon);
            location.distance = d.toFixed(1);
      
          //console.log("********LOCATON " + locX + "***********");
            console.log("myCoords: " + myLat + "," + myLon);
            console.log("locCoords: " + locLat + "," + locLon);
      
            console.log("d: " + d);
            console.log("***************************");
      
          }
      
          });
        };
      

      【讨论】:

      • myLatmyLongetCoordDistance 的预期值,所以我认为不是这样。不过谢谢!
      • 你能给我提供调用 getCoordDistance 的四个值吗?
      • myLatmyLon 是来自 navigate.geolocation.eatchPositionlocLat 的坐标,locLon 是来自 coordinates$scope.ASiteLocs 中的坐标
      • 我将你的代码导入到测试环境并编辑了,有一些分号问题,但似乎可以工作
      • 距离表中的一些结果是什么?
      猜你喜欢
      • 1970-01-01
      • 2012-03-15
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 2011-09-12
      • 2012-06-10
      相关资源
      最近更新 更多