Generate centroids from polygons for GL JS labeling with Turf.js

I have been excited to try Turf.js since it came out, but I haven’t had a reason to until now. It is as awesome as I thought it would be.

One problem with GL JS styling is placing labels in the middle of polygons. As in, you can’t.

Imgur

Fair enough. I imagine this is due to centroid calculation slagging client-side rendering performance. I added a turf.js build step that automates the generation of a centroid point file. It chews through ~470 complex polygons in 1-2 seconds, and I don’t have to worry about maintaining another data layer. Problem solved.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var fs = require('fs');
var turfCentroid = require('turf-centroid');
var geojson = require('./data/geography.geojson.json');

var result = {
"type": "FeatureCollection",
"features": []
};

for (var i = 0; i < geojson.features.length; i++) {
result.features.push(
{
"type": "Feature",
"properties": {"id": geojson.features[i].properties.id},
"geometry": turfCentroid(geojson.features[i]).geometry
}
);
}

fs.writeFile(path.join("./public/data", `labels.geojson.json`), JSON.stringify(result, null, ' '));

Edit: If you have concave/ugly polys, Turf’s point-on-surface is a bit slower but you won’t get a centroid outside of a polygon. Switch in var turfCentroid = require('turf-point-on-surface'); and everything else stays the same.