Всем привет! Это блог компании "Техносерв". В процессе производства на проектах, которые мы выполняем, рождаются интересные технологические кейсы. Их скопилось такое количество, что мы решили начать делиться ими с миром. И да, это наша первая публикация.
Честь начать блог выпала мне, и я пишу о том, что мне близко и любимо: о геоинформационных технологиях. Я работаю в департаменте Больших Данных, где занимаюсь разработкой высоконагруженных геоинформационных систем и сервисов на базе движков для распределенных вычислений. О высоких материях мы еще поговорим, а сегодня плавно начнем погружение в ГИС.
Все чаще и чаще у аналитиков данных (или как еще их называют — Data Scientist) появляется потребность в визуализации данных на карте. Какой инструмент сейчас считается наиболее удобным для работы аналитика? Конечно же, тетрадки! До последнего времени возможностей по визуализации геоданных было не так много. Можно было делать статические растры в matplotlib, иногда можно было добавлять даже базовые карты. Интересной оказалась библиотека для работы с Leaflet, где можно открывать geojson-файлы. Сегодня же я хочу рассказать об ArcGIS API for Python от компании Esri.
Эта статья будет полезна как аналитикам, желающим изучить примеры работы с ГИС, так и картографам и ГИС-специалистам, которым интересно попробовать себя в написании кода.
Что такое ArcGIS API for Python?
Это простая в использовании и богатая по функционалу библиотека для визуализации и анализа геоданных, а также для управления корпоративной ГИС (Географический Информационной Системы), от пространственных данных до администрирования. Важной особенностью этой библиотеки является "питоничность" (Pythonic) с использованием стандартных конструкций, структур и идиом, что выгодно отличает ее от стандартной ArcGIS-библиотеки arcpy, которая порой вызывала ярость у разработчиков как стилем кода, так и быстродействием.
В этой статье пойдет речь о тех функциях, которые доступны без покупки лицензий ArcGIS или подписки ArcGIS Online. Для работы понадобится бесплатный аккаунт ArcGIS Online (я опущу подробности его создания — это довольно просто сделать на http://www.arcgis.com). В этом варианте присутствует ограничение на 1000 объектов в слое.
API распространяется в виде conda-пакета arcgis. Внутри пакета, который представляет собой концептуальную модель ГИС, функциональность организована в нескольких различных модулей, что делает его простым в использовании и понимании. Каждый модуль имеет несколько типов и функций, которые охватывают конкретный аспект ГИС.
Я рассмотрю небольшую часть API в качестве вводного материала.
arcgis.gis
обеспечивает базовую информационную модель как для корпоративной ГИС, так и для ArcGIS Online. Этот модуль обеспечивает функции управления (создание, чтение, обновление и удаление) пользователями, группами и контентом. Собственно, это ваша точка входа в ГИС.arcgis.widgets
— это, собственно, модуль для управления картографическими виджетами (MapView) в Jupyter notebook.
Установка
На данный момент библиотека распространяется только внутри Anaconda for Python 3x. Ставится все просто.
%%cmd
conda install -c esri arcgis
Надеюсь, все прошло успешно. Теперь можно начинать использование.
Если нет желания ставить Anaconda, но библиотеку протестировать хочется, то можно попробовать песочницу от Esri: https://notebooks.esri.com.
Использование
Объект GIS в модуле gis — самый главный в ArcGIS API for Python, ваша входная точка. Он олицетворяет ту ГИС, с которой вы работаете, будь ArcGIS Online или корпоративный ArcGIS. Объект позволяет работать с геоконтентом или же администрировать ГИС. Начнем с инициализации объекта GIS
import arcgis
from arcgis.gis import GIS
Для работы можно использовать как базовое анонимное подключение к ArcGIS Online...
gis = GIS()
… так и с логином.
my_gis = GIS(url='http://arcgis.com', username='andrey_zhukov', password='секрет')
Для любого инструмента можно вызывать справку, например
gis?
Кроме того, поддерживается и контекстный ввод
Встроить карту — это просто!
Давайте инициализируем объект карты hello_map с центром в Москве и с уровнем зума 15.
hello_map = my_gis.map("Москва", zoomlevel = 15)
А теперь вызовем его...
hello_map
Добро пожаловать!
В карте работают базовые элементы — перетаскивание мышью (pan) и изменение масштаба (zoom) как колесом мыши (или соответствующим жестом на тачпаде), так и экранными кнопками.
Последующие манипуляции с объетом hello_map отразятся во фрейме выше.
Чем можно управлять у карты?
Например, зумом.
hello_map.zoom = 10
Увеличим площадь карты
hello_map.height = '600px'
Получится такая картинка:
Посмотрим список доступных базовых карт.
hello_map.basemaps
['streets',
'satellite',
'hybrid',
'topo',
'gray',
'dark-gray',
'oceans',
'national-geographic',
'terrain',
'osm']
Можно все посмотреть? Конечно!
from time import sleep
for basemap in hello_map.basemaps:
hello_map.basemap = basemap
sleep(5)
Во фрейме карты можно будет увидеть примерно такое:
OpenStreetMap — вполне привычно, остановимся на нем.
hello_map.basemap = 'osm'
Поищем адреса. Найдем адрес БЦ Омега плаза и приблизм карту к нему.
Геокодирование по одному адресу абсолютно бесплатно, но пакетное геокодирование уже требует кредитов на счете организации.
location = arcgis.geocoding.geocode('Москва, Ленинская слобода, 19', max_locations=1)[0]
hello_map.extent = location['extent']
На карту можно добавлять контент из галереи ArcGIS Online. Поищем что-нибудь интересное...
from IPython.display import display
items = gis.content.search('title:Moscow', item_type='Feature Collection')
for item in items:
display(item)
Moscow Walking Tour
— отлично! Уточним элемент.
my_layer = items[2]
display(my_layer)
Добавляем сервис и смотрим на наш hello_map
hello_map.add_layer(my_layer)
hello_map.zoom = 10
Мы получили веб-карту, встроенную во фрейм внутри Notebook. В ней поддерживается навигация и вывод информации по клику на объектах. На сегодняшний день многие организации используют технологии ArcGIS не только на корпоративном уровне, но и для публикации открытых данных. Некоторые из этих открытых данных доступны для поиска и использования на ArcGIS Online, другие же можно найти через портал открытых данных (https://opendata.arcgis.com/) и подгрузить в ArcGIS Online.
Happy hacking mapping!
Работа с объектами
Конечно же, каждый Data Scientist, работающий в Jupyter Notebook, привык к pandas и DataFrame. Давайте поработаем уже с полноценным набором данных, используя pandas и ArcGIS.
Для этого сначала импортируем csv в pandas, а потом преобразуем его в слой карты.
В качестве примера я возьму слой паркоматов Москвы. Я уже немного поколдовал с исходным csv. Перекодировал в utf8 и переименовал столбцы, чтобы не возникло неожиданных проблем.
import pandas as pd
parkomats = pd.read_csv(r'.datadata-417-2017-02-14.csv', sep=';')
Посмотрим получившийся объект. В нем уже есть широта и долгота, а также псевдо-geojson-поле geoData. При импорте данных ArcGIS сам пытается опознать поля геометрии или адреса. Если бы нам требовалось собрать данные по адресам, то пришлось бы собирать адрес из нескольких полей.
parkomats.tail()
Теперь импортирум DataFrame из pandas в объекты gis. Для этого просто вызываем функцию import_data. В результате у нас получается объект FeatureCollection
geoparkomats = my_gis.content.import_data(parkomats)
geoparkomats
<FeatureCollection>
Теперь добавим объекты на карту. Для этого инициализируем новый объект map и в него добавим наш новый слой.
parkomat_map = my_gis.map('Москва', zoomlevel=12)
parkomat_map.basemap = 'osm'
parkomat_map.height = '600px'
parkomat_map.add_layer(geoparkomats)
parkomat_map
Уже неплохо! Но неплохо было бы эти данные оформить. Давайте попробуем их разукрасить. Для начала просто по зонам парковки
parkomat_cat_map = my_gis.map('Москва', zoomlevel=10)
parkomat_cat_map.basemap = 'gray'
parkomat_cat_map.add_layer(geoparkomats, {"renderer":"ClassedColorRenderer", "field_name":"ParkingZoneNumber"})
parkomat_cat_map.height = '600px'
parkomat_cat_map
Многие любят теплокарты. Давайте попробуем сделать и ее.
parkomat_heat_map = my_gis.map('Москва', zoomlevel=11)
parkomat_heat_map.basemap = 'dark-gray'
parkomat_heat_map.add_layer(geoparkomats, {"renderer":"HeatmapRenderer"})
parkomat_heat_map.height = '600px'
parkomat_heat_map
Как видите, добавить и стилизовать слой — это не сложно.
Кроме того, можно расположить все карты рядом. Для этого создадим и настроим три новых фрейма и впишем их в один бокс.
just_map = my_gis.map('Москва', zoomlevel=10)
just_map.basemap = 'osm'
just_map.add_layer(geoparkomats)
cat_map = my_gis.map('Москва', zoomlevel=10)
cat_map.basemap = 'gray'
cat_map.add_layer(geoparkomats, {"renderer":"ClassedColorRenderer", "field_name":"ParkingZoneNumber"})
heat_map = my_gis.map('Москва', zoomlevel=10)
heat_map.basemap = 'dark-gray'
heat_map.add_layer(geoparkomats, {"renderer":"HeatmapRenderer"})
from ipywidgets import *
just_map.layout=Layout(flex='1 1', padding='5px')
cat_map.layout=Layout(flex='1 1', padding='5px')
heat_map.layout=Layout(flex='1 1', padding='5px')
box = HBox([just_map, cat_map, heat_map])
box.height = '300px'
box
Заключение
Итак, вы узнали, как легко и просто использовать в Jupyter Notebook полноценные веб-карты с помощью ArcGIS API for Python. Это новый продукт, едва вышедший из беты, но уже довольно интересный, с большими перспективами. С вопросами по работе и предложениями по улучшению API вы можете как выступить в комментариях к статье, так и написать российскому представителю Esri в России — esri-cis.ru.
Материалы этой статьи выложены на GitHub (https://github.com/fall-out-bug/arcgis_python). Код библиотеки и обширные материалы Esri тоже можно найти на GitHub (https://github.com/Esri/arcgis-python-api)
Happy mapping!
Автор: ТЕХНОСЕРВ