Web Analytics Made Easy -
StatCounter Adding Markers to googlemaps - CodingForum

Announcement

Collapse
No announcement yet.

Adding Markers to googlemaps

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Adding Markers to googlemaps

    I'm trying to get addresses from an XML doc and use them to populate a google map with markers. My problems are (A) markers don't show up when I first load the page, but if I return to the page they magically appear, angles sing and all is right with the world, and (B) Markers just flat out refuse to populate when using Firefox. My code is pretty simple and I'm just not understanding where I'm going wrong:

    seemlingly the offending code:
    Code:
    function addMarkers(){
    	
    	http.open('get', 'phoneBook.xml', true);
    	http.send(null);	
    	
    	if(http.readystate == 4){
    		var response = http.responseXML.documentElement;
    		addresses = response.getElementsByTagName("ADDRESS");
    		geocoder = new Array();
    		marker = new Array();
    		
    		for(i=0; i<addresses.length; i++){ 
    		
    		geocoder[i] = new GClientGeocoder();
    		if(geocoder[i]){
    			geocoder[i].getLatLng(
    				addresses[i].firstChild.data,
    					function(point){
    						if(!point){
    							alert(addresses[i].firstChild.data + " Not found");
    							
    						}else{
    							marker[i] = new GMarker(point);
    							map.addOverlay(marker[i]);
    														
    							}
    						}
    					);
    				}
    			}}
    		}
    Whole thing:
    Code:
    <html>
    <head>
        
    <style type = "text/css">
    
    
    
    </style>
    
    <script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA7PRkqszxkPFQEQke6-qyRhTlY7DIGOPhKEx8ClHy7ZG44m2OIBRPjmzVobqXHENzFZzaybI5ZnXE1A" type="text/javascript">
    </script>
    
    <script type = "text/javascript">
    
    	var map = null;
    	var geocoderC = null;
    	
    
    
    function load() {
       if (GBrowserIsCompatible()) {
         map = new GMap2(document.getElementById("map"));
         map.addControl(new GSmallMapControl());
    	 map.addControl(new GMapTypeControl());
    	 map.setCenter(new GLatLng(37.4419, -122.1419), 5);
         geocoder = new GClientGeocoder();
    	 addMarkers();
       }
    }
    
    			
    	function showAddress(address){
    		var geocoderC = new GClientGeocoder();
    		if(geocoderC){
    			geocoderC.getLatLng(
    				address,
    					function(point){
    						if(!point){
    							alert(address + " Not found");
    							
    						}else{
    							map.setCenter(point, 13);
    														
    							}
    						}
    					);
    				}
    			}
    
    	function addMarkers(){
    	
    	http.open('get', 'phoneBook.xml', true);
    	http.send(null);	
    	
    	if(http.readystate == 4){
    		var response = http.responseXML.documentElement;
    		addresses = response.getElementsByTagName("ADDRESS");
    		geocoder = new Array();
    		marker = new Array();
    		
    		for(i=0; i<addresses.length; i++){ 
    		
    		geocoder[i] = new GClientGeocoder();
    		if(geocoder[i]){
    			geocoder[i].getLatLng(
    				addresses[i].firstChild.data,
    					function(point){
    						if(!point){
    							alert(addresses[i].firstChild.data + " Not found");
    							
    						}else{
    							marker[i] = new GMarker(point);
    							map.addOverlay(marker[i]);
    														
    							}
    						}
    					);
    				}
    			}}
    		}
    
    
    	function createRequestObject(){
    		var ro;
    		var browser = navigator.appName;
    		if(browser == "Microsoft Internet Explorer"){
    			ro = new ActiveXObject("Microsoft.XMLHTTP");
    		}else{
    			ro = new XMLHttpRequest();
    		}
    		return ro;
    	}
    	
    	var http = createRequestObject();
    	
    	function sndReq(){
    		http.open('get', 'phoneBook.xml', true);
    		http.onreadystatechange = handleResponse;
    		http.send(null);				
    	}
    		
    	function handleResponse(){
    		
    		if(http.readyState == 4){
    			document.getElementById("theName").innerHTML = ""
    			document.getElementById("address").innerHTML = ""
    			document.getElementById("phone").innerHTML = ""
    			document.getElementById("email").innerHTML = ""
    			
    			var response = http.responseXML.documentElement;
    			listings = response.getElementsByTagName("LISTING");
    			
    				for(i=0; i<listings.length; i++) {
    					
    					firstobj = listings[i].getElementsByTagName('FIRST');
    					
    					if(firstobj[0].firstChild.data == document.getElementById("first").value){
    					
    						firstobj = listings[i].getElementsByTagName("FIRST");
    					     lastobj = listings[i].getElementsByTagName("LAST");
    				    	phoneobj = listings[i].getElementsByTagName("PHONE");
    					  addressobj = listings[i].getElementsByTagName("ADDRESS");
    						emailobj = listings[i].getElementsByTagName("EMAIL");
    						
    					document.getElementById("theName").innerHTML = firstobj[0].firstChild.data + " " + lastobj[0].firstChild.data;
    					document.getElementById("address").innerHTML = addressobj[0].firstChild.data;
    					document.getElementById("phone").innerHTML = phoneobj[0].firstChild.data;
    					document.getElementById("email").innerHTML = emailobj[0].firstChild.data;
    					
    					theAddress = addressobj[0].firstChild.data;
    					showAddress(theAddress);
    					
    				}
    			}
    		}
    	}
    					
    
    
    
    </script>
    	
    	</head>
    	<body onLoad="load()" onUnload="GUnload()">
        	<form id="search">
            	<input type="text" id="first">
                <input type="button" value="Search Phonebook" onClick="sndReq();">
            </form>
            <div id="theName"></div>
            <div id="address"></div>
            <div id="phone"></div>
            <div id="email"></div>
            <div id="map" style="width: 500px; height: 300px;"></div>
    	
    	</body>
    </html>
    Last edited by mixelplik; Apr 8, 2009, 01:35 AM. Reason: clarification

  • #2
    Can you please try wrapping your code in [ code ] ... [ /code ] tags, as suggested by one of the "sticky" posts at the head of the forum? I find it just too hard to follow as it is now.

    Hmmm...I sure do admit I don't see it. Only thing I can think of is that the geocoder is taking too long to return the info???

    Have you tried plopping some info into a <DIV>, via innerHTML, just to see when the geocoder has completed it's work on each address?
    Be yourself. No one else is as qualified.

    Comment


    • #3
      Sorry still learning the ropes, I added the [code] tags.

      Yeah, I've been using the innerHTML (those <divs> at the bottom of the code) to try and display where the wheels are falling off. It seems to be fine until it hits that (if http.readystate == 4) in the addMarker function. Like I said, marker won't load in IE until you refresh the page, and then everything works great. Once you hit Firefox, safari or OPERA the Markers will not generate. Also if I add a marker to the display address function it will work just fine. It's the inital auto populating thats throwing me.

      Comment


      • #4
        AMAZING how indenting code makes it so much easier to see the bugs!

        It's really obvious if you look again.

        Code:
        function addMarkers(){
        	
        	http.open('get', 'phoneBook.xml', true);
        	http.send(null);	
        	
        	if(http.readystate == 4){
                   ...
        Compare that code to this:
        Code:
               function sndReq(){
        		http.open('get', 'phoneBook.xml', true);
        		http.onreadystatechange = handleResponse;
        		http.send(null);				
        	}
        		
        	function handleResponse(){
        		if(http.readyState == 4){
                             ...
        Do you see it?? In the bogus code, you check for the ready state *IMMEDIATELY* after the send! WITHOUT WAITING for a response from the server!

        You *NEED* to have the onreadystatechange handler specified! Always!

        So:
        Code:
        function addMarkers(){
        	
        	http.open('get', 'phoneBook.xml', true);
                [COLOR="Red"]http.onreadystatechange = handleMarkerResponse;[/COLOR]
        	http.send(null);	
        [COLOR="Red"]}
        
        function handleMarkerRespons( ) {
        [/COLOR]	if(http.readystate == 4){
                   ...
        And this explains why it works on refresh: By then, the browser has already got the "phonebook.xml" in its cache and so indeed the readystate *is* 4! But it's not surprising that not all browsers would work that way. They might opt not to cache files obtained via the http object.
        Be yourself. No one else is as qualified.

        Comment


        • #5
          Not to ask a dumbass question, but *WHY* do you go get "phonebook.xml" *TWICE*???

          Surely it's not going to change between the two fetches???

          And for that matter, if it's a local file, on the same server as the HTML page, why not just use ".shtml" (or ".php" or or or) and #include it as text right into the HTML page, instead of having to go read it with the clumsy http object??

          Or is this just preliminary? Eventually you'll get different xml files from different sources?
          Be yourself. No one else is as qualified.

          Comment


          • #6
            LOL - Not a dumbass question in the least, it all started much better looking, but sadly as I frustration grew so did the ugliness of the code. Also, a lot of what I'm doing may look inefficient, but I'm just learning and more focused on seeing what I can and can't do. I'm planning on having users enter info and haveing a perl script write it to a text document, and then people can retreive that info. I'm not planning to use it for anything, just help myself understand how these technologies work.

            Thanks so much for your help - I love making stupid mistakes, beacuase now I'll never make them again..

            It now works swimmingly

            Comment


            • #7
              Okay, makes lots of sense. So you'll take their answers and send them off to an AJAX server to get back the XML needed for the markers. Glad the fix was that easy!
              Be yourself. No one else is as qualified.

              Comment


              • #8
                Code:
                addresses = response.getElementsByTagName("ADDRESS");
                		geocoder = new Array();
                		marker = new Array();
                		
                		for(i=0; i<addresses.length; i++){ 
                		
                		geocoder[i] = new GClientGeocoder();
                		if(geocoder[i]){
                			geocoder[i].getLatLng(
                				addresses[i].firstChild.data,
                A couple of comments on the code shown; you only need one geocoder object, not N. Also, you want to be careful about running too many calls to the geocode object in a loop, that's a good way to get your API key limited or banned. Check the Google Maps API section on Geocoding for details. At the very least, do something to improve your loop, e.g.
                Code:
                var geo= new GClientGeocoder();
                var i,
                    len= addresses.length;
                for ( i=0; i < len; i++ ) {
                
                }
                Two other (relatively) big factors to consider; the use of JSON instead of XML, and/or using Google's built-in GGeoXml object to retrieve that data in a more simple, efficient way.

                Comment

                Working...
                X