29

Me gusta crear un mapa con Google Maps que pueda manejar grandes cantidades de marcadores (más de 10.000). Para no ralentizar el mapa, he creado un archivo XML que solo muestra los marcadores que están dentro de la ventana gráfica actual.Google Maps V3: Mostrar solo marcadores en la ventana gráfica - Borrar el número de marcadores

En primer lugar, yo uso inicializar() para configurar las opciones del mapa:

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); 
    }); 
} 

Cuando se termina el evento 'tilesloaded', utilizo loadMapFromCurrentBounds(), esta función obtendrán los límites actuales y envía una solicitud al archivo XML para mostrar los marcadores que están dentro de la ventana gráfica actual:

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); 
     } 
    }) 
} 

Esto es trabajo grande, sin embargo, el código actual no descarga de marcadores que no están en la ventana gráfica de más. Además de eso, vuelve a cargar marcadores que ya están cargados, lo que ralentiza el mapa realmente rápido al mover el mapa una vista veces en la misma área.

Así que cuando la ventana gráfica cambia, me gusta borrar todo el mapa primero antes de cargar nuevos marcadores. ¿Cuál es la mejor manera de hacer esto?

+0

Hey @ Jeff, thx por las ediciones! Solo quería que supieras que puedes agregar realce de sintaxis a * todas * las respuestas a una pregunta simplemente agregando la etiqueta 'JavaScript', usando el enlace" editar etiquetas "que aparece a la derecha de las etiquetas. ¡Buena suerte! :) – jmort253

+0

El [Marcador Clusterer] (https://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries) podría ser útil cuando se trata de tantos marcadores. – Blazemonger

+1

puede guardar unas líneas de código arriba haciendo 'map.getBounds(). ToUrlValue(). Split (',')' y tiene una buena matriz para sus esquinas. – tim

Respuesta

15

es necesario agregar otro detector de eventos para el mapa:

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

Ver here para más información sobre la eliminación de todas las marcas de un mapa de Google - por desgracia yo no creo que se puede hacer con una sola llamada. Por lo que tendrá que escribir los removeMarkers o algo similar que tendrán que recorrer todos los marcadores en el mapa eliminación de ellos de forma individual, así:

markersArray[i].setMap(null); 

No sé si es más rápido para comprobar si el marcador es en el visor antes de retirar mediante el uso de:

map.getBounds(); 

Read more about Google Map API v3 events

+0

¡Gracias por su respuesta! ¿Por qué tengo que usar 'bounds_changed'? El oyente de eventos que estoy usando ahora ('Tilesloaded') parece hacer lo mismo, cada vez que la ventana gráfica cambia las funciones se llama loadMapFromCurrentBounds(). Probé MarkersArray [i] .setMap (null); pero no funciona. Además de eso, me gustan las soluciones en las que sólo borrar los marcadores que no están en el área de visualización más ... voy a tratar de subir un ejemplo más adelante esta noche! – Thijs

+2

también, tilesloaded no puede disparar si se está moviendo el mapa sólo un poco, es decir, si su movimiento no causa una nueva ficha para cargar en el visor – tim

6

Es posible que desee echa un vistazo a este hilo. Daniel respondió esto bastante bien.

What's the most efficient way to create routes on google maps from gps files?

Además, bounds_changed es la primera oportunidad para llamar a su función. tilesloaded, se llamará constantemente. La ventana gráfica puede contener más de un mosaico para llenar la ventana gráfica.

Alternativamente, también puede hacer un setVisible (falso).

Para quitar el marcador, es posible que deba eliminar los oyentes.

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

Este artículo pasa a través de él bastante bien: Dynamically loading thousands of markers in Google Maps

  • cargar dinámicamente los marcadores hasta llegar a un umbral
  • mantener una tabla hash de los marcadores que ya se han añadido
  • después se ha alcanzado el umbral, elimine los marcadores que no están actualmente dentro de la ventana gráfica
  • eliminar todos los marcadores del mapa cuando el usuario se ha disparado, y no cargue ningún marcadores hasta que el usuario se acerca de nuevo a un nivel razonable
+1

enlace ya no funciona. –

+3

tratar este enlace http://xyzzyb.tumblr.com/post/10317033064/dynamically-loading-thousands-of-markers-in-google-maps – webjunkie

1

Su función original parece como una gran cantidad de código. Me gustaría hacer algo como esto:

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

Es posible que desee echa un vistazo a esta documentación de Google. En él se explica lo que necesita:

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)). 
5

Debido a la siguiente explicación usando 'tilesloaded' o 'bounds_changed' sería muy equivocado y provocar disparos continuos involuntarios. En su lugar, desearía utilizar el evento 'inactivo' que se activará una vez que el usuario haya detenido el desplazamiento/acercamiento.

google.maps.event.addListener (mapa, 'inactivo', loadMapFromCurrentBounds);

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

Cuestiones relacionadas