iPhone3.0の緯度経度APIを用いて移動履歴をマップに反映

iPhone3.0の緯度経度APIを用いて移動履歴をマップに反映してみました。
こんな感じにマーカーとラインが描画されます。

#今日の勉強会が早稲田大学工学部なんだけど、総合のほうに行ってしまった(笑)
簡単なプログラムの作り方はこちら

iPhoneで緯度経度情報を取得して、サーバーに送信

まずは、現在の位置をiPhone3.0の緯度経度APIを使用してサーバーに記録させます。
データーはjQueryajaxを使用して画面遷移のない送信を行います。

  //緯度経度取得
  function ShowTime() {
    navigator.geolocation.watchPosition(callback, handleError)
  }
  //緯度経度取得エラー
  function handleError(a) {
      alert("error");
  }
  var wlat;
  var wlon;
  //緯度経度取得OK
  function callback(a){
    if( wlat != a.coords.latitude || wlon != a.coords.longitude ){
      //日付作成
      Dt = new Date() ;
      now = Dt.getFullYear()+'-'+(Dt.getMonth()+1)+'-'+Dt.getDate()+' '+ Dt.getHours()+':'+Dt.getMinutes()+':'+Dt.getSeconds();
      //サーバーへ緯度経度情報を記録してもらう
      $.ajax({
        type:"GET",
        url: "./?m=iphone&mode=update&type=gps5&mdate=" + now + "&wlat=" + a.coords.latitude + "&wlon=" + a.coords.longitude,
        error:function(XHR, status, errorThrown){
          $("#su1").innerHTML = msg;
        },
        success: function(msg,status){
        $("#su1").append( msg );
          wlat = a.coords.latitude;
          wlon = a.coords.longitude;
        }
      });
    }
  }

DBに緯度経度情報を挿入

iPhoneから定期的に送られるデーターをPHP側でDBに入れる

<?php
$wlat  = mysql_real_escape_string( $_GET['wlat'] );
$wlon  = mysql_real_escape_string( $_GET['wlon'] );
$mdate = mysql_real_escape_string( $_GET['mdate'] );
$sql = " INSERT INTO tablename ( wlat , wlon , mdate )VALUES( '{$wlat}' , '{$wlon}' , '{$mdate}' );";
$result = mysql_query( $sql );
?>

これでDBに緯度経度+時間のデーターが挿入されていきます。

地図に描画する

地図に描画する場合は、DBから緯度経度のxmlファイルを以下のフォーマットで出力すると、マップに張り付けやすくなります。

<?php
            $sql = " SELECT * FROM tablename GROUP BY mdate ORDER BY mdate ";
            $result = mysql_query( $sql );
            $xml = <<<EOD
<markers>
EOD;
            $POINT = "";
            $MARKER = "";
            while( $val = mysql_fetch_assoc( $result ) ){
                $POINT .= <<<EOD
<point lat="{$val['wlat']}" lng="{$val['wlon']}" number="{$val['id']}" />
EOD;
                $MARKER .= <<<EOD
<marker lat="{$val['wlat']}" lng="{$val['wlon']}" html="{$val['mdate']}" label="{$val['mdate']}" />
EOD;
            }
            $xml .= <<<EOD
{$MARKER}
<line colour="#ff0000" width="4" html="You clicked the green polyline">
{$POINT}
</line>
</markers>
EOD;
            header ("Content-Type: text/xml; charset=UTF-8");
            echo mb_convert_encoding( $xml , "UTF-8" , "SJIS" );
            exit;
?>

上記のプログラムで以下のxmlが出力されます。

<markers>
  <marker lat="35.69890537131409" lng="139.77773331614267" html="2009-06-27 13:11:32" label="2009-06-27 13:11:32" />
  <marker lat="35.69851785804274" lng="139.7773911530283" html="2009-06-27 13:15:01" label="2009-06-27 13:15:01" />
  <marker lat="35.69857014571054" lng="139.77631381085249" html="2009-06-27 13:16:02" label="2009-06-27 13:16:02" />
  <marker lat="35.697738813654624" lng="139.77528120752888" html="2009-06-27 13:16:56" label="2009-06-27 13:16:56" />
  <marker lat="35.6985964667426" lng="139.77448428649575" html="2009-06-27 13:18:06" label="2009-06-27 13:18:06" />
  <marker lat="35.69956204332731" lng="139.77334756056973" html="2009-06-27 13:18:37" label="2009-06-27 13:18:37" />
  <line colour="#ff0000" width="4" html="You clicked the green polyline">
    <point lat="35.69890537131409" lng="139.77773331614267" number="3" />
    <point lat="35.69851785804274" lng="139.7773911530283" number="4" />
    <point lat="35.69857014571054" lng="139.77631381085249" number="5" />
    <point lat="35.697738813654624" lng="139.77528120752888" number="6" />
    <point lat="35.6985964667426" lng="139.77448428649575" number="7" />
    <point lat="35.69956204332731" lng="139.77334756056973" number="8" />
  </line>
</markers>

こちらのxmlデーターを用いてマーカーやラインを引きます。
xmlファイルからのマーカーやラインの描画については以下のページがとても参考になります。

  //初期化関数
  var side_bar_html = "";
  var gmarkers = [];
  var htmls = [];
  var i = 0;
  var map;
  function initialize() {
      var request = GXmlHttp.create();
      request.open("GET", "./?m=iphone&mode=xml&type=gps5", true);
      request.onreadystatechange = function() {
          if (request.readyState == 4) {
              var xmlDoc = GXml.parse(request.responseText);
              var markers = xmlDoc.documentElement.getElementsByTagName("marker");
              for (var i = 0; i < markers.length; i++) {
                  var lat = parseFloat(markers[i].getAttribute("lat"));
                  var lng = parseFloat(markers[i].getAttribute("lng"));
                  var point = new GLatLng(lat,lng);
                  var html = markers[i].getAttribute("html");
                  var label = markers[i].getAttribute("label");
                  var marker = createMarker(point,label,html);
                  map.addOverlay(marker);
              }
              document.getElementById("side_bar").innerHTML = side_bar_html;
              var lines = xmlDoc.documentElement.getElementsByTagName("line");
              for (var a = 0; a < lines.length; a++) {
                  var colour = lines[a].getAttribute("colour");
                  var width  = parseFloat(lines[a].getAttribute("width"));
                  var points = lines[a].getElementsByTagName("point");
                  var pts = [];
                  for (var i = 0; i < points.length; i++) {
                      pts[i] = new GLatLng(parseFloat(points[i].getAttribute("lat")),
                                           parseFloat(points[i].getAttribute("lng")));
                  }
                  map.addOverlay(new GPolyline(pts,colour,width));
              }
          }
      }
      request.send(null);
      map = new GMap2(document.getElementById("map"));
      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      map.setCenter(new GLatLng(35.698432,139.77416),18);
  }
  function createMarker(point,name,html) {
      var marker = new GMarker(point);
      GEvent.addListener(marker, "click", function() {
              marker.openInfoWindowHtml(html);
          });
      gmarkers[i] = marker;
      htmls[i] = html;
      side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '<\/a><br>';
      i++;
      return marker;
  }

すべてのソースはこちら

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"  xmlns:v="urn:schemas-microsoft-com:vml">
<head>
  <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
  <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
  <script language="javascript" type="text/javascript" src="/mylib/js/jQuery/jquery-1.2.6.min.js"></script>
  <script src="http://maps.google.com/maps?file=api&v=2.x&key=ABQIAAAA-Zv-tOh5rLvFnp7j8VjVxBR2KzofHwo0vbkJxv-SNr_iZOIu8hRgKp2_yT2GnjbgmYMNd9pYxLFhdg" type="text/javascript"></script>
  <script type="text/javascript">
  <!--
  $(function() {
    ShowTime();
    initialize();
  });
  function ShowTime() {
    //navigator.geolocation.watchPosition(callback, handleError)
  }
  function handleError(a) {
      alert("error");
  }
  var wlat;
  var wlon;
  function callback(a){
    if( wlat != a.coords.latitude || wlon != a.coords.longitude ){
      //日付作成
      Dt = new Date() ;
      now = Dt.getFullYear()+'-'+(Dt.getMonth()+1)+'-'+Dt.getDate()+' '+ Dt.getHours()+':'+Dt.getMinutes()+':'+Dt.getSeconds();
      //リクエスト
      $.ajax({
        type:"GET",
        url: "./?m=iphone&mode=update&type=gps5&mdate=" + now + "&wlat=" + a.coords.latitude + "&wlon=" + a.coords.longitude,
        error:function(XHR, status, errorThrown){
          $("#su1").innerHTML = msg;
        },
        success: function(msg,status){
        $("#su1").append( msg );
          wlat = a.coords.latitude;
          wlon = a.coords.longitude;
        }
      });
    }
  }
  //初期化関数
  var side_bar_html = "";
  var gmarkers = [];
  var htmls = [];
  var i = 0;
  var map;
  function initialize() {
      var request = GXmlHttp.create();
      request.open("GET", "./?m=iphone&mode=xml&type=gps5", true);
      request.onreadystatechange = function() {
          if (request.readyState == 4) {
              var xmlDoc = GXml.parse(request.responseText);
              var markers = xmlDoc.documentElement.getElementsByTagName("marker");
              for (var i = 0; i < markers.length; i++) {
                  var lat = parseFloat(markers[i].getAttribute("lat"));
                  var lng = parseFloat(markers[i].getAttribute("lng"));
                  var point = new GLatLng(lat,lng);
                  var html = markers[i].getAttribute("html");
                  var label = markers[i].getAttribute("label");
                  var marker = createMarker(point,label,html);
                  map.addOverlay(marker);
              }
              document.getElementById("side_bar").innerHTML = side_bar_html;
              var lines = xmlDoc.documentElement.getElementsByTagName("line");
              for (var a = 0; a < lines.length; a++) {
                  var colour = lines[a].getAttribute("colour");
                  var width  = parseFloat(lines[a].getAttribute("width"));
                  var points = lines[a].getElementsByTagName("point");
                  var pts = [];
                  for (var i = 0; i < points.length; i++) {
                      pts[i] = new GLatLng(parseFloat(points[i].getAttribute("lat")),
                                           parseFloat(points[i].getAttribute("lng")));
                  }
                  map.addOverlay(new GPolyline(pts,colour,width));
              }
          }
      }
      request.send(null);
      map = new GMap2(document.getElementById("map"));
      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      map.setCenter(new GLatLng(35.698432,139.77416),18);
  }
  function createMarker(point,name,html) {
      var marker = new GMarker(point);
      GEvent.addListener(marker, "click", function() {
              marker.openInfoWindowHtml(html);
          });
      gmarkers[i] = marker;
      htmls[i] = html;
      side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '<\/a><br>';
      i++;
      return marker;
  }
  function myclick(i) {
      gmarkers[i].openInfoWindowHtml(htmls[i]);
  }
  -->
  </script>
</head>
<bodo>
<div id="su1"></div>
<div id="map" style="width:500px;height:500px;float:left"></div>
<div id="side_bar" style="width:200px;height:500px;float:left"></div>
</body>
</html>