Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Измерение площадей и расстояний

Корректность расчётов расстояний, площадей и построения буферных зон напрямую зависит от используемой системы координат (CRS).

Если данные находятся в географической системе координат (например, WGS 84 (EPSG:4326)), координаты выражены в градусах. Такие данные подходят для отображения объектов на карте, но не подходят для прямых измерений расстояний и площадей.

Чтобы получать результаты в метрах и квадратных метрах, данные необходимо перепроецировать в подходящую проецированную систему координат, например UTM.

В этом разделе мы рассмотрим:

  • почему перед выполнением измерений важно перепроецировать данные и как CRS влияет на результаты измерений;

  • как вычислять площади полигонов;

  • как измерять расстояния между объектами.

0. Импорт библиотек и подготовка данных

0.1 Импорт библиотек

import osmnx as ox

import geopandas as gpd

0.2 Подготовка данных

Загрузим границу района из OpenStreetMap

area_name = "Центральный район, Санкт-Петербург"

admin_border = ox.geocode_to_gdf(area_name)
admin_border.explore(tiles="cartodbpositron")
Loading...

Проверим систему координат:

admin_border.crs
<Geographic 2D CRS: EPSG:4326> Name: WGS 84 Axis Info [ellipsoidal]: - Lat[north]: Geodetic latitude (degree) - Lon[east]: Geodetic longitude (degree) Area of Use: - name: World. - bounds: (-180.0, -90.0, 180.0, 90.0) Datum: World Geodetic System 1984 ensemble - Ellipsoid: WGS 84 - Prime Meridian: Greenwich

Загрузим станции метро в выбранном районе из OpenStreetMap

tags = {"railway": "subway_entrance"}

metro = ox.features_from_place(
    "Центральный район, Санкт-Петербург",
    tags
)

metro.explore(tiles="cartodbpositron")
Loading...

Проверим систему координат:

metro.crs
<Geographic 2D CRS: EPSG:4326> Name: WGS 84 Axis Info [ellipsoidal]: - Lat[north]: Geodetic latitude (degree) - Lon[east]: Geodetic longitude (degree) Area of Use: - name: World. - bounds: (-180.0, -90.0, 180.0, 90.0) Datum: World Geodetic System 1984 ensemble - Ellipsoid: WGS 84 - Prime Meridian: Greenwich

1. Измерение площади

В GeoPandas каждый GeoDataFrame имеет специальный атрибут .geometry, в котором хранятся геометрические объекты пространственных данных — например, точки, линии или полигоны.

Этот атрибут позволяет обращаться к геометрии объектов и выполнять различные пространственные операции.

Одной из таких операций является вычисление площади. Для этого используется атрибут .area, который возвращает площадь каждого полигонального объекта.

Важно помнить, что .area возвращает результат в тех единицах измерения, которые используются в системе координат (CRS).

1.1 Вычисление площади 1.0

Создадим новое поле "area" в GeoDataFrame admin_border и запишем в него вычисленные значения площади.

admin_border['area'] = admin_border.geometry.area
/tmp/ipykernel_2653/1329868239.py:1: UserWarning: Geometry is in a geographic CRS. Results from 'area' are likely incorrect. Use 'GeoSeries.to_crs()' to re-project geometries to a projected CRS before this operation.

  admin_border['area'] = admin_border.geometry.area

Посмотрим на результат

admin_border[['name', 'area']]
Loading...

На этом этапе можно заметить, что полученные значения площади оказываются неожиданно малыми. Это связано с тем, что слой всё ещё находится в географической системе координат.

В географических системах координат (например, WGS 84 / EPSG:4326) положение объектов задаётся в градусах широты и долготы, а не в линейных единицах измерения. Поэтому площадь в таком случае вычисляется в квадратных градусах.

Такие значения сложно интерпретировать, поскольку градусы не являются единицей длины, а их пространственный масштаб изменяется в зависимости от широты.

Поэтому для корректного вычисления площадей и расстояний данные необходимо предварительно перепроецировать в систему координат с метрическими единицами измерения, например UTM.

Обратите внимание на предупреждение UserWarning, которое может появляться при вычислении площади. Оно указывает на то, что расчёты выполняются для данных в географической системе координат, и полученные значения могут быть некорректными. Такое предупреждение служит напоминанием о необходимости перепроецировать данные.

1.2 Перепроецирование данных в UTM

Перепроецируем данные в подходящую UTM-зону, чтобы координаты были выражены в метрах.

Сначала определим подходящую систему координат UTM с помощью метода .estimate_utm_crs(). И перепроецируем слой admin_border в эту систему координат.

utm_crs = admin_border.estimate_utm_crs()

admin_border_utm = admin_border.to_crs(utm_crs)

Убедимся, что система координат действительно изменилась

admin_border_utm.crs
<Projected CRS: EPSG:32636> Name: WGS 84 / UTM zone 36N Axis Info [cartesian]: - E[east]: Easting (metre) - N[north]: Northing (metre) Area of Use: - name: Between 30°E and 36°E, northern hemisphere between equator and 84°N, onshore and offshore. Belarus. Cyprus. Egypt. Ethiopia. Finland. Israel. Jordan. Kenya. Lebanon. Moldova. Norway. Russian Federation. Saudi Arabia. Sudan. Syria. Türkiye (Turkey). Uganda. Ukraine. - bounds: (30.0, 0.0, 36.0, 84.0) Coordinate Operation: - name: UTM zone 36N - method: Transverse Mercator Datum: World Geodetic System 1984 ensemble - Ellipsoid: WGS 84 - Prime Meridian: Greenwich

Мы видим, что в этой системе координат используются метры. Теперь вычислим значения площади ещё раз.

1.3 Вычисление площади 2.0

Создадим новое поле "area_m2" в GeoDataFrame admin_border_utm и запишем туда вычисленные значения площади.

admin_border_utm['area_m2'] = admin_border_utm.geometry.area

Посмотрим на результат

admin_border_utm[['name', 'area', 'area_m2']]
Loading...

Теперь полученные значения выглядят более реалистично. Поскольку площадь объектов вычисляется в квадратных метрах.

Иногда значения площади могут отображаться в экспоненциальной записи (scientific notation). Такой формат используется для компактного представления больших чисел.

Число вида a.bcde+X означает a.bcde×10Xa.bcde \times 10^{X}.

Например: 1.769497e+07 = 1.769497×1071.769497 \times 10^{7} или 17,7 млн.

Это просто альтернативная форма записи большого числа.

Для удобства можно перевести площадь в квадратные километры (1 км² = 1 000 000 м²):

admin_border_utm["area_km2"] = admin_border_utm["area_m2"] / 1_000_000
admin_border_utm[["display_name", "area_km2"]].head()
Loading...

2. Измерение расстояний

Метод .distance() позволяет вычислять расстояние между геометрическими объектами. Предположим, что мы хотим определить, на каком расстоянии находятся станции метро от центра района.

Поскольку исходные данные находятся в географической системе координат, сначала перепроецируем их в подходящую UTM-зону, чтобы выполнять измерения в метрах.

2.0. Подготовка данных

Сначала перепроецируем слой со станциями метро в ту же систему координат, что и границы района.

metro_utm = metro.to_crs(utm_crs)

Также определим центр района, который будем использовать как точку отсчёта для измерения расстояний.

center = admin_border_utm.geometry.centroid.iloc[0]

center_gdf = gpd.GeoDataFrame(geometry=[center], crs=utm_crs)

center_gdf.explore(tiles='cartodbpositron')
Loading...

Центроид — это геометрический центр полигона. Мы используем его как условную точку центра района.

2.1. Вычисление расстояний

Теперь вычислим расстояние от центра района до каждой станции метро.

metro_utm["distance_m"] = metro_utm.geometry.distance(center)

metro_utm[["name", "distance_m"]].head()
Loading...

Полученные значения показывают расстояние в метрах, поскольку данные находятся в проецированной системе координат UTM.

Евклидово расстояние

Метод .distance() вычисляет евклидово расстояние между геометриями — то есть прямое расстояние по плоскости между двумя точками.

Такое расстояние иногда называют «расстоянием по прямой» (straight-line distance или as-the-crow-flies).

В реальных задачах часто используют расстояния по улично-дорожной сети — например, по дорогам или маршрутам общественного транспорта.
С методами сетевого анализа мы познакомимся в 4-м модуле курса.

Тем не менее для многих аналитических задач евклидово расстояние является полезным приближением, особенно при предварительном анализе пространственных данных.

Итог

В этом разделе мы рассмотрели, как корректно измерять площади и расстояния с помощью GeoPandas.

Мы узнали:

  • почему географические CRS не подходят для измерений;

  • как вычислять площади с помощью .area;

  • как измерять расстояния с помощью .distance();

Корректный выбор системы координат — одно из ключевых этапов подготовки данных для последующего пространственного анализа.

Перед выполнением пространственных измерений проверьте:

  • находится ли слой в проецированной CRS;

  • выражены ли координаты в метрах;

  • совпадает ли CRS у всех используемых слоёв.