Aynı adresteki Google işaretçileri tüm işaretçileri göstermiyor


16

Bu harita üzerinde çalışıyorum - http://www.mediwales.com/mapping/test/

Şirketleri iyi planlıyor ve onları kümelendiriyor, ancak aynı binada aynı adrese sahip şirketler ile ilgili bir sorun ortaya çıktı. Hepsinden ziyade sadece bir şirket gösteriyor.

Tüm şirketleri aynı adreste görüntülemeyi nasıl sağlayabilirim?

İşaretçiler bina adı / numarası, sokak, şehir, posta kodu ile coğrafi olarak kodlanır. Sanırım işaretçiler 3 şirket kümede 3 gösterir bir bina olarak vardır. Buna tıkladığınızda, yalnızca bir şirket gösterilir.

GÜNCELLEME:

Onları dengelemeyi başardım, ancak yalnızca birden fazla işaretleyici varsa ofset olmasını istediğimde tüm işaretçileri dengeliyor. (Casey'nin cevabı sayesinde).

   <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>

Yanıtlar:


15

Küme düzgün görüntüleniyor. Tüm işaretçiler çizilir. Sorun sadece en üstteki işaretleyiciyi tıklatarak yalnızca bir işaretleyici varmış gibi görünmesini sağlamanızdır.

Çakışan işaretçilerin içeriğini görmek için, temel işaretleyicilerin bilgi panosu içeriğini en üstteki işaretleyiciye geçirmeniz gerekir.

Bunu yapmak için, ilk önce, her bir işaretçiyi takip edin. MarkerClusterer kullanıyorsunuz, böylece markerClusterer örneği her bir işaretçiyi tutacaktır. Her bir coğrafi kod sonucu geri döndüğünde, bu isteğin latlunu önceden çizilmiş olan tüm işaretçilerle karşılaştırın. Latlng nesnesinin eşittir yöntemini kullanarak konumları karşılaştırabilirsiniz .

Yeni işaretçi mevcut bir işaretleyicinin konumuyla eşleşiyorsa, ilk işaretleyiciden bilgi alan içeriğini alın ve yeni işaretleyicinin bilgi alan içeriğine ekleyin. Bu şekilde, en üstteki işaretleyiciye (ikinci şirket) tıkladığınızda, her iki şirketten de bilgi gösterilecektir. İkiden fazla şirket varsa, eşleşen tüm işaretçiler için bilgi alanı içeriğini almanız gerekir. Bu yöntem ayrıca işaretçi kümesinin hala doğru sayıda işaretçi görüntülemesine izin verir.

İşte çalışan bir örnek ve javascript kodu. Birinci ve ikinci adresler aynı. İşaretçiyi 2 için tıklattığınızda "2 & 1" gösterilir.

<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: Yorumu yanıtla

Alternatif olarak, her bir çakışan işaretçinin konumuna küçük (örneğin .999999 ve 1.000001 arasında) bir çarpan uygulayarak çakışan belirteçleri sürükleyebilirsiniz. İşte bir örnek. Bu, ilk örnekle aynı verileri kullanıyor, ancak 1 ve 2 işaretlerinin üst üste yerleştirilmesi ve bir bilgi penceresini paylaşması yerine, işaretçi 2 işaretçi 1'den ofsettir. biraz daha az doğru. Alakalı kod aşağıdadır:

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

Cevap için teşekkürler. Sadece bu projeye geri dönelim! Doğru, işaretleyicileri biraz dengelemek mümkün mü? İlgili şirketlerin türü, bilgi penceresinin içinde kimin en iyi olduğunu tartışır (aksi halde biliyorum!).
Rob

İyi iş @Casey. Harika görünüyor!
RyanKDalton

@Casey Cevabınız için teşekkürler, bunu kodumda nasıl çalışabilirim? Ben böyle kod yeniden işleme ile mücadele! İşte benim kaynak - view-source: mediwales.com/mapping/members
Rob

@Rob Örnek sayfamı kılavuz olarak kullanın. Kodumuz arasındaki büyük fark, oluşturma işaretleyici kodumu coğrafi kod adres kodumdan çıkardığım ve createMarker adlı kendi işlevine koyduğum. Dürtme tekniğinin çalışmasını sağlamak için de bunu yapmanız gerekecektir.
Casey

@Casey Birkaç denemem oldu ve işe yarayamıyorum ... Sana sadece bunu yapmanı sağlıyormuşum gibi gelmesini istemiyorum ama son günü deniyorum.
Rob

3

Bir satış bölgesi uygulaması için aynı lat / uzun birkaç belirteçleri ile aynı sorunu vardı. Bu benim uygulamamda aynı adresteki birden fazla müşteriyle, örneğin aynı gökdelen binasındaki müşteriler ve dolayısıyla aynı fiziksel sokak adresindeki müşterilerle ortak bir senaryodu.

Çakışan işaretçiler için belki de daha iyi bir kullanıcı deneyimi (UX) ile alternatif bir cevap buldum . Oluşturmak için George MacKerron sayesinde OverlappingMarkerSpiderfier kütüphanesi. Google Maps v3 için bu JavaScript kitaplığı, çakışan işaretçiler için varsayılan tıklama davranışını geçersiz kılar. Kütüphane, üst üste binme için ofset yarıçapını yapılandırmanıza olanak tanır (varsayılan olarak 20 pikseldir).

Http://jawj.github.io/OverlappingMarkerSpiderfier/demo.html ' den Örnek Ekran Görüntüleri :

Tıklamadan önce çakışan işaretlerin ekran görüntüsü Çakışan işaretçilerin herhangi birini tıklamanın ekran görüntüsü Üst üste gelen işaretçilerin "örümcek" webindeki bir işaretçiyi tıklatmanın ekran görüntüsü


0

Yukarıdaki fonksiyonu aşağıdaki gibi değiştirmeyi öneriyorum çünkü elde edilen sonuçlar bana daha iyi geliyor.

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;

}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.