Adding markers to GoogleMaps based on country code
<p>How to add map markers with Google API's geocoder.getLocations(countryCode, addToMap)</p>
In one of our projects we needed to add multiple country markers to our Google map, and when a marker is clicked a list of items should be shown. The biggest issues here were in fact making all of the markers show on the map!
You can get a marker on a country based on the country code by calling Google API's geocoder.getLocations(countryCode, addToMap); and were addToMap processes the response from Google on the country code and created a marker and added it to the map. We had an array of country codes and we started off by just looping through them and calling the Google api for each code. But we soon discovered that Google started to return response code 620 (G_GEO_TOO_MANY_QUERIES) and many of our markers did not appear on the map.
Response code 620 often indicates that you are querying the Google api to often in a short time span, and the solution was to add a delay of 100 mms between each call as soon as we started to receive the 620 code.
This is the code we ended up with:
<script type="text/javascript">
//<![CDATA[
google.load("maps", "2");
var geocoder;
var map;
var lat = <%= Latitude %>; //Ex: 30
var lon = <%= Longitude %>; //Ex: 30
var zoomLevel = <%= ZoomLevel %>; //Ex: 2
// Retrieve location information, pass it to addToMap()
var countries = <%=countries %>; //Array of country codes (ex: ["no", "se", etc])
var status = new Array(countries.length);
var countryIndex = 0;
var MAP_RETRY_DELAY = 100;
google.setOnLoadCallback(load);
function load() {
map = new GMap2(document.getElementById("map"));
var center = new GLatLng(lat, lon);
map.setCenter(center, zoomLevel);
map.addControl(new GLargeMapControl3D());
geocoder = new GClientGeocoder();
// Tooltip
$("div.google-maps-tooltip").appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE));
setTimeout(addCountry, 0);
}
$(function() {
$('#tabs li:last').click(function() {
$('#map').css('z-index', '200');
map.checkResize();
});
});
function displayPoint(marker){
map.panTo(marker.getLatLng());
var markerOffset = map.fromLatLngToDivPixel(marker.getPoint());
$('[id^=tooltip]').not(this).hide();
var title = marker.getTitle();
var titleName = title.split(",");
$("#tooltip" + $.trim(titleName[1])).toggle().css({ top:markerOffset.y, left:markerOffset.x });
}
function addToMap(response) {
if(status[countryIndex] == 200)
return;
status[countryIndex] = response.Status.code;
if (!response || response.Status.code != 200) {
return false;
}
place = response.Placemark[0];
// Retrieve the latitude and longitude
point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
var blueIcon = new GIcon(G_DEFAULT_ICON);
blueIcon.image = "/Images/google_map_icon.gif";
markerOptions = { icon:blueIcon, title: place.AddressDetails.Country.CountryName + ", " + place.AddressDetails.Country.CountryNameCode};
var marker = new GMarker(point, markerOptions);
GEvent.addListener(marker, "click", function(){
displayPoint(marker);
});
map.addOverlay(marker);
}
function addCountry()
{
var countryCode = countries[countryIndex];
this.geocoder.setBaseCountryCode(countryCode);
this.geocoder.getLocations(countryCode, addToMap);
if(status[countryIndex] != 200)
{
setTimeout(addCountry, MAP_RETRY_DELAY);
}
else if(countryIndex + 1 < countries.length)
{
countryIndex++;
setTimeout(addCountry, MAP_RETRY_DELAY);
}
}
function hideList(id){
$(id).hide();
}
//]]>
</script>
<asp:PlaceHolder ID="renderOnMap" runat="server" Visible="false">
<div class="cornerModul">
<div class="cmTop">
</div>
<div class="cmContent">
</asp:PlaceHolder>
<div id="map" style="width: <%=Width%>px; height: <%=Height%>px">
</div>
<asp:Repeater runat="server" ID="repCountries">
<ItemTemplate>
<div id="tooltip<%# Eval("CountryCode") %>" class="google-maps-tooltip" style="display: none">
<h3>
<%# Eval("CountryName")%> -
<a href="#" onclick="javascript:hideList(tooltip<%# Eval("CountryCode") %>);return false;"> (Lukk) </a></h3>
<asp:Repeater runat="server" ID="repItems" DataSource='<%# Eval("xxx") %>'>
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
//Item data
</ItemTemplate>
<FooterTemplate>
</ul></FooterTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>