0

I'm trying to display text labels for MultiLineString features in a geoJSON file using MapLibre GL JS. I'm using the symbol-placement: point option so I can see the labels on different zoom levels and not just when I get really close as it would happen if I use the line option.

...

map.addSource('source_data', {
        type: 'geojson',
        data: 'sample.geojson'
    });

map.addLayer({
    "id": "symbols",
    "type": "symbol",
    "source": "source_data",
    "layout": {
        "symbol-placement": "point",
        "text-field": '{Name}',
        "text-size": 40,
        "text-justify": "center",
        "text-allow-overlap": false
      }
});

...

The thing is that when the MultiLinestring has more than one line, MapLibre is rendering a label for every one of them as seen in the image below. Is there a way to render only one text label for each MultiLineString feature?

I'm leaving a sample of the geoJSON file I'm using (with the two features of the image) because the original file is really long: https://www.jsonblob.com/1120054652224946176

enter image description here

Bejuco
  • 133
  • 12

1 Answers1

1

I would create a new point source for the labels by using turf/center of mass for each feature. This can be used to create a label layer then.

Installation

npm install @turf/center-of-mass

import centerOfMass from "@turf/center-of-mass";

const yourGeojson = {}
const labelPoints = yourGeojson.features.map(feature => centerOfMass(feature, {properties: {Name: feature.properties.Name}}))

map.addSource('labelSource', {'type': 'geojson', 'data': {type: "FeatureCollection", features: labelPoints}})

map.addLayer({
    'id': 'labelLayer',
    'type': 'symbol',
    'source': 'labelSource',
    'layout': {
        'text-field': ['get', 'Name'],
    }
});
MarcelCode
  • 483
  • 3
  • 10
  • Thank you Marcel. I ended up creating a point for each feature by hand but this seems like a good solution as well. – Bejuco Jul 17 '23 at 14:31