Google MapsでJavaScriptのお勉強(PostGISと.NETもあるよ) その4

JavaScriptAjaxする前に、サーバ側の応答処理を書いておくのを忘れていました(・∀・)
当初はJSON形式のデータを返そうかと思っていましたけど、とりあえず手軽にWebService(asmx)で実装してみたり。


昨日作ったサービス層を呼び出すだけなので、こんなカンジの実装になります。
SpotInfoクラスはId、Name、Lon、Lat等のプロパティを持つDTOで、GetSpotInfoList()の最初の100はLIMIT指定です。

[WebMethod]
public SpotInfo[] GetSpots(double minX, double minY, double maxX, double maxY)
{
    List<SpotInfo> list = MapService.GetSpotInfoList( 100, minX, minY, maxX, maxY );

    return( list.ToArray() );
}

で、これを実行すると、こんなXMLが取得できるわけです。

<?xml version="1.0" encoding="utf-8" ?> 
<ArrayOfSpotInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <SpotInfo>
    <Id>6</Id> 
    <Name>朗月堂</Name> 
    <Lon>138.551497222222</Lon> 
    <Lat>35.6533722222222</Lat> 
  </SpotInfo>
  <SpotInfo>
    <Id>1</Id>
    <Name>甲府駅</Name>
    <Lon>138.5690139</Lon>
    <Lat>35.6670556</Lat>
  </SpotInfo>
</ArrayOfSpotInfo>

これをAjaxで取得して、マーカーを更新する処理をJavaScriptで書いていきます。


まずはGMapコントロールで移動、リサイズをした時のイベントを登録しておきます。
#gmapはGMapのインスタンスです

GEvent.addListener( gmap, 'moveend', function()
{
    onMapUpdate();
});
GEvent.addListener( gmap, 'zoom', function()
{
    onMapUpdate();
});

で、イベントハンドラではこんなカンジで、GMapの領域をパラメータにしてWebServiceを呼び出します。

function onMapUpdate()
{
    var ne = gmap.getBounds().getNorthEast();
    var sw = gmap.getBounds().getSouthWest();

    new Ajax.Request( "WebServices/MapWebService.asmx/GetSpots",
    {
        method: 'post',
        parameters: "minX=" + sw.lng() + "&minY=" + sw.lat() +
                    "&maxX=" + ne.lng() + "&maxY=" + ne.lat(),
        asynchronous: true,
        onComplete : function( request )
        {
            onGetSpotsCallback( request.responseText );
        }
    });
}

コールバックハンドラはこんな感じにしました。

function onGetSpotsCallback( res )
{
    removeAllMarkers();

    var dom = GXml.parse( res );
    var spots = $A( dom.getElementsByTagName('SpotInfo') );

    spots.each( function( spot )
    {
        var obj = eval( "(" + xml2json( spot, "  " ) + ")" ).SpotInfo;
        
        var point = new GLatLng( parseFloat( obj.Lat ), parseFloat( obj.Lon ) );
        obj.marker = new GMarker( point );

        makers.push( obj );

        gmap.addOverlay( obj.marker );
    });
}

まず、省略している点を補足しておくと、makersは現在のマーカ一覧を管理しておくためのArrayです。
removeAllMarkers()はmakersに入っている情報を元にGMap.removeOverlay()して、移動前のマーカー情報をクリアする処理になります。


取得したXML複数件のデータなので、Arrayにして1件づつマーカー情報を作成していきます。


で、DOM操作で値を取得してオブジェクトを構築するのも面倒なので、一端JSON形式に変換してオブジェクトを構築するようにしました(°▽°)
XML-JSON形式の変換にはxml2json.jsを利用しています。


最初からサーバ側でJSON形式のデータを生成すればXML変換はいらないわけですが。
まあ勉強ですし、XML(WebService)もそれはそれで使う用途もあると言うことで、そこは深く考えないことにします(´ω`)
#後でJSON形式でデータを返すジェネリックハンドラを作っても良いし


で、これでデータベースと連携するGoogle Mapsの基本動作の検証はできました(`・ω・´)


Google Mapsの使い方については、JavaScriptについては書いてあっても、位置情報データベースとの連携まで書いてあるサンプルとかって少ないですよね。
まあ、PostGISprototype.jsを使用すれば、位置情報の検索やマーカーの更新も簡単に出来ることが分かったと言うことで。
サーバ側ロジックについては、.NETだろうと他の言語だろうとたいした差異は無いですしね。


今後はコレに機能を追加して遊んでいきたいと思います(・∀・)