// JavaScript Document// defines the map containervar map = null;// This determines how far the map will pan when the North, South, East, or West buttons are pressed.// It will scroll the screen by the percentage below * the current screen width or height.var panPercentage = 0.5;// This holds all of the points to be included in the default view.  Google Maps can automatically// adjust the default view to include all of the points in this variable.var mapBounds;//////////////////////////////// zoomIn()//// This zooms the map in by 1 level// It retrieves the current zoom level and subtracts 1 from it.// maximum zoom level is 17; minimum zoom level is 0//////////////////////////////function zoomIn() {map.setZoom(map.getZoom() + 1);}////////////////////////////////// zoomOut()//// This zooms the map out by 1 level// It retrieves the current zoom level and adds 1 to it.// maximum zoom level is 17; minimum zoom level is 0//////////////////////////////function zoomOut() {map.setZoom(map.getZoom() - 1);}///////////////////////////////// setMapType()//// This sets the display type of the map.  The default map formats for standard Google Map are:// G_NORMAL_MAP// G_SATELLITE_MAP// G_HYBRID_MAP// One of these values needs to be passed into this function to set the map type.// Custom map types can be created and called through the Google Maps API.//////////////////////////////function setMapType(mapType) {	map.setMapType(mapType);}/////////////////////////////// aroundTheWorldLngSpan()//// This function adjusts calculation of the visible longitudinal span when the view crosses the // +/-180 degree line.  It insures that the width of the view (in degrees) is calculated correctly.// NE = the North-East corner of the span.// SW = the South-West corner of the span.//////////////////////////////function aroundTheWorldLngSpan(NE,SW) {	if (SW > NE) {		NE = NE + 360;				}	return Math.abs(NE - SW);}	//////////////////////////////// aroundTheWorldLngPan()//// This function adjusts the calculation for the new view point when panning East or West across// the +/-180 degree line.  It insures the map will pan correctly across this boundary.//////////////////////////////function aroundTheWorldLngPan(lng) {	if (lng < -180) {		lng = lng + 360;				}	else if (lng > 180) {		lng = lng - 360;	}	return lng;}	//////////////////////////////// limitNS(lat)//// This ensures that the map does not scroll beyond +/- 85 degrees latitudinally.// Using  +/- 90 degrees as a limit creates a problem.  The spherical coordinates// become so flattened out at the extreme norhtern and southern boundaries// it takes a lof of N-S movement to change 1 degree.  (At least this what I'm assuming// the problem is.)//////////////////////////////function limitNS(lat) {	if (lat > 85) {		lat = 85;	}	else if (lat < -85) {		lat = -85;	}	return lat;}////////////////////////// lngSpan()//// This calculates the latitudinal span of the current view.// It takes into account calculating across the +/- 180 degree line.//////////////////////////////function lngSpan() {	var bounds = map.getBounds(); // the boundary coordinates for the current view	var southWest = bounds.getSouthWest(); // the South-West corner of the boundary	var northEast = bounds.getNorthEast(); // the North-East corner of the boundary	return aroundTheWorldLngSpan(northEast.lng(), southWest.lng());}///////////////////////// latSpan()//// This calculates the latitudinal span of the current view.//////////////////////////////function latSpan() {	var bounds = map.getBounds(); // the boundary coordinates for the current view	var southWest = bounds.getSouthWest(); // the South-West corner of the boundary	var northEast = bounds.getNorthEast(); // the North-East corner of the boundary	return Math.abs(northEast.lat() - southWest.lat());		}	/////////////////////////// panWest()//// This function will pan the map West by a set % of the current visible width.// The percentage is set in the variable panPercentage.// It takes the current visible longitudinal span, multiplies it by panPercentage, and pans the map to the new longitudinal location// The pan will be smooth if the new location is in the current view.//// NOTE: When the map is zoomed nearly all the way out, the panWest() will actually appear to move East.// This is presumable because when Google Maps receives the new coordinates for the center,// It is actually shorter to pan to the East rather than to the West, even though the coordinates// given are to the West.//////////////////////////////function panWest () {	map.panTo(new GLatLng(map.getCenter().lat(), aroundTheWorldLngPan(map.getCenter().lng() - (lngSpan() * panPercentage))));}///////////////////////////// panEast()//// This function will pan the map East by a set % of the current visible width.// The percentage is set in the variable panPercentage.// It takes the current visible longitudinal span, multiplies it by panPercentage, and pans the map to the new longitudinal location// The pan will be smooth if the new location is in the current view.//////////////////////////////function panEast () {	map.panTo(new GLatLng(map.getCenter().lat(), aroundTheWorldLngPan(map.getCenter().lng() + (lngSpan() * panPercentage))));}//////////////////////////////////// panNorth()//// This function will pan the map North by a set % of the current visible width.// The percentage is set in the variable panPercentage.// It takes the current visible latitudinal span, multiplies it by panPercentage, and pans the map to the new latitudinal location// The pan will be smooth if the new location is in the current view.//////////////////////////////function panNorth () {	map.panTo(new GLatLng(limitNS(map.getCenter().lat() + (latSpan() * panPercentage)), map.getCenter().lng()));}////////////////////////////////////// panSouth()//// This function will pan the map South by a set % of the current visible width.// The percentage is set in the variable panPercentage.// It takes the current visible latitudinal span, multiplies it by panPercentage, and pans the map to the new latitudinal location// The pan will be smooth if the new location is in the current view.//////////////////////////////function panSouth () {	map.panTo(new GLatLng(limitNS(map.getCenter().lat() - (latSpan() * panPercentage)), map.getCenter().lng()));}///////////////////////////////////// createMarker(baseIcon, point, index)//// This creates a pushpin based on the baseIcon.  The index defines what number// will appear on the pushpin.  The images for the pushpins with the numbers on them// must be created in advance.///////////////////////////////////function createMarker(baseIcon, point, pinLabel, infoWindow) {  var icon = new GIcon(baseIcon);  icon.image = "images/pushpins/pushpin-condoguy.gif";  var marker = new GMarker(point, icon);  GEvent.addListener(marker, "click", function() {    marker.openInfoWindowHtml("<b>" + infoWindow + "</b>");  });    return marker;}////////////////////////////////// defineCustomPushPin()//// This creates a base icon for all of our markers that specifies the// image to use, the dimensions of the image, and where to position the // message box.////////////////////////////////function defineCustomPushPin() {	var baseIcon = new GIcon();	baseIcon.iconSize = new GSize(58, 59);	baseIcon.iconAnchor = new GPoint(0, 59);	baseIcon.shadow = "images/pushpins/shadow.png";	baseIcon.shadowSize = new GSize(90, 63);	baseIcon.infoWindowAnchor = new GPoint(17, 0);	baseIcon.infoShadowAnchor = new GPoint(17, 0);	return baseIcon;}/////////////////////////////////// adjustView()//// This will adjust the view of the map to include all of the points in the bounds variable./////////////////////////////////function adjustView () {	map.setZoom(map.getBoundsZoomLevel(mapBounds));	var clat = (mapBounds.getNorthEast().lat() + mapBounds.getSouthWest().lat()) /2;	var clng = (mapBounds.getNorthEast().lng() + mapBounds.getSouthWest().lng()) /2;	map.setCenter(new GLatLng(clat,clng));}/////////////////////////////////// showAddress(address, mapPointLabel, customPushPin, infoWindow)//// This translates a street address into a set of longitude and latitude points.  It then// plots that point on the map.//// Currently it calls adjustView() after each point is plotted.  This seems to be a lot of overhead// and I think I ought to be able to call it once after all the points have been mapped.  When I // do that though it doesn't work.  I'm not sure why yet./////////////////////////////////function showAddress(address, mapPointLabel, customPushPin, infoWindow) {  geocoder = new GClientGeocoder();  geocoder.getLatLng(    address,    function(point) {      if (!point) {        alert(address + " not found");	  } else {        var marker = new GMarker(point);		map.addOverlay(createMarker(customPushPin, point, mapPointLabel, infoWindow));				// adds the point to the set of points that need to be made visible in the current view		mapBounds.extend(point);		// adjusts the view to include all the points that are supposed to be visible		adjustView();      }    }  );}////////////////////////////////// parseDOMforMapDataAndPlot()/////////////////////////////////function parseDOMforMapDataAndPlot(customPushPin) {		var	mapPointLatitude = null; // holds the latitude from the DOM parsing		var mapPointLongitude = null; // holds the longitude from the DOM parsing		var mapPointAddr = null; // holds the address from the DOM parsing				// keeps count of how many map points there are so the correct custom pushpin gets used		var mapPointsCount = 0;				// find the mapLocations div tag				var mapPoints = document.getElementById("mapLocations");		for (var i = 0; i < mapPoints.childNodes.length; i++) {			if (mapPoints.childNodes[i].className == "mapItem") {				// extract the label for the pin				mapPointLabel = mapPoints.childNodes[i].firstChild.nodeValue;				mapPointsCount ++;			}			if (mapPoints.childNodes[i].className == "mapItemData") {				for (var j = 0; j < mapPoints.childNodes[i].childNodes.length; j++) {					if (mapPoints.childNodes[i].childNodes[j].firstChild != null) {						// extract the latitude						if (mapPoints.childNodes[i].childNodes[j].className == "lat") {							mapPointLatitude = mapPoints.childNodes[i].childNodes[j].firstChild.nodeValue;						}						// extract the longitude						else if (mapPoints.childNodes[i].childNodes[j].className == "lng") {							mapPointLongitude = mapPoints.childNodes[i].childNodes[j].firstChild.nodeValue;						}						// extract the address						else if (mapPoints.childNodes[i].childNodes[j].className == "addr") {							mapPointAddr = mapPoints.childNodes[i].childNodes[j].firstChild.nodeValue;						}						// extract the sub label						else if (mapPoints.childNodes[i].childNodes[j].className == "subLabel") {							mapPointLabel += "<br />" + mapPoints.childNodes[i].childNodes[j].firstChild.nodeValue;						}						// extract the URL						else if (mapPoints.childNodes[i].childNodes[j].className == "labelLink") {							mapPointLabel += "<br />" + "<a href=\"http://"+mapPoints.childNodes[i].childNodes[j].firstChild.firstChild.nodeValue+"\">"+mapPoints.childNodes[i].childNodes[j].firstChild.firstChild.nodeValue+"</a>"						}					}				}//				var point = new GLatLng(mapPointLatitude, mapPointLongitude);				if (mapPointAddr != null) { 					// add the point from an address					showAddress(mapPointAddr, mapPointsCount, customPushPin, mapPointLabel);								}				// if no address is given, it assumes a longitude and latitude were in the DOM				else {					// add the point from a longitude and latitude					var point = new GLatLng(mapPointLatitude, mapPointLongitude);					map.addOverlay(createMarker(customPushPin, point, mapPointsCount, mapPointLabel));					// adds the point to the set of points that need to be made visible in the current view					mapBounds.extend(point);				}								// reset the variables				mapPointLatitude = null;				mapPointLongitude = null;				mapPointAddr = null;				mapPointLabel = null;			}			      	}}////////////////////////////////// load()//////////////////////////////function load() {	if (GBrowserIsCompatible()) {		// This creates an instance of the map and positions it at the		// div tag id="map" within the body of the HTML.		// The size of the map is defined by the boundary of the div tag.		map = new GMap2(document.getElementById("map"));				// adds the zoom and pan controls within the map		map.addControl(new GLargeMapControl());		// adds the "Normal", "Satellite", and "Hybrid" view buttons within the map		map.addControl(new GMapTypeControl()); 		// This centers the map on 0,0 at the maximum zoom out level.		// The coordinates are (latitude, longitude).		// The zoom level is from 0 to 17, with 0 being zoomed out, and 17 being zoomed in.		map.setCenter(new GLatLng(0,0),0);		mapBounds = new GLatLngBounds();		// parse the DOM and plot the points using a custom pushpin		parseDOMforMapDataAndPlot(defineCustomPushPin())	}}