読者です 読者をやめる 読者になる 読者になる

カンボジアで働いている人の備忘録

24歳、なんかカンボジアで起業したみたいです(他人事)

未経験でWEB関連の仕事に取り掛かった - 4・5日目

カンボジア プログラミング

今回の修正要望は「同一緯度経度に複数のマーカーが存在する場合でも、現状では1つのマーカーしか表示されていない。それでは困るので、Google Mapのマーカーをクリックした際に複数のデータを表示したい」というもの。

この要望を実装するために、Google Map上の複数のマーカーをまとめる機能である「クラスター化」を適用した。しかしパラメーターがおかしいのか、思い通りの動きをしてくれない...というのが前回までのあらすじ。

とにかく一個ずつ進んでいこう

英語でドキュメントを検索しても欲しい情報が見当たらない。こういう場合「パラメーターを変える→動作させて結果を確認」という作業を繰り返して、どのパラメーターがどういう変化をもたらすのかを推測していくしかない。適当に数字をいじくっていると、思い通りの動きをするポイントを発見。やったぜ。

次は「複数のデータをリスト化して表示」という機能を実装しなければならない。これもやり方が分からないので「Gmap3 Cluster Infowindow PHP」 とかのキーワードでググってみる。

...が、これも欲しい情報がヒットしない。もしかしたら正解の情報もあったのかもしれないが、知識不足で内容が理解できない。まーたこのパターンか。プログラマあるある。

行き詰まりそうな感じがしたので方向転換。既存ソースを眺めて記法から推測する方法でやってみる。「それっぽい箇所にそれっぽいコードを書く→動くかどうかチェック」という当てずっぽうスタイル。まさに最終手段。

どっかそれっぽいところないかなぁ...と思っていると、マーカーに関するプロパティを定義している箇所にevent : mouseoverとかmouseoutとかいう記述を発見。どうやら「マウスがマーカーに触れた・離れた時にこういう動きをするよ!」という命令をまとめて書いているっぽい。

もしもこれと同じ記述でいいなら、クラスターに対してevent : clickを設定すればいいんじゃね?と推測。「Gmap3 Cluster Infowindow PHP click event」で再び検索。それっぽいことを書いている海外サイトがヒット。これか。

gmap3 - Getting markers that are inside clusters | CookiesHQ

このサイトの記法をコピペしてJavaScriptを実行してみると...エラーなく動いた。あー、良かった。

情報取得のためのロジックを組んでみよう

Infowindow、つまり「リストを表示させるための器」は用意できた。しかし肝心の中身が存在しない状況。正直、ここからかなり難しそうだなぁ。今まではコピペで済ませられたけど、ここから先はそうもいかない。

マーカーに含まれる住所情報、詳細ページのURL生成、サムネイル用の画像データ...解決すべき問題がたくさんある。一個ずつやらないと。これも推測しつつトライアンドエラーで立ち向かう。

色々試した結果、以下のコードで必要な情報を引っ張ってこれた。

まずは第一ステップ。普通にマーカーをGoogle Mapに表示する際に記述するコード。住所情報の数だけMarkerが生成されるので、クラスター化の際に必要な情報はtagプロパティに埋め込んで再利用できるようにしておく。

marker:{
    values:[
        tag:['詳細ページURL, サムネ画像URL, ID'], 
        latLng:[緯度, 経度],
        data:['infowindowに表示させたい内容']
        ...(省略)...
    ]
}

そして第二ステップ。Google Map上に表示されたマーカーをクラスター化し、そのクラスター化されたマーカーを再び読み込み直して情報を再取得するコード。

cluster:{
    radius:100,
    0: {
        content: '<div class=\'cluster cluster-1\'>CLUSTER_COUNT</div>',
        width: 53,
        height: 52
    },
    20: {
        content: '<div class=\'cluster cluster-2\'>CLUSTER_COUNT</div>',
        width: 56,
        height: 55
    },
    50: {
        content: '<div class=\'cluster cluster-3\'>CLUSTER_COUNT</div>',
        width: 66,
        height: 65
    },
    events:{
        click: function(marker, event, context){
            var length = context.data.markers.length,  //クラスター化されたマーカーの要素数を取得。
            tag_array = [],
            infowindow_contents =''
            for (index = 0; index < length; index++) { //要素数だけfor文を回す。
                tag_array = context.data.markers[index].tag[0], //tag要素が複数ある場合、配列として取得される。
                tag_array = tag_array = tag_array.split(',') 
                console log(tag_array[0]) //詳細ページURL
                console log(tag_array[1]) //サムネ画像URL
                console log(tag_array[2]) //ID
                infowindow_contents += '<a href = \'' + tag_array[0] + '\'>'
                                   +         '<img src = \'' + tag_array[1] + '\'>'
                                   +         context.data.markers[index].data + ' ID:' + tag_array[2] + '<br>'
                                   +   '</a>'
            }
            $(this).gmap3({
                infowindow:{
                    latLng: context.data.latLng,
                    options:{
                        content: infowindow_contents
                    }
                }
            });     
        }
    }
}

これで「クラスター化したマーカーにInfowindowを表示する」「そのInfowindow内にサムネイルと詳細情報用ページリンクを埋め込む」という二つの壁をクリアできた...長かった。

Gmap3のClusterに関するドキュメントが少なくてかなり疲れた。ある程度は勘で補完しないといけないのは、やっぱりしんどい。

とにかく要望されてた機能は実装できた。後はテストを重ねて、本番環境で問題なく動作することを祈るのみ。あぁ怖い。