GeoJSON: геоданные в виде JSON

Урок разбирает GeoJSON — самый веб-дружелюбный формат геоданных — и показывает, как прочитать его стандартным модулем json без единой сторонней библиотеки.

GeoJSON — это формат на основе JSON для хранения векторной геометрии (точек, линий, полигонов) вместе с атрибутами.

Если вы уже работали с JSON, то GeoJSON освоите за минуту: это обычный JSON с заранее оговорённой структурой полей. Его читают браузеры, понимают все веб-карты, и именно он чаще всего ходит по API. Большой плюс — формат текстовый и самодокументируемый: открыв файл, вы сразу видите, что внутри.

Структура: Feature и FeatureCollection

Кирпичик GeoJSON — это Feature (объект): пара «геометрия + свойства». Набор объектов оборачивается в FeatureCollection. Геометрия имеет тип (Point, LineString, Polygon) и массив координат. Критично помнить: координаты идут в порядке [долгота, широта], то есть [x, y], — это обратно привычному «широта, долгота».

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "name": "Парк Горького", "type": "park" },
      "geometry": {
        "type": "Point",
        "coordinates": [37.6010, 55.7290]
      }
    }
  ]
}

Читаем GeoJSON исполнимым кодом

Поскольку GeoJSON — это JSON, его разбирает стандартный модуль json. Никаких geopandas не нужно, чтобы вытащить объекты:

import json

raw = '''{
  "type": "FeatureCollection",
  "features": [
    {"type": "Feature",
     "properties": {"name": "Парк Горького", "type": "park"},
     "geometry": {"type": "Point", "coordinates": [37.601, 55.729]}},
    {"type": "Feature",
     "properties": {"name": "Третьяковка", "type": "museum"},
     "geometry": {"type": "Point", "coordinates": [37.620, 55.741]}}
  ]
}'''

data = json.loads(raw)
print(f"Тип: {data['type']}")
print(f"Объектов: {len(data['features'])}")
for f in data["features"]:
    lon, lat = f["geometry"]["coordinates"]
    name = f["properties"]["name"]
    print(f"  {name}: широта {lat}, долгота {lon}")

Вывод:

Тип: FeatureCollection
Объектов: 2
  Парк Горького: широта 55.729, долгота 37.601
  Третьяковка: широта 55.741, долгота 37.62

Обратите внимание: мы распаковали координаты как lon, lat — именно в этом порядке они лежат в GeoJSON. Перепутать — типичная ошибка, точка уедет в другое место.

Как работает под капотом

Полигон в GeoJSON — это массив колец: первое кольцо внешний контур, последующие — «дырки» (например, остров внутри озера). У линии координаты — массив пар, у точки — одна пара. Спецификация (RFC 7946) предписывает координаты только в WGS84, поэтому в правильном GeoJSON всегда градусы широты-долготы — без указания другой системы. Минус формата — многословность: текст занимает больше места, чем двоичные форматы, поэтому большие наборы веб-карты подгружают тайлами, а не одним файлом.

Частые ошибки

  • Порядок координат. В GeoJSON [долгота, широта]; рефлекс «широта первая» ломает данные.
  • Незамкнутый полигон. Первая и последняя точка кольца обязаны совпадать.
  • Не-WGS84 координаты. Класть метры UTM в GeoJSON — нарушение спецификации; конвертируйте в градусы.

Почему GeoJSON победил в вебе

У GeoJSON есть конкуренты постарше и помощнее, но в вебе победил именно он, и причины поучительны. Во-первых, он нативен для JavaScript: браузер разбирает его встроенным JSON.parse без единой библиотеки, и объект сразу готов к отрисовке на Leaflet. Во-вторых, он самодокументируем — открыв файл, человек видит и понимает структуру, что бесценно при отладке API. В-третьих, он течёт по HTTP так же естественно, как любой другой JSON, и кешируется стандартными средствами. Цена этих удобств — многословность: те же данные в двоичном формате занимают в разы меньше, поэтому для тяжёлых слоёв веб переходит на векторные тайлы (формат MVT), где геометрия упакована компактно и нарезана по плиткам.

Стоит знать и про родственников. TopoJSON — расширение GeoJSON, которое хранит общие границы соседних полигонов один раз, а не дважды: для карты регионов, где области стыкуются, это резко уменьшает размер и гарантирует, что границы не разойдутся. GeoJSON Lines (по объекту на строку) удобен для потоковой обработки гигантских наборов. Но в основе всех них тот же принцип: геометрия плюс свойства в человекочитаемом тексте, координаты в порядке долгота-широта и только в WGS84.

Итог

  • GeoJSON — векторные геоданные в формате JSON; читается модулем json.
  • Feature = геометрия + properties; FeatureCollection — набор Feature.
  • Координаты идут как [долгота, широта] и только в WGS84.
  • Полигон — массив колец: внешний контур плюс «дырки».
Проверьте себя
1. В каком порядке записаны координаты точки в GeoJSON?
A[широта, долгота]
B[долгота, широта]
C[x, y, z] всегда
DВ произвольном
2. Что такое Feature в GeoJSON?
AТолько геометрия
BТолько свойства
CПара «геометрия + properties»
DИмя файла
3. Какая библиотека нужна, чтобы прочитать GeoJSON в Python?
AОбязательно geopandas
BДостаточно стандартного модуля json
CТолько numpy
DНикакая не справится