Домашнє завдання 1 - ViriAldi/HomeworkCycle2020 GitHub Wiki
Цикл домашніх завдань буде присвячено створенню універсальної програми для роботи з ландшафтом планети Земля.
Функціонал програми повинен включати вирішення наступніх проблем:
- Точне визначення висоти над рівнем моря точки, заданої географічними координатами.
- Побудова та інтерактивна візуалізація ландшафту місцевості, заданої сферичним прямокутником, з можливістю вибору його розмірів, положення на земній кулі, точності розрахунків, стилю візуалізації.
- Визначення найкоротшого шляху між 2-ма точками земної поверхні з урахуванням ландшафту. * Розрахунок та візуалізація оптичного пейзажу з будь-якої точки земної кулі.
- Створення інтерактивної тривимірної карти ландшафту, що оновлюється разом із положенням користувача.
Ці проблеми актуальні й не завжди мають розв'язки з достатньою точністю у наш час.
Достойне розв'язання цих проблем принесло б цінні результати в наступні сфери:
- Будівництво
- Гірський туризм
- Навігація
- Допомога людям з вадами зору
- Логістика
- Транспорт
- Data Sience
- Топологія, Геодезія
- Авіація
Визначення висоти точки земної поверхні за географічними координатами - використовується у наш час для топології, навігації, тощо. Багато сучасних систем навігації (і у додатку Google Maps теж) активно використовують цю можливість. Під питанням стоїть точність такого визначення, тому програма має орієнтуватись на це.
Побудова та візуалізація ландшафту місцевості - означає визначення координат множини точок поверхні у тривимірному просторі і створення структури даних, яка б забезпечувала зв'язок між точками поверхні та можливість приблизного відтворення реального земного ландшафту. До того ж ця можливість може допомогти орієнтуватись в просторі людям з вадами зору.
Визначення найкоротшого шляху - актуальна проблема транспорту, логістики, туризму, будівництва. Найкоротший шлях по ландшафту не відповідає прямій лінії, а параметри цього шляху (максимальний нахил, тощо) мають задаватись користувачем.
Реалізація розв'язку поставлених проблем
Задля реалізації точних розвязків цих проблем, я буду використовувати різноманітні датасети з географічними даними. Зокрема основним з них є National Evaluation Data - набір даних про висоту над рівнем моря точок земної поверхні з кроком 30 метрів. Дані представлення у вигляді різних .tiff файлів для різних регіонів світу. Сумарний об'є даних сягатиме декілька сотень Мб.
Для роботи з даними в такому форамті потрібно здійснити наступні кроки:
- Отримати доступ до даних на спеціальному ресурсі Earth Explorer (процес подібний до отримання ключа до API)
- Завантажити дані на носій інформації (жосткий або твердотільний диск)
- Відкрити ці дані у Python програмі за допомогою інструментів модуля pillow
- Сконвертувати ці дані у двовимірний масив за допомогою модуля numpy
- Отриманий двовимірний масив - матриця висот з рівним ходом географічних координат
Для опрацювання даних їх варто зберегти у спеціальну структуру даних, з якою буде легко працювати в процесі вирішення поставлених проблем.
Приклад використання даних для побудови тривимірної поверхні ландшафту
Імпорт потрібних бібліотек
from PIL import Image
import numpy
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
Відкриття і конвертування даних
def read_data(path):
im = Image.open(path)
imarray = numpy.array(im)
imarray = imarray.T
return imarray
Реалізація функції обчислення висоти
def get_elevation(coord, corner_long, corner_lat, grid):
lat, long = coord
ind_lon = int(3 * abs(corner_long - long) // 0.00250)
ind_lat = int(3 * abs(corner_lat - lat) // 0.00250)
return grid[ind_lon][ind_lat]
Обчислення даних для візуалізації
def create_plot_data(coord, size, corner_coord, grid):
# creating arrays with coordinates
coords_x = np.array([x + 0.00083333 * i
for i in range(-size, size + 1)] * (2 * size + 1))
coords_y = np.array([y + 0.00083333 * i for i in range(-size, size + 1)
for j in range(2 * size + 1)])
coords_z = np.array([2 * get_elevation(t, corner_coord, grid)
for t in zip(coords_x, coords_y)])
# scaling coordinates
coords_x = coords_x * 120000
coords_y = coords_y * 100000
# creating 2D arrays
coords_x.resize(2 * size + 1, 2 * size + 1)
coords_y.resize(2 * size + 1, 2 * size + 1)
coords_z.resize(2 * size + 1, 2 * size + 1)
return (coords_x, coords_y, coords_z)
Реалізація візуалізації
def vizualize(plot_data):
X, Y, Z = plot_data
ax = plt.axes(projection='3d')
ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False, rcount = 500, ccount = 500)
# Create cubic bounding box to simulate equal aspect ratio
max_range = np.array([X.max()-X.min(), Y.max()-Y.min(), Z.max()-Z.min()]).max()
Xb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][0].flatten() + 0.5*(X.max()+X.min())
Yb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][1].flatten() + 0.5*(Y.max()+Y.min())
Zb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][2].flatten() + 0.5*(Z.max()+Z.min())
for xb, yb, zb in zip(Xb, Yb, Zb):
ax.plot([xb], [yb], [zb], 'w')
plt.grid()
plt.show()
Робота програми на конкретному прикладі:
if __name__ == "__main__":
x, y = [47.5, 7.5]
size = 40
grid = read_data("srtm_38_03.tif")
plot_data = create_plot_data((x, y), size, (50, 5), grid)
vizualize(plot_data)
Результат (гора Mont Blanc)
Вимоги на систему
-
Спонсор проєкту
Я ініціатор проєкту
-
Бізнес потреба
Покращити доступ до інформації
-
Бізнес вимоги
Ресурс для роботи з ландшафтом землі. Зокрема моделювання і візуалізація ландшафту
-
Питання та обмеження
Граничний термін - 25 травня. Програма - самостійний, унікальний та універсальний ресурс