質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • JavaScript

    17076questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Google マップ

    375questions

    Google Mapは、Google社がオンラインで提供している地図・ローカル検索サービスです。GIS(Geographic Information System:地理情報システム)の中の「WebGIS」に該当します。地図・航空写真・地形の表示方式があり、それぞれユーザーが縮尺を調整して表示させることができます。地域の情報サービスを検索する機能やルート検索の機能も搭載されています。

  • スコープ

    12questions

    スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

  • コールバック

    9questions

    コールバックは他のコードに引数として渡されるコードのことを指します。

グーグルマップで複数個所にピンが立てたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 2,151

wasi300

score 43

グーグルマップに複数個所ピンを立てて、クリックしたらピンがたった場所への説明がポップアップで出てくるプログラムを作りたいのです。しかし上手く行かなくて困っています。

こんな感じのプログラムの流れにしたいです。

1 DBから住所データをPHPで取得してスクリプトタグ内でループさせる
2 住所をgeocoder内で展開させて緯度と経度を取得する
3 取得した緯度、経度を配列に入れて配列に入れる
4 google.maps.LatLngに緯度、経度と表示したいコンテンツを入れたオブジェクトを住所分生成する
5 new google.maps.Markerとクリックを監視するattachMessageを生成したオブジェクト分呼ぶ

という流れにしたいのですが、2を実行すると、コールバック関数の中から自分がやると値を持ち出せなくて、3以降する事ができません。

2と3の部分のコード

        <?php
        $address = array(
                    "愛知県名古屋市西区浄心",
                    "愛知県名古屋市中村区名駅南",
                    "愛知県名古屋市中村区亀島",
                    "愛知県名古屋市中村区東区白壁",
                    "愛知県名古屋市中区栄4丁目",
                    "愛知県名古屋市中区栄1丁目",
                    "愛知県名古屋市中川区山王1丁目",
                    "愛知県名古屋市中区丸の内",
                    );
        ?>

        var data = new Array();


        <?php for($i=0; $i<count($address); $i++) : ?>

          var geocoder = new google.maps.Geocoder();
          geocoder.geocode(
              { address: '<?php echo $address[$i]; ?>' },
              function( results, status )
              {
                  if( status == google.maps.GeocoderStatus.OK )
                  {
                    lat = results[0].geometry.location.k;
                      lng = results[0].geometry.location.D;
                      data.push({position: new google.maps.LatLng(lat,lng), content: '物件<?php echo $i; ?>'})

                      /* コールバック関数の外で代入しようと思いましたができませんでした・・・ */
                    geocoder.lat = results[0].geometry.location.k;


                  }
                  else
                  {
                      alert( 'Faild:' + status );
                  }
              }
           );

         <?php endfor; ?>

         console.log(data); //[]
         console.log(geocoder); 
         /*
            zi {geocode: function}lat: 35.1742916lng: 136.89973759999998__proto__: zi
...(゚∀゚)
         */
         console.log(geocoder.lat); //undefined
         console.log(geocoder.zi) // undefined

         //...orz

jsonデータをループさせました。間違えてたらごめんなさい。

        var data = new Array();
        var geocoder = new google.maps.Geocoder();
        var encode = 'db→PHP→jsonencodeしたデータ';
        var addressAr = JSON.parse(encode);

        for(i=0; i<addressAr.length; i++)
        { 


         geocoder.geocode(
             { address: addressAr[i] },
              function( results, status )
              {
                  if( status == google.maps.GeocoderStatus.OK )
                  {
                    lat = results[0].geometry.location.k;
                      lng = results[0].geometry.location.D;
                      console.log(lat,lng);
                      /*
                        35.1927384 136.88722489999998
                        (index):96 35.1589488 136.8899139
                        (index):96 35.1754295 136.8752482
                        (index):96 35.1687471 136.87301509999998
                        (index):96 35.1676346 136.91235329999995
                        (index):96 35.1671924 136.89628530000005
                        (index):96 35.1536495 136.89023900000007
                        (index):96 35.1742916 136.89973759999998
                      */
                      data.push({position: new google.maps.LatLng(lat,lng), content: 'ab'})
                      /*dataのデータが増えない*/
                  }
                  else
                  {
                      alert( 'Faild:' + status );
                  }
              }
           );
        }

        console.log(data.length); // 0

          for (i = 0; i < data.length; i++) {
                    var myMarker = new google.maps.Marker({
                  position: data[i].position,
                      map: mapdiv
           });
            attachMessage(myMarker, data[i].content); 
// google.maps.InfoWindowを呼ぶプログラム
        }

ぶしつけですみません。もし分かる方が居たら、助言を下さい・・・。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

PHPでJavaScriptを何度も生成する結果、geocoderが複数回生成されては上書きされる事態になっていて、正常に動作しないのでしょう。PHPからjson_encodeなどを使ってデータだけJavaScriptで渡して、ループはJavaScript側で作るというのが適当でしょう。

あと、geocoder.geocodeのコールバック関数はあとから実行されるものですので、先にconsole.logのところにたどり着いてしまって、空の配列が表示されています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/30 15:56

    maisumakun様、ご回答どうもありがとうございます。本番環境にjson_encodeがないので、phpをjs内に書き込んでました。

    実行結果を確認する時にconsoleだけしか見てなかったので、行数がめっちゃ増えててびっくりしました。本番環境にはjsonencodeっぽいものを探して入れようと思います。

    テスト環境にはjson_encodeがあるので、教えて頂いた事を参考にやってみました。

    Geocoderオブジェクトをループの外で呼ぶようにして、PHPのデータをjson_encodeしてJSON.parseしたデータをforループで回しながらgeocodeメソッドを呼ぶようにしました。
    geocodeメソッド内で、ジオコーディングが出来ているのですが、geocodeメソッド内でpushしてもデータが入りません・・・。

    >>コールバック関数はあとから実行されるものですので、先にconsole.logのところにたどり着いてしまって、空の配列が表示されています。

    このデータは、コールバック関数外で使う事はできないのでしょうか?

    キャンセル

0

コールバック関数で処理したデータを外に持ち出す事が自分には出来なかったので、コールバック関数の中から、データを呼びに行く事にしました。ただ、コールバック関数の中でループが何回目か判断ができないので、関数が呼ばれたら何回呼ばれたか記憶してくれる関数を作って、データの配列を引数を添え字にして返す関数を呼んでその引数としてカウンター用の関数を呼んだら、上手くいってるのかどうか分からないですけど希望通り動作しました。多分やり方的には良くないと思います。もっと良いやり方ないですかねぇ・・。



        var data = new Array();
        var mapdiv = document.getElementById('map');
        var myOptions = {/*googlemapのオプション*/}
        var geocoder = new google.maps.Geocoder();
        var encode = 'jsonデータ';
        var room = 'jsonデータ';
        var map = new google.maps.Map(mapdiv, myOptions);

        var addressAr = JSON.parse(encode);
        var roomAr = JSON.parse(room);

        for(i=0; i<addressAr.length; i++)
        { 


             geocoder.geocode({address: addressAr[i]},function(results,status) {
                  if( status == google.maps.GeocoderStatus.OK ) {

                    lat = results[0].geometry.location.k;
                      lng = results[0].geometry.location.D;
                
                    var myMarker = new google.maps.Marker({
                        position: new google.maps.LatLng(lat,lng),
                        map: map,
                        title: roomAr[i]
                    });

                     var infowindow = new google.maps.InfoWindow({
                        content: '<div><h2 style="font-size : 125%;">'+getdata(counter())+'</h2><br /><a href="#"></a></div>',
                        size: new google.maps.Size(350, 100)
                    });

                    google.maps.event.addListener(myMarker, 'click', function() {
                        infowindow.open(map,myMarker);
                    });    


                  } else {
                      alert( 'Faild:' + status );
                  }
            });
        }

        var counter = (function(){
            var n = 0;
              return function() {
                   return n++;
             };
        })();

        function getdata(num) {
            return roomAr[num];
        }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

関連した質問

同じタグがついた質問を見る

  • JavaScript

    17076questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Google マップ

    375questions

    Google Mapは、Google社がオンラインで提供している地図・ローカル検索サービスです。GIS(Geographic Information System:地理情報システム)の中の「WebGIS」に該当します。地図・航空写真・地形の表示方式があり、それぞれユーザーが縮尺を調整して表示させることができます。地域の情報サービスを検索する機能やルート検索の機能も搭載されています。

  • スコープ

    12questions

    スコープとは、プログラム内で変数名など、参照可能な有効範囲のことを指します。

  • コールバック

    9questions

    コールバックは他のコードに引数として渡されるコードのことを指します。