Как стать автором
Обновить

Комментарии 8

Ох, у меня прямо вьетнамские флэшбеки от склеивания Чукотки, страдал как-то с этим в PostGIS

Добрый день!

Да, пришлось с ней повозиться)

Ой не говори кума... Как счас помню, куча геоданных и не указано в какой системе координат ни представлены, а часть вообще в локальных. И надо свести их воедино, а потом прыгать с проекцией, а знаний в геодезии - ноль. А потом ещё аэроснимки привязать. Я тогда в QGis в связке с PostGIS просто влюбился. Да, лихие 2000-е. Пошёл лечить ПТСР. :)

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

Оффлайн карта и не лагает - я о таком давно мечтал!

Предложения по улучшению такие:

  1. Меня смущает избыточная точность координат в геоданных. Произведём несложный расчёт:

L = 40000000
print('Длина экватора: ',L, 'м')
rho = 10**-15
print('Точность геоданных (размер пикселя в градусах): ',rho, '°')
print('Тогда размер пикселя в метрах: ',rho*L/360, 'м')

Если мы хотим рисовать карту даже с точностью до метра (а здесь ведь ещё simplify поработал!), хватило бы 6 десятичных знаков после запятой.

  1. Отображаемый размер города лучше привязать к логарифму населения. А то Москва пузатая слишком :)

Добрый день!

Спасибо за отзыв и предложения (особенно первое) – использую их в дальнейшей работе над картой.

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

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, которая вполне подходит для России.

Спасибо большое за комментарии! Учту их при дальнейшей работой над проектом.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории