restaurantapi/RestaurantAPI/Services/GooglePlacesService.cs

157 lines
4.8 KiB
C#
Raw Normal View History

2025-03-09 15:38:44 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using RestaurantAPI.Models;
public class GooglePlacesService
{
private readonly HttpClient _httpClient;
private readonly string _apiKey;
public GooglePlacesService(HttpClient httpClient, IConfiguration configuration)
{
_httpClient = httpClient;
_apiKey = configuration["GooglePlaces:ApiKey"];
}
public async Task<List<Restaurant>> GetRestaurantsAsync(
double latitude,
double longitude,
int radius = 5000,
int? minPrice = null,
int? maxPrice = null)
{
// Build the Nearby Search URL
string url = $"https://maps.googleapis.com/maps/api/place/nearbysearch/json" +
$"?location={latitude},{longitude}" +
$"&radius={radius}" +
$"&type=restaurant" +
$"&key={_apiKey}";
// Append optional minPrice/maxPrice
if (minPrice.HasValue) url += $"&minprice={minPrice.Value}";
if (maxPrice.HasValue) url += $"&maxprice={maxPrice.Value}";
// Call Google Places Nearby Search
HttpResponseMessage response = await _httpClient.GetAsync(url);
string json = await response.Content.ReadAsStringAsync();
Console.WriteLine("Google API Response: " + json);
// Return empty list if the request failed
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("Error: " + response.StatusCode);
return new List<Restaurant>();
}
// Deserialize the JSON into our GooglePlacesResponse model
var data = JsonSerializer.Deserialize<GooglePlacesResponse>(
json,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
var restaurants = new List<Restaurant>();
if (data?.Results != null)
{
foreach (var place in data.Results)
{
// Skip places missing a name or location
if (string.IsNullOrEmpty(place.Name) || place.Geometry?.Location == null)
{
Console.WriteLine($"Skipping a place due to missing name or location. Name: {place.Name}");
continue;
}
// Use Google's Place ID for unique identification
string placeId = place.PlaceId ?? Guid.NewGuid().ToString();
// Extract the first photo reference if available
string firstPhotoReference = place.Photos?.FirstOrDefault()?.PhotoReference;
// Generate the Google Maps URL
string googleMapsUrl = $"https://www.google.com/maps/place/?q=place_id:{placeId}";
// Create a Restaurant object with all necessary data
restaurants.Add(new Restaurant
{
Id = placeId,
PlaceId = placeId,
Name = place.Name,
Type = place.PriceLevel switch
{
1 => "Fast Food",
2 => "Casual Dining",
3 => "Fine Dining",
4 => "Luxury Dining",
_ => "Unknown"
},
Latitude = place.Geometry.Location.Lat,
Longitude = place.Geometry.Location.Lng,
Rating = place.Rating,
PriceLevel = place.PriceLevel,
PhotoReference = firstPhotoReference,
GoogleMapsUrl = googleMapsUrl
});
}
}
return restaurants;
}
}
// -------------------- Google Places Response Models --------------------
public class GooglePlacesResponse
{
[JsonPropertyName("results")]
public List<GooglePlace> Results { get; set; }
}
public class GooglePlace
{
[JsonPropertyName("place_id")]
public string PlaceId { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
public GoogleGeometry Geometry { get; set; }
[JsonPropertyName("rating")]
public double Rating { get; set; }
[JsonPropertyName("price_level")]
public int? PriceLevel { get; set; }
[JsonPropertyName("photos")]
public List<GooglePhoto> Photos { get; set; }
}
public class GoogleGeometry
{
public GoogleLocation Location { get; set; }
}
public class GoogleLocation
{
[JsonPropertyName("lat")]
public double Lat { get; set; }
[JsonPropertyName("lng")]
public double Lng { get; set; }
}
public class GooglePhoto
{
[JsonPropertyName("photo_reference")]
public string PhotoReference { get; set; }
}