using System;
using System.Linq;
using Rondyo.Chatman.Common.Bll.Geocode;
using System.Web.Script.Serialization;
namespace Rondyo.Chatman.Bll.Geocode.Providers
{
///
/// Parser of google geocode result (json)
///
internal class GoogleMapsGeocodeParser
{
#region Public Methods
///
/// Extract geocode search item entities from google maps json result
///
/// input json result
/// list of geocode search items
public IGeocodeSearchResult ExtractGeocodeSearchItems(string inputJson)
{
GeocodeSearchResult result = new GeocodeSearchResult();
try
{
GoogleGeocodeResult items = new JavaScriptSerializer().Deserialize(inputJson);
result.Status = this.ConvertStatusCode(items.Status.Code.ToString());
result.StatusCode = items.Status.Code.ToString();
if (result.Status == GeocodeSearchStatus.Success)
{
result.SearchItems = items.Placemark
.Where(i => i.AddressDetails != null)
.Select(i => (IGeocodeSearchItem) new GeocodeSearchItem
{
Country = this.GetCountryName(i.AddressDetails),
CountryCode = this.GetCountryNameCode(i.AddressDetails),
AdministrativeArea = this.GetAdministrativeAreaName(i.AddressDetails),
SubAdministrativeArea = this.GetSubAdministrativeAreaName(i.AddressDetails),
Locality = this.GetLocalityName(i.AddressDetails),
Thoroughfare = this.GetThoroughfareName(i.AddressDetails),
PostalCode = this.GetPostalCode(i.AddressDetails),
Coordinates = new GeocodeCoordinates
{
Latitude = i.Point.Coordinates[0],
Longitude = i.Point.Coordinates[1],
Unbounded = i.Point.Coordinates[2] == 1 ? true : false
}
});
}
else
{
result.SearchItems = new GeocodeSearchItem[0];
}
return result;
}
catch (Exception e)
{
result.Status = GeocodeSearchStatus.InternalError;
result.StatusCode = e.Message;
result.SearchItems = new GeocodeSearchItem[0];
return result;
}
}
#endregion
#region Private Methods
///
/// Converts google result code to result status
///
/// google status code
/// result status
private GeocodeSearchStatus ConvertStatusCode(string statusCode)
{
switch (statusCode)
{
case "200":
return GeocodeSearchStatus.Success;
case "602":
case "603":
return GeocodeSearchStatus.NotFound;
case "500":
return GeocodeSearchStatus.ServerError;
case "610":
case "620":
return GeocodeSearchStatus.ServiceForbidden;
case "601":
return GeocodeSearchStatus.InternalError;
default:
return GeocodeSearchStatus.UnknownError;
}
}
///
/// Extracts country name
///
/// address entity
/// country name
private string GetCountryName(GoogleGeocodeAddressDetails address)
{
return (address.Country != null)
? address.Country.CountryName
: String.Empty;
}
///
/// Extracts country abbreviation
///
/// address entity
/// country abbreviation
private string GetCountryNameCode(GoogleGeocodeAddressDetails address)
{
return (address.Country != null)
? address.Country.CountryNameCode
: String.Empty;
}
///
/// Extracts administrative area name
///
/// address entity
/// administrative area name
private string GetAdministrativeAreaName(GoogleGeocodeAddressDetails address)
{
return (address.Country != null && address.Country.AdministrativeArea != null)
? address.Country.AdministrativeArea.AdministrativeAreaName
: String.Empty;
}
///
/// Extracts subadministrative area name
///
/// address entity
/// subadministrative area name
private string GetSubAdministrativeAreaName(GoogleGeocodeAddressDetails address)
{
return (address.Country != null && address.Country.AdministrativeArea != null
&& address.Country.AdministrativeArea.SubAdministrativeArea != null)
? address.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName
: String.Empty;
}
///
/// Extracts locality entity
///
/// address entity
/// locality entity
private GoogleGeocodeLocality GetLocality(GoogleGeocodeAddressDetails address)
{
GoogleGeocodeCountry country = address.Country;
GoogleGeocodeAdministrativeArea administrativeArea = country != null ? country.AdministrativeArea : null;
GoogleGeocodeSubAdministrativeArea subAdministrativeArea = administrativeArea != null ? administrativeArea.SubAdministrativeArea : null;
if (country != null && country.Locality != null)
{
return country.Locality;
}
else if (administrativeArea != null && administrativeArea.Locality != null)
{
return administrativeArea.Locality;
}
else if (subAdministrativeArea != null && subAdministrativeArea.Locality != null)
{
return subAdministrativeArea.Locality;
}
else
{
return null;
}
}
///
/// Extracts locality name
///
/// address entity
/// locality entity name
private string GetLocalityName(GoogleGeocodeAddressDetails address)
{
GoogleGeocodeLocality locality = this.GetLocality(address);
return locality == null ? String.Empty : locality.LocalityName;
}
///
/// Extracts thoroughfare entity
///
/// address entity
/// thoroughfare entity
private GoogleGeocodeThoroughfare GetThoroughfare(GoogleGeocodeAddressDetails address)
{
GoogleGeocodeCountry country = address.Country;
GoogleGeocodeAdministrativeArea administrativeArea = country != null ? country.AdministrativeArea : null;
GoogleGeocodeSubAdministrativeArea subAdministrativeArea = administrativeArea != null ? administrativeArea.SubAdministrativeArea : null;
GoogleGeocodeLocality locality = this.GetLocality(address);
if (country != null && country.Thoroughfare != null)
{
return country.Thoroughfare;
}
else if (administrativeArea != null && administrativeArea.Thoroughfare != null)
{
return administrativeArea.Thoroughfare;
}
else if (subAdministrativeArea != null && subAdministrativeArea.Thoroughfare != null)
{
return subAdministrativeArea.Thoroughfare;
}
else if (locality != null && locality.Thoroughfare != null)
{
return locality.Thoroughfare;
}
else
{
return null;
}
}
///
/// Extracts thoroughfare name
///
/// address entity
/// thoroughfare name
private string GetThoroughfareName(GoogleGeocodeAddressDetails address)
{
GoogleGeocodeThoroughfare thoroughfare = this.GetThoroughfare(address);
return thoroughfare == null ? String.Empty : thoroughfare.ThoroughfareName;
}
///
/// Extracts postal code
///
/// address entity
/// postal code
private string GetPostalCode(GoogleGeocodeAddressDetails address)
{
GoogleGeocodeCountry country = address.Country;
GoogleGeocodeAdministrativeArea administrativeArea = country != null ? country.AdministrativeArea : null;
GoogleGeocodeSubAdministrativeArea subAdministrativeArea = administrativeArea != null ? administrativeArea.SubAdministrativeArea : null;
GoogleGeocodeLocality locality = this.GetLocality(address);
GoogleGeocodeThoroughfare thoroughfare = this.GetThoroughfare(address);
if (administrativeArea != null && administrativeArea.PostalCode != null)
{
return administrativeArea.PostalCode.PostalCodeNumber;
}
else if (subAdministrativeArea != null && subAdministrativeArea.PostalCode != null)
{
return subAdministrativeArea.PostalCode.PostalCodeNumber;
}
else if (locality != null && locality.PostalCode != null)
{
return locality.PostalCode.PostalCodeNumber;
}
else if (thoroughfare != null && thoroughfare.PostalCode != null)
{
return thoroughfare.PostalCode.PostalCodeNumber;
}
else
{
return String.Empty;
}
}
#endregion
#region Google Maps Geocode Result Memebers
///
/// Class presents google geocode json result (it's necessary for parsing)
///
private class GoogleGeocodeResult
{
public GoogleGeocodeStatus Status { get; set; }
public GoogleGeocodePlacemark[] Placemark { get; set; }
}
private class GoogleGeocodeStatus
{
public int Code { get; set; }
}
private class GoogleGeocodePlacemark
{
public GoogleGeocodeAddressDetails AddressDetails { get; set; }
public GoogleGeocodeCoordinates Point { get; set; }
}
private class GoogleGeocodeAddressDetails
{
public GoogleGeocodeCountry Country { get; set; }
}
private class GoogleGeocodeCountry
{
public string CountryName { get; set; }
public string CountryNameCode { get; set; }
public GoogleGeocodeAdministrativeArea AdministrativeArea { get; set; }
public GoogleGeocodeLocality Locality { get; set; }
public GoogleGeocodeThoroughfare Thoroughfare { get; set; }
}
private class GoogleGeocodeAdministrativeArea
{
public string AdministrativeAreaName { get; set; }
public GoogleGeocodeSubAdministrativeArea SubAdministrativeArea { get; set; }
public GoogleGeocodeLocality Locality { get; set; }
public GoogleGeocodeThoroughfare Thoroughfare { get; set; }
public GoogleGeocodePostalCode PostalCode { get; set; }
}
private class GoogleGeocodeSubAdministrativeArea
{
public string SubAdministrativeAreaName { get; set; }
public GoogleGeocodeLocality Locality { get; set; }
public GoogleGeocodeThoroughfare Thoroughfare { get; set; }
public GoogleGeocodePostalCode PostalCode { get; set; }
}
private class GoogleGeocodeLocality
{
public string LocalityName { get; set; }
public GoogleGeocodeThoroughfare Thoroughfare { get; set; }
public GoogleGeocodePostalCode PostalCode { get; set; }
}
private class GoogleGeocodeThoroughfare
{
public string ThoroughfareName { get; set; }
public GoogleGeocodePostalCode PostalCode { get; set; }
}
private class GoogleGeocodePostalCode
{
public string PostalCodeNumber { get; set; }
}
private class GoogleGeocodeCoordinates
{
public double[] Coordinates { get; set; }
}
#endregion
}
}