CakePHPでGeometry型を用いた
位置情報に基づいた検索を行う方法です
大事なこと
最初に言っておきます
CakePHPはGeometry型を用いた取得
には標準では、対応してません
なので取得保存にはちょっと
手順を踏まないといけないです
その前に
詳しくGeometry型について知りたい人は
以下から確認してください
[http://dev.mysql.com/doc/refman/5.6/ja/gis-class-geometry.html](MySQL :: MySQL 5.6 リファレンスマニュアル :: 11.5.2.2 Geometry クラス)
やってみた
データベース
まずデータベースとテーブルを用意しましょう
SQLはこんな感じです
CREATE DATABASE hoge;
USE hoge;
CREATE TABLE IF NOT EXISTS `geometries` (
`id` int(11) NOT NULL,
`hoge_id` int(11) NOT NULL,
`latlng` geometry NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
モデル
次にモデルを用意
ここで保存した際にGeometry型に変換されるように
beforeSaveの所に記述する
virtualFieldも用意しておきましょう
そうするとあとで楽なので
<?php class Geometry extends AppModel {
function beforeSave() {
$lat = $this->data['Geometry']['lat'];
$lng = $this->data['Geometry']['lng'];
$latlng = $this->query("SELECT GeomFromText('POINT($lng $lat)') as latlng");
$this->data['Geometry']['latlng'] = $latlng[0][0]['latlng'];
return true;
}
var $virtualFields = array(
'latitude' => X(latlag),
'longitude' => Y(latlng)
);
}
コントローラー
次にコントローラーでデータを取り出す方法
最初にも書いたとおりいつも通りのCakeの書き方じゃ取り出せ無いです。
でも基本は同じなのでいつもどおり書けばOKです
<?php class Geometries extends AppController {
public function get_geo() {
$geo = $this->Geometory->find(
'all',
array(
'fields' => array(
// ここを変える
),
'order' => array(
'let' => 'ASC'
),
)
);
}
}
気をつけて欲しいのがfieldsのところに条件を与えることです
検索条件だからconditionsのところに条件を与えるとハマります
与えられた位置情報から近い順に情報を取得する場合は
こんなかんじに書きます
GLength(GeomFromText(CONCAT('LineString(".経度." ".緯度.",', X(latlng), ' ', Y(latlng),')'))) AS let
ここの部分を変えれば2点間の距離を求めたり4点の位置に含まれる情報を取得することが出来ます