web-dev-qa-db-ja.com

Google Maps V3:ビューポートにマーカーのみを表示-マーカーの問題をクリア

大量のマーカー(1万を超える)を処理できるGoogleマップで地図を作成したい。マップを遅くしないように、現在のビューポート内にあるマーカーのみを出力するXMLファイルを作成しました。

まず、initialize()を使用してマップオプションを設定します。

function initialize() {
    var myLatlng = new google.maps.LatLng(51.25503952021694,3.27392578125);
    var myOptions = {
        zoom: 8,
        center: myLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

    google.maps.event.addListener(map, 'tilesloaded', function () {
    loadMapFromCurrentBounds(map);
    }); 
}

イベント 'tilesloaded'が終了したら、loadMapFromCurrentBounds()を使用します。この関数は現在の境界を取得し、XMLファイルにリクエストを送信して、現在のビューポート内にあるマーカーを表示します。

function loadMapFromCurrentBounds(map) {

    // First, determine the map bounds
    var bounds = map.getBounds();

    // Then the points
    var swPoint = bounds.getSouthWest();
    var nePoint = bounds.getNorthEast();

    // Now, each individual coordinate
    var swLat = swPoint.lat();
    var swLng = swPoint.lng();
    var neLat = nePoint.lat();
    var neLng = nePoint.lng();

    downloadUrl("mapsxml.php?swLat="+swLat+"&swLng="+swLng+"&neLat="+neLat+"&neLng="+neLng+"", function(data) {
        var xml = parseXml(data);
        var markers = xml.documentElement.getElementsByTagName("marker");
        var infoWindow = new google.maps.InfoWindow; 

        for (var i = 0; i < markers.length; i++) {
            var address = markers[i].getAttribute("address");
            var type = markers[i].getAttribute("type");
            var name = markers[i].getAttribute("name");

            var point = new google.maps.LatLng( 
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng"))
            );

            var html = "<b>" + name + "</b> <br/>" + address;
            var icon = customIcons[type] || {};

            var marker = new google.maps.Marker({
            map: map,
            position: point,
            icon: icon.icon,
            shadow: icon.shadow});

            bindInfoWindow(marker, map, infoWindow, html);
        }
    })
}

これはうまく機能していますが、現在のコードは、ビューポートにないマーカーをオフロードしません。その上、すでにロードされているマーカーを再度ロードします。これにより、マップを同じエリアでビュー時間移動すると、マップの速度が非常に遅くなります。

したがって、ビューポートが変更されたときは、新しいマーカーをロードする前に、まずマップ全体をクリアしたいと思います。これを行う最良の方法は何ですか?

29
Thijs

別のイベントリスナーをマップに追加する必要があります。

google.maps.event.addListener(map,'bounds_changed', removeMarkers);

Googleマップからすべてのマーカーを削除する方法の詳細については こちら を参照してください-残念ながら、1回の呼び出しでそれを実行できるとは思いません。そのため、マップ上のすべてのマーカーを繰り返し処理して、マーカーを個別に削除する必要のある、removeMarkersなどを作成する必要があります。

 markersArray[i].setMap(null);

以下を使用して削除する前に、マーカーがビューポートにあるかどうかを確認する方が速いかどうかわかりません。

 map.getBounds();

Google Map API v3イベントの詳細を読む

15
Paul Owens

このスレッドをチェックしてみてください。ダニエルはこれをかなりうまく答えました。

gpsファイルからGoogleマップにルートを作成する最も効率的な方法は何ですか?

また、bounds_changedは、関数を呼び出す最初の機会です。 tilesloadedは、常に呼び出されます。ビューポートには、ビューポートを埋めるために複数のタイルを含めることができます。

または、setVisible(false)を実行することもできます。

マーカーを削除するには、リスナーを削除する必要がある場合があります。

google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
markers.remove(marker);
delete marker;
6
CrazyEnigma

次の説明のため、 'tilesloaded'または 'bounds_changed'を使用すると、非常に間違って連続したファイアが発生します。代わりに、ユーザーがパン/ズームを停止したときに発生する「アイドル」イベントを使用します。

google.maps.event.addListener(map、 'idle'、loadMapFromCurrentBounds);

https://developers.google.com/maps/articles/toomanymarkers#viewportmarkermanagement

5

この記事はかなりうまくいきます: Googleマップに何千ものマーカーを動的にロードする

  • しきい値に達するまで動的にマーカーをロードします
  • 追加済みのマーカーのハッシュテーブルを保持する
  • しきい値に達した後、現在ビューポート内にないマーカーを削除します
  • ユーザーがズームアウトしたときにマップからすべてのマーカーを削除し、ユーザーが適切なレベルにズームバックするまでマーカーを読み込まない
4
webjunkie

あなたの元の関数はたくさんのコードのようです。私はこのようなことをします:

if( map.getBounds().contains(markers[i].getPosition()) ) {
   myMarkerDisplayFunction(markers[i]);
}
1
tim

Google からこのドキュメントをチェックしてください。それはあなたが必要とするものを説明します:

With the new list of markers you can remove the current markers 
(marker.setMap(null)) that are on the map and 
add the new ones (marker.setMap(map)).
0
hellomello