Click here to Skip to main content
12,829,458 members (44,488 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as


149 bookmarked
Posted 21 Sep 2012

GoogleMapsNet - GoogleMaps Control for .NET

, 21 Sep 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple .NET control for GoogleMaps web services.


This article is an attempt to embed the GoogleMaps collection of web services into a simple .NET control. It should provide the developer a simple solution for accessing the most important parts of the GoogleMaps web services. It however does not cover 100% of all its features but concentrates on the general information provided by Google.


I have done a lot of research in order to find a similar control on the Internet, but I have found only one complete solution, present also here on the CodeProject. Here is the link. It is called GMap.NET and supports other map service providers. The control presented in this article is a pure .NET control, written in C#, and embeds a few of the most important GoogleMaps web services.

It works asynchronously and uses threads to download data from the Internet. You can access all different map types supported by GoogleMaps: roadmap, terrain, satellite, and hybrid. The control loads parts of the world map dynamically, similar to the web browser. However, to avoid memory issues, it does not cache the results.

How is GoogleMaps organized?

It is the collection of web services. Google has also provided the JavaScript API (latest revision is 3.10) in order to use these maps on custom web-sites. Please see the following link to learn more about this API.

So, if we already have this JavaScript API, why do we need the .NET control? Well, you would have to add the WebBrowser .NET control in order to use GoogleMaps on WinForms and provide the background page with embedded JavaScript code, or build some kind of your own local service to handle the API calls.

But, can it be solved in a different manner? At this moment, and if Google does not change the URLs and specifications (algorithms) - it can.

The most tricky part of this story is the HTTP request that travels to GoogleMaps servers and back. In most cases these servers will return the images (in the specific format) and the XML (or JSON) documents. All that is needed to be done, when you finally access the servers, is to put the right images on the right place on the screen.

The Map of the World

GoogleMaps servers will deliver, upon processing the request from the client, the parts of the world map (so called tiles) at the specific zoom level. These tiles are a part of the simple coordinate system based on the latitude-longitude pair of the point on the world map, and rendered at a certain zoom level. The zoom level usually goes from 0 - a single tile representing the whole world, to 17 - the most detailed representation. The world map is divided into 2n tiles horizontally and vertically, where n represents the current zoom level. Each tile is of the size of 256x256 pixels. Depending on the type of the map, the tiles are usually PNG or JPEG images.

So, how do we access these tiles? There is a simple HTTP request that can be sent to GoogleMaps servers to obtain these tiles. First what is needed to be known is that Google has four main servers dedicated to this task. They are at this moment: mts0, mts1, mts2, and mts3. This is an example of the HTTP request sent to Google:

This request addresses the mts0 server and requests the tile with coordinates (48, 96) at zoom level 8. The same result is obtained using the following:

So, using the four servers, instead of only one, will speedup the download and will not overload the single server. What are other params of the request? The param lyrs specifies the type of map to download. Here is a list of all of them: - roadmap - terrain - terrain + labels - satellite - satellite + labels

Now, when we have tiles for the map, we need to assemble it in the right way. How do we do that?

Building the Map

The first thing that needs to be defined is the center of the map. It is the point that is going to be in the center of our screen. We pick it randomly since it can be any point on the globe. Let's center the map at the city of London (51.5081289, -0.1280050), at a zoom level of 8. How do we find the correct tiles?

We will start with the latitude-longitude pair of this location. We need to translate it into absolute screen points (x, y). Remember that at a zoom level of 8 we have 28 tiles horizontally and vertically, and that means that the size of our map is 28*256 x 28*256 pixels. It is obvious that we can not download the whole map and neither do we need to. How do we find the correct tile that holds the center of our map? We need some transformational equations to translate latitude-longitude pair into absolute screen offset. Please see the following link for a general information on this topic.

The GoogleMapsNet control described in this article uses the following method:

public static Point LatLongToPixel(double latitude, double longitude, double zoom)
    Point point = new Point();

    double centerPoint = Math.Pow(2, zoom + 7);
    double totalPixels = 2 * centerPoint;
    double pixelsPerLngDegree = totalPixels / 360;
    double pixelsPerLngRadian = totalPixels / (2 * Math.PI);
    double siny = Math.Min(Math.Max(Math.Sin(latitude * (Math.PI / 180)), -0.9999), 0.9999);
    point = new Point((int)Math.Round(centerPoint + longitude * pixelsPerLngDegree), 
            (int)Math.Round(centerPoint - 0.5 * Math.Log((1 + siny) / (1 - siny)) * pixelsPerLngRadian));

    return point;

After calling this method we get the (x, y) pair of values (32745, 21792). This is the absolute world position of the map center. Next we will calculate the viewport bounds, that is the part of the world map that is visible from our screen. It is quite simple. The center of the viewport is our center point. We form the viewport rectangle by calculating offset to the left side by subtracting the half-width of our screen, and the offset to the top side by subtracting the half-height of our screen. The width and height of our viewport are set to the width and height of our screen. See below:

m_rcViewport = new Rectangle(m_ptMapCenter.X - this.ClientRectangle.Width / 2, 
  m_ptMapCenter.Y - this.ClientRectangle.Height / 2, 
  this.ClientRectangle.Width, this.ClientRectangle.Height);

The last thing that needs to be done is to calculate the left, top, right, and bottom tiles that need to be downloaded. Here is the code:

int startx = m_rcViewport.Left / 256;
int endx = m_rcViewport.Right / 256;
int starty = m_rcViewport.Top / 256;
int endy = m_rcViewport.Bottom / 256;

That's all. After this all we need to do is run the loop and get those tiles, like below:

for (int y = starty; y <= endy; y++)
    for (int x = startx; x <= endx; x++)
        // Download tile with coordinates (x, y)

Finally, our screen looks like the following one:

Adding the Markers

The markers on GoogleMaps are useful since they can keep additional information about places on the map. You can put the marker anywhere on the map. The marker is defined by its (latitude, longitude) pair of coordinates. The GoogleMapsNet control allows you to add markers anywhere. The links to the original GooogleMaps images are shown below: - default marker - marker shadow

marker marker shadow

GoogleMaps Web Service - Goecoding and Reverse Geocoding

The geocoding web service allows you to find locations defined by the (latitude, longitude) pair using the address search criteria. It is accessible through the following HTTP request:

Here we specify the XML output format, put the keyword in the address param, and set the sensor param to true or false. You will receive the XML document from the GoogleMaps servers with the structure described in this link.

Similarly, Google provides the reverse feature to find the addresses based on the (latitude, longitude) pair search. See below:,-0.1280050&sensor=false

The Geocoding and Reverse Geocoding features are supported in the GoogleMapsNet control.

GoogleMaps Web Service - Directions

The Directions web service will provide you a route between the two points on the map. You access it like this:

Again, you will receive the XML document with the structure described in this link. The route is a collection of locations, but returned as an encoded string. The encoding algorithm is described here.

The Directions feature is supported in the GoogleMapsNet control.

GoogleMaps Web Service - Distance Matrix

The Distance Matrix web service will provide you information about the distance between two points on the map. You access it like this:

The XML document structure is described in this link.

The Distance Matrix feature is supported in the GoogleMapsNet control.

GoogleMaps Web Service - Elevation

The Elevation web service will provide you information about the elevation (height) of the point on the map. You access it like this:,-0.1280050&sensor=false

The XML document structure is described in this link.

The Elevation feature is supported in the GoogleMapsNet control.

Demo Application

The Windows Forms demo application, written in C#, and using the GoogleMapsNet control is shown on the screenshot below:

Demo application

All described features are accessible through the control panel on the right side of the main application window. But, let's now see how to use it from C#.

Using the Code

First, you should add a reference to the GoogleMapsNet control to your project, like on the image below:

Next, you add it on the form, or use the creation code, similar to the below one:

googleMapsNet1 = new GoogleMapsNet();
googleMapsNet1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
googleMapsNet1.Latitude = 0;
googleMapsNet1.Location = new System.Drawing.Point(12, 12);
googleMapsNet1.Longitude = 0;
googleMapsNet1.Name = "googleMapsNet1";
googleMapsNet1.ShowGrid = false;
googleMapsNet1.Size = new System.Drawing.Size(1024, 768);
googleMapsNet1.TabIndex = 1;
googleMapsNet1.LongitudeChanged += new System.EventHandler(this.googleMapsNet1_LongitudeChanged);
googleMapsNet1.LatitudeChanged += new System.EventHandler(this.googleMapsNet1_LatitudeChanged);
googleMapsNet1.ZoomChanged += new System.EventHandler(this.googleMapsNet1_ZoomChanged);
googleMapsNet1.Dock = DockStyle.Left;

The GoogleMapsNet control exposes three main events: LatitudeChanged, LongitudeChanged, and ZoomChanged. Add custom handlers for them to track the map params being changed.

To show the map, do the following:

// Show map
googleMapsNet1.ShowMap(mapType, longitude, latitude, zoom);

To add the marker on the map, do the following:

// Add marker
googleMapsNet1.AddMarker(longitude, latitude, zoom);

To remove all markers on the map, do the following:

// Clear markers

To get the Geocoding results, do the following:

// Show locations based on address search
DataTable table = googleMapsNet1.AddressToLongitudeLatitude(address);

To get the Reverse Geocoding results, do the following:

// Show addresses based on location
DataTable table = googleMapsNet1.LongitudeLatitudeToAddress(longitude, latitude);

To add the route to the map, do the following:

// Add route
DataTable table = googleMapsNet1.AddRoute(origin, destination);

To remove all routes on the map, do the following:

// Clear routes

To get the Distance Matrix results, do the following:

// Calculate distance
DataTable table = googleMapsNet1.CalculateDistance(origin, destination);

To get the Elevation results, do the following:

// Calculate elevation
DataTable table = googleMapsNet1.CalculateElevation(origin, destination);

Points of Interest

This was one of the most interesting projects I have been working on recently. I had a very good time working on this and I hope developers will find a good use for this control.


  • September, 2012 - GoogleMapsNet control, version 1.0.


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


About the Author

Software Developer (Senior) Elektromehanika d.o.o. Nis
Serbia Serbia
He has a master degree in Computer Science at Faculty of Electronics in Nis (Serbia), and works as a C++/C# application developer for Windows platforms since 2001. He likes traveling, reading and meeting new people and cultures.

You may also be interested in...

Comments and Discussions

Questionchanging the marker icon Pin
pranjal khanduri19-Dec-16 21:21
memberpranjal khanduri19-Dec-16 21:21 
QuestionNot working for me Pin
Member 1206121327-Apr-16 10:02
memberMember 1206121327-Apr-16 10:02 
GeneralExcellent entry point for using Google maps! Pin
Member 1148048011-Apr-15 11:18
memberMember 1148048011-Apr-15 11:18 
QuestionGoogleMapNet Pin
Member 879941324-Mar-15 21:15
memberMember 879941324-Mar-15 21:15 
AnswerRe: GoogleMapNet Pin
darkoman26-Mar-15 12:57
memberdarkoman26-Mar-15 12:57 
QuestionNice job! Pin
Ravi Bhavnani15-Sep-14 5:26
professionalRavi Bhavnani15-Sep-14 5:26 
Questionadd title Pin
hienbuf12-Sep-14 19:55
memberhienbuf12-Sep-14 19:55 
QuestionAddMarker with different color Pin
firasdaw9-Jul-14 22:34
memberfirasdaw9-Jul-14 22:34 
BugGreat Starter Application. A couple of bugs exist though. One in particular: If you press the Elevation Button and then perform a Go To. Pin
polczym21-May-14 2:49
memberpolczym21-May-14 2:49 
QuestionNeed reverse Function to LatLongToPixel ....PixelToLatLong Pin
AlexanderSW21-Apr-14 6:35
memberAlexanderSW21-Apr-14 6:35 
GeneralMy vote of 1 Pin
brookedev18-Apr-14 6:07
memberbrookedev18-Apr-14 6:07 
QuestionJust gray, no map Pin
Member 100687674-Mar-14 2:53
memberMember 100687674-Mar-14 2:53 
AnswerRe: Just gray, no map Pin
2006 Flauzer5-Aug-14 4:37
professional2006 Flauzer5-Aug-14 4:37 
QuestionGreat work! Pin
cysong16827-Feb-14 15:52
membercysong16827-Feb-14 15:52 
bentroy19-Nov-13 23:19
memberbentroy19-Nov-13 23:19 
darkoman19-Nov-13 23:41
memberdarkoman19-Nov-13 23:41 
Member 1052977716-Jan-14 22:02
memberMember 1052977716-Jan-14 22:02 
Questionquestion Pin
Member 1031440411-Oct-13 18:54
memberMember 1031440411-Oct-13 18:54 
AnswerRe: question Pin
cvogt6145723-Apr-14 8:51
membercvogt6145723-Apr-14 8:51 
QuestionLatLongToPixel Pin
hgbecker8-Aug-13 5:20
professionalhgbecker8-Aug-13 5:20 
QuestionFeature Request Pin
dancodedan23-Jun-13 3:12
memberdancodedan23-Jun-13 3:12 
QuestionEnhanced Feature Pin
hgbecker7-Feb-13 23:20
memberhgbecker7-Feb-13 23:20 
AnswerRe: Enhanced Feature Pin
darkoman8-Feb-13 12:00
memberdarkoman8-Feb-13 12:00 

thanks for the comments.
Here is the simple way of how to draw whatever you want on the Google map using GoogleMapsNet .NET control:

- override the Paint event for the GoogleMapsNet control in your project
- call the base class implementation for the Paint event first
- perform your custom drawing inside your overridden Paint event

To draw the line between any two (or more) given coordinates, please see the implementation of the GoogleMapsRoute class that is the part of the GoogleMaps namespace, and specially its member function called DrawRoute(). Another method that you will need to find the correct X and Y coordinates from the original Latitude and Longitude pair is the method called LatLongToPixel(), the static member function of the GoogleMapsNet control.

Hope I could help you !!!

Best regards,
"Avaritia est radix omnium malorum..."

GeneralRe: Enhanced Feature Pin
hgbecker11-Feb-13 8:45
memberhgbecker11-Feb-13 8:45 
QuestionI have a bug while i move the mouse move on the map Pin
NimrodMazalTov16-Dec-12 21:02
memberNimrodMazalTov16-Dec-12 21:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170326.1 | Last Updated 21 Sep 2012
Article Copyright 2012 by darkoman
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid