diff --git a/README.md b/README.md
index 3c515f2..6b5f3ed 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Includes a model and interface for communicating with five popular Geocoding pro
* [Bing Maps (aka Virtual Earth)](http://www.microsoft.com/maps/) - [docs](http://msdn.microsoft.com/en-us/library/ff701715.aspx)
* :warning: MapQuest [(Commercial API)](http://www.mapquestapi.com/) - [docs](http://www.mapquestapi.com/geocoding/)
* :warning: MapQuest [(OpenStreetMap)](http://open.mapquestapi.com/) - [docs](http://open.mapquestapi.com/geocoding/)
- * [HERE](https://www.here.com/) - [docs](https://developer.here.com/documentation)
+ * [HERE](https://www.here.com/) - [docs](https://developer.here.com/documentation/geocoding-search-api)
The API returns latitude/longitude coordinates and normalized address information. This can be used to perform address validation, real time mapping of user-entered addresses, distance calculations, and much more.
@@ -73,7 +73,7 @@ You will need a [consumer secret and consumer key](http://developer.yahoo.com/bo
MapQuest API requires a key. Sign up here: (http://developer.mapquest.com/web/products/open)
-HERE requires an [app ID and app Code](https://developer.here.com/?create=Freemium-Basic&keepState=true&step=account)
+HERE requires an [API key](https://developer.here.com/?create=Freemium-Basic&keepState=true&step=account).
## How to Build from Source
diff --git a/src/Geocoding.Core/QueryBuilder.cs b/src/Geocoding.Core/QueryBuilder.cs
new file mode 100644
index 0000000..3cdf672
--- /dev/null
+++ b/src/Geocoding.Core/QueryBuilder.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace Geocoding
+{
+ ///
+ /// Provides a custom constructor for Uri query strings.
+ ///
+ public class QueryBuilder
+ {
+ private readonly List parameters = new List();
+
+ ///
+ /// Adds the parameter.
+ ///
+ /// The parameter to add.
+ /// This instance of the Query builder, to allow Fluent calls.
+ public QueryBuilder AddParameter(QueryParameter parameter)
+ {
+ parameters.Add(parameter);
+ return this;
+ }
+
+ ///
+ /// Adds the parameter.
+ ///
+ /// The name/key of the parameter.
+ /// The value of parameter.
+ /// Both name and value will be Url Encoded.
+ /// This instance of the Query builder, to allow Fluent calls.
+ public QueryBuilder AddParameter(String name, String value)
+ {
+ return AddParameter(new QueryParameter(name, value));
+ }
+
+ ///
+ /// Adds the parameter if the value is not null or Empty.
+ ///
+ /// The name/key of the parameter.
+ /// The value of parameter.
+ /// Both name and value will be Url Encoded.
+ /// This instance of the Query builder, to allow Fluent calls.
+ public QueryBuilder AddNonEmptyParameter(String name, String value)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ AddParameter(new QueryParameter(name, value));
+ }
+ return this;
+ }
+
+ ///
+ /// Adds the parameter.
+ ///
+ /// The parameter to add.
+ /// This instance of the Query builder, to allow Fluent calls.
+ public QueryBuilder AddParameters(IEnumerable parameters)
+ {
+ foreach (QueryParameter parameter in parameters)
+ {
+ AddParameter(parameter);
+ }
+ return this;
+ }
+
+ ///
+ /// Gets the query string.
+ ///
+ public String GetQuery(String separator = "&")
+ {
+ return String.Join(separator, parameters.Select(p => p.Query));
+ }
+ }
+}
diff --git a/src/Geocoding.Core/QueryParameter.cs b/src/Geocoding.Core/QueryParameter.cs
new file mode 100644
index 0000000..2d2f75a
--- /dev/null
+++ b/src/Geocoding.Core/QueryParameter.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Globalization;
+using System.Net;
+
+namespace Geocoding
+{
+ public class QueryParameter
+ {
+ public String Name { get; }
+ public String Value { get; }
+
+ public QueryParameter(String name, String value)
+ {
+ Name = name;
+ Value = value;
+ }
+
+ public String Query
+ {
+ get
+ {
+ return String.Format(CultureInfo.InvariantCulture,
+ "{0}={1}",
+ WebUtility.UrlEncode(Name),
+ WebUtility.UrlEncode(Value));
+ }
+ }
+ }
+}
diff --git a/src/Geocoding.Here/HereAddress.cs b/src/Geocoding.Here/HereAddress.cs
index 5067d5b..900205f 100644
--- a/src/Geocoding.Here/HereAddress.cs
+++ b/src/Geocoding.Here/HereAddress.cs
@@ -4,8 +4,7 @@ namespace Geocoding.Here
{
public class HereAddress : Address
{
- readonly string street, houseNumber, city, state, country, postalCode;
- readonly HereLocationType type;
+ readonly string street, houseNumber, city, state, country, postalCode, resultType;
public string AddressLine
{
@@ -37,13 +36,13 @@ public string PostalCode
get { return postalCode ?? ""; }
}
- public HereLocationType Type
+ public String ResultType
{
- get { return type; }
+ get { return resultType; }
}
public HereAddress(string formattedAddress, Location coordinates, string street, string houseNumber, string city,
- string state, string postalCode, string country, HereLocationType type)
+ string state, string postalCode, string country, string resultType)
: base(formattedAddress, coordinates, "HERE")
{
this.street = street;
@@ -52,7 +51,7 @@ public HereAddress(string formattedAddress, Location coordinates, string street,
this.state = state;
this.postalCode = postalCode;
this.country = country;
- this.type = type;
+ this.resultType = resultType;
}
}
}
diff --git a/src/Geocoding.Here/HereGeocoder.cs b/src/Geocoding.Here/HereGeocoder.cs
index 79f3dad..97e820d 100644
--- a/src/Geocoding.Here/HereGeocoder.cs
+++ b/src/Geocoding.Here/HereGeocoder.cs
@@ -16,111 +16,99 @@ namespace Geocoding.Here
///
public class HereGeocoder : IGeocoder
{
- const string GEOCODING_QUERY = "https://geocoder.api.here.com/6.2/geocode.json?app_id={0}&app_code={1}&{2}";
- const string REVERSE_GEOCODING_QUERY = "https://reverse.geocoder.api.here.com/6.2/reversegeocode.json?app_id={0}&app_code={1}&mode=retrieveAddresses&{2}";
- const string SEARCHTEXT = "searchtext={0}";
- const string PROX = "prox={0}";
- const string STREET = "street={0}";
- const string CITY = "city={0}";
- const string STATE = "state={0}";
- const string POSTAL_CODE = "postalcode={0}";
- const string COUNTRY = "country={0}";
-
- readonly string appId;
- readonly string appCode;
+ const string URL_GEOCODE = "https://geocode.search.hereapi.com/v1/geocode";
+ const string URL_REVERSE_GEOCODE = "https://revgeocode.search.hereapi.com/v1/revgeocode";
+
+ const string QN_API_KEY = "apiKey";
+ const string QN_LIMIT = "limit";
+
+ const string QN_GEOCODE_QUERY = "q";
+ const string QN_GEOCODE_STRUCTURED_QUERY = "qq";
+
+ const string SQN_STREET = "street";
+ const string SQN_CITY = "city";
+ const string SQN_STATE = "state";
+ const string SQN_POSTAL_CODE = "postalCode";
+ const string SQN_COUNTRY = "country";
+
+ const string QN_REVERSE_GEOCODE_QUERY = "at";
+
+ readonly string apiKey;
public IWebProxy Proxy { get; set; }
- public Location UserLocation { get; set; }
- public Bounds UserMapView { get; set; }
public int? MaxResults { get; set; }
- public HereGeocoder(string appId, string appCode)
+ public HereGeocoder(string apiKey)
{
- if (string.IsNullOrWhiteSpace(appId))
- throw new ArgumentException("appId can not be null or empty");
+ if (string.IsNullOrWhiteSpace(apiKey))
+ throw new ArgumentException("apiKey can not be null or empty");
- if (string.IsNullOrWhiteSpace(appCode))
- throw new ArgumentException("appCode can not be null or empty");
-
- this.appId = appId;
- this.appCode = appCode;
+ this.apiKey = apiKey;
}
- private string GetQueryUrl(string address)
+ private Uri GetQueryUrl(string address)
{
- var parameters = new StringBuilder();
- var first = AppendParameter(parameters, address, SEARCHTEXT, true);
- AppendGlobalParameters(parameters, first);
+ UriBuilder uriBuilder = new UriBuilder(URL_GEOCODE);
- return string.Format(GEOCODING_QUERY, appId, appCode, parameters.ToString());
- }
+ QueryBuilder queryBuilder = new QueryBuilder();
+ queryBuilder.AddParameter(QN_GEOCODE_QUERY, address)
+ .AddParameters(GetGlobalParameters());
- private string GetQueryUrl(string street, string city, string state, string postalCode, string country)
- {
- var parameters = new StringBuilder();
- var first = AppendParameter(parameters, street, STREET, true);
- first = AppendParameter(parameters, city, CITY, first);
- first = AppendParameter(parameters, state, STATE, first);
- first = AppendParameter(parameters, postalCode, POSTAL_CODE, first);
- first = AppendParameter(parameters, country, COUNTRY, first);
- AppendGlobalParameters(parameters, first);
-
- return string.Format(GEOCODING_QUERY, appId, appCode, parameters.ToString());
+ uriBuilder.Query = queryBuilder.GetQuery();
+ return uriBuilder.Uri;
}
- private string GetQueryUrl(double latitude, double longitude)
+ private Uri GetQueryUrl(string street, string city, string state, string postalCode, string country)
{
- var parameters = new StringBuilder();
- var first = AppendParameter(parameters, string.Format(CultureInfo.InvariantCulture, "{0},{1}", latitude, longitude), PROX, true);
- AppendGlobalParameters(parameters, first);
+ UriBuilder uriBuilder = new UriBuilder(URL_GEOCODE);
- return string.Format(REVERSE_GEOCODING_QUERY, appId, appCode, parameters.ToString());
- }
+ QueryBuilder structuredQueryBuilder = new QueryBuilder();
+ structuredQueryBuilder.AddNonEmptyParameter(SQN_STREET, street)
+ .AddNonEmptyParameter(SQN_CITY, city)
+ .AddNonEmptyParameter(SQN_STATE, state)
+ .AddNonEmptyParameter(SQN_POSTAL_CODE, postalCode)
+ .AddNonEmptyParameter(SQN_COUNTRY, country);
- private IEnumerable> GetGlobalParameters()
- {
- if (UserLocation != null)
- yield return new KeyValuePair("prox", UserLocation.ToString());
+ QueryBuilder queryBuilder = new QueryBuilder();
+ queryBuilder.AddParameter(QN_GEOCODE_STRUCTURED_QUERY, structuredQueryBuilder.GetQuery(";"))
+ .AddParameters(GetGlobalParameters());
- if (UserMapView != null)
- yield return new KeyValuePair("mapview", string.Concat(UserMapView.SouthWest.ToString(), ",", UserMapView.NorthEast.ToString()));
-
- if (MaxResults != null && MaxResults.Value > 0)
- yield return new KeyValuePair("maxresults", MaxResults.Value.ToString(CultureInfo.InvariantCulture));
+ uriBuilder.Query = queryBuilder.GetQuery();
+ return uriBuilder.Uri;
}
- private bool AppendGlobalParameters(StringBuilder parameters, bool first)
+ private Uri GetQueryUrl(double latitude, double longitude)
{
- var values = GetGlobalParameters().ToArray();
+ UriBuilder uriBuilder = new UriBuilder(URL_REVERSE_GEOCODE);
- if (!first) parameters.Append("&");
- parameters.Append(BuildQueryString(values));
+ QueryBuilder queryBuilder = new QueryBuilder();
+ queryBuilder.AddParameter(QN_REVERSE_GEOCODE_QUERY, string.Format(CultureInfo.InvariantCulture, "{0},{1}", latitude, longitude))
+ .AddParameters(GetGlobalParameters());
- return first && !values.Any();
+ uriBuilder.Query = queryBuilder.GetQuery();
+ return uriBuilder.Uri;
}
- private string BuildQueryString(IEnumerable> parameters)
+ private IEnumerable GetGlobalParameters()
{
- var builder = new StringBuilder();
- foreach (var pair in parameters)
- {
- if (builder.Length > 0) builder.Append("&");
+ if (MaxResults != null && MaxResults.Value > 0)
+ yield return new QueryParameter(QN_LIMIT, MaxResults.Value.ToString(CultureInfo.InvariantCulture));
- builder.Append(UrlEncode(pair.Key));
- builder.Append("=");
- builder.Append(UrlEncode(pair.Value));
- }
- return builder.ToString();
+ yield return new QueryParameter(QN_API_KEY, this.apiKey);
}
public async Task> GeocodeAsync(string address, CancellationToken cancellationToken = default(CancellationToken))
{
try
{
- var url = GetQueryUrl(address);
+ Uri url = GetQueryUrl(address);
var response = await GetResponse(url, cancellationToken).ConfigureAwait(false);
return ParseResponse(response);
}
+ catch (HereGeocodingException)
+ {
+ throw;
+ }
catch (Exception ex)
{
throw new HereGeocodingException(ex);
@@ -135,6 +123,10 @@ private string BuildQueryString(IEnumerable> parame
var response = await GetResponse(url, cancellationToken).ConfigureAwait(false);
return ParseResponse(response);
}
+ catch (HereGeocodingException)
+ {
+ throw;
+ }
catch (Exception ex)
{
throw new HereGeocodingException(ex);
@@ -157,6 +149,10 @@ private string BuildQueryString(IEnumerable> parame
var response = await GetResponse(url, cancellationToken).ConfigureAwait(false);
return ParseResponse(response);
}
+ catch (HereGeocodingException)
+ {
+ throw;
+ }
catch (Exception ex)
{
throw new HereGeocodingException(ex);
@@ -183,42 +179,27 @@ async Task> IGeocoder.ReverseGeocodeAsync(double latitude,
return await ReverseGeocodeAsync(latitude, longitude, cancellationToken).ConfigureAwait(false);
}
- private bool AppendParameter(StringBuilder sb, string parameter, string format, bool first)
- {
- if (!string.IsNullOrEmpty(parameter))
- {
- if (!first)
- {
- sb.Append('&');
- }
- sb.Append(string.Format(format, UrlEncode(parameter)));
- return false;
- }
- return first;
- }
-
- private IEnumerable ParseResponse(Json.Response response)
+ private IEnumerable ParseResponse(IEnumerable responseItems)
{
- foreach (var view in response.View)
+ if (responseItems != null)
{
- foreach (var result in view.Result)
+ foreach (var item in responseItems)
{
- var location = result.Location;
yield return new HereAddress(
- location.Address.Label,
- new Location(location.DisplayPosition.Latitude, location.DisplayPosition.Longitude),
- location.Address.Street,
- location.Address.HouseNumber,
- location.Address.City,
- location.Address.State,
- location.Address.PostalCode,
- location.Address.Country,
- (HereLocationType)Enum.Parse(typeof(HereLocationType), location.LocationType, true));
+ item.Address.Label,
+ new Location(item.Position.Latitude, item.Position.Longitude),
+ item.Address.Street,
+ item.Address.HouseNumber,
+ item.Address.City,
+ item.Address.State,
+ item.Address.PostalCode,
+ item.Address.CountryName,
+ item.ResultType);
}
}
}
- private HttpRequestMessage CreateRequest(string url)
+ private HttpRequestMessage CreateRequest(Uri url)
{
return new HttpRequestMessage(HttpMethod.Get, url);
}
@@ -232,32 +213,37 @@ private HttpClient BuildClient()
return new HttpClient(handler);
}
- private async Task GetResponse(string queryURL, CancellationToken cancellationToken)
+ private async Task GetResponse(Uri url, CancellationToken cancellationToken)
{
using (var client = BuildClient())
{
- var response = await client.SendAsync(CreateRequest(queryURL), cancellationToken).ConfigureAwait(false);
+ HttpResponseMessage response = await client.SendAsync(CreateRequest(url), cancellationToken).ConfigureAwait(false);
using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
var jsonSerializer = new DataContractJsonSerializer(typeof(Json.ServerResponse));
var serverResponse = (Json.ServerResponse)jsonSerializer.ReadObject(stream);
- if (serverResponse.ErrorType != null)
+ if (serverResponse.StatusCode != null)
+ {
+ throw new HereGeocodingException(
+ serverResponse.Title,
+ serverResponse.StatusCode.Value,
+ serverResponse.Cause,
+ serverResponse.Action,
+ serverResponse.CorrelationId,
+ serverResponse.RequestId);
+ }
+ else if (serverResponse.Error != null)
{
- throw new HereGeocodingException(serverResponse.Details, serverResponse.ErrorType, serverResponse.ErrorType);
+ throw new HereGeocodingException(
+ serverResponse.ErrorDescription,
+ (int)response.StatusCode,
+ serverResponse.Error);
}
- return serverResponse.Response;
+ return serverResponse.Items;
}
}
}
-
- private string UrlEncode(string toEncode)
- {
- if (string.IsNullOrEmpty(toEncode))
- return string.Empty;
-
- return WebUtility.UrlEncode(toEncode);
- }
}
}
diff --git a/src/Geocoding.Here/HereGeocodingException.cs b/src/Geocoding.Here/HereGeocodingException.cs
index e9204bf..15b52c3 100644
--- a/src/Geocoding.Here/HereGeocodingException.cs
+++ b/src/Geocoding.Here/HereGeocodingException.cs
@@ -7,20 +7,32 @@ public class HereGeocodingException : GeocodingException
{
const string defaultMessage = "There was an error processing the geocoding request. See InnerException for more information.";
- public string ErrorType { get; }
-
- public string ErrorSubtype { get; }
+ public int StatusCode { get; set; }
+ public string Cause { get; set; }
+ public string Action { get; set; }
+ public string CorrelationId { get; set; }
+ public string RequestId { get; set; }
public HereGeocodingException(Exception innerException)
: base(defaultMessage, innerException)
{
}
- public HereGeocodingException(string message, string errorType, string errorSubtype)
+ public HereGeocodingException(string message, int statusCode, string cause)
+ : base(message)
+ {
+ StatusCode = statusCode;
+ Cause = cause;
+ }
+
+ public HereGeocodingException(string message, int statusCode, string cause, string action, string correlationId, string requestId)
: base(message)
{
- ErrorType = errorType;
- ErrorSubtype = errorSubtype;
+ StatusCode = statusCode;
+ Cause = cause;
+ Action = action;
+ CorrelationId = correlationId;
+ RequestId = requestId;
}
}
}
diff --git a/src/Geocoding.Here/HereLocationType.cs b/src/Geocoding.Here/HereLocationType.cs
deleted file mode 100644
index 9d40fc9..0000000
--- a/src/Geocoding.Here/HereLocationType.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-namespace Geocoding.Here
-{
- ///
- /// https://developer.here.com/documentation/geocoder/topics/resource-type-response-geocode.html
- ///
- public enum HereLocationType
- {
- Unknown,
- Point,
- Area,
- Address,
- Trail,
- Park,
- Lake,
- MountainPeak,
- Volcano,
- River,
- GolfCourse,
- IndustrialComplex,
- Island,
- Woodland,
- Cemetery,
- CanalWaterChannel,
- BayHarbor,
- Airport,
- Hospital,
- SportsComplex,
- ShoppingCentre,
- UniversityCollege,
- NativeAmericanReservation,
- Railroad,
- MilitaryBase,
- ParkingLot,
- ParkingGarage,
- AnimalPark,
- Beach,
- DistanceMarker
- }
-}
diff --git a/src/Geocoding.Here/Json.cs b/src/Geocoding.Here/Json.cs
index 9512514..3d520c1 100644
--- a/src/Geocoding.Here/Json.cs
+++ b/src/Geocoding.Here/Json.cs
@@ -7,104 +7,121 @@ namespace Geocoding.Here.Json
[DataContract]
public class ServerResponse
{
- [DataMember(Name = "Response")]
- public Response Response { get; set; }
- [DataMember(Name = "Details")]
- public string Details { get; set; }
- [DataMember(Name = "type")]
- public string ErrorType { get; set; }
- [DataMember(Name = "subtype")]
- public string ErrorSubtype { get; set; }
- }
+ // Successful geocode fields
+ [DataMember(Name = "items")]
+ public Item[] Items { get; set; }
- [DataContract]
- public class Response
- {
- [DataMember(Name = "View")]
- public View[] View { get; set; }
- }
+ // Error fields
+ [DataMember(Name = "status")]
+ public int? StatusCode { get; set; }
+ [DataMember(Name = "title")]
+ public string Title { get; set; }
+ [DataMember(Name = "cause")]
+ public string Cause { get; set; }
+ [DataMember(Name = "action")]
+ public string Action { get; set; }
+ [DataMember(Name = "correlationId")]
+ public string CorrelationId { get; set; }
+ [DataMember(Name = "requestId")]
+ public string RequestId { get; set; }
- [DataContract]
- public class View
- {
- [DataMember(Name = "ViewId")]
- public int ViewId { get; set; }
- [DataMember(Name = "Result")]
- public Result[] Result { get; set; }
+ // Other error fields
+ [DataMember(Name = "error")]
+ public string Error { get; set; }
+ [DataMember(Name = "error_description")]
+ public string ErrorDescription { get; set; }
}
[DataContract]
- public class Result
+ public class Item
{
- [DataMember(Name = "Relevance")]
- public float Relevance { get; set; }
- [DataMember(Name = "MatchLevel")]
- public string MatchLevel { get; set; }
- [DataMember(Name = "MatchType")]
- public string MatchType { get; set; }
- [DataMember(Name = "Location")]
- public Location Location { get; set; }
+ [DataMember(Name = "title")]
+ public String Title { get; set; }
+ [DataMember(Name = "id")]
+ public String Id { get; set; }
+ [DataMember(Name = "resultType")]
+ public String ResultType { get; set; }
+ [DataMember(Name = "houseNumberType")]
+ public String HouseNumberType { get; set; }
+ [DataMember(Name = "address")]
+ public Address Address { get; set; }
+ [DataMember(Name = "position")]
+ public GeoCoordinate Position { get; set; }
+ [DataMember(Name = "access")]
+ public GeoCoordinate[] Access { get; set; }
+ [DataMember(Name = "mapView")]
+ public GeoBoundingBox MapView { get; set; }
+ [DataMember(Name = "scoring")]
+ public Scoring Scoring { get; set; }
}
[DataContract]
- public class Location
+ public class Address
{
- [DataMember(Name = "LocationId")]
- public string LocationId { get; set; }
- [DataMember(Name = "LocationType")]
- public string LocationType { get; set; }
- [DataMember(Name = "Name")]
- public string Name { get; set; }
- [DataMember(Name = "DisplayPosition")]
- public GeoCoordinate DisplayPosition { get; set; }
- [DataMember(Name = "NavigationPosition")]
- public GeoCoordinate NavigationPosition { get; set; }
- [DataMember(Name = "Address")]
- public Address Address { get; set; }
+ [DataMember(Name = "label")]
+ public string Label { get; set; }
+ [DataMember(Name = "countryCode")]
+ public string CountryCode { get; set; }
+ [DataMember(Name = "countryname")]
+ public string CountryName { get; set; }
+ [DataMember(Name = "stateCode")]
+ public string StateCode { get; set; }
+ [DataMember(Name = "state")]
+ public string State { get; set; }
+ [DataMember(Name = "county")]
+ public string County { get; set; }
+ [DataMember(Name = "city")]
+ public string City { get; set; }
+ [DataMember(Name = "cistrict")]
+ public string District { get; set; }
+ [DataMember(Name = "street")]
+ public string Street { get; set; }
+ [DataMember(Name = "houseNumber")]
+ public string HouseNumber { get; set; }
+ [DataMember(Name = "postalCode")]
+ public string PostalCode { get; set; }
}
[DataContract]
public class GeoCoordinate
{
- [DataMember(Name = "Latitude")]
+ [DataMember(Name = "lat")]
public double Latitude { get; set; }
- [DataMember(Name = "Longitude")]
+ [DataMember(Name = "lng")]
public double Longitude { get; set; }
}
[DataContract]
public class GeoBoundingBox
{
- [DataMember(Name = "TopLeft")]
- public GeoCoordinate TopLeft { get; set; }
- [DataMember(Name = "BottomRight")]
- public GeoCoordinate BottomRight { get; set; }
+ [DataMember(Name = "west")]
+ public double West { get; set; }
+ [DataMember(Name = "south")]
+ public double South { get; set; }
+ [DataMember(Name = "east")]
+ public double East { get; set; }
+ [DataMember(Name = "north")]
+ public double North { get; set; }
}
[DataContract]
- public class Address
+ public class Scoring
{
- [DataMember(Name = "Label")]
- public string Label { get; set; }
- [DataMember(Name = "Country")]
- public string Country { get; set; }
- [DataMember(Name = "State")]
- public string State { get; set; }
- [DataMember(Name = "County")]
- public string County { get; set; }
- [DataMember(Name = "City")]
- public string City { get; set; }
- [DataMember(Name = "District")]
- public string District { get; set; }
- [DataMember(Name = "Subdistrict")]
- public string Subdistrict { get; set; }
- [DataMember(Name = "Street")]
- public string Street { get; set; }
- [DataMember(Name = "HouseNumber")]
- public string HouseNumber { get; set; }
- [DataMember(Name = "PostalCode")]
- public string PostalCode { get; set; }
- [DataMember(Name = "Building")]
- public string Building { get; set; }
+ [DataMember(Name = "queryScore")]
+ public double QueryScore { get; set; }
+ [DataMember(Name = "fieldScore")]
+ public FieldScoring FieldScore { get; set; }
}
+
+ [DataContract]
+ public class FieldScoring
+ {
+ [DataMember(Name = "city")]
+ public double City { get; set; }
+ [DataMember(Name = "streets")]
+ public double[] Streets { get; set; }
+ [DataMember(Name = "houseNumber")]
+ public double HouseNumber { get; set; }
+ }
+
}
diff --git a/test/Geocoding.Tests/AddressAssertionExtensions.cs b/test/Geocoding.Tests/AddressAssertionExtensions.cs
index 6ac30b4..f3473d3 100644
--- a/test/Geocoding.Tests/AddressAssertionExtensions.cs
+++ b/test/Geocoding.Tests/AddressAssertionExtensions.cs
@@ -10,10 +10,8 @@ public static void AssertWhiteHouse(this Address address)
string adr = address.FormattedAddress.ToLower();
Assert.True(
adr.Contains("The White House") ||
- adr.Contains("1600 pennsylvania ave nw") ||
- adr.Contains("1600 pennsylvania avenue northwest") ||
- adr.Contains("1600 pennsylvania avenue nw") ||
- adr.Contains("1600 pennsylvania ave northwest")
+ adr.Contains("1600 pennsylvania avenue") ||
+ adr.Contains("1600 pennsylvania ave")
);
AssertWhiteHouseArea(address);
}
@@ -27,11 +25,9 @@ public static void AssertWhiteHouseArea(this Address address)
);
//just hoping that each geocoder implementation gets it somewhere near the vicinity
- double lat = Math.Round(address.Coordinates.Latitude, 2);
- Assert.Equal(38.90, lat);
+ Assert.Equal(38.9, address.Coordinates.Latitude, 1);
- double lng = Math.Round(address.Coordinates.Longitude, 2);
- Assert.Equal(-77.04, lng);
+ Assert.Equal(-77.0, address.Coordinates.Longitude, 1);
}
public static void AssertCanadianPrimeMinister(this Address address)
@@ -43,4 +39,4 @@ public static void AssertCanadianPrimeMinister(this Address address)
Assert.True(adr.Contains("k1m"));
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Geocoding.Tests/HereAsyncGeocoderTest.cs b/test/Geocoding.Tests/HereAsyncGeocoderTest.cs
index 7bbded6..4c249dc 100644
--- a/test/Geocoding.Tests/HereAsyncGeocoderTest.cs
+++ b/test/Geocoding.Tests/HereAsyncGeocoderTest.cs
@@ -10,7 +10,8 @@ public class HereAsyncGeocoderTest : AsyncGeocoderTest
protected override IGeocoder CreateAsyncGeocoder()
{
- return new HereGeocoder(settings.HereAppId, settings.HereAppCode);
+ geoCoder = new HereGeocoder(settings.HereApiKey);
+ return geoCoder;
}
}
}
diff --git a/test/Geocoding.Tests/SettingsFixture.cs b/test/Geocoding.Tests/SettingsFixture.cs
index ef8f78e..5d96fe1 100644
--- a/test/Geocoding.Tests/SettingsFixture.cs
+++ b/test/Geocoding.Tests/SettingsFixture.cs
@@ -40,14 +40,9 @@ public string MapQuestKey
get { return config.GetValue("mapQuestKey"); }
}
- public string HereAppId
+ public string HereApiKey
{
- get { return config.GetValue("hereAppId"); }
- }
-
- public string HereAppCode
- {
- get { return config.GetValue("hereAppCode"); }
+ get { return config.GetValue("hereApiKey"); }
}
}
diff --git a/test/Geocoding.Tests/settings.json b/test/Geocoding.Tests/settings.json
index 47e5f12..9e1db03 100644
--- a/test/Geocoding.Tests/settings.json
+++ b/test/Geocoding.Tests/settings.json
@@ -8,6 +8,5 @@
"mapQuestKey": "",
- "hereAppId": "",
- "hereAppCode": ""
+ "hereApiKey": ""
}