【问题标题】:PHP calculate lat/lng of the square around a given point on the surface?PHP计算表面上给定点周围正方形的纬度/经度?
【发布时间】:2011-12-04 04:58:38
【问题描述】:

给定地球表面点的纬度/经度(以及距离,例如公里),我需要计算左上角、右上角、右下角和左下角的坐标。无论正方形的方向如何。

我找到了一个不错的 PHP 类,用于计算表面上两点之间的距离,但不幸的是,没有关于围绕一个点的正方形(甚至是圆)的函数。

【问题讨论】:

  • 地球表面没有正方形这样的东西,除非你说的是很小的距离。
  • 现在,地球表面是极地的,正方形和圆形 - 都是笛卡尔坐标。想象一个正方形,就像你想象一个坐标系一样,证明它是正确的 - 使左下角尖端为零 (0;0)。从那里开始,您会很容易通过它。但是,如果你想用一个圆圈来做到这一点,那就更复杂了。给定一个圆,我首先将圆中点定位到零 (0;0) 上,现在圆的每个点都必须与 (0;0) 之间的距离为 r,这样您就可以轻松计算出您想要的值..
  • @kenansulayman 简单地说,我需要它用于 panoramio rest api:它需要发送一个带有 min lat、max lat、min lng、max lng 的请求,即定义一个正方形。这个想法是在给定点周围显示照片,距离为 5 公里。我熟悉极坐标/线性和其他东西。
  • 也许他属于平地社会。
  • @Dagon 我懒洋洋的,但 cmon' 是认真的!

标签: php geolocation geometry geocoding


【解决方案1】:

这可能对你有用。这里的方法是从给定点从正北、正东、正西和正南找到目的地点。函数getSquareAroundPoint返回一个指定这四个点的数组,函数getMinMaxCoords返回这些点的最小和最大坐标,按照你提到的REST API的要求(它作为数组的数组返回,以防万一输入坐标在 180 度子午线附近。)它被放置在公共域中。

该方法包括在给定坐标、距离和方位的情况下找到目标点。这种计算称为求解“直接测地线问题”,这在 C.F.F. 中有讨论。 Karney 的文章“Algorithms for geodesics”,2012。下面的getDestinationPoint 方法使用的技术不如 Karney 文章中介绍的算法准确,尤其是因为该技术假设地球是一个完美的球体。

// Distance is in km, alat and alon are in degrees
function getDestinationPoint($alat, $alon, $distance, $bearing){
 $pi=3.14159265358979;
 $alatRad=$alat*$pi/180;
 $alonRad=$alon*$pi/180;
 $bearing=$bearing*$pi/180;
 $alatRadSin=sin($alatRad);
 $alatRadCos=cos($alatRad);
 // Ratio of distance to earth's radius
 $angularDistance=$distance/6370.997;
 $angDistSin=sin($angularDistance);
 $angDistCos=cos($angularDistance);
 $xlatRad = asin( $alatRadSin*$angDistCos +
                                   $alatRadCos*$angDistSin*cos($bearing) );
 $xlonRad = $alonRad + atan2(
            sin($bearing)*$angDistSin*$alatRadCos,
            $angDistCos-$alatRadSin*sin($xlatRad));
 // Return latitude and longitude as two element array in degrees
 $xlat=$xlatRad*180/$pi;
 $xlon=$xlonRad*180/$pi;
 if($xlat>90)$xlat=90;
 if($xlat<-90)$xlat=-90;
 while($xlat>180)$xlat-=360;
 while($xlat<=-180)$xlat+=360;
 while($xlon>180)$xlon-=360;
 while($xlon<=-180)$xlon+=360;
 return array($xlat,$xlon);
}

// Distance is in km, lat and lon are in degrees
function getSquareAroundPoint($lat,$lon,$distance){
 return array(
  getDestinationPoint($lat,$lon,$distance,0), // Get north point
  getDestinationPoint($lat,$lon,$distance,90), // Get east point
  getDestinationPoint($lat,$lon,$distance,180), // Get south point
  getDestinationPoint($lat,$lon,$distance,270) // Get west point
 );
}

// Returns array containing an array with min lat, max lat, min lon, max lon
// If the square defining these points crosses the 180-degree meridian, two
// such arrays are returned.  Otherwise, one such array (within another array)
// is returned.
function getMinMaxCoords($lat,$lon,$distance){
 $s=getSquareAroundPoint($lat,$lon,$distance);
 if($s[3][1]>$s[1][1]){// if west longitude is greater than south longitude
  // Crossed the 180-degree meridian
  return array(
    array($s[2][0],$s[0][0],$s[3][1],180),
    array($s[2][0],$s[0][0],-180,$s[1][1])
  );
 } else {
  // Didn't cross the 180-degree meridian (usual case)
  return array(
    array($s[2][0],$s[0][0],$s[3][1],$s[1][1])
  );
 }
}

// Example: Gets extreme coordinates around point at (10.0,20.0)
print_r(getSquareAroundPoint(10.0,180,100));
print_r(getMinMaxCoords(10.0,180,100));

【讨论】:

  • 他一直在说平面正方形。你的方程是关于极球上的一个正方形..或者你是对的吗?他的问题不清楚。
  • @kenansulayman:如果您阅读了 Gremo 将如何使用以下信息:“需要发送带有 min lat、max lat、min lng、max lng 的请求,即定义一个正方形”,以及输入:“地球表面的一个点”,很明显输出坐标是极坐标。但是,特别是对于“距离——比如 5 公里”,无论如何,差异可能是微不足道的。然而,假设输入靠近 180 度子午线或靠近任一极点。除非“panoramio rest api”可以接受这种特殊情况,否则使用笛卡尔方法的近似值可能会导致一些可怕的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
  • 1970-01-01
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
相关资源
最近更新 更多