before we begin
Get the API keys set up – if you haven’t registered already, go to http://api.maps.nokia.com/en/restplaces/overview.html and do so, then register for a personal app key & code that you can use. After that’s done, edit the App.xaml and insert your own keys.
<usoniandream:ServiceURI x:Key="NOKIA_SERVICE_URI_PLACES" URL="http://places.nlp.nokia.com/places/v1/" /> <usoniandream:ServiceAPIKey x:Key="NOKIA_APP_CODE" Value="" /> <usoniandream:ServiceAPIKey x:Key="NOKIA_APP_ID" Value="" />
the namespace you’ll need to add to your App.xaml is:
xmlns:usoniandream="clr-namespace:Usoniandream.WindowsPhone.LocationServices.Models;assembly=Usoniandream.WindowsPhone.LocationServices"
NuGet for the prerequisites
Easiest way to grab both the Reactive Extensions (rx) and RestSharp is to use NuGet. Install the following two packages and you’re set to move forward:
- Rx_Experimental-Xaml version 1.1.11111
- RestSharp version 102.7
add the references needed
1) Add references to the core library:
- Usoniandream.WindowsPhone.LocationsServices
- Usoniandream.WindowsPhone.Extensions
- Usoniandream.WindowsPhone.GeoConverter
2) Add a reference to the Bing data library:
- Usoniandream.WindowsPhone.LocationsServices.Nokia
add some code
3) Declare a service layer:
public LocationServices.Service.Nokia.Reactive.ServiceLayer nokiaservicelayer = new LocationServices.Service.Nokia.Reactive.ServiceLayer();
4) Declare a property container for the results:
public ObservableCollection<Place> NokiaPlaces { get; set; }
5) Wire the call to get the POI’s nearby:
var places = nokiaservicelayer.GetNokiaPlaces(new WindowsPhone.LocationServices.SearchCriterias.Nokia.Places.Places(CurrentLocation, "sv, en-gb;q=0.8, en;q=0.7")) .DistinctUntilChanged() .ObserveOnDispatcher() .Subscribe(x => { NokiaPlaces.Add(x); }, ex => { // handle error.. });
6) Finally, a bit of xaml to wrap it all up:
<toolkit:MultiselectList x:Name="mslNokiaPlaces" ItemsSource="{Binding NokiaPlaces}" Margin="-20,0,0,0" Visibility="{Binding NokiaPlaces.Count, Converter={StaticResource NumberToVisibilityConverter}}"> <toolkit:MultiselectList.ItemTemplate> <DataTemplate> <Button Style="{StaticResource ChromelessButton}" DataContext="{Binding .}"> <StackPanel> <TextBlock x:Name="Title" Foreground="#004C9A" Text="{Binding Content}" TextTrimming="WordEllipsis" Style="{StaticResource PhoneTextLargeStyle}" /> <TextBlock Text="sponsored result" Style="{StaticResource PhoneTextSubtleStyle}" Visibility="{Binding Sponsored, Converter={StaticResource BoolToVisibilityConverter}}"/> <TextBlock Text="{Binding Distance, Converter={StaticResource DoubleToDistanceConverter}}" Style="{StaticResource PhoneTextNormalStyle}" /> </StackPanel> </Button> </DataTemplate> </toolkit:MultiselectList.ItemTemplate> <toolkit:MultiselectList.ItemContainerStyle> <Style TargetType="toolkit:MultiselectItem"> <Setter Property="Margin" Value="-12,0" /> <Setter Property="CacheMode" Value="BitmapCache" /> </Style> </toolkit:MultiselectList.ItemContainerStyle> </toolkit:MultiselectList>
7) And the end result gives us:
8) from there you can easily add a click handler to the surrounding button that goes out to fetch the details in a similar way as shown below:
public PlaceDetails NokiaPlaceDetails { get; set; } public void FetchDetails(LocationServices.Models.Nokia.Places.Place item) { NokiaService.GetNokiaPlace(new LocationServices.SearchCriterias.Nokia.Places.Place(item.Id, "sv, en-gb;q=0.8, en;q=0.7")) .ObserveOnDispatcher() .Subscribe(x => { NokiaPlaceDetails = x; }, ex => { // handle errors.. }, () => { this.RaisePropertyChanged(""); }); }
9) and the end result of that place detail query could look something like this after you’ve hammered it into a xaml view:
9) and finally, if you instead want to display your results on a map it’s as easy as binding the collection to a MapItemsControl:
<maps:Map ZoomBarVisibility="Visible" ScaleVisibility="Visible" ZoomLevel="15" Center="{Binding CurrentLocation}" CredentialsProvider="{StaticResource BingCredentials}"> <maps:MapItemsControl ItemsSource="{Binding NokiaPlaces}"> <maps:MapItemsControl.ItemTemplate> <DataTemplate> <maps:Pushpin Background="#004C9A" Content="{Binding Content}" Location="{Binding Location}" /> </DataTemplate> </maps:MapItemsControl.ItemTemplate> </maps:MapItemsControl> <maps:Pushpin Location="{Binding CurrentLocation}" Style="{StaticResource MyLocationStyle}" /> </maps:Map>
The BingCredentials is your Bing API key that the Maps control require in order to not show the “invalid credentials” and the MyLocationStyle is simply a style for the pushpin in the shape of an ellipsis.
10) with the neat result as seen below:
The framework libraries, source code and sample app are all on GitHub: https://github.com/peterdrougge/Usoniandream.WIndowsPhone.LocationServices