Движок карты для android

Весь мир в кармане или как сделать мобильную карту за пару дней

В прошлой статье я рассказывал о том, как можно быстро сделать Web-звонилку. А что если поставить более амбициозную задачу — собрать своё собственное приложение с картой, без рекламы и с блэк-джеком? А если всего за пару дней?

Давайте сделаем это! Прошу под кат.

Для начала разберёмся, что нам предстоит сделать. На выходе мы хотим получить приложение со справочными данными и картой. И чтоб работало офлайн. Как разработчика меня в первую очередь интересует как раз карта, ведь показывать справочные данные мы и так умеем. А офлайн — довольно сильное ограничение в этом случае, ведь хороших библиотек с поддержкой офлайна не так много. Поэтому в статье сконцентрируемся на карте, а про справочник поговорим вскользь.

Выбираем движок карты

Первое, что нужно сделать — добыть данные для приложения. На рынке много источников, бесплатных и не очень. Для старта нам вполне подойдёт OpenStreetMap как открытый источник картографических данных. Там же можно взять и какое-то количество POI для нашего справочника.

Следующий шаг — выбираем картодвижок. На просторах интернета их довольно мало, бесплатных ещё меньше, а с поддержкой офлайна вообще единицы. Предлагаю воспользоваться довольно крутым вариантом — mapsforge/vtm. Это векторный OpenGL движок, очень шустрый, поддерживает офлайн, Android, iOS, различные источники данных, кастомную стилизацию, оверлеи, маркеры, 3D и даже 3D-модели объектов! Очень, очень круто.

В репозитории достаточно много примеров для быстрого старта, есть готовые карты, есть плагин, позволяющий собрать собственную карту из данных в OSM формате. Итак, приступаем!

Создаём источник данных MapFileTileSource, указываем местонахождение файла карты. Дополнительно позиционируемся в центр интересующего нас баундинг-бокса, чтоб не оказаться где-то за пределами выбранной локации при старте приложения. Устанавливаем дефолтную тему. Добавляем слой домов и слой подписей. На этом всё. Запускаем — чудеса!

Кажется, быстрее и проще и быть не может.

Делаем геокодинг

Следующий важный шаг — реализация геокодинга. Сама по себе карта — это уже неплохо, но нужна интерактивность. Мы хотим тапать в карту и видеть информацию по объекту, в который попали. И здесь есть некоторая сложность. По большому счёту, полноценный геокодинг в нашей библиотеке отсутствует. Это, пожалуй, самый большой её минус. Если ничего не изобретать, то мы можем воспользоваться имеющейся функциональностью.

Получилось относительно многословно. Нужно найти тайл, получить ways (в терминологии OSM way — это линейный объект), и можно из них извлечь какую-то атрибутику. Помимо ways есть возможность получить ещё и POI, но на этом всё. Остальную логику придется накручивать самостоятельно: выбирать «правильный» из всего множества объектов, в которые попал клик, фильтровать по зум-левелам. И ещё один момент. Фактически, мы теряем информацию об исходной геометрии и получаем в ответ на поиск просто набор линий. Если захочется сделать ещё и гео-редактор, то этого явно будет недостаточно.

Но для демонстрации подхода нас всё устраивает.

«Продвинутый» геокодинг

Вообще говоря, есть более продвинутый вариант. Для этого нам понадобится своя база. В частности, можно воспользоваться SQLite. Правда, нам недостаточно будет стандартного SQLite, и придётся собирать свой, подключив к нему плагин RTree для геопоиска. Как это сделать, я уже рассказывал в статье, раздел «Делаем хороший поиск».
В этом случае мы получаем полный контроль над данными, можем сохранять всё, что требуется, и в нужном формате. Еще и Full Text Search сможем прикрутить и искать наши геообъекты и фирмы по названию, адресу и другим атрибутам.

  1. Делаем таблицы:
    • геообъектов (id, type, geometry, attributes)
    • фирм (id, attributes, geo_id) со ссылкой на геометрию здания, в котором она находится
    • геоиндекса на rtree вот так:
  2. Наполняем всё данными.
  3. При тапе в карту получаем GeoPoint и выполняем запрос:
  4. Последний шаг: фильтруем и выбираем подходящий объект.
Читайте также:  Вспышка при сообщении андроид

Один из вариантов реализации можно посмотреть в репозитории.

В итоге мы уже умеем показывать карту и обрабатывать нажатия. Неплохо.

Добавляем важные мелочи

Давайте добавим пару важных функций.

Начнём с текущей геопозиции. В mapsforge/vtm для этого как раз имеется спец. слой LocationLayer. Использование крайне простое.

Есть только один недостаток — это постоянная пульсация «синей точки» на границе экрана, когда текущая локация находится за пределами карты. Скорее всего, в процессе использования вы редко будете оказываться в такой ситуации, но это вызывает постоянный перерендеринг, соответственно, немного нагружает процессор. Избавиться от этого немного сложнее, нужно залезть в шейдер и поправить его. Но это уже совсем для перфекционистов. Как сделать — можно посмотреть тут.

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

Ещё нам понадобятся кнопки зума.

И вишенка на торте — компас.

Захватываем мир

Друзья, мы на финишной прямой. Осталось добавить последний штрих. Мы ведь планируем захват мира, а это значит, что его нужно как-то запихать в наше приложение.

И дела обстоят так, что с нашим движком это намного проще, чем кажется.
Нам нужно немного модифицировать метод загрузки карты, добавив в него MultyMapTileSource. Это по сути враппер для любых других источников тайлов, который позволяет отображать на карте сразу всё, что в него добавлено. Просто киллер-фича. В итоге нам остаётся подготовить карту мира с минимальной детализацией, добавить её самой первой в наш враппер, а поверх рисовать всё остальное. Более того, мы можем сразу добавить все карты, какие у нас есть в каталоге с картами приложения! Шикарно, просто шикарно. И не забываем, что это офлайн 🙂

Пожалуй, мы готовы к релизу. Собираем билд, выкладываем в маркет и получаем заслуженные звёзды 🙂

Пара ложек дёгтя в огромной бочке мёда

Движок open source, развивается активно, но команда у него, прямо скажем, довольно скромная. По большому счёту это один человек под ником devemux86. И ещё пара ребят контрибьютят время от времени.

Порой встречаются артефакты в отрисовке, какие-то моргания и подёргивания. Но я ни разу не столкнулся с какими-то критическими проблемами и тем более падениями, что не может не радовать.

Есть еще один нюанс, который может не понравиться. Это отрисовка скруглений и окружностей. Пример того, как это выглядит, на скриншоте:

Если в исходной геометрии достаточно много точек (скругление гладенькая), то на карте вы можете увидеть довольно-таки «угловатую» окружность с множеством небольших выпуклостей и вогнутостей. Очевидно, это делается в угоду производительности и размеру map-файла, но выглядит не очень.

Пожалуй, это все минусы на сегодня. Вам решать, сможете вы с ними жить или нет. А мы тем временем используем эту библиотеку уже более 1,5 лет, полёт отличный, по крайней мере, на Андроиде.

Итоги

В этой статье я показал, что даже такую довольно нетривиальную задачу можно решить относительно быстро. Вы получили готовый скелет, с которым можно запрототипировать любой проект, подразумевающий использование офлайн-карты, за минимальное время.

Если возникнет интерес, в следующей статье покажу, как сделать этажи а-ля 2ГИС. И это на самом деле гораздо проще, чем кажется 🙂

Источник

Интеграция карт в ваше Android-приложение

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

В данном статье я расскажу как интегрировать возможность просмотра карт для мобильных устройств на основе Android, на примере Yandex Карт и Google Maps.
Функционал библиотек этих компаний позволяет:

  • Перемещать карту
  • Изменять масштаб
  • Изменять виды карт
  • Получать события от карты

Начнём с отечественного производителя.

Yandex

Библиотеку Yandex MapKit можно скачать с GitHub’а, там же есть версия и для iOS.
Но прежде чем начать использовать, нам надо получить API-key, для этого идём на почту и пишем письмо в support@mobmaps.yandex.ru, указав в заголовке «Map Kit запрос API-ключа». В ответ вам пришлют письмо с указанием дополнительных ссылок на документацию, на правила использования и собственно с самим ключом в теле письма (а могут и не прислать, кстати).

Читайте также:  Прошить андроид с компьютера через flashtool

Пока ждём письмо, берём библиотеку и прикрепляем её к проекту.

После долгого ожидания с кружкой кофе, знакомимся с содержимым письма и информации по ссылкам, берём ключик и пишем в вашем layout’е приложения следующий код:

где заместо «you are key» вставляем полученный ключ. Всё, карта есть.

Далее код показывает, как перемещать карту на заданную координату и использовать зум:

Google

Для использования Google Maps надо совершить куда более изощрённые действия. Я расскажу, как получить debug-key для использования карт, но процесс получения release версии похоже несколько замороченней, но я release ещё не получал.

Для получения debug-key, надо найти ваше хранилище ключей, для отладки.
По-умолчанию, путь будет выглядеть примерно так:

Затем открываем командную строку, переходим в каталог, куда установлена Java:

где путь_до_хранилища_ключей — свой путь до debug.keystore (осторожно, возможны проблемы с пробелами в пути).

После чего в том же окне будет выведен md5-ключ после «Certificate fingerprint (MD5)».
Идём по ссылке и регистрируем код.
После чего Google сгенерирует с нужным кодом для layout и встроенным кодом, берём его и вставляем к себе в layout.
Далее нам, надо наш Activity представить в примерно следующем виде:

Замечу, что Activity наследован должен быть от MapActivity хранящийся в com.google.android.maps.MapActivity.
А в манифесте прописать между тегами вставить:

И не забыть, про разрешение доступа в интернет для приложения:

В остальном функционал GoogleMaps и YandexMapKit весьма схож:

Как можно видеть, процесс интеграции карт в приложения довольно простой, а спектр использования довольно широк.
Более подробно можно ознакомиться ниже.

Определение собственной позиции

Чтобы немного расширить пример, приложу кусок кода:

Но для использования этого кода, в манифесте следует указать следующее разрешение:

Источник

Приложения для создания Карт на Андроид

Подборка приложений, с помощью которых можно создавать и редактировать карты на смартфонах под управлением Android. Одной из лучших утилит с подобными возможностями является Map Draw. Программа позволяет не только пользоваться картами на мобильном устройстве, но и оставлять важные пометки. Благодаря этому проще запомнить расположение определенных мест или составить маршрут. В приложении можно открыть стандартную, спутниковую и гибридную карту, а затем найти на ней любой адрес по названию. Есть возможность нанести отметки, добавить надпись и сохранить изменения в виде JPG изображения.

По схожему принципу работает утилита MapTiler. С ее помощью можно рисовать на карте линии, ставить пометки, планировать маршрут и многое другое. Программа способна определить текущее местоположение по GPS. В ней можно создавать заметки с текстом и фотографиями, которые связаны с определенным адресом на карте. Приложение предоставляет доступ к облачному хранилищу MapTiler Cloud, куда сохраняются внесенные изменения. Программа позволяет загружать карты в PDF формате, аэрофотоснимки беспилотников, планы города и так далее.

Аналогичный функционал имеет популярный мобильный сервис 2ГИС. В нем предусмотрен встроенный конструктор карт, с помощью которого можно добавлять собственную разметку. Есть возможность составлять маршруты, выделять области и отмечать важные места. Утилита позволяет рисовать на карте различные фигуры и объекты.

Существуют и другие утилиты, в которых можно создавать собственные маршруты и отмечать позиции. Например, приложение Яндекс Карты дает возможность наносить схемы проезды и сохранять в высоком качестве для печати. Некоторые программы позволяют поделиться заметками с друзьями и показать правильный маршрут.

Источник

Google MAPs API в android или как работать с картами быстрее

Принцип работы Google MAPs API

Вся документация для работы с картами приведена на (логично) официальном сайте google maps api. Сегодня я рассматриваю только Directions API (документация). Для того что бы получить какую-либо информацию от большого числа, вам необходимо сделать запрос. Ответ прийдет в формате JSON.

Читайте также:  Плагины для андроид студио

Общий вид запроса:

Пример: https://maps.googleapis.com/maps/api/directions/json?origin=55.754724,%2037.621380&destination=55.728466,%2037.604155&key=»Your MAPs API key»

В качестве ответа нам (ожидаемо) пришел JSON с большим набором разных точек с координатами и названиями этих мест.

А как вообще работать с этой страшной штукой?

Если вы только начинаете работать с Android, то советую вам почитать про такую замечательную библиотеку Retrofit, которая превращает работу с запросами в код из 2 строк. Рассматривать сейчас я её не буду.

Но я сегодня хочу рассмотреть пример использования библиотеки Java Client for Google Maps Services. Библиотека как по мне замечательная, освобождает от необходимости писать (пусть даже очень короткие) запросы вручную и отлично подходит в случаях когда нужно писать очень быстро, как например на хакатоне. Я хочу показать живой пример использования данной библиотеки на примере работы с Directions API.

Подключение библиотеки

Для начала нам потребуется получить ключ для нашего приложения. Топаем на оф. сайт, находим сверху кнопку «получить ключ», создаем новый проект, нажимаем далее и готово!
UPD: теперь бесплатно получить нельзя. С лета 2018 года Google обновили план и необходимо ввести данные своей карты для получения 200$ для запросов каждый месяц бесплатно. Этого должно хватать, но конечно тенденция не радует.

Firebase
Для правильной работы приложения нам необходимо получить файл google-service.json. Идем на firebase выбираем наш проект и добавляем его. Далее нам нужно выбрать Android проект, ввести название пакета, регистрируем приложение. Скачиваем файл и перетаскиваем в папку app. К слову её не будет видно в дереве проекта, для этого надо в Android Studio поменять отображение с Android на Project или залезть в наш проект через файловый менеджер. Далее следуем инструкциям где какой код писать.

Включаем в консоли
Так же нам необходимо включить Directions API (или любую другую необходимую вам API) в консоли, для этого идем сюда, выбираем наше приложение и включаем Directions API.

Gradle
В Gradle файлы так же необходимо добавить еще пару строк. В итоге новые строки выглядят вот так:

Обязательно проверяйте, актуальная ли это сейчас версия!

Встраиваем карту в приложение

Google map в андроид реализовывается как фрагмент (или как MapView, но об этом в другой раз, нам сейчас особой разницы нет). Просто встраиваем его в наш layout. В нашем классе, который работает с картой, необходимо найти эту карту и заимплементить интерфейс.

Код для фрагмента выглядит вот так. Я буду работать с MainActivity, соответственно если вы используете другой класс вам необходимо поменять контекст.

Отлично, фрагмент встроили, Android Studio на нас не ругается, едем дальше. Переходим в MainActivity.class и имплементим интерфейс OnMapReadyCallback.

В onCreate пишем

Так же идем в Manifests и прописываем вот такие штуки внутри тэга application

Где вместо @string/google_maps_key должен подставиться ваш ключ для карт, который мы получили ранее. Соответственно вам нужно создать нужный ресурс в файле string.

Пишем всякие интересности

Отлично, карта у нас есть, давайте наконец напишем хоть что-нибудь интересное. Пусть нашей целью будет нарисовать маршрут по Москве через несколько точек:

  • Гум (55.754724, 37.621380)
  • Большой театр (55.760133, 37.618697)
  • Патриаршие пруды (55.764753, 37.591313)
  • Парк культуры (55.728466, 37.604155)

Кладу все наши места в List и делаю это как глобальную переменную.

Для начала создадим по маркеру на каждое место. Маркер это просто объект, которому передаются координаты, а затем они накладываются на карту. Код:

Далее мы пишем вот такой код все в том же методе onMapReady

При запуске приложения мы получили вот такую картину:

Хм, Москва, конечно, весьма запутанная, но не настолько же. Почему же такой странный маршрут нам вернул Google? Потому что он построил маршрут для автомобилей, который идет по умолчанию, но мы можем это изменить. Чтобы построить маршрут для пешеходов, меняем код на:

Теперь наш маршрут выглядит вот так

Существует еще множество настроек, о всех них можно прочитать в документации. Просто мы все параметры будем добавлять не в сырой запрос, а в код, поскольку методы библиотеки имеют те же названия что и просто в запросах.

Источник

Оцените статью