Working with map libraries
Quick answer
This tutorial connects Turf output to rendering: L.geoJSON on Leaflet and a GeoJSON source with setData on MapLibre. It contrasts the three coordinate conventions, namely [lng, lat] in GeoJSON, [lat, lng] in Leaflet and the reversed fitBounds pair order in each library, and shows how to recompute buffers and update a source instead of rebuilding layers. You will be able to wire analysis results into either map.
Key points
- Convert turf.bbox output [west, south, east, north] to Leaflet's [[south, west], [north, east]] before fitBounds.
- Create the source once inside load and update it with map.getSource('zone').setData(zone).
- Precompute area and density into properties before styling features by value.
Example
var site = turf.point([116.391263, 39.907359]);
var zone = turf.buffer(site, 1.2, { units: 'kilometers' });
var map = L.map('map').setView(
[site.geometry.coordinates[1], site.geometry.coordinates[0]], 14
);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
var layer = L.geoJSON(zone, {
style: {
color: '#17694a',
weight: 2,
fillOpacity: 0.2
},
onEachFeature: function (feature, lyr) {
var area = turf.area(feature) / 1e6; // 平方公里
lyr.bindPopup('影响范围 ' + area.toFixed(2) + ' 平方公里');
}
}).addTo(map);
var box = turf.bbox(zone); // [西, 南, 东, 北]
map.fitBounds([[box[1], box[0]], [box[3], box[2]]], { padding: [20, 20] });map.on('load', function () {
map.addSource('zone', { type: 'geojson', data: emptyFC() });
map.addSource('origin', {
type: 'geojson',
data: turf.featureCollection([site])
});
map.addLayer({
id: 'zone-fill',
type: 'fill',
source: 'zone',
paint: { 'fill-color': '#17694a', 'fill-opacity': 0.2 }
});
map.addLayer({
id: 'zone-line',
type: 'line',
source: 'zone',
paint: { 'line-color': '#17694a', 'line-width': 2 }
});
map.addLayer({
id: 'origin-dot',
type: 'circle',
source: 'origin',
paint: { 'circle-radius': 5, 'circle-color': '#c2410c' }
});
redraw(1.2);
});
function redraw(radiusKm) {
var zone = turf.buffer(site, radiusKm, { units: 'kilometers' });
map.getSource('zone').setData(zone);
var b = turf.bbox(zone);
map.fitBounds([[b[0], b[1]], [b[2], b[3]]], {
padding: 40,
duration: 600
});
}
function emptyFC() {
return { type: 'FeatureCollection', features: [] };
}
Notes
- Repeating map.addSource for an existing id throws Source "zone" already exists.
- Buffering lines or nearby points yields MultiPolygon, which some rendering paths handle poorly without dissolve.
English edition written for Atlaslog. Code is taken from the original Chinese page and runs unchanged.
Atlaslog (2026). Working with map libraries. https://www.jingweizhi.com/en/turf/tutorials/map-integration.html (accessed 2026-11-03).