Click here to Skip to main content
15,894,630 members
Articles / Web Development / HTML

AJAX Enabled Google Maps ASP.NET Control

Rate me:
Please Sign up or sign in to vote.
4.64/5 (20 votes)
12 Jul 2010CPOL3 min read 52.3K   2.9K   76  
Using the Google Maps API on server side with AJAX support.
#region Copyright (c), Some Rights Reserved
/*##########################################################################
 * 
 * GoogleMap.cs
 * -------------------------------------------------------------------------
 * By
 * Murat Firat, April 2010
 * bmfirat@gmail.com
 * 
 * -------------------------------------------------------------------------
 * Description:
 * implements asp.net web control that provides handling google map api on server side..
 * 
 * -------------------------------------------------------------------------
 ###########################################################################*/
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Globalization;
using System.Text.RegularExpressions;

namespace GoogleMap
{
    public struct Position
    {
        public Position(double latitude, double longtitude)
        {
            this.latitude = latitude;
            this.longtitude = longtitude;
        }
        public double latitude;
        public double longtitude;

        public override string ToString()
        {
            return "lat:" + latitude + "-lng:" + longtitude;
            //return base.ToString();
        }
    }

    public delegate void MapCenterChangedEventHandler();
    public delegate void ZoomChangedEventHandler();
    public delegate void MapTypeChangedEventHandler();
    public delegate void MapClickedEventHandler(double Latitude, double Longtitude);

    public class GoogleMap : Control, ICallbackEventHandler
    {
        public event MapCenterChangedEventHandler MapCenterChanged;
        public event ZoomChangedEventHandler ZoomChanged;
        public event MapTypeChangedEventHandler MapTypeChanged;
        public event MapClickedEventHandler MapClicked;

        public string JsFilePath = "GoogleMap.js";

        private MapInfo mapinfo = new MapInfo();
        private MarkerList markers = new MarkerList();

        public MapInfo MapInfo
        { get { return mapinfo; } }

        public MarkerList Markers
        { get { return markers; } }

        private HtmlInputHidden hdMapInfo = new HtmlInputHidden();
        private HtmlInputHidden hdAttachedEvents = new HtmlInputHidden();

        //lat::29.444,,lng::40.11,,imgsrc::http://ghghghh,,imgw::12,,imgh::12||lat::29.33,,lng::40.41,,imgsrc::http://dfdf,imgw:12,imgh:12
        public HtmlInputHidden hdMarkers = new HtmlInputHidden();

        public HtmlInputHidden hdRouteMapInfo = new HtmlInputHidden();

        private uint width = 500;
        private uint height = 500;

        public uint Width
        {
            get
            {
                if (ViewState["Width"] == null) return width;//default
                return uint.Parse(ViewState["Width"].ToString());
            }
            set { ViewState["Width"] = value; }
        }
        public uint Height
        {
            get
            {
                if (ViewState["Height"] == null) return height;
                return uint.Parse(ViewState["Height"].ToString());
            }
            set { ViewState["Height"] = value; }
        }
        
        public void PlayRouteMap(List<Position> Positions, int MoveInterval, Marker PositionMarker)
        {
            if (Positions.Count < 2) return;

            //string routeMapInfo hh= "MoveInterval::" + 500;
            string routeMapInfo = "positions==";
            foreach (Position p in Positions)
            {
                routeMapInfo += p.latitude.ToString().Replace(',', '.') + "," + p.longtitude.ToString().Replace(',', '.') + "-";
            }

            routeMapInfo.Remove(routeMapInfo.Length - 1, 1);
            routeMapInfo += ",,,moveinterval==" + MoveInterval + ",,,positionmarker==" + PositionMarker.ToString();

            hdRouteMapInfo.Value = routeMapInfo;
        }

        protected override void OnInit(EventArgs e)
        {
            //post data ile gelen parametreleri al..

            hdMapInfo.ID = "hdMapInfo";
            hdMapInfo.Name = hdMapInfo.ID;

            hdAttachedEvents.ID = "hdAttachedEvents";
            hdAttachedEvents.Name = hdAttachedEvents.ID;

            hdMarkers.ID = "hdMarkers";
            hdMarkers.Name = hdMarkers.ID;

            hdRouteMapInfo.ID = "hdRouteMapInfo";
            hdRouteMapInfo.Name = hdRouteMapInfo.ID;

            Dictionary<string, int> postData = new Dictionary<string, int>();

            string[] allPostKeys = Page.Request.Form.AllKeys;
            for (int i = 0; i < allPostKeys.Length; i++)
                postData.Add(allPostKeys[i], i);

            if (postData.ContainsKey(hdMapInfo.ID))
                hdMapInfo.Value = Page.Request.Form.Get(postData[hdMapInfo.ID]);

            if (postData.ContainsKey(hdAttachedEvents.ID))
                hdAttachedEvents.Value = Page.Request.Form.Get(postData[hdAttachedEvents.ID]);

            if (postData.ContainsKey(hdMarkers.ID))
                hdMarkers.Value = Page.Request.Form.Get(postData[hdMarkers.ID]);

            MapInfo reqMapInfo = MapInfo.FromString(hdMapInfo.Value);

            if (reqMapInfo != null)
            {
                this.mapinfo.MapType = reqMapInfo.MapType;
                this.mapinfo.Zoom = reqMapInfo.Zoom;
                this.mapinfo.Latitude = reqMapInfo.Latitude;
                this.mapinfo.Longtitude = reqMapInfo.Longtitude;
            }

            MarkerList mlist = MarkerList.FromString(hdMarkers.Value);
            if (mlist != null) this.markers = mlist;

            //load mapinfo ,  markers here...

            base.OnInit(e);
        }

        //public void PlayRouteMap

        //works on only postbacks
        //burasi sadece postbacklarda calisiyor, hiddenfieldleri icerde doldur!!
        protected override void Render(HtmlTextWriter writer)
        {
            string AttachedEvents = "";
            if (MapCenterChanged != null) AttachedEvents += "MapCenterChanged,";
            if (ZoomChanged != null) AttachedEvents += "ZoomChanged,";
            if (MapTypeChanged != null) AttachedEvents += "MapTypeChanged,";
            if (MapClicked != null) AttachedEvents += "MapClicked,";

            hdMapInfo.Value = this.mapinfo.ToString();
            hdAttachedEvents.Value = AttachedEvents;
            hdMarkers.Value = markers.ToString();

            hdMapInfo.RenderControl(writer);
            hdAttachedEvents.RenderControl(writer);
            hdMarkers.RenderControl(writer);
            hdRouteMapInfo.RenderControl(writer);

            writer.Write("<div id='map_canvas' style='width:" + this.Width + "px; height:" + this.Height + "px'></div>");
            writer.Write("<script type='text/javascript'>");
            writer.Write("Initialize();");
            writer.Write(" </script>");
            
            writer.Write("<script type='text/javascript'>");
            writer.Write("function DoCallBack(clientarg, callbackfnc, clientcontext, errcallbackfnc)");
            writer.Write("{");
            string s = Page.ClientScript.GetCallbackEventReference(this, "clientarg", "callbackfnc", "clientcontext", "errcallbackfnc", false);
            writer.Write(s + ";");
            writer.Write("}");
            writer.Write(" </script>");

            base.Render(writer);
        }

        protected override void OnPreRender(EventArgs e)
        {
            //js scriptleri referans et
            if (!Page.ClientScript.IsClientScriptIncludeRegistered("jsScript"))
                Page.ClientScript.RegisterClientScriptInclude("jsScript", JsFilePath);

            if (!Page.ClientScript.IsClientScriptIncludeRegistered("gmappath"))
                Page.ClientScript.RegisterClientScriptInclude("gmappath", "http://maps.google.com/maps/api/js?sensor=false");

            base.OnPreRender(e);
        }

        #region ICallbackEventHandler Members

        public void RaiseCallbackEvent(string eventArgument)
        {
            //var clientArg= 'eventtype:'+eventTypeId+'<hdMapInfo>'+mapInfo+'</hdMapInfo>'+'<hdMarkers>'+markersInfo+'</hdMarkers>';

            if (!Regex.IsMatch(eventArgument, "eventtype:.+<hdMapInfo>.+</hdMapInfo><hdMarkers>.*</hdMarkers>"))
                return;

            CultureInfo ciTR = new CultureInfo("tr-TR");

            string eventtype = eventArgument.Substring(10, eventArgument.IndexOf("<hdMapInfo>") - 10);
            string mapInfoStr = eventArgument.Substring(eventArgument.IndexOf("<hdMapInfo>") + "<hdMapInfo>".Length,
                eventArgument.IndexOf("</hdMapInfo>") - "<hdMapInfo>".Length - eventArgument.IndexOf("<hdMapInfo>"));
            string markersStr = eventArgument.Substring(eventArgument.IndexOf("<hdMarkers>") + "<hdMarkers>".Length,
                eventArgument.IndexOf("</hdMarkers>") - "<hdMarkers>".Length - eventArgument.IndexOf("<hdMarkers>"));

            string extra1 = null, extra2 = null, extra3 = null;
            MapInfo reqMapInfo = MapInfo.FromString(mapInfoStr, ref extra1, ref extra2, ref extra3);

            this.markers = MarkerList.FromString(markersStr);

            this.mapinfo.MapType = reqMapInfo.MapType;
            this.mapinfo.Zoom = reqMapInfo.Zoom;
            this.mapinfo.Latitude = reqMapInfo.Latitude;
            this.mapinfo.Longtitude = reqMapInfo.Longtitude;

            //MapInfo mapInfCopy = this.mapinfo.Copy();
            MapInfo mapInfCopyConst = this.mapinfo.Copy();
            MarkerList markerListCopyConst = this.markers.Copy();

            switch (eventtype.ToLower())
            {
                case "mapcenterchanged":
                    if (MapCenterChanged != null)
                        MapCenterChanged.Invoke();
                    break;
                case "zoomchanged":
                    if (ZoomChanged != null)
                        ZoomChanged.Invoke();
                    break;
                case "maptypechanged":
                    if (MapTypeChanged != null)
                        MapTypeChanged.Invoke();
                    break;
                case "mapclicked":
                    if (MapClicked != null)
                        MapClicked.Invoke(
                            double.Parse(extra1.Replace(".", ","), ciTR.NumberFormat),//lat
                            double.Parse(extra2.Replace(".", ","), ciTR.NumberFormat));//lng
                    break;
                default:
                    break;
            }

            responceString = "";

            foreach (Marker m in this.markers.Values)
            {
                if (markerListCopyConst.ContainsKey(m.MarkerId))
                {
                    if (markerListCopyConst[m.MarkerId].ToString() != m.ToString())
                    {
                        //marker updated, updatemarker operation
                        responceString += "||updatemarker####" + m.ToString();
                    }
                }
                else
                {
                    //new marker, addmarker operation
                    responceString += "||addmarker####" + m.ToString();
                }
            }

            if (!string.IsNullOrEmpty(hdRouteMapInfo.Value)) responceString += "||playroutemap####" + hdRouteMapInfo.Value;

            if (this.mapinfo.Latitude != mapInfCopyConst.Latitude || this.mapinfo.Longtitude != mapInfCopyConst.Longtitude)
                responceString += "||setcenter####" + this.mapinfo.Latitude.ToString().Replace(",", ".")
                    + ",," + this.mapinfo.Longtitude.ToString().Replace(",", ".");
            if (this.mapinfo.Zoom != mapInfCopyConst.Zoom)
                responceString += "||setzoom####" + this.mapinfo.Zoom.ToString();
            if (this.mapinfo.MapType != mapInfCopyConst.MapType)
                responceString += "||setmaptype####" + this.mapinfo.MapType.ToString();

            //remove 1st char
            if (responceString.Length > 0) responceString = responceString.Substring(2, responceString.Length - 2);

            //burda clientten gelen stringgi parse et gereken return stringi generate et
            //throw new Exception("The method or operation is not implemented.");
        }

        string responceString = "";
        public string GetCallbackResult()
        {
            return responceString;
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Turkey Turkey
Has BS degree on computer science, working as software engineer in istanbul.

Comments and Discussions