I marcatori di Google allo stesso indirizzo non mostrano tutti i marcatori


16

Ho lavorato su questa mappa - http://www.mediwales.com/mapping/test/

Sta complottando le aziende e le raggruppa bene, ma si è verificato un problema con le aziende nello stesso edificio con lo stesso indirizzo. Mostra solo un'azienda anziché tutte.

Come posso ottenere per visualizzare tutte le aziende allo stesso indirizzo?

I marcatori sono geocodificati per nome / numero dell'edificio, via, città, codice postale. Immagino che i marcatori siano lì come un edificio che ha 3 compagnie che mostrano un 3 nel cluster. Tuttavia, quando fai clic su di esso, mostra solo una società.

AGGIORNARE:

Sono riuscito a farli compensare, ma compensa tutti i marcatori quando voglio solo compensare se ci sono più di un marcatore lo stesso. (Grazie alla risposta di Casey).

   <script type="text/javascript">
    //<![CDATA[

    var customIcons = {
      restaurant: {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
      },
      bar: {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
      }
    };

    function load() {
      var cluster = [];
      var map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(53.4788, -3.9551),
        zoom: 6,
        mapTypeId: 'roadmap'
      });
var infowindow = new google.maps.InfoWindow();
var min = .999999;
var max = 1.000001;

      // Change this depending on the name of your PHP file
      downloadUrl("<?php bloginfo('stylesheet_directory'); ?>/phpsqlajax_genxml.php ", function(data) {
        var xml = data.responseXML;
        var markers = xml.documentElement.getElementsByTagName("marker");
        for (var i = 0; i < markers.length; i++) {
          var name = markers[i].getAttribute("name");
          var address = markers[i].getAttribute("address");
          var type = markers[i].getAttribute("type");



          var offsetLat = markers[i].getAttribute("lat") * (Math.random() * (max - min) + min);
          var offsetLng = markers[i].getAttribute("lng") * (Math.random() * (max - min) + min);



          var point = new google.maps.LatLng(offsetLat, offsetLng);
          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
          });
          google.maps.event.addListener(marker, 'click', (function(marker, i) {
                        return function() {
                            infowindow.setContent(markers[i].getAttribute("name"));
                            infowindow.open(map, marker);
                        }
                    })(marker, i));
          cluster.push(marker);
        }
        var mc = new MarkerClusterer(map,cluster);
      });
    }

    function bindInfoWindow(marker, map, infoWindow, html) {
      google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
      });
    }

    function downloadUrl(url, callback) {
      var request = window.ActiveXObject ?
          new ActiveXObject('Microsoft.XMLHTTP') :
          new XMLHttpRequest;

      request.onreadystatechange = function() {
        if (request.readyState == 4) {
          request.onreadystatechange = doNothing;
          callback(request, request.status);
        }
      };

      request.open('GET', url, true);
      request.send(null);
    }

    function doNothing() {}

    //]]>
  </script>

   <script type="text/javascript">
    //<![CDATA[

    var customIcons = {
      restaurant: {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
      },
      bar: {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
      }
    };

    function load() {
      var cluster = [];
      var map = new google.maps.Map(document.getElementById("map"), {
        center: new google.maps.LatLng(53.4788, -3.9551),
        zoom: 6,
        mapTypeId: 'roadmap'
      });
var infowindow = new google.maps.InfoWindow();

      // Change this depending on the name of your PHP file
      downloadUrl("<?php bloginfo('stylesheet_directory'); ?>/phpsqlajax_genxml.php ", function(data) {
        var xml = data.responseXML;
        var markers = xml.documentElement.getElementsByTagName("marker");
        for (var i = 0; i < markers.length; i++) {
          var name = markers[i].getAttribute("name");
          var address = markers[i].getAttribute("address");
          var type = markers[i].getAttribute("type");
          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
          });
          google.maps.event.addListener(marker, 'click', (function(marker, i) {
                        return function() {
                            infowindow.setContent(markers[i].getAttribute("name"));
                            infowindow.open(map, marker);
                        }
                    })(marker, i));
          cluster.push(marker);
        }
        var mc = new MarkerClusterer(map,cluster);
      });
    }

    function bindInfoWindow(marker, map, infoWindow, html) {
      google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
      });
    }

    function downloadUrl(url, callback) {
      var request = window.ActiveXObject ?
          new ActiveXObject('Microsoft.XMLHTTP') :
          new XMLHttpRequest;

      request.onreadystatechange = function() {
        if (request.readyState == 4) {
          request.onreadystatechange = doNothing;
          callback(request, request.status);
        }
      };

      request.open('GET', url, true);
      request.send(null);
    }

    function doNothing() {}

    //]]>
  </script>

Risposte:


15

Il clusterer viene visualizzato correttamente. Tutti i marker vengono tracciati. Il problema è che puoi solo fare clic sul marcatore più in alto, facendo sembrare che ci sia un solo marcatore.

Per vedere il contenuto dei marker coincidenti, dovrai passare il contenuto della finestra dei marker sottostanti al maggior numero di marker.

Per fare questo, prima di tutto, tieni traccia di ogni marcatore. Stai usando MarkerClusterer, quindi l'istanza markerClusterer conterrà ogni marker. Al ritorno di ogni risultato di geocodice, confronta il latlng di quella richiesta con tutti i marker che sono già stati tracciati. Puoi confrontare le posizioni usando il metodo equals dell'oggetto latlng .

Se il nuovo marker corrisponde alla posizione di un marker esistente, prendi il contenuto della finestra dal primo marker e aggiungilo al contenuto della finestra del nuovo marker. In questo modo, quando fai clic sul marcatore più in alto (la seconda società), mostrerà le informazioni di entrambe le società. Se ci sono più di due società, dovrai prendere i contenuti della finestra per tutti i marker corrispondenti. Questo metodo consentirà inoltre al clusterer di marker di visualizzare ancora il numero corretto di marker.

Ecco un esempio funzionante e il codice javascript. Il primo e il secondo indirizzo sono gli stessi. Quando si fa clic sull'indicatore per 2, verrà visualizzato "2 & 1".

<script type="text/javascript"> 
var map;

//marker clusterer
var mc;
var mcOptions = {gridSize: 20, maxZoom: 17};

//global infowindow
var infowindow = new google.maps.InfoWindow();

//geocoder
var geocoder = new google.maps.Geocoder(); 

var address = new Array("1000 Market St, Philadelphia, PA","1000 Market St, Philadelphia, PA","1002 Market St, Philadelphia, PA","1004 Market St, Philadelphia, PA");
var content = new Array("1","2","3","4");

function createMarker(latlng,text) {

    var marker = new google.maps.Marker({
        position: latlng
    });

    ///get array of markers currently in cluster
    var allMarkers = mc.getMarkers();

    //check to see if any of the existing markers match the latlng of the new marker
    if (allMarkers.length != 0) {
        for (i=0; i < allMarkers.length; i++) {
            var currentMarker = allMarkers[i];
            var pos = currentMarker.getPosition();

            if (latlng.equals(pos)) {
                text = text + " & " + content[i];
            }

        }
    }

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.close();
        infowindow.setContent(text);
        infowindow.open(map,marker);
    });

    return marker;
}

function geocodeAddress(address,i) {

    geocoder.geocode( {'address': address}, function(results, status) {

        if (status == google.maps.GeocoderStatus.OK) {

            var marker = createMarker(results[0].geometry.location,content[i]);
            mc.addMarker(marker);

        } else { 
            alert("Geocode was not successful for the following reason: " + status); 
        } 
    });
}

function initialize(){

    var options = { 
        zoom: 13, 
        center: new google.maps.LatLng(39.96225,-75.13222), 
        mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 

    map = new google.maps.Map(document.getElementById('map'), options); 

    //marker cluster
    mc = new MarkerClusterer(map, [], mcOptions);

    for (i=0; i<address.length; i++) { 
        geocodeAddress(address[i],i);
    }

}       
</script> 

EDIT: risposta al commento

In alternativa, è possibile spostare i marker coincidenti applicando un piccolo (numero casuale compreso tra .999999 e 1.000001, ad esempio) alla posizione di ciascun marker coincidente. Ecco un esempio Questo utilizza gli stessi dati del primo esempio, tranne per il fatto che, anziché i marker 1 e 2 posizionati uno sopra l'altro e condividendo una finestra, il marker 2 viene spostato dal marker 1. Nota che i risultati del tuo geocodice saranno un un po 'meno preciso. Codice pertinente di seguito:

//min and max limits for multiplier, for random numbers
//keep the range pretty small, so markers are kept close by
var min = .999999;
var max = 1.000001;

    function createMarker(latlng,text) {

        ///get array of markers currently in cluster
        var allMarkers = mc.getMarkers();

        //final position for marker, could be updated if another marker already exists in same position
        var finalLatLng = latlng;

        //check to see if any of the existing markers match the latlng of the new marker
        if (allMarkers.length != 0) {
            for (i=0; i < allMarkers.length; i++) {
                var existingMarker = allMarkers[i];
                var pos = existingMarker.getPosition();

                //if a marker already exists in the same position as this marker
                if (latlng.equals(pos)) {

                    //update the position of the coincident marker by applying a small multipler to its coordinates
                    var newLat = latlng.lat() * (Math.random() * (max - min) + min);
                    var newLng = latlng.lng() * (Math.random() * (max - min) + min);

                    finalLatLng = new google.maps.LatLng(newLat,newLng);

                }                   
            }
        }

        var marker = new google.maps.Marker({
            position: finalLatLng
        });     

        google.maps.event.addListener(marker, 'click', function() {
            infowindow.close();
            infowindow.setContent(text);
            infowindow.open(map,marker);
        });

        return marker;
    }

Grazie per la risposta. Sono appena tornato a questo progetto! Giusto, sarebbe possibile compensare un po 'i marker? Il tipo di società coinvolte sosterrebbe chi sarebbe stato in cima alla finestra informativa altrimenti (meschino lo so!).
Rob,

Bel lavoro @ Casey. Sembra fantastico!
RyanKDalton-OffTheGridMaps,

@Casey Grazie per la risposta, come ho potuto inserirlo nel mio codice? Faccio fatica a rielaborare il codice in questo modo! Ecco la mia fonte - view-source: mediwales.com/mapping/members
Rob

@Rob Usa la mia pagina di esempio come guida. Una grande differenza tra il nostro codice è che ho estratto il mio codice di marcatore di creazione dal mio codice di indirizzo geocode e lo ho inserito nella sua funzione chiamata createMarker. Dovrai farlo anche per far funzionare la tecnica del nudge.
Casey,

@Casey Ho avuto un paio di tentativi e non riesco a farlo funzionare ... Non voglio che suoni come se stessi solo facendo in modo che tu lo faccia, ma ho provato per l'ultimo giorno.
Rob

3

Ho avuto lo stesso problema con diversi marcatori allo stesso lat / long esatto per un'app del territorio di vendita. Questo era uno scenario comune nella mia app con più clienti allo stesso indirizzo, ad esempio clienti nello stesso grattacielo e quindi allo stesso indirizzo fisico.

Ho trovato una risposta alternativa con forse una migliore esperienza utente (UX) per i marcatori sovrapposti. Grazie a George MacKerron per la creazione della OverlappingMarkerSpiderfier biblioteca. Questa libreria JavaScript per Google Maps v3 sostituisce il comportamento di clic predefinito per i marcatori sovrapposti. La libreria consente di configurare il raggio di offset per la sovrapposizione (il valore predefinito è 20 pixel).

Schermate di esempio da http://jawj.github.io/OverlappingMarkerSpiderfier/demo.html :

Schermata di marcatori sovrapposti prima del clic Schermata di clic su uno qualsiasi degli indicatori sovrapposti Schermata di selezione di un marker nella rete "spidered" di marker sovrapposti


0

Propongo di modificare la funzione sopra come segue perché i risultati ottenuti mi sembrano migliori.

function adjustMarkerPlace(latlng) {
  ///get array of markers currently in cluster 
  //final position for marker, could be updated if another marker already exists in same position
  var finalLatLng = latlng;

  //check to see if any of the existing markers match the latlng of the new marker
  if (markers.length !== 0) {
      for (let i=0; i < markers.length; i++) {
          var existingMarker = markers[i];
          var pos = existingMarker.getPosition();

          //check if a marker already exists in the same position as this marker
          if (latlng.equals(pos)) {

              //update the position of the coincident marker by applying a small multipler to its coordinates
              var newLat = latlng.lat() + (Math.random() / 10000);
              var newLng = latlng.lng() + (Math.random() / 10000);

              finalLatLng = new google.maps.LatLng(newLat,newLng);

          }
      }
  }

  return finalLatLng;

}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.