大量のマーカー(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);
}
})
}
これはうまく機能していますが、現在のコードは、ビューポートにないマーカーをオフロードしません。その上、すでにロードされているマーカーを再度ロードします。これにより、マップを同じエリアでビュー時間移動すると、マップの速度が非常に遅くなります。
したがって、ビューポートが変更されたときは、新しいマーカーをロードする前に、まずマップ全体をクリアしたいと思います。これを行う最良の方法は何ですか?
別のイベントリスナーをマップに追加する必要があります。
google.maps.event.addListener(map,'bounds_changed', removeMarkers);
Googleマップからすべてのマーカーを削除する方法の詳細については こちら を参照してください-残念ながら、1回の呼び出しでそれを実行できるとは思いません。そのため、マップ上のすべてのマーカーを繰り返し処理して、マーカーを個別に削除する必要のある、removeMarkersなどを作成する必要があります。
markersArray[i].setMap(null);
以下を使用して削除する前に、マーカーがビューポートにあるかどうかを確認する方が速いかどうかわかりません。
map.getBounds();
このスレッドをチェックしてみてください。ダニエルはこれをかなりうまく答えました。
gpsファイルからGoogleマップにルートを作成する最も効率的な方法は何ですか?
また、bounds_changedは、関数を呼び出す最初の機会です。 tilesloadedは、常に呼び出されます。ビューポートには、ビューポートを埋めるために複数のタイルを含めることができます。
または、setVisible(false)を実行することもできます。
マーカーを削除するには、リスナーを削除する必要がある場合があります。
google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
markers.remove(marker);
delete marker;
次の説明のため、 'tilesloaded'または 'bounds_changed'を使用すると、非常に間違って連続したファイアが発生します。代わりに、ユーザーがパン/ズームを停止したときに発生する「アイドル」イベントを使用します。
google.maps.event.addListener(map、 'idle'、loadMapFromCurrentBounds);
https://developers.google.com/maps/articles/toomanymarkers#viewportmarkermanagement
この記事はかなりうまくいきます: Googleマップに何千ものマーカーを動的にロードする
- しきい値に達するまで動的にマーカーをロードします
- 追加済みのマーカーのハッシュテーブルを保持する
- しきい値に達した後、現在ビューポート内にないマーカーを削除します
- ユーザーがズームアウトしたときにマップからすべてのマーカーを削除し、ユーザーが適切なレベルにズームバックするまでマーカーを読み込まない
あなたの元の関数はたくさんのコードのようです。私はこのようなことをします:
if( map.getBounds().contains(markers[i].getPosition()) ) {
myMarkerDisplayFunction(markers[i]);
}
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)).