2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SalesforceAdvent Calendar 2023

Day 12

【Apex】カスタム住所項目の緯度経度の取得

Last updated at Posted at 2023-12-11

2022年に引き続き、2回目のアドベントカレンダー参加です(*'ω'*)

きっかけ

カスタム住所項目がWinter'23にリリースされてから1年が過ぎ、扱うことも増えてきました。

設定自体の煩雑さはさておき
今回はカスタム住所項目の緯度経度を取るのにちょび苦戦したので記事にします。
最後に2住所間の直線距離を取得するメソッドのサンプルコードも書いてます。

標準住所項目の緯度経度の取得方法

以下のヘルプ記事が参考になりますが、
データインテグレーションルールを有効化するだけです。
Addressクラスの変数に入れてあげたらlatitude、longitudeのプロパティで参照できます。

カスタム住所項目の緯度経度の取得方法

カスタム住所項目にはデータインテグレーションルールがないので
GoogleMapのAPIをコールする必要があります。
緯度経度取るためだけに外部連携、、ぐぬぬ。

APIキーの取得

こちらの記事が分かりやすかったです。

HTTPリファラー(ウェブサイト) を設定すると
API keys with referer restrictions cannot be used with this API.
のエラーが出るので別の制限を設けること

Apexでコールアウト処理を実装する

APIキーが取得できたら↓のヘルプどおり実装
リモートサイトまたは指定ログイン情報の設定も忘れずどうぞ

サンプルコード

2住所間の直線距離を取得するメソッドです。

★★★はAPIキーをいれてください。
カスタム住所項目(Address__c)の緯度経度をAPIで取得し
標準項目(Account__r.ShippingAddress)との距離をAddress.getDistance()で取得しています。
レスポンスボディは必要な要素だけ抜いてます。

殴り書きで汚くてスミマセン(*'ω'*)

GeoCode
public class GeoCode {
    public static Double GetDistance(Id id) {
        // レコードを取得
        CustomObject__c customObject = [SELECT Address__c, Account__r.ShippingAddress FROM CustomObject__c WHERE Id = :id];
        
        // Google Geocoding APIを呼び出し
        String key='★★★';
        Http httpProtocol = new Http();
        HttpRequest request = new HttpRequest();
        String endpoint = 'https://maps.googleapis.com/maps/api/geocode/json?address='+ customObject.Address__c +'&key='+key;
        request.setEndPoint(endpoint);
        request.setMethod('GET');
        
        // レスポンスを処理
        HttpResponse response = httpProtocol.send(request);
        Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
        List<Object> addressComponents = (List<Object>)results.values()[0];
        Map<String, Object> component = (Map<String, Object>)addressComponents[0];
        Map<String, Object> geometry = (Map<String, Object>)component.get('geometry');
        Map<String, Object> location = (Map<String, Object>)geometry.get('location');
        
        // 緯度と経度を取得
        Double lat = (Double)location.get('lat');
        Double lng = (Double)location.get('lng');
        System.Location loc = System.Location.newInstance(lat,lng);
       
        // 標準項目との直線距離を取得
        Address shippingAddress = customObject.Account__r.ShippingAddress;
        return shippingAddress.getDistance(loc, 'km');
    }
}

実行結果

カスタム住所項目(Address__c)には東京駅の住所
image.png

標準項目(Account__r.ShippingAddress)には新宿駅の住所
※「JAPAN」にしないとデータインテグレーションルールが動かない(-_-;)
image.png

アノニマスウィンドウで実行した結果が5.94km
System.debug(GeoCode.GetDistance('a0A2r000000HQYgEAO'));
image.png

Googleマップの画面で測定した距離が5.92km
image.png

東京駅の住所が1丁目と広範囲であるかつ
レスポンスの処理で'location'を取ってきている('northeast'と'southwest'もある)ので
若干ズレが出たましたが
ちゃんと住所を入れてくれたら実用できるのではないかと!(*'ω'*)

でもわざわざAPI叩くのはもったいない気がするので
Salesforceさん、カスタム住所項目も簡単に緯度経度取れるようにしてください~~

あとがき

Salesforce開発に携わって4年目になりました。
開発者不足で大御所扱いされる最近です。ぴえ~~。
2024年は変化の一年となり忙しくなりそうですが、Qiita投稿は適度に続けたいです!
それではみなさん、メリークリスマス&よいお年を(*'ω'*)

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?