Created
June 14, 2017 08:53
-
-
Save ErikHen/6a1b5f2c6a126bd48c3893d6a5562f36 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace MyNamespace | |
{ | |
[ServiceConfiguration(typeof(ISelectionQuery))] | |
public class GoogleMapsGeocoding : ISelectionQuery | |
{ | |
private readonly string _googleApiKey; | |
public GoogleMapsGeocoding() | |
{ | |
//get key from config | |
_googleApiKey = ConfigurationManager.AppSettings["GoogleGeocodingApiKey"]; | |
} | |
//Will be called when the editor types something in the selection editor. | |
public IEnumerable<ISelectItem> GetItems(string query) | |
{ | |
if (IsCoordinate(query)) | |
{ | |
//return value if it is coordinates | |
var list = new List<ISelectItem> { new SelectItem() { Text = query, Value = query } }; | |
return list; | |
} | |
if (query.Length < 5) //don't waste API quota on short query | |
{ | |
return null; | |
} | |
var items = GetResultFromGoogle(query); | |
return EditorFriendlyItems(items, query); | |
} | |
//Will be called when initializing an editor with an existing value. | |
public ISelectItem GetItemByValue(string value) | |
{ | |
//just return the saved value | |
return new SelectItem { Text = value, Value = value }; | |
} | |
private IEnumerable<ISelectItem> GetResultFromGoogle(string query) | |
{ | |
if (_googleApiKey.IsNullOrEmpty()) | |
{ | |
var list = new List<ISelectItem>(); | |
list.Add(new SelectItem() { Text = "Error: missing Google API key", Value = null }); | |
return list; | |
} | |
var apiUrl = $"https://maps.googleapis.com/maps/api/geocode/json?address={query}&key={_googleApiKey}"; | |
var webClient = new WebClient { Encoding = Encoding.UTF8 }; | |
var json = (JObject)JsonConvert.DeserializeObject(webClient.DownloadString(apiUrl)); | |
var results = json["results"].Select(r => new SelectItem() | |
{ | |
Text = $"{r["formatted_address"].ToString()} ({r["geometry"]["location"]["lat"].ToString()} {r["geometry"]["location"]["lng"].ToString()})", | |
Value = $"{r["geometry"]["location"]["lat"].ToString()} {r["geometry"]["location"]["lng"].ToString()}" | |
}); | |
return results; | |
} | |
//If items returned by Google doesn't start with the query, add a dummy item to make a better experience for the editor. | |
private IEnumerable<ISelectItem> EditorFriendlyItems(IEnumerable<ISelectItem> items, string query) | |
{ | |
var itemsList = items.ToList(); | |
if (itemsList.Any()) | |
{ | |
if (!itemsList.Any(i => i.Text.StartsWith(query, StringComparison.OrdinalIgnoreCase))) | |
{ | |
itemsList.Insert(0, new SelectItem() { Text = query, Value = null }); | |
} | |
} | |
return itemsList; | |
} | |
//Check if query is coordinates | |
private bool IsCoordinate(string query) | |
{ | |
const string pattern = @"^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$"; | |
var r = new Regex(pattern); | |
return r.Match(query).Success; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment