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 } }