Как поиски боровиков привели меня к спутниковой классификации леса
Нынешний грибной сезон выдался у нас скудным. Виноваты ли поздние весенние заморозки, засушливое лето или бесконечные ливни под занавес — сказать трудно. Первые сообщения о том, что в лесах Ленинградской области наконец появились боровики, я увидел лишь в конце августа. Жена обожает боровики, поэтому каждую осень я занимаюсь поиском их мест.
На «тихую охоту» времени оставалось в обрез: три пары выходных, как мне тогда думалось, не больше. В сезон конкуренция жёстче, чем за вакансию на HH, а тратить драгоценные дни на прогулки с пустой корзиной совсем не хотелось.
Первый боровик обнаружился прямо на нашем дачном участке. Мы сочли это знаком: пора выдвигаться.
Сначала поехали в сторону Алёховщины проверять сосновые боры и беломошники. Для грибника это лес мечты: стройные сосны, сухой песок, много света, а под ногами — седой хрустящий ковёр, на фоне которого так и видится крепкий боровик с тёмно-каштановой шляпкой.
Название «беломошник» народное и слегка обманчивое: светлый покров образуют в основном лишайники (преимущественно родов Cladonia и Cetraria), а вовсе не мхи. Гулять по такому бору — настоящее эстетическое наслаждение.

Грибов не оказалось. Вообще.
В тот же день мы двинулись дальше, к Олонцу. Проверили места, которые приметили две недели назад по дороге на терский берег и на которые рассчитывали, — снова пусто. На обратном пути я наугад свернул к Нижне-Свирскому заповеднику: плана никакого, надежд почти не осталось. И вот там, в придорожной канаве вдоль второстепенной грунтовки, в случайном, да и не слишком похожем на настоящий сосняк перелеске, мы за час набрали две полные корзины.
После такой вылазки (четыре часа за рулём в один конец — не шутка) во мне проснулся чисто айтишный интерес: как выбирать точки для следующего выезда, чтобы не стрелять вхолостую? Почему в хрестоматийном лесу как с открытки — шаром покати, а там, где грибов совсем не ждёшь, их изобилие? Хотелось снизить долю случайности в и без того небыстром занятии.
Пытливый ум, грибной Инстаграм (экстремистская секта, всячески осуждаю) и накопленный опыт подсказывали: между сосной, грибницей и песком существует прямая связь. Тогда я решил построить карту пригодных биотопов.
Отдельный гриб на спутниковом снимке, разумеется, не разглядеть — разрешение не то. Зато можно попытаться отыскать лес, в котором он мог бы расти. Начать пришлось с микологии.
Что мы ищем: биология вида
Прежде чем скармливать спутниковые снимки алгоритмам, стоило разобраться с самим объектом поиска. Я ориентировался на белый гриб сосновый — Boletus pinophilus. Подборку научных статей по теме я поручил Клоду, а сам ушёл пить чай.
Научная справка: молекулярная филогения и систематика Boletus pinophilus
Видовую самостоятельность подтверждает молекулярно-филогенетическая работа Beugelsdijk et al. (2008): анализ фрагментов ДНК (дезоксирибонуклеиновой кислоты) — ITS (Internal Transcribed Spacer, внутреннего транскрибируемого спейсера рибосомной РНК) и GAPDH (Glyceraldehyde-3-Phosphate Dehydrogenase, гена фермента глицеральдегид-3-фосфатдегидрогеназы) — уверенно выделил его в самостоятельную эволюционную линию внутри секции Boletus.
Для моей задачи особенно ценна экологическая характеристика: вид образует эктомикоризу главным образом с сосной обыкновенной (Pinus sylvestris) и тяготеет к сухим, кислым, хорошо дренированным песчаным и супесчаным почвам. Из морфологических признаков стоит отметить мясистую бугристую шляпку тёмного винно-красно-коричневого тона и отчётливый рельефный сетчатый рисунок в верхней части массивной ножки.
Вместе с тем исследование предостерегает от поспешных выводов:
-
Связь с сосной не абсолютна: микоризу находили и в еловых насаждениях.
-
Белый гриб под сосной не всегда оказывается B. pinophilus. Авторы описали образцы, собранные на песчаных почвах под соснами: по облику и биотопу они напоминали сосновый боровик, однако ДНК показала, что это экологическая форма обыкновенного белого гриба — Boletus edulis (в микологических статьях после первого упоминания название рода сокращают: B. pinophilus, B. edulis).
Так, под чашку чая, родилась рабочая гипотеза проекта: сочетание чистого сосняка и бедной песчаной почвы позволяет очертить приоритетные участки для полевой разведки. Это метод косвенного моделирования пригодности местообитаний (Habitat Suitability Modelling). Он не гарантирует наличия мицелия и уж тем более не обещает грибного ковра к выходным, зато безошибочно отсекает заведомо бесперспективные территории.
Сбор «сырья»: почвы, спутники и первые оверлеи
Первыми источниками данных стали:
-
Почвенная карта РСФСР 1988 года под редакцией В. М. Фридланда (масштаб 1:2 500 000);
-
Слой хвойных лесов из системы глобального мониторинга Copernicus Global Land Service (CGLS);
-
Краудсорсинговая картографическая база OpenStreetMap (OSM), из которой выгружались участки с отметками типов растительности.
Каждый источник решал свою задачу. Карта Фридланда указывала на кислые почвы борового ряда. Спутниковый продукт показывал лесные массивы. А в OSM энтузиасты вручную размечают лесные участки. Всё это вовсе не было жизненно необходимо для поездки, но раз уж начал…

Извлечение геоданных: Livewire-харвестинг и оконный доступ к COG
Извлечение почв: динамический веб-харвестинг
На портале soil-db.ru оцифрованную институтом имени Докучаева карту Фридланда готовым файлом не скачать. Она работает в веб-интерфейсе на фреймворке Livewire: когда окно карты сдвигается, браузер вызывает метод loadFeatures, а сервер возвращает геометрию полигонов в событии livewire-map:add-features.
Я написал сборщик на основе протокола Chrome DevTools Protocol (CDP). Он обошёл всю Ленинградскую область сеткой из 55 перекрывающихся окон девятого уровня масштаба, извлёк векторные контуры и объединил их в единый GeoJSON (RFC 7946) — формат хранения географических объектов на основе синтаксиса JSON.
Снимок состояния, скопированный из активного окна, содержал кэш loadedIds: сервер считал эти участки уже переданными и упрямо отказывался отдавать центральную часть Петербурга и Карельский перешеек. Пришлось сбросить идентификаторы и отдельным проходом догрузить недостающие 60 полигонов. Итог: 364 полигона и 25 почвенных разностей. Главный фаворит — иллювиально-железистые подзолы (), визитная карточка сосновых боров на песках.
Маска леса: оконный доступ к COG
Для лесного покрова я взял продукт CGLS-LC100 (Buchhorn et al., 2020) за 2019 год — глобальный растр с шагом 100 м. Скачивать весь файл (около гигабайта) не пришлось: GeoTIFF был подготовлен по стандарту Cloud-Optimized GeoTIFF (COG).
Библиотека GDAL с её виртуальной файловой системой /vsicurl в паре с Python-библиотекой rasterio позволяет читать растр прямо из удалённого хранилища через HTTP-запросы диапазонов байтов (range-requests). Скрипт вырезал строго географическую рамку Ленобласти.
Затем пиксели класса 1 (вечнозелёный хвойный лес) были векторизованы функцией rasterio.features.shapes: получилось 3044 контура площадью более 1 км².
Опираться исключительно на теги OSM (leaf_type=needleleaved — этот тег обозначает иглолистную хвою вообще, а не сосну в частности) мешала фрагментарность покрытия.
Собранные вместе, эти слои дали первый прототип карты, который в ретроспективе оказался совсем неплох.
Вторая поездка: лужские беломошники
С первой версией карты в руках мы позвали друзей и на следующие выходные отправились под Лугу.
Особое чувство безответственности охватывает, когда везёшь людей за 150 км под вечер, полагаясь на файл, который только что склеил скриптом. Но карта и бородатые мужики из инстаграма будто нашёптывали: на песчаных террасах реки Луги хвойный лес совпадает с нужными подзолами.
Первая точка, у самой реки, встретила нас великолепным пейзажем, но грибы там были не те: пёстрые сыроежки да пара старых моховиков. Закрались сомнения…
Переезжаем на вторую точку, углубляемся в массив — и оказываемся в безупречном, хрестоматийном беломошнике. Светлый просторный сосновый бор, белоснежный лишайниковый ковёр, под ним сухой хрустящий песок. И, главное, боровики! Крепкие, тёмно-вишнёвые, будто с картинки. Сомнения, возникшие абзацем выше, оказались напрасными.

Правда, довольно быстро выяснился нюанс: почти всё, что росло на виду, конкуренты срезали ещё ранним субботним утром. Нам достались чужие «хвосты». Зато концепция подтвердилась на местности: косвенные признаки привели нас точно в нужный биотоп. Слой «кто проходил здесь с ведром три часа назад» спутник, увы, выдаёт далеко не всем.
Алгоритм отбора кандидатов
Чтобы не сличать слои на глаз, я формализовал пересечение в виде алгоритма генерации полигонов-кандидатов:
Пайплайн алгоритма кандидатов
-
Экспертная оценка почв: типам почв по Фридланду присвоили рейтинг пригодности (
). В отбор попали почвы начиная с
(в первую очередь те самые иллювиально-железистые подзолы).
-
Растеризация: векторный слой почв преобразовали в растровую сетку, идентичную сетке CGLS-LC100.
-
Логическое пересечение: бинарная маска «хвойный лес
почва
».
-
Полигонизация и фильтрация: маску вернули в векторный вид через
rasterio.features.shapes, отбросив мелкий мусор площадью менее 0,3 км². Осталось 3265 зон общей площадью 10 240 км². -
Зональная статистика подложки: для каждого полигона вычислили среднее содержание песка в подпочве на глубине 60 см по глобальной сетке OpenLandMap / SoilGrids (Hengl et al., 2017) (разрешение 250 м).
-
Разделение на сосну и ель: если средняя песчанистость превышала 60%, полигон получал флаг
pine=true(условный сосняк); если оказывалась ниже — попадал в категорию «прочий хвойный» (чаще всего сырые ельники).
Итог: 1048 «сосновых» зон (4348 км²) и 2217 прочих хвойных.
Флаг pine=true был смелым авансом: он означал не то, что модель распознала сосну, а лишь то, что хвойный лес растёт на относительно лёгкой песчаной почве. Пересечение разномасштабных данных (почвы 1:2,5 млн, песок 250 м, лес 100 м) не делает границы точнее самого грубого из компонентов. Звёзды обозначали приоритет проверки ногами, а не плотность боровиков на квадратный метр.
Архитектура на коленке: мобильный вьюер и смена картографического движка
После Луги стало ясно, что в лесу нужен удобный полевой инструмент. Я поручил Клоду набросать веб-интерфейс со сценариями для смартфона:
-
Тап по участку открывает карточку с кнопками перехода в навигаторы — ссылкой по протоколу
geo:(RFC 5870) для запуска в сторонних офлайн-приложениях на Android. -
Кнопка геолокации на базе встроенного в браузер W3C Geolocation API: стоишь среди сосен и сразу видишь, находишься ли ты внутри расчётного полигона или ещё бредёшь по переходной зоне.
-
Разделение панели на «простой режим» (только грибные места, радар осадков и болота) и «экспертный» (где можно регулировать прозрачность почв и подсвечивать отдельные типы).
Электронный мозг справился не с первой попытки, но справился. Проект перестал быть простым: сам собой подтянулись тестирование и деплой репозитория через GitHub Actions, хранение секретов, журналирование входов и прочая обвязка. Всё, как мы любим.

Инженерия доставки: решение проблемы сдвига в 18 км, PMTiles и Cloudflare Workers
Драматичный переезд с Leaflet на OpenLayers
Первый прототип работал на библиотеке Leaflet. Но тут всплыла фундаментальная проблема геодезических проекций:
-
Стандартные веб-карты (OSM, Google) используют проекцию EPSG:3857 (WGS 84 / Pseudo-Mercator, или Web Mercator).
-
Спутниковые тайлы Яндекса исторически построены на эллипсоидальной проекции Меркатора — EPSG:3395 (WGS 84 / World Mercator).
Если наложить векторный слой из одной проекции на растр в другой, на широте Санкт-Петербурга (60° с. ш.) геометрия на местности смещается примерно на 18 километров. Библиотеку MapLibre GL JS пришлось отвергнуть сразу — она жёстко привязана к Web Mercator. Единственным движком, способным на лету трансформировать растровые и векторные слои в произвольные проекции через WebGL (браузерный интерфейс аппаратного ускорения графики) и Canvas прямо на мобильном процессоре, оказался OpenLayers. Я проверил прототип на смартфоне: подложка Яндекса встала без перекосов, контуры легли пиксель в пиксель.
Векторные тайлы и сжатие в PMTiles
Отдавать мобильному браузеру «сырые» GeoJSON-файлы лесов и болот по 35 МБ через мобильную сеть на лесной опушке — верная смерть. Данные нужно было тайлировать, то есть нарезать на стандартные пространственные квадраты разного масштаба.
Конвейер генерации оформили в виде воспроизводимого bash-скрипта:
-
Утилита mapshaper переводила координаты в специально настроенную азимутальную равновеликую проекцию Ламберта LAEA (Lambert Azimuthal Equal Area, сохраняющую площади объектов) с центром в точке 60° с. ш., 31° в. д. В плоских метрах пороги упрощения и фильтры по площади работают геометрически строго — в отличие от искажающихся угловых градусов WGS84.
-
Команда
-cleanудаляла топологические наложения и осколки растеризации. Источник
Чему Генри Дрейфус мог бы научить создателей интерфейсов, которые рисует ИИ
Искусственный интеллект подтвердил квазигипотезу Римана: каковы дальнейшие шаги?
Машина, превращающая пластик в топливо?
Спросите Итана: способен ли трос из кевлара обеспечить искусственную гравитацию в космосе?
Почти не встретились: какую роль могло сыграть столкновение Земли с Тейей
Беседа с совладельцем клуба «Луноход» Виктором Чередниченко
Неандертальское жилище в Испании: копья, деревянная посуда и загадочная дубинка
Отладка детского мышления: как преодолеть когнитивные барьеры на уроках математики