Опубликован: 15.06.2012 | Доступ: свободный | Студентов: 1549 / 110 | Оценка: 4.19 / 3.63 | Длительность: 07:02:00
Специальности: Программист
Лекция 8:

Датчики и службы

< Лекция 7 || Лекция 8: 12 || Лекция 9 >

Географические координаты

С согласия пользователя приложение для Windows Phone 7 может принимать географические координаты телефона по методу Assisted-GPS или A-GPS.

Наиболее точный метод определения местоположения – по сигналам спутников Глобальной системы позиционирования (Global Positioning System, GPS). Но GPS может быть медленной. Эта система плохо работает в больших городах и в помещениях, ее применение энергоневыгодно, потому что приводит к большому расходу заряда батареи. Для энергосбережения и увеличения скорости, система A-GPS может определять местоположение по вышкам сотовой связи или сети. Эти методы намного более производительны и надежны, но менее точные.

Основным классом для определения местоположения является GeoCoordinateWatcher (Система отслеживания географических координат). Нам понадобится ссылка на сборку System.Device и директива using для пространства имен System.Device.Location. В файле WMAppManifest.xml должен присутствовать такой тег:

<Capability Name="ID_CAP_LOCATION"/>

Конструктор GeoCoordinateWatcher принимает один из элементов перечисления GeoPositionAccuracy (Точность географических координат):

  • Default (По умолчанию)
  • High (Высокая)

После создания объекта GeoCoordinateWatcher необходимо задать обработчик события PositionChanged (Местоположение изменилось) и вызвать метод Start. Событие PositionChanged возвращает объект GeoCoordinate (Географические координаты), имеющий восемь свойств:

  • Latitude (Широта), значение типа double в диапазоне от –90 до 90 градусов.
  • Longitude (Долгота), значение типа double в диапазоне от –180 до 180 градусов.
  • Altitude (Высота) типа double.
  • HorizontalAccuracy (Точность в горизонтальном направлении) и VerticalAccuracy (Точность в вертикальном направлении) типа double.
  • Course (Курс), значение типа double в диапазоне от 0 до 360 градусов.
  • Speed (Скорость) типа double.
  • IsUnknown (Неизвестно), булево значение, которое равно true, если Latitude или Longitude не является числом.

Если приложение не имеет разрешения на определение местоположения, свойства Latitude и Longitude будут иметь значение Double.NaN, и IsUnknown будет true.

Кроме того, в GeoCoordinate есть метод GetDistanceTo (Определить расстояние до), вычисляющий расстояние между двумя объектами GeoCoordinate.

Мы рассмотрим первые два свойства. Их называют географическими координатами. Они определяют точку на поверхности Земли. Широта – это угловое расстояние от экватора. Как правило, широта обозначается как угол от 0 до 90 градусов с указанием С или Ю (сервер или юг). Например, широта Нью-Йорка примерно 40°С. В объекте GeoCoordinate широты к северу от экватора соответствуют положительным значениям, и широты к югу от экватора – отрицательным. Северный Полюс соответствует 90°, и Южный Полюс – –90°.

Географические местоположения с одинаковой широтой образуют линию широты или параллель. Для заданной широты долгота – это угловое расстояние от нулевого меридиана, который проходит через Гринвичскую астрономическую обсерваторию, Англия. Долготу определяют как западную или восточную. Нью-Йорк располагается на 74° западной долготы, потому что он находится на запад от нулевого меридиана. В объекте GeoCoordinate положительные значения долготы соответствуют восточному полушарию, и отрицательные значения – западному. Значения 180 и –180 встречаются на линии перемены дат.

Пространство имен System.Device.Location включает классы, которые используют географические координаты для определения адресов (улиц и городов), но эта возможность не реализована в первой выпущенной версии Windows Phone 7.

Проект XnaLocation просто обеспечивает вывод на экран числовых значений.

Не забудьте добавить соответствующий шрифт.

Добавьте библиотеку System.Device тем же способом, как мы добавляли Microsoft.Devices.Sensors в прошлой программе.

Проект XNA: XnaLocation Файл: Game1.cs (фрагмент, демонстрирующий поля)

…
using System.Device.Location;
…
  public class Game1 : Microsoft.Xna.Framework.Game 
    { GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont segoe14;
        string text = "Obtaining location...";
        Viewport viewport;
        Vector2 textPosition; 
  …

Как и в случае с акселерометром, GeoCoordinateWatcher создается и инициализируется в перегруженном Initialize. Обработчик события вызывается в том же потоке, поэтому для форматирования результатов в строку не надо делать ничего особенного:

Проект XNA: XnaLocation Файл: Game1.cs (фрагмент)

  protected override void Initialize()
        {
            GeoCoordinateWatcher geoWatcher = new GeoCoordinateWatcher();
            geoWatcher.PositionChanged += OnGeoWatcherPositionChanged; 
            geoWatcher.Start();
            base.Initialize(); 
        }
        void OnGeoWatcherPositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> args) 
        { 
            text = String.Format("Latitude: {0:F3}\r\n" + "Longitude: {1:F3}\r\n" + 
"Altitude: {2}\r\n\r\n" + "{3}", args.Position.Location.Latitude, 
args.Position.Location.Longitude, args.Position.Location.Altitude, args.Position.Timestamp);
        } 

Метод LoadContent просто получает шрифт и сохраняет Viewport для позиционирования текста впоследствии:

Проект XNA: XnaLocation Файл: Game1.cs (фрагмент)

protected override void LoadContent() 
        { 
            spriteBatch = new SpriteBatch(GraphicsDevice); 
            segoe14 = this.Content.Load<SpriteFont>("Segoe14");
            viewport = this.GraphicsDevice.Viewport;
        } 

Размер отображаемой строки может меняться в зависимости от значений, поэтому ее местоположение вычисляется на основании ее размера и значений Viewport в методе Update:

Проект XNA: XnaLocation Файл: Game1.cs (фрагмент)

protected override void Update(GameTime gameTime) 
       {
           // Обеспечиваем возможность выхода из игры 
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit();
           Vector2 textSize = segoe14.MeasureString(text);
 textPosition = new Vector2((viewport.Width - textSize.X) / 2,(viewport.Height - textSize.Y) / 2);
           base.Update(gameTime);
       } 

Метод Draw обычный:

Проект XNA: XnaLocation Файл: Game1.cs (фрагмент)

protected override void Draw(GameTime gameTime) 
       {
           GraphicsDevice.Clear(Color.Navy); 
           spriteBatch.Begin(); 
           spriteBatch.DrawString(segoe14, text, textPosition, Color.White); 
           spriteBatch.End(); base.Draw(gameTime); 
       } 

GeoCoordinateWatcher выполняется в течение всего выполнения приложения, поэтому он должен обновлять данные о местоположении в случае перемещения телефона.

Ключевые термины

Microsoft.Devices.Sensors – библиотека, которая используется для работы с акселерометром в Windows Phone 7.

Акселерометр– небольшое аппаратное устройство, по сути, измеряющее силу, пропорциональную ускорению.

Глобальная система позиционирования (Global Positioning System, GPS) – система, использующая для определения местоположения, сигнал спутников.

Краткие итоги

В данной лекции мы:

  • разобрали все датчики и сервисы, используемые в устройствах на Windows Phone 7;
  • научились использовать акселерометр;
  • работали с географическими координатами, написали программу, реагирующую на изменение координат и выводящую их на экран.

Набор для практики

Упражнения

Если вы пользовались эмулятором, постарайтесь найти мобильное устройство на базе WP7 и протестировать на нём написанные программы. Это позволит более наглядно продемонстрировать работу акселерометра и изменение географических координат.

< Лекция 7 || Лекция 8: 12 || Лекция 9 >