Обновить
2
0

Пользователь

Отправить сообщение

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

1. Вам точно не подходят готовые решения?

Вы пишете, что вам не подходят "коробочные" решения, потому что они требуют внешних подключений и не работают с "красивыми" системами координат. Однако это не так. Практически все они позволяют отрисовывать произвольные наборы векторных данных, а "basemap" можно отключить. Набор проекций у layout.Geo вполне адекватный для вашей цели, т.к. там есть разные конические проекции (об этом потом).

То же самое после подготовки данных можно сделать встроенными методами
fig = px.choropleth(regs, geojson=rgshape, locations=regs.fid, color='region', featureidkey='properties.fid')
fig.update_geos(projection_type="conic conformal",
                fitbounds='locations',
                visible=False)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()

С вашими данными что-то не так — видимо, Plotly умеет рисовать только полигоны, описанные в определённую сторону обхода. Я использовал регионы России из natural earth

У geopandas есть встроенные методы для создания интерактивных карт при помощи folium. Да и сам folium несложно использовать. Да, там будут некоторые проблемы с проекциями, но их можно обходить, если вам не нужны внешние тайлы.

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

Основная проблема здесь в том, что уже даже в вашем примере карта достаточно сильно лагает. А в моём ещё сильнее. Как только нужно будет изобразить много данных, этим совсем нельзя будет пользоваться. Не знаю, почему так тупит Plotly, но у решений, основанных на leaflet.js (folium, например) корень проблемы кроется в том, что при изображении векторных объектов, каждый из них добавляется как объект в DOM. После нескольких тысяч точек пользоваться этим становится нереально. Решение — использовать Mapbox/maplibre, у которые работают на WebGL. Однако и тут всё не особо радужно в случае с Plotly — несколько тысяч линий и он не справится даже с этим бэкендом отрисовки.

И при этом API совершенно неудобен для аналитических задач — в Plotly мне надо отдельно хранить geojson с геометрией и отдельно таблицу с атрибутами. Это может быть удобно в случае разработки дашбордов — с одного сервера получили запросом геометрию (или вообще локально её храним), с другого сервера получили данные и что-то точно нарисуем, пустой картинки не будет. Для случая быстрой отрисовки результатов вычислений создавать отдельный json с геометрией — это как-то так себе подход. В folium с этим немного попроще (хотя там наверняка geojson создаётся самой библиотекой, что тоже плохо сказывается на производительности).

Гораздо лучше (на порядки) с удобством API в экосистеме R. Но проблемы с производительностью те же, так как интерактивность реализована через leaflet.

3. Если у вас достаточно много данных, geopandas — это боль,

потому что загружает весь датасет в память сразу. Можно этого избежать, использовав обычный для таких случаев и pandas подход с написанием генераторов и отложенным чтением по чанкам. Но так получается гораздо больше кода, чем если использовать osgeo.ogr, который может весьма эффективно читать объекты с диска по одному. Плюс, тут у вас есть всякие подводные камни в том, как geopandas использует fiona и rtree, которые могут проявиться достаточно быстро при росте объёма данных.

4. Что с этим делать?

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

P.S. про проекции.

EPSG:326XX не подходят для мелкомасштабного картографирования. Это зональная проекция с зонами, вытянутыми вдоль меридианов, и нет смысла использовать её для России, которая вытянута с запада на восток. У вас искажения величин получаются сильные: Кольский полуостров сопоставим с Таймыром, хотя на самом деле он в 4 раза меньше. Если у вас ассоциации с "контурной картой" вызывает равноугольная проекция, то вам здесь лучше подойдёт коническая равноугольная проекция. Можно proj-строкой описать необходимые для России параметры. Но в б.д. кодов есть проекция, названная там "Asia North Lambert Conformal Conic" или ESRI:102027, которая вполне подходит для России.

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

Планируется ли поддержка векторных и растровых форматов данных из баз данных (как файловых SQlite/geopackage, так и клиент-серверных PostGIS, например)?

Планируется ли добавлять поддержку антиалиасинга?

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

2

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность