//<![CDATA[


    var localSearch = new GlocalSearch();
    var map = null;
    var geocoder = new GClientGeocoder();
    var icon = new GIcon();
    
    icon.image = "http://www.google.com/mapfiles/marker.png";
    icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
    icon.iconSize = new GSize(20, 34);
    icon.shadowSize = new GSize(37, 34);
    icon.iconAnchor = new GPoint(10, 34);

    function usePointFromPostcode(postcode, callbackFunction) {
      
      localSearch.setSearchCompleteCallback(null, 
        function() {
          if (localSearch.results[0]) {   
            //alert(localSearch.results.length);
            var resultLat = localSearch.results[0].lat;
            var resultLng = localSearch.results[0].lng;
            var point = new GLatLng(parseFloat(resultLat),parseFloat(resultLng));
            
            callbackFunction(point);
          }else{
            alert("Postcode not found!");
          }
        });  
        
      localSearch.execute(postcode + ", UK");
    }    
    
    function raisePostback()
    {           
        __doPostBack(gGoogleMapPostbackReference,'') 
    } 
        
    function initialize() {
        //alert(GBrowserIsCompatible);
      if (GBrowserIsCompatible()) {
           
        var allowedBounds = new GLatLngBounds(new GLatLng(49.5,-10), new GLatLng(59,2.6));
        map = new GMap2(document.getElementById("map"));

	
        map.enableDoubleClickZoom();
        map.enableContinuousZoom();
        
        switch(gGoogleMapView)
        {
            case "h" :
            {
                map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSize, G_HYBRID_MAP);
                break;
            }
            case "s" :
            {
                map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSize, G_SATELLITE_MAP);
                break;
            }            
            default :
            {
                map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSize);
                break;
            }
        }
	
        if(gGoogleMapShowlarge)
            map.addControl(new GLargeMapControl());
        else
            map.addControl(new GSmallMapControl());
        
        if(gGoogleMapShowTypeControl)
            map.addControl(new GMapTypeControl());        
        
        //alert("OK");

        if(gGoogleMapShowSite)
        {
            
         } 
         else
         {
         
            GEvent.addListener(map, "click", function(marker, point) {
                map.clearOverlays();
                if (marker) {
                
                    map.removeOverlay(marker);
                    clearValues();
                }   
                else {
                    map.addOverlay(new GMarker(point));
                    if(gGoogleMapShowSite)
                    {
                    
                    }
                    else
                    {
                        setData(point);
                    }
                    
                }
            });            
         }
         
        GEvent.addListener(map, "move", function() {
            checkBounds();
        });  

      
        function checkBounds() {
            if (allowedBounds.contains(map.getCenter())) {
                return;
            }
        
            var C = map.getCenter();
            var X = C.lng();
            var Y = C.lat();

            var AmaxX = allowedBounds.getNorthEast().lng();
            var AmaxY = allowedBounds.getNorthEast().lat();
            var AminX = allowedBounds.getSouthWest().lng();
            var AminY = allowedBounds.getSouthWest().lat();

            if (X < AminX) {X = AminX;}
            if (X > AmaxX) {X = AmaxX;}
            if (Y < AminY) {Y = AminY;}
            if (Y > AmaxY) {Y = AmaxY;}
            
            map.setCenter(new GLatLng(Y,X));
        }          
        
	//alert("OK");
	
		

        if(gGoogleMapShowSite)
        {
            toggleTheView(gGoogleMapView);
            return;
        }
        else
        {
            toggleOptions(gGoogleMapStartOption,false);
        }          
		
	//alert("OK");
	

                      
        //                

	//return;

        map.addOverlay(new GMarker(new GLatLng(gGoogleMapLatitude,gGoogleMapLongtitude)));

	
        
        var mt = map.getMapTypes();
        for (var i=0; i<mt.length; i++) {
            mt[i].getMinimumResolution = function() {return gGoogleMapSize;}
        }


	

        if(document.getElementById(gGoogleMapControlId + "txtLat").value != "0" && document.getElementById(gGoogleMapControlId + "txtLng").value != "0")
        {
            placeMarker(false);
        }
        
      }
      else
      {
        alert("Sorry, the Google Maps API is not compatible with this browser");
      }
      
    }
    
    function toggleTheView(view)
    {
        //alert("PLOT");
        var returnLongLat = GridToLatLong2(gGoogleMapShowSiteX,gGoogleMapShowSiteY);
        returnLongLat.OSGB36ToWGS84();
        if(!isNaN(returnLongLat.lat))
        {              
            var point = new GLatLng(returnLongLat.lat,returnLongLat.lng);
            var marker = new GMarker(point,icon);
            switch(view)
            {
                case "h" :
                {
                    map.setCenter(point, gGoogleMapSize, G_HYBRID_MAP);
                    break;
                }
                case "s" :
                {
                    map.setCenter(point, gGoogleMapSize, G_SATELLITE_MAP);
                    break;
                }            
                default :
                {
                    map.setCenter(point, gGoogleMapSize, G_NORMAL_MAP);  
                    break;
                }
            }            
            map.addOverlay(marker);
        }     
    }
    function clearValues()
    {
        map.clearOverlays();
        document.getElementById(gGoogleMapControlId + "ddlLatitude").selectedIndex = 0;
        document.getElementById(gGoogleMapControlId + "ddlLongitude").selectedIndex = 0;
        document.getElementById(gGoogleMapControlId + "txtLatitude").value = "";
        document.getElementById(gGoogleMapControlId + "txtLongitude").value = "";
        document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value = "";
        document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value = "";
        document.getElementById(gGoogleMapControlId + "txtOSRef").value = "";
        document.getElementById(gGoogleMapControlId + "txtAddress").value = "";
        document.getElementById(gGoogleMapControlId + "txtPostcode").value = "";
        document.getElementById(gGoogleMapControlId + "txtLat").value = "0";
        document.getElementById(gGoogleMapControlId + "txtLng").value = "0";
        
        document.getElementById(gGoogleMapControlId + "txtLatitudeDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtLongitudeDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtGridRefEastingDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtGridRefNorthingDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtOSRefDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtAddressDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtPostcodeDummy").value = "";                
        document.getElementById(gGoogleMapControlId + "ddlLatitudeDummy").value = "";
        document.getElementById(gGoogleMapControlId + "ddlLongitudeDummy").value = "";    
    }
    
    function setData(point)
    {
        
        document.getElementById(gGoogleMapControlId + "RadioButtonPC").checked = false;
        document.getElementById(gGoogleMapControlId + "RadioButtonAddress").checked = false;      
        document.getElementById(gGoogleMapControlId + "RadioButtonOS").checked = false;
        document.getElementById(gGoogleMapControlId + "RadioButtonLongtitude").checked = true;
        document.getElementById(gGoogleMapControlId + "RadioButtonGridReference").checked = false;
            
        document.getElementById("tdLl1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdLl2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdLl3").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdPc1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdPc2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdPc3").style.backgroundColor = "#FFFFFF";
        
        document.getElementById("tdOs1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdOs2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdOs3").style.backgroundColor = "#FFFFFF";                
        
        document.getElementById("tdGr1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdGr2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdGr3").style.backgroundColor = "#FFFFFF";
        
        /*document.getElementById("tdLl2").style.color = "#C9C9C9";
        document.getElementById("tdLl_s1").style.color = "#C9C9C9";
        document.getElementById("tdLl_s2").style.color = "#C9C9C9";
        
        document.getElementById("tdPc2").style.color = "#C9C9C9";
        document.getElementById("tdPc_s1").style.color = "#C9C9C9";
        
        document.getElementById("tdOs2").style.color = "#C9C9C9";
        document.getElementById("tdOs_s1").style.color = "#C9C9C9";
        
        document.getElementById("tdGr2").style.color = "#C9C9C9";
        document.getElementById("tdGr_s1").style.color = "#C9C9C9";
        document.getElementById("tdGr_s2").style.color = "#C9C9C9";
        document.getElementById("tdGr_s3").style.color = "#C9C9C9";
        document.getElementById("tdGr_s4").style.color = "#C9C9C9";*/
        
        document.getElementById(gGoogleMapControlId + "txtPostcode").value = "";
        document.getElementById(gGoogleMapControlId + "txtPostcodeDummy").value = "";
        
        enableDisable(gGoogleMapControlId + "txtLongitude",true);
        enableDisable(gGoogleMapControlId + "txtLatitude",true);
        enableDisable(gGoogleMapControlId + "ddlLongitude",true);
        enableDisable(gGoogleMapControlId + "ddlLatitude",true);
        enableDisable(gGoogleMapControlId + "txtOSRef",true);
        enableDisable(gGoogleMapControlId + "txtGridRefEasting",true);
        enableDisable(gGoogleMapControlId + "txtGridRefNorthing",true);
        enableDisable(gGoogleMapControlId + "txtAddress",true);
        enableDisable(gGoogleMapControlId + "txtPostcode",true);
               
        document.getElementById(gGoogleMapControlId + "txtAddress").value = "";
        document.getElementById(gGoogleMapControlId + "txtAddressDummy").value = "";

        enableDisable(gGoogleMapControlId + "txtLongitude",false);
        enableDisable(gGoogleMapControlId + "txtLatitude",false);
        enableDisable(gGoogleMapControlId + "ddlLongitude",false);
        enableDisable(gGoogleMapControlId + "ddlLatitude",false);
        
        document.getElementById("tdLl1").style.backgroundColor = "#B6D2E3";
        document.getElementById("tdLl2").style.backgroundColor = "#B6D2E3";
        document.getElementById("tdLl3").style.backgroundColor = "#B6D2E3";     
        document.getElementById("tdLl2").style.color = "#000000";   
        document.getElementById("tdLl_s1").style.color = "#000000";
        document.getElementById("tdLl_s2").style.color = "#000000";     
           
        setValues(point);
    }
    
    function setValues(point)
    {

        if(point.x < 0)
        {
            document.getElementById(gGoogleMapControlId + "ddlLongitude").selectedIndex = 1;
            document.getElementById(gGoogleMapControlId + "ddlLongitudeDummy").value = "w";
        }
        else
        {
            document.getElementById(gGoogleMapControlId + "ddlLongitude").selectedIndex = 0;
            document.getElementById(gGoogleMapControlId + "ddlLongitudeDummy").value = "e";
        }
        if(point.y < 0)
        {
            document.getElementById(gGoogleMapControlId + "ddlLatitude").selectedIndex = 1;
            document.getElementById(gGoogleMapControlId + "ddlLatitudeDummy").value = "s";                  
        }
        else
        {
            document.getElementById(gGoogleMapControlId + "ddlLatitude").selectedIndex = 0;
            document.getElementById(gGoogleMapControlId + "ddlLatitudeDummy").value = "n"; 
        }  
        
        document.getElementById(gGoogleMapControlId + "txtLongitude").value = point.x.toFixed(4);
        document.getElementById(gGoogleMapControlId + "txtLatitude").value = point.y.toFixed(4);    
        document.getElementById(gGoogleMapControlId + "txtLongitudeDummy").value = point.x.toFixed(4);
        document.getElementById(gGoogleMapControlId + "txtLatitudeDummy").value = point.y.toFixed(4);          
        document.getElementById(gGoogleMapControlId + "txtLat").value = point.y.toFixed(8);
        document.getElementById(gGoogleMapControlId + "txtLng").value = point.x.toFixed(8);
                                           
        var ll2 = new LatLng(point.y, point.x);
        //alert(ll2.lat);
        //alert(ll2.lng);
        //ll2.OSGB36ToWGS84();
        //alert(ll2.lat);
        //alert(ll2.lng);        
        var os2 = ll2.toOSRef();
        document.getElementById(gGoogleMapControlId + "txtOSRef").value = os2.toSixFigureString();
        document.getElementById(gGoogleMapControlId + "txtOSRefDummy").value = os2.toSixFigureString();
        document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value = os2.easting.toFixed(0)
        document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value = os2.northing.toFixed(0);    
        document.getElementById(gGoogleMapControlId + "txtGridRefEastingDummy").value = os2.easting.toFixed(0)
        document.getElementById(gGoogleMapControlId + "txtGridRefNorthingDummy").value = os2.northing.toFixed(0);            
    }
    
    function spatialManualEntry()
    {
            
        if(document.getElementById(gGoogleMapControlId + "txtLat").value == "0" || document.getElementById(gGoogleMapControlId + "txtLng").value == "0")
        {
            alert("The search you are trying to submit is not valid.");
        }
    }
    
    
    function setJS(){document.getElementById(gGoogleMapControlId + "jsCheck").value = "1";}	
    
    function enableDisable(id,val)
    {
        //document.getElementById(id).disabled = val;
    }
    
    function toggleOptions(param, clear)
    {
        try
        {
            map.clearOverlays();
            map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSizeMark);
        }
        catch(e)
        {
        
        }
        
        if(clear)
        {
        
            if(param != "ll")
            {
                document.getElementById(gGoogleMapControlId + "txtLat").value = "0";
                document.getElementById(gGoogleMapControlId + "txtLng").value = "0";
                document.getElementById(gGoogleMapControlId + "ddlLatitude").selectedIndex = 0;
                document.getElementById(gGoogleMapControlId + "ddlLongitude").selectedIndex = 0;    
                document.getElementById(gGoogleMapControlId + "txtLongitude").value = "";
                document.getElementById(gGoogleMapControlId + "txtLatitude").value = "";
            }            
            document.getElementById(gGoogleMapControlId + "txtOSRef").value = "";
            document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value = "";
            document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value = "";
            document.getElementById(gGoogleMapControlId + "txtAddress").value = "";
            document.getElementById(gGoogleMapControlId + "txtPostcode").value = "";            
            
            document.getElementById(gGoogleMapControlId + "txtLongitudeDummy").value = "";
            document.getElementById(gGoogleMapControlId + "txtLatitudeDummy").value = "";
            document.getElementById(gGoogleMapControlId + "txtOSRefDummy").value = "";
            document.getElementById(gGoogleMapControlId + "txtGridRefEastingDummy").value = "";
            document.getElementById(gGoogleMapControlId + "txtGridRefNorthingDummy").value = "";
            document.getElementById(gGoogleMapControlId + "txtAddressDummy").value = "";
            document.getElementById(gGoogleMapControlId + "txtPostcodeDummy").value = "";               
            document.getElementById(gGoogleMapControlId + "ddlLatitudeDummy").value = "";
            document.getElementById(gGoogleMapControlId + "ddlLongitudeDummy").value = "";             
        }
        
        document.getElementById("tdLl1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdLl2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdLl3").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdPc1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdPc2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdPc3").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdOs1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdOs2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdOs3").style.backgroundColor = "#FFFFFF";                
        document.getElementById("tdGr1").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdGr2").style.backgroundColor = "#FFFFFF";
        document.getElementById("tdGr3").style.backgroundColor = "#FFFFFF";
        
        /*document.getElementById("tdLl2").style.color = "#C9C9C9";
        document.getElementById("tdLl_s1").style.color = "#C9C9C9";
        document.getElementById("tdLl_s2").style.color = "#C9C9C9";   
                
        document.getElementById("tdPc2").style.color = "#C9C9C9";
        document.getElementById("tdPc_s1").style.color = "#C9C9C9";
        
        document.getElementById("tdOs2").style.color = "#C9C9C9";
        document.getElementById("tdOs_s1").style.color = "#C9C9C9";
        
        document.getElementById("tdGr2").style.color = "#C9C9C9";
        document.getElementById("tdGr_s1").style.color = "#C9C9C9";
        document.getElementById("tdGr_s2").style.color = "#C9C9C9";
        document.getElementById("tdGr_s3").style.color = "#C9C9C9";
        document.getElementById("tdGr_s4").style.color = "#C9C9C9";*/
        
       
       
        enableDisable(gGoogleMapControlId + "txtLongitude",true);
        enableDisable(gGoogleMapControlId + "txtLatitude",true);
        enableDisable(gGoogleMapControlId + "ddlLongitude",true);
        enableDisable(gGoogleMapControlId + "ddlLatitude",true);
        enableDisable(gGoogleMapControlId + "txtOSRef",true);
        enableDisable(gGoogleMapControlId + "txtGridRefEasting",true);
        enableDisable(gGoogleMapControlId + "txtGridRefNorthing",true);
        enableDisable(gGoogleMapControlId + "txtAddress",true);
        enableDisable(gGoogleMapControlId + "txtPostcode",true);
        
       
        document.getElementById(gGoogleMapControlId + "RadioButtonLongtitude").checked = false;
        document.getElementById(gGoogleMapControlId + "RadioButtonOS").checked = false;
        document.getElementById(gGoogleMapControlId + "RadioButtonGridReference").checked = false;
        document.getElementById(gGoogleMapControlId + "RadioButtonPC").checked = false;
        document.getElementById(gGoogleMapControlId + "RadioButtonAddress").checked = false;
        
        switch (param)
        {
            case "os" :
            {
                enableDisable(gGoogleMapControlId + "txtOSRef",false);
                document.getElementById("tdOs1").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdOs2").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdOs3").style.backgroundColor = "#B6D2E3";                                
                document.getElementById("tdOs2").style.color = "#000000";
                document.getElementById("tdOs_s1").style.color = "#000000";
                document.getElementById(gGoogleMapControlId + "RadioButtonOS").checked = true;
                //document.getElementById("spnTxtGeneral").innerHTML = "Please enter a six figure OS grid reference e.g. SU122421.";
                break;
            }
            case "ll" :
            {
                enableDisable(gGoogleMapControlId + "txtLongitude",false);
                enableDisable(gGoogleMapControlId + "txtLatitude",false);
                enableDisable(gGoogleMapControlId + "ddlLongitude",false);
                enableDisable(gGoogleMapControlId + "ddlLatitude",false);
                document.getElementById("tdLl1").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdLl2").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdLl3").style.backgroundColor = "#B6D2E3";     
                document.getElementById("tdLl2").style.color = "#000000";
                document.getElementById("tdLl_s1").style.color = "#000000";
                document.getElementById("tdLl_s2").style.color = "#000000";                  
                document.getElementById(gGoogleMapControlId + "RadioButtonLongtitude").checked = true;
                //document.getElementById("spnTxtGeneral").innerHTML = "Please enter a lat/long reference e.g. 50.7599 North(+) -1.0899 West(-).";
                break;
            } 
            case "pc" :
            {
                enableDisable(gGoogleMapControlId + "txtPostcode",false);
                document.getElementById("tdPc1").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdPc2").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdPc3").style.backgroundColor = "#B6D2E3"; 
                document.getElementById("tdPc2").style.color = "#000000";
                document.getElementById("tdPc_s1").style.color = "#000000";
                document.getElementById(gGoogleMapControlId + "RadioButtonPC").checked = true;
                //document.getElementById("spnTxtGeneral").innerHTML = "Please enter a postcode e.g. SN2 2GZ.";
                break;
            }
            case "add" :
            {
                enableDisable(gGoogleMapControlId + "txtAddress",false);
                document.getElementById(gGoogleMapControlId + "RadioButtonAddress").checked = true;
                break;
            }            
            case "gr" :
            {
                enableDisable(gGoogleMapControlId + "txtGridRefEasting",false);
                enableDisable(gGoogleMapControlId + "txtGridRefNorthing",false);
                document.getElementById("tdGr1").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdGr2").style.backgroundColor = "#B6D2E3";
                document.getElementById("tdGr3").style.backgroundColor = "#B6D2E3";    
                document.getElementById("tdGr2").style.color = "#000000";     
                document.getElementById("tdGr_s1").style.color = "#000000";
                document.getElementById("tdGr_s2").style.color = "#000000";
                document.getElementById("tdGr_s3").style.color = "#000000";
                document.getElementById("tdGr_s4").style.color = "#000000";                          
                document.getElementById(gGoogleMapControlId + "RadioButtonGridReference").checked = true;
                //document.getElementById("spnTxtGeneral").innerHTML = "Please enter an absolute grid reference e.g. 410235 Easting 170009 Northing.";
                break;
            }                         
        }
    }
    
    function placeMarkerAtPoint(point)
    {
        var marker = new GMarker(point,icon);
        map.addOverlay(marker);
        map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSizeMark);
        setValues(point);
    }


    function placeMarkerAtPointAndSearch(point)
    {
        var marker = new GMarker(point,icon);
        map.addOverlay(marker);
        map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSizeMark);
        setValues(point);
        raisePostback();
    }    
    
    
    function setCenterToPoint(point)
    {
        var marker = new GMarker(point,icon);
        map.addOverlay(marker);
	    map.setCenter(point, gGoogleMapSizeShow);
        document.getElementById(gGoogleMapControlId + "txtLat").value = point.y;
        document.getElementById(gGoogleMapControlId + "txtLng").value = point.x;
    }    
    
    function setCenterToPoint2()
    {
        if(document.getElementById(gGoogleMapControlId + "txtLat").value != "0" && document.getElementById(gGoogleMapControlId + "txtLng").value != "0")
        {
            var point = new GLatLng(document.getElementById(gGoogleMapControlId + "txtLat").value,document.getElementById(gGoogleMapControlId + "txtLng").value);
            map.setCenter(point, gGoogleMapSizeShow);  
        }
        else
        {
            alert("Please select a position to center!");
        }  
    }     

    function placeMarker(search)
    {

        var returnValue = false;
        
        map.clearOverlays();
        document.getElementById(gGoogleMapControlId + "txtLat").value = "0";
        document.getElementById(gGoogleMapControlId + "txtLng").value = "0";
        document.getElementById(gGoogleMapControlId + "txtLatitudeDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtLongitudeDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtGridRefEastingDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtGridRefNorthingDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtOSRefDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtAddressDummy").value = "";
        document.getElementById(gGoogleMapControlId + "txtPostcodeDummy").value = "";                
        document.getElementById(gGoogleMapControlId + "ddlLatitudeDummy").value = "";
        document.getElementById(gGoogleMapControlId + "ddlLongitudeDummy").value = "";          
                        
        var param = "ll";
        if(document.getElementById(gGoogleMapControlId + "RadioButtonPC").checked)
        {
            param = "pc";
        }
        if(document.getElementById(gGoogleMapControlId + "RadioButtonAddress").checked)
        {
            param = "add";
        }        
        if(document.getElementById(gGoogleMapControlId + "RadioButtonOS").checked)
        {
            param = "os";
        }  
        if(document.getElementById(gGoogleMapControlId + "RadioButtonLongtitude").checked)
        {
            param = "ll";
        }               
        if(document.getElementById(gGoogleMapControlId + "RadioButtonGridReference").checked)
        {
            param = "gr";
        }        
        
        switch (param)
        {
            case "os" :
            {
                document.getElementById(gGoogleMapControlId + "ddlLatitude").selectedIndex = 0;
                document.getElementById(gGoogleMapControlId + "ddlLongitude").selectedIndex = 0;
                document.getElementById(gGoogleMapControlId + "txtLatitude").value = "";
                document.getElementById(gGoogleMapControlId + "txtLongitude").value = "";
                document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value = "";
                document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value = "";
                document.getElementById(gGoogleMapControlId + "txtAddress").value = "";
                document.getElementById(gGoogleMapControlId + "txtPostcode").value = "";
                
                                
                var returnLongLat = OSGridToLatLong2(document.getElementById(gGoogleMapControlId + "txtOSRef").value);
                if(!isNaN(returnLongLat.lat))
                {
                    var point = new GLatLng(returnLongLat.lat,returnLongLat.lng);
                    var marker = new GMarker(point,icon);
                    map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSizeMark);  
                    map.addOverlay(marker);
                    setValues(point);
                    if(search){raisePostback();}
                }
                else
                {
                    alert("OS reference was not found!");
                }
                break;
            }
            case "ll" :
            {
                try
                {
                    document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value = "";
                    document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value = "";
                    document.getElementById(gGoogleMapControlId + "txtOSRef").value = "";
                    document.getElementById(gGoogleMapControlId + "txtAddress").value = "";
                    document.getElementById(gGoogleMapControlId + "txtPostcode").value = "";
                                  
                    var point = new GLatLng(parseFloat(document.getElementById(gGoogleMapControlId + "txtLatitude").value),parseFloat(document.getElementById(gGoogleMapControlId + "txtLongitude").value));      
                    if(isNaN(point.x))
                    {
                        alert("Longtitude / Latitude was not found!");
                    }
                    else
                    {
                        var marker = new GMarker(point,icon);
                        map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSizeMark);  
                        map.addOverlay(marker);
                        setValues(point);                        
                        if(search){raisePostback();}
                    }                    
                }
                catch(e)
                {
                    alert("Longtitude / Latitude was not found!");
                }
                break;
            } 
            case "pc" :
            {
		
            
                if(document.getElementById(gGoogleMapControlId + "txtPostcode").value != "")
                {
                    
                    document.getElementById(gGoogleMapControlId + "txtPostcodeDummy").value = document.getElementById(gGoogleMapControlId + "txtPostcode").value; 
                
                    document.getElementById(gGoogleMapControlId + "ddlLatitude").selectedIndex = 0;
                    document.getElementById(gGoogleMapControlId + "ddlLongitude").selectedIndex = 0;
                    document.getElementById(gGoogleMapControlId + "txtLatitude").value = "";
                    document.getElementById(gGoogleMapControlId + "txtLongitude").value = "";
                    document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value = "";
                    document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value = "";
                    document.getElementById(gGoogleMapControlId + "txtAddress").value = "";
                    document.getElementById(gGoogleMapControlId + "txtOSRef").value = "";     
                           
                    if(search)
                    {
                        usePointFromPostcode(document.getElementById(gGoogleMapControlId + "txtPostcode").value, placeMarkerAtPointAndSearch)
                    }
                    else
                    {
                        usePointFromPostcode(document.getElementById(gGoogleMapControlId + "txtPostcode").value, placeMarkerAtPoint)
                    }
                }
                else
                {
                    alert("Postcode was not found!");
                }
                returnValue = false;
                break;
            }
            case "add" :
            {
		
                if(document.getElementById(gGoogleMapControlId + "txtAddress").value.length > 3)
                {
                    findAddressPoint();
                }
                else
                {
                    alert("Place was not found!");
                }
                returnValue = false;
                break;
            }            
            case "gr" :
            {
                if(document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value == "" || document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value == "")
                {
                    alert("Grid reference was not found!");
                    break;
                }
                document.getElementById(gGoogleMapControlId + "ddlLatitude").selectedIndex = 0;
                document.getElementById(gGoogleMapControlId + "ddlLongitude").selectedIndex = 0;
                document.getElementById(gGoogleMapControlId + "txtLatitude").value = "";
                document.getElementById(gGoogleMapControlId + "txtLongitude").value = "";
                document.getElementById(gGoogleMapControlId + "txtPostcode").value = "";
                document.getElementById(gGoogleMapControlId + "txtAddress").value = "";
                document.getElementById(gGoogleMapControlId + "txtOSRef").value = "";                 
                var returnLongLat = GridToLatLong2(document.getElementById(gGoogleMapControlId + "txtGridRefEasting").value,document.getElementById(gGoogleMapControlId + "txtGridRefNorthing").value);
                if(!isNaN(returnLongLat.lat))
                {                
                    var point = new GLatLng(returnLongLat.lat,returnLongLat.lng);
                    var marker = new GMarker(point,icon);
                    map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSizeMark);  
                    map.addOverlay(marker);
                    setValues(point);
                    if(search){raisePostback();}
                }
                else
                {
                    alert("Grid reference was not found!");
                }                
                break;
            }                         
        }	    
        return false;
    }
    
    function centerMap()
    {
        if(document.getElementById(gGoogleMapControlId + "txtLat").value != "0" && document.getElementById(gGoogleMapControlId + "txtLng").value != "0")
        {
            var point = new GLatLng(parseFloat(document.getElementById(gGoogleMapControlId + "txtLat").value),parseFloat(document.getElementById(gGoogleMapControlId + "txtLng").value));
            map.setCenter(point, gGoogleMapSizeShow);        
        }
        else
        {
            alert("Please select a position to center!");
        }          
    }
    
    function expandMap()
    {
        if(document.getElementById(gGoogleMapControlId + "txtLat").value != "0" && document.getElementById(gGoogleMapControlId + "txtLng").value != "0")
        {
            var point = new GLatLng(parseFloat(document.getElementById(gGoogleMapControlId + "txtLat").value),parseFloat(document.getElementById(gGoogleMapControlId + "txtLng").value));
            map.setCenter(point, 19);  
        }
        else
        {
            alert("Please select a position to expand!");
        }  
    }
    
    function addAddressToMap(response) {
      map.clearOverlays();
      //alert(response.Status.code);
      if (!response || response.Status.code != 200) {
        alert("Sorry, we were unable to geocode that address");
      } else {
        place = response.Placemark[0];
        point = new GLatLng(place.Point.coordinates[1],
                            place.Point.coordinates[0]);
        marker = new GMarker(point);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(place.address + '<br>' +
          '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
      }
    }

    // showLocation() is called when you click on the Search button
    // in the form.  It geocodes the address entered into the form
    // and adds a marker to the map at that location.
    function showLocation() {
      var address = document.getElementById(gGoogleMapControlId + "txtAddress").value;
      geocoder.getLocations(address, addAddressToMap);
    }

   // findLocation() is used to enter the sample addresses into the form.
    function findLocation(address) {
      document.getElementById(gGoogleMapControlId + "txtAddress").value = address;
      showLocation();
    }   
    
    function findAddress() {
      var address = document.getElementById(gGoogleMapControlId + "txtAddress").value + ", UK";
      showAddress(address);
    }     
    
    
    function showAddress(address) {
      if (geocoder) {
        geocoder.getLatLng(
          address,
          function(point) {
            if (!point) {
              alert("Place was not found!");
            } else {
              map.setCenter(point, gGoogleMapSizeShow);
              var marker = new GMarker(point);
              map.addOverlay(marker);
              document.getElementById(gGoogleMapControlId + "txtLat").value = point.y.toFixed(8);
              document.getElementById(gGoogleMapControlId + "txtLng").value = point.x.toFixed(8);  
            }
          }
        );
      }
    } 
    
    function findAddressPoint() {
      var address = document.getElementById(gGoogleMapControlId + "txtAddress").value + ", UK";
      showAddressPoint(address);
    }     
    
    function showAddressPoint(address) {
      if (geocoder) {
        geocoder.getLatLng(
          address,
          function(point) {
            if (!point) {         
                alert("Place was not found!");
            } else {
              map.setCenter(new GLatLng(53.15,-3.0), gGoogleMapSizeMark);
              var marker = new GMarker(point);
              map.addOverlay(marker);
                if(point.x.length == 0 || point.y.length == 0)
                {
                    alert("Place was not found!");
                }
                else
                {
                    document.getElementById(gGoogleMapControlId + "txtLat").value = point.y.toFixed(8);
                    document.getElementById(gGoogleMapControlId + "txtLng").value = point.x.toFixed(8);            
                }
              //marker.openInfoWindowHtml(address);
            }
          }
        );
      }
    }    
    

function GridToLatLong2(x,y) {
  var gr = [x,y];
  var E = gr[0], N = gr[1];

  var a = 6377563.396, b = 6356256.910;              // Airy 1830 major & minor semi-axes
  var F0 = 0.9996012717;                             // NatGrid scale factor on central meridian
  var lat0 = 49*Math.PI/180, lon0 = -2*Math.PI/180;  // NatGrid true origin
  var N0 = -100000, E0 = 400000;                     // northing & easting of true origin, metres
  var e2 = 1 - (b*b)/(a*a);                          // eccentricity squared
  var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n;

  var lat=lat0, M=0;
  do {
    lat = (N-N0-M)/(a*F0) + lat;

    var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
    var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
    var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
    var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
    M = b * F0 * (Ma - Mb + Mc - Md);                // meridional arc

  } while (N-N0-M >= 0.00001);  // ie until < 0.01mm

  var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
  var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);              // transverse radius of curvature
  var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);  // meridional radius of curvature
  var eta2 = nu/rho-1;

  var tanLat = Math.tan(lat);
  var tan2lat = tanLat*tanLat, tan4lat = tan2lat*tan2lat, tan6lat = tan4lat*tan2lat;
  var secLat = 1/cosLat;
  var nu3 = nu*nu*nu, nu5 = nu3*nu*nu, nu7 = nu5*nu*nu;
  var VII = tanLat/(2*rho*nu);
  var VIII = tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2);
  var IX = tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat);
  var X = secLat/nu;
  var XI = secLat/(6*nu3)*(nu/rho+2*tan2lat);
  var XII = secLat/(120*nu5)*(5+28*tan2lat+24*tan4lat);
  var XIIA = secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat);

  var dE = (E-E0), dE2 = dE*dE, dE3 = dE2*dE, dE4 = dE2*dE2, dE5 = dE3*dE2, dE6 = dE4*dE2, dE7 = dE5*dE2;
  lat = lat - VII*dE2 + VIII*dE4 - IX*dE6;
  var lon = lon0 + X*dE - XI*dE3 + XII*dE5 - XIIA*dE7;
//alert(lat+'+'+lon)
//alert(lat.toDeg()+'+'+lon.toDeg())
  return new LatLng(lat.toDeg(), lon.toDeg());
}    
/*
 * convert OS grid reference to geodesic co-ordinates
 */
function OSGridToLatLong2(gridRef) {
  var gr = gridrefLetToNum(gridRef);
  var E = gr[0], N = gr[1];

  var a = 6377563.396, b = 6356256.910;              // Airy 1830 major & minor semi-axes
  var F0 = 0.9996012717;                             // NatGrid scale factor on central meridian
  var lat0 = 49*Math.PI/180, lon0 = -2*Math.PI/180;  // NatGrid true origin
  var N0 = -100000, E0 = 400000;                     // northing & easting of true origin, metres
  var e2 = 1 - (b*b)/(a*a);                          // eccentricity squared
  var n = (a-b)/(a+b), n2 = n*n, n3 = n*n*n;

  var lat=lat0, M=0;
  do {
    lat = (N-N0-M)/(a*F0) + lat;

    var Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
    var Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
    var Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
    var Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
    M = b * F0 * (Ma - Mb + Mc - Md);                // meridional arc

  } while (N-N0-M >= 0.00001);  // ie until < 0.01mm

  var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
  var nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);              // transverse radius of curvature
  var rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);  // meridional radius of curvature
  var eta2 = nu/rho-1;

  var tanLat = Math.tan(lat);
  var tan2lat = tanLat*tanLat, tan4lat = tan2lat*tan2lat, tan6lat = tan4lat*tan2lat;
  var secLat = 1/cosLat;
  var nu3 = nu*nu*nu, nu5 = nu3*nu*nu, nu7 = nu5*nu*nu;
  var VII = tanLat/(2*rho*nu);
  var VIII = tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2);
  var IX = tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat);
  var X = secLat/nu;
  var XI = secLat/(6*nu3)*(nu/rho+2*tan2lat);
  var XII = secLat/(120*nu5)*(5+28*tan2lat+24*tan4lat);
  var XIIA = secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat);

  var dE = (E-E0), dE2 = dE*dE, dE3 = dE2*dE, dE4 = dE2*dE2, dE5 = dE3*dE2, dE6 = dE4*dE2, dE7 = dE5*dE2;
  lat = lat - VII*dE2 + VIII*dE4 - IX*dE6;
  var lon = lon0 + X*dE - XI*dE3 + XII*dE5 - XIIA*dE7;
//alert(lat+'+'+lon)
//alert(lat.toDeg()+'+'+lon.toDeg())
  return new LatLng(lat.toDeg(), lon.toDeg());
}
//function LatLon(lat, lon, height) {
//  if (arguments.length < 3) height = 0;
//  this.lat = lat;
//  this.lon = lon;
//  this.height = height;
//}
Number.prototype.toRad = function() {  // convert degrees to radians
  return this * Math.PI / 180;
}

Number.prototype.toDeg = function() {  // convert radians to degrees (signed)
  return this * 180 / Math.PI;
}
/* 
 * convert standard grid reference ('SU387148') to fully numeric ref ([438700,114800])
 *   returned co-ordinates are in metres, centred on grid square for conversion to lat/long
 *
 *   note that northern-most grid squares will give 7-digit northings
 *   no error-checking is done on gridref (bad input will give bad results or NaN)
 */
function gridrefLetToNum(gridref) {
  // get numeric values of letter references, mapping A->0, B->1, C->2, etc:
  var l1 = gridref.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0);
  var l2 = gridref.toUpperCase().charCodeAt(1) - 'A'.charCodeAt(0);
  // shuffle down letters after 'I' since 'I' is not used in grid:
  if (l1 > 7) l1--;
  if (l2 > 7) l2--;

  // convert grid letters into 100km-square indexes from false origin (grid square SV):
  var e = ((l1-2)%5)*5 + (l2%5);
  var n = (19-Math.floor(l1/5)*5) - Math.floor(l2/5);

  // skip grid letters to get numeric part of ref, stripping any spaces:
  gridref = gridref.slice(2).replace(/ /g,'');

  // append numeric part of references to grid index:
  e += gridref.slice(0, gridref.length/2);
  n += gridref.slice(gridref.length/2);

  // normalise to 1m grid, rounding up to centre of grid square:
  switch (gridref.length) {
    case 6: e += '50'; n += '50'; break;
    case 8: e += '5'; n += '5'; break;
    // 10-digit refs are already 1m
  }

  return [e, n];
}

       
//--------------------------------------------------------------------------
// JScoord
// jscoord.js
//
// (c) 2005 Jonathan Stott
//
// Created on 21-Dec-2005
//
// 1.1.1 - 16 Jan 2006
//  - Fixed radix bug in getOSRefFromSixFigureReference that would return
//    the incorrect reference if either the northing or the easting started
//    with a leading zero.
// 1.1 - 23 Dec 2005
//  - Added getOSRefFromSixFigureReference function.
// 1.0 - 11 Aug 2005
//  - Initial version created from PHPcoord v1.1
//--------------------------------------------------------------------------

    
// ================================================================== LatLng

function LatLng(lat, lng) {
    
  this.lat = lat;
  this.lng = lng;
     
  this.distance = LatLngDistance;
      
  this.toOSRef = LatLngToOSRef;
  this.toUTMRef = LatLngToUTMRef;
      
  this.WGS84ToOSGB36 = WGS84ToOSGB36;
  this.OSGB36ToWGS84 = OSGB36ToWGS84;
       
  this.toString = LatLngToString;
}

function LatLngToString() {
  return "(" + this.lat + ", " + this.lng + ")";
}


// =================================================================== OSRef

// References given with OSRef are accurate to 1m.
function OSRef(easting, northing) {
  this.easting  = easting;
  this.northing = northing;
    
  this.toLatLng = OSRefToLatLng;
    
  this.toString = OSRefToString;
  this.toSixFigureString = OSRefToSixFigureString;
}


function OSRefToString() {
  return "(" + this.easting + ", " + this.northing + ")";
}


function OSRefToSixFigureString() {
  var hundredkmE = Math.floor(this.easting / 100000);
  var hundredkmN = Math.floor(this.northing / 100000);
  var firstLetter = "";
  if (hundredkmN < 5) {
    if (hundredkmE < 5) {
      firstLetter = "S";
    } else {
      firstLetter = "T";
    }
  } else if (hundredkmN < 10) {
    if (hundredkmE < 5) {
      firstLetter = "N";
    } else {
      firstLetter = "O";
    }
  } else {
    firstLetter = "H";
  }

  var secondLetter = "";
  var index = 65 + ((4 - (hundredkmN % 5)) * 5) + (hundredkmE % 5);
  var ti = index;
  if (index >= 73) index++;
  secondLetter = chr(index);

  var e = Math.floor((this.easting - (100000 * hundredkmE)) / 100);
  var n = Math.floor((this.northing - (100000 * hundredkmN)) / 100);
  var es = e;
  if (e < 100) es = "0" + es;
  if (e < 10)  es = "0" + es;
  var ns = n;
  if (n < 100) ns = "0" + ns;
  if (n < 10)  ns = "0" + ns;

  return firstLetter + secondLetter + es + ns;
}


// ================================================================== UTMRef

function UTMRef(easting, northing, latZone, lngZone) {
  this.easting  = easting;
  this.northing = northing;
  this.latZone  = latZone;
  this.lngZone  = lngZone;
    
  this.toLatLng = UTMRefToLatLng;
    
  this.toString = UTMRefToString;
}


function UTMRefToString() {
  return this.lngZone + this.latZone + " " +
         this.easting + " " + this.northing;
}


// ================================================================== RefEll

function RefEll(maj, min) {
  this.maj = maj;
  this.min = min;
  this.ecc = ((maj * maj) - (min * min)) / (maj * maj);
}


// ================================================== Mathematical Functions

function sinSquared(x) {
  return Math.sin(x) * Math.sin(x);
}

function cosSquared(x) {
  return Math.cos(x) * Math.cos(x);
}

function tanSquared(x) {
  return Math.tan(x) * Math.tan(x);
}

function sec(x) {
  return 1.0 / Math.cos(x);
}
  
function deg2rad(x) {
  return x * (Math.PI / 180);
}
  
function rad2deg(x) {
  return x * (180 / Math.PI);
}
  
function chr(x) {
  var h = x.toString (16);
  if (h.length == 1)
    h = "0" + h;
  h = "%" + h;
  return unescape (h);
}
  
function ord(x) {
  var c = x.charAt(0);
  var i;
  for (i = 0; i < 256; ++ i) {
    var h = i.toString (16);
    if (h.length == 1)
      h = "0" + h;
    h = "%" + h;
    h = unescape (h);
    if (h == c)
      break;
  }
  return i;
}


// ========================================================= Other Functions

function LatLngDistance(to) {
  var er = 6366.707;

  var latFrom = deg2rad(this.lat);
  var latTo   = deg2rad(to.lat);
  var lngFrom = deg2rad(this.lng);
  var lngTo   = deg2rad(to.lng);

  var x1 = er * Math.cos(lngFrom) * Math.sin(latFrom);
  var y1 = er * Math.sin(lngFrom) * Math.sin(latFrom);
  var z1 = er * Math.cos(latFrom);

  var x2 = er * Math.cos(lngTo) * Math.sin(latTo);
  var y2 = er * Math.sin(lngTo) * Math.sin(latTo);
  var z2 = er * Math.cos(latTo);

  var d = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));

  return d;
}


// ==================================================== Conversion Functions

function OSGB36ToWGS84() {
  var airy1830 = new RefEll(6377563.396, 6356256.909);
  var a        = airy1830.maj;
  var b        = airy1830.min;
  var eSquared = airy1830.ecc;
  var phi = deg2rad(this.lat);
  var lambda = deg2rad(this.lng);
  var v = a / (Math.sqrt(1 - eSquared * sinSquared(phi)));
  var H = 0; // height
  var x = (v + H) * Math.cos(phi) * Math.cos(lambda);
  var y = (v + H) * Math.cos(phi) * Math.sin(lambda);
  var z = ((1 - eSquared) * v + H) * Math.sin(phi);

  var tx =        446.448;
  var ty =       -124.157;
  var tz =        542.060;
  var s  =         -0.0000204894;
  var rx = deg2rad( 0.00004172222);
  var ry = deg2rad( 0.00006861111);
  var rz = deg2rad( 0.00023391666);

  var xB = tx + (x * (1 + s)) + (-rx * y)     + (ry * z);
  var yB = ty + (rz * x)      + (y * (1 + s)) + (-rx * z);
  var zB = tz + (-ry * x)     + (rx * y)      + (z * (1 + s));

  var wgs84 = new RefEll(6378137.000, 6356752.3141);
  a        = wgs84.maj;
  b        = wgs84.min;
  eSquared = wgs84.ecc;

  var lambdaB = rad2deg(Math.atan(yB / xB));
  var p = Math.sqrt((xB * xB) + (yB * yB));
  var phiN = Math.atan(zB / (p * (1 - eSquared)));
  for (var i = 1; i < 10; i++) {
    v = a / (Math.sqrt(1 - eSquared * sinSquared(phiN)));
    phiN1 = Math.atan((zB + (eSquared * v * Math.sin(phiN))) / p);
    phiN = phiN1;
  }

  var phiB = rad2deg(phiN);
    
  this.lat = phiB;
  this.lng = lambdaB;
}

function WGS84ToOSGB36() {
  var wgs84 = new RefEll(6378137.000, 6356752.3141);
  var a        = wgs84.maj;
  var b        = wgs84.min;
  var eSquared = wgs84.ecc;
  var phi = deg2rad(this.lat);
  var lambda = deg2rad(this.lng);
  var v = a / (Math.sqrt(1 - eSquared * sinSquared(phi)));
  var H = 0; // height
  var x = (v + H) * Math.cos(phi) * Math.cos(lambda);
  var y = (v + H) * Math.cos(phi) * Math.sin(lambda);
  var z = ((1 - eSquared) * v + H) * Math.sin(phi);

  var tx =       -446.448;
  var ty =        124.157;
  var tz =       -542.060;
  var s  =          0.0000204894;
  var rx = deg2rad(-0.00004172222);
  var ry = deg2rad(-0.00006861111);
  var rz = deg2rad(-0.00023391666);

  var xB = tx + (x * (1 + s)) + (-rx * y)     + (ry * z);
  var yB = ty + (rz * x)      + (y * (1 + s)) + (-rx * z);
  var zB = tz + (-ry * x)     + (rx * y)      + (z * (1 + s));

  var airy1830 = new RefEll(6377563.396, 6356256.909);
  a        = airy1830.maj;
  b        = airy1830.min;
  eSquared = airy1830.ecc;

  var lambdaB = rad2deg(Math.atan(yB / xB));
  var p = Math.sqrt((xB * xB) + (yB * yB));
  var phiN = Math.atan(zB / (p * (1 - eSquared)));
  for (var i = 1; i < 10; i++) {
    v = a / (Math.sqrt(1 - eSquared * sinSquared(phiN)));
    phiN1 = Math.atan((zB + (eSquared * v * Math.sin(phiN))) / p);
    phiN = phiN1;
  }

  var phiB = rad2deg(phiN);
    
  this.lat = phiB;
  this.lng = lambdaB;
}

function OSRefToLatLng() {
  var airy1830 = new RefEll(6377563.396, 6356256.909);
  var OSGB_F0  = 0.9996012717;
  var N0       = -100000.0;
  var E0       = 400000.0;
  var phi0     = deg2rad(49.0);
  var lambda0  = deg2rad(-2.0);
  var a        = airy1830.maj;
  var b        = airy1830.min;
  var eSquared = airy1830.ecc;
  var phi      = 0.0;
  var lambda   = 0.0;
  var E        = this.easting;
  var N        = this.northing;
  var n        = (a - b) / (a + b);
  var M        = 0.0;
  var phiPrime = ((N - N0) / (a * OSGB_F0)) + phi0;
  do {
    M =
      (b * OSGB_F0)
        * (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n))
          * (phiPrime - phi0))
          - (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))
            * Math.sin(phiPrime - phi0)
            * Math.cos(phiPrime + phi0))
          + ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))
            * Math.sin(2.0 * (phiPrime - phi0))
            * Math.cos(2.0 * (phiPrime + phi0)))
          - (((35.0 / 24.0) * n * n * n)
            * Math.sin(3.0 * (phiPrime - phi0))
            * Math.cos(3.0 * (phiPrime + phi0))));
    phiPrime += (N - N0 - M) / (a * OSGB_F0);
  } while ((N - N0 - M) >= 0.001);
  var v = a * OSGB_F0 * Math.pow(1.0 - eSquared * sinSquared(phiPrime), -0.5);
  var rho =
    a
      * OSGB_F0
      * (1.0 - eSquared)
      * Math.pow(1.0 - eSquared * sinSquared(phiPrime), -1.5);
  var etaSquared = (v / rho) - 1.0;
  var VII = Math.tan(phiPrime) / (2 * rho * v);
  var VIII =
    (Math.tan(phiPrime) / (24.0 * rho * Math.pow(v, 3.0)))
      * (5.0
        + (3.0 * tanSquared(phiPrime))
        + etaSquared
        - (9.0 * tanSquared(phiPrime) * etaSquared));
  var IX =
    (Math.tan(phiPrime) / (720.0 * rho * Math.pow(v, 5.0)))
      * (61.0
        + (90.0 * tanSquared(phiPrime))
        + (45.0 * tanSquared(phiPrime) * tanSquared(phiPrime)));
  var X = sec(phiPrime) / v;
  var XI =
    (sec(phiPrime) / (6.0 * v * v * v))
      * ((v / rho) + (2 * tanSquared(phiPrime)));
  var XII =
    (sec(phiPrime) / (120.0 * Math.pow(v, 5.0)))
      * (5.0
        + (28.0 * tanSquared(phiPrime))
        + (24.0 * tanSquared(phiPrime) * tanSquared(phiPrime)));
  var XIIA =
    (sec(phiPrime) / (5040.0 * Math.pow(v, 7.0)))
      * (61.0
        + (662.0 * tanSquared(phiPrime))
        + (1320.0 * tanSquared(phiPrime) * tanSquared(phiPrime))
        + (720.0
          * tanSquared(phiPrime)
          * tanSquared(phiPrime)
          * tanSquared(phiPrime)));
  phi =
    phiPrime
      - (VII * Math.pow(E - E0, 2.0))
      + (VIII * Math.pow(E - E0, 4.0))
      - (IX * Math.pow(E - E0, 6.0));
  lambda =
    lambda0
      + (X * (E - E0))
      - (XI * Math.pow(E - E0, 3.0))
      + (XII * Math.pow(E - E0, 5.0))
      - (XIIA * Math.pow(E - E0, 7.0));

  return new LatLng(rad2deg(phi), rad2deg(lambda));
}


/**
 * Convert a latitude and longitude into an OSGB grid reference
 *
 * @param latitudeLongitude the latitude and longitude to convert
 * @return the OSGB grid reference
 * @since 0.1
 */
function LatLngToOSRef() {
  var airy1830 = new RefEll(6377563.396, 6356256.909);
  var OSGB_F0  = 0.9996012717;
  var N0       = -100000.0;
  var E0       = 400000.0;
  var phi0     = deg2rad(49.0);
  var lambda0  = deg2rad(-2.0);
  var a        = airy1830.maj;
  var b        = airy1830.min;
  var eSquared = airy1830.ecc;
  var phi = deg2rad(this.lat);
  var lambda = deg2rad(this.lng);
  var E = 0.0;
  var N = 0.0;
  var n = (a - b) / (a + b);
  var v = a * OSGB_F0 * Math.pow(1.0 - eSquared * sinSquared(phi), -0.5);
  var rho =
    a * OSGB_F0 * (1.0 - eSquared) * Math.pow(1.0 - eSquared * sinSquared(phi), -1.5);
  var etaSquared = (v / rho) - 1.0;
  var M =
    (b * OSGB_F0)
      * (((1 + n + ((5.0 / 4.0) * n * n) + ((5.0 / 4.0) * n * n * n))
        * (phi - phi0))
        - (((3 * n) + (3 * n * n) + ((21.0 / 8.0) * n * n * n))
          * Math.sin(phi - phi0)
          * Math.cos(phi + phi0))
        + ((((15.0 / 8.0) * n * n) + ((15.0 / 8.0) * n * n * n))
          * Math.sin(2.0 * (phi - phi0))
          * Math.cos(2.0 * (phi + phi0)))
        - (((35.0 / 24.0) * n * n * n)
          * Math.sin(3.0 * (phi - phi0))
          * Math.cos(3.0 * (phi + phi0))));
  var I = M + N0;
  var II = (v / 2.0) * Math.sin(phi) * Math.cos(phi);
  var III =
    (v / 24.0)
      * Math.sin(phi)
      * Math.pow(Math.cos(phi), 3.0)
      * (5.0 - tanSquared(phi) + (9.0 * etaSquared));
  var IIIA =
    (v / 720.0)
      * Math.sin(phi)
      * Math.pow(Math.cos(phi), 5.0)
      * (61.0 - (58.0 * tanSquared(phi)) + Math.pow(Math.tan(phi), 4.0));
  var IV = v * Math.cos(phi);
  var V = (v / 6.0) * Math.pow(Math.cos(phi), 3.0) * ((v / rho) - tanSquared(phi));
  var VI =
    (v / 120.0)
      * Math.pow(Math.cos(phi), 5.0)
      * (5.0
        - (18.0 * tanSquared(phi))
        + (Math.pow(Math.tan(phi), 4.0))
        + (14 * etaSquared)
        - (58 * tanSquared(phi) * etaSquared));

  N =
    I
      + (II * Math.pow(lambda - lambda0, 2.0))
      + (III * Math.pow(lambda - lambda0, 4.0))
      + (IIIA * Math.pow(lambda - lambda0, 6.0));
  E =
    E0
      + (IV * (lambda - lambda0))
      + (V * Math.pow(lambda - lambda0, 3.0))
      + (VI * Math.pow(lambda - lambda0, 5.0));

  return new OSRef(E, N);
}


/**
 * Convert an UTM reference to a latitude and longitude
 *
 * @param ellipsoid A reference ellipsoid to use
 * @param utm the UTM reference to convert
 * @return the converted latitude and longitude
 * @since 0.2
 */
function UTMRefToLatLng() {
  var wgs84 = new RefEll(6378137, 6356752.314);
  var UTM_F0   = 0.9996;
  var a = wgs84.maj;
  var eSquared = wgs84.ecc;
  var ePrimeSquared = eSquared / (1.0 - eSquared);
  var e1 = (1 - Math.sqrt(1 - eSquared)) / (1 + Math.sqrt(1 - eSquared));
  var x = this.easting - 500000.0;;
  var y = this.northing;
  var zoneNumber = this.lngZone;
  var zoneLetter = this.latZone;

  var longitudeOrigin = (zoneNumber - 1.0) * 6.0 - 180.0 + 3.0;

  // Correct y for southern hemisphere
  if ((ord(zoneLetter) - ord("N")) < 0) {
    y -= 10000000.0;
  }

  var m = y / UTM_F0;
  var mu =
    m
      / (a
        * (1.0
          - eSquared / 4.0
          - 3.0 * eSquared * eSquared / 64.0
          - 5.0
            * Math.pow(eSquared, 3.0)
            / 256.0));

  var phi1Rad =
    mu
      + (3.0 * e1 / 2.0 - 27.0 * Math.pow(e1, 3.0) / 32.0) * Math.sin(2.0 * mu)
      + (21.0 * e1 * e1 / 16.0 - 55.0 * Math.pow(e1, 4.0) / 32.0)
        * Math.sin(4.0 * mu)
      + (151.0 * Math.pow(e1, 3.0) / 96.0) * Math.sin(6.0 * mu);

  var n =
    a
      / Math.sqrt(1.0 - eSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad));
  var t = Math.tan(phi1Rad) * Math.tan(phi1Rad);
  var c = ePrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad);
  var r =
    a
      * (1.0 - eSquared)
      / Math.pow(
        1.0 - eSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad),
        1.5);
  var d = x / (n * UTM_F0);

  var latitude = (
    phi1Rad
      - (n * Math.tan(phi1Rad) / r)
        * (d * d / 2.0
          - (5.0
            + (3.0 * t)
            + (10.0 * c)
            - (4.0 * c * c)
            - (9.0 * ePrimeSquared))
            * Math.pow(d, 4.0)
            / 24.0
          + (61.0
            + (90.0 * t)
            + (298.0 * c)
            + (45.0 * t * t)
            - (252.0 * ePrimeSquared)
            - (3.0 * c * c))
            * Math.pow(d, 6.0)
            / 720.0)) * (180.0 / Math.PI);

  var longitude = longitudeOrigin + (
    (d
      - (1.0 + 2.0 * t + c) * Math.pow(d, 3.0) / 6.0
      + (5.0
        - (2.0 * c)
        + (28.0 * t)
        - (3.0 * c * c)
        + (8.0 * ePrimeSquared)
        + (24.0 * t * t))
        * Math.pow(d, 5.0)
        / 120.0)
      / Math.cos(phi1Rad)) * (180.0 / Math.PI);

  return new LatLng(latitude, longitude);
}


/**
 * Convert a latitude and longitude to an UTM reference
 *
 * @param ellipsoid A reference ellipsoid to use
 * @param latitudeLongitude The latitude and longitude to convert
 * @return the converted UTM reference
 * @since 0.2
 */
function LatLngToUTMRef() {
  var wgs84 = new RefEll(6378137, 6356752.314);
  var UTM_F0   = 0.9996;
  var a = wgs84.maj;
  var eSquared = wgs84.ecc;
  var longitude = this.lng;
  var latitude = this.lat;

  var latitudeRad = latitude * (Math.PI / 180.0);
  var longitudeRad = longitude * (Math.PI / 180.0);
  var longitudeZone = Math.floor((longitude + 180.0) / 6.0) + 1;

  // Special zone for Norway
  if (latitude >= 56.0
    && latitude < 64.0
    && longitude >= 3.0
    && longitude < 12.0) {
    longitudeZone = 32;
  }

  // Special zones for Svalbard
  if (latitude >= 72.0 && latitude < 84.0) {
    if (longitude >= 0.0 && longitude < 9.0) {
      longitudeZone = 31;
    } else if (longitude >= 9.0 && longitude < 21.0) {
      longitudeZone = 33;
    } else if (longitude >= 21.0 && longitude < 33.0) {
      longitudeZone = 35;
    } else if (longitude >= 33.0 && longitude < 42.0) {
      longitudeZone = 37;
    }
  }

  var longitudeOrigin = (longitudeZone - 1) * 6 - 180 + 3;
  var longitudeOriginRad = longitudeOrigin * (Math.PI / 180.0);

  var UTMZone = getUTMLatitudeZoneLetter(latitude);

  ePrimeSquared = (eSquared) / (1 - eSquared);

  var n = a / Math.sqrt(1 - eSquared * Math.sin(latitudeRad) * Math.sin(latitudeRad));
  var t = Math.tan(latitudeRad) * Math.tan(latitudeRad);
  var c = ePrimeSquared * Math.cos(latitudeRad) * Math.cos(latitudeRad);
  var A = Math.cos(latitudeRad) * (longitudeRad - longitudeOriginRad);

  var M =
    a
      * ((1
        - eSquared / 4
        - 3 * eSquared * eSquared / 64
        - 5 * eSquared * eSquared * eSquared / 256)
        * latitudeRad
        - (3 * eSquared / 8
          + 3 * eSquared * eSquared / 32
          + 45 * eSquared * eSquared * eSquared / 1024)
          * Math.sin(2 * latitudeRad)
        + (15 * eSquared * eSquared / 256
          + 45 * eSquared * eSquared * eSquared / 1024)
          * Math.sin(4 * latitudeRad)
        - (35 * eSquared * eSquared * eSquared / 3072)
          * Math.sin(6 * latitudeRad));

  var UTMEasting =
    (UTM_F0
      * n
      * (A
        + (1 - t + c) * Math.pow(A, 3.0) / 6
        + (5 - 18 * t + t * t + 72 * c - 58 * ePrimeSquared)
          * Math.pow(A, 5.0)
          / 120)
      + 500000.0);

  var UTMNorthing =
    (UTM_F0
      * (M
        + n
          * Math.tan(latitudeRad)
          * (A * A / 2
            + (5 - t + (9 * c) + (4 * c * c)) * Math.pow(A, 4.0) / 24
            + (61 - (58 * t) + (t * t) + (600 * c) - (330 * ePrimeSquared))
              * Math.pow(A, 6.0)
              / 720)));

  // Adjust for the southern hemisphere
  if (latitude < 0) {
    UTMNorthing += 10000000.0;
  }

  return new UTMRef(UTMEasting, UTMNorthing, UTMZone, longitudeZone);
}

/**
 * Take a string formatted as a six-figure OS grid reference (e.g.
 * "TG514131") and return a reference to an OSRef object that represents
 * that grid reference. The first character must be H, N, S, O or T.
 * The second character can be any uppercase character from A through Z
 * excluding I.
 *
 * @param ref
 * @return
 * @since 1.1
 */
function getOSRefFromSixFigureReference(ref) {
  var char1 = ref.substring(0, 1);
  var char2 = ref.substring(1, 2);
  // Thanks to Nick Holloway for pointing out the radix bug here
  var east  = parseInt(ref.substring(2, 5), 10) * 100;
  var north = parseInt(ref.substring(5, 8), 10) * 100;
  if (char1 == 'H') {
    north += 1000000;
  } else if (char1 == 'N') {
    north += 500000;
  } else if (char1 == 'O') {
    north += 500000;
    east  += 500000;
  } else if (char1 == 'T') {
    east += 500000;
  }
  var char2ord = ord(char2);
  if (char2ord > 73) char2ord--; // Adjust for no I
  var nx = ((char2ord - 65) % 5) * 100000;
  var ny = (4 - Math.floor((char2ord - 65) / 5)) * 100000;
  return new OSRef(east + nx, north + ny);
}


/**
 *  Work out the UTM latitude zone from the latitude
 *
 * @param latitude
 * @return
 * @since 0.2
 */
function getUTMLatitudeZoneLetter(latitude) {
  if ((84 >= latitude) && (latitude >= 72)) return "X";
  else if (( 72 > latitude) && (latitude >=  64)) return "W";
  else if (( 64 > latitude) && (latitude >=  56)) return "V";
  else if (( 56 > latitude) && (latitude >=  48)) return "U";
  else if (( 48 > latitude) && (latitude >=  40)) return "T";
  else if (( 40 > latitude) && (latitude >=  32)) return "S";
  else if (( 32 > latitude) && (latitude >=  24)) return "R";
  else if (( 24 > latitude) && (latitude >=  16)) return "Q";
  else if (( 16 > latitude) && (latitude >=   8)) return "P";
  else if ((  8 > latitude) && (latitude >=   0)) return "N";
  else if ((  0 > latitude) && (latitude >=  -8)) return "M";
  else if (( -8 > latitude) && (latitude >= -16)) return "L";
  else if ((-16 > latitude) && (latitude >= -24)) return "K";
  else if ((-24 > latitude) && (latitude >= -32)) return "J";
  else if ((-32 > latitude) && (latitude >= -40)) return "H";
  else if ((-40 > latitude) && (latitude >= -48)) return "G";
  else if ((-48 > latitude) && (latitude >= -56)) return "F";
  else if ((-56 > latitude) && (latitude >= -64)) return "E";
  else if ((-64 > latitude) && (latitude >= -72)) return "D";
  else if ((-72 > latitude) && (latitude >= -80)) return "C";
  else return 'Z';
}    
//]]>
