Reputation: 5069
I have one class library in C#. From there I have to call Google service & get latitude & longitude.
I know how to do it using AJAX on page, but I want to call Google Geocoding service directly from my C# class file.
Is there any way to do this or are there any other services which I can use for this.
Upvotes: 54
Views: 115992
Reputation: 2198
Here is the approach I use within my .Net Core API(s), in this case we only need Lat and Lng values to match our internal LocationModel:
public async Task<LocationModel> GetAddressLocation(string address)
{
try
{
var targetUrl = $"https://maps.googleapis.com/maps/api/geocode/json" +
$"?address={address}" +
$"&inputtype=textquery&fields=geometry" +
$"&key={_apiKey}";
_logger.LogDebug($"GetAddressLocation : targetUrl:{targetUrl}");
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Get, targetUrl);
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var stream = await response.Content.ReadAsStreamAsync();
if (response.IsSuccessStatusCode)
{
if (stream == null || stream.CanRead == false)
return null;
using var sr = new StreamReader(stream);
var jsonString = sr.ReadToEnd();
dynamic responseObject = JObject.Parse(jsonString);
var results = responseObject["results"];
var lat = results[0]?["geometry"]?["location"]?["lat"];
var lng = results[0]?["geometry"]?["location"]?["lng"];
var result = new LocationModel { Latitude = lat, Longitude = lng };
return result;
}
else
{
await HandleApiError(response, stream);
throw new DomainException($"UNKNOWN ERROR USING GEOCODING API :: {response}");
}
}
catch (Exception ex)
{
_logger.LogError("ERROR USING Geocoding Service", ex);
throw;
}
}
Upvotes: 2
Reputation: 719
I don't have the reputation to comment, but just wanted to say that Chris Johnsons code works like a charm. The assemblies are:
using System.Net;
using System.Xml.Linq;
Upvotes: 40
Reputation: 1374
You could do something like this:
string address = "123 something st, somewhere";
string requestUri = string.Format("https://maps.googleapis.com/maps/api/geocode/xml?key={1}&address={0}&sensor=false", Uri.EscapeDataString(address), YOUR_API_KEY);
WebRequest request = WebRequest.Create(requestUri);
WebResponse response = request.GetResponse();
XDocument xdoc = XDocument.Load(response.GetResponseStream());
XElement result = xdoc.Element("GeocodeResponse").Element("result");
XElement locationElement = result.Element("geometry").Element("location");
XElement lat = locationElement.Element("lat");
XElement lng = locationElement.Element("lng");
You will also want to validate the response status and catch any WebExceptions. Have a look at Google Geocoding API.
Upvotes: 119
Reputation: 991
UPDATED: The previous package mentioned here is deprecated - there's a new version that is up-to-date and suits .Net Core.
It might be a bit too late for this answer, but for those still getting here looking for an easy way to use Google Places or Geocoding APIs, I wrote this simple nuget called GuigleCore and it can be used like this:
var googleGeocodingApi = new GoogleGeocodingApi("GoogleApiKey");
var address = await googleGeocodingApi.SearchAddressAsync(httpClient, "123 Street, Suburb A");
OR
var googlePlacesApi = new GooglePlacesApi("GoogleApiKey");
var place = await googlePlacesApi.FindPlaces(httpClient, "123 Street, Suburb A"));
You can register it for DI like this:
services.AddScoped(typeof(IGooglePlacesApi), x => new GooglePlacesApi(Configuration["GoogleApiKey"]));
One thing that I like about it is that you get full objects from the API responses, so you have easy access to everything and you can use Linq and other collection helpers to easily retrieve data from it.
You can install it with the nuget command Install-Package GuigleCore or fork it here.
Upvotes: 4
Reputation: 10344
To complete JP Hellemons's answer, to use Geocoding.net and retrieve only the name of the city for example:
IGeocoder geocoder = new GoogleGeocoder() { ApiKey = "API_Key" };
IEnumerable<Address> addresses = await geocoder.GeocodeAsync("address");
foreach(var component in ((GoogleAddress)addresses.First()).Components)
{
foreach(var type in component.Types)
{
if(type == GoogleAddressType.Locality)
{
return component.LongName;
}
}
}
Upvotes: 2
Reputation: 6047
It's an old question. But I had the same question today and came up with this as a solution: C# GeoCoding / Address Validation API (supports several providers including Google Maps).
IGeocoder geocoder = new GoogleGeocoder() { ApiKey = "this-is-my-optional-google-api-key" };
IEnumerable<Address> addresses = await geocoder.GeocodeAsync("1600 pennsylvania ave washington dc");
Console.WriteLine("Formatted: " + addresses.First().FormattedAddress);
// Formatted: 1600 Pennsylvania Ave SE, Washington, DC 20003, USA
Console.WriteLine("Coordinates: " + addresses.First().Coordinates.Latitude + ", " + addresses.First().Coordinates.Longitude);
// Coordinates: 38.8791981, -76.9818437
Here is the corresponding NuGet package :
Install-Package Geocoding.Google
Upvotes: 7
Reputation: 131
This may not be much but I just want to make one improvement in @Chris Johnson code if you just want to get the lat and lng value in double form the var lat and var lng of chris johnson has value with this format < lat>...number...< /lat>
So if you pass the value is a string to get numeric value you have to do like this
double latitude = Double.Pars(lat.Value)
double longitude = Double.Pars(lng.Value)
Upvotes: 1
Reputation: 12855
You can also use the HttpClient class which is often used with Asp.Net Web Api or Asp.Net 5.0.
You have also a http state codes for free, asyn/await programming model and exception handling with HttpClient is easy as pie.
var address = "paris, france";
var requestUri = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=false", Uri.EscapeDataString(address));
using (var client = new HttpClient())
{
var request = await client.GetAsync(requestUri);
var content = await request.Content.ReadAsStringAsync();
var xmlDocument = XDocument.Parse(content);
}
Upvotes: 13
Reputation: 395
You can call the web service and work with the json/xml response.
this returns a json response which you can work with.
As you can read in the terms of usage, you are only allowed to use their web service if you show a google map.
Here you can find all information about the service: https://developers.google.com/maps/documentation/geocoding/
To see how to handle the json response, take a look at this topic: Google Maps v3 geocoding server-side
EDIT: I just found this article: http://www.codeproject.com/Tips/505361/Google-Map-Distance-Matrix-and-Geocoding-API-V3-we
I didn't test this, but maybe it works for you :)
EDIT2: The codeproject example doesn't seem to work :( the url mentioned there returns always the same, no matter what address point is the input...
However you should try to work with the JSON or XML result anyway, as this is the best practice I would say.
Upvotes: 4