.NET Component AlKhemeia.Geo – list of countries, cities and many more functionality

Introduction

You can find the source code here and to see this component in action please visit http://geo.alkhemeia.com

This article aims at explaining

  • Alkhemeia.Geo component
  • How to get a list of countries and cities
  • A list of methods to extract useful information
  • Entities involved

Based on ISO standards, AlKhemeia.Geo, a .NET class library, provides a comprehensive list of Countries and Cities. The component not only provides a list of country/city but also a list of methods to extract useful information out of the database maintained in a resource file in XML format.

The Code

The library consists of two entities

Country.cs

public class Country
 {
 public string ISO { get; set; }
 public string ISO3 { get; set; }
 public string fips { get; set; }
 public string ISONumeric { get; set; }
 public string CountryName { get; set; }
 public string Capital { get; set; }
 public double? AreaSqKm { get; set; }
 public int? Population { get; set; }
 public string Continent { get; set; }
 public string tld { get; set; }
 public string CurrencyCode { get; set; }
 public string CurrencyName { get; set; }
 public string Phone { get; set; }
 public string Languages { get; set; }
 public int geonameid { get; set; }
 public string neighbours { get; set; }
/// <summary>
/// Get an instance of System.Globalization.CultureInfo object based on country name. 
/// Issue:
/// There is a possibility that a country may have more than one cultures. This approach currently does not address that.
/// </summary>
public CultureInfo CultureInfo
{
 get
 {
    return CultureInfo.GetCultures(CultureTypes.AllCultures)
               .Where(c => c.EnglishName.ToLower()
                          .Contains(CountryName.ToLower())).FirstOrDefault();
 }
}
/// <summary>
/// Get an instance of System.Globalization.RegionInfo object 
/// based on country name. 
/// </summary>
public RegionInfo RegionInfo
{
   get
   { 
     return new RegionInfo(ISO);
   }
}
}

City.cs

public class City
{
 public int GeoNameId { get; set; }
 public string Name { get; set; }
 public string AsciiName { get; set; }
 public string AlternateNames { get; set; }
 public float Latitude { get; set; }
 public float Longitude { get; set; }
 public string FeatureClass { get; set; }
 public string FeatureCode { get; set; }
 public string CountryCode { get; set; }
 public string CC2 { get; set; }
 public string Admin1Code { get; set; }
 public string Admin2Code { get; set; }
 public string Admin3Code { get; set; }
 public string Admin4Code { get; set; }
 public int Population { get; set; }
 public string Elevation { get; set; }
 public string Dem { get; set; }
 public string TimeZone { get; set; }
 public string ModificationDate { get; set; }
}

What can be achieved?

  • Find country by ISO code
  • Find country by name
  • Find neighbouring countries of a country
  • Find a list of countries based on population
  • Find a list of countries based on area in square kilometres
  • Find a list of countries in a continent
  • A list of key value pair of continent iso code and name
  • Calculate distance between two countries based on their capitals
  • Find city by ISO code
  • Calculate distance between any two cities
  • Find a list of cities in a country

The methods available for both Cities and Countries are exposed by following interfaces:

ICountryRepository.cs

public interface ICountryRepository : IBaseRepository<Country>    {        
   /// <summary>
   /// Find country by primary key ISO
   /// </summary>
   /// <param name=&amp;quot;iso&amp;quot;>the primary key</param>
   /// <returns>Country</returns>
   Country FindCountry(string iso);

   /// <summary>
   /// Finds a country by name
   /// </summary>
   /// <param name=&amp;quot;name&amp;quot;>country name</param>
   /// <returns>Country</returns>
   Country FindByName(string name);
   
   /// <summary>
   /// Find neighbouring countries of speicified country
   /// </summary>
   /// <param name=&amp;quot;country&amp;quot;>The country</param>
   /// <returns>List of neighbouring countries</returns>
   IList<Country> FindNeighbouringCountries(Country country);     

   /// <summary>
   /// Find countries with the population greater than the specified number
   /// </summary>
   /// <param name=&amp;quot;population&amp;quot;>The population</param>
   /// <returns>List of countries</returns>
   IList<Country> FindCountryWithPopulationGreaterThan(int population);

   /// <summary>
   /// Find countries with the area greater than specified number
   /// </summary>
   /// <param name=&amp;quot;areaSqKm&amp;quot;>Area in square kilometers</param>
   /// <returns>List of countries</returns>
   IList<Country> FindCountryWithAreaGreaterThan(int areaSqKm);

   /// <summary>
   /// Find counties by continent
   /// </summary>
   /// <param name=&amp;quot;continent&amp;quot;>The continent</param>
   /// <returns>List of countries</returns>
   IList<Country> FindCountriesByContinent(string continent);
   /// <summary>
   /// Find countries with names containing the specified strings
   /// </summary>
   /// <param name=&amp;quot;term&amp;quot;>a string</param>
   /// <returns>A list of countries</returns>
   IList<Country> FindCountriesWithNameContaining(string term);

   /// <summary>
   /// Find continent keyvalue pairs
   /// </summary>
   /// <returns>List of keyvalue pairs of continents</returns>
   IList<KeyValuePair<string, string>> FindContinentKeyValuePair();

   /// <summary>
   /// Calculate the distance between two countries based on theircapitals as origins
   /// </summary>
   /// <param name=&amp;quot;isoCountryCode1&amp;quot;>ISO Country Code</param>
   /// <param name=&amp;quot;isoCountryCode2&amp;quot;>ISO Country Code</param>        /// <returns>distance in KM</returns>
   double CalculateDistance(string isoCountryCode1, string isoCountryCode2);
}

ICityRepository.cs

public interface ICityRepository : IBaseRepository<City>
{
  /// <summary>
  /// Find cities with the population greater than the specified number
  /// </summary>
  /// <param name=&amp;quot;population&amp;quot;>The population</param>
  /// <returns>List of cities</returns>
  List<City> FindCityWithPopulationGreaterThan(int population);

  /// <summary>
  /// Find all cities for the specified country
  /// </summary>
  /// <param name=&amp;quot;isoCode&amp;quot;>Country ISO code</param>
  /// <returns>List of cities for the specified country</returns>
  IList<City> FindCitiesByCountry(string isoCode);

  /// <summary>
  /// Find cities which name start with name
  /// </summary>
  /// <param name=&amp;quot;name&amp;quot;>Name/search string of the city</param>
  /// <returns>List of cities whose name matches the name</returns>
  IList<City> FindCityByName(string name);

  /// <summary>
  /// Calculates approximate air distance between two cities in kilometers
  /// </summary>
  /// <param name=&amp;quot;isoCountryCode1&amp;quot;>ISO country code1</param>
  /// <param name=&amp;quot;isoCountryCode2&amp;quot;>ISO country code2</param>
  /// <returns>Distance in Kilometers</returns>
  double CalculateDistance(string city1, string city2);
}

How to use the component?

To keep things simple the implementation of ICountryRepository and ICityRepository are limited for extension/modification only within the project itself and exposed via AlKhemeia.Geo.Globe class as shown below:

public class Globe
{
  private static ICountryRepository _countries;
  private static ICityRepository _cities;

  /// <summary>
  /// 
  /// </summary>
  public static ICountryRepository Countries
  {
   get
   {
     if (_countries == null)
     {
       _countries = new CountryRepository();
     }
     return _countries;
   }
  }

  /// <summary>
  /// 
  /// </summary>
  public static ICityRepository Cities
  {
     get
     {
       if (_cities == null)
       {
         _cities = new CityRepository();
       }
       return _cities;
     }
  }
 }

To use this component all you need to do is to reference AlKhemeia.Geo library in your project. Following example shows you how easy it is to use this component.

class Program
{
  static void Main(string[] args)
  {
    var counties = Globe.Countries.FindAll();
    var cities = Globe.Cities.FindAll();

    var list = Globe.Cities.FindAll();

    var distance = Globe.Cities.CalculateDistance(&amp;quot;london&amp;quot;, &amp;quot;islamabad&amp;quot;);
  }
}

More features to come

– Key value pair of Countries/Cities to be used for ASP.NET components such as DropDown list control

– functionality to create tables i.e. alkhemeia_country and alkhemeia_city in case if someone wants to include the data in their own application.

Advertisements
This entry was posted in .NET C# and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s