Датчики и службы
Географические координаты
С согласия пользователя приложение для 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 и протестировать на нём написанные программы. Это позволит более наглядно продемонстрировать работу акселерометра и изменение географических координат.