Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Webサービスにおける外 部API使用とMySQL位置情報機能 #TechLunch

Webサービスにおける外 部API使用とMySQL位置情報機能 #TechLunch

t(水) @ Livesense TechLunch
発表者:島田 喜裕

Livesense Inc.

April 23, 2014
Tweet

More Decks by Livesense Inc.

Other Decks in Technology

Transcript

  1. $key = "$lat:$lng:$keyword"; //キャッシュの読み出し if (($result = getMyCache($key)) === false)

    { //キャッシュなしの場合・・・ //APIを呼び出して $result = callAPI($lat, $lng, $keyword); //結果をキャッシュに保存 saveCache($key, $result); } return $result; コード例 この方法だとスマートフォンの場合に上手く動作し ない
  2. CREATE TABLE IF NOT EXISTS `cache_fs_search` ( `cache_id` int(11) NOT

    NULL AUTO_INCREMENT, `latlng` point NOT NULL, `result` mediumtext NOT NULL, PRIMARY KEY (`cache_id`), KEY `keyword` (`keyword`), SPATIAL KEY `latlng` (`latlng`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; • テーブル定義 • ユーザ定義関数 DELIMITER $$ DROP FUNCTION IF EXISTS `dbname`.`distance_in_meter` $$ CREATE FUNCTION `distance_in_meter`(a POINT, b POINT) RETURNS double DETERMINISTIC COMMENT 'distance function' BEGIN RETURN round(glength(linestring(a, b)) * 111000); END $$ DELIMITER ;
  3. INSERT INTO cache_fs_search (latlng, result) VALUES (GeomFromText('POINT(35.00000 139.0000)'), 'test result')

    .... • データ • 位置情報の検索 SELECT cache_id, x(latlng) as lat, y(latlng) as lng, result, distance_in_meter(latlng, PointFromText('POINT (35.691147 139.702084)')) d FROM `cache_fs_search` WHERE distance_in_meter(latlng, PointFromText('POINT (35.691147 139.702084)')) < 100 この方法だとインデックスが使用されない
  4. SELECT cache_id, x(latlng) as lat, y(latlng) as lng, result, distance_in_meter(latlng,

    PointFromText('POINT (35.691147 139.702084)')) d FROM `cache_fs_search` WHERE MBRWithin(latlng, GeomFromText('POLYGON (( 35.692047 139.701184, 35.692047 139.702984, 35.690247 139.702984, 35.690247 139.701184, 35.692047 139.701184))')) AND distance_in_meter(latlng, PointFromText('POINT (35.691147 139.702084)')) < 100 •POLYGONでは、バウンディングボックスの4頂点の座標を一周り指定。始点と終点 で同じ頂点を指定するので、合計5つの座標を渡す。 •WHERE句ではまずMBRWithin関数により、latlngがバウンディングボックス内にある かが判定され、その上でdistance_in_meter関数により半径100mの円内にあるかの判 定が実行。 • 検索SQL
  5. SELECT cache_id, x(latlng) as lat, y(latlng) as lng, result, distance_in_meter(latlng,

    PointFromText('POINT (35.691147 139.702084)')) d FROM `cache_fs_search` WHERE MBRWithin(latlng, GeomFromText('LINESTRING (35.692047 139.701184, 35.690247 139.702984)')) AND distance_in_meter(latlng, PointFromText('POINT (35.691147 139.702084)')) < 100 • MBRWithin関数に渡すバウンディングボックスは、 POLYGONではなく対角線を表すLINESTRINGを渡すことに より、同じ結果を得ることが出来る。 • もう少し簡潔にできる