// create the map
function displayGetSpatialMap(GetSpatialXMLfile)
{

    if (GBrowserIsCompatible()) {


      // this variable will collect the html which will eventualkly be placed in the side_bar
      // var side_bar_html = "";
    
      // arrays to hold copies of the markers and html used by the side_bar
      // because the function closure trick doesnt work there
      var gmarkers = [];
      var htmls = [];
      var i = 0;

      // A function to create the marker and set up the event window
      function createMarker(point,name,html) {
        var marker = new GMarker(point, { icon: getIcon() });
        GEvent.addListener(marker, "click", function() {
          marker.openInfoWindowHtml(html);
        });
        // save the info we need to use later for the side_bar
        gmarkers[i] = marker;
        htmls[i] = html;
        // add a line to the side_bar html
        // side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '</a><br>';
        i++;
        return marker;
      }

// Allows a custom icon to be displayed
      function getIcon()
      {
        var icon = new GIcon();
        // SMR icon
        // icon.image = "Images/SMR.png";
        // icon.iconAnchor = new GPoint(16, 16);
        // icon.infoWindowAnchor = new GPoint(16, 0);
        // icon.iconSize = new GSize(25, 30);
        // icon.shadow = "Images/SMRshadow.png";
        // icon.shadowSize = new GSize(66, 30);
        //NHE icon
          icon.image = "Images/NHEicon.png";
	  icon.iconAnchor = new GPoint(12, 34);
	  icon.infoWindowAnchor = new GPoint(13, 2);
	  icon.iconSize = new GSize(27, 40);
	  icon.shadow = "Images/NHEicon_shadow.png";
          icon.shadowSize = new GSize(48, 40);
        return icon;
      }

      // This function picks up the click and opens the corresponding info window
      function myclick(i) {
        gmarkers[i].openInfoWindowHtml(htmls[i]);
      }





<!-- WMS SCRIPT STARTS HERE -->


    /*
     * Call generic wms service for GoogleMaps v2
     * John Deck, UC Berkeley
     * Inspiration & Code from:
     *      Mike Williams http://www.econym.demon.co.uk/googlemaps2/ V2 Reference & custommap code
     *      Brian Flood http://www.spatialdatalogic.com/cs/blogs/brian_flood/archive/2005/07/11/39.aspx V1 WMS code
     *      Kyle Mulka http://blog.kylemulka.com/?p=287  V1 WMS code modifications
     *      http://search.cpan.org/src/RRWO/GPS-Lowrance-0.31/lib/Geo/Coordinates/MercatorMeters.pm
     * 		Modified by Chris Holmes, TOPP to work by default with GeoServer.
     *		Guilhem Vellut <guilhem.vellut@gmail.com> for more accurate Javascript Mercator Fxn
     *
     * Note this only works with gmaps v2.36 and above.  http://johndeck.blogspot.com
     * has scripts
     * that do the same for older gmaps versions - just change from 54004 to 41001.
     *
     * About:
     * This script provides an implementation of GTileLayer that works with WMS
     * services that provide epsg 41001 (Mercator).  This provides a reasonable
     * accuracy on overlays at most zoom levels.  It switches between Mercator
     * and Lat/Long at the myMercZoomLevel variable, defaulting to MERC_ZOOM_DEFAULT
     * of 5.  It also performs the calculation from a GPoint to the appropriate
     * BBOX to pass the WMS.  The overlays could be more accurate, and if you
     * figure out a way to make them so please contribute information back to
     * http://docs.codehaus.org/display/GEOSDOC/Google+Maps.  There is much
     * information at:
     * http://cfis.savagexi.com/articles/2006/05/03/google-maps-deconstructed
     *
     * Use:
     * This script is used by creating a new GTileLayer, setting the required
     * and any desired optional variables, and setting the functions here to
     * override the appropriate GTileLayer ones.
     *
     * At the very least you will need:
     * var myTileLayer= new GTileLayer(new GCopyrightCollection(""),1,17);
     *     myTileLayer.myBaseURL='http://yourserver.org/wms?'
     *     myTileLayer.myLayers='myLayerName';
     *     myTileLayer=CustomGetTileUrl
     *
     * After that you can override the format (myFormat), the level at
     * which the zoom switches (myMercZoomLevel), and the style (myStyles)
     * - be sure to put one style for each layer (both are separated by
     * commas).  You can also override the Opacity:
     *     myTileLayer.myOpacity=0.69
     *     myTileLayer.getOpacity=customOpacity
     *
     * Then you can overlay on google maps with something like:
     * var layer=[G_SATELLITE_MAP.getTileLayers()[0],tileCountry];
     * var custommap = new GMapType(layer, G_SATELLITE_MAP.getProjection(), "WMS");
     * var map = new GMap(document.getElementById("map"));
     *     map.addMapType(custommap);
     */

    var MAGIC_NUMBER=6356752.3142;
    var WGS84_SEMI_MAJOR_AXIS = 6378137.0;
    var WGS84_ECCENTRICITY = 0.0818191913108718138;

    var DEG2RAD=0.0174532922519943;
    var PI=3.14159267;

    //Default image format, used if none is specified
    var FORMAT_DEFAULT="image/png";

    //Google Maps Zoom level at which we switch from Mercator to Lat/Long.
    var MERC_ZOOM_DEFAULT = 15;
    function dd2MercMetersLng(p_lng) {
	    return WGS84_SEMI_MAJOR_AXIS * (p_lng*DEG2RAD);
    }

    function dd2MercMetersLat(p_lat) {
	    var lat_rad = p_lat * DEG2RAD;
	    return WGS84_SEMI_MAJOR_AXIS * Math.log(Math.tan((lat_rad + PI / 2) / 2) * Math.pow( ((1 - WGS84_ECCENTRICITY * Math.sin(lat_rad)) / (1 + WGS84_ECCENTRICITY * Math.sin(lat_rad))), (WGS84_ECCENTRICITY/2)));
    }

    CustomGetTileUrl=function(a,b,c) {
	    if (this.myMercZoomLevel == undefined) {
    	    this.myMercZoomLevel = MERC_ZOOM_DEFAULT;
	    }

	    if (this.myFormat == undefined) {
    	    this.myFormat = FORMAT_DEFAULT;
	    }

	    if (typeof(window['this.myStyles'])=="undefined") this.myStyles="";
	    var lULP = new GPoint(a.x*256,(a.y+1)*256);
	    var lLRP = new GPoint((a.x+1)*256,a.y*256);
	    var lUL = G_NORMAL_MAP.getProjection().fromPixelToLatLng(lULP,b,c);
	    var lLR = G_NORMAL_MAP.getProjection().fromPixelToLatLng(lLRP,b,c);

	    // switch between Mercator and DD if merczoomlevel is set
	    // NOTE -it is now safe to use Mercator exclusively for all zoom levels (if your WMS supports it)
	    // so you can just use the two lines of code below the IF (& delete the ELSE)
    	
	    if (this.myMercZoomLevel!=0 && map.getZoom() < this.myMercZoomLevel) {
		    var lBbox=dd2MercMetersLng(lUL.x)+","+dd2MercMetersLat(lUL.y)+","+dd2MercMetersLng(lLR.x)+","+dd2MercMetersLat(lLR.y);
		    //Change for GeoServer - 41001 is mercator and installed by default.
		    var lSRS="EPSG:54004";
	    } else {
		    var lBbox=lUL.x+","+lUL.y+","+lLR.x+","+lLR.y;
		    var lSRS="EPSG:4326";
	    } 
	    var lURL=this.myBaseURL;
	    lURL+="&REQUEST=GetMap";
	    lURL+="&SERVICE=WMS";
	    lURL+="&VERSION=1.1.1";
	    lURL+="&LAYERS="+this.myLayers;
	    lURL+="&STYLES="+this.myStyles;
	    lURL+="&FORMAT="+this.myFormat;
	    lURL+="&BGCOLOR=0xFFFFFF";
	    lURL+="&TRANSPARENT=TRUE";
	    lURL+="&SRS="+lSRS;
	    lURL+="&BBOX="+lBbox;
	    lURL+="&WIDTH=256";
	    lURL+="&HEIGHT=256";
	    lURL+="&reaspect=false";
	    //document.write(lURL + "<br/>")
	    //alert(" url is " + lURL);
	    return lURL;
    }

    function customOpacity() { return this.myOpacity; }
		
		var allowedBounds = new GLatLngBounds(new GLatLng(51,0), new GLatLng(53.0,2.0));    

<!-- WMS SCRIPT ENDS HERE -->

	      map = new GMap2(document.getElementById(MapDivID));
//	      var map = new GMap2(document.getElementById('map'));
	      map.addControl(new GLargeMapControl());
//	      map.addControl(new GMapTypeControl());
	      map.addControl(new GScaleControl());
// removed CF 22/10/09 as slows everything down          map.addControl(new GOverviewMapControl());

<!-- INCLUDE WMS LAYER HERE (START)-->

  // add custom copyright collection
  var copyrightstatement='<br/>Crown Copyright. All rights reserved.<br/>Norfolk County Council Licence No.100019340<br/>';

  var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), 0, copyrightstatement);
  var copyrightCollection = new GCopyrightCollection('');
  copyrightCollection.addCopyright(copyright);


//	var myTileLayer = new GTileLayer(new GCopyrightCollection(""),1,17);
	var myTileLayer = new GTileLayer(copyrightCollection,1,17);

 //       myTileLayer.myBaseURL='http://www.esdm.no-ip.com/scripts/mapserv460.exe?map=C:/Inetpub/wwwroot/Mapserverservice/Map/WMSNHEdemo.map&'
        
        //myTileLayer.myBaseURL='http://www.norfolkheritageexplorer.no-ip.org/scripts/mapserv.exe?map=C:\Inetpub\wwwroot\WMS\Map\WMSNHEdemo.map&'
//http://www.tilecache.no-ip.com/CallCrop.aspx? is ESDM proxy that gets larger image and returns the middle bit, to avoid tile edge effects
       myTileLayer.myBaseURL='http://www.tilecache.no-ip.com/CallCrop.aspx?'+ WMSURL +'&';
        //alert(myTileLayer.myBaseURL);
        // comman-sep list. fails to retrieve last layer in the list for some reason
        // layers are drawn in the order specified here
        myTileLayer.myLayers='Parishes,NHEareas,NHElines,NHEpoints,NorfolkCounty';
        myTileLayer.myFormat='image/png';
	    myTileLayer.getTileUrl=CustomGetTileUrl;
	    myTileLayer.myOpacity=1;
	    //myTileLayer.myOpacity=0.69;
        myTileLayer.getOpacity=customOpacity;
		
        var layer1=[G_NORMAL_MAP.getTileLayers()[0],myTileLayer];
		var custommap1 = new GMapType(layer1, G_NORMAL_MAP.getProjection(), "NHE data");
		map.addMapType(custommap1);

		var mt = map.getMapTypes();
		for (var i=0; i<mt.length; i++) {
		    mt[i].getMinimumResolution = function() {return 5;}
		}


		// Check if user clicked and then do something very intelligent 
		GEvent.addListener(map,"click",
		   function (overlay, point)
		   {
		        if(overlay)
		        { return; }
		   	    var pt = new GLatLng(point.y,point.x);
		        addInfoTipMarker(pt);
		    }
		);

<!-- Adds InfoTip when clicked -->
	   function addInfoTipMarker(pt){
   		var p = new GPoint(pt);
		// code from Lance on the Google Maps Group

		var b = map.getBounds();
		var sw = b.getSouthWest();
		var ne = b.getNorthEast();
		var w = sw.lng();
		var e = ne.lng();
		var n = ne.lat();
		var s = sw.lat();
		var ts = s;
		var tw = w;
		if(n<s) { s=n; n = ts; }
		if(e<w){ w=e; e = tw; }
		if(s<-90)s=-90;
		if(n>90)n=90;
		if(e>180)e=180;
		if(w<-180)w=-180;

		var span_ew = Math.abs(e - w);
		var span_ns = Math.abs(n - s);

// Evaluate width and height of current map DIV

		CurrentMapDIV = document.getElementById(MapDivID);
		CurrentMapDIVHeight=parseInt(CurrentMapDIV.style.height);
		CurrentMapDIVWidth=parseInt(CurrentMapDIV.style.width);

//		var width  = 768*span_ew/span_ns;
//		var height = 768;
		var width  = CurrentMapDIVWidth * span_ew / span_ns;
		var height = CurrentMapDIVHeight;

		var x = (pt.x - w) * width/span_ew;
		var y = (n - pt.y) * height/span_ns;

		var label1 = 'Info';
		//var label2 = 'Details';
		var htm = "";
		//var html2 = "You clicked on <br>" + pt;

		var URL = GetURL(x, y, w, s, e, n, width, height);
		//htm += '<a href="javascript:zoomIn('+p+');">Zoom In</a>&nbsp;|&nbsp;<a href="javascript:zoomOut('+p+');">Zoom Out</a><br><br>';
		htm += "<iframe marginwidth=\"10\" name=\"WMSToolTip\" id=\"WMSToolTip\" frameborder=0 style=\"width:300px;height:75px;border: 0px;\" src=\"";
		htm += URL;
		htm += "\" ></iframe>";
//		alert(htm);


		map.openInfoWindowHtml(pt, htm);
    //		map.openInfoWindowTabsHtml(pt, [new GInfoWindowTab(label1,html1), new GInfoWindowTab(label2,html2)])


	}

	function GetURL(x, y, w, s, e, n, width, height){
//		r = "http://www.esdm.no-ip.com/scripts/mapserv460.exe?map=C:/Inetpub/wwwroot/Mapserverservice/Map/WMSHostingDemo.map";
        r = ''+WMSURL+'';
//        alert(r);
		r+="&SERVICE=WMS";
		r+="&SRS=EPSG:4326";
		r+="&VERSION=1.1.1";
		r+="&REQUEST=GetFeatureInfo";
		r+="&X=" + parseInt(x);
		r+="&Y=" + parseInt(y);
		r+="&QUERY_LAYERS=Parishes,NHEpoints,NHEareas,NHElines";
		r+="&LAYERS=NHEpoints,NHEareas,NHElines";
		r+="&INFO_FORMAT=text/html";
		r+="&BBOX="+w+","+s+","+e+","+n;
		r+="&WIDTH="+parseInt(width)+"&HEIGHT="+ parseInt(height);
		r+="&FEATURE_COUNT=10";
		return r;
	}


		
<!-- INCLUDE WMS LAYER HERE (END)-->



	      // ===== Start with an empty GLatLngBounds object =====     
	      var bounds = new GLatLngBounds();
	      
	      // Read the data from xml
	      var request = GXmlHttp.create();
	      request.open("GET", GetSpatialXMLfile, true);
	 
//alert(GetSpatialXMLfile);

	      request.onreadystatechange = function() {
		if (request.readyState == 4) {
		  var xmlDoc = request.responseXML;
		  
	  
		// obtain extent of spatial selection
  
//		  if(xmlDoc.documentElement.getElementsByTagName("midas:meta").length > 0)
//		  {
//		  	var meta = xmlDoc.documentElement.getElementsByTagName("midas:meta");
//		  }
//		  else
//		  {
//		   	var meta = xmlDoc.documentElement.getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0", "meta");
//		  }
//		  
//		  var extent = new Array();
//		  var count = 0;
//
//		  for (var i = 0; i < meta.length; i++)
//		  {
//			  if(xmlDoc.documentElement.getElementsByTagName("midas:boundingBox").length > 0)
//			  {
//		    		extent[count]=meta[i].getElementsByTagName("midas:boundingBox");
//		    	  }
//			  else
//		    	  {
//			  	extent[count]=meta[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0", "boundingBox");
//		    	  }
//			  count++;
//		  }
//		  
//		  for (var i = 0; i < extent.length; i++)
//		  {
//	   		var extentMinX= parseFloat(extent[i][0].getAttribute("minx"));
//			var extentMinY= parseFloat(extent[i][0].getAttribute("miny"));
//			var extentMaxX= parseFloat(extent[i][0].getAttribute("maxx"));
//			var extentMaxY= parseFloat(extent[i][0].getAttribute("maxy"));
//		  }
//  
//  		  // set map centre and zoom
//  		  var centreX = (extentMinX + extentMaxX) / 2;
//  		  var centreY = (extentMinY + extentMaxY) / 2;
//		  var zoomlevel = parseInt(360 / parseInt(extentMaxX - extentMinX));
//		  alert (zoomlevel);
 		   
  		   
		  // obtain the array of markers and loop through it
		  
		   if(xmlDoc.documentElement.getElementsByTagName("midas:quickpoint").length > 0)
		   {
		   	var allmarkers = xmlDoc.documentElement.getElementsByTagName("midas:quickpoint");
		   }
		   else
		   {
		     var allmarkers = xmlDoc.documentElement.getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0", "quickpoint");
		   }
		   
		  // only include markers that are Lat/Long
		  var markerLAT = new Array();
		  var markerLONG = new Array();

  	      	  map.setCenter(new GLatLng(0,0), 0);

		  var count = 0;
		  for (var i = 0; i < allmarkers.length; i++)
		  {	
			// works in IE
			if(allmarkers[i].getElementsByTagName("midas:srs").length > 0)
		   	{
				if(allmarkers[i].getElementsByTagName("midas:srs")[0].firstChild.nodeValue == "EPSG:4326")
			//	if(allmarkers[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","srs")[0].firstChild.nodeValue == "EPSG:4326")
			//	if(allmarkers[i].childNodes[0].childNodes[0].nodeValue == "EPSG:4326")
				{
				       markerLAT[count]=parseFloat(allmarkers[i].getElementsByTagName("midas:y")[0].firstChild.nodeValue);
				       markerLONG[count]=parseFloat(allmarkers[i].getElementsByTagName("midas:x")[0].firstChild.nodeValue);
			//	       markerLAT[count]=allmarkers[i].childNodes[2].childNodes[0].nodeValue;
			//	       markerLONG[count]=allmarkers[i].childNodes[1].childNodes[0].nodeValue;
				       count++;
			  	}
			}
			else
			//works in Mozilla
			{
				if(allmarkers[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","srs")[0].firstChild.nodeValue == "EPSG:4326")
				{
			       	       markerLAT[count]=parseFloat(allmarkers[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","y")[0].firstChild.nodeValue);
			       	       markerLONG[count]=parseFloat(allmarkers[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","x")[0].firstChild.nodeValue);
				       count++;
			  	}
			}
		  }
		  
		  // get marker description
			if(xmlDoc.documentElement.getElementsByTagName("midas:appellation").length > 0)
		   	{
		  		var description = xmlDoc.documentElement.getElementsByTagName("midas:appellation");
		  	}
		  	else
		  	{
		  		var description = xmlDoc.documentElement.getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","appellation");
		  	}
		  
		  // generate markers
		  for (var i = 0; i < markerLAT.length; i++)
		    {
			    var lat = markerLAT[i];
			    var lng = markerLONG[i];
			    var point = new GLatLng(lat,lng);
			    // works in IE
			    if(description[i].getElementsByTagName("midas:name").length > 0)
			    {
				    var html = "<p><a href=\"SingleResult.aspx?uid=";
				    	html += description[i].getElementsByTagName("midas:identifier")[0].firstChild.nodeValue;
				    	html += "\">";
				    	html += "NHER " + description[i].getElementsByTagName("midas:identifier")[1].firstChild.nodeValue;
				    	html += "</a>&nbsp;&nbsp;";
				    	html += description[i].getElementsByTagName("midas:name")[0].firstChild.nodeValue;
				    	html += "</p>";
			//	    var html = description[i].getElementsByTagName("midas:name")[0].firstChild.nodeValue;
				    var label = description[i].getElementsByTagName("midas:identifier")[0].firstChild.nodeValue;
			    }
			    else
			    //works in Mozilla
			    {
				    var html = "<p><a href=\"SingleResult.aspx?uid=";
				    	html += description[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","identifier")[0].firstChild.nodeValue;
				    	html += "\">";
				    	html += "NHER " + description[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","identifier")[1].firstChild.nodeValue;
				    	html += "</a>&nbsp;&nbsp;";
				    	html += description[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","name")[0].firstChild.nodeValue;
				    	html += "</p>";
			//	        var html = description[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","name")[0].firstChild.nodeValue;
			//	        var label = description[i].getElementsByTagNameNS("http://www.heritage-standards.org/midas/schema/1.0","identifier")[0].firstChild.nodeValue;
			    }
			    // create the marker
			    var marker = createMarker(point,label,html);
    		    	    map.addOverlay(marker);

			    // ==== Each time a point is found, extent the bounds to include it =====
			    bounds.extend(point);

		    }
		    
		  // put the assembled side_bar_html contents into the side_bar div
//		  document.getElementById("side_bar").innerHTML = side_bar_html;
//  	      alert(MapDivID);
         	 if(MapDivID=='SingleMap')
        	  {
		      map.setZoom(14);
		      
		      // ===== determine the centre from the bounds ======
		      var clat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) /2;
		      var clng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) /2;
		      map.setCenter(new GLatLng(clat,clng));
		  }
		  else
		  // MultiMap
        	  {
		      // ===== determine the zoom level from the bounds =====
		      map.setZoom(map.getBoundsZoomLevel(bounds));
		      
		      

		      // ===== determine the centre from the bounds ======
		      var clat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) /2;
		      var clng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) /2;
		      map.setCenter(new GLatLng(clat,clng));
		  }
		  
		  
		  
<!-- Switch to WMS view here - THIS NEEDS TO BE AT THE END!!! -->
		  map.setMapType(custommap1);
		  
		}
	      }
      	      request.send(null);
      }


    else {
//      alert("Sorry, the Google Maps API is not compatible with this browser");
    }
}
    
function getURLParameters(paramName) {
				var sURL = window.document.URL.toString();
				var ans='';
				if (sURL.indexOf("?") > 0) {
					var arrURLParams = window.location.search.substring(1).split("&");
					var arrParamNames = new Array(arrURLParams.length);
					var arrParamValues = new Array(arrURLParams.length);
					var i = 0;
					for (i=0;i<arrURLParams.length;i++) {
						var sParam =  arrURLParams[i].split("=");
						arrParamNames[i] = sParam[0];
						if (sParam[1] != "")
							arrParamValues[i] = unescape(sParam[1]);
						else
							arrParamValues[i] = "";
						if (arrParamNames[i]==paramName)
							ans = arrParamValues[i];
					}
				}
				return ans
}