日別アーカイブ: 2017-03-11

地図を目次にする簡潔方法

概要

以前に、地図を目次にするウィジェットの作り方で本格的な地図の利用法を掲載しましたが、今回は違う仕組みで簡単な地図目次を作ってみます。

仕組み

ここでは、canvas要素にaddEventListenerを用いてマウスイベントを取り付けて、クリック位置を管理します。マウスイベント関数では、地図上にあらかじめ定義された領域とクリックされたポイントを突き合わせてどの県都が選択されたかを決定します。

作成内容

関東地方、一都六県の地図の所定位置をクリックするとその県都の情報が表示されるものです。

地図を目次にする手順

①基準となる地図を用意する

例として最後の方に示す関東地方の地図(KantoArea1.png)を考えます。地図は自然な形で画面に収まるサイズが望ましいです。もう少し小さい方が更に引き立つと思われるますが、他に表示するものがないので横550px、縦520pxにしました。

➁クリック有効領域を地図にマークする

県や都の地図上の形は複雑ですが、長方形で代表することにします。下のような地図(KantoArea2.png)を作成します。オリジナルな地図(KantoArea1.png)を残しておくことが大切です。

③補助線付き地図とクリック位置が表示されるJavaScriptコードを作成します。このサンプルコードは栃木県から群馬県まで時計回りに、黄色に象られた長方形の左上と右下を順にクリックして、領域の範囲をテーブル化するためだけにあります。入力を失敗したときは再読み込みをしてやり直します。

<html>
<script type="text/javascript" charset="Shift_JIS">
const mesg=["左上", "右下"];
const pref=["栃木", "茨城", "千葉", "神奈川", "東京", "埼玉", "群馬"];
const point=[226, 46,374,173, 380, 58,505,294, 325,302,503,508,   // 画面上の位置
             174,235,305,321, 165,322,312,371, 141,383,303,483,  54, 81,212,206];
var img1 = new Image();                                 // 画像オブジェクト,ロードする
img1.src = "../material/KantoArea2.png";                // 1都6県
var m=n=0;                                              // n:0~6、訪問地番号
var ctx;
//------------------------------------------------------// 2017-03-11
function starting(){                                    // draw-top、ページの読み込み時に実行される
  var canvas = document.getElementById('east');         // canvasの要素を取得する
  if(canvas.getContext){                                // canvasオブジェクト
    ctx = canvas.getContext('2d');                      // canvasのコンテキスト
    canvas.addEventListener('click', clickfunc , false);// マウスイベントを取り付ける
    ctx.drawImage(img1, 0, 0, 550, 520);                // <<<<< 奥の細道全行程図を描画 >>>>>
  }
}                                                       // draw-bottom
function clickfunc (event) {                            // クリックされた時の処理
  document.getElementById("sound3").play();             // キー押下音
  m = Math.floor(n / 2);
  console.log("N="+n+" : "+pref[m]+" "+mesg[n%2]+" X="+event.offsetX+" Y="+event.offsetY);
  ++n;
  return;                                               // 戻り値のない関数は省略可能
}
</script>
<body onload="starting()"><canvas id="east" width="550" height="520" style="border: 0px #999 solid"></canvas></body>
<audio id="sound3" src="https://aidesign.lolipop.jp/wp-content/uploads/2015/09/select06.mp3"></audio>
</html>

④上の関東地方地図の右にデバッグ情報として出力されたクリック位置の値を参照してpointテーブルを編集します。

⑤次に、これまでの開発用コードを保存し、補助線なしの地図に切り替え、クリックされた都県を認識する目次の機能を追加します。

⑥デバッグ用ステートメントを削除するかコメント文にします。使わなくなったmesgテーブルや変数mなども削除します。完成版サンプルコードを以下に掲載します。27行の三項演算子で東京では都を、その他では県が付加されます。33行のreturnは省力できますが、29行のreturnを省略すると正しく動作しません。

<html>
<script type="text/javascript" charset="Shift_JIS">
const pref=["栃木", "茨城", "千葉", "神奈川", "東京", "埼玉", "群馬"];
const point=[233,  6,364,188, 370, 42,536,289, 345,297,532,514,   // 画面上の位置
             138,381,301,486, 134,322,338,372, 116,217,329,314,  66, 46,217,206];
var img1 = new Image();                                 // 画像オブジェクト,ロードする
img1.src = "../material/KantoArea1.png";                // 1都6県
var n=0;                                                // n:0~6、訪問地番号
var ctx;
//------------------------------------------------------// 2017-03-11 Completed.
function starting(){                                    // draw-top、ページの読み込み時に実行される
  var canvas = document.getElementById('east');         // canvasの要素を取得する
  if(canvas.getContext){                                // canvasオブジェクト
    ctx = canvas.getContext('2d');                      // canvasのコンテキスト
    canvas.addEventListener('click', clickfunc , false);// マウスイベントを取り付ける
    ctx.drawImage(img1, 0, 0, 550, 520);                // <<<<< 奥の細道全行程図を描画 >>>>>
  }
}                                                       // draw-bottom
function clickfunc (event) {                            // クリックされた時の処理
  document.getElementById("sound3").play();             // キー押下音
  //console.log("X="+event.offsetX+" Y="+event.offsetY);
  ctx.clearRect(210, 10, 220, 24);
  ctx.font = "18px Gill Sans MT Bold";                  // set font.
  ctx.fillStyle = "red";                                // メッセージの色
  for(var i=0; i<7; ++i){                               // 地点を検索する
    if(ck(event.offsetX, event.offsetY, i)){            // x,yをチェック  検索地の左端・上端~右端・下端
      var s = (i != 4) ? "県" : "都";                   // 東京ならば「都」
      ctx.fillText(pref[i]+s+"が選択されました", 210, 30);
      return;                                           // breakはNG
    }
  }
  ctx.fillText("該当する都県がありません", 210, 30);    // 検出にヒットしない
  return;                                               // 戻り値のない関数は省略可能
}
function ck(x, y, j){                                   // クリックされた位置の有効性をチェック
 if(x>=point[j*4] && x<=point[j*4+2] && y>=point[j*4+1] && y<=point[j*4+3])return true;//範囲内,左端・上端~右端・下端
 return false;                                          // 範囲外
}
</script>
<body onload="starting()"><canvas id="east" width="550" height="520" style="border: 0px #999 solid"></canvas></body>
<audio id="sound3" src="https://aidesign.lolipop.jp/wp-content/uploads/2015/09/select06.mp3"></audio>
</html>

さいごに

多角形で象られた複雑な領域をクリックして制御するデータを作成するツールが出回っていますが、ここでは単純な長方形だけをサポートしています。

長方形だけでは県境で誤差が出て正確さを欠きますが、それでも県庁所在地付近では正確に都県を選択することが可能です。まずは簡単な仕組みを理解して高みを目指しましょう。

詳細な都県情報を出力するには、上記コードの28行を拡張して都県が運営するホームページにジャンプするように編集します。