0
2

More than 3 years have passed since last update.

[php] 簡易版 位置情報APIの実装

Last updated at Posted at 2021-08-24

注意事項 必ずお読みください

  • リソースの情報が小規模なものに限る
    リクエストを受けると全件返す仕様のため、リソース何千件、何万件あるとメモリリークを起こす可能性があります。
    100〜200件程度なら問題ないかと思います。何件という確証は持てないのであくまで目安で。
  • 1日のリクエストが小規模なものに限る
    こちらも上記同様、全件返す仕様であるためリクエスト数が多いと当然その分処理が重くなってしまいます。また仕組み上、モックアップの配列からリソース情報を取得しているので、値に応じて厳選してレスポンスを返す仕様ではありません。
    → 改善点 リレーショナルデータベース(MySQL、PostgreSQL等)を利用して必要なデータのみ取得
    ※このコードを利用してサーバーが落ちたなど不具合があった場合でも、こちらでは一切の責任を負いません。全て自己責任でお試しください。

アプリ利用

  • エリア限定の店舗検索アプリ
    LINE Messaging APIの位置情報を利用した店舗検索を想定してこのAPIを実装しています。
    ※ここではLINEやフロントコードの説明はいたしません

前提知識
- phpの基礎的知識が分かる方(実際に端末でphpを動かせる)
- 公開する際はherokuなど何かしらのサーバーを利用したことがある方

①店舗情報を格納したファイルを読み込む
↓
②LINEから送信された位置情報の値を受け取る
↓
③2点距離を測って、その距離が近いもの順に配列に格納
注. 「Vincenty法」というのを使うのがスタンダードですが、今回は簡易APIということと、リクエストやエリア範囲が小規模を想定しているため、平面での簡単な測定となっています。
↓
④jsonで返す ※当記事ではここまで
↓
⑤どこかのサーバーにデプロイしてGASなどフロントの技術で読み込んでアプリ化

コード全文

<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json; charset=UTF-8');

include_once('./inc/choinomi/kobe/15.php');

$arr = [];

// methodパラメータが付与されたら
if($_SERVER['REQUEST_METHOD'] === 'GET') {
    // LINEで送信して送られてくる情報
    $getX = filter_input(INPUT_GET, 'x', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $getY = filter_input(INPUT_GET, 'y', FILTER_SANITIZE_FULL_SPECIAL_CHARS);

    // 小数点に変更 
    $floatGetX = floatval($getX);
    $floatGetY = floatval($getY);

    foreach ($db as $val) {
        foreach ($val['shop'] as $shop_detail) {
            $name = $shop_detail['name'];
            $desc = $shop_detail['desc'];
            $line = $shop_detail['line'];
            $image = $shop_detail['image'];
            $longitude = floatval($shop_detail['x']);
            $latitude = floatval($shop_detail['y']);

            $minusX = abs($floatGetX - $longitude);
            $minusY = abs($floatGetY - $latitude);

            $distance = hypot($minusX, $minusY);

            $arr['response']['shop'][] = [
                'name' => $name,
                'desc' => $desc,
                'line' => $line,
                'image' => $image,
                'x' => $longitude,
                'y' => $latitude,
                'distance' => $distance,
            ];
        }
    }
} else {
    $arr['status'] = 'no request';
}

// ソート処理
foreach($arr['response']['shop'] as $key => $val) {
    $sort[$key] = $val['distance'];
}
array_multisort(
    $sort, SORT_ASC,
    $arr['response']['shop']
);

// jsonに変換
echo json_encode($arr, JSON_PRETTY_PRINT);

リソースデータ

<?php
// 任意のフォルダ名・ファイル名に
/*
    * データリソース(モックアップ)
    * API仕様
        * name 店舗名
        * desc ディスクリプション
        * line 最寄駅名
        * x 緯度 数値で記載 (例)135.1934386
        * y 経度 数値で記載 (例)34.693952
        * image 画像フルパス https://xxx.com/img/xxx.jpg
*/

$db['db'] = [
    'shop' => [
        [ 'name' => '店舗', 'desc' => 'ディスクリプション', 'line' => '地下鉄三宮駅', 'x' => 緯度, 'y' => 緯度, 'image' => 'xxx.jpg' ],
        [ 'name' => '店舗', 'desc' => 'ディスクリプション', 'line' => '地下鉄三宮駅', 'x' => 緯度, 'y' => 緯度, 'image' => 'xxx.jpg' ],
        [ 'name' => '店舗', 'desc' => 'ディスクリプション', 'line' => '地下鉄三宮駅', 'x' => 緯度, 'y' => 緯度, 'image' => 'xxx.jpg' ],
    ];

デモ

$ php -S localhost:8000
http://localhost:8000/?x=135.189561&y=34.6983314
x と y の値に位置情報を入れてみてください。そうするとdistaceに計算された値が入り小さいもの順(近いもの)にソートかかります。

今回実装するにあたりFBを下さった方
この度は貴重なご意見を下さり、大変ありがとうございました。
@Web_akira

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2