簡體   English   中英

谷歌地圖 API V3 - 完全相同的位置上的多個標記

[英]Google maps API V3 - multiple markers on exact same spot

有點卡在這個上。 我正在通過 JSON 檢索地理坐標列表並將它們彈出到谷歌地圖上。 除了在完全相同的位置上有兩個或更多標記的情況外,一切都運行良好。 API 僅顯示 1 個標記 - 頂部的標記。 我想這很公平,但想找到一種方法以某種方式顯示它們。

我搜索了谷歌並找到了一些解決方案,但它們似乎大多適用於 API 的 V2,或者不是那么好。 理想情況下,我想要一個解決方案,您可以單擊某種組標記,然后顯示標記聚集在它們所在的位置周圍。

有人遇到這個問題或類似問題,願意分享解決方案嗎?

看看OverlappingMarkerSpiderfier
有一個演示頁面,但它們沒有顯示完全相同的標記,只有一些非常接近的標記。

但是可以在http://www.ejw.de/ejw-vor-ort/上看到一個在完全相同的位置帶有標記的真實示例(向下滾動查看地圖並單擊一些標記以查看蜘蛛效果)。

這似乎是您問題的完美解決方案。

如果標記位於同一建築物中,則偏移標記不是真正的解決方案。 您可能想要做的是像這樣修改markerclusterer.js:

  1. 在 MarkerClusterer 類中添加一個原型 click 方法,如下所示 - 我們稍后將在 map initialize() 函數中覆蓋它:

     MarkerClusterer.prototype.onClick = function() { return true; };
  2. 在 ClusterIcon 類中,在 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. 然后,在初始化地圖並聲明 MarkerClusterer 對象的 initialize() 函數中:

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

    其中 multiChoice() 是您的(尚未編寫的)函數,用於彈出一個 InfoWindow,其中包含可供選擇的選項列表。 請注意,markerClusterer 對象被傳遞給您的函數,因為您將需要它來確定該集群中有多少標記。 例如:

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

我將它與 jQuery 一起使用,它完成了這項工作:

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

擴展Chaoley 的答案,我實現了一個函數,給定坐標完全相同的位置列表(具有lnglat屬性的對象),將它們從原始位置移開一點(就地修改對象)。 然后它們圍繞中心點形成一個漂亮的圓圈。

我發現,對於我的緯度(北 52 度),0.0003 度的圓半徑效果最好,並且當轉換為公里時,您必須彌補緯度和經度之間的差異。 您可以在此處找到適合您緯度的近似換算。

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

@Ignatius 最出色的答案,已更新為與 MarkerClusterPlus 的 v2.0.7 一起使用。

  1. 在 MarkerClusterer 類中添加一個原型 click 方法,如下所示 - 我們稍后將在 map initialize() 函數中覆蓋它:

     // BEGIN MODIFICATION (around line 715) MarkerClusterer.prototype.onClick = function() { return true; }; // END MODIFICATION
  2. 在 ClusterIcon 類中,在 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. 然后,在初始化地圖並聲明 MarkerClusterer 對象的 initialize() 函數中:

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

    其中 multiChoice() 是您的(尚未編寫的)函數,用於彈出一個 InfoWindow,其中包含可供選擇的選項列表。 請注意,markerClusterer 對象被傳遞給您的函數,因為您將需要它來確定該集群中有多少標記。 例如:

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

這更像是一種權宜之計的“快速而骯臟”的解決方案,類似於 Matthew Fox 建議的解決方案,這次使用的是 JavaScript。

在 JavaScript 中,您可以通過向兩者添加一個小的隨機偏移量來偏移所有位置的緯度和經度,例如

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

(我發現除以25000可以提供足夠的分離度,但不會將標記從確切位置顯着移動,例如特定地址)

這可以很好地將它們彼此抵消,但前提是您必須仔細放大。 縮小時,仍然不清楚該位置有多個選項。

上面的答案更優雅,但我發現了一種快速而骯臟的方法,實際上效果非常好。 您可以在www.buildinglit.com上看到它的實際效果

我所做的只是在我的 genxml.php 頁面的緯度和經度上添加一個隨機偏移量,因此每次使用標記創建地圖時,它每次返回的結果都略有不同。 這聽起來像是一個 hack,但實際上您只需要標記在隨機方向上輕微移動,如果它們重疊,它們就可以在地圖上點擊。 它實際上工作得很好,我會說比蜘蛛方法更好,因為誰想要處理這種復雜性並讓它們無處不在。 您只想能夠選擇標記。 隨機輕推它非常完美。

這是在我的 php_genxml.php 中創建 while 語句迭代節點的示例

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

請注意,在 lat 和 long 下有 + 偏移量。 從上面的2個變量。 我必須將隨機數除以 0,1000 除以 10000000 以獲得隨機小到足以勉強移動標記的小數。 隨意修改該變量以獲得更精確的變量以滿足您的需求。

我喜歡簡單的解決方案,所以這是我的。 而不是修改庫,這將使其更難維護。 您可以像這樣簡單地觀看活動

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

然后你可以管理它

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

i,即,使用引導程序顯示帶有列表的面板。 我發現這比在“擁擠”的地方做蜘蛛更舒適和有用。 (如果您使用的是clusterer,那么一旦您進行spiderfy,您最終會發生碰撞)。 你也可以在那里檢查縮放。

順便提一句。 我剛剛找到了傳單,它似乎工作得更好,集群和 spiderfy 工作非常流暢http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.10000.html它是開源的。

對於同一建築物中有多個服務的情況,您可以在距離實際點的半徑范圍內稍微偏移標記(例如 0.001 度)。 這也應該產生一個很好的視覺效果。

更新為與 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

查看 V3 的Marker Clusterer - 這個庫將附近的點聚集成一個組標記。 單擊集群時地圖會放大。 我想當你放大時,你仍然會在同一個地方遇到同樣的問題。

我使用了markerclustererplus,對我來說這很有效:

//Code
google.maps.event.addListener(cMarkerClusterer, "clusterclick", function (c) {
            var markers = c.getMarkers();
            
            //Check Markers array for duplicate position and offset a little
            if (markers .length > 1) {
                //Check if all markers are in the same position (with 4 significant digits)
                if (markers .every((val, index, arr) => (val.getPosition().lat().toFixed(4) == arr[0].getPosition().lat().toFixed(4)) && (val.getPosition().lng().toFixed(4) == arr[0].getPosition().lng().toFixed(4)))) { /
                    //Don't modify first element
                    for (i = 1; i < markers.length; i++) {
                        var existingMarker = markers[i];
                        var pos = existingMarker.getPosition();                        
                        var quot = 360.0 / markers.length;
                        var newLat = pos.lat() + -.00008 * Math.cos(+quot * i); //+ -.00008 * Math.cos((+quot * i) / 180 * Math.PI);  //x                        
                        var newLng = pos.lng() + -.00008 * Math.sin(+quot * i);  //+ -.0008 * Math.sin((+quot * i) / 180 * Math.PI);  //Y
                        existingMarker.setPosition(new google.maps.LatLng(newLat, newLng));                        
                    }
                    let cZoom = map.getZoom();
                    map.setZoom(cZoom-1);
                    map.setZoom(cZoom+1);
                } 
            }            
        });

檢查這個: https ://github.com/plank/MarkerClusterer

當您在同一位置有多個標記時,這是修改為在群集標記中有一個 infoWindow 的 MarkerCluster。

你可以在這里看到它是如何工作的:http: //culturedays.ca/en/2013-activities

當用戶放大到最大時,給予偏移將使標記遠離。 所以我找到了實現這一目標的方法。 這可能不是正確的方法,但效果很好。

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

設置標記的 zIndex 以便您可以在頂部看到要在頂部看到的標記圖標,否則它將像自動交換一樣為標記設置動畫。 當用戶點擊標記時,處理 zIndex 以使用 zIndex Swap 將標記置於頂部。

如何擺脫它.. [斯威夫特]

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

即將創建一個新的標記? 檢查clusterArray並操作它的偏移量

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


    }

結果

在此處輸入圖像描述

添加到 Matthew Fox 鬼鬼祟祟的天才答案中,我在設置標記對象時為每個 lat 和 lng 添加了一個小的隨機偏移量。 例如:

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

我使用了這個http://leaflet.github.io/Leaflet.markercluster/並且非常適合我。 添加了完整的解決方案。

<html lang="en">
  <head>
    <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.4/leaflet.markercluster.js"></script>
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.css" />
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.4/MarkerCluster.Default.css" />
 </head>
<body>
   <div id="map"></div>

    <script>
        var addressData = [
            {id: 9, name: "Ankita", title: "Manager", latitude: "33.1128019", longitude: "-96.6958939"},
            {id: 1, name: "Aarti", title: "CEO", latitude: "33.1128019", longitude: "-96.6958939"},
            {id: 2, name: "Payal", title: "Employee", latitude: "33.0460488", longitude: "-96.9983386"}];

        var addressPoints = [];
        for (i = 0; i < addressData.length; i++) {
            var marker = {
                latitude: addressData[i].latitude,
                longitude: addressData[i].longitude,
                coverage: addressData[i]
            };
            addressPoints.push(marker);
        }
        var map = L.map('map').setView(["32.9602172", "-96.7036844"], 5);
        var basemap = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; <a href="http://cartodb.com/attributions">CartoDB</a>', subdomains: 'abcd'});
        basemap.addTo(map);
        
        var markers = L.markerClusterGroup();
        for (var i = 0; i < addressPoints.length; i++) {
           // var icon1 = "app/common_assest/images/pin/redPin.png"; // set ehere you own marker pin whatever you want to set
            var currentMarker = addressPoints[i];
            console.log(currentMarker);
            var contentString = '<div class="mapinfoWindowContent">' +
                    '<div class="mapInfoTitle">Name: ' + currentMarker.coverage.name + '</div>' +
                    '<div class="mapInfoSubText">Licence: ' + currentMarker.coverage.title + '</div>' +
                    '</div>';
   // var myIcon = L.icon({// set ehere you own marker pin whatever you want to set
     // iconUrl: icon1,
    //  iconRetinaUrl: icon1,
   //                });
            var marker = L.marker(new L.LatLng(currentMarker['latitude'], currentMarker['longitude']), {
                title: currentMarker.coverage.name
            });
            marker.bindPopup(contentString);
            markers.addLayer(marker);
        }
        markers.addTo(map);
    </script>
</body>

完全希望它對您有幫助。

我使用的解決方案非常簡單。 只需將@googlemaps/markerclusterer庫與 Maps JavaScript API 結合使用即可。

在地圖上填滿標記后,您只需要一行:

new MarkerClusterer({ map, markers });

所有信息都可以在這里找到https://developers.google.com/maps/documentation/javascript/marker-clustering

我正在使用 Android 的地圖集群。 這些是我正在使用的庫:

implementation 'com.google.android.gms:play-services-places:16.0.0'   
 
implementation 'com.google.android.gms:play-services-maps:16.0.0'
 
implementation 'com.google.android.gms:play-services-location:16.0.0'
 
implementation 'com.google.maps.android:android-maps-utils:2.0.1'

我遇到的問題是,如果兩個項目具有完全相同的緯度和經度點,則集群標記不會分開。 我的解決方法是掃描我的項目數組,如果兩個位置匹配,我會稍微移動它們的位置。 這是我的代碼:

字段變量:

private ArrayList<Tool> esTools;

當您完成初始化工具的 ArrayList 時。 從你的解析方法,調用這個:

loopThroughToolsListAndFixOnesThatHaveSameGeoPoint_FixStackingIssue();

奇跡發生的地方:

private void loopThroughToolsListAndFixOnesThatHaveSameGeoPoint_FixStackingIssue() { 
    DecimalFormat decimalFormatTool = new DecimalFormat("000.0000");
    decimalFormatTool.setRoundingMode(RoundingMode.DOWN);

    for(int backPointer=0; backPointer <= (esTools.size()-1); backPointer++){
        Map<String, Double> compareA = esTools.get(backPointer).getUserChosenGeopoint();
        Double compareA_Latitude = compareA.get("_latitude");
        compareA_Latitude= Double.valueOf(decimalFormatTool.format(compareA_Latitude));
        Double compareA_Longitude = compareA.get("_longitude");
        compareA_Longitude= Double.valueOf(decimalFormatTool.format(compareA_Longitude));
        System.out.println("compareA_Lat= "+ compareA_Latitude+ ", compareA_Long= "+ compareA_Longitude);
        for(int frontPointer=0; frontPointer <= (esTools.size()-1); frontPointer++){
            if(backPointer==frontPointer){
                continue;
            }
            Map<String, Double> compareB = esTools.get(frontPointer).getUserChosenGeopoint();
            Double compareB_Latitude = compareB.get("_latitude");
            compareB_Latitude= Double.valueOf(decimalFormatTool.format(compareB_Latitude));
            Double compareB_Longitude = compareB.get("_longitude");
            compareB_Longitude= Double.valueOf(decimalFormatTool.format(compareB_Longitude));

            if((compareB_Latitude.equals(compareA_Latitude)) && (compareB_Longitude.equals(compareA_Longitude))) {
                System.out.println("these tools match");

                Random randomGen = new Random();
                Double randomNumLat  = randomGen.nextDouble() * 0.00015;
                int addOrSubtractLatitude= ( randomGen.nextBoolean() ? 1 : -1 );
                randomNumLat = randomNumLat*addOrSubtractLatitude;

                Double randomNumLong = randomGen.nextDouble() * 0.00015;
                int addOrSubtractLongitude= ( randomGen.nextBoolean() ? 1 : -1 );
                randomNumLong = randomNumLong*addOrSubtractLongitude;
                System.out.println("Adding Random Latitude="+ randomNumLat + ", Longitude= "+ randomNumLong);

                System.out.println("\n");
                Map<String, Double> latitudeLongitude = new HashMap<>();
                latitudeLongitude.put("_latitude", (compareB_Latitude+ randomNumLat));
                latitudeLongitude.put("_longitude", (compareB_Longitude+ randomNumLong));
                esTools.get(frontPointer).setUserChosenGeopoint(latitudeLongitude);

            }
        }
    }
}

所以上面的方法所做的就是掃描我的ArrayList,看看是否有兩個Tools有匹配點。 如果 Lat Long 點匹配,則稍微移動一個。

擴展上面給出的答案,只需確保在初始化地圖對象時設置 maxZoom 選項。

添加到上述答案,但在 php 和 wordpress 中提供了另一種快速解決方案。 在本例中,我通過 ACF 存儲位置字段並遍歷帖子以獲取該數據。

我發現將 lat / lng 存儲在一個數組中並檢查該數組的值以查看循環是否匹配,然后我們可以使用我們想要移動點的數量更新該數組中的值。

//This is the value to shift the pips by. I found this worked best with markerClusterer
$add_to_latlng = 0.00003;

while ($query->have_posts()) {
    $query->the_post();
    $meta = get_post_meta(get_the_ID(), "postcode", true); //uses an acf field to store location
    $lat = $meta["lat"];
    $lng = $meta["lng"];

    if(in_array($meta["lat"],$lat_checker)){ //check if this meta matches
        
        //if matches then update the array to a new value (current value + shift value)
        // This is using the lng value for a horizontal line of pips, use lat for vertical, or both for a diagonal
        if(isset($latlng_storer[$meta["lng"]])){
            $latlng_storer[$meta["lng"]] = $latlng_storer[$meta["lng"]] + $add_to_latlng;
            $lng = $latlng_storer[$meta["lng"]];
        } else {
            $latlng_storer[$meta["lng"]] = $meta["lng"];
            $lng = $latlng_storer[$meta["lng"]];
        }

    } else {
        $lat_checker[] = $meta["lat"]; //just for simple checking of data
        $latlng_storer[$meta["lat"]] = floatval($meta["lat"]);
        $latlng_storer[$meta["lng"]] =  floatval($meta["lng"]);
    }

    $entry[] = [
        "lat" => $lat,
        "lng" => $lng,
    //...Add all the other post data here and use this array for the pips
    ];
} // end query

一旦我抓住了這些位置,我就會對 $entry 變量進行 json 編碼並在我的 JS 中使用它。

let locations = <?=json_encode($entry)?>;

我知道這是一個相當具體的情況,但我希望這有助於沿線的人!

擴展上面的答案,當你得到連接的字符串,而不是添加/減去位置(例如“37.12340-0.00069”)時,將你的原始緯度/經度轉換為浮點數,例如使用 parseFloat(),然后添加或減去更正。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM