私が持っています $latitude = 29.6815400
および$longitude = 64.3647100
、MySQLでは、これらの座標に最も近い15の場所を取得したいと考えています。このクエリを実行する予定です。
SELECT *
FROM places
WHERE latitude BETWEEN($latitude - 1, $latitude + 1)
AND longitude BETWEEN($longitude - 1, $logintude + 1)
LIMIT 15;
あなたはそれが正しいと思いますか、それとも何か他のものを提案しますか?
近くの場所で最大50Kmの範囲で谷を検索したいので、BEETWEEN
を実行するにはどうすればよいですか?
クエリを実行する前にPHPを使用して何かを実行することもできます。
注:ストアドプロシージャは使用できません。
[〜#〜] php [〜#〜]の計算式は2点間の距離を計算するためのものです:
function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'Mi')
{
$theta = $longitude1 - $longitude2;
$distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))+
(cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
$distance = acos($distance); $distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
switch($unit)
{
case 'Mi': break;
case 'Km' : $distance = $distance * 1.609344;
}
return (round($distance,2));
}
次にクエリを追加して、上記の距離以下の距離を持つすべてのレコードを取得します。
$qry = "SELECT *
FROM (SELECT *, (((acos(sin((".$latitude."*pi()/180)) *
sin((`geo_latitude`*pi()/180))+cos((".$latitude."*pi()/180)) *
cos((`geo_latitude`*pi()/180)) * cos(((".$longitude."-
`geo_longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344)
as distance
FROM `ci_geo`)myTable
WHERE distance <= ".$distance."
LIMIT 15";
同様の計算については、 ここ をご覧ください。
そしてあなたはもっと読むことができます ここ
更新:
longitude2およびlongitude2を計算するには、次のことを知っておく必要があることを覚えておく必要があります。
latitudeの各度合いは、およそ69マイル(111キロメートル)離れています。範囲は、赤道で68.703マイル(110.567 km)から変化します(地球のわずかに楕円形のため)。極で69.407(111.699キロ)に。毎分(1/60度)は約1マイルなので、これは便利です。
経度の程度は、赤道の69.172マイル(111.321)で最も広く、極で次第に減少してゼロになります。北または南に40°の場合、経度間の距離は53マイル(85 km)です。
したがって、50 kmに応じて$longitude2 $latitude2
を計算するにはおよそ:
$longitude2 = $longitude1 + 0.449; //0.449 = 50km/111.321km
$latitude2 = $latitude1 + 0.450; // 0.450 = 50km/111km
MySQLのようなDBMSに大量のクエリをあふれさせることが最善の解決策ではないことを考慮する必要があります。
代わりに、突然完全な円の半径を選択する代わりに、辺$radius
の単純な正方形の内側の座標を持つすべての場所を選択する非常に高速なSQLクエリを推測できます。 PHP
は、余剰をフィルタリングできます。
コンセプトをお見せしましょう:
$lat = 45.0.6072;
$lon = 7.65678;
$radius = 50; // Km
// Every lat|lon degree° is ~ 111Km
$angle_radius = $radius / ( 111 * cos( $lat ) );
$min_lat = $lat - $angle_radius;
$max_lat = $lat + $angle_radius;
$min_lon = $lon - $angle_radius;
$max_lon = $lon + $angle_radius;
$results = $db->getResults("... WHERE latitude BETWEEN $min_lat AND $max_lat AND longitude BETWEEN $min_lon AND $max_lon"); // your own function that return your results (please sanitize your variables)
$filtereds = [];
foreach( $results as $result ) {
if( getDistanceBetweenPointsNew( $lat, $lon, $result->latitude, $result->longitude, 'Km' ) <= $radius ) {
// This is in "perfect" circle radius. Strip it out.
$filtereds[] = $result;
}
}
// Now do something with your result set
var_dump( $filtereds );
このように、MySQLはPHPがこのページに投稿されたgetDistanceBetweenPointsNew()
関数に類似したもので余剰を取り除き、半径の中心への結果セットの座標。
(大きな)パフォーマンスの向上を無駄にしないために、データベースの座標列にインデックスを付けます。
ハッキングハッピー!
私は売り所のアプリで同じようなことをしました。与えられたポイントからの距離で並べ替え、これをSQLのselectステートメントに配置します。
((ACOS(SIN(' . **$search_location['lat']** . ' * PI() / 180) * SIN(**map_lat** * PI() / 180) + COS(' . **$search_location['lat']** . ' * PI() / 180) * COS(**map_lat** * PI() / 180) * COS((' . **$search_location['lng']** . ' - **map_lng**) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS "distance"
置換$search_location
関連するlat/lng値とmap_lat/map_lng値は、lat/lng値を含むSQL列です。次に、距離順に結果を並べ替え、whereまたはhaving句を使用して、50 kmの範囲内でプロパティをフィルタリングできます。
PHPと比較して、SQLをアプローチとして使用することをお勧めします。ページングなどの追加機能が必要な場合に使用します。
少し遅れますが、それは誰かを助けるかもしれません-場所で最も近い都市が必要な場合、孤立した場所は何も取得しないので、私は距離に行きません。これを試して:
$G_how_close_to_find_cities = "1.1"; // e.g. 1.1 = 10% , 1.2=20% etc
$G_how_many_cities_to_find_by_coordinates = "10";
$query = "SELECT * from Cities WHERE
Cities__Latitude <= ('".$latitude*$G_how_close_to_find_cities."') AND Cities__Latitude >= ('".$latitude/$G_how_close_to_find_cities."')
AND Cities__Longitude <= ('".$longitude*$G_how_close_to_find_cities."') AND Cities__Longitude >= ('".$longitude/$G_how_close_to_find_cities."')
ORDER BY SQRT(POWER((Cities__Latitude - ".$latitude."),2)+POWER((Cities__Longitude - ".$longitude."),2)) LIMIT 0,".$G_how_many_cities_to_find_by_coordinates;