ピースペース

ASP.NET MVCでGoogle Maps

with one comment

先月のMVC講習会で、ActionはViewResultの他にもいろいろな形な応答ができると聞いて、
どうゆうときにそれが必要になるのか?とぼんやり考えていたら、
ある施設リストの検索を地図で表示するという仕事の依頼があって、
ちょうど程よく、JsonResultを試すことができた^^v

mapview

Google Maps APIは、APIというかJavaScriptのライブラリで、それを使えば簡単にページ上に地図を表示できる。
必要なのはGoogle Maps APIの理解であり、それがあれば十分で、
地図を表示するためのほぼ全ての処理はクライアント上のScriptが行うので、
サイトがASP.NET MVCであるという特別な配慮はほぼない。

理解する必要があるのは、
入力された検索条件をサーバーに送り、サーバーが行った抽出結果をどうやってScriptに渡すのか?だけ
ajaxで住所リストを要求して、検索結果をjsonで応答して、その応答をMapsなScriptに食わせる。

要求を送る箇所

いつもとおりAjax.BeginFormヘルパで記述する

@{
    AjaxOptions ajaxOptions = new AjaxOptions
    {
        OnSuccess = "OnListLoaded",
        OnFailure = "OnFailure"       
    };   
}

@using (Ajax.BeginForm("Search", ajaxOptions))
{

検索条件を受け取り結果を応答するAction

ここが課題のJsonな応答をつくるところだが、
ただ、結果のリストをコントローラーのJsonメソッドに食わせるだけ(簡単!)だ。
Jsonメソッドはなんでも食べてJsonに化けさせてくれるらしい。
内容によっては失敗する場合もあるかもしれない。が、そこはまだよくわからない;;

[HttpPost]
public ActionResult Search(string submitType, MapCondition condition)
{
    if (submitType == "clear")
        return new EmptyResult();

    IEnumerable<MappedInst> selected = repository.GetByCondition(condition);
    List<MapInstViewModel> vmlist = new List<MapInstViewModel>();
    foreach (var inst in selected)
    {
        vmlist.Add(new MapInstViewModel(inst));
    }
    return Json(vmlist);
}

応答を処理して地図にマーカーを配置するScript

function OnListLoaded(data) {
        mapMarker(data);
}

function mapMarker(data) {
    var op = {
        zoom: 14,
        center: mapCenter,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), op);

    var bounds = new google.maps.LatLngBounds();
    var geocoder = new google.maps.Geocoder();

    var i = data.length;
    while (i– > 0) {
        var inst = data[i];
        geocoder.geocode({ address: inst.ADDRESS },
            function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    for (var g in results) {
                        if (results[g].geometry) {
                            var latlng = results[g].geometry.location;
                            bounds.extend(latlng);
                            var marker = new google.maps.Marker({
                                position: latlng,
                                map: map,
                                title: inst.INST_NAME
                            });
                            attachMessage(marker, inst);
                            map.fitBounds(bounds);
                        }
                    }
                }
            }
        );
    }
}

Script側の要点

MVCのActionのJsonな応答(data)は、既に配列になっていてそのまま処理できる。
らぶり~~ てか、なんて柔軟なんだ! →JavaScript

応答には住所しかないので、geocoder.geocodeでgoogleに座標変換要求を行う。
のコールバックでMarkerを生成する。
生成したMarkerがクリックされたときに情報ウィンドウを表示するイベントハンドラを登録する。
map.fitBoundsで配置したMarkerを程よく表示するように地図の縮尺を調整する。

ちなみに、new google.maps.Markerがコールバックの中にいるので、
map.fitBoundsもやはりその中にいる必要がある。
を外に出すと、Markerがいない状態でfitBoundsすることになる。←に、はまった;;
と、まだまだ怖い→JavaScript。が、その威力を受け入れざるを得ない。
を、素直に理解できる→MVC
講習会でmiso_soupさんが言っておられたMVCの特徴を実感できた気がする。

Written by nasu38yen

2012年9月5日 @ 9:26 AM

カテゴリー: .NET

Tagged with

コメント / トラックバック1件

Subscribe to comments with RSS.

  1. […] ASP.NET MVCでGoogle Maps « ピースペース. 共有:TwitterFacebookいいね:いいね最初の「いいね」をつけてみませんか。 […]


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。