Community Engee

Новый год в России

作者
avatar-nkapyrinnkapyrin
Notebook

Открытка с видом России в новогоднюю ночь

Пример предназначен для демонстрации возможного сценария прохождения новогодних праздников при наблюдении за Россией из космоса.

Мы построим карту и нанесем несколько тематических украшений.

Готовы? Тогда установим некоторые нужные нам библиотеки:

In [ ]:
Pkg.add("GeoJSON")

Затем их обязательно нужно подключить:

In [ ]:
using GeoJSON, Dates, DelimitedFiles, LinearAlgebra
include("$(@__DIR__)/scripts/is_new_year_night.jl");
include("$(@__DIR__)/scripts/lonlat_2_xyz.jl");
include("$(@__DIR__)/scripts/draw_tree.jl");
include("$(@__DIR__)/scripts/draw_firework.jl");

Загрузим исходные данные: карты и перечень российских городов (мы создали собственную карту, преимущественно на основе материалов сайта https://data.humdata.org/):

In [ ]:
# Чтение карты с границами субъектов
fc = GeoJSON.read( "$(@__DIR__)/Россия_ADM1_0_1_гр.geojson" );

# Чтение данных о городах
города = readdlm("$(@__DIR__)/города.csv", ',', skipstart=1);

Когда пространственные ориентиры установлены, укажем временные ориентиры и наша инженерная открытка будет готова к публикации:

In [ ]:
# @markdown Строить карту по местному времени?
Время = "выбрать часовой пояс" # @param ["местное текущее время","выбрать часовой пояс"]

# @markdown Или установите желаемый часовой пояс относительно Москвы
Часовой_пояс = 2 # @param {type:"slider",min:-2,max:10,step:0.25}

if Время == "местное текущее время"
    current_time = now(Dates.UTC)
    utc_hours = Dates.hour(current_time) + Dates.minute(current_time) / 60
else
    utc_hours = 9.5 - Часовой_пояс
end

plot(legend=false, bg_color=:white, bg_inside=:white)

# Субъекты Федерации
for geom in fc.geometry
    for subgeom in geom.coordinates
        for ring in subgeom
            if length(last.(ring)) < 10 continue; end;
            x3d, y3d, z3d = lonlat_2_xyz(first.(ring), last.(ring))
            plot!(x3d, y3d, z3d, color=rand([:skyblue, :lightseagreen, :darkcyan, :lightslateblue, :indigo]), linewidth=4, label=false)
        end
    end
end

# Линия смены года на текущий момент
noon_lon = (12 - utc_hours) * 15
midnight_lon = mod(noon_lon + 180, 360) - 180

#if is_new_year_night(current_time) && midnight_lon > 30 && midnight_lon < 190
    line_lat_full = range(40, 90, 20)
    for (lon_delta, lon_color) = zip([0,0.25,0.5,0.75], [:green3, :lightseagreen, :springgreen, :aquamarine])
        line_lon_full = (midnight_lon + lon_delta) .* ones(size(line_lat_full))
        x3d_full, y3d_full, z3d_full = lonlat_2_xyz(line_lon_full, line_lat_full)
        plot!(x3d_full, y3d_full, z3d_full, color=lon_color, linewidth=8, label=false, alpha=0.6)
    end
#end

# Деревья и салюты
for (lon,lat) in zip(Float64.(города[:, 3]), Float64.(города[:, 2]))
    if lon < midnight_lon
        draw_tree(lon, lat, 0.3)
    elseif lon < midnight_lon + 15.0 
        # Салют!
        draw_tree(lon+rand()-0.5, lat+rand()-0.5, 0.5)
        draw_firework(lon+0.1rand(), lat+0.1rand())
    else
        draw_tree(lon, lat, 0.5)
    end
end

# Основное отличие инженерной открытки от обычной - это наличие осей на графике
plot!(size=(1920, 1080), camera=(-180, 25))
Out[0]:

Сохраним результат чтобы отправить друзьям:

In [ ]:
png( "$(@__DIR__)/Открытка.png" )
Out[0]:
"/user/russia_map/map_new_year_postcard/Открытка.png"

Мы надеемся, что этот пример позволит достаточно точно передать ваше настроение в это новогоднее время. Счастливого нового года!