Карту можно открыть внутри <iframe> в своём веб-приложении и использовать как выбор
населённого пункта. Как только пользователь выбирает город, ваше окно получает его климатические
параметры сообщением postMessage. Регистрация, ключи и серверная часть не нужны.
<iframe
src="https://картаклиматологии.рф/?app=myapp"
width="100%"
height="640"
style="border: 1px solid #ccc; border-radius: 8px"
title="Карта климатологии">
</iframe>
Карта сама определяет, что открыта во фрейме (window.self !== window.top) — специальный
параметр для этого не нужен. Необязательный параметр ?app= задаёт имя вашего приложения:
оно подставляется в подсказку над панелью («Выберите город — данные передадутся в myapp»).
Если параметр не передан, будет нейтральный текст «…передадутся в приложение».
Встраивайте картаклиматологии.рф — это основной адрес карты:
| Адрес | Origin для проверки | Статус |
|---|---|---|
| картаклиматологии.рф | https://xn--80aaamxcajckck1abv6ag.xn--p1ai | основной |
| map.teploov.ru | — | карту не обслуживает, перенаправляет на основной адрес |
Обратите внимание: домен кириллический, и в event.origin браузер отдаёт его
в punycode — https://xn--80aaamxcajckck1abv6ag.xn--p1ai, а не
https://картаклиматологии.рф. Сравнение со строкой в кириллице не сработает.
src iframe на основной и добавьте в allowlist
origin https://xn--80aaamxcajckck1abv6ag.xn--p1ai; строку https://map.teploov.ru
можно удалить.
// Кириллический домен в event.origin приходит в punycode — см. раздел 1
const ALLOWED_ORIGINS = [
'https://xn--80aaamxcajckck1abv6ag.xn--p1ai', // картаклиматологии.рф
];
window.addEventListener('message', (event) => {
// Обязательно проверяйте источник сообщения
if (!ALLOWED_ORIGINS.includes(event.origin)) return;
const msg = event.data;
if (!msg || msg.type !== 'climamap:selection') return;
if (msg.schemaVersion !== 1) return;
console.log(msg.city.name); // "Москва"
console.log(msg.climate.temp_cold_098); // -31
console.log(msg.humidityZone.zoneType); // 2
// Месячные ряды из дополнительных таблиц СП 131 — см. раздел 6
console.log(msg.extra?.tables?.temp_monthly?.values); // [-7, -6.4, -1, ...]
});
targetOrigin: '*', поэтому
проверка event.origin на вашей стороне обязательна. Не доверяйте сообщениям с других
источников и валидируйте schemaVersion.
Тип climamap:selection, текущая версия схемы — 1.
{
"type": "climamap:selection",
"schemaVersion": 1,
"dataset": { "id": "sp131_2025", "name": "СП 131.13330.2025 (Актуальный)" },
"point": { "lat": 55.753215, "lon": 37.622504 },
"city": {
"name": "Москва",
"region": "Московская область",
"coordinates": [55.753215, 37.622504],
"isNearest": false,
"distanceKm": null
},
"climate": {
"temp_cold_098": -31,
"temp_cold_092": -28,
"wind_cold_direction": "З"
/* ... остальные параметры выбранного СП ... */
},
"humidityZone": { "zoneType": 2, "zoneName": "Зона 2 - Нормальная" },
"radiation": null,
"extra": {
"edition": "2025",
"tables": {
"temp_monthly": {
"table": "7.1",
"title": "Средняя месячная и годовая температура воздуха",
"unit": "°С",
"source": "СП 131.13330.2025, таблица 7.1",
"columns": ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII", "Год"],
"values": [-7, -6.4, -1, 6.5, 13.3, 17.2, 19.2, 17.2, 11.4, 5.4, -0.7, -4.8, 5.9]
}
/* ... остальные таблицы, см. раздел 6 ... */
},
"missing": []
}
}
| Поле | Описание |
|---|---|
schemaVersion |
Версия схемы. Сейчас всегда 1. Новые поля могут добавляться без смены версии — неизвестные поля игнорируйте. |
dataset |
Нормативный документ, из которого взяты значения: sp131_2025 (СП 131.13330.2025) или sp131_2020 (СП 131.13330.2020). Пользователь переключает его в панели карты. |
point |
Фактически выбранная точка. Совпадает с координатами города, кроме случая поиска пункта, которого нет в нормах — тогда это координаты найденного адреса. |
city |
Населённый пункт из справочника, чьи климатические данные переданы. |
city.isNearest |
true, если пункт отсутствует в нормах и климат взят по ближайшему городу справочника. В этом случае distanceKm — расстояние до него в километрах. |
climate |
Все климатические параметры пункта — 31 ключ. Полный справочник с единицами измерения и правилами обработки значений — в разделе 4. |
humidityZone |
Зона влажности по СП 50.13330, рассчитанная по координатам точки. zoneType: 1 — влажная, 2 — нормальная, 3 — сухая, 0 — точка вне полигонов зон (см. примечание ниже). |
radiation |
Зарезервировано под датасет солнечной радиации. Сейчас всегда null. |
extra |
Дополнительные таблицы СП 131 по выбранному пункту: месячные ряды температуры, парциального давления, осадков, скорости ветра, солнечной радиации и другие. Подробно — в разделе 6. |
{ "zoneType": 0, "zoneName": null } приходит только тогда, когда точка не попала
ни в один полигон зон — практически это территория за пределами РФ. Такое значение
не подставляйте в расчёт молча: корректнее запросить зону у пользователя.
climateКлючи одинаковы для обеих редакций СП — их всегда 31. Названия ключей стабильны и являются частью контракта: переименовываться они не будут. Значения передаются «как в норме», без единиц измерения в самой строке — единица берётся из таблицы ниже.
| Ключ | Ед. | Параметр по СП |
|---|---|---|
temp_cold_098 | °С | Температура воздуха наиболее холодных суток, обеспеченностью 0,98 |
temp_cold_092 | °С | Температура воздуха наиболее холодных суток, обеспеченностью 0,92 |
temp_cold_5day_098 | °С | Температура воздуха наиболее холодной пятидневки, обеспеченностью 0,98 |
temp_cold_5day_092 | °С | Температура воздуха наиболее холодной пятидневки, обеспеченностью 0,92 (расчётная температура наружного воздуха для теплотехники) |
temp_cold_094 | °С | Температура воздуха, обеспеченностью 0,94 |
temp_cold_abs_min | °С | Абсолютная минимальная температура воздуха |
temp_cold_amp_month | °С | Средняя суточная амплитуда температуры воздуха наиболее холодного месяца |
period_duration_cold_0 | сут | Продолжительность периода со средней суточной температурой воздуха ≤ 0 °С |
temp_cold_avg_0 | °С | Средняя температура воздуха периода со средней суточной температурой ≤ 0 °С |
period_duration_cold_8 | сут | Продолжительность периода со средней суточной температурой воздуха ≤ 8 °С (отопительный период, для ГСОП) |
temp_cold_avg_8 | °С | Средняя температура воздуха периода со средней суточной температурой ≤ 8 °С (для ГСОП) |
period_duration_cold_10 | сут | Продолжительность периода со средней суточной температурой воздуха ≤ 10 °С |
temp_cold_avg_10 | °С | Средняя температура воздуха периода со средней суточной температурой ≤ 10 °С |
humidity_cold_avg_month | % | Средняя месячная относительная влажность воздуха наиболее холодного месяца |
humidity_cold_avg_month_15h | % | Средняя месячная относительная влажность воздуха в 15 ч наиболее холодного месяца |
precip_cold | мм | Количество осадков за ноябрь – март |
wind_cold_direction | — | Преобладающее направление ветра за декабрь – февраль (строка, см. ниже) |
wind_cold_speed_max_jan | м/с | Максимальная из средних скоростей ветра по румбам за январь |
wind_cold_speed_avg_8 | м/с | Средняя скорость ветра за период со средней суточной температурой ≤ 8 °С |
| Ключ | Ед. | Параметр по СП |
|---|---|---|
temp_warm_095 | °С | Температура воздуха, обеспеченностью 0,95 (параметры А) |
temp_warm_098 | °С | Температура воздуха, обеспеченностью 0,98 (параметры Б) |
temp_warm_avg_max_month | °С | Средняя максимальная температура воздуха наиболее тёплого месяца |
temp_warm_abs_max | °С | Абсолютная максимальная температура воздуха |
temp_warm_avg_amp_month | °С | Средняя суточная амплитуда температуры воздуха наиболее тёплого месяца |
humidity_warm_avg_month | % | Средняя месячная относительная влажность воздуха наиболее тёплого месяца |
humidity_warm_avg_month_15h | % | Средняя месячная относительная влажность воздуха в 15 ч наиболее тёплого месяца |
precip_warm | мм | Количество осадков за апрель – октябрь |
precip_warm_max_day | мм | Суточный максимум осадков |
wind_warm_direction | — | Преобладающее направление ветра за июнь – август (строка, см. ниже) |
wind_warm_min_avg | м/с | Минимальная из средних скоростей ветра по румбам за июль |
| Ключ | Ед. | Параметр по СП |
|---|---|---|
pressure | гПа | Барометрическое давление |
climateЗначения передаются ровно так, как напечатаны в таблицах СП. Обе базы приведены к единому виду, поэтому особенностей осталось всего две — но их нужно учесть обязательно.
"-"
В таблицах СП отсутствующие значения помечены прочерком. В обеих базах он передаётся
одинаково — строкой "-", в том числе в числовых полях.
Ключи при этом всегда присутствуют: у каждого пункта передаются все 31.
| Ключ | Пунктов с прочерком, СП 2025 | СП 2020 |
|---|---|---|
temp_cold_avg_0 | 8 | 7 |
wind_cold_speed_max_jan | 5 | 3 |
wind_warm_min_avg | 2 | 3 |
pressure | 2 | — |
precip_warm_max_day | 1 | 1 |
wind_cold_speed_avg_8 | — | 4 |
Пример: у Сочи, Ялты и Феодосии нет периода со средней суточной температурой ≤ 0 °С,
поэтому temp_cold_avg_0 равно "-".
parseFloat("-")
вернёт NaN, и он способен разойтись по всему расчёту незамеченным.
Используйте нормализатор из 5.3.
wind_cold_direction и wind_warm_direction содержат один или
несколько равнозначных румбов, если в норме указано несколько.
Разделитель — запятая, одинаково в обеих редакциях:
"Ю", "СЗ, ЮВ", "С, В, СЗ".
Румбы кириллические: С, СВ, В, ЮВ,
Ю, ЮЗ, З, СЗ. Не разбирайте это поле
как перечисление с фиксированным набором значений — показывайте строкой; если нужен
разбор, режьте по запятой и обрезайте пробелы.
"0,0". Значение передаётся как есть — так же, как напечатано в норме.
Карта отображает его как северное ("С", азимут 0°); тот же разбор делает
нормализатор ниже. Другой трактовки у этого значения нет.
// Число или null — годится для любого числового ключа climate
function num(climate, key) {
const v = climate?.[key];
if (v === undefined || v === null || v === '-') return null;
const n = typeof v === 'number' ? v : parseFloat(String(v).replace(',', '.'));
return Number.isFinite(n) ? n : null;
}
// Направление ветра: массив румбов
function windDirection(climate, key) {
const v = climate?.[key];
if (typeof v !== 'string' || v === '-') return [];
if (v.trim() === '0,0') return ['С']; // Элиста, СП 2020 — см. 5.2
return v.split(',').map(s => s.trim()).filter(Boolean);
}
num(msg.climate, 'temp_cold_5day_092'); // -28
num(msg.climate, 'temp_cold_avg_0'); // null, если в норме прочерк
windDirection(msg.climate, 'wind_cold_direction'); // ["СЗ", "ЮВ"]
null перед расчётом. Если параметр, нужный вашей
методике, отсутствует у выбранного пункта — корректнее показать это пользователю и предложить
другой пункт, чем подставить значение по умолчанию.
extra — дополнительные таблицы СП 131
Кроме 31 параметра холодного и тёплого периодов карта отдаёт остальные содержательные
таблицы СП 131.13330 — месячные ряды температуры и парциального давления водяного пара,
осадки, скорость ветра, суточные амплитуды, солнечную радиацию, освещённость, высоту солнца,
энтальпию и влагосодержание. Всё это лежит в поле extra.
Передаётся только строка выбранного пункта, а не таблица целиком.
Ключи внутри extra.tables — смысловые идентификаторы величин, они стабильны
и не зависят от редакции СП: номера таблиц в редакциях 2020 и 2025 разные, поэтому
номер приходит отдельным полем table.
| Поле | Описание |
|---|---|
extra.edition |
Редакция СП, из которой взяты таблицы: "2020" или "2025". Соответствует dataset.id. |
extra.tables |
Объект «идентификатор величины → данные по пункту». Таблицы, по которым данных для этого пункта нет, в объекте отсутствуют: проверяйте наличие ключа, а не содержимое. |
extra.missing |
Идентификаторы таблиц, по которым данных нет вовсе, — тот же факт в виде списка, для наглядности и логов. Обычно пуст: если пункта в таблице нет, карта подставляет ближайший (см. 6.1). Остаются в списке таблицы, которых не было в этой редакции СП, и таблицы, недоступные в автономной версии карты. |
table |
Номер таблицы в этой редакции СП — например "7.1". |
unit |
Единица измерения, как в документе. Обязательное поле. |
source |
Ссылка на документ и таблицу — например "СП 131.13330.2025, таблица 7.1". Обязательное поле: храните его вместе со значениями, оно нужно для прослеживаемости в экспертизе. |
columns |
Заголовки граф таблицы. Для месячных рядов — ["I", …, "XII", "Год"]. |
values |
Значения по графам. Пропуски — та же строка "-", что и в climate (раздел 5.1). |
rowLabels |
Есть только у таблиц с несколькими рядами на пункт: тогда values[r][c] — ряд rowLabels[r], графа columns[c]. |
substitute |
Есть, только если данные взяты по другому населённому пункту: { "name", "region", "distanceKm", "reason" }. Подробно — в 6.1. |
interpolated, clamped, basis |
Есть только у таблиц, привязанных к географической широте (см. 6.3). |
Охват пунктов у таблиц СП разный: в таблице средних месячных температур 551 пункт, в таблице максимальной июльской амплитуды — 79, а суточный ход освещённости дан всего для девяти городов. Поэтому по части таблиц строки выбранного пункта просто не существует.
В этом случае карта не отдаёт пустоту: она берёт ближайший пункт таблицы,
у которого данные есть, и добавляет к блоку поле substitute.
Ближайший пункт у каждой таблицы свой — по одной величине это может быть
сосед в 50 км, по другой — город в 600 км.
"temp_amp_july_max": {
"table": "8.1",
"unit": "°С",
"source": "СП 131.13330.2025, таблица 8.1",
"columns": ["Максимальная амплитуда температуры воздуха"],
"values": [21.4],
"substitute": {
"name": "Балашов",
"region": "Саратовская область",
"distanceKm": 594,
"reason": "no_row"
}
}
reason: "no_row" — выбранного пункта в таблице нет.reason: "no_values" — строка пункта в таблице есть, но значения в ней не приведены.distanceKm — расстояние от выбранной точки до подставленного пункта, км.substitute нет — значит данные именно выбранного пункта.substitute пользователю. Значения в блоке — не
данные выбранного города, а данные другого населённого пункта. Сохраняйте это поле вместе
со значениями: в проектной документации должно быть видно, откуда взято число, а решение,
приемлема ли замена за 600 км, принимает проектировщик, а не карта.
extra.tables| Ключ | Величина | Ед. | Табл. 2020 / 2025 | Форма values |
|---|---|---|---|---|
temp_monthly | Средняя месячная и годовая температура воздуха | °С | 5.1 / 7.1 | 13 значений |
vapor_pressure_monthly | Среднее месячное и годовое парциальное давление водяного пара | гПа | 7.1 / 11.1 | 13 значений |
precip_monthly | Средняя месячная и годовая сумма осадков | мм | — / 10.1 | 13 значений |
wind_speed_monthly | Средняя месячная и годовая скорость ветра | м/с | — / 12.1 | 13 значений |
temp_amp_july_max | Максимальная суточная амплитуда температуры воздуха в июле | °С | 6.1 / 8.1 | 1 значение |
temp_amp_monthly | Средняя и максимальная суточная амплитуда температуры | °С | 11.1 / 9.1 | 2 ряда × 12 месяцев |
enthalpy_moisture_cooling | Удельная энтальпия и влагосодержание наружного воздуха (тёплый период) | кДж/кг; г/кг | 10.2 / 16.2 | 2 значения, единицы — в units |
illuminance_daily | Суточный ход рассеянной и суммарной освещённости | клк | 12.1 / 14.1 | 12 месяцев × 12 часов, в ячейке пара значений; плюс sunrise / sunset |
radiation_horizontal | Суммарная солнечная радиация на горизонтальную поверхность | МДж/м² | 8.1 / 13.1 | 12 месяцев, по широте |
radiation_vertical | Суммарная солнечная радиация на вертикальную поверхность | МДж/м² | 9.1 / 13.2 | 12 месяцев × 5 ориентаций, по широте |
sun_altitude | Высота солнца над горизонтом | градус | 13.1 / 15.1 | 12 месяцев, по широте |
Прочерк — в графе «Табл.» означает, что такой таблицы в этой редакции СП нет:
осадков и скорости ветра по месяцам в СП 131.13330.2020 не публиковали. Такие таблицы
попадают в extra.missing — подставить сюда данные соседнего пункта нельзя,
величины в норме просто нет.
Солнечная радиация и высота солнца в СП даны не по пунктам, а по географической широте с шагом в несколько градусов. Карта интерполирует их линейно по широте пункта и не экстраполирует: за пределами сетки берётся граничное значение. Вместе со значениями приходят метаданные — чтобы число в проектной документации оставалось прослеживаемым.
"radiation_horizontal": {
"table": "13.1",
"unit": "МДж/м²",
"source": "СП 131.13330.2025, таблица 13.1",
"columns": ["I", "II", "III", /* ... */ "XII"],
"values": [114.6, 217.8, 448.1, /* ... */ 81.5],
"interpolated": true,
"clamped": false,
"basis": {
"lat": 55.753215,
"nodes": [
{ "lat": 52, "values": [102, 195, /* ... */ 71] },
{ "lat": 56, "values": [116, 221, /* ... */ 83] }
]
}
}
interpolated: false и один узел в basis.nodes — широта пункта совпала с узлом сетки, значение табличное.clamped: true — точка за пределами сетки, принято граничное значение ближайшего узла. Если ваш расчёт к этому чувствителен, покажите признак пользователю.isNearest: true.Каждый выбор перезаписывает предыдущий: храните у себя последнее полученное сообщение.
Параллельно с climamap:selection отправляется устаревшее сообщение
KAVRIS_CLIMATE_SELECTED — оно сохранено для ранее подключённых приложений.
В новых интеграциях используйте только climamap:selection, а сообщения других
типов отфильтровывайте по полю type.
Формат открытый: подключить карту может любой желающий, согласование не требуется. Если нужны дополнительные поля или у вас есть замечания к контракту — напишите через раздел «Контакты» на главной странице.