Implementing augmented reality using GART

This article will show the details of implementing augmented reality in Windows Phone using Geo Augmented Reality Toolkit (GART). GART enables you to create augmented reality experiences that depend on real geographical locations. It takes care of overlaying Bing maps, your heading, picture/frames from camera and virtual elements that display information about certain points of interest.

In the last article I wrote about GART, I mentioned 6 steps necessary for creating an augmented reality app using GART. Those steps were:


  • Add an ARDisplay control to your Windows Phone page
  • Add the views you want as children of the ARDisplay control
  • Start and stop services when navigating to and from the page
  • Create a collection of ARItem objects (or your own custom type that inherits from ARItem) and include real geolocation
  • Set ARDisplay.Items equal to your new collection
  • Optionally, style the elements


Of course, the first step is missing (or we could call it the step 0) which is creating the Windows Phone project and adding the GART reference. GART can be downloaded here:

Windows Phone project needs to be created and GART added to references. Now we can start with the 6 steps and the result would be an app that was shown on this youtube video:

GART Windows Phone demo

Add ARDisplay control

Besides adding the reference to the project, you need to add it on the top of the MainPage.xaml page:


The references need to be added to the MainPage.xaml.cs code file:

using GART;  
using GART.Controls;  
using GART.Data;

Adding the control is really simple. Just put it inside the main grid, usually named LayoutRoot.

<Grid x:Name="LayoutRoot">
    <gart:ARDisplay Name="ardisplay" Tap="ardisplay_Tap">


And that’s it. This is just the control, but now we need the layers included, too!

Add the views you want as children of the ARDisplay control

The layers, or the views, need to be added in this specific order, otherview you might encounter problems in displaying them all correctly. Just add them as the children of ARDisplay control:

<Grid x:Name="LayoutRoot">  
    <gart:ARDisplay Name="ardisplay" Tap="ardisplay_Tap">
        <gart:VideoPreview x:Name="videoPreview"/>
        <gart:OverheadMap x:Name="overheadMap" CredentialsProvider="{StaticResource BingCredentials}" />
        <gart:WorldView x:Name="worldView" ItemTemplate="{StaticResource CityItem}" />
        <gart:HeadingIndicator x:Name="headingIndicator" Width="300" Height="300" HorizontalAlignment="Center" VerticalAlignment="Center"/>

You’ll notice that the OverheadMap layers needs Bing credentials – that’s because GART takes care of the Bing maps for you. VideoPreview gives you the frames from the camera, WorldView gives you the layer for virtual elements, and the HeadingIndicator indicates your heading.

To be able to switch between the layers, you should add four buttons in the ApplicationBar. You can add less in case you’re not using all the layers.

    <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
        <shell:ApplicationBarIconButton x:Name="threeDButton" IconUri="/Images/appbar.3D.png" Text="3D" Click="threeDButton_Click"/>
        <shell:ApplicationBarIconButton x:Name="headingButton" IconUri="/Images/appbar.heading.png" Text="heading" Click="headingButton_Click"/>
        <shell:ApplicationBarIconButton x:Name="mapButton" IconUri="/Images/" Text="map" Click="mapButton_Click"/>
        <shell:ApplicationBarIconButton x:Name="rotateDButton" IconUri="/Images/appbar.rotate.png" Text="rotate" Click="rotateDButton_Click"/>

All the buttons have click events, so you need to implement those too. It’s great that GART offers you some helpers to turn on and off layer as easy as possible. You need this in the code behind (MainPage.xaml.cs)

private void threeDButton_Click(object sender, EventArgs e)  

private void headingButton_Click(object sender, EventArgs e)  

private void mapButton_Click(object sender, EventArgs e)  

private void rotateDButton_Click(object sender, EventArgs e)  

private void SwitchHeadingMode()  
    if (headingIndicator.RotationSource == RotationSource.AttitudeHeading)
        headingIndicator.RotationSource = RotationSource.North;
        overheadMap.RotationSource = RotationSource.AttitudeHeading;
        overheadMap.RotationSource = RotationSource.North;
        headingIndicator.RotationSource = RotationSource.AttitudeHeading;

Start and stop services when navigating to and from the page

In the code behind, the MainPage.xaml.cs, you need to start and stop the services:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)  

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)  

Create a collection of ARItem objects (or your own custom type)

For the demo I created (the earlier video), I created a CityPlace class that inherits from ARItem expanding it with one more property called Description – it basically just describes the city place that I’m showing.

using GART.Data;

namespace GARTdemo  
    public class CityPlace : ARItem
    private string description;

    public string Description
            return description;
           if (description != value)
           description = value;
           NotifyPropertyChanged(() => Description);

In the MainPage.xaml.cs I initialize the ObservableCollection and get data (call the method):

private ObservableCollection<ARItem> locationsTvrda;

public MainPage()  
    locationsTvrda = new ObservableCollection<ARItem>();


GetData method adds a bunch of CityPlace items with real geographical locations and descriptions to the locationsTvrda collection.

private void GetData()  
    locationsTvrda.Add(new CityPlace()
        GeoLocation = new GeoCoordinate(45.560450422716464, 18.69576883316039),
        Content = "Kugin spomenik",
        Description = "Spomenik Presvetom Trojstvu - sa svecima Sv. Sebastionom, Sv.Rokom, Sv. Rozalijom i Sv. Katarinom - podignut je 1729. do 1730. godine u središtu Tvrđe kao zavjetni spomenik da se Bog smiluje i da odvrati kugu koja je harala u Osijeku i u cijeloj Slavoniji"

This is done for all the objects. I’m showing just one, as an example. Have in mind that GeoCoordinate class has many possible constructors, so you can add the altitude of the specific objects, too. The problem may only be that they are detected only in the radius of 300 yards (around 275 meters).

Bind ARDisplay.Items to your new collection

At the end of the GetData method, I set the ItemsSource of the ARDisplay control to the ObservableCollection:

ardisplay.ARItems = locationsTvrda;

And that’s it!

Optionally, style the elements

I know I said that we’re done with XAML, but in case you wish to style the virtual elements displayed over the real life objects, you can do it in XAML. For example, the styling used for this demo was this:

    <DataTemplate x:Key="CityItem">
        <Border BorderBrush="Black" BorderThickness="4" CornerRadius="8" Background="#FF003847" Width="320">
            <StackPanel Margin="4">
                <TextBlock x:Name="NameBlock" TextWrapping="NoWrap" Text="{Binding Content}" FontSize="38" VerticalAlignment="Center" Margin="0,0,4,0" d:LayoutOverrides="Width" Grid.Column="1" TextTrimming="WordEllipsis"/>
                <TextBlock x:Name="DescriptionBlock" TextWrapping="Wrap" Text="{Binding Description}" FontSize="24" VerticalAlignment="Center" Margin="0,0,4,0" d:LayoutOverrides="Width" Grid.Column="1" TextTrimming="WordEllipsis" MaxHeight="168"/>

Nothing too complicated or difficult!

That’s it! Augmented reality application in 6 easy steps! :)

Like igrali blog on Facebook! Prefer Twitter?

About Igor Ralic

Software engineer at Microsoft. Running for Office. Passionate about making an impact with great apps & services. Stays close to coffee and away from coriander. Opinions expressed here are my own.