Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
270 views
in Technique[技术] by (71.8m points)

php - google map info window multiple addresses via xml

I'm using the Google map code below to retrieve and plot markers for multiple addresses from an XML file dynamically created with PHP. The code is doing everything I need except for displaying the correct information in the Google map info window for the corresponding marker. I get the information of the last XML item/listing for all the markers.

I've been searching and trying different variations to get it to work, but no luck.

sample XML data

<?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 map code

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);
                    });
            });
        }
    });
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have a problem with the asynchronous nature of the geocoder, and if you add many addresses you will have a problem with the geocoder quota/rate limits (particularly since your code doesn't look at the return status of the geocoder).

All these questions are related:

The simplest solution is to use function closure to associate the call to the geocoder with the returned result:

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

And a createMarker function to associate the infowindow content with the marker:

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

Makes your for loop:

for (var i = 0; i < markers.length; i++)
{
  geocodeAddress(markers[i]);
}

Working example


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...