Ajax and Ajax Frameworks

I have been a developer for nearly 20 years and a web developer for about 10 years. Over the years, I have considered creating a blog to share the things I have learned (and am learning) about web design and development, but I never seemed to have the time. When I began learning about web development using Ajax and Ajax Frameworks, I decided to take the time to create this blog.

My intention for this blog is to focus primarily on Ajax Frameworks, but since web development requires knowledge of many technologies, I will occasionally write about things such as CSS, Javascript, PHP, MySQL, Flash, etc.

Lately, I have been using JQuery as my primary Ajax tool. Although I have used other Ajax Frameworks in the past (Dojo Toolkit, Yahoo! User Interface Library, Scriptaculous/Prototype), JQuery has thus far been the easiest to learn. In my first few posts I will discuss some of the JQuery Plugins that I have created. Some of these include: a plugin for Google Maps (jquery.imGoogleMaps), Form validation and submission  (jquery.imValidateForm), Page Populater (jquery.imPagePopulate), and a plugin to create lists (jquery.imList).

While I am still learning about some of the other Ajax Frameworks, I hope that what I have learned will be helpful to others. Just remember, “When you can pull the pebbles from my hand…”

Share

Google Maps: Using JQuery to Display Multiple Addresses

Saturday, November 28th, 2009

I have recently been updating the JQuery imGoogleMaps Plugin that I created earlier this year. The new version of the plugin will display multiple addresses on a Google Map. I’ll discuss the updated version of the imGoogleMaps plugin in another post. In this post, I’ll discuss how to use JQuery to load multiple addresses from Json data.

Before using the Google Maps API, you need to get an API key.

Add the key to the head section of your html page.

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=..." type="text/javascript"></script>

Now create a container for your map.

<div id="myMap"></div>

Creating The Map

To create a basic map using Javascript is quite simple:

?View Code JAVASCRIPT
var map;
// check if browser is compatible with Google Maps
if (GBrowserIsCompatible()) {
        // create map in the 'myMap' div 
	map = new GMap2(document.getElementById('myMap'));
        // add map controls
	map.addControl(new GSmallMapControl());
	map.addControl(new GMapTypeControl());
 
        //add default icon
	baseIcon = new GIcon(G_DEFAULT_ICON);
	baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
	baseIcon.iconSize = new GSize(20, 34);
	baseIcon.shadowSize = new GSize(37, 34);
	baseIcon.iconAnchor = new GPoint(9, 34);
	baseIcon.infoWindowAnchor = new GPoint(9, 2);
}

Creating a Single Marker Using Latitude and Longitude

Creating markers on a Google Map from latitudes and longitudes is much more straightforward than when using an actual address:

?View Code JAVASCRIPT
// create Geocoder client
var geocoder = new GClientGeocoder();
// Stargate SG-1
var lat = 40.730885;
var lng = -73.997383
// use 'map' object that we created above to center the map
map.setCenter(new GLatLng(lat,lng), 15);
// create a point using the latitude and longitude
// we need the point to create a marker
var point = new GLatLng(lat,lng);
var marker = new GMarker(point);
// add marker to overlay
map.addOverlay(marker);
// display latitude and longitude in the display window that appears when a user clicks on the marker
var address = 'Latitude: '+ lat + ', Longitude: ' + lng;
marker.bindInfoWindowHtml('<p style="color:#000; font-size:11px;">'+address+'</p>');

Creating a Single Marker Using an actual Address

Creating a marker using an address is a bit more involved because we have to created the marker ourselves.

?View Code JAVASCRIPT
var geocoder = new GClientGeocoder();
// Bob Marley's birth place
var address = 'Nine Mile, Saint Ann Parish, Jamaica, West Indies';
geocoder.getLatLng(
	address,
	function(point) {
       		if (!point) {
       			alert(address + " not found");
       		} else {
			map.setCenter(point, 15);
                        // call createMarker function
			map.addOverlay(createMarker(address, point, 1));
       		}
	}
);
// createMarker function
// Needs the address, the point returned from geocoder.getLatLang, 
// and an index needed for multiple markers
function createMarker(address, point, index) {
	  // Create a lettered icon for this point using our icon class
	  var letter = String.fromCharCode("A".charCodeAt(0) + index);
	  var letteredIcon = new GIcon(baseIcon);
	  letteredIcon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
 
	  // Set up our GMarkerOptions object
	  markerOptions = { icon:letteredIcon };
          // Create marker
	  var marker = new GMarker(point, markerOptions);
	  marker.bindInfoWindowHtml('<p style="color:#000; font-size:11px;">'+address+'</p>');	
         // return the marker
	  return marker;
}

It’s a bit more involved but not difficult.

Using JQuery to Create Multiple Markers

The JSON File
Now let’s use JQuery to retrieve addresses from a json file and use these values to create markers on a map. I am still using my the map interface that I created earlier. I’m going to load a php file that contains json data.

$json = '[';
   	$json .= '{"address": "Capitol Building, Washington, DC"},';
	$json .= '{"address": "Constitution Ave NW & 15th St NW Washington, DC 20024"},';
	$json .= '{"address": "17th St NW & Independence Ave Washington, DC 20006"},';
	$json .= '{"address": "Lincoln Memorial Cir SW Washington, DC 20037"},';
	$json .= '{"address": "Constitution Ave NW & Henry Bacon Dr NW Washington, DC 20001"}';
	$json .= ']';
	echo $json;

Retrieving Addresses
First I need to create a Javascript object to store all of my addresses. I’m doing this because I don’t want to create markers until I have loaded all of the addresses.

?View Code JAVASCRIPT
// Create GeoCoder Client
var geocoder = new GClientGeocoder();
// aLatLng is an array that will store all values in the imLatLngs <a href="http://grasshopperpebbles.com/javascript/the-javascript-object/" target="_blank">Javascript Object</a>
var aLatLng = new array();
function imLatLngs(lat, lng) {
	this.lat = lat;
	this.lng = lng;
}

Now I need to retrieve the addresses. I’m going to retrieve the addresses ajaxally using a standard function that I use in all of my plugins.

?View Code JAVASCRIPT
// the php file
var url = 'washingtondc.php';
// call my standard ajax function. Once the data is retrieved, call the <strong>getLatLngs</strong> function
doAjax('GET', url, '', '', getLatLngs);
 
// my standard function
function doAjax(t, u, d, fnBefore, fnSuccess) {
	$.ajax({
		type: t,
		url: u,
		data: d,
		dataType: 'text',
		beforeSend: fnBefore, 
		success: fnSuccess
 	}); //close $.ajax(
};
 
// on success, call <strong>getLatLngs</strong>
function getLatLngs(response) {
        // get the number of addresses. This value is used to let the getAdrLocations know
        // that all the addresses have been loaded
        adr_cnt  = address.length;
 
        // loop through each address
        $.each(response, function(i, itm) {
                // call the getAdrLocations function
		getAdrLocation(itm.address, adr_cnt, i);
	});
}
 
function getAdrLocation(adr, adr_cnt, cnt) {
        // call google maps getLocations method
	geocoder.getLocations(adr, function(response) {
		if (!response || response.Status.code != 200) {
	    		alert("Sorry, we are unable to gecode address: " + adr);
	  	} else { 
                        // see <strong>Note</strong> regarding getLocations response
		    	var place = response.Placemark[0];
 
                        // store latitude and longitude in array
                        // see http://grasshopperpebbles.com/javascript/the-javascript-object/
			aLatLng[cnt] = new imLatLngs(place.Point.coordinates[1], place.Point.coordinates[0]);
 
                        // if the array length is equal the total items in the json object
			if (aLatLng.length == adr_cnt) {
				mapAddress();
			}
	  	}
	});
}
 
function mapAddress() {
       //set bounds	
	bounds = new GLatLngBounds();
	$.each(aLatLng, function(i, itm){
	    	bounds.extend(new GLatLng(itm.lat, itm.lng));
        });
	var latSpan = bounds.toSpan().lat();
	map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
	var newBounds = map.getBounds();
	var newLatSpan = newBounds.toSpan().lat();
	if (latSpan/newLatSpan > .90) { map.zoomOut(); }
 
	$.each(aLatLng, function(i, itm) {
		var point = new GLatLng(itm.lat, itm.lng);
		var marker = new GMarker(point);
                map.addOverlay(marker);
	});	
}

Note: We can use the geocoder.getLocations method to access structured information about an address. In the example above, I’m using the method to get the Latitude and Longitude of an address. For more information about getLocations method, see Extracting Structured Addresses

In the mapAddress function above, the first thing we are doing is adjusting the bounds of the map using the Latitudes and Longitudes stored in the aLatLng array.

?View Code JAVASCRIPT
bounds = new GLatLngBounds();
$.each(aLatLng, function(i, itm){
    	bounds.extend(new GLatLng(itm.lat, itm.lng));
});

We then use this information to center the map and set the appropriate zoom level:

?View Code JAVASCRIPT
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

We then loop through the aLatLng array again to place the markers on the map.

?View Code JAVASCRIPT
$.each(aLatLng, function(i, itm) {
	var point = new GLatLng(itm.lat, itm.lng);
	var marker = new GMarker(point);
        map.addOverlay(marker);
});

That’s about it. As you can see, displaying multiple addresses can be quite involved. I created the imGoogleMaps plugin so that developers can take advantage of Google Maps API without getting into the weeds. I’ll discuss the plugin in a later post, after I have completed the testing. Enjoy.

Share

8 Responses to “Google Maps: Using JQuery to Display Multiple Addresses”

  • Jagis Says:

    Could you please pack up a demo for download? I’ve been looking for a great google map with multiple addresses plotted via an actual address!

    Please do reply.

    Great work.

  • admin Says:

    I created a Google Maps plugin. The next version includes this functionality. It’s almost complete. I just have to test it a bit more. I’ll send you a message when it is complete.

  • thirumalai Says:

    Hi,

    I analyze the abova google map code. It’s nice. I tried this but it’a not work.I think it’s a code integration problem for me. So please tell me easy integration method.

    Thanks ,
    Thirumalai.S

  • admin Says:

    Thirumala,
    Look at the imGoogleMap demos for integration examples. Let me know if you have questions after viewing the demos.

  • mrinal Says:

    how to show multiple address in google map using php in easy way.

  • Chris Says:

    Hi – Is there a way to change the default zoom for a map with only one marker? Right now, for my needs anyway, it would be nice to have the option of setting the zoom out just a bit to show a major intersection near the map point. Is there somewhere in the code where I can add a hardcoded zoom level for now? Thanks, what a great plugin you have developed. Much appreciated.

  • admin Says:

    Chris,
    I have finally released a new version (Version 1.0).

    Release Notes:

    Upgraded to Google Maps V3

    API key is no longer needed – ”
    Street View button control must be opted when map is initialized (show_streetview_overlay)

    Removed auto mode (mode option no longer needed)
    Removed directions option – now popup window only
    Removed show_directions_menu option – now show_directions (in infoWindow)
    Changed imBusinessName to infoWindowBusinessName and imDescription to infoWindowDescription (css)
    json is now the default data_type option (was ‘text’)
    Removed menu_class, print_class, button_class, and search options.
    Added URL to info window. class = infoWindowUrl (see item #9)
    Added show_infowindow_url option. If true (the default), url will display in info window (if exists).
    If false, url link will be added to business name (or name).
    When false, class = .infoWindowBusinessName a

    Removed mapIconMaker
    Added show_traffic and show_bicycling options
    Added kml and georss support

    data_type = ‘layer’
    For multiple layers, add: is_layer_url = true to json record

    You can view demos of the plugin here.

    I am currently developing a Drupal module based upon this plugin, but I haven’t had the time to complete it.

  • Jacek Says:

    THANK YOU FOR THIS…easiest and best tutorial I’ve read

CommentLuv badge