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

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

ただいまの
回答率

90.51%

  • Google API

    528questions

    Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

GoogleMapマーカークラスタの挙動について

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 311

yutabo

score 2

前提・実現したいこと

以下の内容でgooglemapを利用したシステムを作りました
1.GET値から範囲を取得してPHPで該当範囲の情報を
含むxmlデータを作成
2.取得したxmlデータを元にクリック情報を含むマーカーを配置
※スクロールや拡大縮小で1の情報を再取得
3.マーカークラスタを作成

動作を確認すると1,2までの場合は再読込やマーカーをクリック
した時の動作に問題ありませんでした。
しかし3(コードでいうと73行目)を足すと挙動がおかしくなります。
・マーカークラスタをクリックした後にマーカーをクリックすると
インフォウインドーが表示されない、違うマーカーに表示される。
・画面スクロール後の再読込後にマーカーをクリックすると
インフォウインドーが表示されない、違うマーカーに表示される。

マーカークラスタを使用した場合でも問題ない動作にしたいです。

該当のソースコード

<?php
<!DOCTYPE html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>地図データの表示</title>

<script type="text/javascript" src="./js/jquery-1.4.2.min.js"></script>
<script type="text/javascript"     src="https://maps.googleapis.com/maps/api/js?key=hoge"></script>
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>

    <script type="text/javascript">
        var currentInfoWindow
        var marker_ary = new Array();
        var mcs = [];

function initialize() {
        uluru = {lat: lat, lng: lng};    //GETから取得した範囲をセット

        map = new google.maps.Map(document.getElementById('map'), {
            center: uluru,
            zoom: 13
        });

        //最大ズームレベルの設定
        google.maps.event.addListener(map, 'zoom_changed', function() { 
          if ( map.getZoom() < 13 ) { 
            map.setZoom(13); 
          } 
        });

        //idle時のイベント
        google.maps.event.addListener(map, "idle", function() {
            setPointMarker();
        });
}

        function setPointMarker(){
            //リストの内容を削除
            $('#pointlist > ul').empty();

            MarkerDelete();    
            mcs = [];

            //地図の範囲を取得
            var bounds = map.getBounds();
            map_ne_lat = bounds.getNorthEast().lat();
            map_sw_lat = bounds.getSouthWest().lat();
            map_ne_lng = bounds.getNorthEast().lng();
            map_sw_lng = bounds.getSouthWest().lng();

            downloadUrl(指定したURLからXMLファイルを取得, function(data){
                var xml = data.responseXML;

                var markers = xml.documentElement.getElementsByTagName('marker');
                Array.prototype.forEach.call(markers, function(markerElem){

                    var name = markerElem.getAttribute('name');

                    MarkerSet(parseFloat(markerElem.getAttribute('lat')),parseFloat(markerElem.getAttribute('lng')),'<div class="map">' + name + '</div>');

                    //リスト表示
                    var marker_num = marker_ary.length - 1;
                    //liとaタグをセット
                    loc = $('<li>').append($('<a href="javascript:void(0)"/>').text(name));
                    //セットしたタグにイベント「マーカーがクリックされた」をセット
                    loc.bind('click', function(){
                        google.maps.event.trigger(marker_ary[marker_num], 'click');
                    });
                    //リスト表示
                    $('#pointlist > ul').append(loc);
                });
                var markerCluster = new MarkerClusterer( map, mcs,{imagePath:'./images/m'} );
            });

        }

        function MarkerSet(lat,lng,text){
            var marker_num = marker_ary.length;
            var marker_position = new google.maps.LatLng(lat,lng);
            var markerOpts = {
                map: map, 
                position: marker_position
            };
            marker_ary[marker_num] = new google.maps.Marker(markerOpts);

            mcs.push(marker_ary[marker_num]);
            if(text.length>0){
                var infoWndOpts = {
                    content : text
                };
                var infoWnd = new google.maps.InfoWindow(infoWndOpts);
                google.maps.event.addListener(marker_ary[marker_num], "click", function(){
                    //先に開いた情報ウィンドウがあれば、closeする
                    if (currentInfoWindow) {
                        currentInfoWindow.close();
                    }
                    //情報ウィンドウを開く
                    infoWnd.open(map, marker_ary[marker_num]);
                    //開いた情報ウィンドウを記録しておく
                    currentInfoWindow = infoWnd;
                });
            }
        }

        //マーカー削除
        function MarkerDelete() {
            if(marker_ary.length > 0){
                //マーカー削除
                for (i = 0; i <  marker_ary.length; i++) {
                    marker_ary[i].setMap();
                }
                //配列削除
                for (i = 0; i <=  marker_ary.length; i++) {
                    marker_ary.shift();
                }
            }
        }

    </script>
</head>    
<body onload="initialize()">
<div id="pointlist" style="width:20em;float:left;">
    <ul>
        <li>地点リスト</li>
    </ul>
</div>
<div style="float:left;">
    <div id="map" style="width:700px; height:700px"></div>
    <div id="result"></div>
</div>
</body>
</html>

試したこと

デバッグをすると68行目のクリックイベントのイベントでセットした
つもりのインデックスからずれてしまうのが原因のようです。
マーカークラスタを追加すると、なぜこのような挙動になるのかが
分かりません。

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

まだ回答がついていません

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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

  • Google API

    528questions

    Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。