

日本語住所から、google map APIを用いて、複数のマーカーを地図上に表示させるコードを作っています。

複数の住所は、for文を用いてGeocode処理しています。  
また、Geocodeの返り値は非同期処理とのことで、callback関数を使って、すべて住所の緯度経度を取得してから地図を完成させるようにコーディングしています。

実際に当コードを実行してみると、画面上には何の表示もされず（地図は出てこず真っ白）、chromeのデベロッパーツールのconsole上でも何のエラーも表示されません。

コード中にalertを入れて確認してみると、住所の緯度経度自体はきちんと取得できています。  
しかし、地図の中心点を指定する変数の部分はundefinedとなっていました。

いろいろ試行錯誤したのですが、どこが間違っているのか、煮詰まって先に進めません。  
（callback関数の使い方を含め、いろいろ違っているかと思います。）  
何がおかしいのか、ご指摘いただけますでしょうか。

[code]

    <script>
    function initMap() {
    
        var addresses = [
            '東京都千代田区永田町1丁目7-1',
            '東京都千代田区霞が関2丁目1番1号',
            '東京都千代田区霞が関1-1-1',
            '東京都千代田区霞が関2-1-3'
        ];
    
        var latlng = []; //緯度経度の値をセット
        var marker = []; //マーカーの位置情報をセット
        var myLatLng; //地図の中心点をセット用
        var geocoder;
        geocoder = new google.maps.Geocoder();
    
        var map = new google.maps.Map(document.getElementById('map_canvas'));//地図を作成する
    
        geo(aftergeo);
    
        function geo(callback){
            for (var i = 0; i < 3; i++) {
                geocoder.geocode({'address': addresses[i]}, 
                    function(results, status) { // 結果
                        if (status ===     google.maps.GeocoderStatus.OK) { // ステータスがOKの場合
                            latlng[i]=results    [0].geometry.location;// マーカーを立てる位置をセット
                            marker[i] = new     google.maps.Marker({
                                position: results    [0].geometry.location, // マーカーを立てる位置を指定
                                map: map // マーカーを立てる地図を指定
                            });
                        } else { // 失敗した場合
                        }//if文の終了。ifは文なので;はいらない
                    }//function(results, status)の終了
                );//geocoder.geocodeの終了
            }//for文の終了
            callback();//全て取得できたらaftergeo実行
        }//function geo終了
    
        function aftergeo(){
            myLatLng = latlng[0];//最初の住所を地図の中心点に設定
            var opt = {
                center: myLatLng, // 地図の中心を指定
                zoom: 16 // 地図のズームを指定
            };//地図作成のオプションのうちcenterとzoomは必須
            map.setOptions(opt);//オプションをmapにセット
        }//function aftergeo終了
    
    };//function initMap終了
    
    </script>
    
[/code]


CC BY-SA 4.0
2018-10-22T02:59:41.077
49515
2018-10-27T09:34:57.787
30622
question
javascript api google-maps
google map APIで複数の住所をマーカー表示したい


非同期処理なので、「geocoder.geocode」の「function(results, status) { // 結果」はfor文が
**すべて終わってから** 呼び出されます。  
以下の様にforの変数「i」をfunctionの名前空間で保存するようにして、cRef変数でアドレスがすべてGeocode処理されたのを確認して
callback を呼び出すようにすると動作します。

[code]

    <script>
    function initMap() {
    
        var addresses = [
            '東京都千代田区永田町1丁目7-1',
            '東京都千代田区霞が関2丁目1番1号',
            '東京都千代田区霞が関1-1-1',
            '東京都千代田区霞が関2-1-3'
        ];
    
        var latlng = []; //緯度経度の値をセット
        var marker = []; //マーカーの位置情報をセット
        var myLatLng; //地図の中心点をセット用
        var geocoder;
        geocoder = new google.maps.Geocoder();
    
        var map = new google.maps.Map(document.getElementById('map_canvas'));//地図を作成する
    
        geo(aftergeo);
    
        function geo(callback){
            var cRef = addresses.length;
            for (var i = 0; i < addresses.length; i++) {
                (function (i) { 
                    geocoder.geocode({'address': addresses[i]}, 
                        function(results, status) { // 結果
                            if (status === google.maps.GeocoderStatus.OK) { // ステータスがOKの場合
                                latlng[i]=results[0].geometry.location;// マーカーを立てる位置をセット
                                marker[i] = new google.maps.Marker({
                                    position: results[0].geometry.location, // マーカーを立てる位置を指定
                                    map: map // マーカーを立てる地図を指定
                                });
                            } else { // 失敗した場合
                            }//if文の終了。ifは文なので;はいらない
                            if (--cRef <= 0) {
                                callback();//全て取得できたらaftergeo実行
                            }
                        }//function(results, status)の終了
                    );//geocoder.geocodeの終了
                }) (i);
            }//for文の終了
        }//function geo終了
    
        function aftergeo(){
            myLatLng = latlng[0];//最初の住所を地図の中心点に設定
            var opt = {
                center: myLatLng, // 地図の中心を指定
                zoom: 16 // 地図のズームを指定
            };//地図作成のオプションのうちcenterとzoomは必須
            map.setOptions(opt);//オプションをmapにセット
        }//function aftergeo終了
    
    };//function initMap終了
    
    </script>
    
[/code]


CC BY-SA 4.0
2018-10-27T09:34:57.787
49706
2018-10-27T09:34:57.787
30719
49515
answer