Copyright 2008 RevaHealth.com
Caelen King is founder and CEO of RevaHealth.com, a health search engine allowing visitors to search and compare treatments and prices locally, nationally and internationally, including many dentists in the UK and dentists in Ireland.
The Google Maps API is great, but for some things it's overkill. Enter Google's static maps, which are also great, but for some applications they might not be enough.
One solution is to use the static maps and then add a bit of panache. Let's take a typical example where we take a location and in our data find 10 places close to that location. Using static maps we create an URL that has markers for our points and we might set the zoom level using the handy Span attribute.
Unfortunately we cannot interact with the map: if markers overlay each other we cannot tell which is where, we need to provide a key for the markers as they have no tool-tips or events.
By placing divs at the points our markers are displayed we can recover a good deal of our lost ground without needing to use a full map with all its associated overheads, load times and initialization especially. However, to do this we need to know a bit about map projections and a bit about the way Google makes its static maps.
The static maps use a Mercator projection; you can read about the maths here which is probably more than most people want to know. Let’s look at the useful bits for us:
Getting the x-position
Longitude has a nice simple equation
x = y - yo
What does this mean for us? Well if we have a map 200 pixels wide and we know the map's centre point and the length in pixels of a degree is 2.84 pixels then - say a point 3o to the west (left) is 8.533 pixels left of our centre.
How do we know the width of a degree? Well, the map we have is a small window onto a projection of the whole world. At a Google zoom level of 0 we can see the whole world (or a little more depending on the width of our map, at a width of 256 pixels it fits the world exactly). As we zoom in our window shows us a smaller and smaller part of the whole world, 2zoom to be exact. The pixel width of our whole world grows accordingly so though we see a 256px window at zoom 2 the world is 512px wide, at zoom 3, 1024 pixels and so on.
The world being 360o in the round, at zoom level 3 a degree would be 1024/360 = 2.84 (or 1024/2pi if we want to work in radians).
Phew! Feel like we're getting somewhere? Now we can correctly position a div from the edge of our static image.
Getting the y-position
Latitude is a little harder to calculate. From our page of maths we'll take
y = ln( (1+sinO)/(1-sinO)) / 2 (I use this one as it uses basic calculator functions)
If we take our centre then plug its latitude (in radians) into our equation (replace that O after each sin) and multiply by the size of a radian calculation we did for Longitude, then we get where on our virtual map of the world the centre is. Since it is the centre we know it's at 128px on a map that’s 256px wide.
Now when we plug in the latitudes of our markers we get their y co-ordinates on our virtual map and we can place them on the window onto that world because we know its centre on both the virtual map and our window: Subtract our centre's virtual y pixel value from our markers virtual y pixel - As if by magic it will give you the value to offset from our images centre.
Something’s missing here...
Now the observant among us will have noticed a bit of skating around some problems. We've been using the zoom value but we were hoping to use that nice Span attribute to give us our static map... Also, if instead of having a centre point we want the map to centre on the middle of a set of marker points then though the longitude of the centre will just be (maxLongitude+minLongitude)/2. The centre latitude, however, needs us to do some inverting on our y-position function.
Lets start by handling a set of points. We can easily loop over them to find the max and min latitudes and longitudes of the set.
Getting the centre
To find the longitude centre is easy: sum the max and min longitudes and divide by 2. The centre latitude is harder - put the max and min latitudes through our Mercator equation for latitude that we used last time:
y = ln( (1+sinO)/(1-sinO)) / 2
Add the results together and divide by 2 - then invert the function, which is
Math.Atan(Math.Sinh( RESULT )) - where RESULT is (ln((1+sin(radians(maxLatitude))/(1-radians(maxLatitude))) / 2 + ln((1+sin(radians(minLatitude))/(1-radians(minLatitude)))) /2
We'll have been working in radians so multiply this result by 180.00 / Math.PI to get the centre Latitude in degrees.
Calculate the zoom level
To find the zoom level necessary to contain our set of points we first calculate the span of degrees of the latitudes and longitudes. Subtract the minimums from the maximums to give us the largest spans by degrees for our latitude and longitude. If we zoom to a set level on a Google map: at any given zoom level anywhere on the earth the difference between the maximum longitude and the minimum longitude remains the same. - If we return to our discussion of zoom levels from last week and work backwards... we can see that once we know a longitude span we can use it to find an appropriate zoom level. The equation ends up being:
log base2 of (180o / longitudeSpano)
That all required that the longitude was the span we were interested in... Now - if we look at a square map on a page, the central x-axis span does not equal the y-axis span (except at the equator) - Longitude is greater. This means that even if the longitude span is greater than the latitude span, if we set our zoom by longitude all our points' latitude values do not necessarily fit inside our returned map. Luckily, there is a consistent relationship between these spans that depends on latitude - as we get nearer to the equator our latitude spans get closer and closer to our longitude spans (on our handy square map), and by dividing our latitude span by the cos of the centre latitude we'll get the value of our longitude span. This means we can use the zoom level calculation above - using max( longitude span , adjusted latitude span ) as our value.
As if that all wasn't enough, the old problem crops up: that the map only fits the world perfectly at zoom level 0 if it is 256 pixels wide. To account for this before we take our log, divide by 256 and multiply by the width of the map in pixels (at 256pixels wide we get back to where we started).
Well that about wraps it up! As promised, it is possible, maybe even advisable to ignore my convoluted explanation and just use some pre-prepared code snippets instead!
MAP_SIZE = 256;
private double atanh(double rad)
{
return Math.Log(((1 + rad) / (1 - rad)), Math.E) / 2;
}
private double getZoom(double span)
{
double zoom = (180.00/span) * (MAP_SIZE/256.00);
zoom = Math.Log(zoom, 2);
return Math.Floor(zoom);
}
yourReturnType createDivs(double m_maxLatitude, double m_minLatitude, double m_maxLongitude , double m_minLongitude, List m_markerIList){
/**
* find our centre - we can reuse some of these variable later
*/
double atanhsinO = atanh(Math.Sin(m_maxLatitude * Math.PI / 180.00));
double atanhsinD = atanh(Math.Sin(m_minLatitude * Math.PI / 180.00));
double atanhCentre = (atanhsinD + atanhsinO) / 2;
double radianOfCentreLatitude = Math.Atan(Math.Sinh(atanhCentre));
double centreLatitude = radianOfCentreLatitude * 180.00 / Math.PI; //turn it to degrees
double centreLongitude = (m_maxLongitude + m_minLongitude) / 2;
// zoom is decided by the max span of longitude and an adjusted latitude span
// the relationship between the latitude span and the longitude span is /cos
double latitudeSpan = m_maxLatitude - m_minLatitude;
latitudeSpan = latitudeSpan / Math.Cos(radianOfCentreLatitude);
double longitudeSpan = m_maxLongitude - m_minLongitude;
double zoom = getZoom(Math.Max(longitudeSpan, latitudeSpan)) + 1;
/**
* create the x,y co-ordinates for the centre as they would appear on a map of the earth
*/
double power = Math.Pow(2.00, zoom);
double realWidth = 256.00 * power;
// ** result 1 - pixel size of a degree **
double oneDegree = realWidth / 360.00;
double radianLength = realWidth / (2.00 * Math.PI);
// ** result 2 ** the centre on our virtual map
double centreY = radianLength * atanhCentre;
/**
* now we go though the providers creating the x,y's and adjusting them to the virtual frame of our
* map using our centreX,Y values
*/
for (IEnumerator enumerator = m_markerIList.GetEnumerator(); enumerator.MoveNext(); ) // for(Iterator<LaitutudeLongitude> latitudeLongitudeIterator = etc.. for java heads
{
DataRow markerDetails= (DataRow)(enumerator.Current); // LaitutudeLongitude markerDetails = latitudeLongitudeIterator.next(); for java heads, you get the idea
double currentLatitude = double.Parse(markerDetails["Lat"].ToString());
double currentLongitude = double.Parse(markerDetails["Lng"].ToString());
double pixelLongitude = (currentLongitude - centreLongitude) * oneDegree;
double pixelLatitudeRadians = currentLatitude * Math.PI / 180.00;
double localAtanh = atanh(Math.Sin(pixelLatitudeRadians));
double realPixelLatitude = radianLength * localAtanh;
double pixelLatitude = centreY - realPixelLatitude; // convert from our virtual map to the displayed portion
pixelLongitude = pixelLongitude + (MAP_SIZE/2);
pixelLatitude = pixelLatitude + (MAP_SIZE/2);
int roleOverX = (int)(Math.Floor(pixelLongitude)) ;
int roleOverY = (int)(Math.Floor(pixelLatitude));
// now create whatever div you want with the given roleOverX and roleOverY so they overlay the map
// add them to a List or just concatenate a string in this loop and then return .
e.g -
String roleOverDiv = "<div name='" + markerName + "' id='id" + id + "' " + ROLLOVER_STYLE_STRING + " left:" + roleOverX + "px; top:" + roleOverY + "px; '></div>";
returnString += roleOverDiv
}
return returnString; //if using the example above
}
Enjoy.
- Related Videos
- Related Articles
- Ask / Related Q&A
- Google + Pay Per Click Management Agencies
- Share Your Favorite Trips and In-car Videos using Google Maps and YouTube
- How To Set-Up An Interactive Social Network Site That Draws Hundreds Of Daily Unique Visitors
- How to Make Google Static Maps Interactive
- Is Google Chrome Right for Your Business?
- The Google Analytics Beta: Improving Profits through Web Site Analytics
- Google is Always Keen on Improving Its Products and This Has Been Seen Before in Adsense
- Google’s Chrome Shines




AbleCommerce 7 ASP .NET Shopping Cart Review
By: Brad Kort | 02/01/2010Winner of the 2009 ASP .NET Pro Award for E-Commerce, AbleCommerce 7 has a feature set comparable to e-commerce packages many times its $995 list price. Designed to be installed on Windows Web servers, it isn't for beginners. It's many features can boggle the mind. But in the hands of a skilled developer, it can push your storefront to the leading edge of technology and drive your sales.
E Commerce Provider: The Principle Functionalities
By: Tyler Moon | 01/01/2010The process of distribution, buying, selling of products/ goods or even services from the market, online fund transfer through electronic means is collectively known as e commerce since it is online or electronic commercial communication. The other forms are generally referred to as the following: e Business, e Retail, e Tailing, e Commerce and e Com or EC.
Time, Money, and eIntelli
By: Romain dell | 31/12/2009Since our inception in 2003, the Plum Tree Group has been a force for business innovations and solutions. eIntelli saves businesses time and money with its online proposal template and functionalities.
Mobile accessories in market
By: John Milton | 31/12/2009Cell phones are include in our reguler needs and its mobile accessories are the feshion and demand of time to be in touch with current information also.
How To Create Good E-commerce Website Design
By: Mark Spenser | 31/12/2009The following article is a must read for all as it shells out some of the best points that one needs to keep in mind while creating an e-commerce website.
Is Niche Blueprint 2.0 a SCAM? - An Honest Review + Bonus!
By: Leon | 31/12/2009Is Niche Blueprint 2.0 a SCAM? Read this honest review and discover the truth!
Send Flowers to Mumbai to your Beloved Ones on Desired Date
By: Punsons Flora | 31/12/2009Buy and order flowers online or get best flowers delivered or send flowers to India through Punsons Flora. We make buying and ordering flowers online easy and affordable.
with Resale Rights
By: Sandy M | 30/12/2009What are products with resale rights? A product with resale rights is a product that comes with a license that gives you a right to resell the item. Some of these products comes with unlimited licenses meaning you can sell them for any amount of money or even give them away.
How to Make Google Static Maps Interactive
By: Caelen King | 26/11/2008 | ECommerceThe Google Maps API is great, but for some things it's overkill. Enter Google's static maps, which are also great, but for some applications they might not be enough.
Look, No Needles! Dentists are Now Providing Painless Clinics
By: Caelen King | 04/11/2008 | Dental CareIf there is one place many of us dread to go, it is the dentist's chair. The sight of a large syringe being injected into tender gums can bring tears to the eyes of even the most red-blooded person.
10 Questions to Ask Before You Travel Abroad for Medical or Dental Treatment
By: Caelen King | 28/10/2008 | Medical TourismBeing well informed is the cornerstone of being able to make a good decision. Before you travel abroad to visit a dentist, doctor or cosmetic surgeon you should satisfy yourself that you are 100% happy to be treated by this person at their facility. Here are ten questions that will help you become an informed patient.
10 Reasons Why You Should not Travel Abroad for Dental Treatment
By: Caelen King | 13/10/2008 | Dental CareWith medical and dental tourism in the news so often, and the amazing amounts of money that can be saved by travelling for treatment, some people are just rushing into the process without considering all the implications involved.
Cons, Scams, and Rip Offs - How to Avoid Them While Travelling
By: Caelen King | 30/05/2008 | Travel TipsIf you are going to travel for long time then you are going to get ripped off, no ifs, ands or buts about it. It is just a question of time. Typically it will happen the moment you land when you get into your first taxi.
Arriving in Bangkok for the Second Time
By: Caelen King | 15/05/2008 | DestinationsLast time we were in Bangkok we hated it and it was tough to see how moving from one of the world's most polluted cities to another of the world's most populated cites was going to be an improvement. However, from the second we disembarked we were struck by the wealth, cleanliness and orderliness of Bangkok airport.
Why Does the Cost of Dental Implants Vary so Much?
By: Caelen King | 10/12/2007 | Dental CareIt can be frustrating and confusing trying to find out just how much a dental implant is going to cost. Why does the cost vary so much from dentist to dentist, and why after your initial consultation can you be given yet a different price again?