地理空間情報Webアプリの開発(4)

この記事は1年以上前に書かれました。
内容が古くなっている可能性がありますのでご注意下さい。


前回までに、地理空間情報を活用したモバイルWebアプリケーションのサーバー環境を構築し、サーバー側プログラムを開発しました。
そこで今回は、簡単なクライアント側プログラムを開発します。

今回開発するプログラムは、現在地を中心としたOpenStreetMap上に、近くの応急給水拠点をマーカーで表示するというものです。
HTMLファイルの完全なリストは以下の通りです。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>現在地近くの応急給水拠点</title>
  <style>
  html, body {
    padding: 0;
    margin: 0;
    height: 100%;
  }
  #mapdiv {
    height: 100%;
    width: 100%;
  }
  </style>
  <script type="text/javascript" src="openlayers/OpenLayers.js"></script>
  <script type="text/javascript" src="openlayers4jgsi/Crosshairs.js"></script>
  <script type="text/javascript" src="jquery-2.1.1.min.js"></script>
  <script type="text/javascript">

    var map;
    var markers;

    $(function(){
      map = new OpenLayers.Map('mapdiv');
      map.addLayer(new OpenLayers.Layer.OSM());
      markers = new OpenLayers.Layer.Markers('Markers');
      map.addLayer(markers);
      map.events.register( 'moveend', map, showWaterSites );

      if(navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
          function(pos) {
            var lonLat = new OpenLayers.LonLat(pos.coords.longitude, pos.coords.latitude ).transform(
              new OpenLayers.Projection('EPSG:4326'),
              map.getProjectionObject() );
            map.setCenter(lonLat, 15);
            var center = new OpenLayers.Pixel(
              map.getCurrentSize().w / 2,
              map.getCurrentSize().h / 2 );
            var cross = new OpenLayers.Control.Crosshairs( {
              imgUrl: "openlayers4jgsi/crosshairs.png",
              size: new OpenLayers.Size(32, 32),
              position: center
            });
            map.addControl( cross ); 
        });
      }
    })

    function showWaterSites() {
      var lonLat = map.getCenter().transform(
        map.getProjectionObject(),
        new OpenLayers.Projection('EPSG:4326') );
      var param = {'lon' : Math.round(lonLat.lon * 100000) / 100000,
        'lat' : Math.round(lonLat.lat * 100000) / 100000,
        'dist' : 1000};
      $.getJSON('api', param, function(data){ 
        markers.clearMarkers();
        for(i=0 ; i<data.length ; i++) {
          switch(data[i].type) {
            case '配水池' :
              color = '-blue';
              break;
            case '災害用地下給水タンク' :
              color = '-gold';
              break;
            case '緊急給水栓' :
              color = '';
              break;
          }
          var mkIcon = new OpenLayers.Icon('openlayers/img/marker' + color + '.png',
            { w: 21, h: 25 }, { x: -10.5, y: -25 } );
          var lonLat = new OpenLayers.LonLat(data[i].longitude, data[i].latitude).transform(
            new OpenLayers.Projection('EPSG:4326'),
            map.getProjectionObject() );
          var marker = new OpenLayers.Marker(lonLat, mkIcon);
          markers.addMarker(marker);
        }
      })
    }

  </script>
</head>
<body>
  <div id="mapdiv"></div>
</body>
</html>

スクリプトは、DOMの構築が完了したときに初期処理を行なう $(function(){ で始まる無名関数と、地図をドラッグしたときに実行するshowWaterSites()関数から成ります。

初期処理では、OpenLayersを使用してOpenStreetMapを表示するレイヤとマーカーを表示するレイヤを作成し、ドラッグ終了イベントのハンドラとしてshowWaterSites()関数を登録します。
さらに、Geolocation APIで取得した現在位置を中心として地図を表示し、中心に十字線(cross hair)を表示します。

showWaterSites()関数では、前回作成したNode.jsのプログラムをjQueryのgetJSON()関数で呼び出し、地図の中心座標から1,000m以内にある応急給水拠点を取得してマーカーを表示します。マーカーの色は応急給水拠点のtypeによって変えています。

ブラウザでは以下のように表示されます。

地図をドラッグすると、1,000mより離れてしまった応急給水拠点のマーカーは消え、新たに1,000m以内に見つかった応急給水拠点のマーカーが表示されます。

地理空間情報Webアプリの開発 1234