Введение: зачем разработчику карта всех маяков мира?
Когда в пятницу вечером коллега-бэкендер задумчиво отправляет в чат ссылку на карту береговой охраны, у нормальных людей возникает желание спланировать отпуск у моря. У веб-разработчика же загораются глаза от другой мысли: «Интересно, а сколько запросов упадет база, если отрендерить их все одновременно?». (А главное — почему это падает на стейдже, но отлично работает на вашей машине). Представьте, что вы решили запустить свой Open Source проект «A map of every lighthouse» — интерактивный атлас всех навигационных огней планеты. Прямо сейчас это идеальный полигон, чтобы прокачать навыки сбора неструктурированных данных, очистки датасетов, работы с пространственными индексами и оптимизации рендеринга тысяч маркеров на веб-карте.
Исторически сложилось так, что навигационные огни находятся в ведении суверенных государств: Береговой охраны США (USCG), Британского адмиралтейства, международных ассоциаций маячных служб и сотен локальных портовых управлений. Единой, чистой и централизованной базы данных «всех маяков мира» в формате JSON или GeoJSON не существует. Разработчику предстоит собрать эту мозаику самостоятельно.
В этой статье мы подробно разберем архитектуру такого проекта: от поиска и парсинга разрозненных источников до оптимизации базы данных PostGIS и фронтенд-визуализации с использованием современных веб-технологий. Мы рассмотрим реальные примеры кода на Python и JavaScript, а также обсудим подводные камни работы с координатами и морскими навигационными стандартами.
Но прежде чем писать код, давайте разберем главное препятствие: где взять исходные данные и как не утонуть в их разнородности?
1. Источники данных и стратегия парсинга: собираем разрозненные пазлы
Первый и самый трудоемкий этап создания глобальной карты маяков — это агрегация информации. Поскольку единого API не существует, приходится комбинировать открытые государственные реестры, краудсорсинговые базы и специализированные морские порталы.
Основные источники, которые использует дата-инженер:
- OpenStreetMap (OSM): Крупнейшая краудсорсинговая база геоданных. Тег
seamark:type=lighthouseсодержит тысячи точек по всему миру с базовыми атрибутами. - NGA (National Geospatial-Intelligence Agency): Издает официальный «List of Lights» (публикации 110–116), содержащий технические характеристики огней, высоту фокальной плоскости и дальность видимости.
- Национальные ведомства: Данные береговой охраны США, Канады, Австралии и европейских стран, часто доступные в виде CSV-файлов или через государственные ArcGIS REST API.
Для автоматизации сбора данных из правительственных реестров в формате PDF или таблиц Excel пишется скрипт на Python с использованием библиотек requests, BeautifulSoup и geopandas. Ниже приведен пример надежного парсера, который извлекает координаты маяков из открытого API и приводит их к единому стандарту.
import requests
import json
def fetch_lighthouses_from_api(endpoint_url):
headers = {'User-Agent': 'LighthouseMapBot/1.0 (admin@coffee-web.ru)'}
try:
response = requests.get(endpoint_url, headers=headers, timeout=10)
response.raise_for_status()
data = response.json()
lighthouses = []
for item in data.get('features', []):
props = item.get('properties', {})
coords = item.get('geometry', {}).get('coordinates', [])
if len(coords) == 2:
lighthouses.append({
"name": props.get('NAME', 'Unknown Lighthouse'),
"lat": coords[1],
"lon": coords[0],
"range_nm": props.get('RANGE_NM', None)
})
return lighthouses
except requests.exceptions.RequestException as e:
print(f"Ошибка при запросе к API: {e}")
return []
# Пример использова (дописывать код на Stack Overflow мы, конечно же, не будем — напишем свой)