私がやろうとしているのは、データベースにlat/longが保存されているエントリがあることです。ユーザーlat/longとエントリlat/long(DB内)の間の距離を計算したいと思います。その後、500メートル未満の距離のものをエコーしたいと思います。これまでのところ、foreach
を使用してこれを行うことができます。
<?php
mysql_connect("localhost", "beepbee_kunwarh", "kunwar") or die('MySQL Error.');
mysql_select_db("beepbee_demotest") or die('MySQL Error.');
$Lat = $_REQUEST['Lat'];
$long = $_REQUEST['long'];
$query = mysql_query("SELECT a.*, 3956 * 2 * ASIN(SQRT( POWER(SIN(($Lat - Lat) * pi()/180 / 2), 2) + COS($Lat * pi()/180) * COS(Lat * pi()/180) *POWER(SIN(($long - long) * pi()/180 / 2), 2) )) as distance FROM userResponse GROUP BY beepid HAVING distance <= 500 ORDER by distance ASC;");
$data = array();
while ($row = mysql_fetch_array($query)) {
$data[] = $row;
}
echo json_encode($data);
?>
私は数週間前にこれをしました。
このリンクはあなたの最善の策です:
http://code.google.com/apis/maps/articles/phpsqlsearch.html
APIを使用しない場合でも、PHPおよびSQLクエリは非常に役立ちました。
'denil'によって提示されたソリューションが独創的であることを認めたとしても、SQLステートメントに距離計算をダンプすることはお勧めしません。
3つの欠点があります:コードのメンテナンス、SQLサーバーの過負荷、そして(とりわけ)地球は対称的ではありません(トラックにひかれた古いへこんだ野球のようなものです)。これは、将来的にコードを変更したい場合があることを意味します(非常に洗練されたアルゴリズムがいくつかあります--- http://en.wikipedia.org/wiki/Geographical_distance )。
単純な一般的なアルゴリズム(デニルと同じではないにしても同様)で距離を計算する別の関数を使用することをお勧めします。私は純粋なphpであるこのコードを提出します(googlemapsapiを使用する必要はありません):
<?php
function distanceGeoPoints ($lat1, $lng1, $lat2, $lng2) {
$earthRadius = 3958.75;
$dLat = deg2rad($lat2-$lat1);
$dLng = deg2rad($lng2-$lng1);
$a = sin($dLat/2) * sin($dLat/2) +
cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
sin($dLng/2) * sin($dLng/2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$dist = $earthRadius * $c;
// from miles
$meterConversion = 1609;
$geopointDistance = $dist * $meterConversion;
return $geopointDistance;
}
// YOUR CODE HERE
echo distanceGeoPoints(22,50,22.1,50.1);
?>
地球の一部の許容誤差を確認できるフリーソフトウェア(gps trackmakerを試してください)がいくつかあります(精度が必要な場合)。上記の緯度/経度のペアの場合、誤差は+/- 0.1%以内です(地元の地形学者による)。
注意:この式は、地形距離(地形を考慮しない)ではなく、地図距離(海面での距離)を示します。
このクエリを試してください。グーグルで見つけたけど誰が作ったのか忘れた
SELECT a.*,
3956 * 2 * ASIN(SQRT( POWER(SIN(($lat - lat) * pi()/180 / 2), 2) + COS($lat * pi()/180) * COS(lat * pi()/180) *
POWER(SIN(($long - longi) * pi()/180 / 2), 2) )) as
distance FROM table
GROUP BY id HAVING distance <= 500 ORDER by distance ASC
$ latおよび$ long変数は、ユーザーの現在の位置です。 latとlongiは、エントリの緯度と経度です。
http://www.geodatasource.com/developers/php
<?php
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
/*:: :*/
/*:: This routine calculates the distance between two points (given the :*/
/*:: latitude/longitude of those points). It is being used to calculate :*/
/*:: the distance between two locations using GeoDataSource(TM) Products :*/
/*:: :*/
/*:: Definitions: :*/
/*:: South latitudes are negative, east longitudes are positive :*/
/*:: :*/
/*:: Passed to function: :*/
/*:: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) :*/
/*:: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) :*/
/*:: unit = the unit you desire for results :*/
/*:: where: 'M' is statute miles :*/
/*:: 'K' is kilometers (default) :*/
/*:: 'N' is nautical miles :*/
/*:: Worldwide cities and other features databases with latitude longitude :*/
/*:: are available at http://www.geodatasource.com :*/
/*:: :*/
/*:: For enquiries, please contact [email protected] :*/
/*:: :*/
/*:: Official Web site: http://www.geodatasource.com :*/
/*:: :*/
/*:: GeoDataSource.com (C) All Rights Reserved 2014 :*/
/*:: :*/
/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
function distance($lat1, $lon1, $lat2, $lon2, $unit) {
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles = $dist * 60 * 1.1515;
$unit = strtoupper($unit);
if ($unit == "K") {
return ($miles * 1.609344);
} else if ($unit == "N") {
return ($miles * 0.8684);
} else {
return $miles;
}
}
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "M") . " Miles<br>";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "K") . " Kilometers<br>";
echo distance(32.9697, -96.80322, 29.46786, -98.53506, "N") . " Nautical Miles<br>";
?>
3つの関数と3つのクエリのようにテストされ、1つだけが良好な距離を示しました。
メートル単位:
SELECT *,
(
(((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180))+cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344)
* 1000
) as `distance`
FROM `table`
ORDER BY `distance` ASC
キロメートル単位:
SELECT *,
(
(((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180))+cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344)
) as `distance`
FROM `table`
ORDER BY `distance` ASC
このクエリは私にとって完璧でした:
$latitude = "23.139422"; //your current lat
$longitude = "-82.382617"; //your current long
SELECT ( 3959 * acos( cos( radians( '.$latitude.' ) ) * cos( radians( latitude ) ) *
cos( radians( longitude ) - radians( '.$longitude.' ) ) + sin( radians( '.$latitude.' )
) * sin( radians( latitude ) ) ) ) AS distance from TABLE
HAVING distance <= 100 ORDER BY distance ASC
シンプルで簡単な方法
<?php
$lat1 = Yourstart_latitude;
$lon1 = Yourstart_longitude;
$lat2 = Yourend_latitude;
$lon2 = Yourend_longitude;
$theta = $lon1 - $lon2;
$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
$dist = acos($dist);
$dist = rad2deg($dist);
$miles= $dist * 60 * 1.1515;
$unit = 'K';
$km = $miles*1.609344;
echo number_format($km,1);
?>
Google(および他の)APIから離れようとしている人のために、私はしばらくの間これを使用しています。
地球は丸いので、大規模な半径の提出に対していくつかの奇妙な結果があります。互いに約500マイル以内の場所で正常に機能します。
/**
* The max Latitude and Longitude coordinates within a specified milage radius.
*
* @param int $miles
* @param float $longitude
* @param float $latitude
*
* @return array
*/
public function getMaxCoordinates($miles = 50, $longitude, $latitude) {
$oneDegree = 69; // 69 Miles = 1 degree
// Calculate the minimum/maximum possible coordinates.
$lng_min = $longitude - $miles / abs(cos(deg2rad($latitude)) * $oneDegree);
$lng_max = $longitude + $miles / abs(cos(deg2rad($latitude)) * $oneDegree);
$lat_min = $latitude - ($miles / $oneDegree);
$lat_max = $latitude + ($miles / $oneDegree);
return ([
'lat_max' => $lat_max,
'lat_min' => $lat_min,
'lng_max' => $lng_max,
'lng_min' => $lng_min,
'miles' => $miles,
]);
}
Distance-matrix google apiを使用して、緯度と経度の間の距離を計算します。
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,
'https://maps.googleapis.com/maps/api/distancematrix/json?origins='.$prev_add.'&destinations='.$curr_add.'&key=keyyouhavetogenerate'
);
$content = curl_exec($ch);
$array = json_decode($content);
$obj = json_decode($content, TRUE);
$distance = $obj['rows'][0]['elements'][0]['distance']['text'];
このAPIを使用するには、キーが必要です。キー訪問を生成する方法について詳しく知るには https://developers.google.com/maps/documentation/distance-matrix/intro