Статьи

Дополненная реальность, Windows 8 и облачные вычисления


заглавие Описание Ссылка на сайт
Приложениям дополненной реальности требуется серверная часть веб-службы. Это 90-дневное без обязательств, абсолютно бесплатное предложение использовать Windows Azure в качестве веб-службы для клиентов Windows 8. Вы получаете: Compute / 750 небольших вычислительных часов в месяц, веб-сайты / 10 веб-сайтов, мобильные сервисы / 10 мобильных сервисов, реляционная база данных / 1 база данных SQL, отчеты SQL / 100 часов в месяц, хранилище / 35 ГБ с 50 000 000 транзакций хранения, пропускная способность / неограниченный входящий и 25 ГБ исходящий, CDN / 20 ГБ исходящий с 500 000 транзакций, кэш / 128 МБ, служебная шина / 1500 часов ретрансляции и 500 000 сообщений http://www.microsoft.com/click/services
/Redirect2.ashx?CR_CC=200114759
образ
Шаг 0: Что мы будем строить. Дополненная реальность, Windows 8 и облачные вычисления — как реализовать с реальным кодом Введение высокого уровня в наше законченное приложение. http://blogs.msdn.com/b/brunoterkaly/archive/2012
/ 11/05 / step-0-что-мы-будем-строить-
дополненную реальность-windows-8-and-cloud-computing-how-how- в реализации-с реальной code.aspx #
Шаг 1 — Дополненная реальность, Windows 8 и облачные вычисления — Как реализовать с реальным кодом Вступление. Что такое дополненная реальность http://blogs.msdn.com/b/brunoterkaly/archive/2012/10/29/
шаг-1-дополненная реальность-окна-8-и-облачные вычисления-
как реализовать с реальным- code.aspx #
Шаг 2 — Дополненная реальность, Windows 8 и облачные вычисления — Как реализовать с реальным кодом Сборка первой части нашего бэкэнда Azure. http://blogs.msdn.com/b/brunoterkaly/archive/2012/10/30/
step-2-augmented-reality-windows-8-and-
cloud-computing-как реализовать с реальными code.aspx #
Шаг 3 — Дополненная реальность, Windows 8 и облачные вычисления — Как реализовать с реальным кодом (Внедрение облачной среды) В этом посте представлен весь исходный код и пояснения для серверной части Azure. Это серверная часть для Windows 8 Client дополненной реальности. http://blogs.msdn.com/b/brunoterkaly/archive/2012/11/05
/ step-3-augmented-reality-windows-8-and-cloud-computing-как
реализовать с реальными реализующий код из облака-обратно-end.aspx #
Шаг 4 — Дополненная реальность, Windows 8 и облачные вычисления — Как реализовать с реальным кодом … Этот пост содержит весь исходный код и пояснения для клиента Windows 8 (демонстрация дополненной реальности). Клиент дополненной реальности Windows 8 обращается к бэкэнду Azure, описанному в шаге 3 выше. http://blogs.msdn.com/b/brunoterkaly/archive/2012/11/06/
шаг-4-дополненная реальность-окна-8-и-облачные вычисления-как реализовать с реальными- код реализации
Windows-8-client.aspx #
Исходный код — серверная часть веб-службы Это проект Windows Azure, к которому обращаются клиенты Windows 8 http://sdrv.ms/Qoqb1J
Исходный код — клиент Windows 8 Это клиент дополненной реальности для Windows 8 http://sdrv.ms/T38uBC

Это проект Windows 8

образ

  1. Он работает на ОС Windows 8 и был построен с Visual Studio 2012
  2. Этот пост будет строить это приложение с нуля
  3. Он будет связываться с облачным бэкэндом, который мы создали в последнем посте.
  4. Облачный бэкэнд — это облачный проект Windows Azure

    • Он был развернут в центре обработки данных

Уровень клиента — Windows 8

образ

  1. Этот пост основан на последнем посте, который был уровнем Front-End Web Services. Это было облачное приложение Windows Azure (с веб-ролью типа ASP.NET Web API)
  2. Клиент дополненной реальности Windows 8 не будет работать, если не будет облачного сервера

    • Облачный сервер может работать в центре обработки данных MS
    • Или он может работать как проект Visual Studio 2012 с использованием эмулятора вычислений Windows Azure

Создание приложения для Windows 8

образ

  1. В Visual Studio выберите Файл / Новый проект / Приложение Магазина Windows.
  2. Выберите пустое приложение

Проект по умолчанию: изменение файла манифеста приложения

образ

  1. Вы ищете обозреватель решений

    • Он доступен из меню ВИД
  2. Щелкните правой кнопкой мыши Package.appmanifest и выберите VIEW DESIGNER. Это позволит нам изменить возможности. Например, мы хотим разрешить подключение к интернету.

Манифест приложения: включение возможностей

образ

  1. Я выбрал варианты, которые вы видите выше.

    • Интернет, микрофон, доступ к библиотеке изображений, доступ к библиотеке видео, веб-камера
  2. Когда вы запускаете приложение Windows 8, вам все равно необходимо подтвердить использование веб-камеры и микрофона.

Основной интерфейс: MainPage.xaml

образ

  1. Вы также можете использовать EXPRESSION BLEND для редактирования вашего графического интерфейса.
  2. Visual Studio 2012 также имеет дизайнера, доступного в меню просмотра.

Понимание XAML

образ

  1. Пользовательский интерфейс — это просто набор элементов управления XAML
  2. Это просто большой XML-файл, похожий на пользовательский интерфейс Android
  3. StackPanels и Grids составляют большую часть интерфейса
  4. Кнопки, текстовые блоки, изображения, прямоугольники, холсты, радиокнопки вложены в панели стека и сетки
  5. Существует также CapturePanel для отображения живого видео с веб-камеры.
  6. Этот экран показывает одну из панелей стека

    • Содержит вложенные StackPanels
    • Он содержит 2 кнопки и радиокнопки для симулятора GPS

      • Симулятор GPS позволяет выбрать Сан-Франциско, Рено, Денвер или Долину Смерти
      • Моя система не имеет встроенного симулятора

Понимание XAML

образ

  1. Радиокнопки расположены в StackPanel

Понимание XAML

образ

  1. Раздел дополненной реальности — это просто сетка с границами
  2. Сетка содержит TextBlocks, куда мы будем помещать данные, которые мы получаем от вызова нашего облачного бэкэнда Azure, облачного сервиса.

    • Заполнение TextBlocks информацией о местонахождении и погоде выполняется с помощью кода (MainPage.xaml.cs)
    <Page
         x:Class="AugmentedRealityClient.MainPage"
         IsTabStop="false"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="using:AugmentedRealityClient"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         HorizontalAlignment="Center"
         VerticalAlignment="Center">
        <Grid
              Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
              x:Name="LayoutRoot"
              HorizontalAlignment="Left"
              VerticalAlignment="Center">
            <!—Two rows, One column-->
            <Grid.RowDefinitions>
                <RowDefinition Height="165"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Border
                   BorderThickness="3"
                   BorderBrush="White"
                   Grid.Row="0"/>
            <StackPanel
                   Grid.Row="0"
                   Orientation="Horizontal"
                   Margin="6"
                   HorizontalAlignment="Left"
                   VerticalAlignment="Center">
                <Button
                        x:Name="butConfigure"
                        Content="Configure"
                        Width="200"
                        Height="80"
                        FontSize="32"
                        Margin="6"
                        Click="ConfigureCamera_Click"/>
                <Button
                        x:Name="butTurnCameraOn"
                        Content="Take Picture"
                        Width="218"
                        Height="80"
                        FontSize="32"
                        Margin="6,6"/>
                <StackPanel>
                    <TextBlock
                             x:Name="txtGPS"
                             FontSize="14"
                             Canvas.Left="22"
                             Canvas.Top="9"
                             Margin="0,12,0,2"
                             Foreground="Yellow"
                             FontFamily="Segoe UI"
                             Text="GPS Simulator"
                             FontWeight="Bold"
                             HorizontalAlignment="Left"
                             VerticalAlignment="Top"
                             TextAlignment="Center"/>
                    <RadioButton
                             Name="radSF"
                             GroupName="GPS"
                             Content="{Binding Path=City1, Mode=TwoWay}"
                             IsChecked="{Binding Path=IsChecked1, Mode=TwoWay}"
                             Checked="radSF_Checked">
                    </RadioButton>
                    <RadioButton
                             Name="radReno"
                             GroupName="GPS"
                             Content="{Binding Path=City2, Mode=TwoWay}"
                             IsChecked="{Binding Path=IsChecked2, Mode=TwoWay}"
                             Checked="radReno_Checked">
                    </RadioButton>
                    <RadioButton
                             Name="radDenver"
                             GroupName="GPS"
                             Content="{Binding Path=City3, Mode=TwoWay}"
                             IsChecked="{Binding Path=IsChecked3, Mode=TwoWay}"
                             Checked="radDenver_Checked">
                    </RadioButton>
                    <RadioButton
                             Name="radDeathValley"
                             GroupName="GPS"
                             Content="{Binding Path=City4, Mode=TwoWay}"
                             IsChecked="{Binding Path=IsChecked4, Mode=TwoWay}"
                             Checked="radDeathValley_Checked">
                    </RadioButton>
                </StackPanel>
            </StackPanel>
            <StackPanel
                   Grid.Row="1"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center">
                <Canvas
                        x:Name="previewCanvas1"
                        Background="Black"
                        Width="640"
                        Height="600">
                    <CaptureElement
                             x:Name="previewElement1"
                             HorizontalAlignment="Left"
                             VerticalAlignment="Top"/>
                    <Grid
                             HorizontalAlignment="Left"
                             VerticalAlignment="Top"
                             Margin="5">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="300"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="20"/>
                            <RowDefinition Height="20"/>
                            <RowDefinition Height="20"/>
                            <RowDefinition Height="20"/>
                            <RowDefinition Height="20"/>
                        </Grid.RowDefinitions>
                        <!--Row 1-->
                        <Rectangle
                                  Grid.Column="0"
                                  Grid.Row="0"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  Grid.Column="0"
                                  Grid.Row="0"
                                  Text="Neighborhood"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Foreground="#FFF2F213"/>
                        <Rectangle
                                  Grid.Column="1"
                                  Grid.Row="0"
                                  Stroke="white"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  x:Name="bus_and_neighborhood"
                                  Grid.Column="1"
                                  Grid.Row="0"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"/>
                        <!--Row 2-->
                        <Rectangle
                                  Grid.Column="0"
                                  Grid.Row="1"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  Grid.Column="0"
                                  Grid.Row="1"
                                  Text="Elevation"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Foreground="#FFF2F213"/>
                        <Rectangle
                                  Grid.Column="1"
                                  Grid.Row="1"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  x:Name="elevation"
                                  Grid.Column="1"
                                  Grid.Row="1"
                                  Text="(1,0)"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"/>
                        <!--Row 3-->
                        <Rectangle
                                  Grid.Column="0"
                                  Grid.Row="2"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  Grid.Column="0"
                                  Grid.Row="2"
                                  Text="Lat/Long"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Foreground="#FFF2F213"/>
                        <Rectangle
                                  Grid.Column="1"
                                  Grid.Row="2"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  x:Name="latlong"
                                  Grid.Column="1"
                                  Grid.Row="2"
                                  Text="(1,0)"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"/>
                        <!--Row 4-->
                        <Rectangle
                                  Grid.Column="0"
                                  Grid.Row="3"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  Grid.Column="0"
                                  Grid.Row="3"
                                  Text="Max temp"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Foreground="#FFF2F213"/>
                        <Rectangle
                                  Grid.Column="1"
                                  Grid.Row="3"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  x:Name="max_temp"
                                  Grid.Column="1"
                                  Grid.Row="3"
                                  Text="(1,0)"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"/>
                        <!--Row 5-->
                        <Rectangle
                                  Grid.Column="0"
                                  Grid.Row="4"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  Grid.Column="0"
                                  Grid.Row="4"
                                  Text="MinTemp"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  Foreground="#FFF2F213"/>
                        <Rectangle
                                  Grid.Column="1"
                                  Grid.Row="4"
                                  Stroke="White"
                                  Fill="Black"
                                  Opacity=".3"/>
                        <TextBlock
                                  x:Name="min_temp"
                                  Grid.Column="1"
                                  Grid.Row="4"
                                  Text="(1,0)"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"/>
                        <Image
                                  Grid.Column="2"
                                  Grid.Row="0"
                                  Grid.RowSpan="5"
                                  Source="http://www.ssec.wisc.edu/data/us_comp/image1.jpg"
                                  Opacity=".7"/>
                    </Grid>
                </Canvas>
            </StackPanel>
        </Grid>
    </Page>
    
    • Порядок элементов управления имеет решающее значение.
    • Это позволяет нам накладывать данные поверх потока живого видео с веб-камеры.
    • Если вы заметили, многие из текстовых блоков появляются ПОСЛЕ элемента управления CaptureElement.
    • Это контролирует z-порядок элементов управления.
Линия Комментарий
35-49 Две кнопки. Одна кнопка предназначена для включения веб-камеры, а другая — для фотографирования. Я иллюстрировал фотографирование в предыдущем посте. Содержит ссылку на метод события (ConfigureCamera_Click)
50-91 Пользовательский интерфейс для симулятора GPS. Текстовый блок и куча радио кнопок. Все 4 переключателя имеют процедуру обработки события, поскольку в конечном итоге они обращаются в веб-службу Azure для получения нового местоположения GPS.
98 Канва для отображения живого видеопотока дополненной реальности с веб-камеры
103-105 Элемент управления, отображающий потоковое видео в режиме дополненной реальности
143, 169, 196, 224, 250 TextBlocks, которые будут отображать данные дополненной реальности, поступающие из внутреннего облачного приложения Azure.
257 Используется для хранения последних спутниковых изображений погоды

MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// Some extra using statements for my code
using Windows.Devices.Enumeration;
using Windows.Media.Capture;
using Windows.Media.MediaProperties;
using System.Net.Http;
using Windows.Data.Json;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace Windows8AugmentedRealityClient
{
    public sealed partial class MainPage : Page
    {
        private Windows.Media.Capture.MediaCapture m_mediaCaptureMgr;

        // Our GPS simulator
        GPSSimulator _gps_simulator;

        // This object get populated with data from calling into
        // our Windows Azure Web Service, which was created in the
        // previous blog
        private LocationInfo loc_info = new LocationInfo();

        public MainPage()
        {
            this.InitializeComponent();

            // previewElement1 is our view port to see the streaming
            // video content from the web cam
            previewElement1.Source = null;
            // Make sure it is visible
            previewCanvas1.Visibility = Windows.UI.Xaml.Visibility.Visible;

            // Initialize our GPS Simulator
            _gps_simulator = new GPSSimulator();
            _gps_simulator.City1 = "San Francisco";
            _gps_simulator.Gps1 = "37.788345,-122.404679";
            _gps_simulator.IsChecked1 = true;
            _gps_simulator.City2 = "Reno";
            _gps_simulator.Gps2 = "39.545353,-119.815631";
            _gps_simulator.IsChecked2 = false;
            _gps_simulator.City3 = "Denver";
            _gps_simulator.Gps3 = "39.752073,-104.979968";
            _gps_simulator.IsChecked3 = false;
            _gps_simulator.City4 = "Death Valley";
            _gps_simulator.Gps4 = "36.619937,-117.10415";
            _gps_simulator.IsChecked4 = false;

            // Trap some change events (for debugging purposes)
            _gps_simulator.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(gpsChanged);

            // Bind our GPS Simulator to the Windows 8 form's DataContext
            this.DataContext = _gps_simulator;
        }

        private void gpsChanged(object sender, PropertyChangedEventArgs e)
        {
            string s = "The property:'" + e.PropertyName + "' was changed";
        }

        // Ignored for this demo
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        // Hit when user hits the "Configure" button
        // This method initializes the web cam to display the live
        // streaming video content
        internal async void ConfigureCamera_Click(Object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // Initialize Media Capture API
            try
            {
                // Prepare Media Capture
                m_mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
                var _captureSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings();

                DeviceInformationCollection deviceInfos = await DeviceInformation.FindAllAsync(Windows.Devices.Enumeration.DeviceClass.VideoCapture);
                _captureSettings = new MediaCaptureInitializationSettings();
                _captureSettings.StreamingCaptureMode = StreamingCaptureMode.Video;
                _captureSettings.PhotoCaptureSource = PhotoCaptureSource.VideoPreview;
                if (deviceInfos.Count > 0)
                {
                    _captureSettings.VideoDeviceId = deviceInfos[0].Id;
                }
                await m_mediaCaptureMgr.InitializeAsync(_captureSettings);

            }
            catch (Exception exception)
            {
                // Ignore errors for now
                string s = exception.Message;
            }

            // Start the Preview
            try
            {
                previewElement1.Source = m_mediaCaptureMgr;
                await m_mediaCaptureMgr.StartPreviewAsync();
            }
            catch (Exception exception)
            {
                previewElement1.Source = null;
            }
        }

        // This method performs the call into our Azure Web Service
        // fromt the previous post. This method will pass GPS parameters
        // to the cloud service and receive back JSON data that will
        // need to be parsed.
        private async System.Threading.Tasks.Task CallLocationWebService(string gps)
        {
            // Call into the emulator. This assumes you are running the
            // cloud project from the last post in the backgruond
            string _location = "http://127.0.0.1:81/api/values?location={0}";

            // You can use the line below once you deploy your cloud
            // application to the cloud (a MS data center)
            //string _location = "http://locationwebservice.cloudapp.net/api/values?location={0}";

            // Now make the aynchronous call. We need to pass the GPS
            // parameters here to the _location string mentioned above.
            using (HttpClient clientlocation = new HttpClient())
            using (var response = await clientlocation.GetAsync(string.Format(_location, gps)))
            {
                if (response.IsSuccessStatusCode)
                {
                    string webresponse = await response.Content.ReadAsStringAsync();

                    // Parse the string into a JSONObject
                    var parsedResults = JsonObject.Parse(webresponse);

                    IJsonValue val;

                    // Extract data embedded in JSONObject.
                    // Assign to controls in user interface
                    if (parsedResults.TryGetValue("latitude", out val))
                        loc_info.latitude = val.GetString();
                    if (parsedResults.TryGetValue("longitude", out val))
                        loc_info.longitude = val.GetString();
                    if (parsedResults.TryGetValue("bus_and_neighborhood", out val))
                        loc_info.bus_and_neighborhood = val.GetString();
                    if (parsedResults.TryGetValue("elevation", out val))
                        loc_info.elevation = val.GetString();
                    if (parsedResults.TryGetValue("bus_and_neighborhood", out val))
                        loc_info.bus_and_neighborhood = val.GetString();
                    if (parsedResults.TryGetValue("max_temp", out val))
                        loc_info.max_temp = val.GetString();
                    if (parsedResults.TryGetValue("min_temp", out val))
                        loc_info.min_temp = val.GetString();

                    this.bus_and_neighborhood.Text = loc_info.bus_and_neighborhood;
                    this.elevation.Text = loc_info.elevation;
                    this.latlong.Text = loc_info.latitude + "/" + loc_info.longitude;
                    this.max_temp.Text = loc_info.max_temp;
                    this.min_temp.Text = loc_info.min_temp;
                }
            }

        }
        // Checkbox events
        // Called when user clicks a radio button on the GPS Simulator
        private async void radSF_Checked(object sender, RoutedEventArgs e)
        {
            string s = _gps_simulator.Gps1;
            await CallLocationWebService(s);
        }

        private async void radReno_Checked(object sender, RoutedEventArgs e)
        {
            string s = _gps_simulator.Gps2;
            await CallLocationWebService(s);

        }
        private async void radDenver_Checked(object sender, RoutedEventArgs e)
        {
            string s = _gps_simulator.Gps3;
            await CallLocationWebService(s);

        }
        private async void radDeathValley_Checked(object sender, RoutedEventArgs e)
        {
            string s = _gps_simulator.Gps4;
            await CallLocationWebService(s);

        }
        // A helper method. Not currently used but was valuable during
        // debugging my controls.
        public IEnumerable<T> HelperFindMatch<T>(DependencyObject depObj) where T : DependencyObject
        {
            System.Diagnostics.Debugger.Break();
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in HelperFindMatch<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }
        // A helper method. Not currently used but was valuable during
        // debugging my controls.
        public T HelperFindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
        {

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);

                string controlName = child.GetValue(Control.NameProperty) as string;

                if (controlName.IndexOf("rad") != -1 && controlName != name)
                {
                    return child as T;
                }
                else
                {
                    T result = HelperFindVisualChildByName<T>(child, name);

                    if (result != null)
                        return result;
                }
            }
            return null;
        }


    }
    // This class represents the data populated by the Windows Azure
    // Web Service
    public class LocationInfo
    {
        // Data we will lookup
        public string latitude { get; set; }
        public string longitude { get; set; }
        public string elevation { get; set; }
        public string bus_and_neighborhood { get; set; }
        public string max_temp { get; set; }
        public string min_temp { get; set; }


    }
    //Implement INotifiyPropertyChanged interface to subscribe for
    //property change notifications
    public class GPSSimulator : INotifyPropertyChanged
    {
        private string _gps1;
        private string _city1;
        private bool _ischecked1;

        private string _gps2;
        private string _city2;
        private bool _ischecked2;

        private string _gps3;
        private string _city3;
        private bool _ischecked3;

        private string _gps4;
        private string _city4;
        private bool _ischecked4;

        public string Gps1
        {
            get { return _gps1; }
            set
            {
                _gps1 = value;
                RaisePropertyChanged("Gps1");
            }
        }

        public string City1
        {
            get { return _city1; }
            set
            {
                _city1 = value;
                RaisePropertyChanged("City1");
            }
        }
        public bool IsChecked1
        {
            get { return _ischecked1; }
            set
            {
                _ischecked1 = value;
                RaisePropertyChanged("IsChecked1");
            }
        }

        public string Gps2
        {
            get { return _gps2; }
            set
            {
                _gps2 = value;
                RaisePropertyChanged("Gps2");
            }
        }

        public string City2
        {
            get { return _city2; }
            set
            {
                _city2 = value;
                RaisePropertyChanged("City2");
            }
        }
        public bool IsChecked2
        {
            get { return _ischecked2; }
            set
            {
                _ischecked2 = value;
                RaisePropertyChanged("IsChecked2");
            }
        }


        public string Gps3
        {
            get { return _gps3; }
            set
            {
                _gps3 = value;
                RaisePropertyChanged("Gps3");
            }
        }

        public string City3
        {
            get { return _city3; }
            set
            {
                _city3 = value;
                RaisePropertyChanged("City3");
            }
        }
        public bool IsChecked3
        {
            get { return _ischecked3; }
            set
            {
                _ischecked3 = value;
                RaisePropertyChanged("IsChecked3");
            }
        }

        public string Gps4
        {
            get { return _gps4; }
            set
            {
                _gps4 = value;
                RaisePropertyChanged("Gps4");
            }
        }

        public string City4
        {
            get { return _city4; }
            set
            {
                _city4 = value;
                RaisePropertyChanged("City4");
            }
        }
        public bool IsChecked4
        {
            get { return _ischecked4; }
            set
            {
                _ischecked4 = value;
                RaisePropertyChanged("IsChecked4");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }

}

Спасибо за прочтение.  

Ваше задание — перейти на http://programmableweb.com и выполнить собственную дополненную реальность и сопоставления данных.
Не забудьте отправить его мне, чтобы я мог написать об этом в блогеУлыбка