PHP计算表面上给定点周围的方形的lat / lng?

时间:2011-10-10 02:06:01

标签: php geolocation geometry geocoding

给定地球表面的纬度/经度(以及以千米为单位的距离),我需要计算左上角,右上角,右下角和左下角坐标。无论广场的方向如何。

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

1 个答案:

答案 0 :(得分:4)

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

// 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));