2017.9.12
Livvon#5【ジオコーディング#2-住所によるバリデーション-】
電源カフェというサイトを参考に、今日はわざわざ綱島まで来ています。思ったより遠かったのですが、横浜を避けるとこういう変なとこばっかになってしまう・・・・・・。
てか、この電源カフェとかいうサイトの情報ってアテになんないっすね!!!電源ないじゃん!!!!!上島珈琲店に行ってみたかったので来たんだけど、どこにも電源が見当たらない!!!!
まぁこればかりは行ってみないと分からないので仕方ありません。朝の9時とか図書館もあいてないからどーしようもないんだよなあ、、、
セコセコと溜めたモバイルバッテリー、計20,000mA
(うち10,000mAはほんとに使えてるのか怪しいモバイルバッテリーのもの)で凌ぐしかですね・・・・・・。
さて、今日は昨日GoogleのAPIとうまく通信できたので、これをバリデーションに用いたいと思います。
さて、返ってくるJSONのおさらいですが、こんなのが返ってきます。
これそれぞれをバリデーターとして使うのはちょっと使い勝手が悪いので使わないことにします。
ということで、方針としては・・・・・・
1.住所情報を連結した文字列でジオコーディング
2.結果が返って来れば正規の住所なので確認(空のレスポンスの場合不正なのでバリデート)
3.※その情報を基に格納する情報を整形
と、そういう方針でいこうと思います。
3.について※マークがついているのですが、これはどういうことかというと・・・・・・
一応、国情報を登録させる欄があるんですよね。
というのも、グローバル交流が目的の一つなので「国籍」って大事なんですよね。
ただ、問題なのは
この項目って必要ですか?というところでして。
というのも、日本に住居構えてたら日本国籍に決まってんじゃんwwwwwと言えなくはないんですよね。
出稼ぎに来ている外国人という択を完全に抹消することになり、これはこれで問題を孕んでいるのですが、ユーザーに入力させる必要が果たしてあるのかと。
基本的に、ユーザーになるべく入力はさせたくなくて、自動化できるならしたいんですよねこっちとしては。
ユーザーの手間とかってのもあるんですが、そもそも
変な値を入れてくる人の対策が正直めんどくさい(笑)
ただ、国籍での差別というのもあまり宜しくないので、「国籍」ではなく「居住地」として項目を持たせた方がいいのかなぁといった感じはします。
だって、いくら日本に住んでても、中国とか北朝鮮の辺りの方が行き成り泊まりたいですとか言ってきたら、悪気はなくてもちょっと身構えちゃいますよね・・・・・・笑
人間の抱えるバイアスというのは思ったより醜悪なので、知らない方がいい事実だってあると思われるのです。いや、いい人の方が多いのは知ってるんですけどね。だからって交流を拒否ったりしたいとかそーいうんじゃないんですけど、相手をよく知らない状態だとね。それはお互い様と言われたらそうなのかも知れないけれど...
うーん。しばらくはその方針でいこうかな。
国情報ですが、今のところ正規化はしないで平文で持とうかなと思っています。というのも、国なんて生えたり消滅したりする生き物ですし、漏れがあるときついですね。
GoogleのAPIが返してくる結果がそう簡単に変わらないことを祈りましょう。
あっ、でも国別検索とかしようと思うと結局必要になるのか・・・・・・?日本のことを「日本」と言う人もいれば「Japan」とか「JP」とか、「JPN」とか挙げられるじゃん?
それをどう検索したらいいんだろう・・・・・・。
位置検索のことを考えて入れるデータを多少考えなくてはいけないので、ちょっとフローを考えてみましょうか。
すごいざっくりとしたフローは以下の2つです。
1.国名で検索
2.国名以外の住所(都道府県・市町村)
3.場所ピンポイント(建物名・駅名etc...)
3.で検索をかけられた時は、緯度経度による範囲検索でいいと思います。
軽くググってみたところ
こういうエントリが見つかったので、こんな感じのことをすれば実現できそうです。
つまり、なんとかして「検索語句の緯度経度」を取得し、それを中心とした半径mメートルのレコードを取得するSQLを発行すればいいことになります。この辺はジオコーディングのAPI使えばなんとかなると思います。
2.に関しては・・・・・・都道府県とかは記法を揃えることができそうなので、それで一致検索しかないんですかね・・・・・・。ただ、僕が住んでる「横浜市神奈川区」みたいなのだとどう検索するんですかね?
「横浜市」って検索する人も「神奈川区」って検索する人もいると思うんですが、LIKE検索はさすがにやめた方がいい気がするんですよね・・・・・・。とはいえ、位置情報を外部から取ってくるというのもそれはそれで・・・・・・。
で、1.の国名での検索は如何ように実装しようかってとこで今悩んでいるわけですね。
さすがに緯度経度での絞込はコストが高すぎて実用に耐えないと思うので別の方法を考えなくてはいけません。
仕方がないのでAirbnbを参考にします。こーいうのは先駆者の知識を丸パクリして誤魔化すのが正しいと思います(笑)
挙動を見ると、地図ファーストな検索のされ方をされていますね。
もう少し噛み砕いた説明をすると、例えば「神奈川区」で検索をかけると、神奈川区を中心とした地図が表示されて、その描写範囲内のレコードを取ってきています。つまり、平然と西区とか鶴見区が入り込んでくるわけですね。
地図をズームアウトしていくと、普通に海外のホストが表示されるようになります。つまり、地図に表示されている範囲内でテキトーに拾ってきているって感じになります。
これなら、地図の倍率と一角が分かれば正方形で範囲検索できますし、フェッチ速度も最速ですね。
ほんとは楽天トラベルみたいな感じにした方がデータベースとしては見やすいのかなぁとか思ったりするのですが、どう実装すべきか分かったものじゃありませんし私の方も地図ベースに致しましょうかね。結果が取れればいいんだよ、うん()
方針が定まったので実装します。とりあえず緯度と経度が取れれば良いということにしましょう。
先程の緯度経度のクラスをいい感じに書き換えればいいですね。
コンストラクタをオーバーロードすることができないので、ちまちまとメンバ変数にセットしていくことでプロパティを整え、その結果を基に実行するって感じで良さそうですね。
class Geocoding{
private $addressPrefecture = null;
private $addressMunicipality = null;
private $addressLocalName = null;
private $addressBuildingName = null;
public function set_addressPrefecture($addressPrefecture){
$this->addressPrefecture = $addressPrefecture;
}
public function set_addressMunicipality($addressMunicipality){
$this->addressMunicipality = $addressMunicipality;
}
public function set_addressLocalName($addressLocalName){
$this->addressLocalName = $addressLocalName;
}
public function set_addressBuildingName($addressBuildingName){
$this->addressBuildingName = $addressBuildingName;
}
private function generate_address(){
return $this->addressPrefecture.
$this->addressMunicipality.
$this->addressLocalName.
$this->addressBuildingName;
}
...
単純に住所を連結して表示しているだけです。
ちなみにこれ、英語表記だと逆順になるので使えないです。
public function confirm(CreateUserRequest $request)
{
$geocoding = new Geocoding();
$geocoding->set_addressPrefecture($request["addressPrefecture"]);
$geocoding->set_addressMunicipality($request["addressMunicipality"]);
$geocoding->set_addressLocalName($request["addressLocalName"]);
$geocoding->set_addressBuildingName($request["addressBuildingName"]);
$geodata = $geocoding->geocode();
if(!$geodata){
$error_array=[
'addressPrefecture' => '住所に誤りがあるようです。ご確認下さい。',
'addressMunicipality' => '住所に誤りがあるようです。ご確認下さい。',
'addressLocalName' => '住所に誤りがあるようです。ご確認下さい。'
];
if(!empty($request["addressBuildingName"])){
$error_array["addressBuildingName"]='住所に誤りがあるようです。ご確認下さい。';
}
return back()->withInput()->withErrors($error_array);
}
return view('Test.geotest')->with('geodata',$geodata);
//return view('auth.registerConrifm')->with($request);
}
エラーメッセージは定数にすべきなんでしょうけど分かりやすさ重視でハードコーディングです。(笑)
やってることは簡単で、オブジェクトに入力された住所情報をぶん投げて、結果を受け取ってるだけです。この辺りのロジックをうまくやれば、検索精度も上がることでしょう。
一応予定としては、郵便番号ファーストで検索させ、郵便番号+番地で検索することで精度向上を狙います。
あるいは建物名があるのなら、建物名だけ使って検索した方が精度上がるんでしょうかね。わかりませんが、そこをこだわっても仕方がないのであきらめましょう。
※仕様
・郵便番号は手入力させない方針に変更
※後日「郵便番号から住所を入力」を実装予定
郵便番号を住所検索に使う必要性がないのでデータはAPIの結果を使用する方針で。
多種多様な入力値を入れられることをなるべく避け検索精度を上げるために、郵便番号から所定のフォーマットとして住所を自動入力させたい。
実装はテキトーなライブラリを使えば簡単だろうが、相変わらず本質ではないのでプロトタイプでは略。タスクが溜まっていくなあ・・・・・・。
・虚偽の住所もかなりゆるく許容する
何故なら検索可能な時点で対策しづらいため。上記の郵便番号による住所入力にて対策するしかない。
とはいえ、どんな手を使っても結局人手による個人認証以外に対策が存在しないのでこれは諦めるしかない。
もっといい方法は知識人に教えを乞うことにする。
さすがにこれぐらい無茶苦茶な入力をするとエラーが返ってきますが、実は結構いい加減な入力でもどっかの場所にヒットしちゃうんですよね...
でもまぁ、住所の正確性を機械的に把握する方法なんてないですしむずがゆいですが諦めましょう。
いや、一番危惧してるのは「ユーザーのちょっとした誤入力を、ユーザーが気づかないまま処理される」というところです。悪意のある入力に対しては手の施しようがないので無視です。
もちろん、最終的にホストになるためには個人認証を必須にするしかないのかなって感じはしますが、その前段階でなるべく負担を減らしたいところなんですよね。
まぁ、この問題も後回しでいいのかな・・・・・・うーーーん。
とりあえず、これで動くものを作れました。
あとはここに入力された情報をユーザーテーブルにinsertすることで新規登録画面は完成ですし、この情報を基に宿検索および予約フローを作ればプロトタイプは完成になるんですかね。
実際一回Airbnb使ってみたらいろいろ調査が捗るんですが、僕050番号しか持ってないんで電話番号認証できないんですよね(笑)(笑)(笑)
まぁこの辺の問題をどーすっかって感じですが、実在性の証明なんて要らないと僕は思ってるので電話番号認証はつけたくないなーって思ってます。住所が正しければいいんだよ(・∀・)
究極的には、個人認証を目印にしてもらうしかって感じではいます。個人認証済んでないユーザーとやりとりするのは自由だけど、信憑性は落ちるから自己責任でよろしくね、っていう。そういうスタンスでいきたいと思っています。ただホスト側がそれだとちょっとまずいので、将来的にはホストになるには個人認証してね、ってシステムにしたいのですが最初からそれをやるとおそらくまずいので追々ね。
んじゃ、実装してプロフィール画面の機能完成ぐらいが今日の目標かな。プロフィールの編集・変更と、あとユーザー退会あたりの機能なんかつけるか?
・・・・・・いや、プロトタイプ時点でそれって要るのか?
めんどいから表示だけパパっと作る?(悪魔のささやき)
・・・・・・そっちの方が正しいな。プロフィールの変更は本質じゃない。そんなのは後で作ればいいか。
とりあえず画面遷移だけ作って、一通りメインフローが完成したら手をつける感じにしよ。
お久しぶりです!いつもいつもありがとうございます!(・∀・)
まぁ法律の壁ってのは確かにあります。いくら来年1月に民泊法が施行されると言えど、グレーゾーンなことは変わりないですからね。
ただ、住宅は世界各国にあるものなので、必ずしも日本でスタートする必要がないというところが生命線なんですかね・・・・・・。僕自身が適応できないですけど()
あ、エラー報告ありがとうございます。サーバーを人知れずお引っ越ししてたのですが、その際表示に必要なファイルをローカルから消してたのが原因でした・・・・・・。
気づかなかったら一から作り直すことになってました!ありがとうございます笑