Рассказываем, как мы превратили текстовый список адресов в рабочую интерактивную карту — без боли, но с интересными нюансами. Задача звучала просто: положить на карту все библиотеки Санкт-Петербурга, срок — "нужно было ещё вчера". Оцениваем: очистка данных — 15 минут, геокодирование — 30 минут, визуализация — "на лету". Итого — час. Погнали...
Источник данных выбрали очевидный — Википедия. Там есть список из библиотек с адресами. Казалось бы, бери и мапь. Но адреса — это текст, а карта нуждается в координатах.
Википедия даёт нам строки вида:
Санкт-Петербург, наб. реки Фонтанки, д. 44
Санкт-Петербург, В. О., линия 21-я, д. 2
Санкт-Петербург, пос. Комарово, ул. 3-я Дачная, д. 8
Петербургская специфика адресов создаёт дополнительные сложности:
- «В. О.» — это Васильевский остров, и не всякий геокодер поймёт аббревиатуру
- «линия 21-я» — петербургская особенность, в других городах такого нет
- «пос. Комарово» — это уже Курортный район, но формально Санкт-Петербург
- «д. 16/7» — дробные номера домов
- «корп. 2», «корп. 1» — корпуса важны для точности
Выбор пал на Yandex Geocoder — как самый «петербургский» из всех. Он действительно понимает «В. О.» как Васильевский остров и знает про линии. Ии самое главное — Yandex Geocoder API позволяет отправлять запросы пакетно. Обернули в удобный веб-интерфейс и для каждого адреса получили:
- lat, lon — координаты
- precision — точность (exact, number, street, etc.)
- kind — тип объекта (house, street, metro...)
Техническая реализация
import requests
import json
import time
API_KEY = ‘your_yandex_api_key’
def geocode_address(address):
"""Геокодирование одного адреса через Yandex Geocoder"""
url = "https://geocode-maps.yandex.ru/1.x/"
params = {
'apikey': API_KEY,
'geocode': address,
'format': 'json',
'results': 1
}
response = requests.get(url, params=params)
data = response.json()
try:
feature = data['response']['GeoObjectCollection']['featureMember'][0]['GeoObject']
coords = feature['Point']['pos'].split()
precision = feature['metaDataProperty']['GeocoderMetaData']['precision']
return {
'address': address,
'lat': float(coords[1]),
'lon': float(coords[0]),
'precision': precision,
'name': feature['name']
}
except (IndexError, KeyError):
return {'address': address, 'error': 'not_found'}
# Пакетная обработка с задержкой (лимиты API)
addresses = [...] # список из 100+ адресов
results = []
for addr in addresses:
result = geocode_address(addr)
results.append(result)
time.sleep(0.2) # не превышаем лимиты

Итоговая карта покрывает 100+ библиотек — от Российской национальной библиотеки на Московском проспекте до библиотеки-филиала в посёлке Комарово.

Делаем экспорт данных в GeoJSON, отправляем заказчику. Весь процесс занял менее часа с учетом написания интерфейса для геокодирования, в нем кстати есть интересная фича — обратное геокодирование по клику.
Что дальше?
- Добавить атрибутику — часы работы, контакты, фотографии
- Построить изохроны — зоны доступности «15 минут пешком до библиотеки»
- Сравнить с данными Росстата — проверить, все ли библиотеки из официальных реестров попали на карту
Задача, которая могла растянуться на несколько дней, заняла менее часа. Иногда «взять готовое и преобразовать» — лучшая стратегия, чем собирать данные с нуля. Особенно когда речь идёт о городской инфраструктуре. Код геокодера выложили здесь — может, кому-то пригодится для аналогичных задач. Код написан на Python/Flask, деплой на Heroku/VPS занимает 10 минут.