Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions NGeo.Tests/GeoNames/IInvokeGeoNamesServicesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ public void GeoNames_IInvokeGeoNamesServices_ShouldHaveOperationContractAttribut
default(ResultStyle), default(string)) },
};

var postalNearbyResultsOperations = new Dictionary<string, Expression<Func<IInvokeGeoNamesServices, PostalCodeNearbyResults>>>
{
{ "findNearbyPostalCodesJSON", p => p.FindNearbyPostalCodes(default(string), default(string), default(double), default(int),
default(ResultStyle), default(string)) },
};

var countryResultsOperations = new Dictionary<string, Expression<Func<IInvokeGeoNamesServices, Results<Country>>>>
{
{ "countryInfoJSON", p => p.Countries(default(string)) },
Expand All @@ -59,6 +65,7 @@ public void GeoNames_IInvokeGeoNamesServices_ShouldHaveOperationContractAttribut
toponymResultsOperations.ShouldHaveOperationContractAttributes();
toponymOperations.ShouldHaveOperationContractAttributes();
codeResultsOperations.ShouldHaveOperationContractAttributes();
postalNearbyResultsOperations.ShouldHaveOperationContractAttributes();
countryResultsOperations.ShouldHaveOperationContractAttributes();
postalCodedCountryResultsOperations.ShouldHaveOperationContractAttributes();
hierarchyOperations.ShouldHaveOperationContractAttributes();
Expand Down Expand Up @@ -112,6 +119,22 @@ public void GeoNames_IInvokeGeoNamesServices_LookupPostalCode_ShouldHaveWebInvok
attributes[0].BodyStyle.ShouldEqual(WebMessageBodyStyle.Bare);
}

[TestMethod]
public void GeoNames_IInvokeGeoNamesServices_FindNearbyPostalCodes_ShouldHaveWebInvokeAttribute()
{
Expression<Func<IInvokeGeoNamesServices, PostalCodeNearbyResults>> method = p => p.FindNearbyPostalCodes(
default(string), default(string), default(double), default(int), default(ResultStyle), default(string));
var attributes = method.GetAttributes<IInvokeGeoNamesServices, PostalCodeNearbyResults, WebInvokeAttribute>();

attributes.ShouldNotBeNull();
attributes.Length.ShouldEqual(1);
attributes[0].UriTemplate.ShouldEqual("findNearbyPostalCodesJSON?postalcode={postalcode}&country={country}&radius={radiusInKm}"
+ "&maxRows={maximumResults}&style={resultStyle}&username={userName}");
attributes[0].RequestFormat.ShouldEqual(WebMessageFormat.Json);
attributes[0].ResponseFormat.ShouldEqual(WebMessageFormat.Json);
attributes[0].BodyStyle.ShouldEqual(WebMessageBodyStyle.Bare);
}

[TestMethod]
public void GeoNames_IInvokeGeoNamesServices_PostalCodeCountryInfo_ShouldHaveWebInvokeAttribute()
{
Expand Down
22 changes: 22 additions & 0 deletions NGeo.Tests/GeoNames/PostalCodeLookupTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@ public void GeoNames_PostalCodeLookup_ShouldBePublic()
finder.Style.ShouldEqual(ResultStyle.Medium);
}

[TestMethod]
public void GeoNames_PostalCodeNearbyLookup_ShouldBePublic()
{
var finder = new PostalCodeLookup
{
PostalCode = "32819",
RadiusInKm = 15,
Country = "US",
UserName = "username",
MaxRows = 2,
Style = ResultStyle.Medium,
};

finder.ShouldNotBeNull();
finder.PostalCode.ShouldEqual("32819");
finder.RadiusInKm.ShouldEqual(15);
finder.Country.ShouldEqual("US");
finder.UserName.ShouldNotBeNull();
finder.MaxRows.ShouldEqual(2);
finder.Style.ShouldEqual(ResultStyle.Medium);
}

[TestMethod]
public void GeoNames_PostalCodeLookup_ShouldHaveDefaultValues()
{
Expand Down
32 changes: 32 additions & 0 deletions NGeo/GeoNames/GeoNamesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,38 @@ private PostalCodeResults ChannelLookupPostalCode(PostalCodeLookup lookup, int r
}
}

/// <summary>
/// Lookup nearby postal codes. See
/// <seealso cref="http://www.geonames.org/export/web-services.html#findNearbyPostalCodes">Official
/// GeoNames findNearbyPostalCodes Documentation</seealso> for more information.
/// </summary>
/// <param name="lookup">Arguments sent to the GeoNames service.</param>
/// <returns>returns a list of postalcodes and places for the lat/lng query as xml document. The result is sorted by distance. For Canada the FSA is returned (first 3 characters of full postal code)</returns>
public ReadOnlyCollection<PostalCode> FindNearbyPostalCodes(PostalCodeLookup lookup)
{
if (lookup == null) throw new ArgumentNullException("lookup");

var response = ChannelFindNearbyPostalCodes(lookup);
var results = response.Items;
return results != null ? new ReadOnlyCollection<PostalCode>(results) : null;
}

private PostalCodeNearbyResults ChannelFindNearbyPostalCodes(PostalCodeLookup lookup, int retry = 0)
{
try
{
var results = Channel.FindNearbyPostalCodes(lookup.PostalCode, lookup.Country, lookup.RadiusInKm,
lookup.MaxRows, lookup.Style, lookup.UserName);
return results;
}
catch (WebException ex)
{
if (retry < RetryLimit && ex.Message.StartsWith(ClosedConnectionMessage, StringComparison.Ordinal))
return ChannelFindNearbyPostalCodes(lookup, ++retry);
throw;
}
}

/// <summary>
/// Postal Code Country Info (countries available with min & max postal codes). See
/// <seealso cref="http://www.geonames.org/export/web-services.html#postalCodeCountryInfo">Official
Expand Down
6 changes: 6 additions & 0 deletions NGeo/GeoNames/GeoNamesContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public ReadOnlyCollection<PostalCode> LookupPostalCode(PostalCodeLookup lookup)
return _client.LookupPostalCode(lookup);
}

public ReadOnlyCollection<PostalCode> FindNearbyPostalCodes(PostalCodeLookup lookup)
{
if (lookup != null) lookup.UserName = _userName;
return _client.FindNearbyPostalCodes(lookup);
}

public ReadOnlyCollection<PostalCodedCountry> PostalCodeCountryInfo()
{
return _client.PostalCodeCountryInfo(_userName);
Expand Down
2 changes: 2 additions & 0 deletions NGeo/GeoNames/IConsumeGeoNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public interface IConsumeGeoNames : IDisposable

ReadOnlyCollection<PostalCode> LookupPostalCode(PostalCodeLookup lookup);

ReadOnlyCollection<PostalCode> FindNearbyPostalCodes(PostalCodeLookup lookup);

ReadOnlyCollection<PostalCodedCountry> PostalCodeCountryInfo(string userName);

Toponym Get(int geoNameId, string userName);
Expand Down
2 changes: 2 additions & 0 deletions NGeo/GeoNames/IContainGeoNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public interface IContainGeoNames : IDisposable

ReadOnlyCollection<PostalCode> LookupPostalCode(PostalCodeLookup lookup);

ReadOnlyCollection<PostalCode> FindNearbyPostalCodes(PostalCodeLookup lookup);

ReadOnlyCollection<PostalCodedCountry> PostalCodeCountryInfo();

Toponym Get(int geoNameId);
Expand Down
11 changes: 11 additions & 0 deletions NGeo/GeoNames/IInvokeGeoNamesServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ Results<Toponym> FindNearbyPlaceName(double latitude, double longitude, string l
PostalCodeResults LookupPostalCode(string postalcode, string country, int maximumResults,
ResultStyle resultStyle, string userName);

[OperationContract(Name = "findNearbyPostalCodesJSON")]
[WebInvoke(
UriTemplate = "findNearbyPostalCodesJSON?postalcode={postalcode}&country={country}&radius={radiusInKm}"
+ "&maxRows={maximumResults}&style={resultStyle}&username={userName}",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare
)]
PostalCodeNearbyResults FindNearbyPostalCodes(string postalcode, string country, double radiusInKm,
int maximumResults, ResultStyle resultStyle, string userName);

[OperationContract(Name = "postalCodeCountryInfoJSON")]
[WebInvoke(
UriTemplate = "postalCodeCountryInfoJSON?username={userName}",
Expand Down
8 changes: 8 additions & 0 deletions NGeo/GeoNames/PostalCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ public class PostalCode
[DataMember(Name = "lng")]
public double Longitude { get; internal set; }

[DataMember(Name = "distance")]
public string Distance
{
get { return _distance; }
internal set { _distance = value.ToNullIfEmptyOrWhiteSpace(); }
}
private string _distance;

[DataMember(Name = "adminCode1")]
public string Admin1Code { get; internal set; }

Expand Down
5 changes: 5 additions & 0 deletions NGeo/GeoNames/PostalCodeLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public PostalCodeLookup()
/// </summary>
public string Country { get; set; }

/// <summary>
/// Find place names in this radius.
/// </summary>
public double RadiusInKm { get; set; }

/// <summary>
/// GeoNames services require a user name.
/// </summary>
Expand Down
23 changes: 23 additions & 0 deletions NGeo/GeoNames/PostalCodeNearbyResults.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace NGeo.GeoNames
{
[DataContract]
public sealed class PostalCodeNearbyResults : IEnumerable<PostalCode>
{
[DataMember(Name = "postalCodes")]
internal List<PostalCode> Items { get; set; }

public IEnumerator<PostalCode> GetEnumerator()
{
return Items.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
1 change: 1 addition & 0 deletions NGeo/NGeo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<ItemGroup>
<Compile Include="ExtensionMethods.cs" />
<Compile Include="GeoNames\AlternateName.cs" />
<Compile Include="GeoNames\PostalCodeNearbyResults.cs" />
<Compile Include="GeoNames\PostalCodedCountry.cs" />
<Compile Include="GeoNames\PostalCode.cs" />
<Compile Include="GeoNames\PostalCodeResults.cs" />
Expand Down