Following on from my Google Analytics server control, I wanted make something "cooler", so creating a Server Control to render a Google Map control seemed ideal. Part 1 covers the creation of the this control, stay tuned for part 2 which will focus on creating a custom EPiServer property so it can be used in the EPiServer edit area, featuring Geocoding to lookup the coordinates from a UK post code, Map type selection and zoom level.

Anyway here's the generic bit that can be used on any site...

First off we need a set of basic properties to hold Latitude, Longitude, Zoom Level and Map Type:

public double Latitude
{
    get { return GetPropertyValue("Latitude", (double)0); }
    set { SetPropertyValue("Latitude", value); }
}
public double Longitude
{
    get { return GetPropertyValue("Longitude", (double)0); }
    set { SetPropertyValue("Longitude", value); }
}
public int Zoom
{
    get { return GetPropertyValue("Zoom", 5); }
    set { SetPropertyValue("Zoom", value); }
}
public string MapType
{
    get { return GetPropertyValue("MapType", "Map"); }
    set { SetPropertyValue("MapType", value); }
}

Next come's the rather complex looking JavaScript code. I've done it so that it will allow multiple controls to be placed on the same page. IMPORTANT: Make sure you {0} in COMMONJAVASCRIPT is your unique Google Maps/API Key, which is generated on a per domain basis.

private const string COMMONJAVASCRIPT = @"
        <script src=""http://maps.google.com/maps?file=api&amp;v=2&amp;key={0}"" type=""text/javascript""></script>
        <script src=""http://www.google.com/uds/api?file=uds.js&amp;v=1.0&amp;key={0}"" type=""text/javascript""></script>";
        
        private const string JAVASCRIPT = @"
        <script type=""text/javascript"">
        function GoogleMapLoad{6}() {{
          if (GBrowserIsCompatible()) {{
            var map = new GMap2(document.getElementById(""{3}""));
        
                if(""{5}"" == ""Hybrid"")
                   map.setCenter(new GLatLng({1},{2}), parseInt({4}), G_HYBRID_MAP);
                else if(""{5}"" == ""Satellite"")
                   map.setCenter(new GLatLng({1},{2}), parseInt({4}), G_SATELLITE_MAP);
                else
                   map.setCenter(new GLatLng({1},{2}), parseInt({4}), G_NORMAL_MAP);
                
                var point = new GLatLng({1},{2});
                map.addOverlay(new GMarker(point));
                map.addControl(new GMapTypeControl());
                map.addControl(new GLargeMapControl());
            }}
        }}
        </script>";

Next we need to override the default tag that the server control would typically render (span) with a div, so that the Google map has a "canvas".

//Google map must be rendered inside a <DIV> tag, so we'll override the default <SPAN>.
protected override HtmlTextWriterTag TagKey
{
    get
    {
        //Return DIV not SPAN
        return HtmlTextWriterTag.Div;
    }
}

And last but not least, the overloaded CreateChildControls(). Firstly we check to see if there are (valid) Latitude and longitude values, if there is we register two blocks of JavaScript. Notice the second block's key includes the controls ID - which allows multiple maps to be used on the same page. The first 'common' block will only be registered once regardless of how many maps on the page. The second block has five strings passed to it which include the Google API Key (stored in the AppSettings) the control's ClientID (so the map's canvas can be accessed) along with the lat/lng/zoom etc.

protected override void CreateChildControls()
{
    if (Latitude != 0 && Longitude != 0)
    {
        //Check if the COMMON google map javascript block has been registered
        if (!Page.ClientScript.IsClientScriptBlockRegistered(typeof(GoogleMap), "GoogleMap"))
            Page.ClientScript.RegisterClientScriptBlock(typeof(GoogleMap), "GoogleMap", COMMONJAVASCRIPT);

        //Check if the google map javascript block for THIS map has been registered
        if (!Page.ClientScript.IsClientScriptBlockRegistered(typeof(GoogleMap), "GoogleMap" + ID))
            Page.ClientScript.RegisterClientScriptBlock(typeof(GoogleMap), "GoogleMap" + ID, 
                string.Format(CultureInfo.InvariantCulture, JAVASCRIPT,
                        WebConfigurationManager.AppSettings["GoogleMapKey"], //0
                        Latitude,  //1
                        Longitude, //2
                        this.ClientID, //3
                        Zoom, // 4
                        MapType, //5
                        ClientID //6), 
                    false);

        //Now we need to add the google maps onload JavaScript function for THIS MAP ONLY (it its not be added already)
        if (!Page.ClientScript.IsStartupScriptRegistered(typeof(GoogleMap), "GoogleMapLoad" + ID))
            Page.ClientScript.RegisterStartupScript(typeof(GoogleMap), "GoogleMapLoad" + ID, string.Format("GoogleMapLoad{0}();", ClientID), true);

        //Now we need to add the google maps onUNload JavaScript function (it its not be added already)
        if (!Page.ClientScript.IsStartupScriptRegistered(typeof(GoogleMap), "GoogleMapUnload"))
            Page.ClientScript.RegisterStartupScript(typeof(GoogleMap), "GoogleMapUnload", "window.onunload = function () { GUnload(); };", true);
    }
    //now call the base controls Create Child Controls
    base.CreateChildControls();
}

UPDATED: Check out part 2 for how to use this with EPiServer.


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist
posted @ Friday, June 06, 2008 4:17 PM | in C# EPiServer .NET ASP.NET AJAX ASP.NET

Comments

Gravatar
# View Google Analytics in Google Earth and in Google Maps
Posted by Johann Blake
on 6/16/2008 1:15 PM
You can view Google Analytics data in Google Earth and in Google Maps using a free online web service located at:

http://www.mobilgistix.com/web-services/Google_Analytics/google-earth-analytics.aspx

Post Comment

Title *
Name *
Email
Url
Comment *  


Please add 3 and 4 and type the answer here: