I Code, Therefore I Am

while(!(succeed == try()));

C# meet GeoLocation, GeoLocation meet C#


Today we’re going to be learning how to accomplish GeoLocation with C#. What is GeoLocation you ask, well according to Wikipedia it’s:

Geolocation is the identification of the real-world geographic location of an object, such as a radar, mobile phone or an Internet-connected computer terminal. Geolocation may refer to the practice of assessing the location, or to the actual assessed location.


So now you’re probably asking yourself ‘Self, is this complicated?’ and the answer to that is a resounding NO. We’ll be using GeoIPTools.com to get the location; city, country, latitude and longitude. We’ll accmoplish this utilizing the HttpWebRequest and HttpWebResponse classes.

For holding our GeoLocation data I’ve gone with a simple class

internal class GeoLoc
{
    internal string Latitude { get; set; }
    internal string Lognitude { get; set; }
    internal string City { get; set; }
    internal string State { get; set; }
    internal string Country { get; set; }
    internal string Host { get; set; }
    internal string Ip { get; set; }
    internal string Code { get; set; }
}

Now we got an object we can play with. Now we will make a request to http://geoiptool.com/data.php and parse it to get our information. Now we need a method to query geoiptool.com, and that’s what we do next:

/// <summary>
/// Method for retrieving someone's GeoLocation
/// </summary>
/// <returns></returns>
internal GeoLoc GetMyGeoLocation()
{
    try
    {
        //create a request to geoiptool.com
        var request = WebRequest.Create(new Uri("http://geoiptool.com/data.php")) as HttpWebRequest;

        if (request != null)
        {
            //set the request user agent
            request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727)";

            //get the response
            using (var webResponse = (request.GetResponse() as HttpWebResponse))
                if (webResponse != null)
                    using (var reader = new StreamReader(webResponse.GetResponseStream()))
                    {

                        //get the XML document
                        var doc = new XmlDocument();
                        doc.Load(reader);

                        //now we parse the XML document
                        var nodes = doc.GetElementsByTagName("marker");

                        Guard.AssertCondition(nodes.Count > 0,"nodes",new object());
                        //make sure we have nodes before looping
                        //if (nodes.Count > 0)
                        //{
                            //grab the first response
                            var marker = nodes[0] as XmlElement;

                            Guard.AssertNotNull(marker, "marker");

                            //get the data and return it
                            _geoLoc.City = marker.GetAttribute("city");
                            _geoLoc.Country = marker.GetAttribute("country");
                            _geoLoc.Code = marker.GetAttribute("code");
                            _geoLoc.Host = marker.GetAttribute("host");
                            _geoLoc.Ip = marker.GetAttribute("ip");
                            _geoLoc.Latitude = marker.GetAttribute("lat");
                            _geoLoc.Lognitude = marker.GetAttribute("lng");
                            _geoLoc.State = GetMyState(_geoLoc.Latitude, _geoLoc.Lognitude);

                            return _geoLoc;
                        //}
                    }
        }

        // this code would only be reached if something went wrong 
        // no "marker" node perhaps?
        return new GeoLoc();
    }
    catch (Exception ex)
    {
        throw;
    }
}

We’re almost done, but geoiptool.com doesnt provide the state you’re in. Well what do we do you say, we’re going to turn to Google’s API, their geocoding API. We’re doing what they call reverse geocoding, and it’s not near as complicated as it sounds, o let’s do it then:

/// <summary>
/// Method for getting a users state with Geocoding with the help of Google's Geocoding API
/// GeoIpTool.com doesnt return a state value so we have to go this route to get the state
/// </summary>
/// <param name="lon">Users location longitude</param>
/// <param name="lat">Users location latitude</param>
/// <returns></returns>
private string GetMyState(string lon, string lat)
{
    var doc = new XmlDocument();

    try
    {
        doc.Load(string.Format("http://maps.googleapis.com/maps/api/geocode/xml?latlng={0},{1}", lon, lat + "&sensor=false"));
        var element = doc.SelectSingleNode("//GeocodeResponse/status");

        //make sure 'element' isnt null
        Guard.AssertNotNull(element, "element");

        if (element.InnerText == "ZERO_RESULTS")
            return ("No data available");

        var nodeList = doc.SelectNodes("//GeocodeResponse/result/address_component");

        //make sure 'nodeList' is not null
        Guard.AssertNotNull(nodeList, "nodeList");

        foreach (XmlNode node in nodeList)
        {
            var xmlElement = node["type"];
            //MessageBox.Show(xmlElement.InnerText);
            //make sure 'xmlElement' is not null
            Guard.AssertNotNull(xmlElement, "xmlElement");

            var nodeType = xmlElement.InnerText;

            if (nodeType == "administrative_area_level_1")
            {
                var stateName = node["long_name"];

                Guard.AssertNotNull(stateName, "stateName");
                if (stateName != null)
                    return stateName.InnerText;
            }
        }
    }

    catch (Exception ex)
    {
        return ex.ToString();
    }
    return "";
}

And their you have it GeoLocation all wrapped up and tidy. Remember you don’t have to go this route, there are hundreds of ways to accomplish this, this is merely an example.

Happy Coding!


About The Author

Richard has been a professional software developer for over 15 years now. In fact he was a geek long before being a geek was 'cool'. He has his Bachelors in Computer Science from The University of Georgia and is an avid, passionate .NET developer. Richard eats, sleeps, drinks and dreams in code

Comments

One Response to “C# meet GeoLocation, GeoLocation meet C#”

  1. Edmilson Ferreira says:

    Hi, I am new in geolocation and I tried to run your code to get acquainted but I’m having an error with the Guard object. Sorry my silly question but where do I find this API?

Leave a Reply