Google maps API V3 - nhiều điểm đánh dấu trên cùng một vị trí


115

Bit bị mắc kẹt trên cái này. Tôi đang lấy danh sách các hợp đồng địa lý thông qua JSON và đưa chúng lên bản đồ google. Tất cả đều hoạt động tốt, ngoại trừ trong trường hợp khi tôi có hai hoặc nhiều điểm đánh dấu trên cùng một vị trí. API chỉ hiển thị 1 điểm đánh dấu - điểm cao nhất. Điều này đủ công bằng tôi cho rằng nhưng muốn tìm cách hiển thị tất cả chúng bằng cách nào đó.

Tôi đã tìm kiếm trên google và tìm thấy một vài giải pháp nhưng dường như chúng dành cho V2 của API hoặc không tuyệt vời lắm. Lý tưởng nhất là tôi muốn một giải pháp trong đó bạn nhấp vào một số loại điểm đánh dấu nhóm và sau đó hiển thị các điểm đánh dấu được nhóm xung quanh vị trí tất cả chúng nằm trong đó.

Bất cứ ai cũng có vấn đề này hoặc tương tự và sẽ quan tâm để chia sẻ một giải pháp?

Câu trả lời:


116

Hãy xem OverlapsMarkerSpiderfier .
Có một trang thử nghiệm, nhưng họ không hiển thị các điểm đánh dấu chính xác ở cùng một vị trí, chỉ một số trang rất gần nhau.

Nhưng một ví dụ thực tế với các điểm đánh dấu trên cùng một vị trí có thể được nhìn thấy trên http://www.ejw.de/ejw-vor-ort/ (cuộn xuống bản đồ và nhấp vào một vài điểm đánh dấu để xem hiệu ứng nhện ).

Đó dường như là giải pháp hoàn hảo cho vấn đề của bạn.


Điều này thật tuyệt vời và đáp ứng hoàn hảo nhu cầu còn lại từ thư viện cụm, không xử lý các điểm đánh dấu với cùng độ trễ / dài chính xác.
Justin

Nếu sử dụng OverlappingMarkerSpiderfierkết hợp với MarkerClusterer, một tùy chọn tốt là đặt maxZoomtùy chọn trên hàm tạo cụm. Điều này "giải nén" các điểm đánh dấu sau mức thu phóng được chỉ định.
Diederik

@Tad Tôi không biết nếu bạn là nhà phát triển của trang web đó, nhưng tôi muốn cho bạn biết rằng bản đồ trên ejw.de đã bị hỏng. Tôi nhận được một lỗi JS.
Alex

Tôi đã kiểm tra bản demo được đề xuất, nhưng nó có vẻ đã chết. Sau khi nghiên cứu sâu hơn, tôi đã tìm thấy ví dụ này về cách tích hợp các cụm đánh dấu và Spiderifier. Không có bản demo trực tiếp, nhưng chỉ cần sao chép và làm theo readme. github.com/yagoferrer/markerclusterer-plus-spiderfier-example
Sax

34

Bù đắp các điểm đánh dấu không phải là một giải pháp thực sự nếu chúng nằm trong cùng một tòa nhà. Những gì bạn có thể muốn làm là sửa đổi markerclusterer.js như vậy:

  1. Thêm một phương thức nhấp chuột nguyên mẫu trong lớp MarkerClusterer, như vậy - chúng ta sẽ ghi đè lên điều này sau trong hàm khởi tạo bản đồ ():

    MarkerClusterer.prototype.onClick = function() { 
        return true; 
    };
  2. Trong lớp ClusterIcon, thêm đoạn mã sau SAU trình kích hoạt clusterclick:

    // Trigger the clusterclick event.
    google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_);
    
    var zoom = this.map_.getZoom();
    var maxZoom = markerClusterer.getMaxZoom();
    // if we have reached the maxZoom and there is more than 1 marker in this cluster
    // use our onClick method to popup a list of options
    if (zoom >= maxZoom && this.cluster_.markers_.length > 1) {
       return markerClusterer.onClickZoom(this);
    }
  3. Sau đó, trong hàm khởi tạo () nơi bạn khởi tạo bản đồ và khai báo đối tượng MarkerClusterer:

    markerCluster = new MarkerClusterer(map, markers);
    // onClickZoom OVERRIDE
    markerCluster.onClickZoom = function() { return multiChoice(markerCluster); }

    Trong đó multiChoice () là hàm CỦA BẠN (chưa được viết) để bật lên InfoWindow với danh sách các tùy chọn để chọn. Lưu ý rằng đối tượng MarkerClusterer được truyền cho hàm của bạn, bởi vì bạn sẽ cần điều này để xác định có bao nhiêu điểm đánh dấu trong cụm đó. Ví dụ:

    function multiChoice(mc) {
         var cluster = mc.clusters_;
         // if more than 1 point shares the same lat/long
         // the size of the cluster array will be 1 AND
         // the number of markers in the cluster will be > 1
         // REMEMBER: maxZoom was already reached and we can't zoom in anymore
         if (cluster.length == 1 && cluster[0].markers_.length > 1)
         {
              var markers = cluster[0].markers_;
              for (var i=0; i < markers.length; i++)
              {
                  // you'll probably want to generate your list of options here...
              }
    
              return false;
         }
    
         return true;
    }

17

Tôi đã sử dụng nó cùng với jQuery và nó thực hiện công việc:

var map;
var markers = [];
var infoWindow;

function initialize() {
    var center = new google.maps.LatLng(-29.6833300, 152.9333300);

    var mapOptions = {
        zoom: 5,
        center: center,
        panControl: false,
        zoomControl: false,
        mapTypeControl: false,
        scaleControl: false,
        streetViewControl: false,
        overviewMapControl: false,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }


    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

    $.getJSON('jsonbackend.php', function(data) {
        infoWindow = new google.maps.InfoWindow();

        $.each(data, function(key, val) {
            if(val['LATITUDE']!='' && val['LONGITUDE']!='')
            {                
                // Set the coordonates of the new point
                var latLng = new google.maps.LatLng(val['LATITUDE'],val['LONGITUDE']);

                //Check Markers array for duplicate position and offset a little
                if(markers.length != 0) {
                    for (i=0; i < markers.length; i++) {
                        var existingMarker = markers[i];
                        var pos = existingMarker.getPosition();
                        if (latLng.equals(pos)) {
                            var a = 360.0 / markers.length;
                            var newLat = pos.lat() + -.00004 * Math.cos((+a*i) / 180 * Math.PI);  //x
                            var newLng = pos.lng() + -.00004 * Math.sin((+a*i) / 180 * Math.PI);  //Y
                            var latLng = new google.maps.LatLng(newLat,newLng);
                        }
                    }
                }

                // Initialize the new marker
                var marker = new google.maps.Marker({map: map, position: latLng, title: val['TITLE']});

                // The HTML that is shown in the window of each item (when the icon it's clicked)
                var html = "<div id='iwcontent'><h3>"+val['TITLE']+"</h3>"+
                "<strong>Address: </strong>"+val['ADDRESS']+", "+val['SUBURB']+", "+val['STATE']+", "+val['POSTCODE']+"<br>"+
                "</div>";

                // Binds the infoWindow to the point
                bindInfoWindow(marker, map, infoWindow, html);

                // Add the marker to the array
                markers.push(marker);
            }
        });

        // Make a cluster with the markers from the array
        var markerCluster = new MarkerClusterer(map, markers, { zoomOnClick: true, maxZoom: 15, gridSize: 20 });
    });
}

function markerOpen(markerid) {
    map.setZoom(22);
    map.panTo(markers[markerid].getPosition());
    google.maps.event.trigger(markers[markerid],'click');
    switchView('map');
}

google.maps.event.addDomListener(window, 'load', initialize);

Thx hoạt động hoàn hảo cho tôi :) Chỉ là những gì tôi đã tìm kiếm từ nhiều giờ: p
Jicao

Giải pháp đẹp và thanh lịch. Cảm ơn bạn!
Concept211

Giải pháp hoàn hảo bù đắp chút ít! Có thể không, chúng tôi di chuột lên điểm đánh dấu và hơn là nó hiển thị nhiều điểm đánh dấu
Intekhab Khan

14

Mở rộng câu trả lời của Chaoley , tôi đã thực hiện một chức năng, đưa ra một danh sách các vị trí (đối tượng lnglatthuộc tính) có tọa độ giống hệt nhau, di chuyển chúng ra khỏi vị trí ban đầu một chút (sửa đổi các đối tượng tại chỗ). Sau đó, họ tạo thành một vòng tròn đẹp xung quanh điểm trung tâm.

Tôi thấy rằng, đối với vĩ độ của tôi (52deg North), bán kính vòng tròn 0,0003 độ hoạt động tốt nhất và bạn phải bù cho sự khác biệt giữa vĩ độ và kinh độ khi chuyển đổi thành km. Bạn có thể tìm thấy các chuyển đổi gần đúng cho vĩ độ của bạn ở đây .

var correctLocList = function (loclist) {
    var lng_radius = 0.0003,         // degrees of longitude separation
        lat_to_lng = 111.23 / 71.7,  // lat to long proportion in Warsaw
        angle = 0.5,                 // starting angle, in radians
        loclen = loclist.length,
        step = 2 * Math.PI / loclen,
        i,
        loc,
        lat_radius = lng_radius / lat_to_lng;
    for (i = 0; i < loclen; ++i) {
        loc = loclist[i];
        loc.lng = loc.lng + (Math.cos(angle) * lng_radius);
        loc.lat = loc.lat + (Math.sin(angle) * lat_radius);
        angle += step;
    }
};

1
DzinX, tôi đã dành 4 giờ qua để cố gắng tìm ra cách tôi có thể triển khai mã của bạn vào mã của mình mà không có kết quả. Tôi đã đi đến kết luận rằng tôi rất thích điều này và sẽ thực sự đánh giá cao sự giúp đỡ của bạn. Đây là nơi tôi đang cố gắng cắm mã vào: pastebin.com/5qYbvybm - MỌI GIÚP sẽ được đánh giá cao! Cảm ơn!
WebMW

WebMW: Sau khi bạn trích xuất các điểm đánh dấu từ XML, trước tiên bạn phải nhóm chúng thành các danh sách để mỗi danh sách chứa các điểm đánh dấu trỏ đến chính xác cùng một vị trí. Sau đó, trên mỗi danh sách chứa nhiều hơn một phần tử, hãy chạy trueLocList (). Chỉ sau khi bạn làm điều đó, hãy tạo các đối tượng google.maps.Marker.
DzinX

Nó không làm việc .... Nó chỉ thay đổi chờ đợi lat tôi từ 37.68625400000000000,-75.71669800000000000đến 37.686254,-75.716698cũng là như nhau cho tất cả các giá trị ... M mong đợi một cái gì đó giống như ... 37.68625400000000000,-75.71669800000000000để 37.6862540000001234,-75.7166980000001234 37.6862540000005678,-75.7166980000005678..etc .. Tôi cũng đã cố gắng thay đổi góc của tôi.
Premshankar Tiwari

Hummm, hãy đào một chút và hy vọng rằng @DzinX vẫn còn trong khu vực. Bạn có thể giao phối (hoặc bất cứ ai khác) giải thích làm thế nào bạn có được tất cả những con số đó? Lng_radius, v.v? Cảm ơn nhiều. :)
Vae

1
@Vae: Bán kính là bao nhiêu bạn muốn vòng tròn được. Bạn muốn vòng tròn trông tròn theo pixel, vì vậy bạn cần biết, ở vị trí của bạn, tỷ lệ 1 độ vĩ độ đến 1 độ kinh độ (tính bằng pixel trên bản đồ). Bạn có thể tìm thấy điều này trên một số trang web hoặc chỉ thử nghiệm cho đến khi bạn nhận được số chính xác. Góc là bao nhiêu pin đầu tiên ở bên phải từ trên xuống.
DzinX

11

@Ignatius câu trả lời tuyệt vời nhất, được cập nhật để hoạt động với phiên bản v2.0.7 của MarkerClustererPlus.

  1. Thêm một phương thức nhấp chuột nguyên mẫu trong lớp MarkerClusterer, như vậy - chúng ta sẽ ghi đè lên điều này sau trong hàm khởi tạo bản đồ ():

    // BEGIN MODIFICATION (around line 715)
    MarkerClusterer.prototype.onClick = function() { 
        return true; 
    };
    // END MODIFICATION
  2. Trong lớp ClusterIcon, thêm mã sau SAU kích hoạt click / clusterclick:

    // EXISTING CODE (around line 143)
    google.maps.event.trigger(mc, "click", cClusterIcon.cluster_);
    google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name
    
    // BEGIN MODIFICATION
    var zoom = mc.getMap().getZoom();
    // Trying to pull this dynamically made the more zoomed in clusters not render
    // when then kind of made this useless. -NNC @ BNB
    // var maxZoom = mc.getMaxZoom();
    var maxZoom = 15;
    // if we have reached the maxZoom and there is more than 1 marker in this cluster
    // use our onClick method to popup a list of options
    if (zoom >= maxZoom && cClusterIcon.cluster_.markers_.length > 1) {
        return mc.onClick(cClusterIcon);
    }
    // END MODIFICATION
  3. Sau đó, trong hàm khởi tạo () nơi bạn khởi tạo bản đồ và khai báo đối tượng MarkerClusterer:

    markerCluster = new MarkerClusterer(map, markers);
    // onClick OVERRIDE
    markerCluster.onClick = function(clickedClusterIcon) { 
      return multiChoice(clickedClusterIcon.cluster_); 
    }

    Trong đó multiChoice () là hàm CỦA BẠN (chưa được viết) để bật lên InfoWindow với danh sách các tùy chọn để chọn. Lưu ý rằng đối tượng MarkerClusterer được truyền cho hàm của bạn, bởi vì bạn sẽ cần điều này để xác định có bao nhiêu điểm đánh dấu trong cụm đó. Ví dụ:

    function multiChoice(clickedCluster) {
      if (clickedCluster.getMarkers().length > 1)
      {
        // var markers = clickedCluster.getMarkers();
        // do something creative!
        return false;
      }
      return true;
    };

1
Cảm ơn, điều này hoạt động hoàn hảo! Đối với maxZoomvấn đề của bạn , tôi nghĩ đây chỉ là sự cố nếu không có bộ maxZoom hoặc maxZoom cho cụm lớn hơn mức thu phóng cho bản đồ. Tôi đã thay thế mã hóa cứng của bạn bằng đoạn mã này và nó dường như hoạt động tốt:var maxZoom = mc.getMaxZoom(); if (null === maxZoom || maxZoom > mc.getMap().maxZoom) { maxZoom = mc.getMap().maxZoom; if (null === maxZoom) { maxZoom = 15; } }
Pascal

Tôi biết điều này thực sự cũ, nhưng tôi đang cố gắng sử dụng giải pháp này. Tôi có nó hoạt động, nhưng trong trường hợp hiển thị một infowindow với dữ liệu cụm ... làm thế nào để tôi có được vị trí đánh dấu của cụm được nhấp ở vị trí đầu tiên để tôi có thể hiển thị infowindow? các điểm đánh dấu là mảng dữ liệu của tôi ... nhưng làm cách nào tôi có thể hiển thị thông tin trên biểu tượng / điểm đánh dấu cụm?
dùng756659

@ user756659 trong multiChoice bạn nhận lat / lng qua: clickedCluster.center_.lat()/clickedCluster.center_.lng()
Jens Kohl

1
@Pascal và với một chút xáo trộn, chúng tôi kết thúc với cái này, cái này có thể hoạt động, nhưng như tao của python nói. "Tính dễ đọc". var maxZoom = Math.min (mc.getMaxZoom () || 15, mc.getMap (). maxZoom | | 15);
Nande

6

Các câu trả lời ở trên thanh lịch hơn, nhưng tôi đã tìm thấy một cách nhanh chóng và bẩn thỉu mà thực sự hoạt động thực sự thực sự rất tốt. Bạn có thể thấy nó hoạt động tại www.buildinglit.com

Tất cả những gì tôi đã làm là thêm một phần bù ngẫu nhiên vào vĩ độ và kinh độ cho trang genxml.php của tôi để nó trả về kết quả hơi khác nhau mỗi lần với phần bù mỗi lần bản đồ được tạo bằng các điểm đánh dấu. Điều này nghe có vẻ như là một hack, nhưng trong thực tế, bạn chỉ cần các điểm đánh dấu để di chuyển một chút nhẹ nhàng theo hướng ngẫu nhiên để chúng có thể nhấp vào trên bản đồ nếu chúng bị chồng chéo. Nó thực sự hoạt động rất tốt, tôi sẽ nói tốt hơn phương pháp nhện bởi vì ai muốn đối phó với sự phức tạp đó và để chúng mọc ở khắp mọi nơi. Bạn chỉ muốn có thể chọn điểm đánh dấu. Khỏa thân nó hoạt động hoàn hảo.

Dưới đây là một ví dụ về việc tạo nút lặp câu lệnh while trong php_genxml.php của tôi

while ($row = @mysql_fetch_assoc($result)){ $offset = rand(0,1000)/10000000;
$offset2 = rand(0, 1000)/10000000;
$node = $dom->createElement("marker");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("name", $row['name']);
$newnode->setAttribute("address", $row['address']);
$newnode->setAttribute("lat", $row['lat'] + $offset);
$newnode->setAttribute("lng", $row['lng'] + $offset2);
$newnode->setAttribute("distance", $row['distance']);
$newnode->setAttribute("type", $row['type']);
$newnode->setAttribute("date", $row['date']);
$newnode->setAttribute("service", $row['service']);
$newnode->setAttribute("cost", $row['cost']);
$newnode->setAttribute("company", $company);

Lưu ý dưới lat và dài có dấu +. từ 2 biến trên. Tôi đã phải chia ngẫu nhiên 0,1000 cho 10000000 để có được một số thập phân đủ nhỏ ngẫu nhiên để chỉ di chuyển các điểm đánh dấu xung quanh. Hãy tự tin với biến đó để có được một cái chính xác hơn cho nhu cầu của bạn.


Mát mẻ! Đây là bản hack bẩn mà tôi thấy rất hữu ích, không cần phải làm rối mã api của Google Maps
CườngDC

3

Đối với các tình huống có nhiều dịch vụ trong cùng một tòa nhà, bạn có thể bù các điểm đánh dấu chỉ một chút, (giả sử bằng 0,001 độ), trong bán kính từ điểm thực tế. Điều này cũng sẽ tạo ra một hiệu ứng hình ảnh đẹp.


3

Đây là một giải pháp 'nhanh và bẩn' tương tự như cách mà Matthew Fox gợi ý, lần này là sử dụng JavaScript.

Trong JavaScript, bạn chỉ có thể bù độ trễ và dài của tất cả các vị trí của mình bằng cách thêm một phần bù ngẫu nhiên nhỏ vào cả hai, vd

myLocation[i].Latitude+ = (Math.random() / 25000)

(Tôi thấy rằng việc chia cho 25000 sẽ phân tách đủ nhưng không di chuyển điểm đánh dấu khỏi vị trí chính xác, ví dụ như một địa chỉ cụ thể)

Điều này làm cho một công việc khá hợp lý là bù đắp chúng với nhau, nhưng chỉ sau khi bạn phóng to gần. Khi thu nhỏ, vẫn không rõ ràng rằng có nhiều tùy chọn cho vị trí.


1
Tôi thích điều này. Nếu bạn không cần các dấu đại diện chính xác, chỉ cần hạ 25000 đến 250 hoặc 25. Giải pháp đơn giản và nhanh chóng.
Fid

2

Kiểm tra Marker Clusterer cho V3 - thư viện này tập hợp các điểm gần đó vào một điểm đánh dấu nhóm. Bản đồ phóng to khi các cụm được nhấp. Tôi tưởng tượng khi phóng to ngay trong bạn vẫn có cùng một vấn đề với các điểm đánh dấu trên cùng một vị trí.


Đúng, hãy xem thư viện nhỏ tiện dụng đó nhưng dường như nó vẫn không khắc phục được vấn đề. Tôi đang tạo một công cụ định vị dịch vụ cho một công ty đôi khi có nhiều hơn một dịch vụ trong cùng một khối văn phòng và do đó có cùng một địa lý chính xác. Tôi có thể hiển thị các dịch vụ khác nhau trong một cửa sổ thông tin nhưng đây dường như không phải là giải pháp thanh lịch nhất ...
Louzoid

@Louzoid Marker Clusterer không khắc phục được vấn đề như tôi vừa tìm ra. Tôi có cùng một vấn đề, tôi có một số công ty trong một tòa nhà và do đó nó chỉ hiển thị 1 điểm đánh dấu.
Cướp

1

Cập nhật để hoạt động với MarkerClustererPlus.

  google.maps.event.trigger(mc, "click", cClusterIcon.cluster_);
  google.maps.event.trigger(mc, "clusterclick", cClusterIcon.cluster_); // deprecated name

  // BEGIN MODIFICATION
  var zoom = mc.getMap().getZoom();
  // Trying to pull this dynamically made the more zoomed in clusters not render
  // when then kind of made this useless. -NNC @ BNB
  // var maxZoom = mc.getMaxZoom();
  var maxZoom = 15;
  // if we have reached the maxZoom and there is more than 1 marker in this cluster
  // use our onClick method to popup a list of options
  if (zoom >= maxZoom && cClusterIcon.cluster_.markers_.length > 1) {
    var markers = cClusterIcon.cluster_.markers_;
    var a = 360.0 / markers.length;
    for (var i=0; i < markers.length; i++)
    {
        var pos = markers[i].getPosition();
        var newLat = pos.lat() + -.00004 * Math.cos((+a*i) / 180 * Math.PI);  // x
        var newLng = pos.lng() + -.00004 * Math.sin((+a*i) / 180 * Math.PI);  // Y
        var finalLatLng = new google.maps.LatLng(newLat,newLng);
        markers[i].setPosition(finalLatLng);
        markers[i].setMap(cClusterIcon.cluster_.map_);
    }
    cClusterIcon.hide();
    return ;
  }
  // END MODIFICATION

Cách tiếp cận này yêu cầu người dùng nhấp vào biểu tượng cụm và sẽ không bao gồm các trường hợp sử dụng trong đó điều hướng được thực hiện với thanh trượt thu phóng hoặc cuộn chuột. Bất kỳ ý tưởng làm thế nào để giải quyết những vấn đề?
Remi Sture

1

Tôi thích các giải pháp đơn giản vì vậy đây là của tôi. Thay vì sửa đổi lib, điều này sẽ làm cho khó khăn hơn để bảo trì. bạn chỉ có thể xem sự kiện như thế này

google.maps.event.addListener(mc, "clusterclick", onClusterClick);

sau đó bạn có thể quản lý nó trên

function onClusterClick(cluster){
    var ms = cluster.getMarkers();

i, tức là đã sử dụng bootstrap để hiển thị bảng với danh sách. mà tôi thấy dễ thương và dễ sử dụng hơn nhiều so với việc đi nhện ở những nơi "đông đúc". (nếu bạn đang sử dụng một clusterer thì rất có thể bạn sẽ bị va chạm một khi bạn bị nhện). bạn cũng có thể kiểm tra zoom ở đó.

btw. Tôi vừa tìm thấy tờ rơi và nó dường như hoạt động tốt hơn nhiều, cụm AND spiderfy hoạt động rất trôi chảy http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.10000.html và đó là nguồn mở.



0

Mở rộng các câu trả lời ở trên, chỉ cần đảm bảo bạn đặt tùy chọn maxZoom khi khởi tạo đối tượng bản đồ.


0

Cung cấp bù sẽ làm cho các điểm đánh dấu ở xa khi người dùng phóng to tối đa. Vì vậy, tôi tìm thấy một cách để đạt được điều đó. Đây có thể không phải là một cách thích hợp nhưng nó hoạt động rất tốt.

// This code is in swift
for loop markers
{
//create marker
let mapMarker = GMSMarker()
mapMarker.groundAnchor = CGPosition(0.5, 0.5)
mapMarker.position = //set the CLLocation
//instead of setting marker.icon set the iconView
let image:UIIMage = UIIMage:init(named:"filename")
let imageView:UIImageView = UIImageView.init(frame:rect(0,0, ((image.width/2 * markerIndex) + image.width), image.height))
imageView.contentMode = .Right
imageView.image = image
mapMarker.iconView = imageView
mapMarker.map = mapView
}

đặt z Index của điểm đánh dấu để bạn sẽ thấy biểu tượng điểm đánh dấu mà bạn muốn thấy ở trên cùng, nếu không, nó sẽ làm động các điểm đánh dấu như tự động tráo đổi. khi người dùng chạm vào điểm đánh dấu, hãy xử lý zIndex để đưa điểm đánh dấu lên trên bằng cách sử dụng Hoán đổi zIndex.


0

Làm thế nào để thoát khỏi nó .. [Swift]

    var clusterArray = [String]()
    var pinOffSet : Double = 0
    var pinLat = yourLat
    var pinLong = yourLong
    var location = pinLat + pinLong

Một điểm đánh dấu mới sắp được tạo ra? kiểm tra clusterArrayvà thao tác bù

 if(!clusterArray.contains(location)){
        clusterArray.append(location)
    } else {

        pinOffSet += 1
        let offWithIt = 0.00025 // reasonable offset with zoomLvl(14-16)
        switch pinOffSet {
        case 1 : pinLong = pinLong + offWithIt ; pinLat = pinLat + offWithIt
        case 2 : pinLong = pinLong + offWithIt ; pinLat = pinLat - offWithIt
        case 3 : pinLong = pinLong - offWithIt ; pinLat = pinLat - offWithIt
        case 4 : pinLong = pinLong - offWithIt ; pinLat = pinLat + offWithIt
        default : print(1)
        }


    }

kết quả

nhập mô tả hình ảnh ở đây


0

Thêm vào câu trả lời thiên tài lén lút của Matthew Fox, tôi đã thêm một phần bù ngẫu nhiên nhỏ cho mỗi lat và lng khi đặt đối tượng đánh dấu. Ví dụ:

new LatLng(getLat()+getMarkerOffset(), getLng()+getMarkerOffset()),

private static double getMarkerOffset(){
    //add tiny random offset to keep markers from dropping on top of themselves
    double offset =Math.random()/4000;
    boolean isEven = ((int)(offset *400000)) %2 ==0;
    if (isEven) return  offset;
    else        return -offset;
}

-2

Mở rộng câu trả lời ở trên, khi bạn đã tham gia chuỗi, không thêm / trừ vị trí (ví dụ: "37.12340-0.00069"), chuyển đổi vĩ độ / kinh độ ban đầu của bạn thành số float, ví dụ: sử dụng parseFloat (), sau đó thêm hoặc trừ các hiệu chỉnh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.