PHPとGoogle Maps APIを使用したジオコーディング

インターネット上のほとんどのアプリケーションは現在、地形図を埋め込み始めています。

この記事は、Google Map APIを使用して地図を操作することに専念しています。



以下では、Google APIを使用する原則について説明します。最も単純なクラスはSimpleXMLを使用して実装されます(多くの場合、コードは非常に単純であると思われるかもしれません)。 この記事のジオコーディングおよびジオコーダーという用語は英語のままです。





はじめに



ジオコーディングは、入力された住所で緯度と経度を見つけるプロセスです。 Googleは、JavaScript APIとWebサービスの両方を使用してアクセスできる開発ツールへの無料アクセスを提供しています...この記事では、PHPを使用してジオコーダーWebサービスにアクセスする方法を示します。

緯度と経度を決定するためのアプリケーションは多数あり、それらの多くは無料です。 これらの使用方法の例をいくつか示します。

Googleマップを使用してサイトに地図を表示する場合、最も簡単な方法はJavaScript APIを使用することですが、これが常に最良のソリューションとは限りません。

たとえば、アプリケーションがユーザーが入力したアドレスに座標を書き込む場合、このソリューションはJavaScriptが無効になっているユーザーに対しては機能しません。 この状況を防ぐために、Webサービスを使用して、すべてのリクエストをジオコーダーにサーバーにリダイレクトできます。

この記事では、ジオコーダーにすばやくアクセスするのに役立ついくつかのクラスを開発します。



Googleマップを使い始める



Google Maps APIの使用に関するすべてのドキュメントは、このアドレスにあります。

Google Maps APIを使用するために最初にすることは、サイトのAPIキーを作成することです。 このキーは、このAPIへのすべてのリクエストを識別します。 このキーを入手するには、利用規約に同意し、 ページにサイトのアドレスを入力します

現在、ジオコーダーリクエストの最大数は1日あたり15,000に制限されています。 ただし、ジオコーダーの応答はキャッシュできます。

キーを受け取った後、ジオコーダーに連絡できます。 ジオコーダーの使用に関するドキュメントは、次の場所にあります。



ジオコーダークエリの作成



ジオコーダーにリクエストを行う場合、レスポンスを受信する形式を指定できます。 可能な形式は、JSON、XML、KML、およびCSVです。 この記事では、XMLでの応答の操作について説明します。

KML(Keyhole Markup Data Decryption)は、Google Earthで使用するために開発されたXML形式です。 KMLとジオコーダーからのXMLの応答データは同一です。

JSONはJavaScriptで一般的に使用されますが、アプリケーションでも使用できます。 PHPを使用してJSOMを操作するには、次の関数 (PHP 5.2.0以降)を参照してください。 この記事では、 SimpleXML拡張機能を使用してジオコーダーからのXMLデータを処理します

ジオコーダーにリクエストを行うには、HTTPリクエストをmaps.google.com/maps/geoに送信する必要があります。 リクエストパラメータについて以下に説明します。

たとえば、ホワイトハウス(ワシントンDC、ペンシルベニアアベニュー1600)の座標を取得するには、 maps.google.com / maps / geo?q = 1600 + pennsylvania + ave + washington + dc&output = xml&keyをリクエストする必要があります。 = 123456

123456をキーに置き換えます

リクエストで送信する文字列フォーマット文字列は重要ではありませんが、あいまいさはないはずです



ジオコーダーの回答の解析



ジオコーダーにリクエストを送信した後、指定した形式でレスポンスを取得します。 たとえば、指定された住所がホワイトハウスの住所である場合、応答として次のXMLドキュメントを受け取ります。







この回答では、3つの重要な要素を強調しています。

各目印要素に含まれる最初の有用な要素は、フォーマットされた住所住所です。 ユーザーはさまざまな方法で同じアドレスを入力できるため、これは非常に重要です。 上記の例を見ると、文字列「1600 pennsylvania ave washington dc」が検索用に入力され、「1600 Pennsylvania Ave NW、Washington、DC 20006、USA」が回答として受け取られたことがわかります。

次の要素はAddressDetailsで、拡張アドレス言語(xAL)を使用して情報を提供します。 このアイテムには、位置精度の度合いを示す精度属性があります。 精度属性に可能な値:

上記の例では、属性値は8であり、最高レベルの精度を示しています。

AddressDetails要素内の他の要素は、xAL言語仕様に従って見つかった場所の一部を記述します。

各目印要素にはPoint要素が含まれます。 このアイテムには、コンマ区切りデータが含まれます。 最初の要素は経度です。 2つ目は緯度です。 3番目の引数は高度です(使用されません)。



SimpleXMLを使用したジオコーダーデータへのアクセス

結果のXMLを解析するために、SimpleXMLを使用します。これはPHPでXMLを簡単に操作できるようにする拡張機能です。 PHP 5以降、SimpleXMLはPHPに組み込まれています。

XMLデータを読み取るには、構文解析するXML文字列をコンストラクターに渡すことにより、SimpleXMLElementオブジェクトを初期化する必要があります。

$ str = "XML string"; //サンプルXMLファイル

$ xml = new SimpleXMLElement($ str);


SimpleXMLElementクラスのオブジェクトを作成することにより、XML文字列のすべての要素にアクセスできます。これらはオブジェクトの通常のプロパティであるかのようです。 たとえば、次のコードを使用して応答ステータスにアクセスできます。

$ xml = new SimpleXMLElement($ geocoderResponse);

echo $ xml-> Response-> Status-> code;


タイプ$ xml-> Response-> Status-> codeはSimpleXMLElementであることに注意してください。 したがって、文字列または数値への型変換を使用する必要があります。

$ xml = new SimpleXMLElement($ geocoderResponse);

$ status =(int)$ xml-> Response-> Status-> code;

if($ status == 200){...}


これでXMLデータの読み取り方法はわかりましたが、一部の要素には属性が含まれています。 次の例は、これらの属性にアクセスする方法を示しています。

$ xml = new SimpleXMLElement($ geocoderResponse);

foreach($ xml-> Response-> Placemark as $ placemark){

$ precision =(int)$ placemark-> AddressDetails ['Accuracy'];

($精度== 8){...}

}




ジオコーダークラスの作成



この記事では、Googleジオコーダーからの情報を使用するためのソリューションの実装について説明します。 このプロセスでは、3つのクラスの作成が考慮されます。

Geocoderクラスの実装を進めましょう。 このクラスにはlookup()メソッドが含まれ、その入力は検索のアドレスになり、Placecmarkクラスの要素の配列が見つかった場所とともに結果として返されます。

以下のコードは、クラスの実装の一部を示しています。 まず、ジオコーダーの住所が決定されます。 戻りステータスに対応する必要な定数の数を決定します。 定数を使用すると、コードがより読みやすく、保守しやすくなります。 一貫性を保つために、 JavaScript APIに定義されているのと同じ定数を使用します

クラスジオコーダー

{

public static $ url = 'http://maps.google.com/maps/geo';

const G_GEO_SUCCESS = 200;

const G_GEO_BAD_REQUEST = 400;

const G_GEO_SERVER_ERROR = 500;

const G_GEO_MISSING_QUERY = 601;

const G_GEO_MISSING_ADDRESS = 601;

const G_GEO_UNKNOWN_ADDRESS = 602;

const G_GEO_UNAVAILABLE_ADDRESS = 603;

const G_GEO_UNKNOWN_DIRECTIONS = 604;

const G_GEO_BAD_KEY = 610;

const G_GEO_TOO_MANY_QUERIES = 620;

保護された$ _apiKey;

パブリック関数__construct($キー)

{

$ this-> _ apiKey = $ key;

}

}


上記のように、Placemark型のオブジェクトの配列を返すlookup()メソッドを実装します。 ジオコーダーから応答を取得するには、performRequest()というメソッドを作成します。

performRequest()メソッドは、最初の引数としてアドレス文字列を取り、2番目の引数として戻り値の型を取ります。

このメソッドは、Curl関数を使用してHTTP要求を実装します。 サーバーから応答を受信するには、CURLOPT_RETURNTRANSFERパラメーターをtrueに設定する必要があります。

クラスジオコーダー

{

パブリック関数performRequest($ search、$ output = 'xml')

{

$ url = sprintf( "%s?q =%s&output =%s&key =%s&oe = utf-8"、self :: $ url、urlencode($ search)、$ output、$ this-> _ apiKey);

$ ch = curl_init($ url);

curl_setopt($ ch、CURLOPT_RETURNTRANSFER、true);

$ response = curl_exec($ ch);

curl_close($ ch);

$応答を返します。

}

}


今、lookup()メソッドの実装に密接に取り組んでおり、最初にperformRequest()メソッドを使用してサーバーから応答を取得し、SimpleXMLELementクラスのオブジェクトを作成します。 次に、サーバーから返されたリクエストのステータスを読み取ります。 通常の要求は、G_GEO_SUCCESS、G_GEO_UNKNOWN_ADDRESS、またはG_GEO_UNAVAILABLE_ADDRESSになります。 最後の2つの値は、指定された場所が見つからなかったことを示します。この場合、空の配列が返されます。

ステータスコードがG_GEO_SUCCESSの場合、見つかった場所を循環して、それぞれのPlacemarkオブジェクトを作成します... FromSimpleXml()メソッドを記述して、Placemarkクラスのオブジェクトを作成します。

他のすべてのステータスコードについては、例外を作成します。

クラスジオコーダー

{

パブリック関数検索($検索)

{

$ response = $ this-> performRequest($ search、 "xml");

$ xml = new SimpleXMLElement($応答);

$ status =(int)$ xml-> Response-> Status-> code;



スイッチ($ステータス)

{

ケース自己:: G_GEO_SUCCESS:

require_once( "Placemark.php");

$目印=配列();

foreach($ xml->応答->目印として$目印)

$ placemarks [] = Placemark :: FromSimpleXml($ placemark);

$目印を返します。

ケースセルフ:: G_GEO_UNKNOWN_ADDRESS:

ケースセルフ:: G_GEO_UNAVAILABLE_ADDRESS:

return array();

デフォルト:

新しい例外をスロー(sprintf(「Google Geo error%dが発生しました」、$ステータス));

}

}

}


これは、Geocoderクラスの完全なコードです。 performRequest()関数を使用する場合はこれを実行できますが、lookup()メソッドを使用する前にPlacemarkクラスを実装する必要があります。

require_once( "Geocoder.php");

$ address = "1600 Pennsylvania Ave Washington DC";

$ geocoder = new Geocoder( 'your key');

$ xml = $ geocoder-> performRequest($ address、 "xml");

$ json = $ geocoder-> performRequest($ address、 "json");

$ csv = $ geocoder-> performRequest($ address、 "csv");





目印クラスを作成する



現在、場所情報を保存するために使用されるPlacemarkクラスを実装しています。 もちろん、ジオコーダーから返された住所のすべての部分を保存することをお勧めします。3つの要素の保存に制限します。

このクラスを実装するには、値を設定および受信する関数(関数setPoint()、getPoint()、setAddress()、getAddress()、setAccuracy()およびgetAccuracy())を作成します。 Geocoderクラスで使用される静的FromSimpleXml()メソッドも実装します。

Placemarkクラスでは、場所の正確さの原因となる定数を定義します。 たとえば、国のみが定義されているかどうかを判断するには、次を使用します

if($ placemark-> getAccuracy()== Placemark :: ACCURACY_COUNTRY){...}


実装。

クラス目印

{

const ACCURACY_UNKNOWN = 0;

const ACCURACY_COUNTRY = 1;

const ACCURACY_REGION = 2;

const ACCURACY_SUBREGION = 3;

const ACCURACY_TOWN = 4;

const ACCURACY_POSTCODE = 5;

const ACCURACY_STREET = 6;

const ACCURACY_INTERSECTION = 7;

const ACCURACY_ADDRESS = 8;

保護された$ _point;

保護された$ _address;

保護された$ _accuracy;

}


Google Maps APIは、精度のために名前付き定数を定義しません。

次に、いわゆるセッターとゲッターの定義です。著者のコメントはスキップします。

クラス目印

{

//他のコード

パブリック関数setAddress($アドレス)

{

$ this-> _ address =(string)$ address;

}

パブリック関数getAddress()

{

$ this-> _ addressを返します。

}

パブリック関数__toString()

{

return $ this-> getAddress();

}

パブリック関数setPoint(ポイント$ポイント)

{

$ this-> _ point = $ point;

}

パブリック関数getPoint()

{

$ this-> _ point;

}

パブリック関数setAccuracy($精度)

{

$ this-> _ precision =(int)$ precision;

}

パブリック関数getAccuracy()

{

$ this-> _ precision;

}

//他のコード

}


最後に、FromSimpleXml()メソッドを実装します。これは、SimpleXMLElementオブジェクトに基づいてPlacemarkオブジェクトを作成するためのファクトリーメソッドです。

以下で説明する例では、PointクラスとそのCreate()メソッドが使用されます。これらについては以下で説明します。

クラス目印

{

//他のコード

パブリック静的関数FromSimpleXml($ xml)

{

require_once( 'Point.php');

$ point = Point :: Create($ xml-> Point->座標);

$目印=新しい自己;

$ placemark-> setPoint($ポイント);

$ placemark-> setAddress($ xml->アドレス);

$ placemark-> setAccuracy($ xml-> AddressDetails ['Accuracy']);

$目印を返す;

}

}




ポイントクラスの作成



完全に使用するために実装する必要がある最終クラスは、Pointクラスです。 このクラスには、緯度と経度が格納されます。 このデータはコンストラクターで送信され、緯度と経度の値を取得するメソッドもあります。

クラスポイント

{

保護された$ _lat;

保護された$ _lng;

パブリック関数__construct($緯度、$経度)

{

$ this-> _ lat = $緯度;

$ this-> _ lng = $経度;

}

パブリック関数getLatitude()

{

return $ this-> _ lat;

}

パブリック関数getLongitude()

{

return $ this-> _ lng;

}

パブリック静的関数Create($ str)

{

リスト($経度、$緯度、$標高)=爆発( '、'、$ str、3);

新しい自己($緯度、$経度)を返します。

}

}




おわりに



この記事では、Googleマップを使用してジオコーダーを操作するための最も簡単なアルゴリズムについて説明します。 JavaScriptで指定されたクラスを使用することもできますが、JavaScriptをすべてのユーザーが有効にできるわけではないことも覚えておいてください。

また、ジオコーダーの応答をキャッシュすることで、負荷を軽減し、将来の生産性を向上できることを忘れないでください。



参照資料




All Articles