GoogleマップAPI v3で地図とマーカー・バルーンを表示(複数版) version1.4b

この記事は公開から1年以上経過しており、内容が古くなっている可能性があります。

【追記】

2012.06.30 バージョンアップしました。(version1.4b4)

2011.11.11 バージョンアップしました。(version1.4b3)

2011.08.13 バージョンアップしました。(version1.4b2)


ここから本文

バージョン1.3で見つかった、「geocoder.geocodeを使用した住所からの座標取得は、一度に取得できる件数に制限がある」という問題に対して、修正を行ったバージョンをアップロードしました。

スクリプトをダウンロードする

サンプルを見る

 

注意点

今回のバージョンではPHPも使用しております。もしPHP5.2以上が利用できないサーバをご利用の場合は、申し訳ございませんが、このバージョンは使用しないでください。

またサーバのPHPの設定(php.ini)で「allow_url_fopen」が有効になっていないと利用できませんので、こちらもご注意ください。

なお、PHPを使用するといっても、AJAXリクエストで実行させているだけなので、実際にマップを表示するページをPHP化させる必要はありません。

※作った直後でまだ十分な実験を行えていないので、このバージョンを使用する際は、よく動作をご確認の上、ご利用ください。

※現在ではv3でもAPIキーが必要となっています。
https://developers.google.com/maps?hl=ja

 

まず、前バージョンのバグの原因と、その対処方法について説明いたします。

そんなことより設置手順だ

 

原因

上記にも書いてある通り、Google Map APIにて、「geocoder.geocode」を使った住所からの座標取得は、短時間で取得できる件数に制限があります。(Google Map APIの仕様)

 

対処方法

こちらのサイトにて、PHPを用いた住所から座標を取得する方法を発見。

[googlemap]phpで住所から座標を割り出す

しかもPHPから取得する場合、件数制限がないっぽい。
【追記】※短時間で、というのは大丈夫ですが、1日における制限ありました。
1日に住所から取得できる件数というのは、大体2500件くらいと決まってるみたいです。[ Google Geocoding API – Google Maps API Web サービス – Google Codeの使用制限参照 ]
ご注意ください。)

とはいえ、毎回取得しに行くのも無駄なので、一度取得できた住所の座標データはCSV形式でサーバに出力しておき、以降はそれを見に行くという方式にしました。(もちろん新しく住所が追加された場合は、取得しに行き、それをCSVに追加します。)

ただ、正直読み込み速度などが微妙なので、まだまだ改良点はありそう。
【追記】※バージョン1.4b2で速度問題はかなり解消されました。

 

設置手順

では設置方法です。「スクリプトの設定」と「map.js」へのパスが変わる(map.jsがgoogle_map_api_jsフォルダの中に入るため)部分以外は、前バージョンと同じです。

 

1.bodyタグに、バルーン用情報を記述します。複数なんでちょっと長くなりますが4件ほどデータを入れます。(以下例)


<ul id="gmap_list">

<li>
<div class='gmap_title'><a name="gmap_title">アロチ本家丸高</a></div>
<div class='gmap_photo'><img src="img/marutaka.jpg" width="120" alt="京橋幸太郎" /></div>
<div class='gmap_info'>
<span class='gmap_address'>和歌山県和歌山市友田町2-50</span><br />
TEL:073-432-3313<br />
営業時間:17:30~3:00<br />
定休日:日曜
</div>
<div class='clear'></div>
<div class='gmap_description'>
醤油でひと煮立ちさせ、一晩寝かせた豚骨でとったスープはコクが生かされクセになる味
</div>
</li>

<li>
<div class='gmap_title'><a name="gmap_title">井出商店</a></div>
<div class='gmap_photo'><img src="img/yamatame.jpg" width="120" alt="山為食堂" /></div>
<div class='gmap_info'>
<span class='gmap_address'>和歌山県和歌山市田中町4-84</span><br />
TEL:073-424-1689<br />
営業時間:11:30~23:30<br />
定休日:木曜(年始休)
</div>
<div class='clear'></div>
<div class='gmap_description'>
和歌山ラーメンの名を全国に知らしめたのがこちらの店。
</div>
</li>

<li>
<div class='gmap_title'><a name="gmap_title">まるイ</a></div>
<div class='gmap_photo'><img src="img/marui.jpg" width="120" alt="まるイ" /></div>
<div class='gmap_info'>
<span class='gmap_address'>和歌山県和歌山市中之島2323</span><br />
TEL:073-427-2662<br />
営業時間:平日19:00~翌3:00/土19:00~翌4:00<br />
定休日:日曜
</div>
<div class='clear'></div>
<div class='gmap_description'>
全国から集まる麺ファンを虜にするこんもりと盛られたネギの山!
</div>
</li>

<li>
<div class='gmap_title'><a name="gmap_title">ラグマン</a></div>
<div class='gmap_photo'><img src="img/raguman.jpg" width="120" alt="ラグマン" /></div>
<div class='gmap_info'>
<span class='gmap_address'>和歌山県和歌山市黒田258-7 玉置マンション1F</span><br />
TEL:073-475-1200<br />
営業時間:12:00~14:00/17:30~23:30 <br />
定休日:水曜日
</div>
<div class='clear'></div>
<div class='gmap_description'>
“らぐまん”ならではのオリジナルラーメンは、34種類!レゲエが流れるログハウス作りのオシャレなお店。
</div>
</li>

</ul>

<div id="map" style="width:500px;height:500px;"></div>
<div class='clear'></div>

※それぞれに情報は必ずリスト形式にしてください。

ここで必要なものは

  • id=’gmap_list’:このIDを元にバルーン、マーカー用データを取得します。必ず「ul」または「ol」につけてください。
  • class=”gmap_title”+aタグ:タイトルをクリックしたときに該当するマーカーの吹き出しを表示します。
  • class=”gmap_address”:このclass名を元に住所を取得し、座標に変換します。
  • id=”map”:ここにマップが表示されます。必ずwidthとheightを指定してください。

となっています。

もちろんこれまでのバージョン同様、座標データからマーカーを表示することもできます。その場合は前バージョンと同じく「class=”gmap_coord”」を含んだタグを追記してください。


<li>
<div class='gmap_title'><a name='gmap_title'>アロチ本家丸高</a></div>
<div class='gmap_photo'><img src='img/marutaka.jpg' width='120' alt='京橋幸太郎' /></div>
<div class='gmap_info'>
和歌山県和歌山市友田町2-50<br />
TEL:073-432-3313<br />
営業時間:17:30~3:00<br />
定休日:日曜
</div>
<div class='clear'></div>
<div class='gmap_description'>
醤油でひと煮立ちさせ、一晩寝かせた豚骨でとったスープはコクが生かされクセになる味
</div>
<div class='gmap_coord'>
34.2326948,135.1848098
</div>
</li>

class=”gmap_coord”の中の座標は

マーカー緯度,マーカー経度

となっています。(座標についてはこちらから手動で取得できます)

 

※ここで注意点。

マーカー座標を設定する際、以下のパターンが考えられます。

(1) すべて住所から座標に変換する場合。(gmap_addressのみ)

(2) すべて座標を「gmap_coord」に用意しておく場合。(gmap_coordのみ)

(3) 住所から変換するものと、座標が用意されているものが混ざっている場合(gmap_address+gmap_coord)

 

(1) のパターンでは、各項目(<li>内部の記述)の中に「gmap_address」を設定すればOKです。
(この場合「gmap_coord」は必要ありません。)サンプル

(2) のパターンについても、各項目の中に「gmap_coord」を設定すれば問題ありません。
(この場合「gmap_address」は必要ありません。)サンプル

問題は (3) のパターンについて。
一度でも住所から座標を取得する項目がある場合は、すべての項目に「class=”gmap_address”」を設定してください。その中で「class=”gmap_coord”」がある場合は、そちらが優先されます。
つまり「class=”gmap_address”」はとりあえずすべての項目の住所に設定しておき、座標に微調整を加えたいなどの項目がある場合のみ、それに「class=”gmap_coord”」をつけて設定する、という感じで設定してください。
サンプル

上記のサンプルはどれも見た目変わりませんが、ソースがそれぞれ違いますので各ページのソースをご覧ください。

 

2.以下のスクリプトをダウンロードしてください。

 

3.スクリプトの設定を行います。

google_map_api_js.zipをダウンロードしましたら、解凍してください。「google_map_api_js」というフォルダができます。

フォルダの中には

  • get_coord.php
  • map_function.php
  • map.js

の3ファイルが入っています。

map.jsをプログラムが編集できるテキストエディタで開き、27行目付近の

var php_path = "js/v1.4b2/google_map_api_js/get_coord.php";

の部分に、「get_coord.php」までのURLパスを記述してください。

例えば、ウェブルートの「js」フォルダに「google_map_api_js」フォルダをまるごとアップロードする場合は

var php_path = "http://ドメイン/js/google_map_api_js/get_coord.php";

となります。

また、17~22行目付近にかけて、座標やズーム値の初期値を設定できます。

var mc_lat = 34.6862971;    //中心座標の緯度(初期値)
var mc_lng = 135.5196609;    //中心座標の経度(初期値)
var mp_lat = 34.6862971;    //マーカーの緯度(初期値)
var mp_lng = 135.5196609;    //マーカーの経度(初期値)
var zoom = 5;        //ズーム値(初期値)
var zoom_max = 15;    //ズームの最大値(MAX20 MIN1)寄り過ぎを防ぐ

以上の設定が終わりましたら、「google_map_api_js」フォルダをまるごとサーバにアップロードしてください。ただし、上記で設定した通り、map.jsには「get_coord.php」までのパスが記述されているので、それに沿った場所にアップロードしてください。

また、「google_map_api_js」フォルダには、CSVファイルを書き出す必要があるため、パーミッションを777にするなど、書き込み権限をつけてください。

 

4.htmlファイルのheadタグにjqueryとmap.js、Google Map APIを読み込んでください。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="js/google_map_api_js/map.js"></script>

※metaタグで文字コードをutf-8にするのを忘れずに。これがないと正常に動作しない場合があります。
※「jquery」とスクリプトファイル一式(「google_map_api_js」フォルダ)は、「js」フォルダにアップロードしたと仮定して記述しています。

 

5.bodyタグのonloadにて、マップ表示用関数を呼び出します。

<body onload="map_all('map','gmap_list')">

map_allの引数について

  • 第一引数:マップを表示するタグのID(今回はmap)
  • 第二引数:バルーン情報が入っているリストタグのID(今回はgmap_list)

これで、マーカー・バルーン付きマップが表示できます。

 

6.スタイルを整えます。以下をheadタグ内に記述するか、別ファイルに保存してheadタグで埋め込んでください。(スタイルシートのダウンロードはこちら


#map{
float:left;
}

.clear{
clear:both;
}

/*吹き出しのスタイル*/
.gmap_block{
width:320px;
}
.gmap_block .gmap_title{
font-size:100%;
font-weight:bold;
margin-bottom:10px;
}

.gmap_block .gmap_photo{
float:right;
margin-left:10px;
overflow:hidden;
}

.gmap_block .gmap_info{
font-size:75%;
}

.gmap_block .gmap_description{
font-size:75%;
margin-top:10px;
}
/*お店の情報(個別用)*/
#gmap_data{
float:left;
margin-right:10px;
width:320px;
}

#gmap_data .gmap_photo{
float:left;
width:130px;
}

#gmap_data .gmap_title{
font-size:100%;
font-weight:bold;
line-height:1.5em;
}

#gmap_data .gmap_info,
#gmap_data .gmap_description{
font-size:75%;
line-height:1.5em;
}

#gmap_data .gmap_description{
padding-top:5px;
}

/*お店の情報(リスト用)*/
#gmap_list{
width:300px;
height:500px;
overflow:scroll;
float:left;
margin:0px;
padding:0px;
}

#gmap_list li{
list-style-type:none;
margin:0px 0px 20px 0px;
padding:0px;
}

#gmap_list .gmap_photo{
float:left;
width:130px;
}

#gmap_list .gmap_title{
font-size:100%;
font-weight:bold;
line-height:1.5em;
}

#gmap_list .gmap_title a{
color:#0000FF;
text-decoration: underline;
cursor:pointer;
}

#gmap_list .gmap_info,
#gmap_list .gmap_description{
font-size:75%;
line-height:1.5em;
}

#gmap_list .gmap_description{
padding-top:5px;
}

.gmap_coord{
display:none;
}

ここまで、ラーメン屋の記述を例にとっておいてなんですが、10件以上表示可能であることをお見せするため、サンプルでは全都道府県の表示例をご用意いたしました。

全都道府県の表示例(47件):サンプル [新しいウィンドウで開く]

【追記】全都道府県の市区表示例(979件):サンプル [新しいウィンドウで開く]

979件ともなるとさすがに重いです^^;

キャッシュができている状態でも表示まで3,4秒かかります。ちなみにキャッシュなしの状態だとマーカーが表示されるまで2分ほどかかりました。

マーカー件数限界は特に調べてませんが多分1000件くらいでも耐えれると思います。ただ上記に書いているように表示まで時間がかかるので、地区別やカテゴリ別で表示するなど件数を減らしてから表示することをお勧めします。

また、1日に住所から取得できる件数というのは、大体2500件くらいらしい(Google Geocoding API – Google Maps API Web サービス – Google Codeの使用制限参照)ので、そちらもご注意ください(キャッシュされているのであればいいですが、1日のうちに2500件以上新規に住所から取得しようとしても多分できません。)

以上です。

バグなどありましたらご連絡いただけるとありがたいです。

コメント

  1. 0606 より:

    使わせていただきますm(__)m
    ありがとうございます(・∀・)

    zoomの初期値がうまく機能しないのは僕の設定がどこかおかしいからですかね~。。

  2. nandani より:

    0606さん
    コメントありがとうございます^^

    zoomについて。
    複数版で使用する場合は、基本的にすべてのマーカーが表示されるように、zoomや中心地は自動調整されます。
    また、マーカーが少ない場合、最大値まで寄ってしまうので、それを防ぐにはzoom_maxを調整します。

    というわけなんですが、そういう意味を超越しておかしかったりしますか?

  3. sun より:

    大変参考にさせていただいております。

    一つお伺いしたいのですが、
    複数マーカーを使用する場合、マーカー個数に制限はあるのでしょうか?

    試しに500件複数表示させたのですが、
    ブラウザ(IE7,8)によってスクリプトが固まってしまいます。
    ※IE9,FireFox,safariでは正常に表示されます。

  4. nandani より:

    sunさん。

    バグ報告ありがとうございます。
    すみません。
    よく調べたら、500件どころか85件超えたくらいで、スクリプトエラーとなってしまうようです。
    nth-childがどうやらアウトっぽいので、ここが修正でき次第、アップロードいたします。
    すぐには無理かもしれませんが^^;

  5. sun より:

    nandani様

    お返事頂きましてありがとうございました。

    こちらのサイトはとても参考になりますので
    今後も参考にさせていただきます。

  6. nandani より:

    sunさん。

    報告していただいたバグ修正が完了しました。
    とりあえずIE7 or 8で900件オーバーでもマーカーが表示されるようになりましたので、もしこの湖面と見てたらご確認してみてください。

  7. yu より:

    はじめまして。コード流用させていただいています、ありがとうございます。
    初期表示されるマップの中心座標がうまくいかなかくて質問させていただきます。

    日本国内の場合はうまく動くのですが、海外でNY近辺に複数ピンをたてたところ、中心が北大西洋あたりにきてしまいます。
    ピンは、
    40.771117,-73.976784
    40.763901,-73.992405
    40.808612,-73.958845
    の3箇所たてましたが、どうもマイナス値がうまく動いていないのでは?という感じがしました。

    お手数おかけしますが、ご確認していただけますでしょうか。
    よろしくお願いします。

  8. nandani より:

    yuさん。

    コメントありがとうございます。

    おわっ!?
    マジですか。
    日本国内でしか試してなかったので気づかなかったです。
    できるだけ早く修正いたしますが、いつになるかは分からない状況です。
    簡単に治ればいいんですが・・・
    ご了承ください。

  9. nandani より:

    yuさん。

    お知らせいただいたバグの件ですが、原因分かりました。
    頂いたコメントの通り、マイナス値を考慮していなかったのが原因でした。
    後日修正版をアップロードいたしますが、とりあえずの解決方法として、「map.js」を開き、map_all関数の中にある125~130行目付近の

    var minLat = 999;
    var maxLat = 0;
    var minLng = 999;
    var maxLng = 0;

    var minLat = 999;
    var maxLat = -999;
    var minLng = 999;
    var maxLng = -999;

    に変更してください。
    これでおそらく正常に動作するかと思います。

    原因の目処を立てていただいたおかげですんなりと解決できました。
    ありがとうございました。

  10. yu より:

    素早いお返事ありがとうございます!
    遅くなりましたが、修正してうまく動くこと確認いたしました。

    すばらしいコードにも、素早いご対応にも、
    大変感動しております。このコード、大切に使います。
    ありがとうございました!!

  11. keith69 より:

    はじめまして!大変ありがたく使わせて頂いております。

    早速ですが質問させてください。

    単一住所でonload=initialize()にしてjavascriptでMapのオプション指定を入れるとMapコントロールの表示部分を変えることが出来たのですが、複数住所のmap_all()指定の際にはうまくいきません。

    map.jsに記述を足してみたりもしたのですが出来ませんでした。

    なにか方法があるのでしょうか?

    よろしくお願い致します。

  12. keith69 より:

    申し訳ありません、自己解決?しました。
    map.js内のmap_optionを見落としていました。
    お恥ずかしい限りです・・・

    失礼致しました。

  13. nandani より:

    keith69さん

    無事解決したようで何よりです^^

  14. sugar より:

    はじめまして!
    マーカーをオリジナル画像にしたいのですが、**をいじればOK的に簡単にできますか?

  15. nandani より:

    sugarさん。

    コメントありがとうございます。
    現在のスクリプトは、マーカー変更を考慮してません。
    というわけで、別のマーカーにするにはスクリプトを変更する必要があります。
    変更箇所は「map.js」の「AddGMarker」関数の中にある

    //////////////////////////////////////////////////////////////////////////////
    // マーカーオブジェクト生成
    var marker = new google.maps.Marker({
    position: position,
    map: map
    });
    //////////////////////////////////////////////////////////////////////////////

    という部分。

    例えば
    http://maps.google.co.jp/mapfiles/ms/icons/red-pushpin.png
    というマーカーに差し替えるとします。
    その場合

    //////////////////////////////////////////////////////////////////////////////
    // マーカーオブジェクト生成
    var marker = new google.maps.Marker({
    position: position,
    icon: “http://maps.google.co.jp/mapfiles/ms/icons/red-pushpin.png”,
    map: map
    });
    //////////////////////////////////////////////////////////////////////////////

    としてください。
    この「icon:」のURLを変えることにより任意のマーカーに変更できます。
    なお、この場合、マーカーの影はつきませんので注意してください。
    影を考慮しだすと座標なども設定する必要が出てきてちょっとややこしくなります。
    こんな感じ。

    //////////////////////////////////////////////////////////////////////////////
    // マーカーオブジェクト生成
    var marker = new google.maps.Marker({
    position: position,
    icon: “http://maps.google.co.jp/mapfiles/ms/icons/red-pushpin.png”,
    shadow: new google.maps.MarkerImage(
    “http://maps.google.co.jp/mapfiles/ms/icons/pushpin_shadow.png”,
    new google.maps.Size(40, 45),
    new google.maps.Point(0, 0),
    new google.maps.Point(18, 34)
    ),
    map: map
    });
    //////////////////////////////////////////////////////////////////////////////

    影の座標やサイズはその画像に寄るのでこまかく調整するしかないです。
    こんな感じでいかがでしょうか。
    がんばってください!

  16. sugar より:

    ものすごく、すばやくお返事いただいてありがとうございます!!
    助かりました!!!

  17. ぽにょ より:

    はじめまして。大変有用なプログラムを公開いただき、ありがとうございます。

    とあるサイトで利用させていただくなかで、IEでうまく表示されないという症状があったのですが、原因がわかりましたのでレアなケースですが、どなたかの役に立つかもしれませんので報告だけさせていただきます。バグではありません。

    当てはまるのは、たぶん以下の条件の場合です。
    —————————
    1:複数ポイント使用

    2:html内で、”gamp_address”や”gmap_coord”のclassを当てているタグに別のクラスも並置している。
    —————————

    この場合、IE全般では正常に表示されません。
    IE用の分岐後の判定で、等価チェックしているため、postdataが取得できない感じです。

    解消方法はもちろん、他classを並置しないことですね。

    ただ、いかんともしがたい場合がありますので、そうした場合は当該判定部分を、match(“gmap_address”) 等とすることで解消します。

    e.g. map.js v1.4b3だと227行あたり
    ///////////////////////
    var str = “”;
    for(var j=0; j<gmap_tag_array.length; j++){
    str = gmap_tag_array[j].className;
    if(str.match("gmap_address")){
    gmap_address = gmap_tag_array[j];
    }else if(str.match("gmap_coord")){
    gmap_coord = gmap_tag_array[j];
    }
    }
    ///////////////////////

    突然、失礼しました。

  18. nandani より:

    ぽにょさん。
    コメントありがとうございます。
    というか、貴重な情報ありがとうございます!^^

  19. mm より:

    すばらしい機能をありがとうございます。設置したところ、クロームでのみ、map部分をドラッグしたりクリックできないようなんですが、設置の仕方を間違えているのでしょうか?
    使用させていただいているのは最新バージョンの(version1.4b4)です。 
    よろしくお願いいたします。

  20. mm より:

    立て続けにコメント申し訳ございません。
    先程のクロームの件、ブラウザの問題だったようで、戻りました。
    ご迷惑おかけしました。

    また、カスタマイズしたい表示について質問がございます。
    マップの下にjQueryのタブで5つほど切り替えて、各切り替えたタブ内にを設置したいと思っております。
    仕様上、は、1つしか設置できないのでしょうか?
    試しに、複数設置してみたところ、ブラウザ上で「gmap_coord」クラスで囲まれた座標が存在しない項目がありますとメッセージがでて困っております。
    よろしくお願い致します。

タイトルとURLをコピーしました