Главная » Разработка для Windows Phone 7 » Географические координаты Windows Phone 7

0

С согласия пользователя приложение для 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 просто обеспечивает вывод на экран числовых значений. Проект XNA: XnaLocation Файл: Game1.cs (фрагмент, демонстрирующий поля)

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(kootenay14, text, textPosition, Color.White); spriteBatch.End();

base.Draw(gameTime);

}

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

Но на эмуляторе телефона приложение GeoCoordinateWatcher может не работать. При использовании с некоторыми бета-версиями инструментов разработки для Windows Phone 7 акселерометр всегда возвращает координаты Принстона, Нью-Джерси, наверное, как робкое напоминание о месте, где Алан Тьюринг получил свою первую ученую степень.

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

  • Комментарии