Google Maps Markerclusterer не загружается из XML

Я хочу начать с того, что знаю, что этот вопрос задавали в прошлом, но мне не удалось заставить старые ответы работать. Я боролся с Google Maps Markerclusterer последние 7 часов. Я относительно новичок в Javascript и смог создать карты Google для своего онлайн-каталога. Я нашел Makerclusterer и подумал, что это идеальное решение моей проблемы со слишком большим количеством маркеров. Проблема в том, что я умею читать только из XML, а пример кода для этого читается из JSON. После нескольких часов попыток заставить его читать из XML я решил, что могу просто преобразовать свой XML в формат JSON, и это было бы легко исправить, но это тоже не сработало.

Вот пример MarkerClusterer, который мы все знаем и любим, отлично работает на моем сервере: (файл кластера)

Вот мой динамически сгенерированный XML-файл (он содержит названия городов, долготу и широту): (XML-файл)

Ниже приведен пример кода MarkerClusterer. Я прочитал десятки комментариев «просто бросьте маркерные точки в массив и передайте их кластеризатору», но я с треском провалился около дюжины раз. Любой вклад приветствуется.

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

person user2246930    schedule 22.04.2013    source источник


Ответы (1)


Хорошо, если вы должны использовать xml, хорошая новость заключается в том, что это не намного сложнее. Доступ к элементам xml очень похож на доступ к обычному DOM с рядом отличий.

Следует обратить внимание на то, что все данные, поступающие из xml, представляют собой строку, поэтому там, где требуются числа, вы должны преобразовать их в числовой тип. Например, при работе со значениями широты и долготы при создании google.maps.LatLng и т. д. А что касается загрузки xml для чтения, мы будем использовать ajax для его загрузки.

Я собрал пример с некоторой дополнительной утилитой (обратите внимание на выбор для выбора различных состояний, а также на маркеры, на которые можно щелкнуть, чтобы показать информационное окно), чтобы вы могли их просмотреть. Я добавил библиотеку jQuery только для того, чтобы упростить код запроса ajax, хотя jQuery можно было использовать и для других вещей в коде, на преобразование которых я не тратил время. Мне любопытно, что такое «count_unverified» в xml? Ну, наслаждайтесь!

<!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>
person astupidname    schedule 22.04.2013
comment
Большое спасибо, astupidname! Это сработало идеально. count_unverified — это просто количество магазинов в данном городе. - person user2246930; 22.04.2013