Logical Rabbit.

さくらのVPS

Google Map JavaScript APIで任意のマーカーアイコンを使用する方法と、そのアイコンの凡例をHTML表示するメモ。

1) ペイントソフトで1枚の画像ファイルに複数のアイコンを描いて 2) Google Map JavaScript APIで画像ファイルから各々のアイコンを切り出し、マーカーアイコンとして適用して 3) 同時にHTMLでも各々のアイコンを切り出し、凡例を表示する までの手順メモです。

取り敢えずメモなので説明画像も何もないですが、そのうち追加すると思いますよ、えぇそのうち…

用意するもの

  1. お絵かきソフト (アンチエイリアシング、透過PNG画像作成ができるもの)
  2. アイコンデザイン画
  3. HTMLとJavaScriptソースを書くためのツール
  4. Google Map JavaScript APIのAPIキー

手順1. 画像ファイルの作成

アイコンをまとめた画像ファイルの作成については、古のスプライトとかビットマップ画像とかを見たことがある人なら何の説明も要らない気がします。要はアレです。

何はともあれ、画像ファイルにアイコン画像を描きこみます。この際、アイコンの形状に関わらず、四角形(正方形のほうが管理しやすいと思います)の中央に収まるようにします。

次に、アイコン形状的に余白となる部分をマジックワンド等で選択、透過部分となるように設定します。具体的には消去して透明にするとか、アルファチャネルいじるとか。

透過部分の指定が終わったら、透過PNG画像として保存します。ここでは marker_icons.png とします。たぶんGIFでもJPEGでも、透過できて一般的なWebブラウザで表示できる形式なら何でもOKと思います。まあJPEGは予想外のゴミが入りそうだから止めた方がいいと思うけど。

手順2. Google Mapで使用するマーカーへの適用

マーカー( google.maps.Markerクラス )へ任意の画像ファイルを指定する方法は、コンストラクタのmarkerOptionsに iconプロパティ を指定することで行います。iconプロパティへはSVGパスかオブジェクト( google.maps.Icon )を指定可能なので、今回は後者のオブジェクト指定を使用します。

iconオブジェクトでは画像ファイルのURL (url)、画像ファイル中でのアイコン開始位置 (origin)、アイコンの大きさ (size) を指定します。他にもアイコンに被せるラベル文字列の開始位置などを指定できるので、微調整が必要な場合はこれらで調整していきます。

origin プロパティは google.maps.Pointクラス、size プロパティは google.maps.Sizeクラスを指定します。

例: /images/makrer_icons.png を読み込み、画像左上から30×30ピクセルのアイコン画像を使用する場合

var pos = new google.maps.LatLng( lat, lng );
var markerOptions = {
  label: 'marker',
  position: pos,
  map:       window.map,
  icon: {
    url: '/images/marker_icons.png',
    origin: new google.maps.Point( 0, 0 ),
    size: new google.maps.Size( 30, 30 )
  }
};
var marker = new google.maps.Marker( markerOptions );

手順3. HTMLによる凡例の表示

凡例を表示する際、先述の makrer_icons.png をそのまま表示してしまうと、複数のアイコン画像がずらずら並んだモノが出てしまいよろしくありません。このファイル自体に凡例としての説明部を書き込んでしまうという手もありそうですが、なんだか無駄が多いので止めておきましょう。うん、止めよう(ちょっと企んだ)

凡例の構成としては 1) アイコン、 2) 説明文 の列挙となりますので、 <ul> タグを使用して、リストのヘッダにアイコン画像を表示することにします。この際 <li> タグの list-item-image 属性では画像のクリッピングができないので、:before を使用して背景画像として表示することにします。

例: /images/makrer_icons.png を読み込み、画像左上から30×30ピクセルのアイコン画像について凡例を表示する場合

<style>
.marker {
  list-style-type: none;  /* デフォルトのリスト接頭辞は非表示にする */
}

.marker:before {
  background: url('/images/marker_icons.png') no-repeat 0px 0px; /* 画像を読み込み、左上部分から表示 */
  width: 30px;   /* 画像の表示幅 = クリッピング領域 */
  height: 30px;  /* 画像の表示高さ = クリッピング領域 */
  top: 0;
  left: 0;
  display: inline-block; /* 幅を指定するのでblock、<li>の本文に並べるのでinline */
  vertical-align: middle; /* バランスを考えて<li>の本文が画像中央に来るようにする */
  content: ' ';
}
</style>

<ul>
  <li class="marker">これはアイコンの説明文です</li>
</ul>

実際には複数のアイコンを説明することになるはずなので、クラス定義はアイコンの数だけ用意し、表示位置を変えていくことで切り出し位置を定義します。