Модуль 5: Робота з геоданими

УРОК 5

Час60-90 хвилин
ПотрібноУроки 1-4, events.csv з Уроку 3
РезультатІнтерактивна карта з подіями

Задача

Координати — ключові дані в розвідці. Типові задачі:

Нові терміни

WGS84Стандартна система координат GPS. Широта/довгота в градусах. Використовується майже скрізь.
HaversineФормула розрахунку відстані по сфері. Враховує кривизну Землі — точніша за пряму лінію.
КластерГрупа близьких точок. Кластеризація — автоматичне групування за близькістю.
GeoJSONФормат для геоданих. Стандарт для обміну координатами, полігонами, маршрутами.
FoliumБібліотека для створення інтерактивних карт. Генерує HTML з картою.

Встановлення

pip install geopy folium

geopy — розрахунки відстаней, геокодування. folium — візуалізація на карті.

Частина 1: Розрахунок відстані

Відстань між двома точками

from geopy.distance import geodesic # Координати двох точок (широта, довгота) point1 = (48.4567, 35.0234) # Точка 1 point2 = (48.5123, 35.1456) # Точка 2 # Розрахунок відстані distance = geodesic(point1, point2) print(f"Відстань: {distance.kilometers:.2f} км") print(f"Відстань: {distance.meters:.0f} м") print(f"Відстань: {distance.miles:.2f} миль")

geodesic використовує формулу Вінсенті — точніша за Haversine, враховує еліпсоїдність Землі.

Матриця відстаней

Коли є багато точок — рахуємо відстані між усіма парами:

from geopy.distance import geodesic import pandas as pd # Список точок points = [ {"id": "A", "lat": 48.4567, "lon": 35.0234}, {"id": "B", "lat": 48.5123, "lon": 35.1456}, {"id": "C", "lat": 48.4800, "lon": 35.0800}, {"id": "D", "lat": 49.1234, "lon": 36.5678}, ] # Рахуємо відстані між усіма парами results = [] for i, p1 in enumerate(points): for p2 in points[i+1:]: # Тільки унікальні пари coord1 = (p1['lat'], p1['lon']) coord2 = (p2['lat'], p2['lon']) dist = geodesic(coord1, coord2).kilometers results.append({ 'from': p1['id'], 'to': p2['id'], 'distance_km': round(dist, 2) }) # Виводимо df = pd.DataFrame(results) print(df.sort_values('distance_km'))

Частина 2: Пошук у радіусі

Знайти всі точки в радіусі N км від заданої:

from geopy.distance import geodesic # Центральна точка center = (48.4647, 35.0462) radius_km = 5 # Радіус пошуку # Усі точки для перевірки all_points = [ {"id": "P1", "lat": 48.4567, "lon": 35.0234}, {"id": "P2", "lat": 48.5123, "lon": 35.1456}, {"id": "P3", "lat": 48.4700, "lon": 35.0500}, {"id": "P4", "lat": 49.1234, "lon": 36.5678}, {"id": "P5", "lat": 48.4600, "lon": 35.0400}, ] # Фільтруємо nearby = [] for point in all_points: coord = (point['lat'], point['lon']) dist = geodesic(center, coord).kilometers if dist <= radius_km: point['distance_km'] = round(dist, 2) nearby.append(point) print(f"Точки в радіусі {radius_km} км від {center}:") for p in sorted(nearby, key=lambda x: x['distance_km']): print(f" {p['id']}: {p['distance_km']} км")

Частина 3: Кластеризація

Автоматичне групування близьких точок. Корисно для виявлення зон концентрації активності.

from geopy.distance import geodesic def simple_cluster(points, max_distance_km=2): """ Проста кластеризація: об'єднуємо точки ближче ніж max_distance_km. Повертає список кластерів. """ clusters = [] used = set() for i, p1 in enumerate(points): if i in used: continue # Новий кластер cluster = [p1] used.add(i) # Шукаємо сусідів for j, p2 in enumerate(points): if j in used: continue coord1 = (p1['lat'], p1['lon']) coord2 = (p2['lat'], p2['lon']) if geodesic(coord1, coord2).kilometers <= max_distance_km: cluster.append(p2) used.add(j) clusters.append(cluster) return clusters # Тестові дані points = [ {"id": "A", "lat": 48.4567, "lon": 35.0234}, {"id": "B", "lat": 48.4590, "lon": 35.0260}, # Близько до A {"id": "C", "lat": 48.4580, "lon": 35.0240}, # Близько до A, B {"id": "D", "lat": 49.1234, "lon": 36.5678}, # Далеко {"id": "E", "lat": 49.1250, "lon": 36.5700}, # Близько до D ] clusters = simple_cluster(points, max_distance_km=5) for i, cluster in enumerate(clusters, 1): ids = [p['id'] for p in cluster] print(f"Кластер {i}: {', '.join(ids)}")
💡 Це спрощений алгоритм. Для серйозної кластеризації є sklearn.cluster.DBSCAN — він ефективніший на великих даних.

Частина 4: Візуалізація на карті

Folium створює інтерактивну HTML-карту:

import folium # Координати для центрування карти center_lat = 48.4647 center_lon = 35.0462 # Створюємо карту m = folium.Map( location=[center_lat, center_lon], zoom_start=12, tiles='OpenStreetMap' # Можна: 'CartoDB positron', 'CartoDB dark_matter' ) # Додаємо маркери points = [ {"id": "P1", "lat": 48.4567, "lon": 35.0234, "type": "fire"}, {"id": "P2", "lat": 48.5123, "lon": 35.1456, "type": "movement"}, {"id": "P3", "lat": 48.4700, "lon": 35.0500, "type": "contact"}, ] # Кольори за типом colors = {"fire": "red", "movement": "blue", "contact": "green"} for p in points: folium.Marker( location=[p['lat'], p['lon']], popup=f"{p['id']}: {p['type']}", # Текст при кліку tooltip=p['id'], # Текст при наведенні icon=folium.Icon(color=colors.get(p['type'], 'gray')) ).add_to(m) # Зберігаємо m.save('map.html') print("Карту збережено у map.html")

Відкрий map.html у браузері — побачиш інтерактивну карту з маркерами.

Додаткові елементи карти

# Коло (радіус пошуку) folium.Circle( location=[48.4647, 35.0462], radius=5000, # метри color='blue', fill=True, opacity=0.3 ).add_to(m) # Лінія між точками folium.PolyLine( locations=[[48.4567, 35.0234], [48.5123, 35.1456]], color='red', weight=2 ).add_to(m) # Полігон (зона) folium.Polygon( locations=[ [48.45, 35.00], [48.50, 35.00], [48.50, 35.10], [48.45, 35.10] ], color='green', fill=True, opacity=0.2 ).add_to(m)

Практична задача

Аналіз координат з CSV та візуалізація. Створи analyze_geo.py:

Якщо не працює

ПомилкаРішення
ModuleNotFoundError: geopy/foliumpip install geopy folium
ValueError: coordinates out of rangeШирота має бути -90..90, довгота -180..180
Карта не відображаєтьсяВідкрий HTML у браузері, не в редакторі коду
Порожня картаПеревір координати — можливо, вони в іншій частині світу

Робота з AI

Є CSV з колонками: id, lat, lon, timestamp, event_type. Напиши скрипт, який: 1. Знаходить усі точки в радіусі 10 км від координати 48.5, 35.1 2. Групує їх у кластери (відстань < 2 км) 3. Для кожного кластера рахує кількість подій по типах 4. Створює карту з кластерами різних кольорів 5. Зберігає звіт у CSV Використовуй geopy, pandas, folium.

Чек-лист

☐ geopy та folium встановлено ☐ Розрахунок відстані працює ☐ Пошук у радіусі знаходить точки ☐ Кластеризація групує близькі точки ☐ events_map.html створено і відкривається

Самостійна практика

Наступний урок

Урок 6: Аналіз часових патернів

Робота з датами, виявлення закономірностей, графіки активності.