2011-11-15 2 views
12

最近、Google Maps APIを見て、自分のウェブサイトで新しいことを試してみました。私は現在、このコードを使用しています:郵便番号の半径10マイル以内の町を検索する。 Google Maps API

<?php 

$postcode = $_REQUEST['postcode']; 

$url = 'http://maps.googleapis.com/maps/api/geocode/xml?address='.$postcode.'&sensor=false'; 
$parsedXML = simplexml_load_file($url); 

if($parsedXML->status != "OK") { 
echo "There has been a problem: " . $parsedXML->status; 
} 

$myAddress = array(); 
foreach($parsedXML->result->address_component as $component) { 
if(is_array($component->type)) $type = (string)$component->type[0]; 
else $type = (string)$component->type; 

$myAddress[$type] = (string)$component->long_name; 
} 
header('Content-Type: application/json'); 
echo json_encode($myAddress); 


?> 

単に町、郡など

可能な場合に、私は定義郵便番号を使用して、Googleのデータベースを検索し、返します、私だけでなく、表示したいと思い最寄りの町だけでなく、半径5〜10マイル以内の都市もあります。誰かが私にこのことをどうやって行っていいのか教えてもらえますか?任意のヘルプ

+0

有望なQ&Aのカップルがあります:http://stackoverflow.com/search?q=radius+search+google+maps+php - それらのうち、あなたがチェックしたものは何ですか?なぜあなたの問題を解決するのに役立たなかったのですか? – Gordon

+0

私はそれらを見てみましょう、私は私の質問を入力中に示唆された記事を見たが、多くの有用なものを見ていない。英国の郵便番号データベースをRoyal Mailに支払うことなく、どこでそれを買うことができるのか分かりますか?私はwikileaksがそれをリリースしたと言った記事を見たが、これは2009年だったので、完全に最新ではないと推測している –

+0

、ごめんなさい。クイックグーグルはhttps://www.ordnancesurvey.co.uk/opendatadownload/products.htmlを持ってきましたが、これは無料で使用できるかどうかはわかりません。 – Gordon

答えて

51

ため

おかげ更新:私はhttp://www.mullie.eu/geographic-searches/

に、この特定の主題についてのより詳細なブログ投稿を書きました - にGoogle MapsのAPIを使用して、使用可能なすべての町経由

ループ緯度&経度を取得します。これらをどこかに保存してください(データベース)。 - 注意してください、Googleは膨大な量の通話を受け付けないので、通話を抑制します。

その後、町をフェッチする場合、あなたが特定の範囲をwithing都市をつかむために以下のコードのようなコードを使用することができます:上記のコードについて

public static function getNearby($lat, $lng, $type = 'cities', $limit = 50, $distance = 50, $unit = 'km') 
{ 
    // radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius' 
    if ($unit == 'km') $radius = 6371.009; // in kilometers 
    elseif ($unit == 'mi') $radius = 3958.761; // in miles 

    // latitude boundaries 
    $maxLat = (float) $lat + rad2deg($distance/$radius); 
    $minLat = (float) $lat - rad2deg($distance/$radius); 

    // longitude boundaries (longitude gets smaller when latitude increases) 
    $maxLng = (float) $lng + rad2deg($distance/$radius/cos(deg2rad((float) $lat))); 
    $minLng = (float) $lng - rad2deg($distance/$radius/cos(deg2rad((float) $lat))); 

    // get results ordered by distance (approx) 
    $nearby = (array) FrontendDB::getDB()->retrieve('SELECT * 
                FROM table 
                WHERE lat > ? AND lat < ? AND lng > ? AND lng < ? 
                ORDER BY ABS(lat - ?) + ABS(lng - ?) ASC 
                LIMIT ?;', 
                array($minLat, $maxLat, $minLng, $maxLng, (float) $lat, (float) $lng, (int) $limit)); 

    return $nearby; 
} 

注:

  • 独自のデータベースラッパーが使用されているので、mysql_query、PDO、...に変換してください。
  • これは正確ではありません。 DBで正確な球面計算を行うことはできません。したがって、緯度は&となり、経度の下限は&となります。これは、基本的に、あなたの距離よりわずかに遠い場所(実際の半径(実際にはかなり円です)のすぐ北東にありますが、最大緯度&の経度内にあります。。

    _________________ 
    | /\  | 
    | Y/ \ | 
    |/  \ | 
    |(  X  )| 
    | \  /| 
    | \ / | 
    |______\_/______| 
    

    上記:それは)データベース内の制限を広場にこれは自分の半径をwithing都市の荒いが、ナット100%正確選択を与える

私はこれを説明しようとするでしょう円(幾分)は、場所Xに基づいて、場所を検索したい実際の半径です。これはあなたのDBからまっすぐに達成するのは難しいですが、 DBから実際に取得するものは周囲の四角です。ご覧のとおり、(Yのような)場所がこれらの最大値&分の境界に入る可能性がありますが、実際には要求された半径には達していません。これらは後でPHPでフィルタリングすることができます。

この最後の問題に取り組むには、すべての結果をループし、ルートの位置と見つかった近距離の正確な距離を計算して、実際に半径内にあるかどうかを計算します。そのためには、このコードを使用することができます。

public static function getDistance($lat1, $lng1, $lat2, $lng2, $unit = 'km') 
{ 
    // radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius' 
    if ($unit == 'km') $radius = 6371.009; // in kilometers 
    elseif ($unit == 'mi') $radius = 3958.761; // in miles 

    // convert degrees to radians 
    $lat1 = deg2rad((float) $lat1); 
    $lng1 = deg2rad((float) $lng1); 
    $lat2 = deg2rad((float) $lat2); 
    $lng2 = deg2rad((float) $lng2); 

    // great circle distance formula 
    return $radius * acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($lng1 - $lng2)); 
} 

これは、位置Xと位置Yの間で(準)の正確な距離を計算し、その後、あなたがラフデシベルを渡すために十分に近かったまさにそれらの都市を除外することができます - フェッチしますが、実際にはあなたの範囲内にあるだけではありません。

+4

なぜあなたは6アップ=を持っているのか分からない) –

+0

素晴らしい答え、ありがとう –

関連する問題