2013-07-13 31 views
6

MVC 4アプリケーションにGoogleマップを組み込んでいます。かなり簡単です。しかし、複数のマーカーを動的に追加する最良の方法に関する質問があります。私のユーザーは、コントローラーのアクションメソッドを呼び出すことで、販売するアイテムのリストを検索し、それぞれのアイテムと場所を地図上に表示したいと考えています。私が確信していないのは、マーカを地図に動的に追加する方法または最良の方法です。これはクライアントのすべてのJavaScriptです。基本的には、すべてのマーカー情報をMVCサーバーコードからクライアントに送信できるようにしたいと思いますが、そのようにするか、そうする必要があるかはわかりません。MVC 4とGoogle Maps API v3

+0

で、覚えておいてください、更新されたマップだけの事でしょうか?または、検索結果もテキストとして表示されるため、更新されますか? – mostruash

+0

検索結果も更新されます。 – Hosea146

+0

もう一度質問します。動的には、検索結果がアクションに対するAJAXリクエストと非同期に更新されることを意味しますか? – mostruash

答えて

10

にあなたの結果を結合:あなたはまだ始まったばかりしている場合プロジェクト私は現在取り組んでいます、これは私たちがそれを処理する方法です:

FooViewModelと呼ばれるメインのViewModelをしましょう。

のviewmodels:鑑み

public class FooViewModel 
{ 
    // Your search results: 
    public IEnumerable<FooWithLocationViewModel> Foos { get; set; } 

    // Properties for your search filter: 
    public decimal? MaxPrice { get; set; } 
    public CityEnum? City { get; set; } 
    ... 
} 

public class FooWithLocationViewModel 
{ 
    public string Name { get; set; } 
    public decimal Price { get; set; } 
    ... 
    public double Latidude { get; set; } 
    public double Longitude { get; set; } 
    ... 
} 

、各FooWithLocationViewModelため<div>があります。私たちは、HTML5で有効なdata-*属性を利用します:

ビュー:マップを初期化

:今

@model FooViewModel 

... 

@foreach(FooWithLocationViewModel foo in Model.Foos) 
{ 
    <div class="foo" data-latitude="@(foo.Latitude)" 
     data-longitude="@(foo.Longitude)"> 
     <span>@foo.Name</span> 
     <span>@foo.Price</span> 
     ... 
    </div> 
} 

<div id="map-canvas"></div> 

、それはJavaScriptのための時間です、私はあなたがjQueryのを使用していることを想定していますが、マーカーを追加し、markers配列に格納:このアプローチは、約、すべてが府で行われているどのような良いことだ

function initialize() { 
    var foos = $(".foo"); 
    var markers = new Array(); 
    var mapOptions = { 
     ... 
    }}; 
    var mapCanvas = document.getElementById('map-canvas'); 
    if (mapCanvas != null) { 
     map = new google.maps.Map(mapCanvas, mapOptions); 

     $.each(foos, function (key, value) { 
      markers[key] = new google.maps.Marker({ 
       map: map, 
       draggable: false, 
       animation: google.maps.Animation.DROP, 
       position: new google.maps.LatLng(
        Number($(value).attr("data-latitude")), 
        Number($(value).attr("data-longitude") 
       )); 
      }); 

      google.maps.event.addListener(markers[key], 'click', function() { 
       // If you need this... 
      }); 
     }); 
    } 
} 

Googleマップを初期化するしたがって、スクリプトをビューに埋め込む必要はありません。私たちはHTML5に優しいアプローチを採用しています。それは簡単です。

+1

これは良い答えです!おおよそ私が考えていたアイデアだが、デリバリメカニズムとしてデータを使用して自分のアイデアを改善したので、ちょうどJavaScriptのチャンクを外すつもりでしたが、これははるかに洗練されています。 – rtpHarry

+0

@rtpハリー、ありがとう。それが他人を助けることを願って – mostruash

+0

を軽度の拡張子として使用する場合は、SPANSにクラスまたは説明の識別子を渡す場合は、この情報を再利用してマーカーコンテンツを生成することができます。 JSまたは配列を埋め込むよりも小さい – stefancarlton

2

Web APIを使用して、すべて非同期に処理します。 JSONオブジェクトをクライアントに渡し、情報を解析し、古いマーカーを削除して新しいマーカーを追加します。あなたのコメントの後

EDIT:

あなたが試したし、我々はあなたがに実行している問題であなたを助けることができる仕事を得ることができなかった内容の一部を投稿した場合。 http://angularjs.org/のWeb APIを使用して、上の偉大なチュートリアル - -

http://www.asp.net/web-api GETリクエストのための角度チェックアウト(http://docs.angularjs.org/api/ngを$ HTTP。)およびUI

+0

ありがとうございます。しかし、150ポイントのポイントでは、私はこれ以上のポイントを探しています。 – Hosea146

0

は、この要件のためのアプローチを提案したい:検索ボタンクリックで

  1. - サーバに要求を送信し、それ(POSTリクエストやAJAX POST)こと。

  2. サーバー 'search()'アクションで検索を実行します。

  3. search()アクションには2つの責任があります。1.検索結果を表示します。 2.地図上に対応するマーカーを表示します。

  4. 検索結果はデー​​タと表現になりますので、 'div'/'table/tr/td'となります。この表現 は、クライアントリソースとクライアント側の処理時間を使用せずにサーバー上で生成されます。したがって、「SearchView」はデータと表現の両方を返すことができます。

  5. また、それぞれの検索結果に対応するマーカーが表示されます。これは完全にクライアントの責任です。それで最初の責任とは別にしておきましょう。 JSONシリアライズライブラリを使用すると、シリアライズされた 'マーカー' json配列を検索結果と混合するのではなく、 'SearchView'に挿入します。個々の検索結果をクリックしたときにマーカーを強調表示する必要がある場合は、各検索結果に緊密にバインドしてマーカーの詳細を表示したい場合があります。ユースケースは、最初にすべての検索結果を表示し、すべてのマーカーを表示することができます。次に、ユーザーがクリック/ホバーオーバーすると(ホバーはそこでは機能しないため、これはモバイル向けのものではないと考えてください)、個々の検索結果をマーカの位置を変更したり、選択した検索結果にラベルや情報を追加できます。

  6. また、各検索アクションでスクリプトを読み込まないように、スクリプトを別のファイルに保存することもできます。 SearchViewから、JSONのシリアル化されたマーカーと初期のマップ位置を渡すことで、 'InitializeMap()' JS関数を呼び出すことができます。

  7. JSONを使用する方が良いアプローチであり、アプリケーションをAJAXに簡単に変換できる柔軟性を提供します。また、マーカーの詳細を取得するためにJqueryを使用してHTMLを解析するよりも高速です。ここで

    function InitializeMap(initialMapPosition,markers){ 
    var latlng = new google.maps.LatLng(initialMapPosition.latitude,initialMapPosition.longitude); 
    var options = { 
        zoom: 15, 
        center: latlng, 
        mapTypeId: google.maps.MapTypeId.ROADMAP // this could be as per your requirement. 
        }; 
    
    var map = new google.maps.Map($('#map-canvas')[0], options); 
    // Place markers on map 
    for(i = 0; i < markers.length; i++) { 
        var latLng = new google.maps.LatLng(markers[i].lat, markers[i].lng); 
        var marker = new google.maps.Marker({ 
         position: latLng, 
         map: map 
        }); 
    } 
    

    }

+0

ポイント7の説明:HTMLの解析(クライアント側で行われる)は、Googleマップコントロールを計算上表示するのと比べて何もありません。それは絶対に負担ではありません。 – mostruash

+0

速度に合意しました(ただし、検索結果の数によって異なります)。しかし、将来の変更のためには、JSONオブジェクトを持つことは間違いなく良い選択です。 –

0

テーマに関する私の考えです。

最近、私はAJAX主導のWebアプリケーション(私はあなたがAJAXベースのソリューションを探しているわけではないが、私と一緒にいることは分かっていると知っています)という単一ページのプロジェクトでした。

私は、異なるエンティティの場所を示すために使用されたそのアプリケーションにGoogleマップを統合しました。

ユーザーが何かを検索したときに、ブラウザーでジオコーディングを行うのではなく、サーバーにリクエストを送信しました。サーバー上では、受信テキストはGoogle APIを使用してジオコーディングされ、結果は後で使用するためにローカルDBにキャッシュされました。同じリクエストが再び来た場合、私はDBから地理座標を取り出してそれをクライアントに送り返します。

戻り値の型はかなりシンプルでした。すなわち

public class Marker 
{ 
    public double Lat{set;get;} 
    public double Lon{set;get;} 
    public string Title{set;get;} 
} 

クライアント上で、私は単にリストを反復処理し、地図上のマーカーを描画します(マーカーをプロットすると、ジオコーディング要求するよりも高速です)。

今、同じことをポストバックで行うことができます。あなたがしなければならないのは、これはあなたがして繰り返すことができ、すべてのマーカーのリストにVARマーカーを記入します

var markers = @Html.Action("GetMarkers") 

あなたの初期化関数の呼び出しで、あります。

は、ユーザーが検索ボタンを押した後GetMarkersの戻り値の型が

public JsonResult GetMarkers() 
{ 
    ... 
    // returns List<Markers> 
} 
関連する問題