I want to start by saying I know this question has been asked in the past, but I was unable to get the old answers to work. I've been fighting with Google Maps Markerclusterer for the last 7 hours. I am relatively new to Javascript and have been able to build Google maps for my online directory fine. I found Makerclusterer and thought it would be the perfect solution to my too many marker issue. The problem is, I only know how to read from XML and the example code for this reads from JSON. After trying for a few hours to get it to read from XML I figured I could simply convert my XML into JSON format and that would be an easy fix, but that did not work either.

Here's the MarkerClusterer example that we all know and love running fine on my server: (cluster file)

Here's my dynamically generated XML file (it contains city names, lon, and lat coords): (XML file)

Below is the example MarkerClusterer code. I've read dozens of "just throw the marker points into an array and feed it to the clusterer" comments but I've failed miserably about a dozen times now. Any input is appreciated.

<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/data.json">
</script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js"></script>

<script type="text/javascript">
  function initialize() {
    var center = new google.maps.LatLng(37.4419, -122.1419);

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 3,
      center: center,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var markers = [];
    for (var i = 0; i < 100; i++) {
      var dataPhoto = data.photos[i];
      var latLng = new google.maps.LatLng(dataPhoto.latitude,
          dataPhoto.longitude);
      var marker = new google.maps.Marker({
        position: latLng
      });
      markers.push(marker);
    }
    var markerCluster = new MarkerClusterer(map, markers);
  }
  google.maps.event.addDomListener(window, 'load', initialize);
</script>
有帮助吗?

解决方案

Well, if you must use xml the good news is it's not that much more difficult. Accessing xml elements works a lot like accessing the normal DOM with a number of differences.

One thing to look out for is that all data coming from xml is a string, so where Number's are required you must convert to Number type. Such as when dealing with lat & lon values when creating google.maps.LatLng and such. And as far as loading the xml to be read, we'll use ajax for the loading of that.

I threw together an example, with some extra utility (note the select for picking different states, as well as the markers are clickable to show an info window) for you to peruse. I threw in the jQuery library just to simplify the ajax request code, though the jQuery could be used as well for other things within the code which I did not take the time to convert. I am curious, what is the 'count_unverified' in the xml? Well, enjoy!

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Google Maps MarkerClusterer</title>
<style type="text/css">
.map-infowindow {
    border:3px ridge blue;
    padding:6px;
}
</style>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript">

function initialize(elementId, stateAbbr) {
    var callback = function (data, status, xhr) {
        //data will be the xml returned from the server
        if (status == 'success') {
            createMap(elementId, data);
        }
    };
    //using jQuery to fire off an ajax request to load the xml,
    //using our callback as the success function
    $.ajax(
        {
            url : 'http://historyads.com/xml_state.php',
            data : 'state='+ stateAbbr,
            dataType : 'xml',
            success : callback
        }
    );
}

function createMap(elementId, xml) {
    var i, xmlMarker, lat, lng, latLng,
        map = new google.maps.Map(
            document.getElementById(elementId),
            {
                mapTypeId: google.maps.MapTypeId.ROADMAP
            }
        ),
        infoWindow = new google.maps.InfoWindow({maxWidth:200}),
        xmlMarkers = xml.getElementsByTagName('marker'),
        markers = [],
        latlngs = [],
        bounds = new google.maps.LatLngBounds();
    //private function, for scope retention purposes
    function createMarker(latlng, name, count_unverified) {
        latlngs.push(latlng);
        var marker = new google.maps.Marker({
            position: latlng,
            map: map
        });
        google.maps.event.addListener(
            marker,
            "click",
            function () {
                var info = '<div class="map-infowindow"><h4 class="map-info-title">';
                info += name +'</h4><p class="map-info-content">count_unverified: ';
                info += count_unverified +'</p>';
                infoWindow.setContent(info);
                infoWindow.open(map, marker);
            }
        );
        markers.push(marker);
    }
    for (i = 0; i < xmlMarkers.length; i++) {
        xmlMarker = xmlMarkers[i];
        //lat & lng in the xml file are strings, convert to Number
        lat = Number(xmlMarker.getAttribute('lat'));
        lng = Number(xmlMarker.getAttribute('lng'));
        latLng = new google.maps.LatLng(lat, lng);
        createMarker(
            latLng,
            xmlMarker.getAttribute('name'),
            xmlMarker.getAttribute('count_unverified')
        );
    }
    markerCluster = new MarkerClusterer(map, markers);
    for (i = 0; i < latlngs.length; i++) {
        bounds.extend(latlngs[i]);
    }
    map.fitBounds(bounds);
    return map;
}

function buildStatesSelect() {
    var i,
        select = document.getElementById('stateSelect'),
        states = [
            'AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL',
            'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME',
            'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH',
            'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI',
            'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY'
        ],
        len = states.length;
    for (i = 0; i < len; i++) {
        addOption(select, new Option(states[i], states[i]));
    }
    select.onchange = function () {
        var opt = this.options[this.options.selectedIndex];
        if (opt.value != '') {
            initialize('map', opt.value);
        }
    };
}

function addOption(select, option) {
    try {
        select.add(option,null); //standard method
    } catch(er) {
        select.add(option); //IE only
    }
}

google.maps.event.addDomListener(
    window,
    'load',
    function () {
        initialize('map', 'FL');
        buildStatesSelect();
    }
);

</script>
</head>
<body>
<div id="map" style="width:500px; height:500px;"></div>
<select id="stateSelect">
<option value="">Select State</option>
</select>
</body>
</html>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top