Recently I implemented BackYardTweets. Big part
of the site is geo targeting. What that means is that to figure out location of the user visiting the site and getting
longitude and latitude of that location. The implementation uses the following work flow:
- When user visits the site, only information that is available is IP adress assigned to your network connection by
user's internet service provider. The implementation translates that IP address to location including coordinates (longitude and
latitude).
-
After user has logged in, application allows user to change location. User
can pick country, region and city. From these three (some time only 2), application determines geolocation.
Now I will explain how these two steps are performed.
Convert IP Address To Geo Location
Application uses IP to geo location service provided by IP Location tools. A
simple HTTP request to this site's target URL sends xml response that containss all the data that you will need to get location of
site's visitor. Following is sample response.
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Ip>74.125.45.100</Ip>
<Status>OK</Status>
<CountryCode>US</CountryCode>
<CountryName>United States</CountryName>
<RegionCode>06</RegionCode>
<RegionName>California</RegionName>
<City>Mountain View</City>
<ZipPostalCode>94043</ZipPostalCode>
<Latitude>37.4192</Latitude>
<Longitude>-122.057</Longitude>
</Response>
Following code snippet shows the implementation that was done in the application to get geo location based on IP
address of site visitor.
public class UserGeoLocator
{
private const string ApiUrl = "http://ipinfodb.com/ip_query.php?ip={0}";
public SiteUser GetUserLocation(string ipAddress)
{
if (string.IsNullOrEmpty(ipAddress))
{
return null;
}
string reqUrl = string.Format(ApiUrl, ipAddress);
HttpWebRequest httpReq = HttpWebRequest.Create(reqUrl) as HttpWebRequest;
try
{
string result = string.Empty;
HttpWebResponse response = httpReq.GetResponse() as HttpWebResponse;
using (var reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
return ProcessResponse(result);
}
catch (Exception ex)
{
throw;
}
}
private SiteUser ProcessResponse(string strResp)
{
StringReader sr = new StringReader(strResp);
XElement respElement = XElement.Load(sr);
string callStatus = (string)respElement.Element("Status");
if (string.Compare(callStatus, "OK", true) != 0)
{
return null;
}
SiteUser user = new SiteUser() {IP = (string) respElement.Element("Ip"),
City = (string) respElement.Element("City"),
Country = (string)respElement.Element("CountryName"),
CountryCode = (string)respElement.Element("CountryCode"),
RegionCode = (string)respElement.Element("RegionCode"),
RegionName = (string)respElement.Element("RegionName"),
PostalCode = (string)respElement.Element("ZipPostalCode"),
Latitude = (decimal)respElement.Element("Latitude"),
Longitude = (decimal)respElement.Element("Longitude")};
return user;
}
}
Geo Location From Address
Application allows user to select Country, Region and City. This needs to
be translated to geo location. Application uses Google's Map API to accomplish the task. For this
you will need to apply for key from Google. Following code snippet is from the application. It takes
address of user as input and translates it to latitude and latitude. Following
code snippet is from class implemented in the application.
public static bool GetGeoLocationFromGoogle(string nearLocation,
out double longitude, out double latitude)
{
bool ret = false;
longitude = latitude = 0d;
string apiKey = ConfigHelper.GooleMapKey;
string reqUrl = string.Format("http://maps.google.com/maps/geo?q={0}&output={1}&key={2}",
HttpUtility.UrlEncode(nearLocation), "csv", apiKey);
WebClient httpClient = new WebClient();
try
{
string response = httpClient.DownloadString(reqUrl);
string[] values = response.Split(",".ToCharArray());
if (values.Length == 4)
{
if (values[0] == "200")
{
latitude = double.Parse(values[2]);
longitude = double.Parse(values[3]);
ret = true;
}
}
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
return ret;
}
See how it works
Use see all this in action at following link