Nokia Places API for Windows Phone
In this post I will demonstrate way to begin using the Nokia RESTful Places API and display places data in your Windows Phone application.
Nokia’s RESTful Places API is a web service API that allows you to offer your application’s users Nokia’s Places service as available in Nokia Maps and other applications within the look & feel of your own application. The Places service supports a variety of use cases that center around two major features:
- Place discovery – Help users find the places relevant to them
- Place information retrieval – Provide detailed information about places users are interested in
When you use the Places API to build an application, your users can find individual locations in
- over 200 countries
- over 1.5 million different areas (cities, districts, regions)
- over 25 million streets split into 90 million and more individual segments
- over 120 million point addresses within 15 countries
- over 75 million named and categorized places in more than 200 countries
Several million of those places come with rich attribution/content like
- editorial information for trusted content partners like Lonely Planet and Michelin
- ratings, reviews and images aggregated from a variety of online communities
- additional business information, often provided by the owner
In following scenario I will create WP7 app that will explore Nokia Places in your neighborhood, display them as pushpins on Bing Map, and show additional data (like images) on each pushpin tap. But first, in order to use API’s, you have to register as a Nokia Developer and retrieve your API Key. Also, you should register for Bing Maps Account, to submit credential data to your Bing Maps control:
Also, to consume Nokia Places API data you need an HTTP client and some Json framework for data deserialization. In this scenario I used RestSharp and Json.NET, and you can easily download nuget packages from following links:
(note: Json.NET was part of RestSharp package, but since version 103, Json.NET was removed from RestSharp as a dependency).
So, in this demo, we will collect current GPS location and ask Nokia Places service for nearby places:
private GeoCoordinateWatcher watcher; private GeoCoordinate myLocation; private string nokiaPlacesUrl = "http://demo.places.nlp.nokia.com/places/v1/discover/explore"; private string nokiaPlaceUrl = "http://demo.places.nlp.nokia.com/places/v1/places/"; private string nokiaPlacesAppID = "YOUR_APP_ID"; private string nokiaPlacesAppCode = "YOUR_APP_CODE"; private List<Place> places; private bool ignoreMapTap = false; public MainPage() { InitializeComponent(); watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged); watcher.Start(); } private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e) { if (watcher.Status != GeoPositionStatus.Ready) return; myLocation = e.Position.Location; mapPlaces.SetView(myLocation, 14); watcher.Stop(); this.GetPlaces(myLocation); } private void GetPlaces(GeoCoordinate location) { string url = string.Format("{0}?at={1},{2}&app_id={3}&app_code={4}&tf=plain&pretty=true", nokiaPlacesUrl, location.Latitude, location.Longitude, nokiaPlacesAppID, nokiaPlacesAppCode); var client = new RestClient(url); var request = new RestRequest(string.Empty, Method.GET); client.ExecuteAsync<RestRequest>(request, (response) => { places = this.ParsePlaces(response.Content); this.AddPushpins(places); }); }
Resulting Json response from service looks like this:
In following method we deserialize result to list of Places objects:
private List<Place> ParsePlaces(string json) { List<Place> places = new List<Place>(); if (json == string.Empty) return places; JToken jToken = JObject.Parse(json)["results"]["items"]; if (jToken == null) return places; IList<JToken> jlList = jToken.Children().ToList(); foreach (JToken token in jlList) { Place place = JsonConvert.DeserializeObject<Place>(token.ToString()); if (place.type == "urn:nlp-types:place") { IList<JToken> jTokenListPosition = token["position"].ToList(); GeoCoordinate position = new GeoCoordinate(); position.Latitude = double.Parse(jTokenListPosition[0].ToString()); position.Longitude = double.Parse(jTokenListPosition[1].ToString()); place.position = position; places.Add(place); } } return places; }
Places are added to map in following method:
private void AddPushpins(List<Place> places) { mapPlaces.Children.Clear(); Pushpin pushpinMe = new Pushpin(); pushpinMe.Background = new SolidColorBrush(Colors.Green); pushpinMe.Location = myLocation; pushpinMe.Content = "You"; mapPlaces.Children.Add(pushpinMe); foreach (Place place in places) { Pushpin pushpin = new Pushpin(); pushpin.Background = new SolidColorBrush(Colors.Blue); pushpin.Opacity = 0.6; pushpin.Location = place.position; pushpin.Tap += new EventHandler<GestureEventArgs>(pushpin_Tap); pushpin.Content = place.title; mapPlaces.Children.Add(pushpin); } }
This is how it looks in our app:
When user taps one of pushpins, another call to service is requested.
private void pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e) { ignoreMapTap = true; Pushpin pushpin = (sender as Pushpin); Place place = places.Where(p => p.position == pushpin.Location).FirstOrDefault(); this.DataContext = place; stackPanelDetail.Visibility = Visibility.Visible; image.Source = null; string url = string.Format("{0}{1}?app_id={2}&app_code={3}", nokiaPlaceUrl, place.id, nokiaPlacesAppID, nokiaPlacesAppCode); var client = new RestClient(url); var request = new RestRequest(string.Empty, Method.GET); client.ExecuteAsync<RestRequest>(request, (response) => { try { string firstImageUrl = JObject.Parse(response.Content)["media"]["images"]["items"].First["src"].ToString(); image.Source = new BitmapImage(new Uri(firstImageUrl, UriKind.Absolute)); } catch { } }); }
This call will return place’s details like alternative names, contact phones, fax, emails, websites, categories, rating, images etc (see image below):
In our scenario, we will display place data and first of images in media collection:
Conclusion
You can use Nokia Places API in various scenarios. For example, you can create some kind on City Explorer application and use various data together with Windows Phone platform features like Bing Maps Direction Task, Email Compose Task, Phone Call Task, Share Link Task and Web Browser Task to provide great app experience. Nokia also provide more robust maps services like Nokia Maps, Nokia Directions and Nokia Traffic which can be easily combined with WP Browser control (see Nokia Places API Blog for more information about this integration).
Additional resources and references about Nokia RESTful Places API can be found in following links:
Nokia RESTful Places Quick Start
Nokia RESTful Places User Guide
Nokia RESTful Places API Reference
Complete working zip solution can be downloaded from here (don’t forget to put your Bing Maps credentials in MainPage.xaml and nokiaPlacesAppID and nokiaPlacesAppCode in MainPage.xaml.cs).
This looks great! I really wish I had an app that needed this. I hope some devs take advantage of this. It’s for all devices, not just Nokia’s, ya? Could it be used on Windows 8?
Yes, it could be used on any platform.
From the looks of the TOU, it appears that this Places API has the same (stupid) limitation of the Bing Places API; you can’t save off any result for usage later. That means, in the case of your app for instance, you couldn’t save the Empire State building as a “favorite” and automatically bring up its information later.
I’m getting this from this area of the TOU:
”
You hereby agree that You will not:
…
(x) pre-fetch, cache, or store any Nokia Maps Content or Places Content except through API functionality specifically intended for such use and except that You may store (i) references and IDs; and (ii) limited amounts of Nokia Maps Content or Places Content solely for the purpose of testing your Application, if You do so temporarily, securely, and in a manner that does not permit use of the Nokia Maps Content or Places Content outside of the Service;
”
bah.
Hello! Right now I am learning programming, specifically Windows Phone, so I am very unexperienced and your example looks very nice for learning, but I can’t really make one thing, I have an error that “The type or namespace name ‘Place’ could not be found (are you missing a using directive or an assembly reference?)”. As far as I understand, in line
private List places; means that Place is a data type, but how can I declare it or something?
Thanks!
“Place” is my custom class. You can find it in source code (downlad link is at the end of post).
Oh, that’s quite embarrassing. Sorry for disturbing and sorry that I didn’t see that link.
Thanks for tutorial!
Alriiight! Quick update, I realised that you have to make class of Place with something like
public string type { get; set; }
public GeoCoordinate position { get; set; }
public string title { get; set; }
for Json! Learning by examples is fun!
Sorry for disturbing
Glad to help
That’s me again
I seem to get “InvalidCastException was unhandled” on
client.ExecuteAsync(request, (response) =>
{
places = this.ParsePlaces(response.Content);
this.AddPushpins(places);
});
using your ready source code. Maybe that’s my mistake? Thanks.
Error is probably JSON-data related. I didn’t create bullet-proof code in this example. As with any other data-related API, this one also needs additional testing. My suggestion is to inspect returned JSON result, and check in which part of ParsePlaces() method exception is raised.
I am pretty new to programming so do forgive my ignorance – is Nokia Maps now fully integrated with Bing? If so, would we be able to use similar code to replicate this with Bing alone?
Can it be use to develop for windows phone 8 ?
I suggest you to use new WP8 Maps Services (http://msdn.microsoft.com/en-us/library/windowsphone/develop/microsoft.phone.maps.services(v=vs.105).aspx); GeocodeQuery particular.
New WP8 map control and services are product of Microsoft/Nokia partnership.
alright, thanks a lot : )
I developed my application for windows phone 8 taxi stops, I need the address and phone information. How do I attach the information from Nokia maps. If you have any information on this subject would be very happy if you help.
this application does not work with the location emulator?
yes I am working on emulator. I am developing a WP 8 application. I use the Nokia Maps application. I need the information of the taxi stops, the car phone. How do I withdraw this information. I’d appreciate it if you help.