/* INFINITY CODE 2013-2019 */ /* http://www.infinity-code.com */ using System; using System.Collections.Generic; using System.Text; using InfinityCode.RealWorldTerrain.ExtraTypes; using InfinityCode.RealWorldTerrain.Webservices.Base; using InfinityCode.RealWorldTerrain.Webservices.Results; using InfinityCode.RealWorldTerrain.XML; using UnityEngine; namespace InfinityCode.RealWorldTerrain.Webservices { /// /// This class is used to search for a location by address.\n /// https://developers.google.com/maps/documentation/geocoding/intro /// public class RealWorldTerrainGoogleGeocoding : RealWorldTerrainTextWebServiceBase { private RealWorldTerrainGoogleGeocoding(RequestParams p) { _status = RequestStatus.downloading; StringBuilder url = new StringBuilder("https://maps.googleapis.com/maps/api/geocode/xml?sensor=false"); p.GenerateURL(url); www = new RealWorldTerrainWWW(url.ToString()); www.OnComplete += OnRequestComplete; } /// /// Creates a new request for a location search using object with parameters. /// /// Parameters of request /// Instance of the search query. public static RealWorldTerrainGoogleGeocoding Find(RequestParams p) { return new RealWorldTerrainGoogleGeocoding(p); } /// /// Converts response into an array of results. /// /// Response of Google API. /// Array of result. public static RealWorldTerrainGoogleGeocodingResult[] GetResults(string response) { try { RealWorldTerrainXML xml = RealWorldTerrainXML.Load(response); string status = xml.Find("//status"); if (status != "OK") return null; List results = new List(); RealWorldTerrainXMLList resNodes = xml.FindAll("//result"); foreach (RealWorldTerrainXML node in resNodes) { results.Add(new RealWorldTerrainGoogleGeocodingResult(node)); } return results.ToArray(); } catch (Exception exception) { Debug.Log(exception.Message + "\n" + exception.StackTrace); } return null; } /// /// The base class containing the request parameters. /// public abstract class RequestParams { /// /// Your application's API key. This key identifies your application for purposes of quota management. /// public string key; /// /// The language in which to return results. /// List of supported languages: /// https://developers.google.com/maps/faq#languagesupport /// public string language; /// /// Available to Google Maps APIs Premium Plan customers but not to holders of a previous Maps API for Business license. /// public string client; /// /// Uses instead of an API key to authenticate requests. /// public string signature; internal virtual void GenerateURL(StringBuilder url) { if (!string.IsNullOrEmpty(key)) url.Append("&key=").Append(key); if (!string.IsNullOrEmpty(language)) url.Append("&language=").Append(language); if (!string.IsNullOrEmpty(client)) url.Append("&client=").Append(client); if (!string.IsNullOrEmpty(signature)) url.Append("&signature=").Append(signature); } } /// /// Request parameters for Geocoding /// public class GeocodingParams : RequestParams { /// /// The street address that you want to geocode, in the format used by the national postal service of the country concerned. \n /// Additional address elements such as business names and unit, suite or floor numbers should be avoided. /// public string address; /// /// A component filter for which you wish to obtain a geocode. \n /// See Component Filtering for more information. \n /// https://developers.google.com/maps/documentation/geocoding/intro?hl=en#ComponentFiltering \n /// The components filter will also be accepted as an optional parameter if an address is provided. /// public string components; /// /// The bounding box of the viewport within which to bias geocode results more prominently. \n /// This parameter will only influence, not fully restrict, results from the geocoder. /// public RealWorldTerrainGeoRect bounds; /// /// The region code, specified as a ccTLD ("top-level domain") two-character value. \n /// This parameter will only influence, not fully restrict, results from the geocoder. /// public string region; /// /// Constructor /// public GeocodingParams() { } /// /// Constructor /// /// /// The street address that you want to geocode, in the format used by the national postal service of the country concerned. \n /// Additional address elements such as business names and unit, suite or floor numbers should be avoided. /// public GeocodingParams(string address) { this.address = address; } internal override void GenerateURL(StringBuilder url) { base.GenerateURL(url); if (!string.IsNullOrEmpty(address)) url.Append("&address=").Append(RealWorldTerrainWWW.EscapeURL(address)); if (!string.IsNullOrEmpty(components)) url.Append("&components=").Append(components); if (bounds != null) url.Append("&bounds=").Append(bounds.bottom).Append(",").Append(bounds.left).Append("|").Append(bounds.top).Append(",").Append(bounds.right); if (!string.IsNullOrEmpty(region)) url.Append("®ion=").Append(region); } } /// /// Request parameters for Reverse Geocoding /// public class ReverseGeocodingParams : RequestParams { /// /// The longitude value specifying the location for which you wish to obtain the closest, human-readable address. /// public double? longitude; /// /// The latitude value specifying the location for which you wish to obtain the closest, human-readable address. /// public double? latitude; /// /// The place ID of the place for which you wish to obtain the human-readable address. \n /// The place ID is a unique identifier that can be used with other Google APIs. \n /// For example, you can use the placeID returned by the Google Maps Roads API to get the address for a snapped point. \n /// For more information about place IDs, see the place ID overview. \n /// The place ID may only be specified if the request includes an API key or a Google Maps APIs Premium Plan client ID. /// public string placeId; /// /// One or more address types, separated by a pipe (|). \n /// Examples of address types: country, street_address, postal_code. \n /// For a full list of allowable values, see the address types on this page:\n /// https://developers.google.com/maps/documentation/geocoding/intro?hl=en#Types \n /// Specifying a type will restrict the results to this type. \n /// If multiple types are specified, the API will return all addresses that match any of the types. \n /// Note: This parameter is available only for requests that include an API key or a client ID. /// public string result_type; /// /// One or more location types, separated by a pipe (|). \n /// https://developers.google.com/maps/documentation/geocoding/intro?hl=en#ReverseGeocoding \n /// Specifying a type will restrict the results to this type. \n /// If multiple types are specified, the API will return all addresses that match any of the types. \n /// Note: This parameter is available only for requests that include an API key or a client ID. /// public string location_type; /// /// The longitude and latitude values specifying the location for which you wish to obtain the closest, human-readable address. /// public Vector2? location { get { return new Vector2(longitude.HasValue ? (float)longitude.Value : 0, latitude.HasValue ? (float)latitude.Value : 0); } set { if (value.HasValue) { longitude = value.Value.x; latitude = value.Value.y; } else { longitude = null; latitude = null; } } } /// /// Constructor /// /// The longitude value specifying the location for which you wish to obtain the closest, human-readable address. /// The latitude value specifying the location for which you wish to obtain the closest, human-readable address. public ReverseGeocodingParams(double longitude, double latitude) { this.longitude = longitude; this.latitude = latitude; } /// /// Constructor /// /// The longitude and latitude values specifying the location for which you wish to obtain the closest, human-readable address. public ReverseGeocodingParams(Vector2 location) { this.location = location; } /// /// Constructor /// /// The place ID of the place for which you wish to obtain the human-readable address. \n /// The place ID is a unique identifier that can be used with other Google APIs. \n /// For example, you can use the placeID returned by the Google Maps Roads API to get the address for a snapped point. \n /// For more information about place IDs, see the place ID overview. \n /// The place ID may only be specified if the request includes an API key or a Google Maps APIs Premium Plan client ID. /// public ReverseGeocodingParams(string placeId) { this.placeId = placeId; } internal override void GenerateURL(StringBuilder url) { base.GenerateURL(url); if (longitude.HasValue && latitude.HasValue) url.Append("&latlng=").Append(latitude.Value.ToString(RealWorldTerrainCultureInfo.numberFormat)).Append(",").Append(longitude.Value.ToString(RealWorldTerrainCultureInfo.numberFormat)); else if (!string.IsNullOrEmpty(placeId)) url.Append("&placeId=").Append(placeId); else throw new Exception("You must specify latitude and longitude, location, or placeId."); if (!string.IsNullOrEmpty(result_type)) url.Append("&result_type=").Append(result_type); if (!string.IsNullOrEmpty(location_type)) url.Append("&location_type=").Append(location_type); } } } }