Совместное использование Turf.js и OpenLayers формирует архитектуру, в которой визуализация пространственных данных отделена от их анализа. OpenLayers отвечает за работу с картографическим слоем, источниками данных, проекциями и рендерингом, тогда как Turf.js предоставляет функциональность геообработки на стороне клиента.
Такое разделение позволяет строить приложения, в которых геометрические операции выполняются непосредственно в браузере без обращения к серверу, что критично для интерактивных карт, аналитических панелей и офлайн-режимов.
OpenLayers оперирует объектами ol.Feature, содержащими
геометрию в формате GeoJSON или внутреннем представлении библиотеки.
Turf.js, напротив, работает исключительно с GeoJSON-структурами.
Связующий слой между ними — сериализация и десериализация геометрии:
Основная идея заключается в том, что Turf.js никогда не работает напрямую с объектами OpenLayers.
OpenLayers предоставляет встроенные утилиты для преобразования объектов.
import GeoJSON from 'ol/format/GeoJSON';
const format = new GeoJSON();
const geojson = format.writeFeature(feature, {
featureProjection: 'EPSG:3857',
dataProjection: 'EPSG:4326'
});
На этом этапе важно учитывать проекции:
featureProjection — система координат карты (обычно Web
Mercator)dataProjection — стандарт GeoJSON (WGS84)После преобразования данные становятся совместимыми с Turf.js:
import * as turf from '@turf/turf';
const buffered = turf.buffer(geojson, 500, { units: 'meters' });
Результат — новый GeoJSON-объект, содержащий геометрию буфера.
const bufferedFeature = format.readFeature(buffered, {
featureProjection: 'EPSG:3857',
dataProjection: 'EPSG:4326'
});
Буферизация используется для анализа зон влияния объектов: дорог, зданий, маршрутов.
const buffer = turf.buffer(pointGeoJSON, 2, { units: 'kilometers' });
const bufferFeature = format.readFeature(buffer, {
featureProjection: 'EPSG:3857',
dataProjection: 'EPSG:4326'
});
vectorSource.addFeature(bufferFeature);
Ключевой момент — единицы измерения. Turf.js не использует координаты карты напрямую, а оперирует реальными географическими единицами.
Операция пересечения часто используется в анализе зон покрытия.
const intersection = turf.intersect(polygonA, polygonB);
Если пересечение отсутствует, результатом становится
null, что требует проверки перед добавлением на карту.
const union = turf.union(polygonA, polygonB);
OpenLayers затем отображает результат как единый объект, что полезно для упрощения визуализации сложных регионов.
OpenLayers предоставляет события взаимодействия с картой, которые можно использовать для динамического анализа.
map.on('click', function (evt) {
const coordinate = evt.coordinate;
});
Далее координаты переводятся в GeoJSON Point:
import { point } from '@turf/turf';
const pointGeoJSON = point([lon, lat]);
Turf.js предоставляет точные геодезические вычисления.
const from = turf.point([lon1, lat1]);
const to = turf.point([lon2, lat2]);
const distance = turf.distance(from, to, { units: 'kilometers' });
В OpenLayers результат обычно отображается как подпись или используется для построения линий.
import { lineString } from '@turf/turf';
const line = lineString([
[lon1, lat1],
[lon2, lat2]
]);
После преобразования линия добавляется в слой карты.
Turf.js позволяет генерировать регулярные сетки, полезные для тепловых карт и агрегации данных.
const bbox = [minX, minY, maxX, maxY];
const grid = turf.squareGrid(bbox, 10, { units: 'kilometers' });
Каждая ячейка сетки становится отдельным объектом OpenLayers после конвертации.
Хотя OpenLayers имеет собственную кластеризацию, Turf.js позволяет предварительно анализировать плотность данных.
const hex = turf.hexGrid(bbox, 5, { units: 'kilometers' });
Дальнейшая агрегация точек:
const points = turf.featureCollection([...]);
const result = turf.collect(hex, points, 'value', 'values');
Ключевой аспект интеграции — различие систем координат:
EPSG:3857EPSG:4326Ошибки в этом слое приводят к:
Поэтому стандартный конвейер всегда включает преобразование через GeoJSON.
При обработке тысяч объектов возникают ограничения:
Оптимизационные подходы:
ol/source/Vector с clear() и
массовым добавлениемmap.on('click', function (evt) {
const coord = toLonLat(evt.coordinate);
const pointFeature = turf.point(coord);
const buffered = turf.buffer(pointFeature, 1, { units: 'kilometers' });
const olFeature = format.readFeature(buffered, {
featureProjection: 'EPSG:3857',
dataProjection: 'EPSG:4326'
});
vectorSource.clear();
vectorSource.addFeature(olFeature);
});
Turf.js позволяет выполнять:
turf.pointsWithinPolygon)turf.centroid)turf.simplify)turf.clusters)В связке с OpenLayers это формирует интерактивные аналитические карты, где каждое изменение данных мгновенно отражается на визуализации.
При сложных геометриях используется упрощение:
const simplified = turf.simplify(polygon, {
tolerance: 0.01,
highQuality: true
});
Это снижает нагрузку на OpenLayers при отрисовке и ускоряет взаимодействие.
В OpenLayers результаты Turf.js обычно помещаются в отдельные слои:
Такое разделение позволяет изолировать визуальные эффекты и повторно использовать результаты анализа без пересчёта.
Комбинация событий OpenLayers и функций Turf.js позволяет строить системы:
Все вычисления выполняются на клиенте, а визуализация обновляется мгновенно через источники OpenLayers.