我正在使用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万,当它们不应该接近那么高时。如果我使用注释掉的坐标,它会正确返回(42.6英里)
由于测试坐标工作,我知道这不是一个数学问题。有人知道是什么导致公式无法正常工作吗?
编辑
Here是整个项目的掠夺者。如果这有帮助。
EDIT2
我发现了一些奇怪的东西,结果在不同的浏览器中有所不同,因此,chrome显示一组数字,IE显示另一组,等等。
答案 0 :(得分:0)
我不完全确定,在这里,没有测试它,但看起来GetLocation函数通过将它们声明为函数参数来覆盖变量myLat和myLon的闭包范围,所以你要分配location.coords.latitude的值到函数作用域myLat变量中,而不是在代码块开头声明的myLat。
抛出console.log(myLat,myLon);进入getCoordDistance的开头并检查它们的值。我敢打赌,他们并不是你所期望的。
编辑:它实际上可能是缺少分号和东西。这里有一小段代码重新校准,可以在像jsbin.com这样的隔离环境中运行。它似乎工作正常。你缺少4个分号,所以除非这个赋值失败,否则它应该有效:myLon = Number(document.getElementById(&#34; lon&#34;)。innerHTML)
有人抱怨变数&#34; i&#34;和&#34; locX&#34;没有被定义
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("***************************");
}
});
};
答案 1 :(得分:0)
除了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>
答案 2 :(得分:0)
您的点坐标是经度纬度
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英里,坐标转置距离是aprox 200