/* 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);
}
}
}
}