这可能对你有用。这里的方法是从给定点从正北、正东、正西和正南找到目的地点。函数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));