Оживите свой следующий отпуск!

Я обожаю безвкусные туристические карты. Вы знаете, о чем я говорю: эти красочные мультяшные карты с трехмерными изображениями замков, памятников и Лондонского глаза. Было бы здорово сделать индивидуальную версию для собственного отпуска? Что ж, держитесь за свой паспорт, потому что, если вы знаете Python, мы как раз этим и займемся!

В этом проекте Quick Success Data Science мы будем использовать библиотеку Folium для создания индивидуальной туристической карты для моего отпуска в Исландии. Мы будем использовать пользовательские значки для вулканов и водопадов, накладывать карты местности и дорог, а также отмечать места проживания. Не волнуйтесь, если вы никогда не поедете в Исландию, потому что вы можете использовать этот проект в качестве шаблона для своих собственных поездок.

Ключевые темы программирования

Этот проект — это не только развлечения и игры. Вы также изучите несколько полезных геопространственных методов, таких как:

  1. Как сложить фрагменты базовой карты в Folium для отображения нескольких типов объектов на одной карте.
  2. Как использовать собственные маркеры для объектов на карте.
  3. Как добавить статический текст на карту Folium и изменить ее размер и цвет (это не так просто, как вы думаете).
  4. Как добавить индексную карту.

Фолиум

Библиотека Folium с открытым исходным кодом позволяет визуализировать карты с помощью Leaflet.JS, мощной библиотеки JavaScript для создания интерактивных картографических веб-приложений на мобильных и настольных платформах. Впервые выпущенный в 2013 году, Folium чрезвычайно популярен, и в Интернете вы найдете множество материалов, которые помогут вам узнать, как его использовать и настроить в соответствии с вашими потребностями.

С помощью Folium вы можете выбирать наборы плиток из картографических сервисов, таких как OpenStreetMap, Mapbox и Stamen. Эти наборы фрагментов представляют собой наборы растровых или векторных данных, разбитых на однородную сетку квадратных фрагментов с 22 предустановленными уровнями масштабирования. Они позволяют создавать красивые карты-листовки без особых усилий.

Чтобы установить Folium в среде conda, используйте следующую команду:

conda install -c conda-forge folium

Чтобы установить Folium с помощью pip:

pip install folium

Для удобства мы также будем использовать библиотеку pandas с открытым исходным кодом. Вы можете установить его с помощью следующих команд:

conda install pandas

or

pip install pandas

Код

Следующий код был введен в Jupyter Notebook и описан по ячейке.

Импорт библиотек

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

Мы будем использовать модуль Folium plugins для создания индексной карты, которая помещает отображаемую область в более широкий контекст. Модуль DivIcon позволит нам использовать пользовательские значки для таких объектов, как водопады и вулканы.

import pandas as pd
import folium
from folium import plugins
from folium.features import DivIcon

Загрузка базы данных вулканов

Исландию легко можно было бы назвать «Вулканической страной», потому что в ней насчитывается около 130 вулканических гор, из которых более 30 классифицируются как «активные». Я собрал файл CSV некоторых из них с их именами и координатами и сохранил его как Gist. Для удобства мы импортируем этот файл как DataFrame pandas.

volcano_df = pd.read_csv('https://bit.ly/458vXfu')
volcano_df.head(3)

Размещение

Во время длительного отпуска легко потерять счет времени, поэтому мы будем записывать местонахождение каждой ночи как «День 1», «День 2» и т. д. (вы можете легко использовать фактическую дату или что-то еще). Чтобы создать базу данных для построения графиков, я выполнил онлайн-поиск широты и долготы каждого города и ввел ее как словарь Python.

accommodations = {'Days 1-3': (64.128288, -21.827774),
                  'Day 4':    (65.688492, -18.126169),
                  'Day 5':    (65.6000, -17.0000),
                  'Day 6':    (65.28333, -14.40139),
                  'Day 7':    (64.656888, -14.290051),
                  'Day 8':    (63.7833302, -18.0666664),
                  'Day 9':    (63.5445, -19.8),
                  'Day 10':   (64.258149, -20.514890),
                  'Day 11':   (64.80806, -22.80500)}

Водопады

Исландию также можно назвать «Страной водопадов», поскольку в ней насчитывается более 10 000 водопадов. К счастью, я планирую посетить только шесть, поэтому мы введем их как словарь Python, как мы сделали это для размещения.

waterfalls = {'Kolugjufur':     (65.3335, -20.5645),
              'Hengifoss':      (65.1, -14.9),
              'Svartifoss':     (64.023, -16.975),
              'Skogafoss':      (63.5245, -19.5083),
              'Seljalandsfoss': (63.6095, -19.989),
              'Gullfoss':       (64.3223, -20.1193)}

Пользовательские значки

Значки — это визуальные представления объектов на карте. Знакомый пример — перевернутая капля, используемая для обозначения местоположения на Картах Google. Для этого проекта мы будем использовать пользовательские иконки для вулканов и водопадов. Для размещения мы будем использовать стандартный круговой маркер Folium.

Для представления водопадов я использовал бесплатный значок водопада, поставляемый с моей подпиской на Microsoft 365. Для вулканов я использовал значок из ICONFINDER. Я заплатил за эту иконку, чтобы она была лицензирована для коммерческого использования без указания авторства.

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

Folium поддерживает несколько типов файлов, таких как PNG и JPG, и позволяет масштабировать изображения значков, поэтому вам не нужно беспокоиться о размере значка. Сохраните значки в той же папке, что и ваш блокнот или скрипт Python.

Составление карты

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

# Create basemap and overlay tiles:
center_location = [64.9, -18.6]
map = folium.Map(location=center_location, 
                 tiles='Stamen Terrain', 
                 control_scale=True,
                 zoom_start=7)
folium.raster_layers.TileLayer(tiles='Stamen Toner', opacity=0.3).add_to(map)

# Loop through volcano DataFrame and post volcano names and symbols:
for index, row in volcano_df.iterrows():
    volcano_icon = folium.features.CustomIcon('volcano_icon.png', 
                                              icon_size=(20, 20))
    
    folium.Marker(location=(row['Latitude'], row['Longitude']),
                  icon=volcano_icon).add_to(map)
    
    folium.map.Marker((row['Latitude'], row['Longitude']),
                      icon=DivIcon(
                          icon_size=(25, 25),
                          icon_anchor=(-5, 14),
                          html=f'<div style="font-size: 8pt">%s</div>' % str(
                               row['Volcano Name']))).add_to(map)
    
# Loop through waterfalls dictionary and post waterfall names and symbols:  
for key, value in waterfalls.items():
    waterfall_icon = folium.features.CustomIcon('waterfall_icon_dark_blue.jpg', 
                                                icon_size=(25, 25))
    
    folium.Marker(location=value,
                  fill_opacity=0.5,
                  icon=waterfall_icon).add_to(map)
    
    folium.map.Marker(location=value,
                      icon=DivIcon(
                          icon_size=(23, 23),
                          icon_anchor=(-10, 14),
                          html=f'<div style="color: blue">%s</div>' % str(key))
                     ).add_to(map)

# Loop through accommodations dictionary and post names and symbols:  
for key, value in accommodations.items():          
    folium.CircleMarker(location=value,
                        radius=8,    
                        color='red',
                        fill_color ='red',
                        fill_opacity=0.5).add_to(map)
    
    folium.map.Marker(location=value,
                      icon=DivIcon(
                          icon_size=(45, 30),
                          icon_anchor=(15, 9),
                          html=f'<div style="font-size: 8pt">%s</div>' % str(key)
                      )
                     ).add_to(map)

# Add index map:
mini_map = folium.plugins.MiniMap(toggle_display=True)
map.add_child(mini_map)

map  

Первый шаг — присвоить координаты широты и долготы центральной точки карты переменной с именем center_location. Затем мы вызываем класс Folium Map и передаем ему местоположение, плитку для использования и начальный уровень масштабирования. Параметр control_scale активирует масштабную линейку карты.

Хотя тайл Stamen Terrain включает в себя дороги, они тусклые и плохо видны, поэтому мы накладываем на тайл местности более темный тайл Stamen Toner. Установив непрозрачность плитки тона на низкое значение, например 0,3, плитка местности будет скрыта только частично.

Чтобы увидеть дополнительные тайлы карты, доступные в Folium, загляните в этот блог.

Затем мы проходим через DataFrame вулканов и публикуем его содержимое. Метод folium.features.CustomIcon() позволяет нам использовать наш собственный значок вулкана и контролировать его размер. Класс folium.Marker() размещает на карте значок каждого вулкана.

Вот сложная часть. Folium разработан для динамических, интерактивных веб-карт, поэтому делать что-то такое, казалось бы, простое, как публикация статического текста, немного неудобно. Мы должны использовать аргумент html и передать его f'<div style="font-size: 8pt">%s</div>' % str(row['Volcano Name']). Мы используем этот формат html не только для размещения имени, но и для управления размером его шрифта. Обратите внимание, как текст должен быть преобразован в строку, прежде чем его можно будет вывести на график.

Нанесение водопада и мест размещения осуществляется по одному и тому же основному формату. Разница в том, что мы используем аргумент html, чтобы изменить цвет текста для водопадов на синий.

Мы заканчиваем добавлением индексной карты (mini_map). Эта карта будет динамически изменять свое положение при увеличении и уменьшении масштаба.

Вот финальная карта:

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

Печать карты

Как упоминалось ранее, карты Folium предназначены для использования онлайн. Хотя их можно сохранить как изображение программно, проще просто сделать снимок экрана. Затем вы можете вставить результат в программу, такую ​​​​как Microsoft PowerPoint или Publisher, для дополнительных украшений перед печатью.

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

Краткое содержание

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

Спасибо!

Благодарим за чтение и, пожалуйста, подпишитесь на меня для новых проектов Quick Success Data Science в будущем.