MapLibre GL JS中多行字符串的单一文本标签

huangapple go评论75阅读模式
英文:

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

MapLibre GL JS中多行字符串的单一文本标签

英文:

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

MapLibre GL JS中多行字符串的单一文本标签

答案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 &quot;@turf/center-of-mass&quot;;

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

map.addSource(&#39;labelSource&#39;, {&#39;type&#39;: &#39;geojson&#39;, &#39;data&#39;: {type: &quot;FeatureCollection&quot;, features: labelPoints}})

map.addLayer({
    &#39;id&#39;: &#39;labelLayer&#39;,
    &#39;type&#39;: &#39;symbol&#39;,
    &#39;source&#39;: &#39;labelSource&#39;,
    &#39;layout&#39;: {
        &#39;text-field&#39;: [&#39;get&#39;, &#39;Name&#39;],
    }
});

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月19日 02:22:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定