Я использую код карты Google ниже для извлечения и построения маркеров для нескольких адресов из файла XML, динамически созданного с помощью PHP. Код делает все, что мне нужно, за исключением отображения правильной информации в информационном окне карты Google для соответствующего маркера. Я получаю информацию о последнем элементе XML / листинге для всех маркеров.
Я искал и пробовал разные варианты, чтобы заставить его работать, но не повезло.
примеры данных XML
<?xml version="1.0" encoding="UTF-8"?> <listings> <listing> <address>123 Street</address> <city>MANOTICK</city> </listing> <listing> <address>456 Street</address> <city>MANOTICK</city> </listing> <listing> <address>111 Avenue</address> <city>MANOTICK</city> </listing> <listing> <address>777 Avenue</address> <city>Ottawa</city> </listing> <listing> <address>333 Street</address> <city>Manotick</city> </listing> </listings>
код карты google
function initialize () { var myLatLng = new google.maps.LatLng(45.2340684, -75.6287287); var myOptions = { zoom: 10, mapTypeControl: true, center: myLatLng, zoomControl: true, zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL }, StreetViewControl: false, mapTypeId: google.maps.MapTypeId.ROADMAP } var map = new google.maps.Map(document.getElementById('google_map'), myOptions); var info_window = new google.maps.InfoWindow; google.maps.event.addListener (map, 'click', function () { info_window.close(); }); downloadUrl ('listings.xml', function (listings_data) { var markers = listings_data.documentElement.getElementsByTagName('listing'); var geocoder = new google.maps.Geocoder(); for (var i = 0; i < markers.length; i++) { var address = markers[i].getElementsByTagName('address')[0].firstChild.data; var city = markers[i].getElementsByTagName('city')[0].firstChild.data; var address_google_map = address + ', ' + city + ', ON'; var info_text = address + '<br />' + city + ' ON'; geocoder.geocode ({'address': address_google_map}, function (results) { var marker = new google.maps.Marker ({ map: map, position: results[0].geometry.location }); google.maps.event.addListener (marker, 'click', function() { info_window.setContent(info_text); info_window.open(map, marker); }); }); } }); }
У вас возникла проблема с асинхронным характером геокодера, и если вы добавите много адресов, у вас будет проблема с ограничениями квоты / скорости геокодера (в частности, поскольку ваш код не смотрит на статус возврата геокодера).
Все эти вопросы связаны:
Самое простое решение – использовать закрытие функции для связывания вызова с геокодером с возвращенным результатом:
geocodeAddress(xmldata) { var address = xmldata.getElementsByTagName('address')[0].firstChild.data; var city = xmldata.getElementsByTagName('city')[0].firstChild.data; var address_google_map = address + ', ' + city + ', ON'; var info_text = address + '<br />' + city + ' ON'; geocoder.geocode ({'address': address_google_map}, function (results, status) { if (status == google.maps.GeocoderStatus.OK) { createMarker(results[0].geometry.location, info_text); } else { alert("geocode of "+ address +" failed:"+status); } }); }
И функция createMarker, чтобы связать содержимое infowindow с маркером:
function createMarker(latlng, html) { var marker = new google.maps.Marker ({ map: map, position: latlng }); google.maps.event.addListener(marker, 'click', function() { info_window.setContent(html); info_window.open(map, marker); }); }
Делает ваш цикл for:
for (var i = 0; i < markers.length; i++) { geocodeAddress(markers[i]); }
Рабочий пример