Получение геопозиции устройства
На устройствах с ОС Аврора информацию о географическом местоположении устройства предоставляет служба Geoclue. Цель GeoClue — использовать все возможные источники геолокации для наилучшего определения местоположения пользователя:
- спутники (приёмник GPS) в связке с A-GPS. A-GPS ускоряет определение местоположения в несколько раз за счёт подгрузки данных о спутниках из интернета. Точность до 10 метров;
- LBS сервисы (Яндекс.Локатор). Сервисы определяют местоположение по базовым станциям и WiFi-точкам. Точность зависит от окружения (от 50 метров по WiFi и до 2 километров по станциям).
В нативных приложениях информацию о геопозиции устройства можно получить с помощью модуля Qt Positioining как в C++, так и в QML-коде.
В процессе разработки приложения геоданные можно эмулировать с помощью плагина в SDK.
Геоданные можно использовать при работе с картами.
Режимы геолокации
Режим получения геоданных задается в настройках устройства в разделе "Геолокация":
Существует несколько способов геолокации, соответствующих следующим опциям получения данных о местоположении:
- Геолокация высокой точности — спутники, базовые станции и WIFI-точки, а также сеть с получением данных о спутниках;
- Только устройство — только спутники;
- Режим энергосбережения — только базовые станции и WIFI-точки.
Для работы только со спутниками необходимо находиться на открытой местности. Время, необходимое для набора данных и получения координат только со спутников, может превышать 5 минут. Определить работу влияние устройств заглушающих спутники геопозиции можно по следующим признакам:
Если в системе нет ключа Яндекс.Локатора, то единственными признаками заглушения спутников будут отличие фактического и выданного местоположения при спуфинге либо невозможность определить позицию при глушении или спуфинге. Если в режиме высокой точности радиус окружности на картах соответствует точности в 50+ метров, то определения по спутникам не произошло — позиция выдаётся Яндекс.Локатором, что может говорить о заглушении/спуфинге. В случае, когда ключ установлен в Яндекс.Локаторе, можно переключиться в режим энергосбережения в настройках геопозиции, если есть подозрение на спуфинг:
Конфигурация проекта
Для использования службы геолокации
в desktop-файле необходимо указать
разрешение Location
.
Для работы с модулем Qt Positioning в C++ необходимо прописать зависимость в spec-файле:
Requires: qt5-qtpositioning
И необходимо подключить positioning
в pro-файле:
QT += positioning
или Positioining
в CMakeLists.txt:
find_package (Qt5 COMPONENTS Core Positioining Qml Gui Quick LinguistTools REQUIRED)
Для работы с модулем Qt Positioning в QML достаточно прописать зависимость в spec-файле:
Requires: qt5-qtdeclarative-import-positioning
Получение геолокации в QML
Получить геолокационные данные в QML-части приложения можно следующим образом:
- Импортировать Qt Positioining:
import QtPositioning 5.3
. - Создать и активировать объект
PositionSource
для получения геоданных. - Обработать геоданные, например, вывести их на экран.
PositionSource
содержит свойствоposition
, которое содержит свойствоcoordinate
, из которого извлекаются широта, долгота, высота над уровнем моря.position
также содержит метку времени (timestamp
) и скорость движения в метрах в секунду (speed
).
Пример получения всех описанных выше данных:
import QtQuick 2.6
import Sailfish.Silica 1.0
import QtPositioning 5.3
Page {
PositionSource {
// Опционально можно задать интервал получения геоданных в миллисекундах.
// При навигации по спутникам интервал по умолчанию равен 1000 миллисекунд.
// При навигации по Яндекс.Локатору интервал по умолчанию — 5000 миллисекунд.
updateInterval: 1000
id: positionSource
active: true
}
SilicaFlickable {
anchors.fill: parent
contentHeight: pageHeader.height + displayColumn.height
PageHeader {
id: pageHeader
title: qsTr("PositionSource")
}
Column {
id: displayColumn
y: pageHeader.height
width: parent.width
Label {
text: positionSource.position.timestamp
width: parent.width
}
Label {
text: positionSource.position.coordinate
}
Label {
text: positionSource.position.coordinate.latitude.toFixed(6)
width: parent.width
}
Label {
text: positionSource.position.coordinate.longitude.toFixed(6)
width: parent.width
}
Label {
text: positionSource.position.coordinate.altitude.toFixed(6)
width: parent.width
}
Label {
text: qsTr("%1 meters / second").arg(positionSource.position.speed)
width: parent.width
}
}
}
}