前提とする環境 PHP+PostgreSQL(PostGIS)
こちらの説明は以下の環境を前提としています。
・PHPが動作するWebサーバ(IIS,Apache,Nginx)など
・PostgreSQL(PostGISの拡張機能を利用します)
PostGISのインストール
PostgreSQL 9.1 以上のバージョンでは、PostGISの導入がSQLの実行だけで完了するため非常に簡単になりました。
CREATE EXTENSION postgis;
また、Amazon Web ServiceではRDSというPostgreSQLのデータベースをレンタルすることも可能です。
任意の半径のポリゴンをPostGISで作成する
GIS処理の基本
簡単ですが、PostgreSQLのGIS処理の概念を説明です。詳しくはドキュメントを御覧ください。
データ型
PostGISには空間情報を処理するために専用のデータ型が2つ有ります。
・平面データの geometry型
・球面データの geography型
今回は簡単かつ正確にメートル単位での円形を作成するために球面データを扱う、geography型を用います。
SQLによる円形ポリゴンの作成
PostGISの関数を活用して、緯度経度から点を作成し、点を円形のポリゴンに変換します。
複数の関数を組み合わせて処理するため、それぞれの関数毎にステップを踏んで説明致します。
今後はソースコードの中で、緯度をlat、経度をlonと表記します。
ステップ1 : 点データの作成
ST_Point関数を用いて、点データを作成します。
SELECT ST_POINT( lon, lat) ;
ステップ2 : 球面データ型へキャスト
ステップ1では平面データ型のgeometry型が生成されているので、geography関数を用いて球面データ型のgeography型へキャストします。
SELECT GEOGRAPHY( ST_POINT( lon, lat) );
ステップ3 : 点を円形に変換
点を円バッファに変換します。ST_Buffer( geography型 , 半径(メートル))関数を用いて、点データを円形のポリゴンデータに変換します。例では1,000m
SELECT ST_Buffer( GEOGRAPHY( ST_POINT( lon, lat) ) , 1000 );
ステップ4 : KMLのポリゴンタグへ変換
ST_AsKMLを用いて、geography型からkmlのポリゴン形状の定義部分の文字列を出力します。
SELECT ST_AsKML(ST_Buffer( GEOGRAPHY( ST_POINT( lon, lat) ) , 1000 ));
PHPによるAPI化
緯度経度と半径をパラメータとして取得し、動的に円形のポリゴンを出力するAPIを作成します。
入力パラメータ
- lon : 経度
- lat:緯度
- r : 半径
- color : 色 ( αbgr )
今回は各値にデフォルト値を用意して、入力が無くても動作します。
URL例
<?php
//データベースへ接続
$conn_string = "host=localhost port=5432 dbname=database1 user=user1 password=*****";
$conn = pg_pconnect($conn_string);
if (!$conn) {
echo "An error occurred.\n";
exit;
}
//パラメータの取得
if(isset($_GET['lon']) ){
$lon = $_GET['lon'];
} else {
$lon=139.989136553437;
}
if(isset($_GET['lat']) ){
$lat = $_GET['lat'];
}else {
$lat = 35.65945922265559;
}
if(isset($_GET['r']) ){
$radius = $_GET['r'];
}else {
$radius = 1000;
}
if(isset($_GET['o']) ){
$color = $_GET['o'];
}else {
$color ="4cff7b00";
}
//SQLの作成
$sql ="SELECT ST_AsKML(ST_Buffer( GEOGRAPHY(ST_Point(".$lon.",".$lat.")) , ".$radius.")) AS p ;";
//検索実行
$result = pg_query($conn, $sql);
if (!$result) {
echo "An error occurred.\n";
exit;
}
//検索結果の取得
$row = pg_fetch_row($result);
//KML文字列の取得
$str = <<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name></name>
<Style id="s">
<LineStyle>
<color>{$color}</color>
</LineStyle>
<PolyStyle>
<color>{$color}</color>
</PolyStyle>
</Style>
<Placemark>
<name>polygon</name>
<styleUrl>#s</styleUrl>
{$row[0]}
</Placemark>
</Document>
</kml>
EOD;
header('Content-Type: application/vnd.google-earth.kml+xml kml');
header('Content-Disposition: attachment; filename="mar.kml"');
print $str;
?>