道草日記

通勤幾星霜…寄り道回り道の日記です。

Google Maps API でキャラ移動

2007-09-01 | Ajax/JavaScript

Google Maps APIを使い、マップ上に、キャラクタを表示し、アニメーションで見どころを案内するページを作った。その要点をメモ

参考:Geekなページ:Goolge Maps APIプログラミング

  • 説明、写真ファイル名、経度、緯度を列挙したデータをCSVファイルとして用意
  • アニメーションGIFのキャラクタを用意
  • Ajaxでデータを読み込む
  • Google Mapの中心部にキャラクタを表示
  • データの経度緯度まで、Mapをアニメーション移動
  • データ位置まで来たら、説明と写真を入れた吹き出しを表示
  • 次のデータ位置へ移動


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<META http-equiv="Content-Script-Type" content="text/javascript">
<META http-equiv="Content-Style-Type" content="text/css">
<TITLE>マップガイド by Google Map</TITLE>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAyjE-CmkYoBEG1_vXXnSKtRTtSqMrFOBF7R4HWUv3t6HbAYFw9BTl9n98u93sTmyxu9zWFQ1JHzjLwA"  type="text/javascript" charset="utf-8"></script>
<SCRIPT type="text/javascript">
<!--
var DATANUM;  // ノード数
var node = new Array(); //ノードObj

var DELTA = 60; // 移動増分
var INTERVAL = 40;  //間隔
var PAUSETIME = 50;    //停止時間

var map;    //Google Maps API 1.0
var point; //Gpoint
var zoom;    //現在のMAP倍率(API 1.0形式)
var cnt = 0;    //現在のノード番号
var dtime = 0;  //増分時間
var elapse = 0;  //経過時間
var deltax;
var deltay;

var NODEFILE = "city-node.csv"; //ノードファイル名
var STARTX = 138.5160;  //初期中心経度
var STARTY = 35.6610;  //初期中心緯度
var AX1 = 138.4843;    //拡大倍率の地域の経度、緯度
var AX2 = 138.6128;
var AY1 = 35.6935;
var AY2 = 35.6153;

//ノード・クラス
function class_node(){
  this.msg = "";
  this.img = "";  //写真ファイル名(length=0の場合、停止しない)
  this.x = 0; //東経
  this.y = 0; //北緯
}


function onLoad() {
  zoom = 2;
  loadDataFile(NODEFILE);
  if (GBrowserIsCompatible()) {
// 移動位置を指定するのに1個のGpointを使い回しいしている。
// GMap2のGLatLng()だと、値の代入ができず、その都度newで作ら
// なければならないので。
    map = new GMap(document.getElementById("map"));
    point = new GPoint(STARTX,STARTY);
    map.centerAndZoom(point,zoom);
    window.setInterval("update()", INTERVAL);
  }
}

function update() {
  var htmlstr;
  if (dtime >= DELTA) {
    dtime = 0;
    if (elapse >= PAUSETIME) {
      cnt++;
      if (cnt >= DATANUM) {
        cnt = 0;
      }
      elapse = 0;
    }
  }
  if (dtime == 0) {
    point.x = parseFloat(node[cnt].x);
    point.y = parseFloat(node[cnt].y);
    if (cnt == DATANUM - 1) {
      deltax = (parseFloat(node[0].x) - parseFloat(node[cnt].x)) / DELTA;
      deltay = (parseFloat(node[0].y) - parseFloat(node[cnt].y)) / DELTA;
    } else {
      deltax = (parseFloat(node[cnt+1].x) - parseFloat(node[cnt].x)) / DELTA;
      deltay = (parseFloat(node[cnt+1].y) - parseFloat(node[cnt].y)) / DELTA;
    }
  } else if (elapse >= PAUSETIME) {
    point.x += deltax;
    point.y += deltay;
  }
  if (elapse < PAUSETIME) {
    if (node[cnt].img.length == 0) {
      elapse = PAUSETIME;
    } else {
      if (elapse == 0) {
        if ((point.x > AX1 && point.x < AX2) && (point.y < AY1 && point.y > AY2 )) {
          if (zoom > 2) {
            zoom = 2;
            map.centerAndZoom(point,zoom);
          }
        } else {
          if (zoom = 2) {
            zoom = 4;
            map.centerAndZoom(point,zoom);
          }
        }
        htmlstr ="<table width=200 height=80><tr><td style="font-size:10pt"><a href="./image/"+node[cnt].img+"" target="_blank"><img src="./image/"+node[cnt].img+"" width=100 height=76 align=right border=1>"+node[cnt].msg+"</a></td></tr></table>";
        if (node[cnt].img.length > 0) {
          map.openInfoWindowHtml(point,htmlstr);
        }
      }
      elapse++;
      if (elapse >= PAUSETIME) {
        map.closeInfoWindow();
      }
    }
  } else {
    map.recenterOrPanToLatLng(point);
  }

  if (elapse >= PAUSETIME) {
    dtime++;
  }
}

function loadDataFile(fName)
{
  httpObj = createXMLHttpRequest(makeArray);
  if (httpObj)
  {
    httpObj.open("GET",fName,true);
    httpObj.send(null);
  }
  else {
    alert(httpObj.status);
  }
}

function makeArray()
{
  var tabText;
  var i,j;
  if ((httpObj.readyState == 4) && (httpObj.status == 200))
  {
    tabText = httpObj.responseText;
    lineData = tabText.split('n');
    for (i = 0; i < lineData.length; i++)
    {
      wCount = lineData[i].split(",");
      node[i] = new class_node();
      for (j = 0; j < wCount.length; j++)
      {
        switch(j){
          case 0:
            node[i].msg = wCount[j];
            break;
          case 1:
            node[i].img = wCount[j];
            break;
          case 2:
            node[i].x = wCount[j];
            break;
          case 3:
            node[i].y = wCount[j];
        }
      }
    }
    DATANUM = i - 1; //nodeテキストの最後のデータの後にも改行入れること。
  }
}

  // HTTP通信用、共通関数
function createXMLHttpRequest(cbFunc)
{
  var XMLhttpObject = null;
  try{
    XMLhttpObject = new XMLHttpRequest();
  }catch(e){
    try{
      XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");
    }catch(e){
      try{
        XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");
      }catch(e){
        return null;
      }
    }
  }
  if (XMLhttpObject) XMLhttpObject.onreadystatechange = cbFunc;
  return XMLhttpObject;
}
//-->
</SCRIPT>

</HEAD>
<BODY onload="onLoad()" onunload="GUnload()">
  <img src="【キャラクタ画像ファイル名】" style="z-index:1;position:absolute;left:195px;top:170px;">
  <div id="map" style="width:450px; height:400px; z-index:0; position:absolute;"></div>
</BODY>
</HTML>




最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。