Geo Augmented Reality on Your Windows Phone Apps

GART is an excellent toolkit that helps Windows Phone developers quickly add Geo Augmented Reality into the phone app. There's also a Silverlight and Windows Phone Augmented Reality Toolkit (SLARToolkit) which for your reference I am adding here, but we will workout a very simple introductory Geo Augmented Reality using GART. The objective of this small code snippet is that the user will be see a camera view on her/he phone. Once s/he rotates the phone in 360, the nearest attractions (in this case, only three data points) will be shown, along with its distance from the user’s location in meters. Unfortunately, the Windows Phone emulator doesn’t support a camera view in the default setting, we need a motion-enabled device to run the app, because GART makes usage of that particular capability.

Depending your current location, you may expect to see output like the following:

1546369_410299179100268_1594752163_n

Getting Started

First of all download the library and add to your project as well as Microsoft.Phone.Controls.Toolkit. Add a GeoCoordinateWather to track current location of the user, an ObservableCollection of the locations and a variable to hold the current location of the user.

 private readonly GeoCoordinateWatcher _GeoWatcher = 
     new GeoCoordinateWatcher(GeoPositionAccuracy.High);
private ObservableCollection<ARItem> locations;
private GeoPosition<GeoCoordinate> CurrentPosition { get; set; }

Putting Up the AR Display

Before we can start playing with the GART library, we are going to add the VideoPreview control to show the camera view and the WorldView control which actually adds the data points on top of that.

 <controls:ARDisplay Name="ardisplay" AttitudeRefreshRate="50" MovementThreshold="10">
    <controls:VideoPreview x:Name="videoPreview" Canvas.ZIndex="1"/>
    <controls:WorldView x:Name="worldView" 
          ItemTemplate="{StaticResource DestinationTemplate}" 
         MinItemScale="0.1" MaxItemScale="1.0" FarClippingPlane="100000000000.0" 
         NearClippingPlane="1.0" 
         Canvas.ZIndex="1"/>
</controls:ARDisplay>

Calculating Distance

There’s an in-built method in the GeoCoordinate class that can take care of the distance calculation:

 private string GetLocationText(double lat, double lon)
{
    if (CurrentPosition != null && CurrentPosition.Location != null)
    {
        var start = new GeoCoordinate
              (CurrentPosition.Location.Latitude, 
               CurrentPosition.Location.Longitude);
        var end = new GeoCoordinate(lat, lon);
        var distance = start.GetDistanceTo(end);

        return distance < 1000
            ? string.Format("{0}m away.", Math.Round((double)distance, 0))
            : string.Format("{0}km away.", Math.Round((double)distance / 1000, 2));
    }

    return string.Empty;
}

Feeding the Dataset into GART

The most important part, yet simple is to feed the location data points we need to plot.

 public MainPage()
{
    InitializeComponent();

    _GeoWatcher.PositionChanged += (o, args) 
    => Dispatcher.BeginInvoke(() =>
    {
        CurrentPosition = _GeoWatcher.Position;

        locations = new ObservableCollection<ARItem><br>        {            new Destination()<br>            {<br>                GeoLocation = new GeoCoordinate(23.776345, 90.41609), <br>                Content = "গুলশান জামে মসজিদ",<br>                Description = GetLocationText(23.776345, 90.41609)<br>            },            new Destination()<br>            {<br>                GeoLocation = new GeoCoordinate(23.774594, 90.41200299999998), <br>                Content = "নিকেতন মসজিদ",<br>                Description = GetLocationText(23.774594, 90.41200299999998)<br>            },            new Destination()<br>            {<br>                GeoLocation = new GeoCoordinate(23.779672, 90.41493), <br>                Content = "গুলশান ১ ডিসিসি মসজিদ",<br>                Description = GetLocationText(23.779672, 90.41493)<br>            }<br>        }; 




        ardisplay.ARItems = locations;
    });

    _GeoWatcher.Start();
}

Source code

You can download the full code from here.