Developer

【Lightning Web Component】GoogleMapAPIを使って地図を表示させる③

Developer
この記事は約8分で読めます。

こんにちは、アンダーソンです。
今回はGoogleMapAPIを使って地図を表示させてみた第三段です。
今回は指定した箇所の移動距離と時間をとって表示させてみました。

スポンサーリンク

directionsの呼び出し

2点間の移動距離と時間をとるにはdirections APIを使います。
使い方は

https://maps.googleapis.com/maps/api/directions/(出力形式:Json or XML)?origin=(緯度、経度)&destination=(緯度,経度)&key=(yourkey)

です。緯度経度のところは他にも場所の名前(東京ディズニーランドとか)でもOKです。
これを呼び出してJson形式のファイルを受け取るんですが、これがiframe内のJavaScriptでは呼び出しはできないので、Apexでhttpリクエストを行いJsonを受け取る必要があります。
描画自体はiframe内のJavaScriptでできますのでそちらは別で準備します。
ではまずApexです。

@AuraEnabled(cacheable=true)
public static String directions(String mode,String recordId){
 
        Latitude = '35.6684415';
        Longitude = '139.6007843';
        //表示中の取引先の緯度経度を取得
        Account acc = [SELECT Field1__Latitude__s,Field1__Longitude__s FROM Account Where Id = :recordId LIMIT 1];
        //情報をURLへ変更
        String url = 'https://maps.googleapis.com/maps/api/directions/json?';
        String origin = 'origin=' + Latitude + ',' + Longitude;
        String destination = '&destination=' + acc.Field1__Latitude__s + ',' + acc.Field1__Longitude__s;
        String type = '&mode=' + mode;
        String key = '&key=' + GOOGLEAPIKEY;

        String endPoint = url + origin + destination + type + key;
        //コールアウト
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endPoint);
        req.setMethod('GET');
        HttpResponse res = http.send(req);

        return res.getBody();
    }

引数としてmodeとレコードIdを受け取って動的に変更できるようにしています。
originには今回は初期値を入れています。
ではこのApexを呼び出して受け取ったJsonを表示していきます。

jsonData;
@track distance;
@track duration;

modeChange(event){
        
        if (event.target.label === '車移動') {
            getDirections({mode: 'driving',recordId: this.recordId})
            .then (data => {
                this.jsonData = JSON.parse(data);
                this.distance = this.jsonData.routes[0].legs[0].distance.text;
                this.duration = this.jsonData.routes[0].legs[0].duration.text;
            })
            this.param = {
                type : "DRIVING",
                center : { lat: this.accounts.data.Field1__Latitude__s, lng: this.accounts.data.Field1__Longitude__s },
                zoom: 15
            }
        } else if (event.target.label === '徒歩移動') {
            getDirections({mode: 'walking',recordId: this.recordId})
            .then (data => {
                this.jsonData = JSON.parse(data);
                this.distance = this.jsonData.routes[0].legs[0].distance.text;
                this.duration = this.jsonData.routes[0].legs[0].duration.text;
            })
            this.param = {
                type : "WALKING",
                center : { lat: this.accounts.data.Field1__Latitude__s, lng: this.accounts.data.Field1__Longitude__s },
                zoom: 15
            }
        }
        this.search = true;
        
        this.contentWindow = this.template.querySelector('iframe').contentWindow;
        this.contentWindow.postMessage(this.param,VFHOST);
    }

エラーの時の処理は面倒なので今は書いてませんが。。。
これでApexから戻った値をコンポーネントに表示させています。
@trackのデコードをしておくことでこの距離時間が変更されるとコンポーネントが変更されます。

Mapに描画する

iframeのVF側では次のようにしてマップに描画をします。

function directions(center, zoom, mode){
        map = new google.maps.Map(document.getElementById("map"), {});
        let rendererOptions = {
            map: map, 
            draggable: true, 
            preserveViewport: true 
        };
        let directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
        let directionsService = new google.maps.DirectionsService();
        directionsDisplay.setMap(map);
        let request = {
            origin: new google.maps.LatLng(latitude, longitude), 
            destination: new google.maps.LatLng(center), 
            travelMode: mode, 
        };
        directionsService.route(request, function(response,status) {
            if (status === google.maps.DirectionsStatus.OK) {
                new google.maps.DirectionsRenderer({
                    map: map,
                    directions: response,
                    suppressMarkers: true // デフォルトのマーカーを削除
                });
                let leg = response.routes[0].legs[0];
                makeMarker(leg.end_location, markers.goalMarker, map);
                setTimeout(function() {
                    map.setZoom(zoom); // ルート表示後にズーム率を変更
                });
            }
        });
    }

これでOKです。
ではみてみましょう。

うまく切り替わってますね。

まとめ

今回はApexにJavaScriptと二つのプログラミングをうまく使ってそれぞれの動きでMapの表示をやってみました。
今回の実装は簡単なことではありますが、基本的なことなのでぜひ試しにやってみてください。

その他の開発に関する記事はこちらです。

Developerも含めた試験問題にチャレンジしてみましょう。

コメント