Leaflet и Turf.js часто применяются совместно для построения интерактивных карт, где визуализация данных дополняется пространственными вычислениями в браузере. Такая связка позволяет выполнять геоаналитику без серверной обработки, включая измерения расстояний, построение буферов, проверку пересечений и анализ полигонов.
Leaflet использует систему координат WGS84 в виде широты и долготы, но внутри рендеринга применяет проекцию Web Mercator (EPSG:3857). Turf.js работает исключительно в географических координатах WGS84 (longitude, latitude).
Ключевое правило интеграции — единый формат входных данных:
[lat, lng][lng, lat]Ошибки в порядке координат являются наиболее частой причиной некорректных геометрических вычислений.
Пример преобразования:
const leafletPoint = [55.751244, 37.618423];
const turfPoint = turf.point([leafletPoint[1], leafletPoint[0]]);
Геометрии, создаваемые Turf.js, могут быть напрямую добавлены на карту после преобразования в GeoJSON-слой.
const point = turf.point([37.618423, 55.751244]);
L.geoJSON(point).addTo(map);
Аналогично работают полигоны и линии:
const line = turf.lineString([
[37.61, 55.75],
[37.62, 55.76],
[37.63, 55.77]
]);
L.geoJSON(line).addTo(map);
Leaflet автоматически интерпретирует GeoJSON и отображает его через
L.geoJSON.
Turf.js предоставляет точные расчёты расстояний по поверхности Земли, используя сферическую модель.
const from = turf.point([37.618423, 55.751244]);
const to = turf.point([30.31413, 59.93863]);
const distance = turf.distance(from, to, { units: 'kilometers' });
Результат может быть использован для:
Интеграция с Leaflet:
L.marker([55.751244, 37.618423]).addTo(map);
L.marker([59.93863, 30.31413]).addTo(map);
const line = turf.lineString([
[37.618423, 55.751244],
[30.31413, 59.93863]
]);
L.geoJSON(line, {
style: { color: 'blue' }
}).addTo(map);
Буферизация используется для создания зоны влияния вокруг объекта.
const center = turf.point([37.618423, 55.751244]);
const buffer = turf.buffer(center, 5, { units: 'kilometers' });
L.geoJSON(buffer, {
style: {
color: 'red',
fillOpacity: 0.2
}
}).addTo(map);
Буфер может применяться для:
Turf.js позволяет определять пересечения геометрий.
const poly1 = turf.polygon([[
[37.6, 55.75],
[37.7, 55.75],
[37.7, 55.80],
[37.6, 55.80],
[37.6, 55.75]
]]);
const poly2 = turf.polygon([[
[37.65, 55.77],
[37.75, 55.77],
[37.75, 55.82],
[37.65, 55.82],
[37.65, 55.77]
]]);
const intersects = turf.booleanIntersects(poly1, poly2);
Результат используется для:
В Leaflet отображение:
L.geoJSON(poly1, { style: { color: 'green' } }).addTo(map);
L.geoJSON(poly2, { style: { color: 'orange' } }).addTo(map);
Turf.js позволяет создавать выборки точек внутри заданной области.
const polygon = turf.polygon([[
[37.6, 55.75],
[37.7, 55.75],
[37.7, 55.80],
[37.6, 55.80],
[37.6, 55.75]
]]);
const points = turf.randomPoint(50, { bbox: turf.bbox(polygon) });
L.geoJSON(points).addTo(map);
Такие данные применяются для:
При работе с большим количеством объектов Leaflet часто использует кластеризацию, а Turf.js помогает предварительно анализировать плотность.
const points = turf.randomPoint(200, {
bbox: [37.5, 55.7, 37.8, 55.9]
});
L.geoJSON(points, {
pointToLayer: (feature, latlng) => {
return L.circleMarker(latlng, {
radius: 4
});
}
}).addTo(map);
Дополнительно можно вычислять плотность:
const clustered = turf.clustersDbscan(points, 0.5, {
units: 'kilometers'
});
Turf.js предоставляет операции трансформации объектов:
const poly = turf.polygon([[
[37.6, 55.75],
[37.7, 55.75],
[37.7, 55.80],
[37.6, 55.80],
[37.6, 55.75]
]]);
const scaled = turf.transformScale(poly, 1.5);
Результат легко визуализируется через Leaflet:
L.geoJSON(scaled, {
style: { color: 'purple', fillOpacity: 0.3 }
}).addTo(map);
Leaflet предоставляет мощный механизм управления слоями, который напрямую работает с GeoJSON-структурами Turf.js.
const geoLayer = L.geoJSON(null, {
style: feature => ({
color: feature.properties.color || 'blue'
})
}).addTo(map);
geoLayer.addData(turf.point([37.61, 55.75]));
geoLayer.addData(turf.point([37.62, 55.76]));
Такой подход используется для:
Turf.js позволяет интерполировать точки вдоль линии:
const route = turf.lineString([
[37.618, 55.751],
[37.62, 55.76],
[37.65, 55.78]
]);
const segment = turf.along(route, 2, { units: 'kilometers' });
В Leaflet:
L.geoJSON(route, { color: 'blue' }).addTo(map);
L.geoJSON(segment, { color: 'red' }).addTo(map);
Проверка принадлежности точки:
const pt = turf.point([37.618423, 55.751244]);
const poly = turf.polygon([[
[37.6, 55.75],
[37.7, 55.75],
[37.7, 55.80],
[37.6, 55.80],
[37.6, 55.75]
]]);
const inside = turf.booleanPointInPolygon(pt, poly);
Используется для:
При интеграции Turf.js с Leaflet ключевым фактором становится оптимизация:
Пример фильтрации:
const bbox = [37.5, 55.7, 37.8, 55.9];
const filtered = points.features.filter(p =>
turf.booleanPointInPolygon(p, turf.bboxPolygon(bbox))
);
Связка Leaflet и Turf.js позволяет строить интерактивные аналитические интерфейсы, где каждое изменение карты сопровождается перерасчётом геометрий.
map.on('click', (e) => {
const clicked = turf.point([e.latlng.lng, e.latlng.lat]);
const buffer = turf.buffer(clicked, 3, { units: 'kilometers' });
L.geoJSON(buffer, {
style: { color: 'cyan', fillOpacity: 0.2 }
}).addTo(map);
});
Такой подход используется для: