см. файл map2.py
Содержание:
- 1. Создание карты
- 2. Добавление точек на карту
- 3. Берем координаты вулканов из базы
- 4. Всплывающие окна
- 5. HTML и Google ссылки для окон
- 6. Стилизация точек
- 7. Добавление нового слоя на карту
- 8. lambda функция: зависимость цвета от населения
- 9. Добавление панели переключения слоев
- Скриншоты
Приложение на языке Python. Использованные библиотеки: Pandas, Folium.
В приложении 3 слоя: 1-й слой - basemap - очертания стран и континентов, 2-й слой - polygon layer - население стран показано цветом, 3-й слой - point layer с точками на карте, указывающими местоположение вулканов. Слои можно включать или выключать при помощи панели.
Всплывающие окна с названиями вулканов, высотой и кликабельными ссылками в Google.
Вулканы отмечены разными цветами (зеленый, желтый и красный) в зависимости от высоты.
- Импортируем Folium и создаем объект map класса Map с тремя параметрами.
map = folium.Map(location=[38.58, -99.09], zoom_start=5, tiles="Stamen Terrain")
** location (широта, долгота) - выбираем где будет открыта карта.
** zoom_start - выбираем стартовое приближение.
** tiles - внешний вид 1-го слоя.
- Сохраняем карту в формате HTML.
map.save("Map_html_popup_advanced.html")
- Создадем FeatureGroup.
fgv = folium.FeatureGroup(name="Volcanoes")
** FeatureGroup позволяет добавить множество features, таких как: Marker, CircleMarker, GeoJson layer, итд.
** FeatureGroup это контейнер для объектов. Все объекты на карте будут помещены в FeatureGroup, так их проще показать или скрыть все разом.
-
Метод add_child для добавления объекта (точек) к существующему объекту (map).
-
Используем объект CircleMarker с аргументами (положение, цвет, прозрачность, и т.д.) библиотеки Folium для создания точек на карте.
-
CircleMarker позволяет создавать всплывающие окна при нажатии на точку на карте.
-
Далее
map.add_child(fgv)
- Импортируем библиотеку Pandas.
data = pandas.read_csv("Volcanoes.txt")
-
Используем цикл for для перебора структуры данных (dataframe).
-
Для этого создаем 2 списка: lat & lon (работа со списком проще и быстрее, чем с dataframe series).
data = pandas.read_csv("Volcanoes.txt")
lat = list(data["LAT"])
lon = list(data["LON"])
- Проходим циклом for, каждый раз получая широту и долготу для каждого из вулканов.
for lt, ln in zip(lat, lon):
** Функция zip используется для итерации 2 списков за раз.
-
Создаем 2 дополнительных списка elev & name - высота и названия вулканов.
-
Перебираем все 4 списка.
for lt, ln, el, name in zip(lat, lon, elev, name):
- Разместим ссылки во всплывающем окне. Код ниже создает всплывающие окна с названием вулкана в качестве Google ссылки.
html = """
Volcano name:<br>
<a href="https://www.google.com/search?q=%%22%s%%22" target="_blank">%s</a><br>
Height: %s m
"""
** Символы %s являются заполнителями, в которые будут вставлены переменные класса str.
** В примере ниже, str. переменные name и el вставляются в переменную html:
iframe = folium.IFrame(html=html % (name, name, el)
- Так выглядит теперь цикл for:
for lt, ln, el, name in zip(lat, lon, elev, name):
iframe = folium.IFrame(html=html % (name, name, el), width=200, height=100)
fg.add_child(folium.Marker(location=[lt, ln], popup=folium.Popup(iframe), icon = folium.Icon(color = "green")))
-
Так как в библиотеке Folium отсутствует функционал для создания динамических маркеров, мы используем встроенный функционал Pyhton.
-
Создадим функцию которая будет возвращать разные цвета в зависимости от высоты.
def color_producer(elevation):
if elevation < 1000:
return 'green'
elif 1000 <= elevation < 3000:
return 'orange'
else:
return 'red'
- Теперь добавим функцию color_producer в цикл for.
for lt, ln, el in zip(lat, lon, elev):
iframe = folium.IFrame(html=html % str(el), width=200, height=100)
fg.add_child(folium.Marker(location=[lt, ln], popup=folium.Popup(iframe), icon = folium.Icon(color=color_producer(el))))
- Изменим внешиний вид точек, показывающих вулканы на карте. Используем dir(folium) для поиска метода создания круглых маркеров. После того как нужный метод найден, воспользуемся функцией help для поиска аргументов, которые передадим методу для стилизации маркеров.
fgv.add_child(folium.CircleMarker(location=[lt, ln], radius=6, popup=folium.Popup(iframe), fill_color=color_producer(el), color='grey', fill_opacity=0.7))
-
В данный момент у нас 2 слоя: базовый слой и слой с маркерами. Добавим слой, показвающий количество населения в разных странах.
-
Создадим новую FeatureGroup.
fgp = folium.FeatureGroup(name="Population") и добавим к ней child fgp.add_child
-
Добавим polygon layer с помощью метода GeoJson: folium.GeoJson
-
Данные для GeoJson возьмем из файла world.json
** Не открывайте world.json через Atom, если не уверены, что в мощности вашего компьютера. Используйте редактор "полегче", напр.: Notepad.
- Задаём атрибут data для метода GeoJson, равный:
fgp.add_child(folium.GeoJson(data=open('world.json', 'r', encoding='utf-8-sig').read()))
** Метод open нужен для создания файлового объекта Python, далее укажем путь к файлу 'world.json'.
** Метод read() в конце нужен так как новые версии Folium принимают строку, вместо файла, в качестве вводных данных.
-
В файле world.json есть информация о населении каждой из стран, которая хранится в атрибуте "POP2005".
-
Добавим новый аргумент style_function в GeoJson:
style_function=lambda x: {'fillColor':'green' if x['properties']['POP2005'] < 10000000
else 'orange' if 10000000 <= x['properties']['POP2005'] < 20000000 else 'red'}))
** x['properties']['POP2005'] В данном примере, 'properties' это ключ, 'POP2005' его значение в словаре в файле world.json, x означает 'features' в том же файле.
- Используем класс LayerControl модуля folium.
map.add_child(folium.LayerControl())