>

Статьи>

Использование картографических библиотек MFW в ОС Аврора

Использование картографических библиотек MFW в ОС Аврора

Logo

Использование картографических библиотек MFW в ОС Аврора

В чём проблема существующих решений?

Работа с картами в ОС Аврора достаточно долгое время была представлена Qt-модулями Location и Positioning, и плагином WebTiles.

Основным минусом такого подхода является использование только растровых тайлов. И для работы с картой нам требуется более широкий функционал, например, офлайн построение маршрута и офлайн работа с адресами и координатами (прямой и обратный геокодинг).

Какое решение мы искали?

По мере продвижения в поисках решения мы составили список требований к Картам:

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

Какие решения были найдены?

И по итогам исследований мы составили список доступных решений. Можно использовать Navitel, СитиГид или Panorama Mobile. Но эти решения нельзя использовать в собственных приложениях.

Среди API доступны решения от Yandex и 2ГИС, но у них нет подходящего API под ОС Аврора, и у Yandex подразумевается платное использование сервиса в промышленных масштабах.

Также есть OpenSource-решения, такие как OSM Scout Server и PureMaps. Но у первого сложная интеграция и нет API для работы с тайлами, а второй проект в стазисе.

В итоге мы пришли к выводу, что требуется собственное решение, инструменты, которые позволят разработчикам интегрировать Карты в приложения под ОС Аврора. В качестве основного движка была выбрана MapLibre Native библиотека, на основе которой было реализовано собственное решение.

Наш вариант решения

Схема проекта получилась следующая:

First_scheme

Трудности реализации жестов

Начали работы над созданием собственных инструментов, и столкнулись с проблемами обработки жестов на мобильном устройстве.

Мы реализовали следующие жесты: zoom, перемещение, вращение, наклон карты и другие.

Zoom in/out Перемещение Вращение Наклон карты
zoom move rotate pitch

Основные сложности возникли с обработкой жестов с двумя касаниями и их детектированием:

  • Приближение/отдаление (zoom);
  • Вращение карты;
  • Наклон карты;
  • Одновременное вращение и zoom;
  • Длительные касания — в процессе могут быть задействованы все вышеперечисленные жесты.

Также возникли проблемы с жестом поворота, центральная точка «убегала» при зуме и многократных поворотах карты из стороны в сторону.

Решение:

Нам понадобилось учитывать множество факторов и делать тонкую настройку параметров обработки касаний экрана.

  • Задержка анимации передвижения карты нужна для плавного движения при перетаскивании пальцем.
  • Настройка коэффициентов чувствительности и порогов, например, когда детектировать жест перемещения.
  • Определение центров вращения. Так как вращение делается двумя пальцами, то не ясно, как выбирать центр вращения. Например, один палец неподвижен, а вторым описывается окружность, тогда центр вращения будет под неподвижным пальцем. А при одновременном движении двумя пальцами, центр может динамически меняться в промежутке между точками касания двух пальцем.
  • Плотность пикселей (Pixel Density) и разрешения экранов. Коэффициенты чувствительности и порогов сильно зависят от параметров экрана.

Трудности со шрифтами

Проблемы реализации скелинга шрифтов, когда шрифты при рендеринге в движке не учитывали pixel ratio или pixel density, и при высоких разрешения экрана текст на карте был очень мелкий, и на него никак нельзя повлиять, увеличить.

  • Qt API неправильно выдавал коэффициент экрана в С++-коде на ОС Аврора.
  • Движок Maplibre почему-то не учитывал коэффициент экрана конкретного девайса для рендеринга шрифтов.
  • API библиотеки Maplibre из коробки не предоставляет методов управления размером шрифтов.

Мы пришли к тому, что нужно использовать файл настройки стилизации.

  • Стили в формате MapLibre GL Style JSON с возможностью динамической смены стилей.
  • Подходит для онлайн и оффлайн карт.

Решение:

  • Взять из Maplibre json-файл стиля после полной загрузки карт.
  • Поменять параметры размера шрифтов.
  • Установить новый стиль.

Что умеет собственное решение

Общая структура проекта представлена на схеме:

Project Scheme

Были созданы библиотеки MFW, которые предоставляют весь необходимый функционал для работы с картами, маршрутизацией и геокодированием.

Картографические библиотеки предназначены для интеграции карт в приложения под ОС Аврора.

Набор библиотек MFW имеет следующий состав.

  • Библиотека MfwMap обеспечивает:
    • подключение онлайн/офлайн карт к приложению и их отображение;
    • взаимодействие с картой при помощи жестов;
    • управление картой, ее стилями и слоями, добавление объектов на карту.
  • Библиотека MfwOfflineRouting обеспечивает:
    • построение маршрута по двум или нескольким точкам;
    • получение необходимой информации для ведения по маршруту;
    • обновление ранее полученного объекта маршрута.
  • Библиотека MfwOfflineGeocoding обеспечивает:
    • получение адреса по координатам;
    • получение координат по адресу;
    • получение списка автоподсказок при наборе адреса.
  • Docker-образ со скриптами генерации офлайн информации MfwExportScripts предоставляет возможности:
    • генерация данных для офлайн-карт;
    • генерация данных для построения маршрутов;
    • генерация данных для геокодирования.

Application MFW Submodules - MFW-библиотеки могут быть интегрированы в разрабатываемое приложение по средствам сабмодулей исходного кода.

Application MFW Plugins - MFW-библиотеки могут быть интегрированы в разрабатываемое приложение в качестве QML-плагинов.

Libpostal, Geocoder NLP - библиотеки для геокодинга и для работы с базами адресов.

Protobuf - механизм для сериализации данных, использующий компактный бинарный формат.

MapLibre GL Native - бесплатная библиотека с открытым исходным кодом для работы с картами в приложениях на различных платформах. Для ускорения отображения карт используется аппаратный рендеринг векторных тайлов.

OpenGL ES, Qt Scene Graph - набор инструментов и библиотек для аппаратного рендеринга.

Документация и примеры использования

Документация расположена в исходниках библиотек в формате QDoc в .cpp/.hpp-файлах.

Все репозитории содержат файлы README на русском/английском языках с информацией о том, как скачать репозиторий, как подключить компонент в составе CMake-проекта и как использовать его в своём проекте.

Собранная русскоязычная документация доступна на портале разработчиков.

В дополнение, приложение MfwMap Example включает в себя описание реализованных сценариев использования.

Картографический инструментарий включает в себя два приложения, реализующих разные варианты подключения библиотек, а также иллюстрирующих их функционал:

  • Приложение MfwMap Example осуществляет подключение библиотек в исходниках в виде сабмодулей в составе проекта. Поэтому библиотеки будут собираться вместе с основным проектом. Система сборки – Cmake. Приложение иллюстрирует функционал для большого количества сценариев использования, включая работу со слоями и стилями карты, управление картой и источниками тайлов, построение маршрутов, использование геокодинга и многое другое.
  • Приложение MapTemplate выполняет подключение библиотек в проект в виде бинарных файлов. Система сборки – qmake. Приложение иллюстрирует минимальный функционал, его основная цель – показать подключение библиотек, предварительно собранных в виде QML-плагинов.

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

Как начать использовать наше решение?

Для удобного просмотра кода, реализующего использование функционала библиотек, а также документации в коде, удобно скачать основной пример MfwMap Example по инструкции в README:

  1. Клонируем проект со всеми репозиториями:

    git clone --recurse-submodules https://hub.mos.ru/auroraos/examples-extra/MfwMap.git
    
  2. В настройках Build Engine в Аврора SDK увеличиваем оперативную память и количество ядер: Tools → Options → Aurora OS → Build Engine. Это необязательный пункт, но рекомендуем его сделать.

    Настройки

  3. Открываем проект в Аврора SDK и ждём окончания процесса конфигурирования проекта. Для просмотра реализованного в приложении функционала можно собрать проект и запустить приложение на устройстве или эмуляторе.

Для максимально быстрого старта можно скачать исходники демо-приложения MapTemplate с уже собранными библиотеками, собрать и запустить.

Примечание:

  • example – ветка с бинарными артефактами, собранными под 5 версию ОС Аврора;
  • example_4 – ветка с бинарными артефактами, собранными под 4 версию ОС Аврора.

Стоит учесть, что бинарные артефакты библиотек обновляются не так часто, как их исходники.

Интеграция в свой проект

Рассмотрим вариант подключения библиотек в виде бинарных файлов в qmake-проект более подробно на примере подключения MfwMap под 5 версию ОС Аврора под архитектуру aarch64.

  1. Скачиваем готовые собранные библиотеки из репозитория с примером MapTemplate, то есть из ветки example. Например, библиотека libMfwMap.so находится здесь. Или собираем из исходников последнюю версию из репозитория с помощью Аврора SDK.

  2. Создаём проект с подпроектами, например, ru.auroraos.MyProject. В корневом .pro-файле (ru.auroraos.MyProject) будет следующее:

    TEMPLATE = subdirs
    SUBDIRS = \
        app \    // само приложение
        mfw    // подпроект для подключения плагинов
    
  3. Кладём библиотеку, например, по пути ru.auroraos.MyProject/mfw/lib/aarch64/MfwMap/libMfwMap.so, туда же кладём файл qmldir с указанием пути до плагина на устройстве:

    module MfwMap
    plugin MfwMap ../../
    
  4. Файл mfw.pro будет выглядеть следующим образом:

    TARGET = mfw
    TEMPLATE = aux
    
    MfwLibs_install.path = \
        /usr/share/ru.auroraos.MyProject/lib
    MfwLibs_install.files = \
        $$IN_PWD/lib/aarch64/MfwMap/libMfwMap.so
    
    MfwMapPlugin_install.path = \
        /usr/share/ru.auroraos.MyProject/lib/qmlplugins/MfwMap
    MfwMap_install.files = \
        $$IN_PWD/lib/aarch64/MfwMap/qmldir
    
    INSTALLS += \
    MfwLibs_install \
    MfwMapPlugin_install
    
  5. Для установки MfwOfflineRouting помимо самой библиотеки с qmldir-файлом необходимо добавить библиотеки protobuf. Нужно скачать готовые сборки из того же примера MapTemplate. В mfw.pro добавятся следующие строки для protobuf:

    protobuf_install.path = \
        /usr/share/ru.auroraos.MyProject/lib
    protobuf_install.files = \
        $$IN_PWD/lib/aarch64/MfwOfflineRouting/libprotobuf.so.3.18.3.0 \
        $$IN_PWD/lib/aarch64/MfwOfflineRouting/libprotobuf.so
    
    INSTALLS += \
    protobuf_install
    
  6. В .spec-файл необходимо прописать добавленные зависимости в исключения:

    %define __provides_exclude_from ^%{_datadir}/%{name}/lib/.*$
    %define __requires_exclude ^(libMfwMap.*|libMfwOfflineRouting.*|libprotobuf.so*).*$
    //  пример кода с учётом плагина маршрутов и необходимого ему protobuf.
    
  7. В файле приложения app.pro подключить библиотеку:

    LIBS += -L$$IN_PWD/../mfw/lib/aarch64/MfwMap \
        -lMfwMap
    
  8. В коде основного приложения импортируем данный плагин для использования классов из него, например, в файле MfwMapPage.qml:

    import QtQuick 2.0
    import Sailfish.Silica 1.0
    import QtPositioning 5.2
    import MfwMap 1.0
    
    Page {
    
        MfwMap {
            id: map
    
            anchors {
                fill: parent
                topMargin: Theme.paddingLarge
            }
    
            center: QtPositioning.coordinate(55.752121, 37.617664) // Moscow
            zoomLevel: 12.0
            metersPerPixelTolerance: 0.1
    
            accessToken: "YourAccessToken"
            styleUrl: "mapbox://styles/mapbox/streets-v10"
        }
    }
    

Использование офлайн-данных

Генерация офлайн-данных для какого-либо региона нужна для работы офлайн карт, а также для работы маршрутов и геокодинга в этом регионе. Процесс генерации данных и использования их в приложении-примере MfwMap Example подробно описан в README репозитория MfwExportScripts.

Краткий пример приведём здесь. Использование скриптов для получения офлайн-данных:

  1. Скачать файл вида *.osm.pbf с необходимым регионом с сайта geofabrik.de, например, “Northwestern Federal District” в Российской Федерации.

  2. Воспользоваться сайтом OpenStreetMap и найти по названию желаемый город/регион, например, для Санкт-Петербурга  берём код города 4271007.

  3. Запустить скрипт run.sh из репозитория MfwExportScripts (для запуска требуется Docker):

    sh run.sh northwestern-federal-district-latest.osm.pbf 4271007 mbtiles /var/volume_with_osm_pbf
    

Результат работы скриптов

В результате генерации получаем данные для выбранного региона:

  • Файл с векторными тайлами типа mbtiles, который является базой данных. Если в команде sh run.sh использовать аргумент mvtiles, то результат будет в виде набора файлов, разложенных по директориям. в директории для работы офлайн-карт.
  • Глифы – архив со шрифтами.
  • Директории с данными для libpostal и файлами для геокодера.
  • Tar-архив с тайлами и графом маршрутизации valhalla.

Данные артефакты нужно поместить на устройство (можно в одну директорию).

Также для подключения сгенерированных данных в приложении понадобятся файлы стилей с темами и прописанными в них путями до тайлов карт. Например, светлая и тёмная темы map_light_theme.json и dark_matter.json из репозитория.

Подключение к онлайн-сервисам, имеющим схему, отличную от mapbox/http/https

Некоторые провайдеры тайлов карт работают с запросами, основанными на следующей схеме: «адрес сервиса, предоставляющего карты» + «relative url», где «relative url» – относительная часть адреса, использующая некоторую особенную схему. К примеру, сервисы карт VK работают с запросами по схеме mmr:// + относительная часть. В таких случаях в качестве адреса сервиса (host) нужно задавать свойство apiBaseUrl.

Если же для доступа сервис требует ключ API или токен, то соответствующий параметр нужно добавить в аргументы запроса в свойстве urlSuffix.

Пример подключения VK-maps:

MfwMap {

    width: parent.width
    height: parent.height - header.height
    anchors.top: header.bottom

    zoomLevel: 12.0
    metersPerPixelTolerance: 0.1

    apiKey: "some api key"
    apiBaseUrl: "https://maps.vk.com/"
    urlSuffix: "?api_key=%1".arg(apiKey)
    styleUrl: "https://maps.vk.com/api/styles/main_style.json"
}

Для доступа к сервису VK-maps нужно запросить ключ API у VK по ссылке.

Если нет ключа API, то можно использовать демо-сервис:

apiBaseUrl: "https://demo.maps.vk.com/"

Заключение

Библиотеки MFW для ОС Аврора предоставляют разработчикам продвинутый функционал:

  • Полноценный набор инструментов для работы с картами.
  • Гибкую систему интеграции в проекты различной сложности.
  • Поддержку как онлайн, так и офлайн режимов работы.
  • Возможности кастомизации и расширения функционала.

Основные преимущества новых библиотек:

  • Модульная архитектура позволяет подключать только необходимые компоненты.
  • Подробная документация и готовые примеры кода ускоряют процесс разработки.
  • Поддерживаются различные картографические сервисы и форматы данных.

Чтобы глубже погрузиться в тему, рекомендуем изучить официальную документацию и запустить примеры реализации.

Статья будет интересна и полезна разработчикам мобильных приложений под ОС Аврора и специалистам по геоинформационным системам.

Мы используем cookies для персонализации сайта и его более удобного использования. Вы можете запретить cookies в настройках браузера.

Пожалуйста ознакомьтесь с политикой использования cookies.