首页 > 解决方案 > 谷歌地图 - 标记聚类问题

问题描述

我正在尝试将 Google Maps Marker Clusterer 添加到我的 Google Maps 实例中,但我遇到了问题。关于我的谷歌地图,我正在加载 170 多个经纬度标记,它们存储在本地 SQL 数据库中。我已按照此处的说明进行操作,但似乎没有任何效果。

目前,标记位于多边形区域内,以可视化特定区域的范围。

<script>

function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(51.93916880428746, -0.504345273716126),
    zoom: 11
});
    var infoWindow = new google.maps.InfoWindow;

    // before the loop
    var markerClusterer = new MarkerClusterer(map, markers, {imagePath: "../img/icons/markerclusterer/m"});

        // Change this depending on the name of your PHP or XML file
        // var mapxmlloc = '../maps/GenerateMarkers.php?type=area&town=' + $("#viewtown").val();
        downloadUrl('../maps/GenerateMarkers.php?type=area', function(data) {
            var xml = data.responseXML;
            var markers = xml.documentElement.getElementsByTagName('marker');
            Array.prototype.forEach.call(markers, function(markerElem) {
                var id = markerElem.getAttribute('id');
                var name = markerElem.getAttribute('name');
                var address = markerElem.getAttribute('address');
                var type = markerElem.getAttribute('type');
                var point = new google.maps.LatLng(
                        parseFloat(markerElem.getAttribute('lat')),
                        parseFloat(markerElem.getAttribute('lng')));
                //bounds.extend(loc);
                var infowincontent = document.createElement('div');
                var strong = document.createElement('strong');
                strong.textContent = name
                infowincontent.appendChild(strong);
                infowincontent.appendChild(document.createElement('br'));

                // inside the loop
                markerClusterer.addMarker(marker);

                var text = document.createElement('text');
                text.textContent = address
                infowincontent.appendChild(text);
                var icon = customLabel[type] || {};
                var marker = new google.maps.Marker({
                    map: map,
                    position: point,
                    label: icon.label
                });


                google.maps.Polygon.prototype.getBoundingBox = function() {
                    var bounds = new google.maps.LatLngBounds();


                    this.getPath().forEach(function(element,index) {
                        bounds.extend(element)
                    });

                    center = bounds.getCenter();
            map.fitBounds(bounds);

                    return(bounds);
                };

                // Define the LatLng coordinates for the polygon's path.
                var Area = [
                    {lat: 51.9111974504221, lng:-0.700698528012367},
                    {lat: 52.0351347507547, lng:-0.643706950863929},
                    {lat: 52.018657752549, lng:-0.576415691098304},
                    {lat: 52.0317553486016, lng:-0.511871013363929},
                    {lat: 52.0258407801943, lng:-0.426726970395179},
                    {lat: 52.0359795613826, lng:-0.350509319027992},
                    {lat: 51.9970768309839, lng:-0.356143903446877},
                    {lat: 51.9860834929546, lng:-0.366786908817971},
                    {lat: 51.9594345951621, lng:-0.372966718388283},
                    {lat: 51.9607039496942, lng:-0.391506147099221},
                    {lat: 51.9426122542336, lng:-0.390132856083596},
                    {lat: 51.9115396390844, lng:-0.385371899137112},
                    {lat: 51.8756431849685, lng:-0.350498775159167},
                    {lat: 51.8739474946844, lng:-0.357193568860338},
                    {lat: 51.8613337917255, lng:-0.35015545240526},
                    {lat: 51.8368163993317, lng:-0.394237032444834},
                    {lat: 51.8547386835508, lng:-0.432860842259287},
                    {lat: 51.840104453352, lng:-0.463244905979991},
                    {lat: 51.8500732137816, lng:-0.4774928002671},
                    {lat: 51.8057051120858, lng:-0.5543970971421},
                    {lat: 51.8775924472208, lng:-0.592407560093079},
                    {lat: 51.891668332384, lng:-0.630516385776672},
                    {lat: 51.8909267401722, lng:-0.642876004917297},
                    {lat: 51.9003546441251, lng:-0.651630735141907},
                    {lat: 51.9007783236945, lng:-0.675663327915344},
                    {lat: 51.9110513299895, lng:-0.700725888950501}
                ];

                //Construct the polygon.
                var AreaOutside = new google.maps.Polygon({
                    paths: Area,
                    strokeColor: '#000000',
                    strokeOpacity: 0.8,
                    strokeWeight: 1,
                    fillColor: '#ffffff',
                    fillOpacity: 0
                });


                AreaOutside.setMap(map);

                marker.addListener('click', function() {
                    infoWindow.setContent(infowincontent);
                    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() {}

我认为聚类最适合我拥有的大量单个标记。我是谷歌地图的新手,所以任何指导/帮助将不胜感激。当我运行此代码时,控制台中会出现各种 Javascript 错误:

如:

markerclusterer.js:653 Uncaught TypeError: marker.getPosition is not a function
    at MarkerClusterer.isMarkerInBounds_ (markerclusterer.js:653)
    at MarkerClusterer.createClusters_ (markerclusterer.js:790)
    at MarkerClusterer.setReady_ (markerclusterer.js:534)
    at MarkerClusterer.onAdd (markerclusterer.js:224)
    at Qu.draw (overlay.js:3)
    at Ru.Jb (overlay.js:4)
    at eu (map.js:38)
    at map.js:41

标签: javascriptgoogle-maps

解决方案


您在创建标记对象之前添加marker到。markerClusterer由于这个原因,一个空/空对象正在到达没有 getPosition 函数的 markerClusterer。

您需要将markerClusterer.addMarker方法移到创建标记之后,如下所示。

// inside the loop
markerClusterer.addMarker(marker); // Move this line


var text = document.createElement('text');
text.textContent = address
infowincontent.appendChild(text);
var icon = customLabel[type] || {};
var marker = new google.maps.Marker({
    map: map,
    position: point,
    label: icon.label
});

var text = document.createElement('text');
text.textContent = address
infowincontent.appendChild(text);
var icon = customLabel[type] || {};
var marker = new google.maps.Marker({
    map: map,
    position: point,
    label: icon.label
});

    // inside the loop
markerClusterer.addMarker(marker); // Move it here

在创建markerClusteredmarkers对象之前,未初始化相似数组。您可以创建一个空白数组以传递给函数,如下所示。

var markersArray = new Array();

var markerClusterer = new MarkerClusterer(map, markersArray , {imagePath: "../img/icons/markerclusterer/m"});

当我浏览剩余的代码时,还有很多问题。移动了一些代码并在 CAPS 中添加了带有前缀“J -”的注释

下面的代码解决了我注意到的一些问题。但是,当您从 PHP 页面获取数据时,代码没有经过测试。

function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
    center: new google.maps.LatLng(51.93916880428746, -0.504345273716126),
    zoom: 11
});
var infoWindow = new google.maps.InfoWindow;



// Change this depending on the name of your PHP or XML file
// var mapxmlloc = '../maps/GenerateMarkers.php?type=area&town=' + $("#viewtown").val();
downloadUrl('../maps/GenerateMarkers.php?type=area', function(data) {

    // J - INITIALIZE MARKERS ARRAY AND BOUNDS BEFORE THE LOOP ITERATION
    var markersArray = new Array()
    var bounds = new google.maps.LatLngBounds();

    var xml = data.responseXML;
    var markers = xml.documentElement.getElementsByTagName('marker');

    Array.prototype.forEach.call(markers, function(markerElem) {
        var id = markerElem.getAttribute('id');
        var name = markerElem.getAttribute('name');
        var address = markerElem.getAttribute('address');
        var type = markerElem.getAttribute('type');
        var point = new google.maps.LatLng(
                parseFloat(markerElem.getAttribute('lat')),
                parseFloat(markerElem.getAttribute('lng')));

        var infowincontent = document.createElement('div');
        var strong = document.createElement('strong');
        strong.textContent = name
        infowincontent.appendChild(strong);
        infowincontent.appendChild(document.createElement('br'));

        var text = document.createElement('text');
        text.textContent = address
        infowincontent.appendChild(text);
        var icon = customLabel[type] || {};
        var marker = new google.maps.Marker({
            map: map,
            position: point,
            label: icon.label
        });

        // J - ADD LISTENER IMMEDIATELY AFTER ADDING 
        marker.addListener('click', function() {
            infoWindow.setContent(infowincontent);
            infoWindow.open(map, marker);
        });

        // J - ADD MARKER TO THE ARRAY. 
        markersArray.push(marker);

        // J - ADD POINT TO EXTEND THE BOUNDS 
        bounds.extend(point);

    }); // J - END FOR EACH ITERATION HERE

    // J - CREATE MARKER CLUSTER USING THE MARKERS ARRAY 
    var markerClusterer = new MarkerClusterer(map, markersArray, {imagePath: "../img/icons/markerclusterer/m"});

    // J - FIT THE BOUNDS TO THE MAP JUST ONCE OUTSIDE THE LOOP
    map.fitBounds(bounds);

    // THE AREAOUTSIDE POLYGON NEEDS TO BE GREATED JUST ONCE, SO MOVED IT OUT OF THE LOOP
    // Define the LatLng coordinates for the polygon's path.
    var Area = [
        {lat: 51.9111974504221, lng:-0.700698528012367},
        {lat: 52.0351347507547, lng:-0.643706950863929},
        {lat: 52.018657752549, lng:-0.576415691098304},
        {lat: 52.0317553486016, lng:-0.511871013363929},
        {lat: 52.0258407801943, lng:-0.426726970395179},
        {lat: 52.0359795613826, lng:-0.350509319027992},
        {lat: 51.9970768309839, lng:-0.356143903446877},
        {lat: 51.9860834929546, lng:-0.366786908817971},
        {lat: 51.9594345951621, lng:-0.372966718388283},
        {lat: 51.9607039496942, lng:-0.391506147099221},
        {lat: 51.9426122542336, lng:-0.390132856083596},
        {lat: 51.9115396390844, lng:-0.385371899137112},
        {lat: 51.8756431849685, lng:-0.350498775159167},
        {lat: 51.8739474946844, lng:-0.357193568860338},
        {lat: 51.8613337917255, lng:-0.35015545240526},
        {lat: 51.8368163993317, lng:-0.394237032444834},
        {lat: 51.8547386835508, lng:-0.432860842259287},
        {lat: 51.840104453352, lng:-0.463244905979991},
        {lat: 51.8500732137816, lng:-0.4774928002671},
        {lat: 51.8057051120858, lng:-0.5543970971421},
        {lat: 51.8775924472208, lng:-0.592407560093079},
        {lat: 51.891668332384, lng:-0.630516385776672},
        {lat: 51.8909267401722, lng:-0.642876004917297},
        {lat: 51.9003546441251, lng:-0.651630735141907},
        {lat: 51.9007783236945, lng:-0.675663327915344},
        {lat: 51.9110513299895, lng:-0.700725888950501}
    ];

    //Construct the polygon.
    var AreaOutside = new google.maps.Polygon({
        paths: Area,
        strokeColor: '#000000',
        strokeOpacity: 0.8,
        strokeWeight: 1,
        fillColor: '#ffffff',
        fillOpacity: 0
    });

    AreaOutside.setMap(map);
});
}

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

推荐阅读