Penanda Google di alamat yang sama tidak menunjukkan semua penanda

16

Saya telah mengerjakan peta ini - http://www.mediwales.com/mapping/test/

Ini merencanakan perusahaan dengan baik dan mengelompokkan mereka baik-baik saja tetapi masalah muncul dengan perusahaan di gedung yang sama dengan alamat yang sama. Itu hanya menunjukkan satu perusahaan daripada mereka semua.

Bagaimana saya bisa menampilkan semua perusahaan di alamat yang sama?

Marker di-geocode dengan nama / nomor gedung, jalan, kota, kode pos. Saya menduga spidol ada sebagai bangunan yang memiliki 3 perusahaan menunjukkan 3 di cluster. Namun ketika Anda mengkliknya, itu hanya menunjukkan satu perusahaan.

MEMPERBARUI:

Saya telah berhasil membuat mereka untuk mengimbangi, tapi itu mengimbangi semua penanda ketika saya hanya ingin mengimbanginya jika ada lebih dari satu penanda yang sama. (Terima kasih atas jawaban 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>
rampok
sumber

Jawaban:

15

Cluster ditampilkan dengan benar. Semua marker sedang diplot. Masalahnya adalah Anda hanya dapat mengeklik penanda paling atas, sehingga sepertinya hanya ada satu penanda.

Untuk melihat konten untuk marker bertepatan, Anda harus meneruskan konten infowindow marker yang mendasari ke marker paling atas.

Untuk melakukan ini, pertama-tama, lacak setiap penanda. Anda menggunakan MarkerClusterer, jadi instance markerClusterer akan menampung setiap marker. Saat setiap hasil geocode kembali, bandingkan latlng permintaan itu dengan semua penanda yang telah diplot. Anda dapat membandingkan posisi menggunakan metode sama dengan objek latlng .

Jika marker baru cocok dengan posisi marker yang ada, ambil konten infowindow dari marker pertama dan tambahkan ke konten infowindow marker baru. Dengan cara ini, ketika Anda mengklik penanda paling atas (perusahaan kedua), itu akan menampilkan informasi dari kedua perusahaan. Jika ada lebih dari dua perusahaan, Anda harus mengambil konten arus kas masuk untuk semua penanda yang cocok. Metode ini juga akan memungkinkan clusterer penanda untuk tetap menampilkan jumlah penanda yang benar.

Berikut adalah contoh kerja dan kode javascript. Alamat pertama dan kedua adalah sama. Ketika Anda mengklik penanda untuk 2, itu akan menampilkan "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: Respons terhadap komentar

Sebagai alternatif, Anda bisa mendorong penanda bertepatan dengan menerapkan pengganda kecil (angka acak antara 0,999999 dan 1,000001, misalnya) pengganda ke posisi masing-masing penanda bertepatan. Berikut ini sebuah contoh. Ini menggunakan data yang sama dengan contoh pertama, kecuali, alih-alih penanda 1 dan 2 ditempatkan di atas satu sama lain dan berbagi infowindow, penanda 2 diimbangi dari penanda 1. Perhatikan bahwa hasil geocode Anda akan menjadi sedikit kurang akurat. Kode yang relevan di bawah ini:

//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;
    }
Casey
sumber
Terima kasih balasannya. Baru saja kembali ke proyek ini! Benar, mungkinkah untuk mengimbangi spidol sedikit? Jenis perusahaan yang terlibat akan berdebat siapa yang teratas dalam jendela info sebaliknya (kecil saya tahu!).
Rob
Kerja bagus @Casey. Itu terlihat hebat!
RyanKDalton-OffTheGridMaps
@Casey Terima kasih atas jawabannya, bagaimana saya bisa memasukkannya ke dalam kode saya? Saya kesulitan dengan pengerjaan ulang kode seperti ini! Inilah sumber saya - view-source: mediwales.com/mapping/members
Rob
@Rob Gunakan halaman contoh saya sebagai panduan. Satu perbedaan besar antara kode kita adalah bahwa saya telah menarik kode penanda buat saya dari kode alamat geocode saya dan memasukkannya ke dalam fungsinya sendiri yang disebut createMarker. Anda harus melakukan ini juga untuk mendapatkan teknik dorongan untuk bekerja.
Casey
@Casey Saya sudah melakukan beberapa upaya dan tidak bisa membuatnya bekerja ... Saya tidak ingin itu terdengar seperti saya hanya membuat Anda melakukannya tetapi saya sudah mencoba untuk hari terakhir.
Rob
3

Saya memiliki masalah yang sama dengan beberapa penanda pada lat / long yang sama persis untuk aplikasi wilayah penjualan. Ini adalah skenario umum di aplikasi saya dengan banyak pelanggan di alamat yang sama, misalnya pelanggan di gedung pencakar langit yang sama dan dengan demikian di alamat jalan fisik yang sama.

Saya menemukan jawaban alternatif dengan pengalaman pengguna yang lebih baik (UX) untuk marker yang tumpang tindih. Terima kasih kepada George MacKerron untuk membuat perpustakaan OverlappingMarkerSpiderfier . Pustaka JavaScript untuk Google Maps v3 ini mengesampingkan perilaku klik default untuk marker yang tumpang tindih. Perpustakaan memungkinkan Anda untuk mengonfigurasi radius offset untuk tumpang tindih (default hingga 20 piksel).

Contoh Screenshot dari http://jawj.github.io/OverlappingMarkerSpiderfier/demo.html :

Cuplikan layar penanda yang tumpang tindih sebelum klik Cuplikan layar mengklik salah satu penanda yang tumpang tindih Cuplikan layar mengklik marker di web "spidered" marker tumpang tindih

Steve Jansen
sumber
0

Saya mengusulkan untuk mengubah fungsi di atas sebagai berikut karena hasil yang diperoleh menurut saya lebih baik.

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;

}

Paul Bozan
sumber