Проект I#

Анализ застройки и землепользования#

Цель:#

  1. Визуализировать данные о застройке и землепользовании для выбранного района города

  2. Рассчитать долю застроенной территории

  3. Отобразить структуру землепользования

Шаги:#

  1. Выберите район (например: “Хамовники, Москва”) Для Москвы и Санкт-Петербурга не будет проблем с выгрузкой границ района, так как они являются единицами административного деления. Для других городов – нужно проверять

  2. Загрузите данные:

    • Здания (osmnx.features_from_place с тегом building).

    • Землепользование (osmnx.features_from_place с тегом landuse).

  3. Рассчитайте долю застроенной территории:

    • (Площадь всех зданий / площадь района) × 100%.

  4. Постройте график:

    • Круговую диаграмму структуры землепользования

Требования к итоговому результату:#

  • Две картосхемы: застройки (1) и типов землепользования (2)

  • Значение доли застройки в %

  • График с категориями землепользования

  • Сохраненный результат в виде иллюстрации в любом графическом формате (jpg, png или др.)

Формат сдачи задания:#

  • Документ в формате .ipynb

  • Итоговая визуализация в виде одного или нескольких изображений (jpg, png или др.)

Критерии оценивания (max. 10 баллов)#

1. Корректность данных (2 балла)

  • 1 балл – Получены данные о зданиях (building) без ошибок.

  • 1 балл – Получены данные о землепользовании (landuse) без ошибок.

2. Расчеты и анализ (2 балла)

  • 1 балл – Правильно вычислена доля застроенной территории (%).

  • 1 балл – Построена круговая диаграмма структуры землепользования.

3. Визуализация (2 балла)

  • 1 балл – Создана картосхема застройки (здания).

  • 1 балл – Создана картосхема типов землепользования.

4. Оформление итогового результата (4 балла)

  • 1 балл – Сданный код структурирован и читаем

  • до 3 баллов – Отличная итоговая визуализация (читаема, есть все основные элементы на картосехемах, отображены итоговые расчеты)

Примерный ход работы#

Шаг 1: Импортируем библиотеки#

import osmnx as ox
import geopandas as gpd
import matplotlib.pyplot as plt

Шаг 2: Выгружаем данные о застройке и землепользовании из OSM#

# Определяем имя для поиска
place_name = ... # тут имя рассматриваемого района в кавычках

# Загружаем границу района
district = ...

buildings = ...
landuse = ...

Шаг 3: Перепроецируем данные в нужнную UTM-зону#

# Определяем UTM-зону
data_crs = ...

# Перепроецируем данные 
district_utm = ... 
buildings_utm = ...
landuse_utm = ...

Шаг 4: Вычисляем площадь района#

area_district = ...


#Смотрим на результат
print(f"Площадь района: {area_district[0]} м²")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 5
      1 area_district = ...
      4 #Смотрим на результат
----> 5 print(f"Площадь района: {area_district[0]} м²")

TypeError: 'ellipsis' object is not subscriptable

Шаг 5: Вычисляем площадь зданий#

buildings_utm['area'] = ...
buildings_area = buildings_utm['area'].sum()

#Смотрим на результат
print(f"Площадь застроенной территории: {buildings_area} м²")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[5], line 1
----> 1 buildings_utm['area'] = ...
      2 buildings_area = buildings_utm['area'].sum()
      4 #Смотрим на результат

TypeError: 'ellipsis' object does not support item assignment

Шаг 6: Вычисляем долю застроенной территории#

built_share = ...

#Смотрим на результат
print(f"Площадь застроенной территории: {built_share[0]:.2f} %")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[6], line 4
      1 built_share = ...
      3 #Смотрим на результат
----> 4 print(f"Площадь застроенной территории: {built_share[0]:.2f} %")

TypeError: 'ellipsis' object is not subscriptable

Шаг 7: Вычисляем площадь по разным типам землепользования#

landuse_utm['area'] = ...
summary = landuse_utm.groupby('landuse')['area'].sum()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[7], line 1
----> 1 landuse_utm['area'] = ...
      2 summary = landuse_utm.groupby('landuse')['area'].sum()

TypeError: 'ellipsis' object does not support item assignment

Шаг 8: Визуализируем карты и график#

import matplotlib.pyplot as plt

# отсортируем Series по убыванию
summary_sorted = summary.sort_values(ascending=False)

fig, ax = plt.subplots(figsize=(6, 6))
summary_sorted.plot.pie(
    ax=ax,
    autopct='%1.1f%%',  # подписи с одной десятичной
    startangle=90       # стартовый угол
)
ax.set_ylabel('')       # убираем подпись оси Y
ax.set_title('Структура землепользования (от большего к меньшему)')

plt.tight_layout()
plt.show()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[8], line 4
      1 import matplotlib.pyplot as plt
      3 # отсортируем Series по убыванию
----> 4 summary_sorted = summary.sort_values(ascending=False)
      6 fig, ax = plt.subplots(figsize=(6, 6))
      7 summary_sorted.plot.pie(
      8     ax=ax,
      9     autopct='%1.1f%%',  # подписи с одной десятичной
     10     startangle=90       # стартовый угол
     11 )

NameError: name 'summary' is not defined

Шаг 9: Визуализируем карту застройки#

from matplotlib_scalebar.scalebar import ScaleBar 

# Создаём карту
fig, ax = plt.subplots(figsize=(10, 10))

# Землепользование — заливка
landuse_utm.plot(
    ax=ax, 
    column='landuse', 
    legend=True, 
    alpha=0.5, 
    cmap='Set3',  # мягкая цветовая палитра
    edgecolor='none'
)

# Здания — серые контуры
buildings_utm.plot(ax=ax, color='grey', linewidth=0.3, edgecolor='black', alpha=0.7)

# Границы района — чёрные
district_utm.boundary.plot(ax=ax, color='black', linewidth=1)

# Добавляем масштабную линейку (в метрах)
scalebar = ScaleBar(dx=1, units="m", location='lower left')
ax.add_artist(scalebar)

#Добавляем заголовок к легенде
legend = ax.get_legend()
if legend:
    legend.set_title("Типы землепользования:")

# Заголовок и оформление
ax.set_title(place_name, fontsize=16, pad=20)
ax.axis('off')
plt.tight_layout()
plt.show()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[9], line 7
      4 fig, ax = plt.subplots(figsize=(10, 10))
      6 # Землепользование — заливка
----> 7 landuse_utm.plot(
      8     ax=ax, 
      9     column='landuse', 
     10     legend=True, 
     11     alpha=0.5, 
     12     cmap='Set3',  # мягкая цветовая палитра
     13     edgecolor='none'
     14 )
     16 # Здания — серые контуры
     17 buildings_utm.plot(ax=ax, color='grey', linewidth=0.3, edgecolor='black', alpha=0.7)

AttributeError: 'ellipsis' object has no attribute 'plot'
../_images/11c4e1eb70184389643d2df87e55692b48f35cde1c6b992f6ad0ac50b3fae478.png

Найдите решение следующих задач:

  • Как можно одновременно отобразить карту и график на одном изображении?

  • Как добавить значение доли застроенной территории прямо на карту?

  • Как синхронизировать цвета типов землепользования на карте и на круговой диаграмме?

  • Как сделать всю информацию на круговой диаграмме читаемой