Here is the page-level script code to do this:
<script src="http://code.google.com/apis/gears/gears_init.js" type="text/javascript"
charset="utf-8"></script>
<script src="Scripts/geo.js?id=1" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
if (geo_position_js.init()) {
var
map1 = document.getElementById("map1");
geo_position_js.getCurrentPosition(success_callback,
error_callback, { enableHighAccuracy: true });
}
function success_callback(p)
{
try {
var
lat = document.getElementById("Lat");
lat.value
= p.coords.latitude;
var
lng = document.getElementById("Lng");
lng.value = p.coords.longitude;
map1.Longitude
= lng.value;
map1.Latitude
= lat.value;
__doPostBack(null, null);
}
catch
(e) { }
}
function
error_callback(p) {
}
</script>
The first script uses Google's gears object (used in
Chrome, for example) which stores the browser's geolocation information.
The second script is an implementation that looks for different device types
and handles the "quirks". The inline third script simply implements
all the above and populates two hidden fields with the latitude and longitude.
Since I am using the Artem.GoogleMap server control in this case, we have to
trigger a postback to get the control to render a map.
Now what if none of this works? Let's have a look at the ASP.NET page codebehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(Lat.Value) && !String.IsNullOrEmpty(Lng.Value))
{
double
latitude = double.Parse(Lat.Value);
double
longitude = double.Parse(Lng.Value);
var
request = new GeoRequest(latitude, longitude);
var
response = request.GetResponse();
if (response.Status == GeoStatus.OK)
{
FormattedAdr.Text
= response.Results[0].FormattedAddress;
map1.Address
= FormattedAdr.Text;
}
}
else
{
var
loc = GEOIP.GeoLocation.GetLocation();
map1.Latitude
= loc.Latitude;
map1.Longitude
= loc.Longitude;
FormattedAdr.Text
= loc.City + " " + loc.Region + " " + loc.PostalCode;
map1.DataBind();
}
}
You
can see above that if the hidden fields are not empty, we issue a GoogleGeocoding
request and map the coordinates. And, if that fails, I use the free MaxMind Geolocation
javascript API, but I do this server-side as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
namespace GEOIP
{
public static class GeoLocation
{
public static Location GetLocation()
{
try
{
WebClient wc = new WebClient();
string s = wc.DownloadString("http://j.maxmind.com/app/geoip.js");
wc.Dispose();
/* SAMPLE
function geoip_country_code()
{ return 'US'; }
function geoip_country_name() { return 'United States'; }
function geoip_city() { return 'Deland'; }
function geoip_region() { return 'FL'; }
function geoip_region_name() { return 'Florida'; }
function geoip_latitude() { return '29.0575'; }
function geoip_longitude() { return '-81.3344'; }
function geoip_postal_code() { return ''; }
function geoip_area_code() { return '386'; }
function geoip_metro_code() { return '534'; } */
s = s.Replace("function geoip_country_code() { return '", "");
s = s.Replace("function geoip_country_name() { return '", "");
s = s.Replace("function geoip_city() { return
'", "");
s = s.Replace("function geoip_region() { return '", "");
s = s.Replace("function geoip_region_name() { return '", "");
s = s.Replace("function geoip_latitude() { return '", "");
s = s.Replace("function geoip_longitude() { return '", "");
s = s.Replace("function geoip_postal_code() { return '", "");
s = s.Replace("function geoip_area_code() { return '", "");
s = s.Replace("function geoip_metro_code() { return '", "");
s = s.Replace("'; }", "");
string[] s2 = s.Split("\n".ToCharArray());
Location loc = new Location();
loc.CountryCode = s2[0];
loc.CountryName = s2[1];
loc.City = s2[2];
loc.Region = s2[3];
loc.RegionName = s2[4];
loc.Latitude = double.Parse(s2[5]);
loc.Longitude = double.Parse(s2[6]);
loc.PostalCode = s2[7];
loc.AreaCode = s2[8];
loc.MetroCode = s2[9];
return loc;
}
catch
{
return null;
}
}
}
}
public class Location
{
public string CountryCode { get; set; }
public string CountryName { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string RegionName { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public string PostalCode { get; set; }
public string AreaCode { get; set; }
public string MetroCode { get; set; }
}
The result is that we can get a
map for virtually any browser or device. You can download the sample Visual Studio 2010 solution, which includes the two Artem libraries in it's /bin folder. The complete Artem
GoogleMaps setup is available on Codeplex.com