Google Places API - Part 1

by CameronM 4. August 2014 08:54

Apps that help you find restaurants, bars, cinemas and other businesses are extremely popular. Apps like Yelp are bringing local search and reviews to the fore, with many people relying on these services to help them decide where to spend their hard-earned money.

Many of the big names, such as Google, also provide services that can be used to create your very own place-finding app. In this post, we’ll look at how you can user Google Places API to build a Windows Phone 8 ‘What’s near me’ app.

Signing up for the Google Places API

The first step is to sign up for the Google Places API. To do that, you’ll need a Google account and access to the API Console. Check out this page for more information about how to add access to the Place API to your account.

Once you’ve added the Places API to your account, you’ll need the take a note of the API key associated with that account to make any requests to the web service.

Creating our Visual Studio solution

Okay, so now that we have our API key, it’s time to fire up Visual Studio. Start by creating a new Class Library (Portable) project. Name the project GooglPlaces.PCL and the solution GooglePlaces.

Add two new folders to the project, one named Models and the other ViewModels. Using nuget, either via the ‘Manage Packages’ context menu, or using the console, add the Microsoft HTTP Client Libraries and the Json.NET packages. These will help us call the web service and then handle the resulting Json.

Performing a location based search

The Url for performing a basic Places search if as follows:

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=[Latitude],[Longitude]&radius=500&key=[Your API Key]

One handy tool you can use when dealing with API’s that return Json, is found at Json2CSharp. Copy and paste the Json formatted results from a call to the above Url into the textbox, hit Generate and a bunch of C# classes will be displayed.  These classes have been added to the Models folder of our project. For readability, each class was added to its’ own .cs file, however you could simply add them as a single file also.

The MainViewModel contains an ObservableCollection of results and a couple of asynchronous methods that call the Places API. This will be enough to get us started with creating a Windows Phone app and displaying a list of results.

In our app we’ll be retrieving the Latitude and Longitude from the device, so these will need to be variables we send to the web service. We’ll use a hard coded radius and create a class variable to hold the API Key.

public class MainViewModel : NotifyBase
{
    string baseUrl = "https://maps.googleapis.com/maps/api/place/nearbysearch";
    string apiKey = "[Your API Key]";
 
    private ObservableCollection<Result> _Results;
    public ObservableCollection<Result> Results
    {
        get { return _Results; }
        set
        {
            _Results = value;
            OnPropertyChanged("Results");
        }
    }
 
    public async Task LoadDataAsync(double Lat, double Long)
    {
        // convert the lat and long to a string
        string LatLong = string.Format("{0},{1}", Lat.ToString("0.0000"), Long.ToString("0.0000"));
 
        // build the NearbySearch Uri
        Uri uri = new Uri(string.Format("{0}/json?location={1}&radius=500&key={2}", baseUrl, LatLong, apiKey));
 
        // await the call to the API
        await FetchDataAsync(uri);
    }
 
    private async Task FetchDataAsync(Uri uri)
    {
        HttpClient client = new HttpClient();
        var response = await client.GetStringAsync(uri);
 
        var results = JsonConvert.DeserializeObject<ListRootObject>(response);
        this.Results = new ObservableCollection<Result>(results.results);
    }
}

Creating the Windows Phone project

With the basic methods and properties in our PCL, it’s time to add a new Windows Phone App (found in the C#/Store Apps category in Visual Studio).

Add a reference to the GooglePlaces.PCL project.

Create an application property that exposes our MainView model, so that it can be referenced throughout the app. In the App.xaml.cs file add the following code.

private static MainViewModel _ViewModel;
public static MainViewModel ViewModel
{
    get
    {
        if(_ViewModel == null)
            _ViewModel = new MainViewModel();
        return _ViewModel;
    }
    set
    {
        _ViewModel = value;
    }
 
}

Calling the ViewModel from the MainPage

We’ll override the OnNavigatedTo event to link the MainPage with the MainViewModel. This ensures that the ViewModel is available whenever the page gets called. In the MainPage.cs file add the following code.

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    this.DataContext = App.ViewModel;
 
    await App.ViewModel.LoadDataAsync(37.422, -122.083);
 
    base.OnNavigatedTo(e);
}

In this post just hard coding the latitude and longitude, to confirm that everything is wired up correctly. In a future post, we'll modify the code from How to get the phone's current location for Windows Phone 8 to get the actual location from the device.

Displaying the results

Now that we’ve linked the ViewModel, it’s time to add the XAML that will display the results. 

Add a new xmlns named local to your MainPage.xaml as follows:

xmlns:local="clr-namespace:GooglePlaces.WP"

Inside the ContentPanel Grid control, add the following mark-up:

<local:LongListSelector ItemsSource="{Binding Results}">
    <local:LongListSelector.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="12,0,0,17" >
                <Image Source="{Binding icon}" 
                        Height="48" Width="48" 
                        VerticalAlignment="Top" 
                        Margin="0,0,8,0"/>
                <StackPanel Margin="12,0,0,17" 
                            Width="432"
                            VerticalAlignment="Top" >
                    <TextBlock Text="{Binding name}" 
                                HorizontalAlignment="Left" 
                                VerticalAlignment="Top" 
                                FontSize="{StaticResource PhoneFontSizeLarge}" 
                                FontFamily="{StaticResource PhoneFontFamilyNormal}" />
                    <TextBlock Text="{Binding vicinity}" 
                                HorizontalAlignment="Left" 
                                Style="{StaticResource PhoneTextSubtleStyle}" />
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </local:LongListSelector.ItemTemplate>
</local:LongListSelector>

Run the app on your device and test out the results – you should get a list of places in the vicinity of the Lat/Long you hard-coded.

Tags: ,

C# | Windows Phone 8