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.
|