DISTANCE関数、GEOLOCATION関数とは
Spring’16からSOQLでDISTANCE関数が使用できるようになりました。
DISTANCE関数
DISTANCEは以下のような形で使用します。
DISTANCE(緯度経度or住所, GEOLOCATION, 単位)
DISTANCEの第一引数は緯度経度型または住所複合型(取引先の請求先住所など)で指定します。
第二引数はGEOLOCATION関数を使って、緯度経度を出します。
第三引数は距離の単位を指定します。
今のところ、キロ’km’かマイル’mi’のどちらかしかないそうです。
DISTANCE関数はSelect文でも、Where文でも、Order by句でも使用することが可能です。
GEOLOCATION関数
GEOLOCATION関数もセットで使用されるため、こちらも使い方を簡単に説明します。
GEOLOCATION(緯度, 経度)
こちらは緯度と経度を数値で指定して、緯度経度型を返します。
実際に使ってみる
私が野球が好きということもあり、東京駅(緯度:35.681167 経度:139.767052)から30km未満のスタジアムを取得するプログラムを作ってみます。
使用するデータ
プロ野球12球団の本拠地を以下オブジェクトで登録します。
ラベル | API参照名 | データ型 |
---|---|---|
球場名 | Name | テキスト(80) |
緯度経度 | LatLng__c | 地理位置情報 |
登録したデータはこんな感じ
球場名 | 緯度経度 (Latitude) | 緯度経度 (Longitude) |
---|---|---|
ZOZOマリンスタジアム | 35.645195 | 140.030858 |
ナゴヤドーム | 35.185958 | 136.947305 |
ほっともっとフィールド神戸 | 34.680657 | 135.073416 |
マツダ Zoom-Zoom スタジアム広島 | 34.391784 | 132.483526 |
メットライフドーム | 35.768790 | 139.420591 |
横浜スタジアム | 35.443336 | 139.640000 |
楽天生命パーク宮城 | 38.259974 | 140.904462 |
京セラドーム大阪 | 34.670387 | 135.475066 |
阪神甲子園球場 | 34.721206 | 135.361621 |
札幌ドーム | 43.014841 | 141.408055 |
東京ドーム | 35.705639 | 139.751891 |
福岡 ヤフオク!ドーム | 33.593835 | 130.363662 |
明治神宮野球場 | 35.674510 | 139.717049 |
Apexコードから検索して表示
東京駅(緯度: 35.681167 経度: 139.767052)から30km未満のスタジアムを検索するプログラム
Double lat = 35.681167; Double lng = 139.767052; List stdList = [ Select Id, Name, DISTANCE(LatLng__c, GEOLOCATION(:lat, :lng), 'km') DIC From Stadium__c Where DISTANCE(LatLng__c, GEOLOCATION(:lat, :lng), 'km') <= 30 Order by DISTANCE(LatLng__c, GEOLOCATION(:lat, :lng), 'km') ]; for(Stadium__c std : stdList){ String str = std.Name + '' + std.get('DIC') + 'kmです'; System.debug(str); }
出力結果
明治神宮野球場まで4.576767299971091kmです
ZOZOマリンスタジアムまで24.165917067639356kmです
横浜スタジアムまで28.83487176521629kmです
見事に東京駅から30km圏内のスタジアムが抽出されました。距離は細かいところまで出ますね。
注意点
- DISTANCE関数はあくまで2地点での直線距離なので、実際のルートはヘリでも使わない限り長くなります。
- DISTANCE関数で条件を絞り込む場合、サポートされるのはイコールなしの不等号(>または<)のみとなります。 =>や=<を使用すると、以下エラーが発生します。
System.UnexpectedException: The DISTANCE function only supports the operators > and <. Try rewriting your query using one of those operators.
- 距離の単位はキロかマイルしかサポートされていませんので、メートル指定したい場合は、キロに変換する必要があります(300mだったら、0.3キロに変換)
- Order byで別名は使用できないため、上記のように距離の近い順からソートするような場合は、Select句で指定した書き方を同じように書く必要があります。ちょっと面倒。。。
補足
DISTANCE関数は住所複合型を指定することも可能です。
東京駅から住所(請求先)(BillingAddress)までの距離を取得
Select Id, Name, DISTANCE(BillingAddress, GEOLOCATION(35.681167, 139.767052), 'km') From Accountt
でも、緯度経度と住所を逆にすると使えなかったようです。
Select Id, Name, DISTANCE(GEOLOCATION(35.681167, 139.767052), BillingAddress, 'km') From Account
→このSOQLはエラー
また、住所を2つ使用することもNGでした。
Select Id, Name, DISTANCE(BillingAddress, BillingAddress, 'km') From Accountt
→このSOQLもエラー
以上のことから、第一引数には住所複合型or緯度経度型、第二引数にはGEOLOCATIONを指定するということが正しい使い方のようです。
コメント