Important alert: (current site time 7/15/2013 7:49:57 AM EDT)
 

article

A Google Maps .Net Control

Email
Submitted on: 9/5/2005 4:28:13 PM
By: Bill Pierce 
Level: Intermediate
User Rating: By 2 Users
Compatibility: C#, VB.NET, ASP.NET
Views: 45184
 
     This article examines a custom ASP.Net server control I developed to make using the Google Maps API easier for .Net developers. This article assumes you are somewhat familiar with Google Maps (or are at least somewhat curious). If you're not familiar with Google Maps or its sweet API checkout http://maps.google.com/ and http://www.google.com/apis/maps/documentation/ for the low down. You may see references throughout the article to "my control, my GoogleMaps control, my GMap control, etc." I did not create the Google Maps API, I merely created a wrapper for ASP.Net using C#, XML, and XSL.

This article has accompanying files
 
 
Terms of Agreement:   
By using this article, you agree to the following terms...   
  1. You may use this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this article from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the article or article's description.
				

Introduction

This article examines a custom ASP.Net server control I developed to make using the Google Maps API easier for .Net developers. This article assumes you are somewhat familiar with Google Maps (or are at least somewhat curious). If you're not familiar with Google Maps or its sweet API checkout http://maps.google.com/ and http://www.google.com/apis/maps/documentation/ for the low down. You may see references throughout the article to "my control, my GoogleMaps control, my GMap control, etc." I did not create the Google Maps API, I merely created a wrapper for ASP.Net using C#, XML, and XSL.

As I stated above, my main goal for this control was to make it easy to use a Google Map using .Net languages. I also tried very hard not to use any fancy or proprietary "hacks" or workarounds when creating this control.

Setup & Configuration

I need to point out a few quick things before we get to the examples. The Google Maps Documentaion makes some specific recommendations for the DOCTYPE, HTML Namespaces, and STYLES for your Google Map pages. Each of the example pages starts like so

<!DOCTYPE html PUBLIC "-//W3C//DTD 
XHTML 1.0 Strict//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:v="urn:schemas-microsoft-com:vml">
  
<head>
    <meta http-equiv="content-type" 
content="text/html; charset=UTF-8"/>
    <title>. . .</title>
    <style type="text/css">
      v\:* 
 {
       behavior:url(#default#VML);
 }
    </style>
    . . .
</head>

Note the "strict" DOCTYPE, the custom xmlns attributes in the HTML tag, and the cryptic looking stylsheet entry for v\:*. If you don't include these values in your pages, strange thing may happen. I noticed them especially when using polylines in Internet Explorer.

Google API Key

You'll need a valid Google API key (get one here) to run the examples. The key included in the downloadable code (see the web.config file) will work as long as your application is located at http://localhost/TestWeb/

Web.Config Setup

The GMap control is based on the "div" tag. Unfortunately, ASP.Net renders div tag controls as tables in non-IE browsers by default. Inorder for the control to render properly in FireFox, you need to add the following entries to your web.config or machine.config file

<browserCaps>
  <case 
match="^Mozilla/5\.0\s*([^)]*\))\s*(Gecko\/\d+)\s*Firefox\/
(?'version'(?'major'\d+)(?'minor'\.\d+)(?'letters'\w*)).*">
   
type=Firefox/${version}
    version=${version}
    majorversion=${major}
    minorversion=${minor}
    frames=true
    tables=true
    cookies=true
    javascript=true
    javaapplets=true
    ecmascriptversion=1.5
    w3cdomversion=1.0
    css1=true
    css2=true
    xml=true
    tagwriter=System.Web.UI.HtmlTextWriter
    <filter match="^b" with="${letters}">
      beta=true
    </filter>
 </case>
</browserCaps>

It's a good idea in general to add these values to the machine.config file on your web server. Why? So things like asp:panel and other "div" based controls will render properly in FireFox. [Editor: All right Bill, it's been 450 words and I haven't seen a GMap yet so stop yapping and get to it]

The Good Stuff

Included in the downloadable code (see Download source files above) is a web project called TestWeb with nine (9) example pages on how to use my GMap Control in your applications (see all examples at http://www.sctc.state.co.us/dev/GoogleMaps/. The download includes the complete source for the control.

Basics.aspx

This is the simplest use of a GMap. Here we are just creating a GMap with a width of 500px and height of 300px. What could be simpler?

<form id="Form1" method="post" 
runat="server">
  <wcp:GMap runat="server" id="gMap" Width="500px" 
Height="300px" />
</form>

Basics.aspx.cs

To initialize the map, you'll always want to make a call to CenterAndZoom. Otherwise you may just get a big grey box.

protected 
GMap gMap;
private void Page_Load(object sender, System.EventArgs e)
{
 gMap.CenterAndZoom(new GPoint(-122.141944F, 37.441944F), 4);
}

Houston, we have a GMap!

Controls.aspx.cs

The .aspx code for the Controls example is identical to the Basics example. Here we are adding some basic controls to our map.

protected GMap gMap;
private void Page_Load(object sender, System.EventArgs e)
{
 gMap.AddControl( new GSmallMapControl());
 gMap.AddControl( new GMapTypeControl());
 gMap.CenterAndZoom(new GPoint(-122.141944F, 37.441944F), 4);
}

GMap & GMarker Events

Now let's say you want to tap in to some of the events provided by the Google Maps API. You can access any of the GMap events by implementing the proper JavaScript functions in your page. The events are outlined below and demonstrated in the following examples:

Event Handler Notes
GMap_Click(overlay, point) "this" will reference the GMap being clicked
GMap_Move() "this" will reference the GMap being moved
GMap_MoveStart() "this" will reference the GMap being moved
GMap_MoveEnd() "this" will reference the GMap that was moved
GMap_Zoom(oldZoomLevel, newZoomLevel) "this" will reference the GMap being zoomed
GMap_WindowOpen()  
GMap_WindowClose()  
GMap_AddOverlay(overlay) "this" will reference the GMap to which the overlay was added
GMap_RemoveOverlay(overlay) "this" will reference the GMap which lost the overlay
GMap_ClearOverlays() "this" will referenct the GMap being cleared
GMarker_Click() "this" will reference the GMarker that was clicked
GMarker_InfoWindowOpen()  
GMarker_InfoWindowClose()  

Listeners.aspx

  <script type="text/javascript">
    function GMap_MoveEnd()
    {
      var center = this.getCenterLatLng();
      var latLngStr = '(' + center.y + ', ' + 
center.x + ')';
      
document.getElementById('message').innerHTML = latLngStr;
    }
  </script>
</head>
<body>
  <form id="Form1" method="post" runat="server">
    <wcp:GMap runat="server" id="gMap" Width="500px" 
Height="300px" />
    <asp:Label Runat="server" ID="message" />
  </form>
</body>

Here we are implementing one of the GMap javascript event functions, GMap_MoveEnd. This function will run anytime the user stops moving the GMap with their mouse. The JavaScript code gets the current Center coordinate of the map (this), formats the values and displays them in the "message" label.

InfoWindow.aspx.cs

This example opens the GMap Info Window and displays "Hello World". Note this examples uses javascript to create a new DOM text node. GMap also supports OpenInfoWindowHtml which accepts a string of HTML to display in the info window.

protected GMap gMap;
private void Page_Load(object sender, System.EventArgs e)
{
 GPoint gp = new GPoint(-122.141944F, 37.441944F);
 gMap.CenterAndZoom(gp, 4);
 gMap.OpenInfoWindow(gp, "document.createTextNode('Hello World')");
}

Overlays.aspx.cs

What fun is a map without points of interest or line annotations? You can add "overlays" to your GMap programmatically. Currently the only two overlays provided by the Google Maps API are the GMarker and GPolyline. This examples shows the usage of both.

protected GMap gMap;
private void Page_Load(object sender, System.EventArgs e)
{ 
 gMap.AddControl(new GSmallMapControl());
 gMap.AddControl(new GMapTypeControl());
 GPoint gp = new GPoint(-122.141944F, 37.441944F);
 gMap.CenterAndZoom(gp, 5);
 GMarker gm = new GMarker(gp, "FirstMarker");
 gMap.Overlays.Add(gm);
 GPolyline gPoly = new GPolyline();
 gPoly.Weight = 5;
 gPoly.Opacity = 0.25F;
 gPoly.Color = Color.Red;
 for( int i=1; i<6; i++ )
 {
float x = gp.X + (0.005F*-i);
float y = gp.Y + (0.005F*-i);
 
gPoly.Points.Add(new GPoint(x, y));
 }
 gMap.Overlays.Add(gPoly);
}

ClickHandling.aspx

You can also capture the GMap click event and take any desired actions based on the click, like adding or removing an overlay:

  <script 
type="text/javascript">
    function GMap_Click(overlay, point)
    {
      if( overlay )
       this.removeOverlay(overlay);
      else if( point )
        this.addOverlay(new 
GMarker(point));
    }
  </script>
</head>
<body>
  <form id="Form1" method="post" runat="server">
    <wcp:GMap runat="server" id="gMap" Width="500px" 
Height="300px" />
  </form>
</body>

MarkerInfoWindow.aspx

You can also capture the GMarker click event and show an info window over the marker with any HTML you want:

  <script type="text/javascript">
    function GMarker_Click()
    {
      var html = "<b>" + this.id + 
"</b>";
      this.openInfoWindowHtml(html);
    }
  </script>
</head>
<body>
  <form id="Form1" method="post" runat="server">
    <wcp:GMap runat="server" id="gMap" Width="500px" 
Height="300px" />
  </form>
</body>

MarkerInfoWindow.aspx.cs

Create the GMarkers programmatically using any .Net language. Set each GMarker's Id so it will be displayed client-side when clicked.

protected GMap gMap;
private void Page_Load(object sender, System.EventArgs e)
{
 GPoint gp = new GPoint(-122.141944F, 37.441944F);
 GMarker gm = new GMarker(gp, "FirstMarker");
 gMap.Overlays.Add(gm);
 gm = new GMarker(new GPoint(gp.X + 0.005F, gp.Y + 0.005F), 
"SecondMarker");
 gMap.Overlays.Add(gm);
 gMap.CenterAndZoom(gp, 4);
}

Icons.aspx

The GMap control also supports custom icons. Creating icons requires a little more work, unless you have access to the proper images. We'll borrow some of Google's for demonstration purposes.

  <script type="text/javascript">
    function GMarker_Click()
    {
      var html = "You clicked me!";
      this.openInfoWindowHtml(html);
    }
  </script>
</head>
<body>
  <form id="Form1" method="post" runat="server">
    <wcp:GMap runat="server" id="gMap" Width="500px" 
Height="300px" />
  </form>
</body>

Icons.aspx.cs

Again, the theme here is programmatically creating Google API objects and interacting with them using C#/VB.Net.

protected GMap 
gMap;
private void Page_Load(object sender, System.EventArgs e)
{
 GPoint gp = new GPoint(-122.141944F, 37.441944F);
 GIcon tiny = new GIcon();
 tiny.Id = "tiny";
 tiny.Image = new 
Uri("http://labs.google.com/ridefinder/images/mm_20_red.png");
 tiny.Shadow = new 
Uri("http://labs.google.com/ridefinder/images/mm_20_shadow.png");
 tiny.IconSize = new GSize(12, 20);
 tiny.ShadowSize = new GSize(22, 20);
 tiny.IconAnchor = new GPoint(6, 20);
 tiny.InfoWindowAnchor = new GPoint(5, 1);
 gMap.Icons.Add(tiny);
 gMap.AddControl(new GSmallMapControl());
 gMap.AddControl(new GMapTypeControl());
 gMap.CenterAndZoom(gp, 4);
 GMarker gm = new GMarker(gp, "TinyMarker", tiny.Id);
 gMap.Overlays.Add(gm);
}

DataListExample.aspx

This is the final example that I wanted to throw in to this article. I wanted to demonstrate just how easily you could create multiple GMap controls. This example creates six (6) maps centered at the same point each with a different zoom level.

<body>
  <form id="Form1" method="post" runat="server">
    <asp:DataList Runat="server" ID="dlMaps" 
RepeatDirection="Horizontal" 
 RepeatColumns="2" RepeatLayout="Table">
      <ItemTemplate>
        <wcp:GMap runat="server" 
ID="gMap" width="400px" height="240px" />
        <asp:Label 
Runat="server">
          Location: 
(-122.141944, 37.441944) Zoom Level:
            
<%# Container.DataItem %>
        </asp:Label>
      </ItemTemplate>
    </asp:DataList>
  </form>
</body>

DataListExample.aspx.cs

Here we get a little fancy by creating an ArrayList of zoom values. This ArrayList serves as the DataSource for our DataList. During the DataBinding, we get a reference to each GMap and center it at the given point and zoom out by one step each time.

protected DataList dlMaps;
private const int MAX_ZOOM = 6;
private void Page_Load(object sender, System.EventArgs e)
{
 ArrayList al = new ArrayList();
 for( int i=1; i<=MAX_ZOOM; i++ )
al.Add(i);
 dlMaps.DataSource = al;
 dlMaps.DataBind();
}
private void dlMaps_ItemDataBound(object s, DataListItemEventArgs 
dliea)
{
 GMap map = (GMap)dliea.Item.Controls[0];
 int zoom = Convert.ToInt32(dliea.Item.DataItem);
 map.CenterAndZoom(new GPoint(-122.141944F, 37.441944F), zoom);
}

Conclusion

In this article we covered the basic usage of my .Net GMap control. I hope you are able to get some good mileage out of this control.

winzip iconDownload article

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come out every day, so no prevention program can catch 100% of them. For your own safety, please:
  1. Re-scan downloaded files using your personal virus checker before using it.
  2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.

If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com

 
Terms of Agreement:   
By using this article, you agree to the following terms...   
  1. You may use this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this article from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the article or article's description.

Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Intermediate category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments
9/8/2005 2:47:14 PMWinWin

Hello Bill, i am looking forward to seeing your control BUT i am getting the following error. There is no testWeb.global

I am using the localHost/testWeb as u suggested.

By the way do u know whether i can use visual Web Developer 2005 beta 2 environment with your control, etc.

Thanks for any help, Win Win

Line 1: <%@ Application Codebehind="Global.asax.cs" Inherits="TestWeb.Global" %>

Could not load type 'TestWeb.Global'.

(If this comment was disrespectful, please report it.)

 
9/27/2005 10:01:40 AMRedBully

This wrapper looks very nice and I'm looking forward to using it.

I don't have Visual Studio so I complied all the source code in the WPierce.Web folder using csc.exe and putting the compiled DLL into my website's bin folder.

C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc.exe /t:library /out:c:\MyWebSite\bin\WCPierce.Web.dll /recurse:*.cs

I also had to change all the 'codebehind' statments to 'src' in the aspx and global.asax files.

Seems to be working fine.
(If this comment was disrespectful, please report it.)

 
3/13/2006 3:25:23 PMJim McFetridge

The documentation for this code is exceptional and well thought-out.
(If this comment was disrespectful, please report it.)

 
5/12/2009 4:23:40 AM

awesome..!!!
(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.