OGC API — Features и Processes
> Кратко. /api/ogc отдаёт слои сети по стандарту OGC API — Features (GeoJSON в WGS 84): участки, узлы, потребители, источники, задвижки. Там же — OGC API — Processes: трассировка, локализация аварии, выборки, статистика и гидравлический расчёт. Так слои ТГИД подключают QGIS, GDAL и ГИС акиматов без GeoServer.
Адреса
| Адрес | Что |
|---|---|
GET /api/ogc |
стартовая страница: ссылки conformance, data, processes, service-desc (/openapi.json) |
GET /api/ogc/conformance |
классы стандарта: Features часть 1 (core, geojson, oas30), часть 4 (запись, ETag), Processes часть 1 |
GET /api/ogc/collections |
пять коллекций с охватом сети |
GET /api/ogc/collections/{id} |
одна коллекция |
GET /api/ogc/collections/{id}/items |
объекты: GeoJSON FeatureCollection (application/geo+json) |
GET /api/ogc/collections/{id}/items/{fid} |
один объект с ETag (для записи) |
Вход — как у API v1: Authorization: Bearer <токен входа>, роль не ниже «Просмотр». Ключи ArcGIS, MCP и API v2
здесь не действуют.
Коллекции
| id | Объекты | Свойства (кроме fileid — фрагмент) |
|---|---|---|
pipes |
живые участки основной схемы с геометрией (без участков внутренних схем) | name, node_start, node_end, sign, diameter_mm, diameter_internal_mm, length_m, state_supply, state_return (из первого паспорта трубы) |
nodes |
узлы основной схемы (без узлов внутренних схем) | name, node_type |
consumers |
реальные и обобщённые потребители в точке узла | name, kind (real, generalized), source_id, node_id, load_gcal_h |
heat_sources |
источники тепла | name, node_id |
valves |
задвижки в середине участка | name, line_id, diameter_mm, state (1 открыта, 2 закрыта) |
Что учесть:
- Участков и узлов внутренних схем (камер, ЦТП) в коллекциях нет — как в выборке по условиям, FeatureServer
и встраиваемой карте. Во фрагменте 74 копии Алматы
pipesотдаёт 3625 участков (ещё 196 — внутренние схемы). - Свойства участка берутся из первого по номеру паспорта трубы, а выборка по условиям — из самого длинного. На участках с несколькими паспортами Ду может различаться; во фрагменте 74 обе дают 2068 участков Ду ≥ 500.
- Реальные и обобщённые потребители лежат в разных таблицах, и номера в них повторяются. Поэтому
idобобщённого потребителя в коллекции сдвинут на 1 000 000 000 (id5 в таблице обобщённых — объект1000000005), а номер в его таблице — в свойствеsource_id.idв коллекции уникален,/items/{fid}возвращает ровно один объект.
Объекты: items
| Параметр | Что |
|---|---|
limit |
1…10 000, по умолчанию 100 |
offset |
сдвиг; следующая страница — ссылка rel: next (есть, пока страница полная), предыдущая — prev |
bbox |
minLon,minLat,maxLon,maxLat в CRS84 (долгота, широта); объект попадает, если его рамка пересекает bbox |
fileid |
фрагмент |
Системы координат: геометрия — всегда WGS 84 в порядке «долгота, широта» (CRS84), 7 знаков после запятой; охват
коллекций — тоже CRS84. Параметра crs нет. В базе сеть хранится в своей системе города: API пересчитывает
геометрию сам и переводит bbox в систему сети. Неверный bbox (не четыре числа, min > max, широта за ±90) —
400. Общего числа объектов (numberMatched) в ответе нет — только numberReturned.
Пример — участки в рамке в центре Алматы (копия Алматы):
curl -s "$API/api/ogc/collections/pipes/items?bbox=76.93,43.24,76.95,43.25&limit=3" -H "Authorization: Bearer $TOKEN"
{"type":"FeatureCollection","numberReturned":3,"features":[
{"type":"Feature","id":993,"geometry":{"type":"LineString","coordinates":[[76.9367993,43.2507663],[76.9369258,43.2499472]]},
"properties":{"fileid":1,"name":null,"node_start":324,"node_end":330,"sign":1,"diameter_mm":800.0,
"diameter_internal_mm":806.0,"length_m":91.6,"state_supply":1,"state_return":1}}, "…"],
"links":[{"href":".../items?bbox=76.93%2C43.24%2C76.95%2C43.25&limit=3&offset=0","rel":"self","type":"application/geo+json"},
{"href":".../items?bbox=76.93%2C43.24%2C76.95%2C43.25&limit=3&offset=3","rel":"next","type":"application/geo+json"}]}
Сверка на копии Алматы: в этой рамке 2041 участок — столько же насчитали OGC (limit=10000), FeatureServer
(returnCountOnly с geometry) и GDAL (ogrinfo -spat). Во фрагменте 74 у OGC и FeatureServer одинаково: 3821
участок, 1777 узлов, 1037 потребителей, 2 источника, 35 задвижек.
QGIS и GDAL
QGIS: «Слой → Добавить слой → Добавить слой WFS / OGC API — Features» → «Создать», адрес <API>/api/ogc,
версия «OGC API — Features». Вход — проверка подлинности «API Header»: заголовок Authorization, значение
Bearer <токен>. Токен входа живёт 8 часов; для постоянного подключения удобнее FeatureServer с ключом
на 90 дней.
GDAL (драйвер OAPIF). Выполнено на стенде копии Алматы, GDAL 3.9.2:
ogrinfo -ro -so "OAPIF:http://127.0.0.1:8090/api/ogc"
# 1: pipes (title: Участки теплосети) (Line String)
# 2: nodes (title: Узлы сети) (Point)
# 3: consumers (title: Потребители) (Point)
# 4: heat_sources (title: Источники тепла) (Point)
# 5: valves (title: Задвижки) (Point)
ogrinfo -ro -so -spat 76.93 43.24 76.95 43.25 "OAPIF:http://127.0.0.1:8090/api/ogc" pipes
# Feature Count: 2041
# Supported SRS: OGC:CRS84
С включённым входом токен передаётся настройкой GDAL GDAL_HTTP_HEADERS="Authorization: Bearer <токен>"
(на стенде без входа этот вариант не проверялся).
Запись (часть 4)
POST /collections/{id}/items, PUT и PATCH /items/{fid} (JSON Merge Patch), DELETE /items/{fid} — узлы,
участки, задвижки и источники; потребители — только чтение. Правка идёт теми же операциями, что в окне редактора:
права вида объекта, журнал отмены, audit_log, проверка связности. Версия — ETag из GET …/items/{fid},
If-Match с устаревшей версией — 412. Нужны MUTATIONS_ENABLED, для геометрии, создания и удаления —
TOPOLOGY_MUTATIONS_ENABLED. Подробно — docs/ogc-api.md в репозитории API.
Процессы
| Адрес | Что |
|---|---|
GET /api/ogc/processes |
девять процессов |
GET /api/ogc/processes/{id} |
описание: входы (JSON Schema без $ref) и выход result |
POST /api/ogc/processes/{id}/execution |
{"inputs": {…}, "response": "raw" | "document"} |
GET /api/ogc/jobs/{jobId}, …/results |
состояние и результат задания (только heat-hydraulic) |
| Процесс | Инструмент MCP | Запуск |
|---|---|---|
network-trace |
network_trace |
синхронно |
valve-isolation |
valve_isolation |
синхронно |
network-select |
select_network |
синхронно |
network-statistics |
network_statistics |
синхронно |
regime-analysis |
regime_analysis |
синхронно |
thematic-summary |
thematic_summary |
синхронно |
wear-priorities |
wear_priorities |
синхронно |
data-quality |
data_quality |
синхронно |
heat-hydraulic |
run_calculation |
задание Celery: 201 и Location на /jobs/{id} |
Входы, права и ограничения частоты — те же, что у инструментов MCP. heat-hydraulic — настоящий
расчёт (право «Запуск расчётов», результаты пишутся в базу).
Пример — длина сети фрагмента 74 (копия Алматы):
curl -s -X POST "$API/api/ogc/processes/network-statistics/execution" -H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" -d '{"inputs":{"query":"length","fragment_ids":[74]},"response":"document"}'
# {"result":{"query":"length","title":"Длина теплопроводов, м","fragment_ids":[74],
# "length_supply_m":197263.2,"length_return_m":197576.4,"length_total_m":394839.6}}
Выборка участков Ду ≥ 500 во фрагменте 74 (network-select, {"target":"lines","conditions":[{"field":"diameter", "op":"ge","value":500}],"fragment_ids":[74],"limit":1}) вернула total: 2068, total_length_m: 245608.8 за 0,16 с.
Ошибки — RFC 7807 (application/problem+json): no-such-process (404), invalid-parameter-value (400 — неверные
входы), result-not-ready (404), no-such-job (404); 5xx — без подробностей. Состояние задания
(GET /api/ogc/jobs/{jobId}) берётся из того же источника, что GET /api/v1/task/{task_id}. API нескольких
городов помнит город каждого задания: неизвестный или чужой номер — 404 no-such-job. API одного города спрашивает
Celery, а тот не отличает неизвестное задание от ещё не начатого — ответ accepted.
Для разработчика
- API:
routers/ogc.py(Features, ссылки от адреса запроса иAPI_PUBLIC_PREFIX),database/ogc_features.py(COLLECTIONS,MAX_LIMIT,parse_bbox),routers/ogc_write.pyиdatabase/ogc_transactions.py(запись),routers/ogc_processes.py(PROCESSES). Те же коллекции — у FeatureServer и встраиваемой карты. - Тесты: API —
tests/test_ogc_features.py,tests/test_ogc_write.py,tests/test_ogc_processes.py(в том числеtest_jobs_status_without_stub— состояние задания без подмены); e2e —e2e/functions/developer-api.spec.ts(OGC против FeatureServer, рамка, ошибки, процессы).
