Объединение библиотеки maps-util с Jetpack Compose

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

Кластеризация имеет значение, если вы хотите отобразить множество точек интереса (POI) в одном регионе. Вместо того, чтобы загромождать карту тысячами точек, перекрывающих друг друга, вы можете перегруппировать их под одним элементом: кластером. Как только увеличенная область уменьшится настолько, чтобы показать их все, кластер исчезнет, ​​чтобы вместо этого показать эти точки.

Излишне говорить, что я был разочарован отсутствием поддержки. Тем не менее, библиотека едва добралась до своего первого стабильного релиза, и им пришлось расставить приоритеты. Тем более, что текущая реализация кластера скрывается в библиотеке maps-util, которая не вписывается в парадигму Compose.

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

Объединение библиотеки Maps Util

Судя по тому, что мы видели, у команды оставалось два варианта сделать кластеризацию совместимой:

  • принести свое внутреннее решение, которое лучше подходит для Compose.
  • bridge с библиотекой maps-util.

Хотя первый вариант превосходит второй (по соображениям производительности и интеграции), это влечет за собой значительную доработку, чтобы обеспечить его полную поддержку. И в результате отложили бы его выпуск на неизвестную дату.

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

Соединение библиотеки maps-util означает предоставление экземпляра GoogleMap из библиотеки Compose, которая до сих пор была внутренней. Мы внедрим этот экземпляр в ClusterManager (из библиотеки maps-util), который позаботится обо всем остальном за нас. Для получения дополнительной информации вы можете прочитать этот открытый вопрос с подробным описанием запроса функции.

Учтите, что этот экземпляр не относится к GoogleMap Composable из этой библиотеки карт, даже если они носят одно и то же имя!

Они создали экспериментальный MapEffect Composable, который предоставляет экземпляр GoogleMap в качестве параметра. Используйте его для создания одного экземпляра ClusterManager (используя remember).

Поскольку он действует как аварийный люк, он имеет некоторые ограничения. Во-первых, Marker Composable позволяет настроить его внешний вид за счет прерывания события клика. Во-вторых, даже если бы вы могли настроить свои маркеры, это не относится к вашим кластерам. Таким образом, вы получите макет по умолчанию (цветной кружок с размером кластера, написанным в его центре).

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

Для вдохновения Google предоставляет этот пример для настройки ваших кластеров. Мы возьмем его оттуда и создадим наши маркеры.

Разработка наших маркеров

Если вы изучили код, вы увидите, что карта отображает маркеры в виде растровых изображений. Посмотрим правде в глаза, это наша самая большая проблема. Нам нужно сгенерировать растровые изображения, которые еще не видны на экране. Следовательно, мы не можем использовать Composable, который каким-то образом превратился бы в Bitmap. Возможно, вы захотите посмотреть на некоторые обходные пути, но я бы не советовал этого делать.

К сожалению, нам нужно оставить Composable для файла View. Это может быть изображение или пользовательская фигура, которую вы нарисуете, например, внутри Canvas. После того, как вы создали свой View, вы можете превратить его в Bitmap, используя этот метод расширения:

Затем мы применим этот метод внутри средства визуализации кластера:

В данном случае я создал два пользовательских представления: MarkerView и ClusterView. Вы можете повторно использовать один и тот же класс для маркеров и кластеров, если хотите. Средство визуализации нуждается только в его экземпляре, затем вы будете создавать уникальные растровые изображения из этой базы при вызове обратных вызовов кластеризации.

Вы можете получить некоторые сложные формы, рисуя на холсте. Вот тот же пример, что и выше, с пользовательскими маркерами и кластерами:

И маркер, и кластер имеют одну и ту же базу, но их размер, цвета и некоторые вводимые тексты меняются в зависимости от информации ClusterItem. Кластер отличается тем, что показывает свой размер внутри формы капли. Довольно круто, нет?

Что дальше?

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

Но это еще не все: к моменту написания этой статьи команда активно разрабатывает свое внутреннее решение для кластеризации. Мало того, что мы можем ожидать более подходящей интеграции (исключительно в Compose), а также более высокой производительности — устаревшая кластеризация через maps-util страдает от технических решений.

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