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=&quot;iso&quot;>the primary key</param> /// <returns>Country</returns> Country FindCountry(string iso); /// <summary> /// Finds a country by name /// </summary> /// <param name=&quot;name&quot;>country name</param> /// <returns>Country</returns> Country FindByName(string name); /// <summary> /// Find neighbouring countries of speicified country /// </summary> /// <param name=&quot;country&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=&quot;population&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=&quot;areaSqKm&quot;>Area in square kilometers</param> /// <returns>List of countries</returns> IList<Country> FindCountryWithAreaGreaterThan(int areaSqKm); /// <summary> /// Find counties by continent /// </summary> /// <param name=&quot;continent&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=&quot;term&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=&quot;isoCountryCode1&quot;>ISO Country Code</param> /// <param name=&quot;isoCountryCode2&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=&quot;population&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=&quot;isoCode&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=&quot;name&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=&quot;isoCountryCode1&quot;>ISO country code1</param> /// <param name=&quot;isoCountryCode2&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(&quot;london&quot;, &quot;islamabad&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.