Опубликован: 02.08.2013 | Доступ: свободный | Студентов: 468 / 15 | Длительность: 18:38:00
Специальности: Программист
Самостоятельная работа 16:

Работа с датчиками, определение местоположения

Определение местоположения

На странице MapPage.xaml показана работа с картой и службой определения местоположения, пример подготовлен на основе примера "Simple Map control sample" ("Пример работы с картой"), скачать пример в исходном виде можно здесь: http://code.msdn.microsoft.com/wpapps/Simple-Map-control-sample-fc94908f.

В файле CoordinateConverter.cs находится статический метод, который используется для разбора показателей о географическом расположении пользователя, Листинг 24.2.

using System;
using System.Device.Location; //Для класса GeoCoordinate.
using Windows.Devices.Geolocation; //Для класса Geocoordinate.

namespace P16_1
{
    public static class CoordinateConverter
    {
        public static GeoCoordinate ConvertGeocoordinate(Geocoordinate geocoordinate)
        {
            //Разбор показателей из geocoordinate
            return new GeoCoordinate
                (
                geocoordinate.Latitude,
                geocoordinate.Longitude,
                geocoordinate.Altitude ?? Double.NaN,
                geocoordinate.Accuracy,
                geocoordinate.AltitudeAccuracy ?? Double.NaN,
                geocoordinate.Speed ?? Double.NaN,
                geocoordinate.Heading ?? Double.NaN
                );
        }
    }
}
Листинг 47.2. Файл CoordinateConverter.cs

В файле MapPage.xaml (Листинг 24.3) содержится объявление элемента управления Map. Обратите внимание на то, что для использовании этого элемента управления в приложении, которое будет опубликовано, нужно указать идентификатор приложения и ключ аутентификации. Его можно получить на https://www.bingmapsportal.com/.

<phone:PhoneApplicationPage
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps"
    x:Class="P16_1.MapPage"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="{Binding LocalizedResources.ApplicationTitle, 
Source={StaticResource LocalizedStrings}}" 
Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
            <TextBlock Text="{Binding LocalizedResources.NavPageName, 
Source={StaticResource LocalizedStrings}}" 
Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" 
Margin="12,0,12,0">
            <maps:Map x:Name="sampleMap" LandmarksEnabled="False" Loaded="sampleMap_Loaded"/>
        </Grid>
     </Grid>

</phone:PhoneApplicationPage>
Листинг 47.3. Код файла MapPage.xaml

И в этом файле, и в файле кода, при создании панели приложения, используются строковые ресурсы из файла AppResources.resx и механизм привязки данных.

В Листинге 24.4 приведен код файла MapPage.xaml.cs. Здесь присутствуют, помимо механизмов для работы с картой и для определения местоположения, и вспомогательные механизмы. В частности, обратите внимание на объект currentLocation – именно в нём хранятся данные, полученные после определения местоположения, он же используется и для позиционирования маркера местоположения на карте. При работе с картой применяется масштабирование карты, включение и отключение маркера, указывающего на расположение устройства, включение и отключение меток на карте.

using System;
using System.Windows;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Controls;
using P16_1.Resources;
using Microsoft.Phone.Maps;
using Microsoft.Phone.Maps.Controls;
using System.Device.Location; // Для класса GeoCoordinate.
using Windows.Devices.Geolocation; //Для класса Geocoordinate.
using System.Windows.Shapes;
using System.Windows.Media;


namespace P16_1
{
    public partial class MapPage : PhoneApplicationPage
    {
        //Параметры масштабирования карты
        const int MIN_ZOOM_LEVEL = 1;
        const int MAX_ZOOM_LEVEL = 20;
        const int MIN_ZOOMLEVEL_FOR_LANDMARKS = 16;
        //Параметры определения местоположения и вывода дополнительных сведений
        ToggleStatus locationToggleStatus = ToggleStatus.ToggledOff;
        ToggleStatus landmarksToggleStatus = ToggleStatus.ToggledOff;
        //Для определения местоположения
        GeoCoordinate currentLocation = null;
        MapLayer locationLayer = null;

        // Конструктор.
        public MapPage()
        {
                        InitializeComponent();

            // Создание панели приложения ApplicationBar.
            BuildLocalizedApplicationBar();

            // Получение текущего расположения.
            GetLocation();
        }

        //Перед публикаией приложения здесь нужно указать параметры
        // ApplicationID и AuthenticationToken
        // их можно получить в Центре разработчиков Windows Phone
        private void sampleMap_Loaded(object sender, RoutedEventArgs e)
        {
            MapsSettings.ApplicationContext.ApplicationId = "<applicationid>";
            MapsSettings.ApplicationContext.AuthenticationToken = "<authenticationtoken>";
        }

        #region Обаботчики событий для кнопок и команд меню панели приложения

        void ToggleLocation(object sender, EventArgs e)
        {
            switch (locationToggleStatus)
            {
                case ToggleStatus.ToggledOff:
                    ShowLocation();
                    CenterMapOnLocation();
                    locationToggleStatus = ToggleStatus.ToggledOn;
                    break;
                case ToggleStatus.ToggledOn:
                    sampleMap.Layers.Remove(locationLayer);
                    locationLayer = null;
                    locationToggleStatus = ToggleStatus.ToggledOff;
                    break;
            }
        }

        void ToggleLandmarks(object sender, EventArgs e)
        {
            switch (landmarksToggleStatus)
            {
                case ToggleStatus.ToggledOff:
                    sampleMap.LandmarksEnabled = true;
                    if (sampleMap.ZoomLevel < MIN_ZOOMLEVEL_FOR_LANDMARKS)
                    {
                        sampleMap.ZoomLevel = MIN_ZOOMLEVEL_FOR_LANDMARKS;
                    }
                    landmarksToggleStatus = ToggleStatus.ToggledOn;
                    break;
                case ToggleStatus.ToggledOn:
                    sampleMap.LandmarksEnabled = false;
                    landmarksToggleStatus = ToggleStatus.ToggledOff;
                    break;
            }

        }

        void ZoomIn(object sender, EventArgs e)
        {
            if (sampleMap.ZoomLevel < MAX_ZOOM_LEVEL)
            {
                sampleMap.ZoomLevel++;
            }
        }

        void ZoomOut(object sender, EventArgs e)
        {
            if (sampleMap.ZoomLevel > MIN_ZOOM_LEVEL)
            {
                sampleMap.ZoomLevel--;
            }
        }

        #endregion

        #region Вспомогательные функции для обработчиов событий кнопок и
 команд меню панели приложения

        private void ShowLocation()
        {
            // Создание окружности, которая будт использована в качестве метки текущего расположения.
            Ellipse myCircle = new Ellipse();
            myCircle.Fill = new SolidColorBrush(Colors.Blue);
            myCircle.Height = 20;
            myCircle.Width = 20;
            myCircle.Opacity = 50;

            // Создания объекта MapOverlay на котором будет расположена окружность.
            MapOverlay myLocationOverlay = new MapOverlay();
            myLocationOverlay.Content = myCircle;
            myLocationOverlay.PositionOrigin = new Point(0.5, 0.5);
            myLocationOverlay.GeoCoordinate = currentLocation;

            // Создания слоя карты, MapLayer, на котором будет размещен объект MapOverlay.
            locationLayer = new MapLayer();
            locationLayer.Add(myLocationOverlay);

            // Добавлениее слоя MapLayer к карте.
            sampleMap.Layers.Add(locationLayer);

        }

        private async void GetLocation()
        {
            // Получить текущее расположение.
            Geolocator myGeolocator = new Geolocator();
            Geoposition myGeoposition = await myGeolocator.GetGeopositionAsync();
            Geocoordinate myGeocoordinate = myGeoposition.Coordinate;
            //Вызов вспомогательного метода для конверсии координат
            currentLocation = CoordinateConverter.ConvertGeocoordinate(myGeocoordinate);
        }

        //Центровка карты по текущему расположению
        private void CenterMapOnLocation()
        {
            sampleMap.Center = currentLocation;
        }

        #endregion

        // Создание локализованной панели приложения.
        private void BuildLocalizedApplicationBar()
        {
            // Установка панели приложения на новый объект ApplicationBar.
            ApplicationBar = new ApplicationBar();
            ApplicationBar.Opacity = 0.5;

            // Создание кнопок с локализованными надписями из AppResources.
            // Переключатель включения определения местоположения.
            ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/location.png", UriKind.Relative));
            appBarButton.Text = AppResources.AppBarToggleLocationButtonText;
            appBarButton.Click += ToggleLocation;
            ApplicationBar.Buttons.Add(appBarButton);
            // Переключатель для вывода дополнительных сведений на карте.
            appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/landmarks.png", UriKind.Relative));
            appBarButton.Text = AppResources.AppBarToggleLandmarksButtonText;
            appBarButton.Click += ToggleLandmarks;
            ApplicationBar.Buttons.Add(appBarButton);
            // Кнопка увеличения масштаба.
            appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/zoomin.png", UriKind.Relative));
            appBarButton.Text = AppResources.AppBarZoomInButtonText;
            appBarButton.Click += ZoomIn;
            ApplicationBar.Buttons.Add(appBarButton);
            // Кнопка уменьшения масштаба.
            appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/zoomout.png", UriKind.Relative));
            appBarButton.Text = AppResources.AppBarZoomOutButtonText;
            appBarButton.Click += ZoomOut;
            ApplicationBar.Buttons.Add(appBarButton);

            // Создание элементов меню с локализованными надписями из AppResources.
            // Элемент-переключатель для определения местоположения.
            ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarToggleLocationMenuItemText);
            appBarMenuItem.Click += ToggleLocation;
            ApplicationBar.MenuItems.Add(appBarMenuItem);
            // Элемент-переключатель для вывода меток на карте.
            appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarToggleLandmarksMenuItemText);
            appBarMenuItem.Click += ToggleLandmarks;
            ApplicationBar.MenuItems.Add(appBarMenuItem);
            // Элемент для увеличения масштаба.
            appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarZoomInMenuItemText);
            appBarMenuItem.Click += ZoomIn;
            ApplicationBar.MenuItems.Add(appBarMenuItem);
            // Элемент для уменьшения масштаба.
            appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarZoomOutMenuItemText);
            appBarMenuItem.Click += ZoomOut;
            ApplicationBar.MenuItems.Add(appBarMenuItem);
        }

        private enum ToggleStatus
        {
            ToggledOff,
            ToggledOn
        }
    }
}
Листинг 47.4. Код файла MapPage.xaml.cs

При отладке приложения в эмуляторе, как в случае с акселерометром, так и при работе с картами и системой определения местоположения, можно воспользоваться его дополнительными инструментами, рис. 47.2.

Отладка в эмуляторе приложения, использующего карты и средства определения местоположения

увеличить изображение
Рис. 47.2. Отладка в эмуляторе приложения, использующего карты и средства определения местоположения

Выводы

В этой лабораторной работе мы рассмотрели работу с акселерометром и системной определения местоположения в Windows Phone. Использование акселерометра позволяет организовать управление приложениями путём перемещения телефона в пространстве. Использование системы определения местоположение позволяет узнавать географические координаты пользователя.

Задание

Подумайте, как использование встроенных датчиков устройства может расширить возможности пользователя по управлению приложением, которое вы разрабатываете. Кроме того, проанализируйте возможности использования в приложении сервиса определения местоположения. Подготовьте отчет о проделанной работе.

Дополнительные материалы

К данной лекции подготовлено видеоприложение и демонстрационный программный проект.