英文:
Single text label for a MultiLineString in MapLibre GL JS
问题
我试图在使用 MapLibre GL JS 显示 GeoJSON 文件中的 MultiLineString 要素的文本标签。我正在使用 symbol-placement: point
选项,这样我就可以在不同的缩放级别上看到标签,而不仅仅在靠得很近的时候才能看到,就像使用 line
选项时会发生的那样。
...
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
}
});
...
问题是,当 MultiLinestring 有多条线时,MapLibre 会为每一条线都渲染一个标签,如下图所示。有没有办法只为每个 MultiLineString 要素渲染一个文本标签?
我留下了我正在使用的 GeoJSON 文件的示例(带有图像中的两个要素),因为原始文件非常长:https://www.jsonblob.com/1120054652224946176
英文:
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
答案1
得分: 1
我会使用每个要素的turf/center of mass来创建一个新的标签点源。然后可以使用这个点源来创建一个标签图层。
安装
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'],
}
});
英文:
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
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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'],
}
});
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论