Javascript&;谷歌地图圈
目前我使用的公式如下,但不如Vincenty公式准确,你可以在这个链接上找到: 我的问题是,有人能帮我简化javascript代码,让我在公式中实现它吗?我正在尝试学习javascript,但它有点超出了我的能力 ex=lat2 ey=2 我认为最简单的方法是运行代码,然后做一个360度的数组来计算ex/ey坐标Javascript&;谷歌地图圈,javascript,google-maps-api-3,Javascript,Google Maps Api 3,目前我使用的公式如下,但不如Vincenty公式准确,你可以在这个链接上找到: 我的问题是,有人能帮我简化javascript代码,让我在公式中实现它吗?我正在尝试学习javascript,但它有点超出了我的能力 ex=lat2 ey=2 我认为最简单的方法是运行代码,然后做一个360度的数组来计算ex/ey坐标 <script type="text/javascript"> function drawCircle(point, radius, dir, addtoBounds
<script type="text/javascript">
function drawCircle(point, radius, dir, addtoBounds) {
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var earthsradius = 6378137;
var points = 360;
// find the radius in lat/lon
var rlat = (radius / earthsradius) * r2d;
var rlng = rlat / Math.cos(point.lat() * d2r);
var extp = new Array();
if (dir==1) {var start=0;var end=points+1} // one extra here makes sure we connect the
else {var start=points+1;var end=0}
for (var i=start; (dir==1 ? i < end : i > end); i=i+dir)
{
var theta = Math.PI * (i / (points/2));//i is number of points + 1
var lat1=point.lat()*d2r;
var lon1=point.lng()*d2r;
var d=radius;
var R=earthsradius;
var ex = Math.asin( Math.sin(lat1)*Math.cos(d/R) +
Math.cos(lat1)*Math.sin(d/R)*Math.cos(theta));
var ey = lon1 + Math.atan2(Math.sin(theta)*Math.sin(d/R)*Math.cos(lat1),
Math.cos(d/R)-Math.sin(lat1)*Math.sin(ex));
extp.push(new google.maps.LatLng(ex*r2d, ey*r2d));
if (addtoBounds) bounds.extend(extp[extp.length-1]);
}
// alert(extp.length);
return extp;
}
函数drawCircle(点、半径、方向、添加边界){
var d2r=Math.PI/180;//度到弧度
var r2d=180/Math.PI;//弧度到度
var earthsradius=6378137;
var点=360;
//以lat/lon为单位查找半径
var rlat=(半径/地球半径)*r2d;
var rlng=rlat/Math.cos(point.lat()*d2r);
var extp=新数组();
如果(dir==1){var start=0;var end=points+1}//这里有一个额外的值确保我们连接
else{var start=points+1;var end=0}
对于(变量i=start;(dir==1?iend);i=i+dir)
{
var theta=Math.PI*(i/(点数/2));//i是点数+1
var lat1=point.lat()*d2r;
var lon1=point.lng()*d2r;
var d=半径;
var R=地球半径;
var ex=数学asin(数学sin(lat1)*数学cos(d/R)+
数学cos(lat1)*数学sin(d/R)*数学cos(theta));
变量ey=lon1+Math.atan2(Math.sin(θ)*Math.sin(d/R)*Math.cos(lat1),
数学cos(d/R)-数学sin(lat1)*数学sin(ex));
extp.push(新的google.maps.LatLng(ex*r2d,ey*r2d));
if(addtoBounds)bounds.extend(extp[extp.length-1]);
}
//警报(扩展长度);
返回extp;
}
下面是转换为php的直接公式。我正在尝试将此代码放入谷歌地图代码中。movable type链接实际上在javascript中有这段代码,但由于我对php了解得更多,所以我将其转换为测试代码,这段代码运行得非常完美
<?php
$lat1 = 29.10860062;
$lon1 = -95.46209717;
$a = 6378137;
$b = 6356752.314245;
$f = 1/298.257223563; // WGS-84 ellipsoid params
$brng = 32.8;
$s = 1796884.48;
$alpha1 = deg2rad($brng);
$sinAlpha1 = sin($alpha1);
$cosAlpha1 = cos($alpha1);
$tanU1 = (1-$f) * tan(deg2rad($lat1));
$cosU1 = 1 / sqrt((1 + pow($tanU1,2)));
$sinU1 = $tanU1*$cosU1;
$sigma1 = atan2($tanU1, $cosAlpha1);
$sinAlpha = $cosU1 * $sinAlpha1;
$cosSqAlpha = 1 - pow($sinAlpha,2);
$uSq = $cosSqAlpha * (pow($a,2) - pow($b,2)) / (pow($b,2));
$A = 1 + $uSq/16384*(4096+$uSq*(-768+$uSq*(320-175*$uSq)));
$B = $uSq/1024 * (256+$uSq*(-128+$uSq*(74-47*$uSq)));
$sigma = $s / ($b*$A);
$sigmaP = 2*pi;
$limit = 100;
$counter = 1;
while ( $counter <= $limit ) {
$cos2SigmaM = cos(2*$sigma1 + $sigma);
$sinSigma = sin($sigma);
$cosSigma = cos($sigma);
$deltaSigma = $B*$sinSigma*($cos2SigmaM+$B/4*($cosSigma*(-1+2*pow($cos2SigmaM,2))-$B/6*$cos2SigmaM*(-3+4*pow($sinSigma,2))*(-3+4*pow($cos2SigmaM,2))));
$sigmaP = $sigma;
$sigma = $s / ($b*$A) + $deltaSigma;
$counter = $counter+1;
};
$tmp = $sinU1*$sinSigma - $cosU1*$cosSigma*$cosAlpha1;
$lat2 = atan2($sinU1*$cosSigma + $cosU1*$sinSigma*$cosAlpha1,(1-$f)*sqrt(pow($sinAlpha,2)+ pow($tmp,2)));
$lambda = atan2($sinSigma*$sinAlpha1, $cosU1*$cosSigma - $sinU1*$sinSigma*$cosAlpha1);
$C = $f/16*$cosSqAlpha*(4+$f*(4-3*$cosSqAlpha));
$L = $lambda - (1-$C) * $f * $sinAlpha *($sigma + $C*$sinSigma*($cos2SigmaM+$C*$cosSigma*(-1+2*pow($cos2SigmaM,2))));
if (deg2rad($lon1)+$L+(3*pi)<(2*pi)) {
( $lon2 = (deg2rad($lon1)+$L+(3*pi))-pi);
} else {
( $lon2 = ((deg2rad($lon1)+$L+3*pi))%(2*pi))-pi;}
$revAz = atan2($sinAlpha, -$tmp); // final bearing, if required
?>
由于您提供的链接已经在javascript中提供了公式,所以硬部分已经完成,您可以复制它并调用它,而不是将其重写到您的函数中。只需记住对源进行属性设置。我删除了没有被使用的变量。另外,我只是将
361
硬编码到公式中,因为您只是将其分配给一个points变量。如果要将度数传递到公式中,可以将其更改回原来的值。我为循环分离了,对我来说这更具可读性,而且我认为您以前的工作方式与您的预期不符。在处理度和弧度时,我总是将这些转换打包成函数,因为这样可以提高可读性。为此,我使用prototype
将它们连接到JavaScript中的Number
对象,如下所示:
Number.prototype.toRad = function() {
//'this' is the current number the function is acting on.
//e.g. 360.toRad() == 2PI radians
return this * Math.PI / 180;
}
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
}
不太难理解,prototype允许您在JavaScript中扩展对象,类似于基于类的语言中的继承。网上有很多资源可以帮助澄清
以下是经过修改的drawCircle函数:
function drawCircle(point, radius, dir, addtoBounds) {
//best practice is to use [] rather then new Array(),
//both do the same thing.
var extp = [];
if (dir == 1) {
for (var i = 0; i < 361; i++) {
//destVincenty function returns a object with
//lat, lon, and final bearing.
var destPoint = destVincenty(point.lat(), point.lng(), i, radius);
//add new point
extp.push(new google.maps.LatLng(destPoint.lat, destPoint.lon));
if (addtoBounds) bounds.extend(extp[extp.length - 1]);
}
}
else {
for (var i = 361; i > 0; i--) {
var destPoint = destVincenty(point.lat(), point.lng(), i, radius);
extp.push(new google.maps.LatLng(destPoint.lat, destPoint.lon));
if (addtoBounds) bounds.extend(extp[extp.length - 1]);
}
}
return extp;
}
函数绘图圆(点、半径、方向、添加边界){
//最佳做法是使用[],而不是使用新数组(),
//两者都做同样的事情。
var extp=[];
if(dir==1){
对于(变量i=0;i<361;i++){
//destVincenty函数返回具有
//lat、lon和最终轴承。
var destPoint=destVincenty(point.lat(),point.lng(),i,半径);
//添加新点
extp.push(新的google.maps.LatLng(destPoint.lat,destPoint.lon));
if(addtoBounds)bounds.extend(extp[extp.length-1]);
}
}
否则{
对于(var i=361;i>0;i--){
var destPoint=destVincenty(point.lat(),point.lng(),i,半径);
extp.push(新的google.maps.LatLng(destPoint.lat,destPoint.lon));
if(addtoBounds)bounds.extend(extp[extp.length-1]);
}
}
返回extp;
}
下面是一个。有帮助吗?我感谢您花时间编写代码。我很感激,但在我挖掘的过程中。我发现哈弗森公式对我需要的东西不太准确。Vincenty公式就是我想要的。我正试图使你的代码适应新的公式。任何帮助都会很好。再次感谢你。啊哈。名称不匹配。我已经确定了为什么我学习javascript速度慢,它不会像php那样告诉你错误在哪里。布莱恩,在你给我这个代码后,我花了大约一个小时才让它开始工作,不得不改变一些关于ect的事情,这个公式是完美的。我添加了Andrew Leach上周提供的阴影(参见他发布的链接)。非常感谢您花这么多时间。是的,JavaScript调试有时会很痛苦。有许多工具可以帮助定位和调试错误。下面列出了一些最常见的方法。就个人而言,我喜欢Firebug和IE9内置开发工具。