Pull to refresh

Comments 18

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

Рассматривали, но у большинства альтернатив есть проблемы с детализацией в регионах, особенно если город не является областным центром. Тоесть в Москве, Казани, Екатеринбурге все хорошо, а например в Калачинске в Омской области уже могут отсутствовать многие дома, дороги или пятиэтажки отмечены как частные дома.
Яндекс.Карты в плане детализации в нашей стране все-таки впереди всех. Поэтому пытались "притереться" именно к ним

А яндекс не умеет возвращать тайлы? Их можно было бы вставлять в довольно низкоуровневый OSMDroid

К тому же на этих тайлах можно было бы сразу и точки рисовать

Да, на тайлы смотрели.
"В качестве альтернативы мы также рассматривали решение с использованием тайлов. Это отдельный слой карты, состоящий из заранее подготовленных растровых картинок, на которых можно рисовать всё что угодно. Для нас это решение не подошло, так как пришлось бы отдельно генерировать изображения для пересечений каждого из 40+ фильтров друг с другом."
Поэтому на бэкенде их готовить не очень удобно.

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

В целом я думаю эти проблемы можно побороть если сильно постараться.

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

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

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

В принципе генерация тайлов на сервере оказалась вполне рабочим решением. Да, такие тайлы не получится эффективно кешировать, так как слишком много вариантов фильтров, но мы их просто без кеширования на лету генерировали, и получалось быстро. Правда, при условии быстрого доступа к объектам. У нас они лежали в памяти сервера в квадродереве, без БД. На генплан города-миллионника в принципе нам хватало памяти обычного недорогого сервера.

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

Не знаю, сколько у вас там объявлений, но вряд ли больше чем кадастровых участков в городе.

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

Координаты меркатора можно 1 раз посчитать для каждого дома и сохранить в эластик.

А в вебе оно также устроено, рисуется на канвасе в отдельном потоке?

Тут на самом деле очень много способов как сделать лучше)

На вебе у нас, насколько мне известно, используется кластеризация, а не "одно объявление - одна точка".

Очень понравилось изложение, спасибо большое, по сути - самодельный event loop. А что думаете о переносе большей части логики в NDK?

О переносе в NDK думали вскользь. У нас в приложении кроме этих расчетов особо и нечего выносить в NDK, а ради сотни строк перенастраивать сборку, CI парится с объяснениями работы JNI и С++ тоже не очень хочется. Нам проще эти расчеты тогда на бэкенд утащить

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

Не до конца понял про "параллельно рисовать в шаренную память". Тут проблема не только и не столько в рисовании, а в том как потом добавить это на карту.
Пробовали например вместо 4 объектов с большими Bitmap добавлять на карту 16-32-64 объекта на карту с Bitmap меньшего размера. Но по производительности получалось хуже.

А почему координаты точек не передавать в виде бинарного блоба и рендеринг тайлов не вынести в мобилу? Выглядит что для мобилы это должна быть типовая задача

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

А по поводу рендеринга тайлов на мобиле - мы пробовали и визуально нам это меньше понравилось, поэтому развивали наш текущий подход
Вот пример из экспериментов тайлами
https://youtu.be/39_qCY_ij9Y

Почему-то прочитав заголовок, подумал что речь пойдет об OpenGL.

Не знаю позволяет ли yandex api создавать пользовательские слои, но если бы я думал о решении данной задачи, то в первую очередь смотрел бы в сторону собственного слоя с OpenGL контекстом.

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

Если же использовать современный OpenGL ES c  (AEP)  и поддержкой геометрических шейдеров, то для каждой метки достаточно добавить в буфер одну вершину, причем без проекции, а проекцию координат и создание прямоугольника доверить геометрическому шейдеру.

У Яндекс.Карты есть возможность добавлять свои слои, но там весьма ограниченный набор функций и к сожалению возможности работать с OpenGL напрямую там нет.
https://yandex.ru/dev/maps/mapkit/doc/android-ref/full/com/yandex/mapkit/layers/package-summary.html
В целом бы конечно свой слой с OpenGL по сути решил бы многие проблемы)

Просто мысль. Может тогда в самом приложении можно повесить прозрачный слой с OpenGL над вьюшкой с картами? Нижний идёт к Яндексу, верхний на ваш rest к базе. Андроид толком не знаю, но представляется маловероятным, что это невозможно.

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

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

Sign up to leave a comment.