将经纬度转化为距离

3
我的问题有点棘手,如果我的问题并不清楚,我表示歉意。
我使用的是GoogleMap v3 API。用户可以在地图上单击以创建一个标记,如果他单击标记,我会将纬度和经度信息放入infoWindow(已完成)。
我尝试的事情是:用户可以给出尺寸(公里/英里),我必须画出给定尺寸的矩形(创建标记应该是该区域的中心)。问题来自于只采用纬度和经度的latlng或bounds。所以我试图进行转换。
以下是代码的主要部分。
//latitude
// 1°lat = 111,11 km
//for me: 1km = 0.00900 .

//longitude
//1°lat =  111,11 km * cos latitude
// for me : 1 km = ((1/Math.cos(latitude)) /111.11)

var myBounds = new Array();

var longkm = 5;
var largkm = 2;
myBounds[0] = new google.maps.LatLngBounds(
    new google.maps.LatLng(positionmarqueur.lat()-(0.009*longkm), positionmarqueur.lng()-(Math.abs(((1/Math.cos(positionmarqueur.lat()-(0.009*longkm))) /111.11))*largkm)),
    new google.maps.LatLng(positionmarqueur.lat()+(0.009*longkm), positionmarqueur.lng()+(Math.abs(((1/Math.cos(positionmarqueur.lat()+(0.009*longkm))) /111.11))*largkm))
);

var overlay1 = new google.maps.Rectangle({
    map: map,
    bounds: myBounds[0],
    strokeColor: "green",
    strokeWeight: 1
});

var longkm = 10;
var largkm = 10;
myBounds[1] = new google.maps.LatLngBounds(
    new google.maps.LatLng(positionmarqueur.lat()-(0.009*longkm), positionmarqueur.lng()-(Math.abs(((1/Math.cos(positionmarqueur.lat()-(0.009*longkm))) /111.11))*largkm)),
    new google.maps.LatLng(positionmarqueur.lat()+(0.009*longkm), positionmarqueur.lng()+(Math.abs(((1/Math.cos(positionmarqueur.lat()+(0.009*longkm))) /111.11))*largkm))
);

var overlay2 = new google.maps.Rectangle({
    map: map,
    bounds: myBounds[1],
    strokeColor: "blue",
    strokeWeight: 1
});

这应该绘制一个5*2的矩形和一个10*10公里的正方形(信息:在代码中上面是 var positionmarqueur = latLng)。

如果我看一下结果:第一个矩形看起来超过50/20公里。(我在除以10时有误吗?我不是很擅长数学,但看起来正确)。

第二个……就像一个200*40公里的矩形……

那么问题出在哪里?是公式有误吗?还是我太傻了,漏了什么?

谢谢。

1个回答

3
使用的算法是:
  var largkm = 5,
      longkm = 10;

  var bounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(positionmarqueur.lat() - ((largkm/2)/110.54), positionmarqueur.lng() - ((longkm/2)/(Math.cos(positionmarqueur.lat())*111.32))),
    new google.maps.LatLng(positionmarqueur.lat() + ((largkm/2)/110.54), positionmarqueur.lng() + ((longkm/2)/(Math.cos(positionmarqueur.lat())*111.32)))
  );

(注意:由于我们是从中心定义边界,因此将矩形大小除以2)

演示请见 http://jsfiddle.net/gaby/a5QVM/


更新

您应该使用谷歌几何库,该库使用谷歌地图使用的任何投影,因此转换将准确无误。(您需要更改Google API的URL为:http://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=false

更具体地说,您应该使用google.maps.geometry.spherical.computeOffset方法。

var rectbounds = new google.maps.LatLngBounds(
    spherical.computeOffset(spherical.computeOffset(positionmarqueur, longkm*1000/2, -90),largkm*1000/2,0),
    spherical.computeOffset(spherical.computeOffset(positionmarqueur, longkm*1000/2, 90), largkm*1000/2,180)
);

更新的演示:http://jsfiddle.net/a5QVM/10/
*1000 是为了将距离转换为米,因为这是 computeOffset 方法所期望的单位


如果你使用克莱蒙费朗的位置(45.7581263,3.1317803),有一个小技巧。我将编辑jsfiddle并提供有效的答案。 - ssbb
你确定这个公式没问题吗?我的意思是,如果你画一个100/100公里的正方形,它实际上不是正方形,而是一个长方形,这是因为JavaScript的近似计算吗?还是因为地球的倾斜导致我在Google地图上看到的是这样的? - ssbb
1
@ssbb更新了答案,提供了更准确的解决方案(使用谷歌方法进行转换)。 - Gabriele Petrioli
@GabrielePetrioli 当我使用球形边界并调用 LatLngBounds.getSouthWest()getNorthEast() 时,我得到的是西北和东南边界?发生了什么导致这些被颠倒 - http://jsfiddle.net/mtpultz/dspqxLzr/24/. 我添加了控制台日志记录。 - mtpultz
如果我在等式中交换0和180,似乎可以解决这个问题 - http://jsfiddle.net/mtpultz/dspqxLzr/29/ - mtpultz

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